Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions AutomaticInterface/AutomaticInterface/Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ is not ClassDeclarationSyntax classSyntax
{
return string.Empty;
}
var namespaceName = GetNameSpace(typeSymbol);

var generationAttribute = GetGenerationAttribute(typeSymbol);
var namespaceName = GetNameSpace(typeSymbol, generationAttribute);
var asInternal = GetAsInternal(generationAttribute);
var interfaceName = $"I{classSyntax.GetClassName()}";

var interfaceGenerator = new InterfaceBuilder(namespaceName, interfaceName);
var interfaceGenerator = new InterfaceBuilder(namespaceName, interfaceName, asInternal);

interfaceGenerator.AddClassDocumentation(GetDocumentationForClass(classSyntax));
interfaceGenerator.AddGeneric(GetGeneric(classSyntax, namedTypeSymbol));
Expand All @@ -77,15 +78,18 @@ is not ClassDeclarationSyntax classSyntax
return generatedCode;
}

private static string GetNameSpace(ISymbol typeSymbol)
{
var generationAttribute = typeSymbol
.GetAttributes()
.FirstOrDefault(x =>
x.AttributeClass != null
&& x.AttributeClass.Name.Contains(AutomaticInterfaceGenerator.DefaultAttributeName)
);
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();
Expand All @@ -96,6 +100,18 @@ private static string GetNameSpace(ISymbol typeSymbol)
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(1).FirstOrDefault().Value;

return asInternal.GetValueOrDefault();
}

private static void AddMethodsToInterface(List<ISymbol> members, InterfaceBuilder codeGenerator)
Expand Down
4 changes: 2 additions & 2 deletions AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal sealed record MethodInfo(

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

public class InterfaceBuilder(string nameSpaceName, string interfaceName)
public class InterfaceBuilder(string nameSpaceName, string interfaceName, bool asInternal)
{
private const string Autogenerated = """
//--------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -104,7 +104,7 @@ public string Build()
cb.AppendLine(
"[global::System.CodeDom.Compiler.GeneratedCode(\"AutomaticInterface\", \"\")]"
);
cb.AppendLine($"public partial interface {interfaceName}{genericType}");
cb.AppendLine($"{(asInternal ? "internal" : "public")} partial interface {interfaceName}{genericType}");
cb.AppendLine("{");

cb.Indent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace AutomaticInterface
[AttributeUsage(AttributeTargets.Class)]
internal sealed class {{{AutomaticInterfaceGenerator.DefaultAttributeName}}}Attribute : Attribute
{
internal {{{AutomaticInterfaceGenerator.DefaultAttributeName}}}Attribute(string namespaceName = "") { }
internal {{{AutomaticInterfaceGenerator.DefaultAttributeName}}}Attribute(string namespaceName = "", bool asInternal = false) { }
}
}
""",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using AutomaticInterface;

namespace AutomaticInterfaceExample
{
/// <summary>
/// Class Documentation will be copied
/// </summary>
[GenerateAutomaticInterface(asInternal: true)]
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Major Code Smell",
"S1144:Unused private types or members should be removed",
Justification = "Demo class"
)]
public class DemoClass3 : IDemoClass3
{
/// <summary>
/// This is a test method
/// </summary>
public void Test() { }
}
}
20 changes: 20 additions & 0 deletions AutomaticInterface/Tests/Misc/Misc.AsInternal.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//--------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//--------------------------------------------------------------------------------------------------

#nullable enable
namespace AutomaticInterfaceExample
{
[global::System.CodeDom.Compiler.GeneratedCode("AutomaticInterface", "")]
internal partial interface IDemoClass
{
/// <inheritdoc cref="AutomaticInterfaceExample.DemoClass.AMethod(AutomaticInterfaceExample.DemoClass?, string)" />
string AMethod(global::AutomaticInterfaceExample.DemoClass? x, string y);

}
}
#nullable restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//--------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//--------------------------------------------------------------------------------------------------

#nullable enable
namespace AutomaticInterfaceExample
{
[global::System.CodeDom.Compiler.GeneratedCode("AutomaticInterface", "")]
public partial interface IDemoClass
{
/// <inheritdoc cref="AutomaticInterfaceExample.DemoClass.AMethod(AutomaticInterfaceExample.DemoClass?, string)" />
string AMethod(global::AutomaticInterfaceExample.DemoClass? x, string y);

}
}
#nullable restore
40 changes: 40 additions & 0 deletions AutomaticInterface/Tests/Misc/Misc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,44 @@ class DemoClass

await Verify(Infrastructure.GenerateCode(code));
}

[Fact]
public async Task AsInternal()
{
const string code = """

using AutomaticInterface;
namespace AutomaticInterfaceExample;
[GenerateAutomaticInterface(asInternal: true)]
public class DemoClass
{
public string AMethod(DemoClass? x, string y)
{
return "Ok";
}
}

""";
await Verify(Infrastructure.GenerateCode(code));
}

[Fact]
public async Task AsInternalExplicitFalse()
{
const string code = """

using AutomaticInterface;
namespace AutomaticInterfaceExample;
[GenerateAutomaticInterface(asInternal: false)]
public class DemoClass
{
public string AMethod(DemoClass? x, string y)
{
return "Ok";
}
}

""";
await Verify(Infrastructure.GenerateCode(code));
}
}