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