mirror of
https://github.com/zoriya/EntityFrameworkCore.Projectables.git
synced 2026-05-24 11:44:20 +00:00
Improved expression tree generation
This commit is contained in:
@@ -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
|
||||
|
||||
+1
-1
@@ -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();
|
||||
}
|
||||
}
|
||||
+14
@@ -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();
|
||||
}
|
||||
}
|
||||
+27
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user