public static AddNagMessage ( NagType nag, string message ) : void | ||
nag | NagType | Should the message be shown once, or keep being shown /// every time the terminal welcome message appears? |
message | string | Message to print |
return | void |
public static void WalkAssemblies(Assembly[] assemblies) { SafeHouse.Logger.SuperVerbose("Begin walking assemblies."); foreach (Assembly assembly in assemblies) { if (!assembly.GlobalAssemblyCache) { SafeHouse.Logger.SuperVerbose("Walking assembly: " + assembly.FullName); try { WalkAssembly(assembly); } catch (Exception ex) { string message = string.Format(assemblyLoadErrorFormat, assembly.FullName, assembly.Location); SafeHouse.Logger.LogError(message); Debug.AddNagMessage(Debug.NagType.NAGONCE, message); SafeHouse.Logger.LogError(string.Format("Exception: {0}\nStack Trace:\n{1}", ex.Message, ex.StackTrace)); } } } SafeHouse.Logger.SuperVerbose("Begin static walk methods."); foreach (AssemblyWalkAttribute walkAttribute in AllWalkAttributes.Keys) { if (!string.IsNullOrEmpty(walkAttribute.StaticWalkMethod)) { Type managerType = AllWalkAttributes[walkAttribute]; var walkMethod = managerType.GetMethod(walkAttribute.StaticWalkMethod, BindingFlags.Static | BindingFlags.Public); walkMethod.Invoke(null, null); } SafeHouse.Logger.Log("Attribute " + walkAttribute.ToString() + " loaded " + walkAttribute.LoadedCount + " objects."); } SafeHouse.Logger.SuperVerbose("Finish walking assemblies."); }
/// <summary> /// Report nag message on terminal if there is a C# type derived from kOS.Safe.Encapsulated.Structure /// which was not given a KOSNomenclatureAttribute to work from. All Structure derivatives will need /// to be given at least one KOS name by being given such an attribute. /// </summary> private static void NagCheck(Type t) { StringBuilder message = new StringBuilder(); if (!cSharpToKosMap.ContainsKey(t)) { if (ShowNagHeader) { // show the nag header only once, with the first type. message.Append(NagHeader); ShowNagHeader = false; } else { message.Append("\n"); } message.Append("\"" + t.FullName + "\""); } if (message.Length > 0) { SafeHouse.Logger.Log(message.ToString()); Debug.AddNagMessage(Debug.NagType.NAGFOREVER, message.ToString()); } }
/// <summary> /// Report nag message on terminal if there is a C# type derived from kOS.Safe.Encapsulated.Structure /// which was not given a KOSNomenclatureAttribute to work from. All Structure derivatives will need /// to be given at least one KOS name by being given such an attribute. /// </summary> private static void NagCheck(IEnumerable <Type> checkTypes) { StringBuilder message = new StringBuilder(); foreach (Type t in checkTypes) { if (!cSharpToKosMap.ContainsKey(t)) { if (message.Length == 0) { message.Append(NagHeader); } else { message.Append("\n"); } message.Append("\"" + t.FullName + "\""); } } if (message.Length > 0) { SafeHouse.Logger.Log(message.ToString()); Debug.AddNagMessage(Debug.NagType.NAGFOREVER, message.ToString()); } }
private static void PopulateOneAssemblyMapping(Assembly assembly) { // A bit slow, but only executes this once during the life of the program: IEnumerable <Type> allStructureTypes = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(Structure)) || t == typeof(Structure)); // The nomenclature mapping data is contained in KOSNomenclatureAttributes that are attached to the classes: foreach (Type t in allStructureTypes) { object[] attribs = t.GetCustomAttributes(typeof(KOSNomenclatureAttribute), false); foreach (object obj in attribs) { KOSNomenclatureAttribute attrib = obj as KOSNomenclatureAttribute; if (attrib == null) { continue; // hypothetically impossible since GetCustomAttributes explicitly asked for only attributes of this type. } try { if (attrib.CSharpToKOS) { cSharpToKosMap.Add(t, attrib.KOSName); } } catch (ArgumentException) { // There can be a many-to-one map (given two different C# types, they both return the same KOS type), but // not a one-to-many map (given one C# type, it has two kOS types it tries to return). string msg = "kOS developer error: name clash in KOSNomenclature: two mappings from C# class " + t.FullName + " found."; Debug.AddNagMessage(Debug.NagType.NAGFOREVER, msg); } try { if (attrib.KOSToCSharp) { kosToCSharpMap.Add(attrib.KOSName, t); } } catch (ArgumentException) { // There can be a many-to-one map (given two different kos types, they both return the same C# type), but // not a one-to-many map (given one kos type, it has two C# types it tries to return). string msg = "kOS developer error: name clash in KOSNomenclature: two mappings from KOS name " + attrib.KOSName + " found."; Debug.AddNagMessage(Debug.NagType.NAGFOREVER, msg); } } } NagCheck(allStructureTypes); }
/// <summary> /// Populate the nomenclature dictionaries based on the given type, which inherits /// from Structure. This method is automatically called by the AssemblyWalkAttribute /// </summary> /// <param name="t">A type inheriting from Structure</param> public static void PopulateType(Type t) { object[] attribs = t.GetCustomAttributes(typeof(KOSNomenclatureAttribute), false); foreach (object obj in attribs) { KOSNomenclatureAttribute attrib = obj as KOSNomenclatureAttribute; if (attrib == null) { continue; // hypothetically impossible since GetCustomAttributes explicitly asked for only attributes of this type. } try { if (attrib.CSharpToKOS) { cSharpToKosMap.Add(t, attrib.KOSName); } } catch (ArgumentException) { // There can be a many-to-one map (given two different C# types, they both return the same KOS type), but // not a one-to-many map (given one C# type, it has two kOS types it tries to return). string msg = "kOS developer error: name clash in KOSNomenclature: two mappings from C# class " + t.FullName + " found."; Debug.AddNagMessage(Debug.NagType.NAGFOREVER, msg); } try { if (attrib.KOSToCSharp) { kosToCSharpMap.Add(attrib.KOSName, t); } } catch (ArgumentException) { // There can be a many-to-one map (given two different kos types, they both return the same C# type), but // not a one-to-many map (given one kos type, it has two C# types it tries to return). string msg = "kOS developer error: name clash in KOSNomenclature: two mappings from KOS name " + attrib.KOSName + " found."; Debug.AddNagMessage(Debug.NagType.NAGFOREVER, msg); } } NagCheck(t); }
public static void WalkAssembly(Assembly assembly) { foreach (Type type in assembly.GetTypes()) { foreach (AssemblyWalkAttribute walkAttribute in AllWalkAttributes.Keys) { if (!string.IsNullOrEmpty(walkAttribute.StaticRegisterMethod)) { Type managerType = AllWalkAttributes[walkAttribute]; var managerRegisterMethod = managerType.GetMethod(walkAttribute.StaticRegisterMethod, BindingFlags.Static | BindingFlags.Public); if (managerRegisterMethod != null) { if (walkAttribute.AttributeType != null) { var attr = type.GetCustomAttributes(walkAttribute.AttributeType, false).FirstOrDefault(); if (attr != null) { if (walkAttribute.InterfaceType != null) { bool isInterface = !type.IsInterface && type.GetInterfaces().Contains(walkAttribute.InterfaceType); if (isInterface) { managerRegisterMethod.Invoke(null, new[] { attr, type }); walkAttribute.LoadedCount++; } else { string message = string.Format("Attribute {0} found on type {1}, but type does not implement the required interface {2}", walkAttribute.AttributeType.Name, type.Name, walkAttribute.InterfaceType.Name); SafeHouse.Logger.LogError(message); Debug.AddNagMessage(Debug.NagType.NAGONCE, message); } } else if (walkAttribute.InherritedType != null) { if (walkAttribute.InherritedType.IsAssignableFrom(type)) { managerRegisterMethod.Invoke(null, new[] { attr, type }); walkAttribute.LoadedCount++; } else { string message = string.Format("Attribute {0} found on type {1}, but type does not inherrit from the required type {2}", walkAttribute.AttributeType.Name, type.Name, walkAttribute.InherritedType.Name); SafeHouse.Logger.LogError(message); } } else { managerRegisterMethod.Invoke(null, new[] { attr, type }); walkAttribute.LoadedCount++; } } } else if (walkAttribute.InterfaceType != null) { bool isInterface = !type.IsInterface && type.GetInterfaces().Contains(walkAttribute.InterfaceType); if (isInterface) { managerRegisterMethod.Invoke(null, new[] { type }); walkAttribute.LoadedCount++; } } else if (walkAttribute.InherritedType != null) { if (walkAttribute.InherritedType.IsAssignableFrom(type)) { managerRegisterMethod.Invoke(null, new[] { type }); walkAttribute.LoadedCount++; } } } } } } }
public static void LoadWalkAttribute(Assembly assembly) { foreach (Type type in assembly.GetTypes()) { var attr = type.GetCustomAttributes(typeof(AssemblyWalkAttribute), true).FirstOrDefault() as AssemblyWalkAttribute; if (attr != null) { SafeHouse.Logger.LogWarning(string.Format("Found attribute on type {0}", type.Name)); if (!string.IsNullOrEmpty(attr.StaticRegisterMethod)) { if (attr.AttributeType != null) { // the register method should support parameters of <AttributeType> and Type if (CheckMethodParameters(type, attr.StaticRegisterMethod, attr.AttributeType, typeof(Type))) { AllWalkAttributes.Add(attr, type); SafeHouse.Logger.SuperVerbose(string.Format("Add attribute on type {0}", type.Name)); } else { string message = string.Format("Found AssemblyWalkAttribute on type {0} but the specified StaticRegisterMethod does not accept parameters of types {1} and Type", type.Name, attr.AttributeType.Name); SafeHouse.Logger.LogError(message); Debug.AddNagMessage(Debug.NagType.NAGFOREVER, message); } } else if (attr.InherritedType != null || attr.InterfaceType != null) { // the register method should support only a parameter of Type if (CheckMethodParameters(type, attr.StaticRegisterMethod, typeof(Type))) { AllWalkAttributes.Add(attr, type); SafeHouse.Logger.SuperVerbose(string.Format("Add attribute on type {0}", type.Name)); } else { string message = string.Format("Found AssemblyWalkAttribute on type {0} but the specified StaticRegisterMethod does not accept parameters of type Type", type.Name); SafeHouse.Logger.LogError(message); Debug.AddNagMessage(Debug.NagType.NAGFOREVER, message); } } } else if (!string.IsNullOrEmpty(attr.StaticWalkMethod)) { // the static walk method should accept no parameters if (CheckMethodParameters(type, attr.StaticWalkMethod)) { AllWalkAttributes.Add(attr, type); SafeHouse.Logger.SuperVerbose(string.Format("Add attribute on type {0}", type.Name)); } else { string message = string.Format("Found AssemblyWalkAttribute on type {0} but the specified StaticWalkMethod does not accept zero parameters", type.Name, attr.AttributeType.Name); SafeHouse.Logger.LogError(message); Debug.AddNagMessage(Debug.NagType.NAGFOREVER, message); } } else { string message = string.Format("Found AssemblyWalkAttribute on type {0} but neither StaticRegisterMethod nor StaticWalkMethod are specified", type.Name); SafeHouse.Logger.LogError(message); Debug.AddNagMessage(Debug.NagType.NAGFOREVER, message); } } } }