diff --git a/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj b/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj index f0b0404..6bdd40e 100644 --- a/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj +++ b/AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj @@ -24,7 +24,7 @@ MIT True latest-Recommended - 5.2.6 + 5.3.0 README.md true 1701;1702;NU5128 diff --git a/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs b/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs index 258134e..27cd54f 100644 --- a/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs +++ b/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -16,9 +17,8 @@ ClassDeclarationSyntax classSyntax /// to the containing namespace of the type symbol. /// public string NamespaceName { get; } = - PrepareValue( + PrepareNamespaceName( generationAttribute, - AutomaticInterfaceGenerator.NamespaceParameterName, typeSymbol.ContainingNamespace.ToDisplayString() ); @@ -78,4 +78,19 @@ private static T PrepareValue(AttributeData? generationAttribute, string key, return defaultValue; } + + private static string PrepareNamespaceName(AttributeData? generationAttribute, string containingNamespaceName) + { + var namespacePattern = PrepareValue( + generationAttribute, + AutomaticInterfaceGenerator.NamespaceParameterName, + containingNamespaceName + ); + + Debug.Assert(namespacePattern != null); + + var namespaceName = namespacePattern!.Replace("*", containingNamespaceName); + + return namespaceName; + } } diff --git a/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs b/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs index 66e0126..beee03f 100644 --- a/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs +++ b/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs @@ -32,7 +32,7 @@ internal sealed class {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attrib /// /// Use source generator to automatically create a Interface from this class /// - /// Namespace name for the generated interface. Defaults to the same namespace as the class. + /// Namespace name for the generated interface. Defaults to the same namespace as the class. The '*' character may be used as a placeholder for the containing type's namespace, allowing you to specify only a prefix for the target namespace instead of its full name. /// Interface name for the generated interface. Defaults to an interface version of the class name, e.g ExampleClass -> IExampleClass. /// If true, the generated interface will be internal, otherwise public internal {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attribute(string {{AutomaticInterfaceGenerator.NamespaceParameterName}} = default(string), string {{AutomaticInterfaceGenerator.InterfaceParameterName}} = default(string), bool {{AutomaticInterfaceGenerator.AsInternalParameterName}} = false) { } diff --git a/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinBrackedNamespace.verified.txt b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinBrackedNamespace.verified.txt new file mode 100644 index 0000000..ae56a17 --- /dev/null +++ b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinBrackedNamespace.verified.txt @@ -0,0 +1,18 @@ +//-------------------------------------------------------------------------------------------------- +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//-------------------------------------------------------------------------------------------------- + +namespace AutomaticInterfaceExample.CustomNameSpaceSuffix +{ + [global::System.CodeDom.Compiler.GeneratedCode("AutomaticInterface", "")] + public partial interface IDemoClass + { + /// + int DemoMethod(); + + } +} diff --git a/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinFileNamespace.verified.txt b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinFileNamespace.verified.txt new file mode 100644 index 0000000..ae56a17 --- /dev/null +++ b/AutomaticInterface/Tests/Misc/Misc.CustomNameSpaceWithWildcardWithinFileNamespace.verified.txt @@ -0,0 +1,18 @@ +//-------------------------------------------------------------------------------------------------- +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. +// +//-------------------------------------------------------------------------------------------------- + +namespace AutomaticInterfaceExample.CustomNameSpaceSuffix +{ + [global::System.CodeDom.Compiler.GeneratedCode("AutomaticInterface", "")] + public partial interface IDemoClass + { + /// + int DemoMethod(); + + } +} diff --git a/AutomaticInterface/Tests/Misc/Misc.cs b/AutomaticInterface/Tests/Misc/Misc.cs index d1b0677..a9ace1b 100644 --- a/AutomaticInterface/Tests/Misc/Misc.cs +++ b/AutomaticInterface/Tests/Misc/Misc.cs @@ -365,6 +365,48 @@ class DemoClass await Verify(Infrastructure.GenerateCode(code)); } + + [Fact] + public async Task CustomNameSpaceWithWildcardWithinBrackedNamespace() + { + const string code = """ + + using AutomaticInterface; + + namespace AutomaticInterfaceExample + { + [GenerateAutomaticInterface("*.CustomNameSpaceSuffix")] + class DemoClass + { + public int DemoMethod() => 5; + } + } + + """; + + await Verify(Infrastructure.GenerateCode(code)); + } + + [Fact] + public async Task CustomNameSpaceWithWildcardWithinFileNamespace() + { + const string code = """ + + using AutomaticInterface; + + namespace AutomaticInterfaceExample; + + [GenerateAutomaticInterface("*.CustomNameSpaceSuffix")] + class DemoClass + { + public int DemoMethod() => 5; + } + + """; + + await Verify(Infrastructure.GenerateCode(code)); + } + [Fact] public async Task AsInternal() {