diff --git a/src/EntityFrameworkCore.Projectables.Generator/ExpressionSyntaxRewriter.cs b/src/EntityFrameworkCore.Projectables.Generator/ExpressionSyntaxRewriter.cs index 5ada000..158b47c 100644 --- a/src/EntityFrameworkCore.Projectables.Generator/ExpressionSyntaxRewriter.cs +++ b/src/EntityFrameworkCore.Projectables.Generator/ExpressionSyntaxRewriter.cs @@ -49,17 +49,34 @@ namespace EntityFrameworkCore.Projectables.Generator { var symbolInfo = _semanticModel.GetSymbolInfo(node); - if (symbolInfo.Symbol is not null && symbolInfo.Symbol.Kind is SymbolKind.Property or SymbolKind.Method or SymbolKind.Field && SymbolEqualityComparer.Default.Equals(symbolInfo.Symbol.ContainingType, _targetTypeSymbol)) + if (symbolInfo.Symbol is not null) { - return SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, - SyntaxFactory.IdentifierName("@this"), - node - ); - } - else - { - return base.VisitIdentifierName(node); + if (symbolInfo.Symbol.Kind is SymbolKind.Property or SymbolKind.Method or SymbolKind.Field && SymbolEqualityComparer.Default.Equals(symbolInfo.Symbol.ContainingType, _targetTypeSymbol)) + { + return SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.IdentifierName("@this"), + node + ); + } + else if (symbolInfo.Symbol.Kind is SymbolKind.NamedType) + { + var typeInfo = _semanticModel.GetTypeInfo(node); + + if (typeInfo.Type is not null) + { + return SyntaxFactory.ParseTypeName( + typeInfo.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + ); + } + } } + + return base.VisitIdentifierName(node); + } + + public override SyntaxNode? VisitQualifiedName(QualifiedNameSyntax node) + { + return base.VisitQualifiedName(node); } } } diff --git a/src/EntityFrameworkCore.Projectables.Generator/ProjectableInterpreter.cs b/src/EntityFrameworkCore.Projectables.Generator/ProjectableInterpreter.cs index 0d68b2d..4b400e1 100644 --- a/src/EntityFrameworkCore.Projectables.Generator/ProjectableInterpreter.cs +++ b/src/EntityFrameworkCore.Projectables.Generator/ProjectableInterpreter.cs @@ -92,7 +92,13 @@ namespace EntityFrameworkCore.Projectables.Generator return null; } - descriptor.ReturnTypeName = returnTypeSyntaxRewriter.Visit(methodDeclarationSyntax.ReturnType).ToString(); + var returnTypeSymbol = semanticModel.GetSymbolInfo(returnTypeSyntaxRewriter.Visit(methodDeclarationSyntax.ReturnType)).Symbol; + if (returnTypeSymbol is null) + { + return null; + } + + descriptor.ReturnTypeName = returnTypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); descriptor.Body = expressionSyntaxRewriter.Visit(methodDeclarationSyntax.ExpressionBody.Expression); foreach (var additionalParameter in ((ParameterListSyntax)parameterSyntaxRewriter.Visit(methodDeclarationSyntax.ParameterList)).Parameters) { @@ -108,7 +114,13 @@ namespace EntityFrameworkCore.Projectables.Generator return null; } - descriptor.ReturnTypeName = propertyDeclarationSyntax.Type.ToString(); + var returnTypeSymbol = semanticModel.GetSymbolInfo(returnTypeSyntaxRewriter.Visit(propertyDeclarationSyntax.Type)).Symbol; + if (returnTypeSymbol is null) + { + return null; + } + + descriptor.ReturnTypeName = returnTypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); descriptor.Body = expressionSyntaxRewriter.Visit(propertyDeclarationSyntax.ExpressionBody.Expression); } else diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt index a2b7ca0..f2ad130 100644 --- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt +++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt @@ -8,7 +8,7 @@ namespace EntityFrameworkCore.Projectables.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression => + public static System.Linq.Expressions.Expression> Expression => (global::Foo.C @this) => @this.Dees.First(); } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.TypesInBodyGetsFullyQualified.verified.txt b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.TypesInBodyGetsFullyQualified.verified.txt new file mode 100644 index 0000000..29de077 --- /dev/null +++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.TypesInBodyGetsFullyQualified.verified.txt @@ -0,0 +1,14 @@ +using System; +using System.Linq; +using EntityFrameworkCore.Projectables; +using Foo; + +namespace EntityFrameworkCore.Projectables.Generated +#nullable disable +{ + public static class Foo_C_Foo + { + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => @this.Dees.OfType().Count(); + } +} \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.cs b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.cs index b79208d..198f3e3 100644 --- a/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.cs +++ b/tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTests.cs @@ -292,6 +292,33 @@ namespace Foo { return Verifier.Verify(result.GeneratedTrees[0].ToString()); } + [Fact] + public Task TypesInBodyGetsFullyQualified() + { + var compilation = CreateCompilation(@" +using System; +using System.Linq; +using EntityFrameworkCore.Projectables; +namespace Foo { + class D { } + + class C { + public System.Collections.Generic.List Dees { get; set; } + + [Projectable] + public int Foo => Dees.OfType().Count(); + } +} +"); + + var result = RunGenerator(compilation); + + Assert.Empty(result.Diagnostics); + Assert.Single(result.GeneratedTrees); + + return Verifier.Verify(result.GeneratedTrees[0].ToString()); + } + [Fact] public Task ProjectableExtensionMethod() {