diff --git a/AutomaticInterface/AutomaticInterface/AutomaticInterfaceGenerator.cs b/AutomaticInterface/AutomaticInterface/AutomaticInterfaceGenerator.cs
index aa8a5b6..f147501 100644
--- a/AutomaticInterface/AutomaticInterface/AutomaticInterfaceGenerator.cs
+++ b/AutomaticInterface/AutomaticInterface/AutomaticInterfaceGenerator.cs
@@ -12,6 +12,7 @@ public class AutomaticInterfaceGenerator : IIncrementalGenerator
public const string IgnoreAutomaticInterfaceAttributeName = "IgnoreAutomaticInterface";
public const string NamespaceParameterName = "namespaceName";
public const string InterfaceParameterName = "interfaceName";
+ public const string AsInternalParameterName = "asInternal";
public void Initialize(IncrementalGeneratorInitializationContext context)
{
diff --git a/AutomaticInterface/AutomaticInterface/Builder.cs b/AutomaticInterface/AutomaticInterface/Builder.cs
index 840657b..4f67120 100644
--- a/AutomaticInterface/AutomaticInterface/Builder.cs
+++ b/AutomaticInterface/AutomaticInterface/Builder.cs
@@ -52,13 +52,12 @@ is not ClassDeclarationSyntax classSyntax
{
return string.Empty;
}
- var generationAttribute = GetGenerationAttribute(typeSymbol);
- var asInternal = GetAsInternal(generationAttribute);
+
var symbolDetails = GetSymbolDetails(typeSymbol, classSyntax);
var interfaceGenerator = new InterfaceBuilder(
symbolDetails.NamespaceName,
symbolDetails.InterfaceName,
- asInternal
+ symbolDetails.AccessLevel
);
interfaceGenerator.AddClassDocumentation(GetDocumentationForClass(classSyntax));
@@ -80,43 +79,6 @@ is not ClassDeclarationSyntax classSyntax
return generatedCode;
}
- private static AttributeData? GetGenerationAttribute(ISymbol typeSymbol)
- {
- return typeSymbol
- .GetAttributes()
- .FirstOrDefault(x =>
- x.AttributeClass != null
- && x.AttributeClass.Name.Contains(AutomaticInterfaceGenerator.DefaultAttributeName)
- );
- }
-
- private static string GetNameSpace(ISymbol typeSymbol, AttributeData? generationAttribute)
- {
- if (generationAttribute == null)
- {
- return typeSymbol.ContainingNamespace.ToDisplayString();
- }
-
- var customNs = generationAttribute.ConstructorArguments.FirstOrDefault().Value?.ToString();
-
- return string.IsNullOrWhiteSpace(customNs)
- ? typeSymbol.ContainingNamespace.ToDisplayString()
- : customNs!;
- }
-
- private static bool GetAsInternal(AttributeData? generationAttribute)
- {
- if (generationAttribute == null)
- {
- return false;
- }
-
- var asInternal = (bool?)
- generationAttribute.ConstructorArguments.Skip(2).FirstOrDefault().Value;
-
- return asInternal.GetValueOrDefault();
- }
-
private static GeneratedSymbolDetails GetSymbolDetails(
ITypeSymbol typeSymbol,
ClassDeclarationSyntax classSyntax
diff --git a/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs b/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs
index b0c63d9..258134e 100644
--- a/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs
+++ b/AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs
@@ -34,11 +34,31 @@ ClassDeclarationSyntax classSyntax
$"I{classSyntax.GetClassName()}"
);
- private static string PrepareValue(
- AttributeData? generationAttribute,
- string key,
- string defaultValue
- )
+ ///
+ /// Determines the access level for the generated interface.
+ /// This property is derived from the presence of
+ /// that, if set, defines the interface as `internal`. Otherwise, the interface defaults to `public`.
+ ///
+ public string AccessLevel { get; } =
+ PrepareValue(
+ generationAttribute,
+ AutomaticInterfaceGenerator.AsInternalParameterName,
+ false
+ )
+ ? "internal"
+ : "public";
+
+ ///
+ /// Prepares a value by retrieving it from an attribute's constructor arguments if available; otherwise, returns the provided default value.
+ ///
+ /// The type of the value to prepare.
+ /// The attribute data containing constructor arguments.
+ /// The key to identify the relevant parameter in the constructor arguments.
+ /// The default value to return if the attribute does not provide a value.
+ ///
+ /// The retrieved value from the attribute constructor's arguments, or the provided default value if the key is not found.
+ ///
+ private static T PrepareValue(AttributeData? generationAttribute, string key, T defaultValue)
{
var parameterSymbol = generationAttribute?.AttributeConstructor?.Parameters.SingleOrDefault(
x => x.Name == key
@@ -49,10 +69,10 @@ string defaultValue
var index = generationAttribute!.AttributeConstructor!.Parameters.IndexOf(
parameterSymbol
);
- var result = generationAttribute.ConstructorArguments[index].Value!.ToString();
- if (!string.IsNullOrWhiteSpace(result))
+ var result = generationAttribute.ConstructorArguments[index].Value;
+ if (result != null)
{
- return result;
+ return (T)result;
}
}
diff --git a/AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs b/AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs
index 654a129..fc46f1d 100644
--- a/AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs
+++ b/AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs
@@ -24,7 +24,7 @@ internal sealed record MethodInfo(
public record EventInfo(string Name, string Type, string Documentation);
- public class InterfaceBuilder(string nameSpaceName, string interfaceName, bool asInternal)
+ public class InterfaceBuilder(string nameSpaceName, string interfaceName, string accessLevel)
{
private const string Autogenerated = """
//--------------------------------------------------------------------------------------------------
@@ -104,7 +104,7 @@ public string Build()
cb.AppendLine(
"[global::System.CodeDom.Compiler.GeneratedCode(\"AutomaticInterface\", \"\")]"
);
- cb.AppendLine($"{(asInternal ? "internal" : "public")} partial interface {interfaceName}{genericType}");
+ cb.AppendLine($"{accessLevel} partial interface {interfaceName}{genericType}");
cb.AppendLine("{");
cb.Indent();
diff --git a/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs b/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs
index c10df77..90e0e37 100644
--- a/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs
+++ b/AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs
@@ -29,7 +29,7 @@ namespace AutomaticInterface
[AttributeUsage(AttributeTargets.Class)]
internal sealed class {{{AutomaticInterfaceGenerator.DefaultAttributeName}}}Attribute : Attribute
{
- internal {{{AutomaticInterfaceGenerator.DefaultAttributeName}}}Attribute(string {{{AutomaticInterfaceGenerator.NamespaceParameterName}}} = "", string {{{AutomaticInterfaceGenerator.InterfaceParameterName}}} = "", bool asInternal = false) { }
+ 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.cs b/AutomaticInterface/Tests/Misc/Misc.cs
index a49a7f3..d1b0677 100644
--- a/AutomaticInterface/Tests/Misc/Misc.cs
+++ b/AutomaticInterface/Tests/Misc/Misc.cs
@@ -366,8 +366,8 @@ class DemoClass
}
[Fact]
- public async Task AsInternal()
- {
+ public async Task AsInternal()
+ {
const string code = """
using AutomaticInterface;
@@ -381,13 +381,13 @@ public string AMethod(DemoClass? x, string y)
}
}
- """;
+ """;
await Verify(Infrastructure.GenerateCode(code));
- }
-
+ }
+
[Fact]
- public async Task AsInternalExplicitFalse()
- {
+ public async Task AsInternalExplicitFalse()
+ {
const string code = """
using AutomaticInterface;
@@ -401,7 +401,7 @@ public string AMethod(DemoClass? x, string y)
}
}
- """;
+ """;
await Verify(Infrastructure.GenerateCode(code));
}
}