diff --git a/src/MdDocs.ApiReference/Model/IndexerOverloadDocumentation.cs b/src/MdDocs.ApiReference/Model/IndexerOverloadDocumentation.cs index b0f6ec87..f6756596 100644 --- a/src/MdDocs.ApiReference/Model/IndexerOverloadDocumentation.cs +++ b/src/MdDocs.ApiReference/Model/IndexerOverloadDocumentation.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Grynwald.MdDocs.ApiReference.Model.XmlDocs; +using Grynwald.MdDocs.Common; using Mono.Cecil; namespace Grynwald.MdDocs.ApiReference.Model diff --git a/src/MdDocs.ApiReference/Model/MethodLikeOverloadDocumentation.cs b/src/MdDocs.ApiReference/Model/MethodLikeOverloadDocumentation.cs index 7b2668b8..516a9884 100644 --- a/src/MdDocs.ApiReference/Model/MethodLikeOverloadDocumentation.cs +++ b/src/MdDocs.ApiReference/Model/MethodLikeOverloadDocumentation.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Grynwald.MdDocs.ApiReference.Model.XmlDocs; +using Grynwald.MdDocs.Common; using Mono.Cecil; namespace Grynwald.MdDocs.ApiReference.Model diff --git a/src/MdDocs.ApiReference/Model/SimpleMemberDocumentation.cs b/src/MdDocs.ApiReference/Model/SimpleMemberDocumentation.cs index 490fd243..1172c1a3 100644 --- a/src/MdDocs.ApiReference/Model/SimpleMemberDocumentation.cs +++ b/src/MdDocs.ApiReference/Model/SimpleMemberDocumentation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Grynwald.MdDocs.ApiReference.Model.XmlDocs; +using Grynwald.MdDocs.Common; using Grynwald.Utilities.Collections; using Mono.Cecil; diff --git a/src/MdDocs.ApiReference/Model/TypeDocumentation.cs b/src/MdDocs.ApiReference/Model/TypeDocumentation.cs index cbf280c2..559d5474 100644 --- a/src/MdDocs.ApiReference/Model/TypeDocumentation.cs +++ b/src/MdDocs.ApiReference/Model/TypeDocumentation.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Grynwald.MdDocs.ApiReference.Model.XmlDocs; +using Grynwald.MdDocs.Common; using Grynwald.Utilities.Collections; using Microsoft.Extensions.Logging; using Mono.Cecil; diff --git a/src/MdDocs.ApiReference/Model/_Extensions/TypeDefinitionExtensions.cs b/src/MdDocs.ApiReference/Model/_Extensions/TypeDefinitionExtensions.cs index 97bdb2f1..f46c861e 100644 --- a/src/MdDocs.ApiReference/Model/_Extensions/TypeDefinitionExtensions.cs +++ b/src/MdDocs.ApiReference/Model/_Extensions/TypeDefinitionExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Grynwald.MdDocs.Common; using Grynwald.Utilities.Collections; using Mono.Cecil; @@ -98,13 +99,13 @@ public static IEnumerable GetCustomAttributes(this TypeDefiniti return type.CustomAttributes .Where(attribute => { - if (typeKind == TypeKind.Class && attribute.AttributeType.FullName == Constants.DefaultMemberAttributeFullName) + if (typeKind == TypeKind.Class && attribute.AttributeType.FullName == SystemTypeNames.DefaultMemberAttributeFullName) return false; - if (typeKind == TypeKind.Class && attribute.AttributeType.FullName == Constants.ExtensionAttributeFullName) + if (typeKind == TypeKind.Class && attribute.AttributeType.FullName == SystemTypeNames.ExtensionAttributeFullName) return false; - if (typeKind == TypeKind.Struct && attribute.AttributeType.FullName == Constants.IsReadOnlyAttributeFullName) + if (typeKind == TypeKind.Struct && attribute.AttributeType.FullName == SystemTypeNames.IsReadOnlyAttributeFullName) return false; if (!attribute.AttributeType.Resolve().IsPublic) diff --git a/src/MdDocs.ApiReference/Model/_Helpers/CSharpDefinitionFormatter.cs b/src/MdDocs.ApiReference/Model/_Helpers/CSharpDefinitionFormatter.cs index afe941b8..72aeba39 100644 --- a/src/MdDocs.ApiReference/Model/_Helpers/CSharpDefinitionFormatter.cs +++ b/src/MdDocs.ApiReference/Model/_Helpers/CSharpDefinitionFormatter.cs @@ -463,7 +463,7 @@ private static void AppendTypeModifiers(StringBuilder definitionBuilder, TypeDef break; case TypeKind.Struct: - if (type.CustomAttributes.Any(a => a.AttributeType.FullName == Constants.IsReadOnlyAttributeFullName)) + if (type.CustomAttributes.Any(a => a.AttributeType.FullName == SystemTypeNames.IsReadOnlyAttributeFullName)) { definitionBuilder.Append("readonly "); } @@ -477,7 +477,7 @@ private static void AppendBaseTypes(TypeDefinition type, TypeKind typeKind, Stri if (typeKind == TypeKind.Enum) { var underlyingType = type.Fields.Single(f => f.Name == "value__").FieldType; - if (underlyingType.FullName != Constants.Int32FullName) + if (underlyingType.FullName != SystemTypeNames.Int32FullName) { definitionBuilder.Append(" : "); definitionBuilder.Append(GetDisplayName(underlyingType)); @@ -488,8 +488,8 @@ private static void AppendBaseTypes(TypeDefinition type, TypeKind typeKind, Stri // get the default (implicit) base type: "object" for classes, "System.ValueType" for structs // if the base type is the default type, the base type will not be explicitly included in the definition var defaultBaseType = typeKind == TypeKind.Struct - ? Constants.ValueTypeFullName - : (typeKind == TypeKind.Class ? Constants.ObjectFullName : ""); + ? SystemTypeNames.ValueTypeFullName + : (typeKind == TypeKind.Class ? SystemTypeNames.ObjectFullName : ""); if (type.HasInterfaces) { @@ -594,7 +594,7 @@ private static string GetLiteral(TypeReference typeReference, object value) var typeDefinition = typeReference.Resolve(); // string => put in quotation marks - if (typeReference.FullName == Constants.StringFullName) + if (typeReference.FullName == SystemTypeNames.StringFullName) { if (value is null) { @@ -694,7 +694,7 @@ private static string GetLiteral(TypeReference typeReference, object value) } } - private static bool IsFlagsEnum(TypeDefinition type) => type.CustomAttributes.Any(a => a.AttributeType.FullName == Constants.FlagsAttributeFullName); + private static bool IsFlagsEnum(TypeDefinition type) => type.CustomAttributes.Any(a => a.AttributeType.FullName == SystemTypeNames.FlagsAttributeFullName); private static string GetDisplayName(TypeReference typeReference) { @@ -718,7 +718,7 @@ private static string GetDefinition(ParameterDefinition parameter) AppendCustomAttributes(definitionBuilder, parameter.GetCustomAttributes(), singleLine: true); // add "params" prefix if method allows multiple values - if (parameter.CustomAttributes.Any(a => a.AttributeType.FullName == Constants.ParamArrayAttributeFullName)) + if (parameter.CustomAttributes.Any(a => a.AttributeType.FullName == SystemTypeNames.ParamArrayAttributeFullName)) { definitionBuilder.Append("params "); } diff --git a/src/MdDocs.CommandLineHelp/Constants.cs b/src/MdDocs.CommandLineHelp/CommandLineParserTypeNames.cs similarity index 64% rename from src/MdDocs.CommandLineHelp/Constants.cs rename to src/MdDocs.CommandLineHelp/CommandLineParserTypeNames.cs index 097754d3..5db74577 100644 --- a/src/MdDocs.CommandLineHelp/Constants.cs +++ b/src/MdDocs.CommandLineHelp/CommandLineParserTypeNames.cs @@ -1,17 +1,15 @@ #pragma warning disable IDE1006 // Naming Styles: Ignore hint that const strings should be prefixed with 's_' as all these fields are public namespace Grynwald.MdDocs.CommandLineHelp { - internal static class Constants + /// + /// Defines constants for names of type names defined by the "CommandLineParser" library + /// + internal static class CommandLineParserTypeNames { public const string VerbAttributeFullName = "CommandLine.VerbAttribute"; public const string OptionAttributeFullName = "CommandLine.OptionAttribute"; public const string ValueAttributeFullName = "CommandLine.ValueAttribute"; public const string AssemblyUsageAttributeFullName = "CommandLine.Text.AssemblyUsageAttribute"; - - public const string AssemblyTitleAttributeFullName = "System.Reflection.AssemblyTitleAttribute"; - public const string AssemblyInformationalVersionAttribute = "System.Reflection.AssemblyInformationalVersionAttribute"; - - public const string BooleanFullName = "System.Boolean"; } } #pragma warning restore IDE1006 // Naming Styles diff --git a/src/MdDocs.CommandLineHelp/Grynwald.MdDocs.CommandLineHelp.csproj b/src/MdDocs.CommandLineHelp/Grynwald.MdDocs.CommandLineHelp.csproj index 840ce9c4..2cdf1cf9 100644 --- a/src/MdDocs.CommandLineHelp/Grynwald.MdDocs.CommandLineHelp.csproj +++ b/src/MdDocs.CommandLineHelp/Grynwald.MdDocs.CommandLineHelp.csproj @@ -23,4 +23,10 @@ + + + + + + diff --git a/src/MdDocs.CommandLineHelp/Model/_Application/ApplicationDocumentation.cs b/src/MdDocs.CommandLineHelp/Model/_Application/ApplicationDocumentation.cs index ac0a57b7..7255497c 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Application/ApplicationDocumentation.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Application/ApplicationDocumentation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Grynwald.MdDocs.Common; using Grynwald.MdDocs.Common.Model; using Microsoft.Extensions.Logging; using Mono.Cecil; @@ -36,14 +37,14 @@ public static ApplicationDocumentation FromAssemblyFile(string filePath, ILogger { var types = definition.MainModule.Types.Where(x => !x.IsAbstract); - if (types.Any(x => x.HasAttribute(Constants.VerbAttributeFullName))) + if (types.Any(x => x.HasAttribute(CommandLineParserTypeNames.VerbAttributeFullName))) { - logger.LogInformation($"Found a class attributed with '{Constants.VerbAttributeFullName}'. Assuming application has sub-commands"); + logger.LogInformation($"Found a class attributed with '{CommandLineParserTypeNames.VerbAttributeFullName}'. Assuming application has sub-commands"); return MultiCommandApplicationDocumentation.FromAssemblyDefinition(definition, logger); } else { - logger.LogInformation($"Found *no* class attributed with '{Constants.VerbAttributeFullName}'. Assuming application without sub-commands"); + logger.LogInformation($"Found *no* class attributed with '{CommandLineParserTypeNames.VerbAttributeFullName}'. Assuming application without sub-commands"); return SingleCommandApplicationDocumentation.FromAssemblyDefinition(definition, logger); } } @@ -53,7 +54,7 @@ public static ApplicationDocumentation FromAssemblyFile(string filePath, ILogger protected static string LoadApplicationName(AssemblyDefinition definition) { var name = definition - .GetAttributeOrDefault(Constants.AssemblyTitleAttributeFullName) + .GetAttributeOrDefault(SystemTypeNames.AssemblyTitleAttributeFullName) ?.ConstructorArguments?.Single().Value as string; if (name == null || String.IsNullOrEmpty(name)) @@ -68,7 +69,7 @@ protected static string LoadApplicationName(AssemblyDefinition definition) protected static string? LoadApplicationVersion(AssemblyDefinition definition) { var version = definition - .GetAttributeOrDefault(Constants.AssemblyInformationalVersionAttribute) + .GetAttributeOrDefault(SystemTypeNames.AssemblyInformationalVersionAttribute) ?.ConstructorArguments.Single().Value as string; if (String.IsNullOrEmpty(version)) @@ -82,7 +83,7 @@ protected static string LoadApplicationName(AssemblyDefinition definition) protected static IReadOnlyList LoadAssemblyUsage(AssemblyDefinition definition) { - var assemblyUsageAttribute = definition.GetAttributeOrDefault(Constants.AssemblyUsageAttributeFullName); + var assemblyUsageAttribute = definition.GetAttributeOrDefault(CommandLineParserTypeNames.AssemblyUsageAttributeFullName); return assemblyUsageAttribute == null ? Array.Empty() diff --git a/src/MdDocs.CommandLineHelp/Model/_Application/MultiCommandApplicationDocumentation.cs b/src/MdDocs.CommandLineHelp/Model/_Application/MultiCommandApplicationDocumentation.cs index aa360635..d2449592 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Application/MultiCommandApplicationDocumentation.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Application/MultiCommandApplicationDocumentation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Grynwald.MdDocs.Common; using Microsoft.Extensions.Logging; using Mono.Cecil; @@ -42,8 +43,8 @@ private IReadOnlyList LoadCommands(AssemblyDefinition defi { return definition.MainModule.Types .Where(x => !x.IsAbstract) - .WithAttribute(Constants.VerbAttributeFullName) - .Where(x => !x.GetAttribute(Constants.VerbAttributeFullName).GetPropertyValueOrDefault("Hidden")) + .WithAttribute(CommandLineParserTypeNames.VerbAttributeFullName) + .Where(x => !x.GetAttribute(CommandLineParserTypeNames.VerbAttributeFullName).GetPropertyValueOrDefault("Hidden")) .Select(type => CommandDocumentation.FromTypeDefinition(this, type, logger)) .ToArray(); } diff --git a/src/MdDocs.CommandLineHelp/Model/_Application/SingleCommandApplicationDocumentation.cs b/src/MdDocs.CommandLineHelp/Model/_Application/SingleCommandApplicationDocumentation.cs index 98e1c001..de8cdd8c 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Application/SingleCommandApplicationDocumentation.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Application/SingleCommandApplicationDocumentation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Grynwald.MdDocs.Common; using Microsoft.Extensions.Logging; using Mono.Cecil; @@ -38,7 +39,7 @@ private UnnamedCommandDocumentation LoadCommand(AssemblyDefinition definition, I { bool IsCommandLineParameter(PropertyDefinition property) { - return property.HasAttribute(Constants.OptionAttributeFullName) || property.HasAttribute(Constants.ValueAttributeFullName); + return property.HasAttribute(CommandLineParserTypeNames.OptionAttributeFullName) || property.HasAttribute(CommandLineParserTypeNames.ValueAttributeFullName); } // get all types with at least one property attributed as either [Option] or [Value] diff --git a/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentation.cs b/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentation.cs index 11418bc3..a3f1c3a7 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentation.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Grynwald.MdDocs.Common; using Microsoft.Extensions.Logging; using Mono.Cecil; @@ -43,7 +44,7 @@ public static CommandDocumentation FromTypeDefinition(MultiCommandApplicationDoc if (definition is null) throw new ArgumentNullException(nameof(definition)); - var verbAttribute = definition.GetAttribute(Constants.VerbAttributeFullName); + var verbAttribute = definition.GetAttribute(CommandLineParserTypeNames.VerbAttributeFullName); var name = (string)verbAttribute.ConstructorArguments.First(x => x.Type.FullName == "System.String").Value; diff --git a/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentationBase.cs b/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentationBase.cs index aa9154b5..99dfe93c 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentationBase.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Commands/CommandDocumentationBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Grynwald.MdDocs.Common; using Microsoft.Extensions.Logging; using Mono.Cecil; @@ -53,7 +54,7 @@ protected internal CommandDocumentationBase( protected static IReadOnlyList LoadOptions(TypeDefinition definition, ILogger logger) { return definition.GetAllProperties() - .WithAttribute(Constants.OptionAttributeFullName) + .WithAttribute(CommandLineParserTypeNames.OptionAttributeFullName) .Select(property => OptionDocumentation.FromPropertyDefinition(property, logger)) .Where(option => !option.Hidden) .ToArray(); @@ -62,7 +63,7 @@ protected static IReadOnlyList LoadOptions(TypeDefinition d protected static IReadOnlyList LoadValues(TypeDefinition definition, ILogger logger) { return definition.GetAllProperties() - .WithAttribute(Constants.ValueAttributeFullName) + .WithAttribute(CommandLineParserTypeNames.ValueAttributeFullName) .Select(property => ValueDocumentation.FromPropertyDefinition(property, logger)) .Where(value => !value.Hidden) .ToArray(); diff --git a/src/MdDocs.CommandLineHelp/Model/_Commands/UnnamedCommandDocumentation.cs b/src/MdDocs.CommandLineHelp/Model/_Commands/UnnamedCommandDocumentation.cs index 890f8077..321e8761 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Commands/UnnamedCommandDocumentation.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Commands/UnnamedCommandDocumentation.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Grynwald.MdDocs.Common; using Microsoft.Extensions.Logging; using Mono.Cecil; @@ -26,7 +27,7 @@ public static UnnamedCommandDocumentation FromTypeDefinition(ApplicationDocument throw new ArgumentNullException(nameof(definition)); // unnamed commands must not have a "verb" attribute - if (definition.HasAttribute(Constants.VerbAttributeFullName)) + if (definition.HasAttribute(CommandLineParserTypeNames.VerbAttributeFullName)) throw new ArgumentException("Cannot create unnamed command from type definition annotated with a Verb attribute", nameof(definition)); return new UnnamedCommandDocumentation(application, LoadOptions(definition, logger), LoadValues(definition, logger)); diff --git a/src/MdDocs.CommandLineHelp/Model/_Parameters/OptionDocumentation.cs b/src/MdDocs.CommandLineHelp/Model/_Parameters/OptionDocumentation.cs index ab656cd9..7ba23691 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Parameters/OptionDocumentation.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Parameters/OptionDocumentation.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Grynwald.MdDocs.Common; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Mono.Cecil; @@ -46,7 +47,7 @@ internal OptionDocumentation( } private OptionDocumentation(PropertyDefinition definition, ILogger logger) - : base(definition, definition.GetAttribute(Constants.OptionAttributeFullName)) + : base(definition, definition.GetAttribute(CommandLineParserTypeNames.OptionAttributeFullName)) { m_Logger = logger ?? throw new ArgumentNullException(nameof(logger)); @@ -55,7 +56,7 @@ private OptionDocumentation(PropertyDefinition definition, ILogger logger) // special handling for bool options: // bool options are treated as "switch" parameters that do not require a value to be passed in, // e.g. the option is set using "--option" not "--option true" - if (definition.PropertyType.FullName == Constants.BooleanFullName) + if (definition.PropertyType.FullName == SystemTypeNames.BooleanFullName) { IsSwitchParameter = true; @@ -92,7 +93,7 @@ public static OptionDocumentation FromPropertyDefinition(PropertyDefinition defi { string? name = default; char? shortName = default; - foreach (var arg in definition.GetAttribute(Constants.OptionAttributeFullName).ConstructorArguments) + foreach (var arg in definition.GetAttribute(CommandLineParserTypeNames.OptionAttributeFullName).ConstructorArguments) { if (arg.Type.FullName == typeof(string).FullName) { diff --git a/src/MdDocs.CommandLineHelp/Model/_Parameters/ValueDocumentation.cs b/src/MdDocs.CommandLineHelp/Model/_Parameters/ValueDocumentation.cs index 2a5a4f2f..9857b60e 100644 --- a/src/MdDocs.CommandLineHelp/Model/_Parameters/ValueDocumentation.cs +++ b/src/MdDocs.CommandLineHelp/Model/_Parameters/ValueDocumentation.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Grynwald.MdDocs.Common; using Microsoft.Extensions.Logging; using Mono.Cecil; @@ -28,9 +29,9 @@ internal ValueDocumentation( Name = name; } - private ValueDocumentation(PropertyDefinition property) : base(property, property.GetAttribute(Constants.ValueAttributeFullName)) + private ValueDocumentation(PropertyDefinition property) : base(property, property.GetAttribute(CommandLineParserTypeNames.ValueAttributeFullName)) { - var valueAttribute = property.GetAttribute(Constants.ValueAttributeFullName); + var valueAttribute = property.GetAttribute(CommandLineParserTypeNames.ValueAttributeFullName); Index = (int)valueAttribute.ConstructorArguments.Single().Value; Name = valueAttribute.GetPropertyValueOrDefault("MetaName"); diff --git a/src/MdDocs.CommandLineHelp/_Extensions/CustomAttributeProviderExtensions.cs b/src/MdDocs.CommandLineHelp/_Extensions/CustomAttributeProviderExtensions.cs deleted file mode 100644 index 6100ddd7..00000000 --- a/src/MdDocs.CommandLineHelp/_Extensions/CustomAttributeProviderExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Mono.Cecil; - -namespace Grynwald.MdDocs.CommandLineHelp -{ - internal static class CustomAttributeProviderExtensions - { - public static CustomAttribute GetAttribute(this ICustomAttributeProvider definition, string name) - { - return definition - .CustomAttributes - .Single(a => a.AttributeType.FullName == name); - } - - public static CustomAttribute GetAttributeOrDefault(this ICustomAttributeProvider definition, string name) - { - return definition - .CustomAttributes - .SingleOrDefault(a => a.AttributeType.FullName == name); - } - - public static bool HasAttribute(this ICustomAttributeProvider definiton, string name) - { - return definiton.CustomAttributes.Any(x => x.AttributeType.FullName == name); - } - - public static IEnumerable WithAttribute(this IEnumerable definitons, string name) where T : ICustomAttributeProvider - { - return definitons.Where(x => x.HasAttribute(name)); - } - } -} diff --git a/src/MdDocs.Common.Test/Grynwald.MdDocs.Common.Test.csproj b/src/MdDocs.Common.Test/Grynwald.MdDocs.Common.Test.csproj index f2207fc4..f9219a51 100644 --- a/src/MdDocs.Common.Test/Grynwald.MdDocs.Common.Test.csproj +++ b/src/MdDocs.Common.Test/Grynwald.MdDocs.Common.Test.csproj @@ -18,6 +18,7 @@ + \ No newline at end of file diff --git a/src/MdDocs.ApiReference.Test/Model/_Extensions/CustomAttributeProviderExtensionsTest.cs b/src/MdDocs.Common.Test/_Extensions/CustomAttributeProviderExtensionsTest.cs similarity index 95% rename from src/MdDocs.ApiReference.Test/Model/_Extensions/CustomAttributeProviderExtensionsTest.cs rename to src/MdDocs.Common.Test/_Extensions/CustomAttributeProviderExtensionsTest.cs index 2b546fb0..f1fff8dc 100644 --- a/src/MdDocs.ApiReference.Test/Model/_Extensions/CustomAttributeProviderExtensionsTest.cs +++ b/src/MdDocs.Common.Test/_Extensions/CustomAttributeProviderExtensionsTest.cs @@ -1,9 +1,8 @@ using System.Linq; -using Grynwald.MdDocs.ApiReference.Model; using Grynwald.MdDocs.TestHelpers; using Xunit; -namespace Grynwald.MdDocs.ApiReference.Test.Model +namespace Grynwald.MdDocs.Common.Test { public class CustomAttributeProviderExtensionsTest : DynamicCompilationTestBase { diff --git a/src/MdDocs.Common/Grynwald.MdDocs.Common.csproj b/src/MdDocs.Common/Grynwald.MdDocs.Common.csproj index 1badbcc1..d40f473d 100644 --- a/src/MdDocs.Common/Grynwald.MdDocs.Common.csproj +++ b/src/MdDocs.Common/Grynwald.MdDocs.Common.csproj @@ -29,5 +29,9 @@ <_Parameter1>Grynwald.MdDocs.Test - + + + + + diff --git a/src/MdDocs.ApiReference/Model/Constants.cs b/src/MdDocs.Common/SystemTypeNames.cs similarity index 53% rename from src/MdDocs.ApiReference/Model/Constants.cs rename to src/MdDocs.Common/SystemTypeNames.cs index 1ced0df1..ae24fa65 100644 --- a/src/MdDocs.ApiReference/Model/Constants.cs +++ b/src/MdDocs.Common/SystemTypeNames.cs @@ -1,17 +1,28 @@ -namespace Grynwald.MdDocs.ApiReference.Model +#pragma warning disable IDE1006 // Naming Styles: Ignore hint that const strings should be prefixed with 's_' as all these fields are public +namespace Grynwald.MdDocs.Common { - internal static class Constants + /// + /// Defines shared constants for names of .NET System types and attributes emitted by the compiler + /// + public static class SystemTypeNames { - public const string ExtensionAttributeFullName = "System.Runtime.CompilerServices.ExtensionAttribute"; + // Built-in types / types with special meaning in C# public const string StringFullName = "System.String"; - public const string FlagsAttributeFullName = "System.FlagsAttribute"; - public const string ObjectFullName = "System.Object"; public const string ValueTypeFullName = "System.ValueType"; + public const string ObjectFullName = "System.Object"; public const string EnumFullName = "System.Enum"; public const string Int32FullName = "System.Int32"; + public const string BooleanFullName = "System.Boolean"; + + // Common Attribute types + public const string ExtensionAttributeFullName = "System.Runtime.CompilerServices.ExtensionAttribute"; + public const string FlagsAttributeFullName = "System.FlagsAttribute"; public const string DefaultMemberAttributeFullName = "System.Reflection.DefaultMemberAttribute"; public const string IsReadOnlyAttributeFullName = "System.Runtime.CompilerServices.IsReadOnlyAttribute"; public const string ObsoleteAttributeFullName = "System.ObsoleteAttribute"; public const string ParamArrayAttributeFullName = "System.ParamArrayAttribute"; + public const string AssemblyTitleAttributeFullName = "System.Reflection.AssemblyTitleAttribute"; + public const string AssemblyInformationalVersionAttribute = "System.Reflection.AssemblyInformationalVersionAttribute"; } } +#pragma warning restore IDE1006 // Naming Styles diff --git a/src/MdDocs.Common/_Extensions/TypeDefinitionExtensions.cs b/src/MdDocs.Common/_Extensions/TypeDefinitionExtensions.cs deleted file mode 100644 index 7fe95553..00000000 --- a/src/MdDocs.Common/_Extensions/TypeDefinitionExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Linq; -using Mono.Cecil; - -namespace Grynwald.MdDocs.Common -{ - public static class TypeDefinitionExtensions - { - public static (string name, long value)[] GetEnumValues(this TypeDefinition type) - { - if (!type.IsEnum) - throw new InvalidOperationException($"Type '{type.FullName}' is not a enum"); - - return type.Fields - .Where(f => f.IsPublic && !f.IsSpecialName) - .Select(f => (f.Name, Convert.ToInt64(f.Constant))) - .ToArray(); - } - } -} diff --git a/src/MdDocs.CommandLineHelp/_Extensions/CustomAttributeExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/CustomAttributeExtensions.cs similarity index 82% rename from src/MdDocs.CommandLineHelp/_Extensions/CustomAttributeExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/CustomAttributeExtensions.cs index 8eba10ce..9f9e3f15 100644 --- a/src/MdDocs.CommandLineHelp/_Extensions/CustomAttributeExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/CustomAttributeExtensions.cs @@ -1,11 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Text; using Mono.Cecil; -namespace Grynwald.MdDocs.CommandLineHelp +namespace Grynwald.MdDocs.Common { public static class CustomAttributeExtensions { diff --git a/src/MdDocs.ApiReference/Model/_Extensions/CustomAttributeProviderExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/CustomAttributeProviderExtensions.cs similarity index 57% rename from src/MdDocs.ApiReference/Model/_Extensions/CustomAttributeProviderExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/CustomAttributeProviderExtensions.cs index c65370ee..8783c68c 100644 --- a/src/MdDocs.ApiReference/Model/_Extensions/CustomAttributeProviderExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/CustomAttributeProviderExtensions.cs @@ -1,13 +1,13 @@ -using System.Diagnostics.CodeAnalysis; +using System.Collections.Generic; using System.Linq; using Mono.Cecil; -namespace Grynwald.MdDocs.ApiReference.Model +namespace Grynwald.MdDocs.Common { /// /// Extensions methods for . /// - internal static class CustomAttributeProviderExtensions + public static class CustomAttributeProviderExtensions { /// /// Determines whether the specified member is an extension. @@ -15,7 +15,7 @@ internal static class CustomAttributeProviderExtensions /// The member to check. /// Returns true if the member is an extension (i.e. has the System.Runtime.CompilerServices.ExtensionAttribute attribute). public static bool IsExtension(this ICustomAttributeProvider member) => - member.CustomAttributes.Any(x => x.AttributeType.FullName == Constants.ExtensionAttributeFullName); + member.CustomAttributes.Any(x => x.AttributeType.FullName == SystemTypeNames.ExtensionAttributeFullName); /// /// Checks whether the specified member is obsolete. @@ -25,7 +25,7 @@ public static bool IsExtension(this ICustomAttributeProvider member) => /// Returns true if the member has been marked as obsolete using the System.ObsoleteAttribute attribute. public static bool IsObsolete(this ICustomAttributeProvider member, out string? message) { - var obsoleteAttribute = member.CustomAttributes.SingleOrDefault(x => x.AttributeType.FullName == Constants.ObsoleteAttributeFullName); + var obsoleteAttribute = member.CustomAttributes.SingleOrDefault(x => x.AttributeType.FullName == SystemTypeNames.ObsoleteAttributeFullName); if (obsoleteAttribute == null) { @@ -38,5 +38,30 @@ public static bool IsObsolete(this ICustomAttributeProvider member, out string? return true; } } + + + public static CustomAttribute GetAttribute(this ICustomAttributeProvider definition, string name) + { + return definition + .CustomAttributes + .Single(a => a.AttributeType.FullName == name); + } + + public static CustomAttribute GetAttributeOrDefault(this ICustomAttributeProvider definition, string name) + { + return definition + .CustomAttributes + .SingleOrDefault(a => a.AttributeType.FullName == name); + } + + public static bool HasAttribute(this ICustomAttributeProvider definiton, string name) + { + return definiton.CustomAttributes.Any(x => x.AttributeType.FullName == name); + } + + public static IEnumerable WithAttribute(this IEnumerable definitons, string name) where T : ICustomAttributeProvider + { + return definitons.Where(x => x.HasAttribute(name)); + } } } diff --git a/src/MdDocs.ApiReference/Model/_Extensions/EventDefinitionExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/EventDefinitionExtensions.cs similarity index 95% rename from src/MdDocs.ApiReference/Model/_Extensions/EventDefinitionExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/EventDefinitionExtensions.cs index e9d6717d..f2170cd8 100644 --- a/src/MdDocs.ApiReference/Model/_Extensions/EventDefinitionExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/EventDefinitionExtensions.cs @@ -2,7 +2,7 @@ using System.Linq; using Mono.Cecil; -namespace Grynwald.MdDocs.ApiReference.Model +namespace Grynwald.MdDocs.Common { public static class EventDefinitionExtensions { diff --git a/src/MdDocs.ApiReference/Model/_Extensions/FieldDefinitionExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/FieldDefinitionExtensions.cs similarity index 95% rename from src/MdDocs.ApiReference/Model/_Extensions/FieldDefinitionExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/FieldDefinitionExtensions.cs index 0bbc97e7..87edc474 100644 --- a/src/MdDocs.ApiReference/Model/_Extensions/FieldDefinitionExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/FieldDefinitionExtensions.cs @@ -2,7 +2,7 @@ using System.Linq; using Mono.Cecil; -namespace Grynwald.MdDocs.ApiReference.Model +namespace Grynwald.MdDocs.Common { public static class FieldDefinitionExtensions { diff --git a/src/MdDocs.ApiReference/Model/_Extensions/MethodDefinitionExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/MethodDefinitionExtensions.cs similarity index 82% rename from src/MdDocs.ApiReference/Model/_Extensions/MethodDefinitionExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/MethodDefinitionExtensions.cs index acc4a927..70548bc3 100644 --- a/src/MdDocs.ApiReference/Model/_Extensions/MethodDefinitionExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/MethodDefinitionExtensions.cs @@ -2,9 +2,9 @@ using System.Linq; using Mono.Cecil; -namespace Grynwald.MdDocs.ApiReference.Model +namespace Grynwald.MdDocs.Common { - internal static class MethodDefinitionExtensions + public static class MethodDefinitionExtensions { /// /// Gets a methods's public custom attributes excluding attributes emitted by the C# compiler not relevant for the user. @@ -21,7 +21,7 @@ public static IEnumerable GetCustomAttributes(this MethodDefini return parameter.CustomAttributes .Where(attribute => { - if (attribute.AttributeType.FullName == Constants.ExtensionAttributeFullName) + if (attribute.AttributeType.FullName == SystemTypeNames.ExtensionAttributeFullName) return false; if (!attribute.AttributeType.Resolve().IsPublic) diff --git a/src/MdDocs.ApiReference/Model/_Extensions/ParameterDefinitionExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/ParameterDefinitionExtensions.cs similarity index 77% rename from src/MdDocs.ApiReference/Model/_Extensions/ParameterDefinitionExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/ParameterDefinitionExtensions.cs index 76ba05f6..fd1a7afe 100644 --- a/src/MdDocs.ApiReference/Model/_Extensions/ParameterDefinitionExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/ParameterDefinitionExtensions.cs @@ -2,9 +2,9 @@ using System.Linq; using Mono.Cecil; -namespace Grynwald.MdDocs.ApiReference.Model +namespace Grynwald.MdDocs.Common { - internal static class ParameterDefinitionExtensions + public static class ParameterDefinitionExtensions { /// /// Gets a parameter's custom attributes excluding attributes emitted by the C# compiler not relevant for the user. @@ -22,10 +22,10 @@ public static IEnumerable GetCustomAttributes(this ParameterDef return parameter.CustomAttributes .Where(attribute => { - if (attribute.AttributeType.FullName == Constants.IsReadOnlyAttributeFullName) + if (attribute.AttributeType.FullName == SystemTypeNames.IsReadOnlyAttributeFullName) return false; - if (attribute.AttributeType.FullName == Constants.ParamArrayAttributeFullName) + if (attribute.AttributeType.FullName == SystemTypeNames.ParamArrayAttributeFullName) return false; if (!attribute.AttributeType.Resolve().IsPublic) diff --git a/src/MdDocs.ApiReference/Model/_Extensions/PropertyDefinitionExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/PropertyDefinitionExtensions.cs similarity index 95% rename from src/MdDocs.ApiReference/Model/_Extensions/PropertyDefinitionExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/PropertyDefinitionExtensions.cs index f9edcc1a..c09b65b4 100644 --- a/src/MdDocs.ApiReference/Model/_Extensions/PropertyDefinitionExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/PropertyDefinitionExtensions.cs @@ -2,7 +2,7 @@ using System.Linq; using Mono.Cecil; -namespace Grynwald.MdDocs.ApiReference.Model +namespace Grynwald.MdDocs.Common { public static class PropertyDefinitionExtensions { diff --git a/src/MdDocs.CommandLineHelp/_Extensions/TypeDefinitionExtensions.cs b/src/MdDocs.Common/_Extensions/_Cecil/TypeDefinitionExtensions.cs similarity index 59% rename from src/MdDocs.CommandLineHelp/_Extensions/TypeDefinitionExtensions.cs rename to src/MdDocs.Common/_Extensions/_Cecil/TypeDefinitionExtensions.cs index f660930e..7a54fbd3 100644 --- a/src/MdDocs.CommandLineHelp/_Extensions/TypeDefinitionExtensions.cs +++ b/src/MdDocs.Common/_Extensions/_Cecil/TypeDefinitionExtensions.cs @@ -1,11 +1,24 @@ using System; using System.Collections.Generic; +using System.Linq; using Mono.Cecil; -namespace Grynwald.MdDocs.CommandLineHelp +namespace Grynwald.MdDocs.Common { - internal static class TypeDefinitionExtensions + public static class TypeDefinitionExtensions { + public static (string name, long value)[] GetEnumValues(this TypeDefinition type) + { + if (!type.IsEnum) + throw new InvalidOperationException($"Type '{type.FullName}' is not a enum"); + + return type.Fields + .Where(f => f.IsPublic && !f.IsSpecialName) + .Select(f => (f.Name, Convert.ToInt64(f.Constant))) + .ToArray(); + } + + /// /// Gets all the type's properties including the properties defined in base classes. /// diff --git a/src/MdDocs.CommandLineHelp/Nullable.cs b/src/shared/Nullable.cs similarity index 100% rename from src/MdDocs.CommandLineHelp/Nullable.cs rename to src/shared/Nullable.cs