Skip to content

Commit

Permalink
Fix generation when type is in global namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
Dreamescaper committed Jun 12, 2024
1 parent 7f5c34a commit ef4b25e
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 6 deletions.
16 changes: 16 additions & 0 deletions ServiceScan.SourceGenerator.Tests/AddServicesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,22 @@ public class InterfacelessService {}
Assert.Equal(Sources.GetMethodImplementation(registrations), results.GeneratedTrees[1].ToString());
}

[Fact]
public void DontGenerateAnythingIfTypeIsInvalid()
{
var attribute = $"[GenerateServiceRegistrations(AssignableTo = typeof(IWrongService))]";

var compilation = CreateCompilation(Sources.MethodWithAttribute(attribute));

var results = CSharpGeneratorDriver
.Create(_generator)
.RunGenerators(compilation)
.GetRunResult();

// One file for generated attribute itself.
Assert.Single(results.GeneratedTrees);
}

private static Compilation CreateCompilation(params string[] source)
{
var path = Path.GetDirectoryName(typeof(object).Assembly.Location)!;
Expand Down
39 changes: 39 additions & 0 deletions ServiceScan.SourceGenerator.Tests/GeneratedMethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,45 @@ private partial void AddServices( IServiceCollection services)
Assert.Equal(expected, results.GeneratedTrees[1].ToString());
}

[Fact]
public void MethodInGlobalNamespace()
{
var compilation = CreateCompilation(Services,
"""
using ServiceScan.SourceGenerator;
using Microsoft.Extensions.DependencyInjection;
using GeneratorTests;

public static partial class ServicesExtensions
{
[GenerateServiceRegistrations(AssignableTo = typeof(IService))]
public static partial IServiceCollection AddServices(this IServiceCollection services);
}
""");

var results = CSharpGeneratorDriver
.Create(_generator)
.RunGenerators(compilation)
.GetRunResult();

var expected = """
using Microsoft.Extensions.DependencyInjection;



public static partial class ServicesExtensions
{
public static partial IServiceCollection AddServices(this IServiceCollection services)
{
return services
.AddTransient<GeneratorTests.IService, GeneratorTests.MyService>();
}
}
""";

Assert.Equal(expected, results.GeneratedTrees[1].ToString());
}

private static Compilation CreateCompilation(params string[] source)
{
var path = Path.GetDirectoryName(typeof(object).Assembly.Location)!;
Expand Down
9 changes: 7 additions & 2 deletions ServiceScan.SourceGenerator/DependencyInjectionGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using ServiceScan.SourceGenerator.Model;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using ServiceScan.SourceGenerator.Model;
using static ServiceScan.SourceGenerator.DiagnosticDescriptors;

namespace ServiceScan.SourceGenerator;
Expand Down Expand Up @@ -56,10 +56,12 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
var returnType = method.ReturnsVoid ? "void" : "IServiceCollection";
var namespaceDeclaration = method.Namespace is null ? "" : $"namespace {method.Namespace};";
var source = $$"""
using Microsoft.Extensions.DependencyInjection;
namespace {{method.Namespace}};
{{namespaceDeclaration}}
{{method.TypeModifiers}} class {{method.TypeName}}
{
Expand Down Expand Up @@ -185,6 +187,9 @@ private static DiagnosticModel<MethodWithAttributesModel> ParseMethodModel(Gener

if (!attributeData[i].HasSearchCriteria)
return Diagnostic.Create(MissingSearchCriteria, attributeData[i].Location);

if (attributeData[i].HasErrors)
return null;
}

var model = MethodModel.Create(method, context.TargetNode);
Expand Down
7 changes: 5 additions & 2 deletions ServiceScan.SourceGenerator/Model/AttributeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ record AttributeModel(
string Lifetime,
string? TypeNameFilter,
bool AsImplementedInterfaces,
Location Location)
Location Location,
bool HasErrors)
{
public bool HasSearchCriteria => TypeNameFilter != null || AssignableToTypeName != null;

Expand Down Expand Up @@ -41,6 +42,8 @@ public static AttributeModel Create(AttributeData attribute)
var textSpan = attribute.ApplicationSyntaxReference.Span;
var location = Location.Create(syntax, textSpan);

return new(assignableToTypeName, assignableToGenericArguments, assemblyOfTypeName, lifetime, typeNameFilter, asImplementedInterfaces, location);
var hasError = assemblyType is { TypeKind: TypeKind.Error } || assignableTo is { TypeKind: TypeKind.Error };

return new(assignableToTypeName, assignableToGenericArguments, assemblyOfTypeName, lifetime, typeNameFilter, asImplementedInterfaces, location, hasError);
}
}
2 changes: 1 addition & 1 deletion ServiceScan.SourceGenerator/Model/MethodModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ record MethodModel(
public static MethodModel Create(IMethodSymbol method, SyntaxNode syntax)
{
return new MethodModel(
Namespace: method.ContainingNamespace.ToDisplayString(),
Namespace: method.ContainingNamespace.IsGlobalNamespace ? null : method.ContainingNamespace.ToDisplayString(),
TypeName: method.ContainingType.Name,
TypeMetadataName: method.ContainingType.ToFullMetadataName(),
TypeModifiers: GetModifiers(GetTypeSyntax(syntax)),
Expand Down
4 changes: 3 additions & 1 deletion ServiceScan.SourceGenerator/SymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public static class SymbolExtensions
{
public static string ToFullMetadataName(this ISymbol symbol)
{
return symbol.ContainingNamespace.ToDisplayString() + "." + symbol.MetadataName;
return symbol.ContainingNamespace.IsGlobalNamespace
? symbol.MetadataName
: symbol.ContainingNamespace.ToDisplayString() + "." + symbol.MetadataName;
}
}

0 comments on commit ef4b25e

Please sign in to comment.