Improved expression tree generation

This commit is contained in:
Koen Bekkenutte
2021-06-03 02:27:55 +08:00
parent 6808ea6465
commit 5e8e84f1db
5 changed files with 82 additions and 12 deletions
@@ -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);
}
}
}
@@ -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
@@ -8,7 +8,7 @@ namespace EntityFrameworkCore.Projectables.Generated
{
public static class Foo_C_Foo
{
public static System.Linq.Expressions.Expression<System.Func<global::Foo.C, D>> Expression =>
public static System.Linq.Expressions.Expression<System.Func<global::Foo.C, global::Foo.D>> Expression =>
(global::Foo.C @this) => @this.Dees.First();
}
}
@@ -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<System.Func<global::Foo.C, int>> Expression =>
(global::Foo.C @this) => @this.Dees.OfType<global::Foo.D>().Count();
}
}
@@ -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<D> Dees { get; set; }
[Projectable]
public int Foo => Dees.OfType<D>().Count();
}
}
");
var result = RunGenerator(compilation);
Assert.Empty(result.Diagnostics);
Assert.Single(result.GeneratedTrees);
return Verifier.Verify(result.GeneratedTrees[0].ToString());
}
[Fact]
public Task ProjectableExtensionMethod()
{