565 lines
20 KiB
C#
565 lines
20 KiB
C#
using Microsoft.CodeAnalysis.CSharp.Symbols;
|
|||
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
||
|
|
using Roslyn.Utilities;
|
||
|
|
|
||
|
|
namespace Microsoft.CodeAnalysis.CSharp;
|
||
|
|
|
||
|
|
internal abstract class ExpressionVariableFinder<TFieldOrLocalSymbol> : CSharpSyntaxWalker where TFieldOrLocalSymbol : Symbol
|
||
|
|
{
|
||
|
|
private ArrayBuilder<TFieldOrLocalSymbol> _variablesBuilder;
|
||
|
|
|
||
|
|
private SyntaxNode _nodeToBind;
|
||
|
|
|
||
|
|
protected void FindExpressionVariables(ArrayBuilder<TFieldOrLocalSymbol> builder, CSharpSyntaxNode node)
|
||
|
|
{
|
||
|
|
ArrayBuilder<TFieldOrLocalSymbol> variablesBuilder = _variablesBuilder;
|
||
|
|
_variablesBuilder = builder;
|
||
|
|
VisitNodeToBind(node);
|
||
|
|
_variablesBuilder = variablesBuilder;
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitSwitchExpression(SwitchExpressionSyntax node)
|
||
|
|
{
|
||
|
|
Visit((SyntaxNode?)(object)node.GoverningExpression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitSwitchExpressionArm(SwitchExpressionArmSyntax node)
|
||
|
|
{
|
||
|
|
SyntaxNode nodeToBind = _nodeToBind;
|
||
|
|
_nodeToBind = (SyntaxNode)(object)node;
|
||
|
|
Visit((SyntaxNode?)(object)node.Pattern);
|
||
|
|
Visit((SyntaxNode?)(object)node.WhenClause?.Condition);
|
||
|
|
Visit((SyntaxNode?)(object)node.Expression);
|
||
|
|
_nodeToBind = nodeToBind;
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitVariableDeclarator(VariableDeclaratorSyntax node)
|
||
|
|
{
|
||
|
|
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
if (node.ArgumentList != null)
|
||
|
|
{
|
||
|
|
Enumerator<ArgumentSyntax> enumerator = node.ArgumentList.Arguments.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
ArgumentSyntax current = enumerator.Current;
|
||
|
|
Visit((SyntaxNode?)(object)current.Expression);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
VisitNodeToBind(node.Initializer);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitGotoStatement(GotoStatementSyntax node)
|
||
|
|
{
|
||
|
|
if (node.Kind() == SyntaxKind.GotoCaseStatement)
|
||
|
|
{
|
||
|
|
Visit((SyntaxNode?)(object)node.Expression);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void VisitNodeToBind(CSharpSyntaxNode node)
|
||
|
|
{
|
||
|
|
SyntaxNode nodeToBind = _nodeToBind;
|
||
|
|
_nodeToBind = (SyntaxNode)(object)node;
|
||
|
|
Visit((SyntaxNode?)(object)node);
|
||
|
|
_nodeToBind = nodeToBind;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected void FindExpressionVariables(ArrayBuilder<TFieldOrLocalSymbol> builder, SeparatedSyntaxList<ExpressionSyntax> nodes)
|
||
|
|
{
|
||
|
|
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
ArrayBuilder<TFieldOrLocalSymbol> variablesBuilder = _variablesBuilder;
|
||
|
|
_variablesBuilder = builder;
|
||
|
|
Enumerator<ExpressionSyntax> enumerator = nodes.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
ExpressionSyntax current = enumerator.Current;
|
||
|
|
VisitNodeToBind(current);
|
||
|
|
}
|
||
|
|
_variablesBuilder = variablesBuilder;
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitEqualsValueClause(EqualsValueClauseSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Value);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitArrowExpressionClause(ArrowExpressionClauseSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Expression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitSwitchSection(SwitchSectionSyntax node)
|
||
|
|
{
|
||
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
Enumerator<SwitchLabelSyntax> enumerator = node.Labels.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
SwitchLabelSyntax current = enumerator.Current;
|
||
|
|
switch (current.Kind())
|
||
|
|
{
|
||
|
|
case SyntaxKind.CasePatternSwitchLabel:
|
||
|
|
{
|
||
|
|
CasePatternSwitchLabelSyntax casePatternSwitchLabelSyntax = (CasePatternSwitchLabelSyntax)current;
|
||
|
|
SyntaxNode nodeToBind = _nodeToBind;
|
||
|
|
_nodeToBind = (SyntaxNode)(object)casePatternSwitchLabelSyntax;
|
||
|
|
Visit((SyntaxNode?)(object)casePatternSwitchLabelSyntax.Pattern);
|
||
|
|
if (casePatternSwitchLabelSyntax.WhenClause != null)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(casePatternSwitchLabelSyntax.WhenClause.Condition);
|
||
|
|
}
|
||
|
|
_nodeToBind = nodeToBind;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case SyntaxKind.CaseSwitchLabel:
|
||
|
|
{
|
||
|
|
CaseSwitchLabelSyntax caseSwitchLabelSyntax = (CaseSwitchLabelSyntax)current;
|
||
|
|
VisitNodeToBind(caseSwitchLabelSyntax.Value);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitAttribute(AttributeSyntax node)
|
||
|
|
{
|
||
|
|
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
if (node.ArgumentList != null)
|
||
|
|
{
|
||
|
|
Enumerator<AttributeArgumentSyntax> enumerator = node.ArgumentList.Arguments.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
AttributeArgumentSyntax current = enumerator.Current;
|
||
|
|
VisitNodeToBind(current.Expression);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitThrowStatement(ThrowStatementSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Expression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitReturnStatement(ReturnStatementSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Expression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitYieldStatement(YieldStatementSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Expression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitExpressionStatement(ExpressionStatementSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Expression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitLockStatement(LockStatementSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Expression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitIfStatement(IfStatementSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Condition);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitSwitchStatement(SwitchStatementSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Expression);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitDeclarationPattern(DeclarationPatternSyntax node)
|
||
|
|
{
|
||
|
|
VariableDesignationSyntax designation = node.Designation;
|
||
|
|
if (designation != null && designation.Kind() == SyntaxKind.SingleVariableDesignation)
|
||
|
|
{
|
||
|
|
TFieldOrLocalSymbol val = MakePatternVariable(node.Type, (SingleVariableDesignationSyntax)node.Designation, _nodeToBind);
|
||
|
|
if ((object)val != null)
|
||
|
|
{
|
||
|
|
_variablesBuilder.Add(val);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
base.VisitDeclarationPattern(node);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitVarPattern(VarPatternSyntax node)
|
||
|
|
{
|
||
|
|
VisitPatternDesignation(node.Designation);
|
||
|
|
base.VisitVarPattern(node);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void VisitPatternDesignation(VariableDesignationSyntax node)
|
||
|
|
{
|
||
|
|
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
switch (node.Kind())
|
||
|
|
{
|
||
|
|
case SyntaxKind.SingleVariableDesignation:
|
||
|
|
{
|
||
|
|
TFieldOrLocalSymbol val = MakePatternVariable(null, (SingleVariableDesignationSyntax)node, _nodeToBind);
|
||
|
|
if ((object)val != null)
|
||
|
|
{
|
||
|
|
_variablesBuilder.Add(val);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case SyntaxKind.ParenthesizedVariableDesignation:
|
||
|
|
{
|
||
|
|
Enumerator<VariableDesignationSyntax> enumerator = ((ParenthesizedVariableDesignationSyntax)node).Variables.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
VariableDesignationSyntax current = enumerator.Current;
|
||
|
|
VisitPatternDesignation(current);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default:
|
||
|
|
throw ExceptionUtilities.UnexpectedValue((object)node.Kind());
|
||
|
|
case SyntaxKind.DiscardDesignation:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitRecursivePattern(RecursivePatternSyntax node)
|
||
|
|
{
|
||
|
|
TFieldOrLocalSymbol val = MakePatternVariable(node.Type, node.Designation as SingleVariableDesignationSyntax, _nodeToBind);
|
||
|
|
if ((object)val != null)
|
||
|
|
{
|
||
|
|
_variablesBuilder.Add(val);
|
||
|
|
}
|
||
|
|
base.VisitRecursivePattern(node);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitListPattern(ListPatternSyntax node)
|
||
|
|
{
|
||
|
|
TFieldOrLocalSymbol val = MakePatternVariable(null, node.Designation as SingleVariableDesignationSyntax, _nodeToBind);
|
||
|
|
if ((object)val != null)
|
||
|
|
{
|
||
|
|
_variablesBuilder.Add(val);
|
||
|
|
}
|
||
|
|
base.VisitListPattern(node);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected abstract TFieldOrLocalSymbol MakePatternVariable(TypeSyntax type, SingleVariableDesignationSyntax designation, SyntaxNode nodeToBind);
|
||
|
|
|
||
|
|
public override void VisitParenthesizedLambdaExpression(ParenthesizedLambdaExpressionSyntax node)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitQueryExpression(QueryExpressionSyntax node)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.FromClause.Expression);
|
||
|
|
Visit((SyntaxNode?)(object)node.Body);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitQueryBody(QueryBodySyntax node)
|
||
|
|
{
|
||
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
Enumerator<QueryClauseSyntax> enumerator = node.Clauses.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
QueryClauseSyntax current = enumerator.Current;
|
||
|
|
if (current.Kind() == SyntaxKind.JoinClause)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(((JoinClauseSyntax)current).InExpression);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Visit((SyntaxNode?)(object)node.Continuation);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitBinaryExpression(BinaryExpressionSyntax node)
|
||
|
|
{
|
||
|
|
ArrayBuilder<ExpressionSyntax> instance = ArrayBuilder<ExpressionSyntax>.GetInstance();
|
||
|
|
ExpressionSyntax expressionSyntax = node;
|
||
|
|
do
|
||
|
|
{
|
||
|
|
BinaryExpressionSyntax binaryExpressionSyntax = (BinaryExpressionSyntax)expressionSyntax;
|
||
|
|
ArrayBuilderExtensions.Push<ExpressionSyntax>(instance, binaryExpressionSyntax.Right);
|
||
|
|
expressionSyntax = binaryExpressionSyntax.Left;
|
||
|
|
}
|
||
|
|
while (expressionSyntax is BinaryExpressionSyntax);
|
||
|
|
Visit((SyntaxNode?)(object)expressionSyntax);
|
||
|
|
while (instance.Count > 0)
|
||
|
|
{
|
||
|
|
Visit((SyntaxNode?)(object)ArrayBuilderExtensions.Pop<ExpressionSyntax>(instance));
|
||
|
|
}
|
||
|
|
instance.Free();
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitInvocationExpression(InvocationExpressionSyntax node)
|
||
|
|
{
|
||
|
|
if (receiverIsInvocation(node, out var nested))
|
||
|
|
{
|
||
|
|
ArrayBuilder<InvocationExpressionSyntax> instance = ArrayBuilder<InvocationExpressionSyntax>.GetInstance();
|
||
|
|
ArrayBuilderExtensions.Push<InvocationExpressionSyntax>(instance, node);
|
||
|
|
node = nested;
|
||
|
|
while (receiverIsInvocation(node, out nested))
|
||
|
|
{
|
||
|
|
ArrayBuilderExtensions.Push<InvocationExpressionSyntax>(instance, node);
|
||
|
|
node = nested;
|
||
|
|
}
|
||
|
|
Visit((SyntaxNode?)(object)node.Expression);
|
||
|
|
do
|
||
|
|
{
|
||
|
|
Visit((SyntaxNode?)(object)node.ArgumentList);
|
||
|
|
}
|
||
|
|
while (ArrayBuilderExtensions.TryPop<InvocationExpressionSyntax>(instance, ref node));
|
||
|
|
instance.Free();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Visit((SyntaxNode?)(object)node.Expression);
|
||
|
|
Visit((SyntaxNode?)(object)node.ArgumentList);
|
||
|
|
}
|
||
|
|
static bool receiverIsInvocation(InvocationExpressionSyntax invocationExpressionSyntax, out InvocationExpressionSyntax reference)
|
||
|
|
{
|
||
|
|
if (invocationExpressionSyntax.Expression is MemberAccessExpressionSyntax { Expression: InvocationExpressionSyntax expression })
|
||
|
|
{
|
||
|
|
reference = expression;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
reference = null;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitDeclarationExpression(DeclarationExpressionSyntax node)
|
||
|
|
{
|
||
|
|
BaseArgumentListSyntax argumentListSyntaxOpt = (node.Parent as ArgumentSyntax)?.Parent as BaseArgumentListSyntax;
|
||
|
|
VisitDeclarationExpressionDesignation(node, node.Designation, argumentListSyntaxOpt);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void VisitDeclarationExpressionDesignation(DeclarationExpressionSyntax node, VariableDesignationSyntax designation, BaseArgumentListSyntax argumentListSyntaxOpt)
|
||
|
|
{
|
||
|
|
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
switch (designation.Kind())
|
||
|
|
{
|
||
|
|
case SyntaxKind.SingleVariableDesignation:
|
||
|
|
{
|
||
|
|
TFieldOrLocalSymbol val = MakeDeclarationExpressionVariable(node, (SingleVariableDesignationSyntax)designation, argumentListSyntaxOpt, _nodeToBind);
|
||
|
|
if ((object)val != null)
|
||
|
|
{
|
||
|
|
_variablesBuilder.Add(val);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case SyntaxKind.ParenthesizedVariableDesignation:
|
||
|
|
{
|
||
|
|
Enumerator<VariableDesignationSyntax> enumerator = ((ParenthesizedVariableDesignationSyntax)designation).Variables.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
VariableDesignationSyntax current = enumerator.Current;
|
||
|
|
VisitDeclarationExpressionDesignation(node, current, argumentListSyntaxOpt);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default:
|
||
|
|
throw ExceptionUtilities.UnexpectedValue((object)designation.Kind());
|
||
|
|
case SyntaxKind.DiscardDesignation:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitAssignmentExpression(AssignmentExpressionSyntax node)
|
||
|
|
{
|
||
|
|
if (node.IsDeconstruction())
|
||
|
|
{
|
||
|
|
CollectVariablesFromDeconstruction(node.Left, node);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Visit((SyntaxNode?)(object)node.Left);
|
||
|
|
}
|
||
|
|
Visit((SyntaxNode?)(object)node.Right);
|
||
|
|
}
|
||
|
|
|
||
|
|
public override void VisitConstructorDeclaration(ConstructorDeclarationSyntax node)
|
||
|
|
{
|
||
|
|
if (node.Initializer != null)
|
||
|
|
{
|
||
|
|
VisitNodeToBind(node.Initializer);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void CollectVariablesFromDeconstruction(ExpressionSyntax possibleTupleDeclaration, AssignmentExpressionSyntax deconstruction)
|
||
|
|
{
|
||
|
|
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
switch (possibleTupleDeclaration.Kind())
|
||
|
|
{
|
||
|
|
case SyntaxKind.TupleExpression:
|
||
|
|
{
|
||
|
|
Enumerator<ArgumentSyntax> enumerator = ((TupleExpressionSyntax)possibleTupleDeclaration).Arguments.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
ArgumentSyntax current = enumerator.Current;
|
||
|
|
CollectVariablesFromDeconstruction(current.Expression, deconstruction);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case SyntaxKind.DeclarationExpression:
|
||
|
|
{
|
||
|
|
DeclarationExpressionSyntax declarationExpressionSyntax = (DeclarationExpressionSyntax)possibleTupleDeclaration;
|
||
|
|
CollectVariablesFromDeconstruction(declarationExpressionSyntax.Designation, declarationExpressionSyntax.Type, deconstruction);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default:
|
||
|
|
Visit((SyntaxNode?)(object)possibleTupleDeclaration);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void CollectVariablesFromDeconstruction(VariableDesignationSyntax designation, TypeSyntax closestTypeSyntax, AssignmentExpressionSyntax deconstruction)
|
||
|
|
{
|
||
|
|
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
switch (designation.Kind())
|
||
|
|
{
|
||
|
|
case SyntaxKind.SingleVariableDesignation:
|
||
|
|
{
|
||
|
|
SingleVariableDesignationSyntax designation2 = (SingleVariableDesignationSyntax)designation;
|
||
|
|
TFieldOrLocalSymbol val = MakeDeconstructionVariable(closestTypeSyntax, designation2, deconstruction);
|
||
|
|
if ((object)val != null)
|
||
|
|
{
|
||
|
|
_variablesBuilder.Add(val);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
case SyntaxKind.ParenthesizedVariableDesignation:
|
||
|
|
{
|
||
|
|
Enumerator<VariableDesignationSyntax> enumerator = ((ParenthesizedVariableDesignationSyntax)designation).Variables.GetEnumerator();
|
||
|
|
while (enumerator.MoveNext())
|
||
|
|
{
|
||
|
|
VariableDesignationSyntax current = enumerator.Current;
|
||
|
|
CollectVariablesFromDeconstruction(current, closestTypeSyntax, deconstruction);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default:
|
||
|
|
throw ExceptionUtilities.UnexpectedValue((object)designation.Kind());
|
||
|
|
case SyntaxKind.DiscardDesignation:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected abstract TFieldOrLocalSymbol MakeDeclarationExpressionVariable(DeclarationExpressionSyntax node, SingleVariableDesignationSyntax designation, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind);
|
||
|
|
|
||
|
|
protected abstract TFieldOrLocalSymbol MakeDeconstructionVariable(TypeSyntax closestTypeSyntax, SingleVariableDesignationSyntax designation, AssignmentExpressionSyntax deconstruction);
|
||
|
|
|
||
|
|
protected ExpressionVariableFinder()
|
||
|
|
: base((SyntaxWalkerDepth)0)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
}
|
||
|
|
internal class ExpressionVariableFinder : ExpressionVariableFinder<LocalSymbol>
|
||
|
|
{
|
||
|
|
private Binder _scopeBinder;
|
||
|
|
|
||
|
|
private Binder _enclosingBinder;
|
||
|
|
|
||
|
|
private static readonly ObjectPool<ExpressionVariableFinder> s_poolInstance = CreatePool();
|
||
|
|
|
||
|
|
internal static void FindExpressionVariables(Binder scopeBinder, ArrayBuilder<LocalSymbol> builder, CSharpSyntaxNode node, Binder enclosingBinderOpt = null)
|
||
|
|
{
|
||
|
|
if (node != null)
|
||
|
|
{
|
||
|
|
ExpressionVariableFinder expressionVariableFinder = s_poolInstance.Allocate();
|
||
|
|
expressionVariableFinder._scopeBinder = scopeBinder;
|
||
|
|
expressionVariableFinder._enclosingBinder = enclosingBinderOpt ?? scopeBinder;
|
||
|
|
expressionVariableFinder.FindExpressionVariables(builder, node);
|
||
|
|
expressionVariableFinder._scopeBinder = null;
|
||
|
|
expressionVariableFinder._enclosingBinder = null;
|
||
|
|
s_poolInstance.Free(expressionVariableFinder);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
internal static void FindExpressionVariables(Binder binder, ArrayBuilder<LocalSymbol> builder, SeparatedSyntaxList<ExpressionSyntax> nodes)
|
||
|
|
{
|
||
|
|
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
if (nodes.Count != 0)
|
||
|
|
{
|
||
|
|
ExpressionVariableFinder expressionVariableFinder = s_poolInstance.Allocate();
|
||
|
|
expressionVariableFinder._scopeBinder = binder;
|
||
|
|
expressionVariableFinder._enclosingBinder = binder;
|
||
|
|
expressionVariableFinder.FindExpressionVariables(builder, nodes);
|
||
|
|
expressionVariableFinder._scopeBinder = null;
|
||
|
|
expressionVariableFinder._enclosingBinder = null;
|
||
|
|
s_poolInstance.Free(expressionVariableFinder);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override LocalSymbol MakePatternVariable(TypeSyntax type, SingleVariableDesignationSyntax designation, SyntaxNode nodeToBind)
|
||
|
|
{
|
||
|
|
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
if (designation == null)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
NamedTypeSymbol containingType = _scopeBinder.ContainingType;
|
||
|
|
if ((object)containingType != null && containingType.IsScriptClass && (object)_scopeBinder.LookupDeclaredField(designation) != null)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext(_scopeBinder.ContainingMemberOrLambda, _scopeBinder, _enclosingBinder, type, designation.Identifier, LocalDeclarationKind.PatternVariable, nodeToBind, null);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override LocalSymbol MakeDeclarationExpressionVariable(DeclarationExpressionSyntax node, SingleVariableDesignationSyntax designation, BaseArgumentListSyntax argumentListSyntaxOpt, SyntaxNode nodeToBind)
|
||
|
|
{
|
||
|
|
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
NamedTypeSymbol containingType = _scopeBinder.ContainingType;
|
||
|
|
if ((object)containingType != null && containingType.IsScriptClass && (object)_scopeBinder.LookupDeclaredField(designation) != null)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return SourceLocalSymbol.MakeLocalSymbolWithEnclosingContext(_scopeBinder.ContainingMemberOrLambda, _scopeBinder, _enclosingBinder, node.Type, designation.Identifier, node.IsOutVarDeclaration() ? LocalDeclarationKind.OutVariable : LocalDeclarationKind.DeclarationExpressionVariable, nodeToBind, (SyntaxNode)(object)argumentListSyntaxOpt);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected override LocalSymbol MakeDeconstructionVariable(TypeSyntax closestTypeSyntax, SingleVariableDesignationSyntax designation, AssignmentExpressionSyntax deconstruction)
|
||
|
|
{
|
||
|
|
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
|
||
|
|
NamedTypeSymbol containingType = _scopeBinder.ContainingType;
|
||
|
|
if ((object)containingType != null && containingType.IsScriptClass && (object)_scopeBinder.LookupDeclaredField(designation) != null)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return SourceLocalSymbol.MakeDeconstructionLocal(_scopeBinder.ContainingMemberOrLambda, _scopeBinder, _enclosingBinder, closestTypeSyntax, designation.Identifier, LocalDeclarationKind.DeconstructionVariable, (SyntaxNode)(object)deconstruction);
|
||
|
|
}
|
||
|
|
|
||
|
|
public static ObjectPool<ExpressionVariableFinder> CreatePool()
|
||
|
|
{
|
||
|
|
return new ObjectPool<ExpressionVariableFinder>((Factory<ExpressionVariableFinder>)(() => new ExpressionVariableFinder()), 10, true);
|
||
|
|
}
|
||
|
|
}
|