Skip to content

Commit 8fb7ec5

Browse files
Merge branch 'ChaseFlorell-users/CFlorell/task/cleanup_asInternal'
# Conflicts: # AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj # AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs # AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs # README.md
2 parents b2f551d + f4f1579 commit 8fb7ec5

7 files changed

Lines changed: 39 additions & 57 deletions

File tree

AutomaticInterface/AutomaticInterface/AutomaticInterface.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2525
<EnableNETAnalyzers>True</EnableNETAnalyzers>
2626
<AnalysisLevel>latest-Recommended</AnalysisLevel>
27-
<Version>5.2.2</Version>
27+
<Version>5.2.3</Version>
2828
<PackageReadmeFile>README.md</PackageReadmeFile>
2929
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
3030
<NoWarn>1701;1702;NU5128</NoWarn>

AutomaticInterface/AutomaticInterface/AutomaticInterfaceGenerator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class AutomaticInterfaceGenerator : IIncrementalGenerator
1212
public const string IgnoreAutomaticInterfaceAttributeName = "IgnoreAutomaticInterface";
1313
public const string NamespaceParameterName = "namespaceName";
1414
public const string InterfaceParameterName = "interfaceName";
15+
public const string AsInternalParameterName = "asInternal";
1516

1617
public void Initialize(IncrementalGeneratorInitializationContext context)
1718
{

AutomaticInterface/AutomaticInterface/Builder.cs

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ is not ClassDeclarationSyntax classSyntax
5050
{
5151
return string.Empty;
5252
}
53-
var generationAttribute = GetGenerationAttribute(typeSymbol);
54-
var asInternal = GetAsInternal(generationAttribute);
53+
5554
var symbolDetails = GetSymbolDetails(typeSymbol, classSyntax);
5655
var interfaceGenerator = new InterfaceBuilder(
5756
symbolDetails.NamespaceName,
5857
symbolDetails.InterfaceName,
59-
asInternal
58+
symbolDetails.AccessLevel
6059
);
6160

6261
interfaceGenerator.AddClassDocumentation(GetDocumentationForClass(classSyntax));
@@ -78,43 +77,6 @@ is not ClassDeclarationSyntax classSyntax
7877
return generatedCode;
7978
}
8079

81-
private static AttributeData? GetGenerationAttribute(ISymbol typeSymbol)
82-
{
83-
return typeSymbol
84-
.GetAttributes()
85-
.FirstOrDefault(x =>
86-
x.AttributeClass != null
87-
&& x.AttributeClass.Name.Contains(AutomaticInterfaceGenerator.DefaultAttributeName)
88-
);
89-
}
90-
91-
private static string GetNameSpace(ISymbol typeSymbol, AttributeData? generationAttribute)
92-
{
93-
if (generationAttribute == null)
94-
{
95-
return typeSymbol.ContainingNamespace.ToDisplayString();
96-
}
97-
98-
var customNs = generationAttribute.ConstructorArguments.FirstOrDefault().Value?.ToString();
99-
100-
return string.IsNullOrWhiteSpace(customNs)
101-
? typeSymbol.ContainingNamespace.ToDisplayString()
102-
: customNs!;
103-
}
104-
105-
private static bool GetAsInternal(AttributeData? generationAttribute)
106-
{
107-
if (generationAttribute == null)
108-
{
109-
return false;
110-
}
111-
112-
var asInternal = (bool?)
113-
generationAttribute.ConstructorArguments.Skip(2).FirstOrDefault().Value;
114-
115-
return asInternal.GetValueOrDefault();
116-
}
117-
11880
private static GeneratedSymbolDetails GetSymbolDetails(
11981
ITypeSymbol typeSymbol,
12082
ClassDeclarationSyntax classSyntax

AutomaticInterface/AutomaticInterface/GeneratedSymbolDetails.cs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,31 @@ ClassDeclarationSyntax classSyntax
3434
$"I{classSyntax.GetClassName()}"
3535
);
3636

