From 9dd4f938dadcfd9cf6895b160105f94b7097f50e Mon Sep 17 00:00:00 2001 From: RoosterDragon Date: Tue, 28 Mar 2023 19:04:14 +0100 Subject: [PATCH] Cache reflection calls when running utility lints and commands. Reduces runtime of --check-yaml command to 70% of original. --- OpenRA.Game/Exts.cs | 17 ++++------ OpenRA.Game/IUtilityCommand.cs | 31 +++++++++++++++++++ .../Lint/CheckActorReferences.cs | 10 +++--- OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs | 6 ++-- OpenRA.Mods.Common/Lint/CheckConditions.cs | 19 +++++++----- OpenRA.Mods.Common/Lint/CheckCursors.cs | 4 +-- .../Lint/CheckLocomotorReferences.cs | 2 +- OpenRA.Mods.Common/Lint/CheckNotifications.cs | 6 ++-- OpenRA.Mods.Common/Lint/CheckPalettes.cs | 12 +++---- OpenRA.Mods.Common/Lint/CheckSequences.cs | 8 ++--- .../Lint/CheckSyncAnnotations.cs | 2 +- OpenRA.Mods.Common/Lint/CheckTraitLocation.cs | 2 +- .../Lint/CheckTranslationReference.cs | 8 ++--- .../Lint/CheckVoiceReferences.cs | 4 +-- .../CheckExplicitInterfacesCommand.cs | 2 +- .../UtilityCommands/CreateManPage.cs | 6 ++-- .../UtilityCommands/ExtractEmmyLuaAPI.cs | 12 +++---- .../UtilityCommands/ExtractLuaDocsCommand.cs | 20 ++++++------ .../ExtractSettingsDocsCommand.cs | 8 ++--- .../ExtractSpriteSequenceDocsCommand.cs | 4 +-- .../ExtractTraitDocsCommand.cs | 4 +-- .../ExtractWeaponDocsCommand.cs | 4 +-- .../ExtractZeroBraneStudioLuaAPI.cs | 10 +++--- OpenRA.Utility/Program.cs | 2 +- 24 files changed, 116 insertions(+), 87 deletions(-) diff --git a/OpenRA.Game/Exts.cs b/OpenRA.Game/Exts.cs index 566a361cd9..3f97b5446b 100644 --- a/OpenRA.Game/Exts.cs +++ b/OpenRA.Game/Exts.cs @@ -45,21 +45,16 @@ namespace OpenRA return a.GetTypes().Select(t => t.Namespace).Distinct().Where(n => n != null); } - public static bool HasAttribute(this MemberInfo mi) + public static bool HasAttribute(this MemberInfo mi) + where TAttribute : Attribute { - return Attribute.IsDefined(mi, typeof(T)); + return Attribute.IsDefined(mi, typeof(TAttribute)); } - public static T[] GetCustomAttributes(this MemberInfo mi, bool inherit) - where T : class + public static TAttribute[] GetCustomAttributes(this MemberInfo mi, bool inherit) + where TAttribute : Attribute { - return (T[])mi.GetCustomAttributes(typeof(T), inherit); - } - - public static T[] GetCustomAttributes(this ParameterInfo mi) - where T : class - { - return (T[])mi.GetCustomAttributes(typeof(T), true); + return (TAttribute[])mi.GetCustomAttributes(typeof(TAttribute), inherit); } public static T Clamp(this T val, T min, T max) where T : IComparable diff --git a/OpenRA.Game/IUtilityCommand.cs b/OpenRA.Game/IUtilityCommand.cs index 2ac0e72be3..32667b98a9 100644 --- a/OpenRA.Game/IUtilityCommand.cs +++ b/OpenRA.Game/IUtilityCommand.cs @@ -9,12 +9,43 @@ */ #endregion +using System; +using System.Reflection; +using OpenRA.Primitives; using OpenRA.Traits; namespace OpenRA { public class Utility { + static readonly ConcurrentCache TypeFields = + new ConcurrentCache(type => type.GetFields()); + + static readonly ConcurrentCache<(MemberInfo Member, Type AttributeType), bool> MemberHasAttribute = + new ConcurrentCache<(MemberInfo Member, Type AttributeType), bool>( + x => Attribute.IsDefined(x.Member, x.AttributeType)); + + static readonly ConcurrentCache<(MemberInfo Member, Type AttributeType, bool Inherit), object[]> MemberCustomAttributes = + new ConcurrentCache<(MemberInfo Member, Type AttributeType, bool Inherit), object[]>( + x => x.Member.GetCustomAttributes(x.AttributeType, x.Inherit)); + + public static FieldInfo[] GetFields(Type type) + { + return TypeFields[type]; + } + + public static bool HasAttribute(MemberInfo member) + where TAttribute : Attribute + { + return MemberHasAttribute[(member, typeof(TAttribute))]; + } + + public static TAttribute[] GetCustomAttributes(MemberInfo member, bool inherit) + where TAttribute : Attribute + { + return (TAttribute[])MemberCustomAttributes[(member, typeof(TAttribute), inherit)]; + } + public readonly ModData ModData; public readonly InstalledMods Mods; diff --git a/OpenRA.Mods.Common/Lint/CheckActorReferences.cs b/OpenRA.Mods.Common/Lint/CheckActorReferences.cs index ee8650080e..e962e8a389 100644 --- a/OpenRA.Mods.Common/Lint/CheckActorReferences.cs +++ b/OpenRA.Mods.Common/Lint/CheckActorReferences.cs @@ -39,16 +39,16 @@ namespace OpenRA.Mods.Common.Lint void CheckTrait(Action emitError, ActorInfo actorInfo, TraitInfo traitInfo, Ruleset rules) { var actualType = traitInfo.GetType(); - foreach (var field in actualType.GetFields()) + foreach (var field in Utility.GetFields(actualType)) { - if (field.HasAttribute()) + if (Utility.HasAttribute(field)) CheckActorReference(emitError, actorInfo, traitInfo, field, rules.Actors, - field.GetCustomAttributes(true)[0]); + Utility.GetCustomAttributes(field, true)[0]); - if (field.HasAttribute()) + if (Utility.HasAttribute(field)) CheckWeaponReference(emitError, actorInfo, traitInfo, field, rules.Weapons); - if (field.HasAttribute()) + if (Utility.HasAttribute(field)) CheckVoiceReference(emitError, actorInfo, traitInfo, field, rules.Voices); } } diff --git a/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs b/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs index 19155e1f51..da16b070d0 100644 --- a/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs +++ b/OpenRA.Mods.Common/Lint/CheckChromeHotkeys.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Lint // Build the list of widget keys to validate var checkWidgetFields = modData.ObjectCreator.GetTypesImplementing() - .SelectMany(w => w.GetFields() + .SelectMany(w => Utility.GetFields(w) .Where(f => f.FieldType == typeof(HotkeyReference)) .Select(f => (w.Name.Substring(0, w.Name.Length - 6), f.Name))) .ToArray(); @@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Lint foreach (var w in modData.ObjectCreator.GetTypesImplementing()) { - foreach (var m in w.GetMethods().Where(m => m.HasAttribute())) + foreach (var m in w.GetMethods().Where(m => Utility.HasAttribute(m))) { var p = m.GetParameters(); if (p.Length == 3 && p[0].ParameterType == typeof(MiniYamlNode) && p[1].ParameterType == typeof(Action) @@ -104,7 +104,7 @@ namespace OpenRA.Mods.Common.Lint if (type == null) continue; - checkArgKeys.AddRange(type.GetCustomAttributes(true).SelectMany(x => x.LogicArgKeys)); + checkArgKeys.AddRange(Utility.GetCustomAttributes(type, true).SelectMany(x => x.LogicArgKeys)); } foreach (var n in node.Value.Nodes) diff --git a/OpenRA.Mods.Common/Lint/CheckConditions.cs b/OpenRA.Mods.Common/Lint/CheckConditions.cs index a0f590637f..9cf7cb8f62 100644 --- a/OpenRA.Mods.Common/Lint/CheckConditions.cs +++ b/OpenRA.Mods.Common/Lint/CheckConditions.cs @@ -38,20 +38,23 @@ namespace OpenRA.Mods.Common.Lint foreach (var trait in actorInfo.Value.TraitInfos()) { - var fieldConsumed = trait.GetType().GetFields() - .Where(x => x.HasAttribute()) + var fields = Utility.GetFields(trait.GetType()); + var properties = trait.GetType().GetProperties(); + + var fieldConsumed = fields + .Where(x => Utility.HasAttribute(x)) .SelectMany(f => LintExts.GetFieldValues(trait, f)); - var propertyConsumed = trait.GetType().GetProperties() - .Where(x => x.HasAttribute()) + var propertyConsumed = properties + .Where(x => Utility.HasAttribute(x)) .SelectMany(p => LintExts.GetPropertyValues(trait, p)); - var fieldGranted = trait.GetType().GetFields() - .Where(x => x.HasAttribute()) + var fieldGranted = fields + .Where(x => Utility.HasAttribute(x)) .SelectMany(f => LintExts.GetFieldValues(trait, f)); - var propertyGranted = trait.GetType().GetProperties() - .Where(x => x.HasAttribute()) + var propertyGranted = properties + .Where(x => Utility.HasAttribute(x)) .SelectMany(f => LintExts.GetPropertyValues(trait, f)); foreach (var c in fieldConsumed.Concat(propertyConsumed)) diff --git a/OpenRA.Mods.Common/Lint/CheckCursors.cs b/OpenRA.Mods.Common/Lint/CheckCursors.cs index 13bdff450b..4b070d32f1 100644 --- a/OpenRA.Mods.Common/Lint/CheckCursors.cs +++ b/OpenRA.Mods.Common/Lint/CheckCursors.cs @@ -45,10 +45,10 @@ namespace OpenRA.Mods.Common.Lint { foreach (var traitInfo in actorInfo.Value.TraitInfos()) { - var fields = traitInfo.GetType().GetFields(); + var fields = Utility.GetFields(traitInfo.GetType()); foreach (var field in fields) { - var cursorReference = field.GetCustomAttributes(true).FirstOrDefault(); + var cursorReference = Utility.GetCustomAttributes(field, true).FirstOrDefault(); if (cursorReference == null) continue; diff --git a/OpenRA.Mods.Common/Lint/CheckLocomotorReferences.cs b/OpenRA.Mods.Common/Lint/CheckLocomotorReferences.cs index 1ee73b38ee..b1293f453c 100644 --- a/OpenRA.Mods.Common/Lint/CheckLocomotorReferences.cs +++ b/OpenRA.Mods.Common/Lint/CheckLocomotorReferences.cs @@ -42,7 +42,7 @@ namespace OpenRA.Mods.Common.Lint { foreach (var traitInfo in actorInfo.Value.TraitInfos()) { - var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute()); + var fields = Utility.GetFields(traitInfo.GetType()).Where(f => Utility.HasAttribute(f)); foreach (var field in fields) { var locomotors = LintExts.GetFieldValues(traitInfo, field); diff --git a/OpenRA.Mods.Common/Lint/CheckNotifications.cs b/OpenRA.Mods.Common/Lint/CheckNotifications.cs index 05a284bc65..486366a359 100644 --- a/OpenRA.Mods.Common/Lint/CheckNotifications.cs +++ b/OpenRA.Mods.Common/Lint/CheckNotifications.cs @@ -35,11 +35,11 @@ namespace OpenRA.Mods.Common.Lint { foreach (var traitInfo in actorInfo.Value.TraitInfos()) { - var fields = traitInfo.GetType().GetFields(); - foreach (var field in fields.Where(x => x.HasAttribute())) + var fields = Utility.GetFields(traitInfo.GetType()); + foreach (var field in fields.Where(x => Utility.HasAttribute(x))) { string type = null; - var notificationReference = field.GetCustomAttributes(true).First(); + var notificationReference = Utility.GetCustomAttributes(field, true).First(); if (!string.IsNullOrEmpty(notificationReference.NotificationTypeFieldName)) { var fieldInfo = fields.First(f => f.Name == notificationReference.NotificationTypeFieldName); diff --git a/OpenRA.Mods.Common/Lint/CheckPalettes.cs b/OpenRA.Mods.Common/Lint/CheckPalettes.cs index e894d3c0ab..851b789c97 100644 --- a/OpenRA.Mods.Common/Lint/CheckPalettes.cs +++ b/OpenRA.Mods.Common/Lint/CheckPalettes.cs @@ -39,10 +39,10 @@ namespace OpenRA.Mods.Common.Lint { foreach (var traitInfo in actorInfo.Value.TraitInfos()) { - var fields = traitInfo.GetType().GetFields(); + var fields = Utility.GetFields(traitInfo.GetType()); foreach (var field in fields) { - var paletteReference = field.GetCustomAttributes(true).FirstOrDefault(); + var paletteReference = Utility.GetCustomAttributes(field, true).FirstOrDefault(); if (paletteReference == null) continue; @@ -82,10 +82,10 @@ namespace OpenRA.Mods.Common.Lint if (projectileInfo == null) continue; - var fields = projectileInfo.GetType().GetFields(); + var fields = Utility.GetFields(projectileInfo.GetType()); foreach (var field in fields) { - var paletteReference = field.GetCustomAttributes(true).FirstOrDefault(); + var paletteReference = Utility.GetCustomAttributes(field, true).FirstOrDefault(); if (paletteReference == null) continue; @@ -126,10 +126,10 @@ namespace OpenRA.Mods.Common.Lint var tilesetPalettes = new List<(string Tileset, string PaletteName)>(); foreach (var traitInfo in worldActorInfo.TraitInfos()) { - var fields = traitInfo.GetType().GetFields(); + var fields = Utility.GetFields(traitInfo.GetType()); foreach (var field in fields) { - var paletteDefinition = field.GetCustomAttributes(true).FirstOrDefault(); + var paletteDefinition = Utility.GetCustomAttributes(field, true).FirstOrDefault(); if (paletteDefinition == null) continue; diff --git a/OpenRA.Mods.Common/Lint/CheckSequences.cs b/OpenRA.Mods.Common/Lint/CheckSequences.cs index 8292c0db60..deeb67f8c0 100644 --- a/OpenRA.Mods.Common/Lint/CheckSequences.cs +++ b/OpenRA.Mods.Common/Lint/CheckSequences.cs @@ -47,10 +47,10 @@ namespace OpenRA.Mods.Common.Lint var traitName = traitInfo.GetType().Name; traitName = traitName.Remove(traitName.Length - 4); - var fields = traitInfo.GetType().GetFields(); + var fields = Utility.GetFields(traitInfo.GetType()); foreach (var field in fields) { - var sequenceReference = field.GetCustomAttributes(true).FirstOrDefault(); + var sequenceReference = Utility.GetCustomAttributes(field, true).FirstOrDefault(); if (sequenceReference == null) continue; @@ -103,10 +103,10 @@ namespace OpenRA.Mods.Common.Lint if (projectileInfo == null) continue; - var fields = projectileInfo.GetType().GetFields(); + var fields = Utility.GetFields(projectileInfo.GetType()); foreach (var field in fields) { - var sequenceReference = field.GetCustomAttributes(true).FirstOrDefault(); + var sequenceReference = Utility.GetCustomAttributes(field, true).FirstOrDefault(); if (sequenceReference == null) continue; diff --git a/OpenRA.Mods.Common/Lint/CheckSyncAnnotations.cs b/OpenRA.Mods.Common/Lint/CheckSyncAnnotations.cs index 4fd5f5a6a6..78431e0b14 100644 --- a/OpenRA.Mods.Common/Lint/CheckSyncAnnotations.cs +++ b/OpenRA.Mods.Common/Lint/CheckSyncAnnotations.cs @@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Lint const BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly; while (type != null) { - if (((MemberInfo[])type.GetFields(Flags)).Concat(type.GetProperties(Flags)).Any(x => x.HasAttribute())) + if (((MemberInfo[])type.GetFields(Flags)).Concat(type.GetProperties(Flags)).Any(x => Utility.HasAttribute(x))) return true; type = type.BaseType; } diff --git a/OpenRA.Mods.Common/Lint/CheckTraitLocation.cs b/OpenRA.Mods.Common/Lint/CheckTraitLocation.cs index 2157b2a2b3..db459ba4b7 100644 --- a/OpenRA.Mods.Common/Lint/CheckTraitLocation.cs +++ b/OpenRA.Mods.Common/Lint/CheckTraitLocation.cs @@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Lint { foreach (var traitInfo in actorInfo.Value.TraitInfos()) { - var traitLocation = traitInfo.GetType().GetCustomAttributes(true).FirstOrDefault(); + var traitLocation = Utility.GetCustomAttributes(traitInfo.GetType(), true).FirstOrDefault(); if (traitLocation == null) continue; diff --git a/OpenRA.Mods.Common/Lint/CheckTranslationReference.cs b/OpenRA.Mods.Common/Lint/CheckTranslationReference.cs index 81191f1bc7..470cc81f42 100644 --- a/OpenRA.Mods.Common/Lint/CheckTranslationReference.cs +++ b/OpenRA.Mods.Common/Lint/CheckTranslationReference.cs @@ -39,10 +39,10 @@ namespace OpenRA.Mods.Common.Lint { foreach (var traitInfo in actorInfo.Value.TraitInfos()) { - var fields = traitInfo.GetType().GetFields(); + var fields = Utility.GetFields(traitInfo.GetType()); foreach (var field in fields) { - var translationReference = field.GetCustomAttributes(true).FirstOrDefault(); + var translationReference = Utility.GetCustomAttributes(field, true).FirstOrDefault(); if (translationReference == null) continue; @@ -72,7 +72,7 @@ namespace OpenRA.Mods.Common.Lint foreach (var modType in modData.ObjectCreator.GetTypes()) { - foreach (var fieldInfo in modType.GetFields(Binding).Where(m => m.HasAttribute())) + foreach (var fieldInfo in modType.GetFields(Binding).Where(m => Utility.HasAttribute(m))) { if (fieldInfo.FieldType != typeof(string)) emitError($"Translation attribute on non string field {fieldInfo.Name}."); @@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Lint if (!translation.HasMessage(key)) emitError($"{key} not present in {language} translation."); - var translationReference = fieldInfo.GetCustomAttributes(true)[0]; + var translationReference = Utility.GetCustomAttributes(fieldInfo, true)[0]; if (translationReference.RequiredVariableNames != null && translationReference.RequiredVariableNames.Length > 0) referencedVariablesPerKey.GetOrAdd(key, translationReference.RequiredVariableNames); diff --git a/OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs b/OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs index 57e6cd5ab0..b2ed921e38 100644 --- a/OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs +++ b/OpenRA.Mods.Common/Lint/CheckVoiceReferences.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.Common.Lint { foreach (var traitInfo in actorInfo.Value.TraitInfos()) { - var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute()); + var fields = Utility.GetFields(traitInfo.GetType()).Where(f => Utility.HasAttribute(f)); foreach (var field in fields) { var voiceSets = LintExts.GetFieldValues(traitInfo, field); @@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Lint foreach (var traitInfo in actorInfo.TraitInfos()) { - var fields = traitInfo.GetType().GetFields().Where(f => f.HasAttribute()); + var fields = Utility.GetFields(traitInfo.GetType()).Where(f => Utility.HasAttribute(f)); foreach (var field in fields) { var voices = LintExts.GetFieldValues(traitInfo, field); diff --git a/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs b/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs index d106400c3e..08070db7ed 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CheckExplicitInterfacesCommand.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.UtilityCommands var interfaces = implementingType.GetInterfaces(); foreach (var interfaceType in interfaces) { - if (!interfaceType.HasAttribute()) + if (!Utility.HasAttribute(interfaceType)) continue; var interfaceMembers = interfaceType.GetMembers(); diff --git a/OpenRA.Mods.Common/UtilityCommands/CreateManPage.cs b/OpenRA.Mods.Common/UtilityCommands/CreateManPage.cs index 4e61ddbfe1..2c6dc17086 100644 --- a/OpenRA.Mods.Common/UtilityCommands/CreateManPage.cs +++ b/OpenRA.Mods.Common/UtilityCommands/CreateManPage.cs @@ -41,10 +41,10 @@ namespace OpenRA.Mods.Common.UtilityCommands sections.Add("Launch", new LaunchArguments(new Arguments(Array.Empty()))); foreach (var section in sections.OrderBy(s => s.Key)) { - var fields = section.Value.GetType().GetFields(); + var fields = Utility.GetFields(section.Value.GetType()); foreach (var field in fields) { - if (!field.HasAttribute()) + if (!Utility.HasAttribute(field)) continue; Console.WriteLine(".TP"); @@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.UtilityCommands else Console.WriteLine(); - var lines = field.GetCustomAttributes(false).SelectMany(d => d.Lines); + var lines = Utility.GetCustomAttributes(field, false).SelectMany(d => d.Lines); foreach (var line in lines) Console.WriteLine(line); } diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractEmmyLuaAPI.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractEmmyLuaAPI.cs index 4faaa5292e..6473838b76 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractEmmyLuaAPI.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractEmmyLuaAPI.cs @@ -173,7 +173,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { foreach (var t in globalTables) { - var name = t.GetCustomAttributes(true).First().Name; + var name = Utility.GetCustomAttributes(t, true).First().Name; Console.WriteLine("---Global variable provided by the game scripting engine."); foreach (var obsolete in t.GetCustomAttributes(false).OfType()) @@ -191,9 +191,9 @@ namespace OpenRA.Mods.Common.UtilityCommands var body = ""; - if (member.HasAttribute()) + if (Utility.HasAttribute(member)) { - var lines = member.GetCustomAttributes(true).First().Lines; + var lines = Utility.GetCustomAttributes(member, true).First().Lines; foreach (var line in lines) Console.WriteLine($" --- {line}"); } @@ -258,11 +258,11 @@ namespace OpenRA.Mods.Common.UtilityCommands { Console.WriteLine(); - var isActivity = memberInfo.HasAttribute(); + var isActivity = Utility.HasAttribute(memberInfo); - if (memberInfo.HasAttribute()) + if (Utility.HasAttribute(memberInfo)) { - var lines = memberInfo.GetCustomAttributes(true).First().Lines; + var lines = Utility.GetCustomAttributes(memberInfo, true).First().Lines; foreach (var line in lines) Console.WriteLine($" --- {line}"); } diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs index b7179a8828..39641feb1c 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractLuaDocsCommand.cs @@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.UtilityCommands foreach (var t in tables) { - var name = t.GetCustomAttributes(true).First().Name; + var name = Utility.GetCustomAttributes(t, true).First().Name; var members = ScriptMemberWrapper.WrappableMembers(t); Console.WriteLine(); @@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.UtilityCommands Console.WriteLine("|---------:|-------------|"); foreach (var m in members.OrderBy(m => m.Name)) { - var desc = m.HasAttribute() ? m.GetCustomAttributes(true).First().Lines.JoinWith("
") : ""; + var desc = Utility.HasAttribute(m) ? Utility.GetCustomAttributes(m, true).First().Lines.JoinWith("
") : ""; Console.WriteLine($"| **{m.LuaDocString()}** | {desc} |"); } } @@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.UtilityCommands var actorCategories = utility.ModData.ObjectCreator.GetTypesImplementing().SelectMany(cg => { - var catAttr = cg.GetCustomAttributes(false).FirstOrDefault(); + var catAttr = Utility.GetCustomAttributes(cg, false).FirstOrDefault(); var category = catAttr != null ? catAttr.Category : "Unsorted"; var required = ScriptMemberWrapper.RequiredTraitNames(cg); @@ -106,9 +106,9 @@ namespace OpenRA.Mods.Common.UtilityCommands { var mi = property.mi; var required = property.required; - var hasDesc = mi.HasAttribute(); + var hasDesc = Utility.HasAttribute(mi); var hasRequires = required.Length > 0; - var isActivity = mi.HasAttribute(); + var isActivity = Utility.HasAttribute(mi); Console.Write($"| **{mi.LuaDocString()}**"); @@ -118,7 +118,7 @@ namespace OpenRA.Mods.Common.UtilityCommands Console.Write(" | "); if (hasDesc) - Console.Write(mi.GetCustomAttributes(false).First().Lines.JoinWith("
")); + Console.Write(Utility.GetCustomAttributes(mi, false).First().Lines.JoinWith("
")); if (hasDesc && hasRequires) Console.Write("
"); @@ -136,7 +136,7 @@ namespace OpenRA.Mods.Common.UtilityCommands var playerCategories = utility.ModData.ObjectCreator.GetTypesImplementing().SelectMany(cg => { - var catAttr = cg.GetCustomAttributes(false).FirstOrDefault(); + var catAttr = Utility.GetCustomAttributes(cg, false).FirstOrDefault(); var category = catAttr != null ? catAttr.Category : "Unsorted"; var required = ScriptMemberWrapper.RequiredTraitNames(cg); @@ -155,9 +155,9 @@ namespace OpenRA.Mods.Common.UtilityCommands { var mi = property.mi; var required = property.required; - var hasDesc = mi.HasAttribute(); + var hasDesc = Utility.HasAttribute(mi); var hasRequires = required.Length > 0; - var isActivity = mi.HasAttribute(); + var isActivity = Utility.HasAttribute(mi); Console.Write($"| **{mi.LuaDocString()}**"); @@ -167,7 +167,7 @@ namespace OpenRA.Mods.Common.UtilityCommands Console.Write(" | "); if (hasDesc) - Console.Write(mi.GetCustomAttributes(false).First().Lines.JoinWith("
")); + Console.Write(Utility.GetCustomAttributes(mi, false).First().Lines.JoinWith("
")); if (hasDesc && hasRequires) Console.Write("
"); diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs index 7bce492893..fa8d4a5792 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractSettingsDocsCommand.cs @@ -59,8 +59,8 @@ namespace OpenRA.Mods.Common.UtilityCommands sections.Add("Launch", new LaunchArguments(new Arguments(Array.Empty()))); foreach (var section in sections.OrderBy(s => s.Key)) { - var fields = section.Value.GetType().GetFields(); - if (fields.Any(field => field.GetCustomAttributes(false).Length > 0)) + var fields = Utility.GetFields(section.Value.GetType()); + if (fields.Any(field => Utility.GetCustomAttributes(field, false).Length > 0)) { Console.WriteLine($"## {section.Key}"); if (section.Key == "Launch") @@ -72,11 +72,11 @@ namespace OpenRA.Mods.Common.UtilityCommands foreach (var field in fields) { - if (!field.HasAttribute()) + if (!Utility.HasAttribute(field)) continue; Console.WriteLine($"### {field.Name}"); - var lines = field.GetCustomAttributes(false).SelectMany(d => d.Lines); + var lines = Utility.GetCustomAttributes(field, false).SelectMany(d => d.Lines); foreach (var line in lines) { Console.WriteLine(line); diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractSpriteSequenceDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractSpriteSequenceDocsCommand.cs index fb6e4f8812..86e220243d 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractSpriteSequenceDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractSpriteSequenceDocsCommand.cs @@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { type.Namespace, type.Name, - Description = string.Join(" ", type.GetCustomAttributes(false).SelectMany(d => d.Lines)), + Description = string.Join(" ", Utility.GetCustomAttributes(type, false).SelectMany(d => d.Lines)), InheritedTypes = type.BaseTypes() .Select(y => y.Name) .Where(y => y != type.Name && y != "Object"), @@ -64,7 +64,7 @@ namespace OpenRA.Mods.Common.UtilityCommands .Where(fi => fi.FieldType.IsGenericType && fi.FieldType.GetGenericTypeDefinition() == typeof(SpriteSequenceField<>)) .Select(fi => { - var description = string.Join(" ", fi.GetCustomAttributes(false) + var description = string.Join(" ", Utility.GetCustomAttributes(fi, false) .SelectMany(d => d.Lines)); var valueType = fi.FieldType.GetGenericArguments()[0]; diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs index 5298468242..c8d130e1d0 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractTraitDocsCommand.cs @@ -54,7 +54,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { type.Namespace, Name = type.Name.EndsWith("Info") ? type.Name.Substring(0, type.Name.Length - 4) : type.Name, - Description = string.Join(" ", type.GetCustomAttributes(false).SelectMany(d => d.Lines)), + Description = string.Join(" ", Utility.GetCustomAttributes(type, false).SelectMany(d => d.Lines)), RequiresTraits = RequiredTraitTypes(type) .Select(y => y.Name), InheritedTypes = type.BaseTypes() @@ -73,7 +73,7 @@ namespace OpenRA.Mods.Common.UtilityCommands DefaultValue = FieldSaver.SaveField(objectCreator.CreateBasic(type), fi.Field.Name).Value.Value, InternalType = Util.InternalTypeName(fi.Field.FieldType), UserFriendlyType = Util.FriendlyTypeName(fi.Field.FieldType), - Description = string.Join(" ", fi.Field.GetCustomAttributes(true).SelectMany(d => d.Lines)), + Description = string.Join(" ", Utility.GetCustomAttributes(fi.Field, true).SelectMany(d => d.Lines)), OtherAttributes = fi.Field.CustomAttributes .Where(a => a.AttributeType.Name != nameof(DescAttribute) && a.AttributeType.Name != nameof(FieldLoader.LoadUsingAttribute)) .Select(a => diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs index 4247cf03a5..a2a432ba3e 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractWeaponDocsCommand.cs @@ -59,7 +59,7 @@ namespace OpenRA.Mods.Common.UtilityCommands { type.Namespace, Name = type.Name.EndsWith("Info") ? type.Name.Substring(0, type.Name.Length - 4) : type.Name, - Description = string.Join(" ", type.GetCustomAttributes(false).SelectMany(d => d.Lines)), + Description = string.Join(" ", Utility.GetCustomAttributes(type, false).SelectMany(d => d.Lines)), InheritedTypes = type.BaseTypes() .Select(y => y.Name) .Where(y => y != type.Name && y != $"{type.Name}Info" && y != "Object"), @@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.UtilityCommands DefaultValue = FieldSaver.SaveField(objectCreator.CreateBasic(type), fi.Field.Name).Value.Value, InternalType = Util.InternalTypeName(fi.Field.FieldType), UserFriendlyType = Util.FriendlyTypeName(fi.Field.FieldType), - Description = string.Join(" ", fi.Field.GetCustomAttributes(true).SelectMany(d => d.Lines)), + Description = string.Join(" ", Utility.GetCustomAttributes(fi.Field, true).SelectMany(d => d.Lines)), OtherAttributes = fi.Field.CustomAttributes .Where(a => a.AttributeType.Name != nameof(DescAttribute) && a.AttributeType.Name != nameof(FieldLoader.LoadUsingAttribute)) .Select(a => diff --git a/OpenRA.Mods.Common/UtilityCommands/ExtractZeroBraneStudioLuaAPI.cs b/OpenRA.Mods.Common/UtilityCommands/ExtractZeroBraneStudioLuaAPI.cs index 3435f22d89..266b57fcc1 100644 --- a/OpenRA.Mods.Common/UtilityCommands/ExtractZeroBraneStudioLuaAPI.cs +++ b/OpenRA.Mods.Common/UtilityCommands/ExtractZeroBraneStudioLuaAPI.cs @@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.UtilityCommands var tables = utility.ModData.ObjectCreator.GetTypesImplementing().OrderBy(t => t.Name); foreach (var t in tables) { - var name = t.GetCustomAttributes(true).First().Name; + var name = Utility.GetCustomAttributes(t, true).First().Name; Console.WriteLine(" " + name + " = {"); Console.WriteLine(" type = \"class\","); Console.WriteLine(" childs = {"); @@ -64,9 +64,9 @@ namespace OpenRA.Mods.Common.UtilityCommands if (propertyInfo != null) Console.WriteLine(" type = \"value\","); - if (member.HasAttribute()) + if (Utility.HasAttribute(member)) { - var desc = member.GetCustomAttributes(true).First().Lines.JoinWith("\n"); + var desc = Utility.GetCustomAttributes(member, true).First().Lines.JoinWith("\n"); Console.WriteLine(" description = [[{0}]],", desc); } @@ -105,9 +105,9 @@ namespace OpenRA.Mods.Common.UtilityCommands if (propertyInfo != null) Console.WriteLine(" type = \"value\","); - if (property.HasAttribute()) + if (Utility.HasAttribute(property)) { - var desc = property.GetCustomAttributes(true).First().Lines.JoinWith("\n"); + var desc = Utility.GetCustomAttributes(property, true).First().Lines.JoinWith("\n"); Console.WriteLine(" description = [[{0}]],", desc); } diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index bcb4ac6a7e..d064b2b11e 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -162,7 +162,7 @@ namespace OpenRA static void GetActionUsage(string key, Action action) { - var descParts = action.Method.GetCustomAttributes(true) + var descParts = Utility.GetCustomAttributes(action.Method, true) .SelectMany(d => d.Lines).ToArray(); if (descParts.Length == 0)