Skip to content

Commit

Permalink
Tweaks and simplifications
Browse files Browse the repository at this point in the history
  • Loading branch information
roji committed Jan 6, 2023
1 parent c16b2f6 commit 333fdec
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 85 deletions.
135 changes: 54 additions & 81 deletions src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,7 @@ public override Expression VisitIdentifierName(IdentifierNameSyntax identifierNa
// TODO: Separate out EF Core-specific logic (EF Core would extend this visitor)
if (localSymbol.Type.Name.Contains("DbSet"))
{
var queryRootType = ResolveType(localSymbol.Type)!;
// TODO: Decide what to actually return for query root
return Constant(null, queryRootType);
throw new NotImplementedException("DbSet local symbol");
}

// We have an identifier which isn't in our parameters stack - it's a closure parameter.
Expand All @@ -349,7 +347,7 @@ public override Expression VisitIdentifierName(IdentifierNameSyntax identifierNa
// We haven't seen this captured variable yet
if (memberExpression is null)
{
memberExpression = _capturedVariables[localSymbol] = _capturedVariables[localSymbol] =
memberExpression = _capturedVariables[localSymbol] =
Field(
Constant(new FakeClosureFrameClass()),
new FakeFieldInfo(
Expand Down Expand Up @@ -762,47 +760,7 @@ public override Expression VisitParenthesizedExpression(ParenthesizedExpressionS
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override Expression VisitParenthesizedLambdaExpression(ParenthesizedLambdaExpressionSyntax lambda)
{
if (lambda.ExpressionBody is null)
{
throw new NotSupportedException("Lambda with null expression body");
}

if (lambda.Modifiers.Any())
{
throw new NotImplementedException("Lambda with modifiers: " + lambda.Modifiers);
}

if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))
{
throw new NotImplementedException("Async lambda");
}

var translatedParameters = new List<ParameterExpression>();
foreach (var parameter in lambda.ParameterList.Parameters)
{
if (_semanticModel.GetDeclaredSymbol(parameter) is not { } parameterSymbol ||
ResolveType(parameterSymbol.Type) is not { } parameterType)
{
throw new InvalidOperationException("Could not found symbol for parameter lambda: " + parameter);
}

translatedParameters.Add(Parameter(parameterType, parameter.Identifier.Text));
}

_parameterStack.Push(_parameterStack.Peek()
.AddRange(translatedParameters.Select(p => new KeyValuePair<string, ParameterExpression>(p.Name ?? throw new NotImplementedException(), p))));

try
{
var body = Visit(lambda.ExpressionBody);
return Lambda(body, translatedParameters);
}
finally
{
_parameterStack.Pop();
}
}
=> VisitLambdaExpression(lambda);

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -881,42 +839,7 @@ NotSupportedException NotSupported()
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override Expression VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax lambda)
{
if (lambda.ExpressionBody is null)
{
throw new NotSupportedException("SimpleLambda with null expression body");
}

if (lambda.Modifiers.Any())
{
throw new NotImplementedException("SimpleLambda with modifiers: " + lambda.Modifiers);
}

if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))
{
throw new NotImplementedException("SimpleLambda with async keyword");
}

var paramName = lambda.Parameter.Identifier.Text;
if (_semanticModel.GetDeclaredSymbol(lambda.Parameter) is not { } parameterSymbol ||
ResolveType(parameterSymbol.Type) is not { } parameterType)
{
throw new InvalidOperationException("Could not found symbol for parameter lambda: " + lambda.Parameter);
}

var parameter = Parameter(parameterType, paramName);
_parameterStack.Push(_parameterStack.Peek().SetItem(paramName, parameter));

try
{
var body = Visit(lambda.ExpressionBody);
return Lambda(body, parameter);
}
finally
{
_parameterStack.Pop();
}
}
=> VisitLambdaExpression(lambda);

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -945,6 +868,56 @@ public override Expression VisitTypeOfExpression(TypeOfExpressionSyntax typeOf)
public override Expression DefaultVisit(SyntaxNode node)
=> throw new NotSupportedException($"Unsupported syntax node of type '{node.GetType()}': {node}");

private Expression VisitLambdaExpression(AnonymousFunctionExpressionSyntax lambda)
{
if (lambda.ExpressionBody is null)
{
throw new NotSupportedException("Lambda with null expression body");
}

if (lambda.Modifiers.Any())
{
throw new NotImplementedException("Lambda with modifiers: " + lambda.Modifiers);
}

if (!lambda.AsyncKeyword.IsKind(SyntaxKind.None))
{
throw new NotImplementedException("Async lambda");
}

var lambdaParameters = lambda switch
{
SimpleLambdaExpressionSyntax simpleLambda => SyntaxFactory.SingletonSeparatedList(simpleLambda.Parameter),
ParenthesizedLambdaExpressionSyntax parenthesizedLambda => parenthesizedLambda.ParameterList.Parameters,
_ => throw new ArgumentOutOfRangeException()
};

var translatedParameters = new List<ParameterExpression>();
foreach (var parameter in lambdaParameters)
{
if (_semanticModel.GetDeclaredSymbol(parameter) is not { } parameterSymbol ||
ResolveType(parameterSymbol.Type) is not { } parameterType)
{
throw new InvalidOperationException("Could not found symbol for parameter lambda: " + parameter);
}

translatedParameters.Add(Parameter(parameterType, parameter.Identifier.Text));
}

_parameterStack.Push(_parameterStack.Peek()
.AddRange(translatedParameters.Select(p => new KeyValuePair<string, ParameterExpression>(p.Name ?? throw new NotImplementedException(), p))));

try
{
var body = Visit(lambda.ExpressionBody);
return Lambda(body, translatedParameters);
}
finally
{
_parameterStack.Pop();
}
}

private Type ResolveType(SyntaxNode node)
=> _semanticModel.GetTypeInfo(node).Type is { } typeSymbol
? ResolveType(typeSymbol)
Expand Down
3 changes: 1 addition & 2 deletions src/EFCore.Design/Query/Internal/LinqToCSharpTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,7 @@ public virtual SyntaxNode TranslateExpression(Expression node, ISet<string> coll
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
[return: NotNullIfNotNull(nameof(node))]
protected virtual SyntaxNode? TranslateCore(Expression node, ISet<string> collectedNamespaces, bool statementContext = false)
protected virtual SyntaxNode TranslateCore(Expression node, ISet<string> collectedNamespaces, bool statementContext = false)
{
_capturedVariables.Clear();
_collectedNamespaces = collectedNamespaces;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,19 @@ public PrecompiledQueryCodeGenerator(
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public async Task GeneratePrecompiledQueries(string projectDir, DbContext context, string outputDir, CancellationToken cancellationToken = default)
public async Task GeneratePrecompiledQueries(
string projectFilePath,
DbContext context,
string outputDir,
CancellationToken cancellationToken = default)
{
// https://gist.github.com/DustinCampbell/32cd69d04ea1c08a16ae5c4cd21dd3a3
MSBuildLocator.RegisterDefaults();

Console.Error.WriteLine("Loading project...");
using var workspace = MSBuildWorkspace.Create();

var project = await workspace.OpenProjectAsync(projectDir, cancellationToken: cancellationToken)
var project = await workspace.OpenProjectAsync(projectFilePath, cancellationToken: cancellationToken)
.ConfigureAwait(false);

Console.WriteLine("Compiling project...");
Expand Down

0 comments on commit 333fdec

Please sign in to comment.