37-
private static string PrepareValue(
38-
AttributeData? generationAttribute,
39-
string key,
40-
string defaultValue
41-
)
37+
/// <summary>
38+
/// Determines the access level for the generated interface.
39+
/// This property is derived from the presence of <see cref="AutomaticInterfaceGenerator.AsInternalParameterName"/>
40+
/// that, if set, defines the interface as `internal`. Otherwise, the interface defaults to `public`.
41+
/// </summary>
42+
public string AccessLevel { get; } =
43+
PrepareValue(
44+
generationAttribute,
45+
AutomaticInterfaceGenerator.AsInternalParameterName,
46+
false
47+
)
48+
? "internal"
49+
: "public";
50+
51+
/// <summary>
52+
/// Prepares a value by retrieving it from an attribute's constructor arguments if available; otherwise, returns the provided default value.
53+
/// </summary>
54+
/// <typeparam name="T">The type of the value to prepare.</typeparam>
55+
/// <param name="generationAttribute">The attribute data containing constructor arguments.</param>
56+
/// <param name="key">The key to identify the relevant parameter in the constructor arguments.</param>
57+
/// <param name="defaultValue">The default value to return if the attribute does not provide a value.</param>
58+
/// <returns>
59+
/// The retrieved value from the attribute constructor's arguments, or the provided default value if the key is not found.
60+
/// </returns>
61+
private static T PrepareValue<T>(AttributeData? generationAttribute, string key, T defaultValue)
4262
{
4363
var parameterSymbol = generationAttribute?.AttributeConstructor?.Parameters.SingleOrDefault(
4464
x => x.Name == key
@@ -49,10 +69,10 @@ string defaultValue
4969
var index = generationAttribute!.AttributeConstructor!.Parameters.IndexOf(
5070
parameterSymbol
5171
);
52-
var result = generationAttribute.ConstructorArguments[index].Value!.ToString();
53-
if (!string.IsNullOrWhiteSpace(result))
72+
var result = generationAttribute.ConstructorArguments[index].Value;
73+
if (result != null)
5474
{
55-
return result;
75+
return (T)result;
5676
}
5777
}
5878

AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal sealed record MethodInfo(
2424

2525
public record EventInfo(string Name, string Type, string Documentation);
2626

27-
public class InterfaceBuilder(string nameSpaceName, string interfaceName, bool asInternal)
27+
public class InterfaceBuilder(string nameSpaceName, string interfaceName, string accessLevel)
2828
{
2929
private const string Autogenerated = """
3030
//--------------------------------------------------------------------------------------------------
@@ -104,9 +104,7 @@ public string Build()
104104
cb.AppendLine(
105105
"[global::System.CodeDom.Compiler.GeneratedCode(\"AutomaticInterface\", \"\")]"
106106
);
107-
cb.AppendLine(
108-
$"{(asInternal ? "internal" : "public")} partial interface {interfaceName}{genericType}"
109-
);
107+
cb.AppendLine($"{accessLevel} partial interface {interfaceName}{genericType}");
110108
cb.AppendLine("{");
111109

112110
cb.Indent();

AutomaticInterface/AutomaticInterface/RegisterAttributesExtensions.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ namespace AutomaticInterface
2424
/// <summary>
2525
/// Use source generator to automatically create a Interface from this class
2626
/// </summary>
27-
/// <param name="namespaceName22">Namespace name for the generated interface. Defaults to the same namespace as the class.</param>
28-
/// <param name="interfaceName">Interface name for the generated interface. Defaults to an interface version of the class name, e.g ExampleClass -> IExampleClass.</param>
29-
/// <param name="asInternal">If true, the generated interface will be internal, otherwise public</param>
3027
[AttributeUsage(AttributeTargets.Class)]
3128
internal sealed class {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attribute : Attribute
3229
{
@@ -36,7 +33,7 @@ internal sealed class {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attrib
3633
/// <param name="namespaceName">Namespace name for the generated interface. Defaults to the same namespace as the class.</param>
3734
/// <param name="interfaceName">Interface name for the generated interface. Defaults to an interface version of the class name, e.g ExampleClass -> IExampleClass.</param>
3835
/// <param name="asInternal">If true, the generated interface will be internal, otherwise public</param>
39-
internal {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attribute(string {{AutomaticInterfaceGenerator.NamespaceParameterName}} = "", string {{AutomaticInterfaceGenerator.InterfaceParameterName}} = "", bool asInternal = false) { }
36+
internal {{AutomaticInterfaceGenerator.DefaultAttributeName}}Attribute(string {{AutomaticInterfaceGenerator.NamespaceParameterName}} = default(string), string {{AutomaticInterfaceGenerator.InterfaceParameterName}} = default(string), bool {{AutomaticInterfaceGenerator.AsInternalParameterName}} = false) { }
4037
}
4138
}
4239
""",

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ Note that we use [Verify](https://github.com/VerifyTests/Verify) for testing. It
188188

189189
## Changelog
190190

191+
### 5.2.3
192+
193+
- Refactor 'asInternal' logic to remove duplicate attribute lookup. Thanks ChaseFlorell!
194+
191195
### 5.2.2
192196

193197
- Smaller fixes to the Docstrings - warnings about missing xml comments should be fixed

0 commit comments

Comments
 (0)