1 //
2 // Copyright (c) 2010-2023 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System;
8 using System.Collections.Generic;
9 using System.Linq;
10 using System.Reflection;
11 using Antmicro.Renode.Utilities;
12 
13 namespace Antmicro.Renode.RobotFramework
14 {
15     internal class KeywordManager : IDisposable
16     {
KeywordManager()17         public KeywordManager()
18         {
19             keywords = new Dictionary<string, List<Keyword>>();
20             objects = new Dictionary<Type, IRobotFrameworkKeywordProvider>();
21         }
22 
Register(Type t)23         public void Register(Type t)
24         {
25             if(!typeof(IRobotFrameworkKeywordProvider).IsAssignableFrom(t))
26             {
27                 return;
28             }
29 
30             foreach(var methodAttr in t.GetMethodsWithAttribute<RobotFrameworkKeywordAttribute>())
31             {
32                 var method = methodAttr.Method;
33                 var attr = methodAttr.Attribute;
34                 var keyword = attr.Name ?? method.Name;
35                 if(!keywords.ContainsKey(keyword))
36                 {
37                     keywords.Add(keyword, new List<Keyword>());
38                 }
39 
40                 keywords[keyword].Add(new Keyword(this, method));
41             }
42         }
43 
GetOrCreateObject(Type declaringType)44         public object GetOrCreateObject(Type declaringType)
45         {
46             IRobotFrameworkKeywordProvider result;
47             if(!objects.TryGetValue(declaringType, out result))
48             {
49                 result = (IRobotFrameworkKeywordProvider)Activator.CreateInstance(declaringType);
50                 objects.Add(declaringType, result);
51             }
52 
53             return result;
54         }
55 
TryExecuteKeyword(string keywordName, object[] arguments, out object keywordResult)56         public KeywordLookupResult TryExecuteKeyword(string keywordName, object[] arguments, out object keywordResult)
57         {
58             keywordResult = null;
59             if(!keywords.TryGetValue(keywordName, out var candidates))
60             {
61                 return KeywordLookupResult.KeywordNotFound;
62             }
63             object[] parsedArguments = null;
64             var keyword = candidates.FirstOrDefault(x => x.TryMatchArguments(arguments, out parsedArguments));
65             if(keyword == null)
66             {
67                 return KeywordLookupResult.ArgumentsNotMatched;
68             }
69             if(keyword.ReplayMode != Replay.Never)
70             {
71                 Recorder.Instance.RecordEvent(keywordName, arguments, keyword.ReplayMode);
72             }
73             keywordResult = keyword.Execute(parsedArguments);
74             return KeywordLookupResult.Success;
75         }
76 
GetRegisteredKeywords()77         public string[] GetRegisteredKeywords()
78         {
79             return keywords.Keys.ToArray();
80         }
81 
Dispose()82         public void Dispose()
83         {
84             foreach(var obj in objects)
85             {
86                 obj.Value.Dispose();
87             }
88         }
89         private readonly Dictionary<string, List<Keyword>> keywords;
90         private readonly Dictionary<Type, IRobotFrameworkKeywordProvider> objects;
91 
92         public enum KeywordLookupResult
93         {
94             Success,
95             KeywordNotFound,
96             ArgumentsNotMatched
97         }
98     }
99 }
100 
101