Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IOperation support for query operations. #21356

Merged
merged 13 commits into from
Sep 20, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions src/Compilers/CSharp/Portable/Operations/CSharpOperationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ private IOperation CreateInternal(BoundNode boundNode)
return CreateBoundPatternSwitchLabelOperation((BoundPatternSwitchLabel)boundNode);
case BoundKind.IsPatternExpression:
return CreateBoundIsPatternExpressionOperation((BoundIsPatternExpression)boundNode);
case BoundKind.QueryClause:
return CreateBoundQueryClauseOrExpressionOperation((BoundQueryClause)boundNode);
default:
var constantValue = ConvertToOptional((boundNode as BoundExpression)?.ConstantValue);
return Operation.CreateOperationNone(_semanticModel, boundNode.Syntax, constantValue, getChildren: () => GetIOperationChildren(boundNode));
Expand Down Expand Up @@ -1386,5 +1388,136 @@ private IIsPatternExpression CreateBoundIsPatternExpressionOperation(BoundIsPatt
Optional<object> constantValue = ConvertToOptional(boundIsPatternExpression.ConstantValue);
return new LazyIsPatternExpression(expression, pattern, _semanticModel, syntax, type, constantValue);
}

private IOperation CreateBoundQueryClauseOrExpressionOperation(BoundQueryClause boundQueryClause)
{
var queryClauseKindOpt = GetQueryClauseKind(boundQueryClause);
return queryClauseKindOpt.HasValue ?
CreateBoundQueryClauseOperation(boundQueryClause, queryClauseKindOpt.Value) :
CreateBoundQueryOrContinuationOrOrderExpressionOperation(boundQueryClause);
}

private IQueryClause CreateBoundQueryClauseOperation(BoundQueryClause boundQueryClause, QueryClauseKind queryClauseKind)
{
Lazy<IOperation> underlyingExpression = new Lazy<IOperation>(() => Create(boundQueryClause.Value));
SyntaxNode syntax = boundQueryClause.Syntax;
ITypeSymbol type = boundQueryClause.Type;
Optional<object> constantValue = ConvertToOptional(boundQueryClause.ConstantValue);

switch(queryClauseKind)
{
case QueryClauseKind.FromClause:
return new LazyFromQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

case QueryClauseKind.SelectClause:
return new LazySelectQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

case QueryClauseKind.WhereClause:
return new LazyWhereQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

case QueryClauseKind.LetClause:
return new LazyLetQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

case QueryClauseKind.OrderByClause:
return new LazyOrderByQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

case QueryClauseKind.GroupByClause:
return new LazyGroupByQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

case QueryClauseKind.JoinClause:
return new LazyJoinQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

case QueryClauseKind.JoinIntoClause:
return new LazyJoinIntoQueryClause(underlyingExpression, _semanticModel, syntax, type, constantValue);

default:
throw ExceptionUtilities.Unreachable;
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw UnexpectedValue(queryClauseKind) #Closed

}
}

private IOperation CreateBoundQueryOrContinuationOrOrderExpressionOperation(BoundQueryClause boundQueryClause)
{
switch(boundQueryClause.Syntax.Kind())
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does one use the syntax kind, and the other uses a different kind? #Closed

{
case SyntaxKind.QueryExpression:
return CreateBoundQueryExpressionOperation(boundQueryClause);

case SyntaxKind.QueryContinuation:
return CreateBoundQueryContinuationOperation(boundQueryClause);

case SyntaxKind.AscendingOrdering:
return CreateBoundOrderingExpressionOperation(boundQueryClause, OrderKind.Ascending);

case SyntaxKind.DescendingOrdering:
return CreateBoundOrderingExpressionOperation(boundQueryClause, OrderKind.Descending);

case SyntaxKind.QueryBody:
return boundQueryClause.Value != null ? Create((BoundQueryClause)boundQueryClause.Value) : null;
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do you get nul lhere? #Closed

Copy link
Contributor Author

@mavasani mavasani Aug 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just a defensive guard, I'll remove it unless any test breaks. #Closed


default:
throw ExceptionUtilities.Unreachable;
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw UnexpecteValue #Closed

}
}

private IQueryExpression CreateBoundQueryExpressionOperation(BoundQueryClause boundQueryClause)
{
Lazy<IOperation> lastClauseOrContinuation = new Lazy<IOperation>(() => Create(boundQueryClause.Value));
SyntaxNode syntax = boundQueryClause.Syntax;
ITypeSymbol type = boundQueryClause.Type;
Optional<object> constantValue = ConvertToOptional(boundQueryClause.ConstantValue);
return new LazyQueryExpression(lastClauseOrContinuation, _semanticModel, syntax, type, constantValue);
}

private IQueryContinuation CreateBoundQueryContinuationOperation(BoundQueryClause boundQueryClause)
{
Lazy<IOperation> queryBody = new Lazy<IOperation>(() => Create(boundQueryClause.Value));
IRangeVariableSymbol definedSymbol = boundQueryClause.DefinedSymbol;
SyntaxNode syntax = boundQueryClause.Syntax;
ITypeSymbol type = boundQueryClause.Type;
Optional<object> constantValue = ConvertToOptional(boundQueryClause.ConstantValue);
return new LazyQueryContinuation(queryBody, definedSymbol, _semanticModel, syntax, type, constantValue);
}

private IOrderingExpression CreateBoundOrderingExpressionOperation(BoundQueryClause boundQueryClause, OrderKind orderKind)
{
Lazy<IOperation> expression = new Lazy<IOperation>(() => Create(boundQueryClause.Value));
SyntaxNode syntax = boundQueryClause.Syntax;
ITypeSymbol type = boundQueryClause.Type;
Optional<object> constantValue = ConvertToOptional(boundQueryClause.ConstantValue);
return new LazyOrderingExpression(expression, orderKind, _semanticModel, syntax, type, constantValue);
}

private QueryClauseKind? GetQueryClauseKind(BoundQueryClause boundQueryClause)
{
switch(boundQueryClause.Syntax.Kind())
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Aug 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you use map some syntax kins to query clause kinds here. why not map them all? #Closed

Copy link
Contributor Author

@mavasani mavasani Aug 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will pull all of the syntax kind comparisons into a single switch statement. #Closed

{
case SyntaxKind.FromClause:
return QueryClauseKind.FromClause;

case SyntaxKind.SelectClause:
return QueryClauseKind.SelectClause;

case SyntaxKind.WhereClause:
return QueryClauseKind.WhereClause;

case SyntaxKind.LetClause:
return QueryClauseKind.LetClause;

case SyntaxKind.OrderByClause:
return QueryClauseKind.OrderByClause;

case SyntaxKind.GroupClause:
return QueryClauseKind.GroupByClause;

case SyntaxKind.JoinClause:
return QueryClauseKind.JoinClause;

case SyntaxKind.JoinIntoClause:
return QueryClauseKind.JoinIntoClause;

default:
return null;
}
}
}
}
Loading