提交 fbfa6ab6 编写于 作者: M Manish Vasani

Address PR feedback

1. Add Locals property to ILoopStatement
2. Remove IterationVariable from foreach loops and VB ForTo loops.
3. Add InvalidCondition to Do loops for VB error cases.
4. Rename property AddLoopBottomExpressionList to NextVariables
5. Add relevant unit tests
6. Remove ISyntheticLocalReferenceExpression and SyntheticLocalKind
上级 9734c226
......@@ -1134,11 +1134,12 @@ private IWhileLoopStatement CreateBoundWhileStatementOperation(BoundWhileStateme
{
Lazy<IOperation> condition = new Lazy<IOperation>(() => Create(boundWhileStatement.Condition));
Lazy<IOperation> body = new Lazy<IOperation>(() => Create(boundWhileStatement.Body));
ImmutableArray<ILocalSymbol> locals = boundWhileStatement.Locals.As<ILocalSymbol>();
SyntaxNode syntax = boundWhileStatement.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundWhileStatement.WasCompilerGenerated;
return new LazyWhileLoopStatement(condition, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyWhileLoopStatement(condition, body, locals, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IDoLoopStatement CreateBoundDoStatementOperation(BoundDoStatement boundDoStatement)
......@@ -1146,11 +1147,13 @@ private IDoLoopStatement CreateBoundDoStatementOperation(BoundDoStatement boundD
DoLoopKind doLoopKind = DoLoopKind.DoWhileBottomLoop;
Lazy<IOperation> condition = new Lazy<IOperation>(() => Create(boundDoStatement.Condition));
Lazy<IOperation> body = new Lazy<IOperation>(() => Create(boundDoStatement.Body));
Lazy<IOperation> invalidCondition = new Lazy<IOperation>(() => null);
ImmutableArray<ILocalSymbol> locals = boundDoStatement.Locals.As<ILocalSymbol>();
SyntaxNode syntax = boundDoStatement.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundDoStatement.WasCompilerGenerated;
return new LazyDoLoopStatement(doLoopKind, condition, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyDoLoopStatement(doLoopKind, condition, body, invalidCondition, locals, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IForLoopStatement CreateBoundForStatementOperation(BoundForStatement boundForStatement)
......@@ -1169,16 +1172,30 @@ private IForLoopStatement CreateBoundForStatementOperation(BoundForStatement bou
private IForEachLoopStatement CreateBoundForEachStatementOperation(BoundForEachStatement boundForEachStatement)
{
ILocalSymbol iterationVariable = boundForEachStatement.IterationVariables.Length == 1 ?
boundForEachStatement.IterationVariables.FirstOrDefault() :
null;
ImmutableArray<ILocalSymbol> locals = boundForEachStatement.IterationVariables.As<ILocalSymbol>();
Lazy<IOperation> loopControlVariable;
if (boundForEachStatement.DeconstructionOpt != null)
{
loopControlVariable = new Lazy<IOperation>(() => Create(boundForEachStatement.DeconstructionOpt));
}
else if (locals.Length == 1)
{
var local = (LocalSymbol)locals.Single();
loopControlVariable = new Lazy<IOperation>(() => new LocalReferenceExpression(local, _semanticModel, local.GetDeclaratorSyntax(), local.Type, local.ConstantValue, local.IsImplicitlyDeclared));
}
else
{
loopControlVariable = new Lazy<IOperation>(() => null);
}
Lazy<IOperation> collection = new Lazy<IOperation>(() => Create(boundForEachStatement.Expression));
Lazy<IOperation> body = new Lazy<IOperation>(() => Create(boundForEachStatement.Body));
Lazy<ImmutableArray<IOperation>> nextVariables = new Lazy<ImmutableArray<IOperation>>(() => ImmutableArray<IOperation>.Empty);
SyntaxNode syntax = boundForEachStatement.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundForEachStatement.WasCompilerGenerated;
return new LazyForEachLoopStatement(iterationVariable, collection, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyForEachLoopStatement(locals, loopControlVariable, collection, nextVariables, body, _semanticModel, syntax, type, constantValue, isImplicit);
}
private ISwitchStatement CreateBoundSwitchStatementOperation(BoundSwitchStatement boundSwitchStatement)
......
......@@ -992,8 +992,9 @@ static IEnumerable<T> MyIterator<T>(IEnumerable<T> source, Func<T, bool> predica
string expectedOperationTree = @"
ILocalFunctionStatement (Local Function: System.Collections.Generic.IEnumerable<T> Iterator()) (OperationKind.LocalFunctionStatement) (Syntax: 'IEnumerable ... }')
IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IForEachLoopStatement (Iteration variable: T element) (LoopKind.ForEach) (OperationKind.LoopStatement) (Syntax: 'foreach (va ... rn element;')
LoopControlVariable: null
IForEachLoopStatement (LoopKind.ForEach) (OperationKind.LoopStatement) (Syntax: 'foreach (va ... rn element;')
Locals: Local_1: T element
LoopControlVariable: ILocalReferenceExpression: element (OperationKind.LocalReferenceExpression, Type: T, Constant: null) (Syntax: 'foreach (va ... rn element;')
Collection: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable<T>) (Syntax: 'source')
Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IParameterReferenceExpression: source (OperationKind.ParameterReferenceExpression, Type: System.Collections.Generic.IEnumerable<T>) (Syntax: 'source')
......@@ -1008,7 +1009,7 @@ static IEnumerable<T> MyIterator<T>(IEnumerable<T> source, Func<T, bool> predica
IfTrue: IReturnStatement (OperationKind.YieldReturnStatement) (Syntax: 'yield return element;')
ReturnedValue: ILocalReferenceExpression: element (OperationKind.LocalReferenceExpression, Type: T) (Syntax: 'element')
IfFalse: null
AtLoopBottomExpressionList(0)
NextVariables(0)
IReturnStatement (OperationKind.YieldBreakStatement) (Syntax: '{ ... }')
ReturnedValue: null
";
......
......@@ -984,8 +984,10 @@ public void M()
}
";
string expectedOperationTree = @"
IForEachLoopStatement (Iteration variable: null) (LoopKind.ForEach) (OperationKind.LoopStatement) (Syntax: 'foreach (va ... }')
LoopControlVariable: null
IForEachLoopStatement (LoopKind.ForEach) (OperationKind.LoopStatement) (Syntax: 'foreach (va ... }')
Locals: Local_1: System.UInt32 x
Local_2: System.UInt32 y
LoopControlVariable: IOperation: (OperationKind.None) (Syntax: 'var (x, y)')
Collection: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'new Point[] ... int(0, 1) }')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: IArrayCreationExpression (Element Type: Point) (OperationKind.ArrayCreationExpression, Type: Point[]) (Syntax: 'new Point[] ... int(0, 1) }')
......@@ -1005,7 +1007,7 @@ public void M()
OutConversion: null
Initializer: null
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
AtLoopBottomExpressionList(0)
NextVariables(0)
";
var expectedDiagnostics = DiagnosticDescription.None;
......
......@@ -37,6 +37,7 @@ static void Main()
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerLessThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i < 4')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 4) (Syntax: '4')
InvalidCondition: null
Body: IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'sum += ids[i];')
Expression: ICompoundAssignmentExpression (BinaryOperationKind.IntegerAdd) (OperationKind.CompoundAssignmentExpression, Type: System.Int32) (Syntax: 'sum += ids[i]')
......@@ -951,6 +952,7 @@ static bool TakeOutParam<T>(T y, out T x)
";
string expectedOperationTree = @"
IWhileLoopStatement (LoopKind.While) (OperationKind.LoopStatement) (Syntax: 'while (Dumm ... }')
Locals: Local_1: System.Int32 x1
Condition: IInvocationExpression (System.Boolean X.Dummy(System.Boolean x, System.Object y, System.Object z)) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: 'Dummy(f, Ta ... ar x1), x1)')
Instance Receiver: null
Arguments(3):
......@@ -999,5 +1001,82 @@ static bool TakeOutParam<T>(T y, out T x)
";
VerifyOperationTreeForTest<WhileStatementSyntax>(source, expectedOperationTree);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(17602, "https://github.com/dotnet/roslyn/issues/17602")]
public void IWhileUntilLoopStatement_DoWithOutVar()
{
string source = @"
class X
{
public static void Main()
{
bool f = true;
/*<bind>*/do
{
f = false;
} while (Dummy(f, TakeOutParam((f ? 1 : 2), out var x1), x1));/*</bind>*/
}
static bool Dummy(bool x, object y, object z)
{
System.Console.WriteLine(z);
return x;
}
static bool TakeOutParam<T>(T y, out T x)
{
x = y;
return true;
}
}
";
string expectedOperationTree = @"
IDoLoopStatement (DoLoopKind: DoWhileBottomLoop) (LoopKind.Do) (OperationKind.LoopStatement) (Syntax: 'do ... x1), x1));')
Locals: Local_1: System.Int32 x1
Condition: IInvocationExpression (System.Boolean X.Dummy(System.Boolean x, System.Object y, System.Object z)) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: 'Dummy(f, Ta ... ar x1), x1)')
Instance Receiver: null
Arguments(3):
IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: 'f')
ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: System.Boolean) (Syntax: 'f')
InConversion: null
OutConversion: null
IArgument (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument) (Syntax: 'TakeOutPara ... out var x1)')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'TakeOutPara ... out var x1)')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IInvocationExpression (System.Boolean X.TakeOutParam<System.Int32>(System.Int32 y, out System.Int32 x)) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: 'TakeOutPara ... out var x1)')
Instance Receiver: null
Arguments(2):
IArgument (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument) (Syntax: 'f ? 1 : 2')
IConditionalExpression (OperationKind.ConditionalExpression, Type: System.Int32) (Syntax: 'f ? 1 : 2')
Condition: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: System.Boolean) (Syntax: 'f')
WhenTrue: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
WhenFalse: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) (Syntax: '2')
InConversion: null
OutConversion: null
IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: 'var x1')
ILocalReferenceExpression: x1 (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'var x1')
InConversion: null
OutConversion: null
InConversion: null
OutConversion: null
IArgument (ArgumentKind.Explicit, Matching Parameter: z) (OperationKind.Argument) (Syntax: 'x1')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'x1')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILocalReferenceExpression: x1 (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'x1')
InConversion: null
OutConversion: null
InvalidCondition: null
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'f = false;')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Boolean) (Syntax: 'f = false')
Left: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: System.Boolean) (Syntax: 'f')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: False) (Syntax: 'false')
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<DoStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
......@@ -5,7 +5,7 @@
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Represents a C# fixed staement.
/// Represents a C# fixed statement.
/// </summary>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Represents a reference to a local variable synthesized by language analysis.
/// </summary>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
public interface ISyntheticLocalReferenceExpression : IOperation
{
/// <summary>
/// Kind of the synthetic local.
/// </summary>
SyntheticLocalKind SyntheticLocalKind { get; }
}
}
......@@ -32,6 +32,11 @@ public enum DoLoopKind
/// Loop executes while the loop condition evaluates to <code>false</code>.
/// </summary>
DoUntilTopLoop = 0x4,
/// <summary>
/// Indicates an invalid loop. For example, VB 'Do While' or 'Do Until' loop with syntax errors where both the top and bottom conditions are provided.
/// </summary>
Invalid = 0xf,
}
}
......@@ -20,6 +20,14 @@ public interface IDoLoopStatement : ILoopStatement
/// Represents kind of do loop statement.
/// </summary>
DoLoopKind DoLoopKind { get; }
/// <summary>
/// Additional conditional supplied for loop in error cases.
/// For example, for VB 'Do While' or 'Do Until' loop with syntax errors where both the top and bottom conditions are provided.
/// The top condition is preferred and exposed as <see cref="Condition"/> and the bottom condition is exposed by this property.
/// This property should be null for all non-error cases.
/// </summary>
IOperation InvalidCondition { get; }
}
}
......@@ -5,7 +5,7 @@
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Represents a C# 'foreach' statement or a VB 'For Each' staement.
/// Represents a C# 'foreach' statement or a VB 'For Each' statement.
/// </summary>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
......@@ -14,13 +14,7 @@ namespace Microsoft.CodeAnalysis.Semantics
public interface IForEachLoopStatement : ILoopStatement
{
/// <summary>
/// Iteration variable of the loop.
/// </summary>
ILocalSymbol IterationVariable { get; }
/// <summary>
/// Optional loop control variable in VB that refers to the operation for declaring a new local variable or reference an existing variable or an expression.
/// This field is always null for C#.
/// Refers to the operation for declaring a new local variable or reference an existing variable or an expression.
/// </summary>
IOperation LoopControlVariable { get; }
......@@ -30,10 +24,10 @@ public interface IForEachLoopStatement : ILoopStatement
IOperation Collection { get; }
/// <summary>
/// Optional list comma separate operations to execute at loop bottom in VB.
/// Optional list of comma separated next variables at loop bottom in VB.
/// This list is always empty for C#.
/// </summary>
ImmutableArray<IOperation> AtLoopBottomExpressionList { get; }
ImmutableArray<IOperation> NextVariables { get; }
}
}
......@@ -27,11 +27,6 @@ public interface IForLoopStatement : ILoopStatement
/// List of operations to execute at the bottom of the loop. This comes from the third clause of the for statement.
/// </summary>
ImmutableArray<IOperation> AtLoopBottom { get; }
/// <summary>
/// Declarations local to the loop.
/// </summary>
ImmutableArray<ILocalSymbol> Locals { get; }
}
}
......@@ -14,15 +14,10 @@ namespace Microsoft.CodeAnalysis.Semantics
public interface IForToLoopStatement : ILoopStatement
{
/// <summary>
/// Loop control variable refers to the operation for declaring a new local variable or reference an existing variable or an expression.
/// Refers to the operation for declaring a new local variable or reference an existing variable or an expression.
/// </summary>
IOperation LoopControlVariable { get; }
/// <summary>
/// Optional local variable symbol declared or inferred from <see cref="LoopControlVariable"/> which acts as the loop iteration variable.
/// </summary>
ILocalSymbol IterationVariable { get; }
/// <summary>
/// Operation for setting the initial value of the loop control variable. This comes from the expression between the 'For' and 'To' keywords.
/// </summary>
......@@ -39,8 +34,8 @@ public interface IForToLoopStatement : ILoopStatement
IOperation StepValue { get; }
/// <summary>
/// Optional list of comma separate operations to execute at loop bottom.
/// Optional list of comma separated next variables at loop bottom.
/// </summary>
ImmutableArray<IOperation> AtLoopBottomExpressionList { get; }
ImmutableArray<IOperation> NextVariables { get; }
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
......@@ -19,6 +21,10 @@ public interface ILoopStatement : IOperation
/// Body of the loop.
/// </summary>
IOperation Body { get; }
/// <summary>
/// Declarations local to the loop.
/// </summary>
ImmutableArray<ILocalSymbol> Locals { get; }
}
}
......@@ -86,12 +86,12 @@ public override IOperation VisitIfStatement(IIfStatement operation, object argum
public override IOperation VisitDoLoopStatement(IDoLoopStatement operation, object argument)
{
return new DoLoopStatement(operation.DoLoopKind, Visit(operation.Condition), Visit(operation.Body), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
return new DoLoopStatement(operation.DoLoopKind, Visit(operation.Condition), Visit(operation.Body), Visit(operation.InvalidCondition), operation.Locals, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitWhileLoopStatement(IWhileLoopStatement operation, object argument)
{
return new WhileLoopStatement(Visit(operation.Condition), Visit(operation.Body), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
return new WhileLoopStatement(Visit(operation.Condition), Visit(operation.Body), operation.Locals, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitForLoopStatement(IForLoopStatement operation, object argument)
......@@ -101,12 +101,12 @@ public override IOperation VisitForLoopStatement(IForLoopStatement operation, ob
public override IOperation VisitForToLoopStatement(IForToLoopStatement operation, object argument)
{
return new ForToLoopStatement(operation.IterationVariable, Visit(operation.LoopControlVariable), Visit(operation.InitialValue), Visit(operation.LimitValue), Visit(operation.StepValue), Visit(operation.Body), VisitArray(operation.AtLoopBottomExpressionList), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
return new ForToLoopStatement(operation.Locals, Visit(operation.LoopControlVariable), Visit(operation.InitialValue), Visit(operation.LimitValue), Visit(operation.StepValue), Visit(operation.Body), VisitArray(operation.NextVariables), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitForEachLoopStatement(IForEachLoopStatement operation, object argument)
{
return new ForEachLoopStatement(operation.IterationVariable, Visit(operation.LoopControlVariable), Visit(operation.Collection), VisitArray(operation.AtLoopBottomExpressionList), Visit(operation.Body), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
return new ForEachLoopStatement(operation.Locals, Visit(operation.LoopControlVariable), Visit(operation.Collection), VisitArray(operation.NextVariables), Visit(operation.Body), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitLabelStatement(ILabelStatement operation, object argument)
......@@ -214,11 +214,6 @@ public override IOperation VisitParameterReferenceExpression(IParameterReference
return new ParameterReferenceExpression(operation.Parameter, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitSyntheticLocalReferenceExpression(ISyntheticLocalReferenceExpression operation, object argument)
{
return new SyntheticLocalReferenceExpression(operation.SyntheticLocalKind, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitInstanceReferenceExpression(IInstanceReferenceExpression operation, object argument)
{
return new InstanceReferenceExpression(operation.InstanceReferenceKind, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
......
......@@ -79,8 +79,7 @@ public enum OperationKind
LocalReferenceExpression = 0x105,
/// <summary>Indicates an <see cref="IParameterReferenceExpression"/>.</summary>
ParameterReferenceExpression = 0x106,
/// <summary>Indicates an <see cref="ISyntheticLocalReferenceExpression"/>.</summary>
SyntheticLocalReferenceExpression = 0x107,
// Unused 0x107
/// <summary>Indicates an <see cref="IFieldReferenceExpression"/>.</summary>
FieldReferenceExpression = 0x108,
/// <summary>Indicates an <see cref="IMethodBindingExpression"/>.</summary>
......
......@@ -205,11 +205,6 @@ public virtual void VisitParameterReferenceExpression(IParameterReferenceExpress
DefaultVisit(operation);
}
public virtual void VisitSyntheticLocalReferenceExpression(ISyntheticLocalReferenceExpression operation)
{
DefaultVisit(operation);
}
public virtual void VisitInstanceReferenceExpression(IInstanceReferenceExpression operation)
{
DefaultVisit(operation);
......@@ -680,11 +675,6 @@ public virtual TResult VisitParameterReferenceExpression(IParameterReferenceExpr
return DefaultVisit(operation, argument);
}
public virtual TResult VisitSyntheticLocalReferenceExpression(ISyntheticLocalReferenceExpression operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitInstanceReferenceExpression(IInstanceReferenceExpression operation, TArgument argument)
{
return DefaultVisit(operation, argument);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Kinds of synthetic local references.
/// </summary>
public enum SyntheticLocalKind
{
None = 0x0,
/// <summary>
/// Created to capture the step value of a VB for loop.
/// </summary>
ForLoopStepValue = 0x1,
/// <summary>
/// Created to capture the limit value of a VB for loop.
/// </summary>
ForLoopLimitValue = 0x2
}
}
......@@ -122,7 +122,6 @@ Microsoft.CodeAnalysis.OperationKind.SizeOfExpression = 514 -> Microsoft.CodeAna
Microsoft.CodeAnalysis.OperationKind.StopStatement = 80 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.SwitchCase = 1033 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.SwitchStatement = 4 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.SyntheticLocalReferenceExpression = 263 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.ThrowExpression = 519 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.TryStatement = 14 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.TupleExpression = 292 -> Microsoft.CodeAnalysis.OperationKind
......@@ -343,6 +342,7 @@ Microsoft.CodeAnalysis.Semantics.DoLoopKind.DoUntilBottomLoop = 3 -> Microsoft.C
Microsoft.CodeAnalysis.Semantics.DoLoopKind.DoUntilTopLoop = 4 -> Microsoft.CodeAnalysis.Semantics.DoLoopKind
Microsoft.CodeAnalysis.Semantics.DoLoopKind.DoWhileBottomLoop = 1 -> Microsoft.CodeAnalysis.Semantics.DoLoopKind
Microsoft.CodeAnalysis.Semantics.DoLoopKind.DoWhileTopLoop = 2 -> Microsoft.CodeAnalysis.Semantics.DoLoopKind
Microsoft.CodeAnalysis.Semantics.DoLoopKind.Invalid = 15 -> Microsoft.CodeAnalysis.Semantics.DoLoopKind
Microsoft.CodeAnalysis.Semantics.DoLoopKind.None = 0 -> Microsoft.CodeAnalysis.Semantics.DoLoopKind
Microsoft.CodeAnalysis.Semantics.IAddressOfExpression
Microsoft.CodeAnalysis.Semantics.IAddressOfExpression.Reference.get -> Microsoft.CodeAnalysis.IOperation
......@@ -420,6 +420,7 @@ Microsoft.CodeAnalysis.Semantics.IDeclarationPattern.DeclaredSymbol.get -> Micro
Microsoft.CodeAnalysis.Semantics.IDefaultCaseClause
Microsoft.CodeAnalysis.Semantics.IDefaultValueExpression
Microsoft.CodeAnalysis.Semantics.IDoLoopStatement
Microsoft.CodeAnalysis.Semantics.IDoLoopStatement.InvalidCondition.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IDoLoopStatement.Condition.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IDoLoopStatement.DoLoopKind.get -> Microsoft.CodeAnalysis.Semantics.DoLoopKind
Microsoft.CodeAnalysis.Semantics.IDynamicMemberReferenceExpression
......@@ -447,19 +448,16 @@ Microsoft.CodeAnalysis.Semantics.IFixedStatement
Microsoft.CodeAnalysis.Semantics.IFixedStatement.Body.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IFixedStatement.Variables.get -> Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement
Microsoft.CodeAnalysis.Semantics.IForEachLoopStatement
Microsoft.CodeAnalysis.Semantics.IForEachLoopStatement.AtLoopBottomExpressionList.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.IForEachLoopStatement.NextVariables.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.IForEachLoopStatement.Collection.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IForEachLoopStatement.IterationVariable.get -> Microsoft.CodeAnalysis.ILocalSymbol
Microsoft.CodeAnalysis.Semantics.IForEachLoopStatement.LoopControlVariable.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IForLoopStatement
Microsoft.CodeAnalysis.Semantics.IForLoopStatement.AtLoopBottom.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.IForLoopStatement.Before.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.IForLoopStatement.Condition.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IForLoopStatement.Locals.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement.AtLoopBottomExpressionList.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement.NextVariables.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement.InitialValue.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement.IterationVariable.get -> Microsoft.CodeAnalysis.ILocalSymbol
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement.LimitValue.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement.LoopControlVariable.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IForToLoopStatement.StepValue.get -> Microsoft.CodeAnalysis.IOperation
......@@ -518,6 +516,7 @@ Microsoft.CodeAnalysis.Semantics.ILockStatement.Body.get -> Microsoft.CodeAnalys
Microsoft.CodeAnalysis.Semantics.ILockStatement.Expression.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ILoopStatement
Microsoft.CodeAnalysis.Semantics.ILoopStatement.Body.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ILoopStatement.Locals.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
Microsoft.CodeAnalysis.Semantics.ILoopStatement.LoopKind.get -> Microsoft.CodeAnalysis.Semantics.LoopKind
Microsoft.CodeAnalysis.Semantics.IMemberInitializerExpression
Microsoft.CodeAnalysis.Semantics.IMemberInitializerExpression.InitializedMember.get -> Microsoft.CodeAnalysis.Semantics.IMemberReferenceExpression
......@@ -576,8 +575,6 @@ Microsoft.CodeAnalysis.Semantics.ISwitchStatement.Cases.get -> System.Collection
Microsoft.CodeAnalysis.Semantics.ISwitchStatement.Value.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ISymbolInitializer
Microsoft.CodeAnalysis.Semantics.ISymbolInitializer.Value.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ISyntheticLocalReferenceExpression
Microsoft.CodeAnalysis.Semantics.ISyntheticLocalReferenceExpression.SyntheticLocalKind.get -> Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind
Microsoft.CodeAnalysis.Semantics.IThrowExpression
Microsoft.CodeAnalysis.Semantics.IThrowExpression.Expression.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ITryStatement
......@@ -670,10 +667,6 @@ Microsoft.CodeAnalysis.Semantics.SimpleUnaryOperationKind.PostfixIncrement = 3 -
Microsoft.CodeAnalysis.Semantics.SimpleUnaryOperationKind.PrefixDecrement = 6 -> Microsoft.CodeAnalysis.Semantics.SimpleUnaryOperationKind
Microsoft.CodeAnalysis.Semantics.SimpleUnaryOperationKind.PrefixIncrement = 5 -> Microsoft.CodeAnalysis.Semantics.SimpleUnaryOperationKind
Microsoft.CodeAnalysis.Semantics.SimpleUnaryOperationKind.True = 9 -> Microsoft.CodeAnalysis.Semantics.SimpleUnaryOperationKind
Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind
Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind.ForLoopLimitValue = 2 -> Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind
Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind.ForLoopStepValue = 1 -> Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind
Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind.None = 0 -> Microsoft.CodeAnalysis.Semantics.SyntheticLocalKind
Microsoft.CodeAnalysis.Semantics.UnaryAndBinaryOperationExtensions
Microsoft.CodeAnalysis.Semantics.UnaryOperandKind
Microsoft.CodeAnalysis.Semantics.UnaryOperandKind.Boolean = 1536 -> Microsoft.CodeAnalysis.Semantics.UnaryOperandKind
......@@ -865,7 +858,6 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSizeOfExpression(
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitStopStatement(Microsoft.CodeAnalysis.Semantics.IStopStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSwitchCase(Microsoft.CodeAnalysis.Semantics.ISwitchCase operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSwitchStatement(Microsoft.CodeAnalysis.Semantics.ISwitchStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSyntheticLocalReferenceExpression(Microsoft.CodeAnalysis.Semantics.ISyntheticLocalReferenceExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitThrowExpression(Microsoft.CodeAnalysis.Semantics.IThrowExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTryStatement(Microsoft.CodeAnalysis.Semantics.ITryStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTupleExpression(Microsoft.CodeAnalysis.Semantics.ITupleExpression operation) -> void
......@@ -956,7 +948,6 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.Vi
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitStopStatement(Microsoft.CodeAnalysis.Semantics.IStopStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSwitchCase(Microsoft.CodeAnalysis.Semantics.ISwitchCase operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSwitchStatement(Microsoft.CodeAnalysis.Semantics.ISwitchStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSyntheticLocalReferenceExpression(Microsoft.CodeAnalysis.Semantics.ISyntheticLocalReferenceExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitThrowExpression(Microsoft.CodeAnalysis.Semantics.IThrowExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTryStatement(Microsoft.CodeAnalysis.Semantics.ITryStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTupleExpression(Microsoft.CodeAnalysis.Semantics.ITupleExpression operation, TArgument argument) -> TResult
......
......@@ -898,18 +898,32 @@ Namespace Microsoft.CodeAnalysis.Semantics
Private Function CreateBoundDoLoopStatementOperation(boundDoLoopStatement As BoundDoLoopStatement) As IDoLoopStatement
Dim doLoopKind As DoLoopKind = GetDoLoopKind(boundDoLoopStatement)
Dim isTopTest As Boolean = boundDoLoopStatement.ConditionIsTop
Dim isWhile As Boolean = Not boundDoLoopStatement.ConditionIsUntil
Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.ConditionOpt))
Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.Body))
Dim invalidConditionOpt As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function()
If doLoopKind = DoLoopKind.Invalid Then
Debug.Assert(boundDoLoopStatement.TopConditionOpt IsNot Nothing)
Debug.Assert(boundDoLoopStatement.BottomConditionOpt IsNot Nothing)
Debug.Assert(boundDoLoopStatement.ConditionOpt Is boundDoLoopStatement.TopConditionOpt)
Return Create(boundDoLoopStatement.BottomConditionOpt)
Else
Debug.Assert(boundDoLoopStatement.TopConditionOpt Is Nothing OrElse boundDoLoopStatement.BottomConditionOpt Is Nothing)
Return Nothing
End If
End Function)
Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty
Dim syntax As SyntaxNode = boundDoLoopStatement.Syntax
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
Dim isImplicit As Boolean = boundDoLoopStatement.WasCompilerGenerated
Return New LazyDoLoopStatement(doLoopKind, condition, body, _semanticModel, syntax, type, constantValue, isImplicit)
Return New LazyDoLoopStatement(doLoopKind, condition, body, invalidConditionOpt, locals, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Shared Function GetDoLoopKind(boundDoLoopStatement As BoundDoLoopStatement) As DoLoopKind
If boundDoLoopStatement.TopConditionOpt IsNot Nothing AndAlso boundDoLoopStatement.BottomConditionOpt IsNot Nothing Then
Return DoLoopKind.Invalid
End If
If boundDoLoopStatement.ConditionIsTop Then
If boundDoLoopStatement.ConditionIsUntil Then
Return DoLoopKind.DoUntilTopLoop
......@@ -926,13 +940,13 @@ Namespace Microsoft.CodeAnalysis.Semantics
End Function
Private Function CreateBoundForToStatementOperation(boundForToStatement As BoundForToStatement) As IForToLoopStatement
Dim iterationVariable As ILocalSymbol = boundForToStatement.DeclaredOrInferredLocalOpt
Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundForToStatement.DeclaredOrInferredLocalOpt IsNot Nothing, ImmutableArray.Create(Of ILocalSymbol)(boundForToStatement.DeclaredOrInferredLocalOpt), ImmutableArray(Of ILocalSymbol).Empty)
Dim loopControlVariable As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.ControlVariable))
Dim initialValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.InitialValue))
Dim limitValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.LimitValue))
Dim stepValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.StepValue))
Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.Body))
Dim atLoopBottomExpressionList As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Dim nextVariables As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Function()
Return boundForToStatement.NextVariablesOpt.NullToEmpty.Select(Function(n) Create(n)).ToImmutableArray
End Function)
......@@ -940,23 +954,25 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
Dim isImplicit As Boolean = boundForToStatement.WasCompilerGenerated
Return New LazyForToLoopStatement(iterationVariable, loopControlVariable, initialValue, limitValue, stepValue, body, atLoopBottomExpressionList, _semanticModel, syntax, type, constantValue, isImplicit)
Return New LazyForToLoopStatement(locals, loopControlVariable, initialValue, limitValue, stepValue, body, nextVariables, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundForEachStatementOperation(boundForEachStatement As BoundForEachStatement) As IForEachLoopStatement
Dim iterationVariable As ILocalSymbol = boundForEachStatement.DeclaredOrInferredLocalOpt
Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundForEachStatement.DeclaredOrInferredLocalOpt IsNot Nothing, ImmutableArray.Create(Of ILocalSymbol)(boundForEachStatement.DeclaredOrInferredLocalOpt), ImmutableArray(Of ILocalSymbol).Empty)
Dim loopControlVariable As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.ControlVariable))
Dim collection As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.Collection))
Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.Body))
Dim atLoopBottomExpressionList As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Dim nextVariables As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Function()
Return boundForEachStatement.NextVariablesOpt.NullToEmpty.Select(Function(n) Create(n)).ToImmutableArray
Return If(boundForEachStatement.NextVariablesOpt.IsDefault,
ImmutableArray(Of IOperation).Empty,
boundForEachStatement.NextVariablesOpt.SelectAsArray(Function(n) Create(n)))
End Function)
Dim syntax As SyntaxNode = boundForEachStatement.Syntax
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
Dim isImplicit As Boolean = boundForEachStatement.WasCompilerGenerated
Return New LazyForEachLoopStatement(iterationVariable, loopControlVariable, collection, atLoopBottomExpressionList, body, _semanticModel, syntax, type, constantValue, isImplicit)
Return New LazyForEachLoopStatement(locals, loopControlVariable, collection, nextVariables, body, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundTryStatementOperation(boundTryStatement As BoundTryStatement) As ITryStatement
......@@ -1038,11 +1054,12 @@ Namespace Microsoft.CodeAnalysis.Semantics
Private Function CreateBoundWhileStatementOperation(boundWhileStatement As BoundWhileStatement) As IWhileLoopStatement
Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWhileStatement.Condition))
Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWhileStatement.Body))
Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty
Dim syntax As SyntaxNode = boundWhileStatement.Syntax
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
Dim isImplicit As Boolean = boundWhileStatement.WasCompilerGenerated
Return New LazyWhileLoopStatement(condition, body, _semanticModel, syntax, type, constantValue, isImplicit)
Return New LazyWhileLoopStatement(condition, body, locals, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundDimStatementOperation(boundDimStatement As BoundDimStatement) As IVariableDeclarationStatement
......
......@@ -267,7 +267,8 @@ Class C
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IForToLoopStatement (Iteration variable: i As System.Int32) (LoopKind.ForTo) (OperationKind.LoopStatement) (Syntax: 'For i = 0 T ... Next')
IForToLoopStatement (LoopKind.ForTo) (OperationKind.LoopStatement) (Syntax: 'For i = 0 T ... Next')
Locals: Local_1: i As System.Int32
LoopControlVariable: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
InitialValue: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
LimitValue: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10')
......@@ -283,7 +284,7 @@ IForToLoopStatement (Iteration variable: i As System.Int32) (LoopKind.ForTo) (Op
ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
InConversion: null
OutConversion: null
AtLoopBottomExpressionList(0)
NextVariables(0)
]]>.Value
Dim expectedDiagnostics = String.Empty
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Semantics
Imports Microsoft.CodeAnalysis.Test.Utilities
......@@ -34,6 +34,7 @@ IDoLoopStatement (DoLoopKind: DoWhileBottomLoop) (LoopKind.Do) (OperationKind.Lo
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerLessThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i < 4')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 4) (Syntax: '4')
InvalidCondition: null
Body: IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: 'Do'BIND:"Do ... While i < 4')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'sum += ids(i)')
Expression: ICompoundAssignmentExpression (BinaryOperationKind.IntegerAdd) (OperationKind.CompoundAssignmentExpression, Type: System.Int32) (Syntax: 'sum += ids(i)')
......@@ -70,6 +71,7 @@ IDoLoopStatement (DoLoopKind: DoUntilTopLoop) (LoopKind.Do) (OperationKind.LoopS
Left: IFieldReferenceExpression: C.X As System.Int32 (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'X')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'X')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
InvalidCondition: null
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Do Until X ... Loop')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'X = X - 1')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'X = X - 1')
......@@ -973,6 +975,7 @@ IDoLoopStatement (DoLoopKind: DoWhileTopLoop) (LoopKind.Do) (OperationKind.LoopS
Condition: IInvocationExpression ( Function C.G() As System.Boolean) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: 'G()')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'G')
Arguments(0)
InvalidCondition: null
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Do While G( ... Loop')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(1)')
Expression: IInvocationExpression (Sub System.Console.WriteLine(value As System.Int32)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(1)')
......@@ -1011,6 +1014,7 @@ IDoLoopStatement (DoLoopKind: DoWhileBottomLoop) (LoopKind.Do) (OperationKind.Lo
Condition: IInvocationExpression ( Function C.G() As System.Boolean) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: 'G()')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'G')
Arguments(0)
InvalidCondition: null
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Do'BIND:"Do ... p While G()')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(1)')
Expression: IInvocationExpression (Sub System.Console.WriteLine(value As System.Int32)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(1)')
......@@ -1044,6 +1048,7 @@ IDoLoopStatement (DoLoopKind: DoUntilBottomLoop) (LoopKind.Do) (OperationKind.Lo
Left: IFieldReferenceExpression: C.X As System.Int32 (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'X')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'X')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
InvalidCondition: null
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Do'BIND:"Do ... Until X < 0')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'X = X - 1')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'X = X - 1')
......@@ -1106,5 +1111,44 @@ IWhileLoopStatement (LoopKind.While) (OperationKind.LoopStatement) (Syntax: 'Whi
]]>.Value
VerifyOperationTreeForTest(Of WhileBlockSyntax)(source, expectedOperationTree)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact(), WorkItem(17602, "https://github.com/dotnet/roslyn/issues/17602")>
Public Sub IWhileUntilLoopStatement_DoWhileWithTopAndBottomCondition()
Dim source = <![CDATA[
Class C
Sub M(i As Integer)
Do While i > 0'BIND:"Do While i > 0"
i = i + 1
Loop Until i <= 0
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IDoLoopStatement (DoLoopKind: Invalid) (LoopKind.Do) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'Do While i ... ntil i <= 0')
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i > 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
InvalidCondition: IBinaryOperatorExpression (BinaryOperationKind.IntegerLessThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i <= 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Do While i ... ntil i <= 0')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'i = i + 1')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'i = i + 1')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'i + 1')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC30238: 'Loop' cannot have a condition if matching 'Do' has one.
Loop Until i <= 0
~~~~~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of DoLoopBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
End Class
End Namespace
......@@ -208,7 +208,8 @@ End Module
]]>.Value
Dim expectedOperationTree = <![CDATA[
IForToLoopStatement (Iteration variable: i As System.Int32) (LoopKind.ForTo) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
IForToLoopStatement (LoopKind.ForTo) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
Locals: Local_1: i As System.Int32
LoopControlVariable: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
InitialValue: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0, IsInvalid) (Syntax: '0')
LimitValue: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) (Syntax: '')
......@@ -219,7 +220,7 @@ IForToLoopStatement (Iteration variable: i As System.Int32) (LoopKind.ForTo) (Op
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1, IsInvalid) (Syntax: 'For i As In ... Next i')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
AtLoopBottomExpressionList(1):
NextVariables(1):
ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
]]>.Value
......@@ -248,7 +249,8 @@ Module Program
End Module]]>.Value
Dim expectedOperationTree = <![CDATA[
IForToLoopStatement (Iteration variable: As System.Object) (LoopKind.ForTo) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For Step (M ... Next')
IForToLoopStatement (LoopKind.ForTo) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For Step (M ... Next')
Locals: Local_1: As System.Object
LoopControlVariable: ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: '')
InitialValue: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, IsInvalid) (Syntax: '')
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
......@@ -262,7 +264,7 @@ IForToLoopStatement (Iteration variable: As System.Object) (LoopKind.ForTo) (Op
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1, IsInvalid) (Syntax: 'For Step (M ... Next')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'For Step (M ... Next')
AtLoopBottomExpressionList(0)
NextVariables(0)
]]>.Value
Dim expectedDiagnostics = <![CDATA[
......@@ -295,7 +297,8 @@ Module Program
End Module]]>.Value
Dim expectedOperationTree = <![CDATA[
IForToLoopStatement (Iteration variable: i As System.Int32) (LoopKind.ForTo) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
IForToLoopStatement (LoopKind.ForTo) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
Locals: Local_1: i As System.Int32
LoopControlVariable: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
InitialValue: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
LimitValue: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) (Syntax: 'Program')
......@@ -306,7 +309,7 @@ IForToLoopStatement (Iteration variable: i As System.Int32) (LoopKind.ForTo) (Op
Operand: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'x')
Children(0)
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
AtLoopBottomExpressionList(1):
NextVariables(1):
ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
]]>.Value
......
......@@ -683,7 +683,8 @@ private static IEnumerable<IOperation> GetOperationsUptoInvalidOperation(IOperat
operation.Kind != OperationKind.None &&
operation.Kind != OperationKind.InvalidExpression &&
operation.Kind != OperationKind.InvalidStatement &&
operation.Kind != OperationKind.PlaceholderExpression)
operation.Kind != OperationKind.PlaceholderExpression &&
(operation.Kind != OperationKind.TupleExpression || !(semanticModel.GetOperationInternal(node.Parent)?.Kind == OperationKind.LoopStatement))) // https://github.com/dotnet/roslyn/issues/20798
{
Assert.True(set.Contains(operation));
}
......
......@@ -414,6 +414,7 @@ public override void VisitDoLoopStatement(IDoLoopStatement operation)
LogLoopStatementHeader(operation);
Visit(operation.Condition, "Condition");
Visit(operation.InvalidCondition, "InvalidCondition");
Visit(operation.Body, "Body");
}
......@@ -432,7 +433,6 @@ public override void VisitForLoopStatement(IForLoopStatement operation)
LogLoopStatementHeader(operation);
Visit(operation.Condition, "Condition");
LogLocals(operation.Locals);
VisitArray(operation.Before, "Before", logElementCount: false);
VisitArray(operation.AtLoopBottom, "AtLoopBottom", logElementCount: false);
Visit(operation.Body, "Body");
......@@ -441,9 +441,6 @@ public override void VisitForLoopStatement(IForLoopStatement operation)
public override void VisitForToLoopStatement(IForToLoopStatement operation)
{
LogString(nameof(IForToLoopStatement));
LogSymbol(operation.IterationVariable, " (Iteration variable");
LogString(")");
LogLoopStatementHeader(operation);
Visit(operation.LoopControlVariable, "LoopControlVariable");
......@@ -451,7 +448,7 @@ public override void VisitForToLoopStatement(IForToLoopStatement operation)
Visit(operation.LimitValue, "LimitValue");
Visit(operation.StepValue, "StepValue");
Visit(operation.Body, "Body");
VisitArray(operation.AtLoopBottomExpressionList, "AtLoopBottomExpressionList", logElementCount: true);
VisitArray(operation.NextVariables, "NextVariables", logElementCount: true);
}
private void LogLocals(IEnumerable<ILocalSymbol> locals, string header = "Locals")
......@@ -482,19 +479,19 @@ private void LogLoopStatementHeader(ILoopStatement operation)
var kindStr = $"{nameof(LoopKind)}.{operation.LoopKind}";
LogString($" ({kindStr})");
LogCommonPropertiesAndNewLine(operation);
LogLocals(operation.Locals);
}
public override void VisitForEachLoopStatement(IForEachLoopStatement operation)
{
LogString(nameof(IForEachLoopStatement));
LogSymbol(operation.IterationVariable, " (Iteration variable");
LogString(")");
LogLoopStatementHeader(operation);
Visit(operation.LoopControlVariable, "LoopControlVariable");
Visit(operation.Collection, "Collection");
Visit(operation.Body, "Body");
VisitArray(operation.AtLoopBottomExpressionList, "AtLoopBottomExpressionList", logElementCount: true);
VisitArray(operation.NextVariables, "NextVariables", logElementCount: true);
}
public override void VisitLabelStatement(ILabelStatement operation)
......@@ -700,16 +697,6 @@ public override void VisitParameterReferenceExpression(IParameterReferenceExpres
LogCommonPropertiesAndNewLine(operation);
}
public override void VisitSyntheticLocalReferenceExpression(ISyntheticLocalReferenceExpression operation)
{
LogString(nameof(ISyntheticLocalReferenceExpression));
var kindStr = $"{nameof(SynthesizedLocalKind)}.{operation.SyntheticLocalKind}";
LogString($" ({kindStr})");
LogCommonPropertiesAndNewLine(operation);
base.VisitSyntheticLocalReferenceExpression(operation);
}
public override void VisitInstanceReferenceExpression(IInstanceReferenceExpression operation)
{
LogString(nameof(IInstanceReferenceExpression));
......
......@@ -101,44 +101,47 @@ public override void VisitDefaultCaseClause(IDefaultCaseClause operation)
base.VisitDefaultCaseClause(operation);
}
public override void VisitDoLoopStatement(IDoLoopStatement operation)
private void WalkLoopStatement(ILoopStatement operation)
{
var loopKind = operation.LoopKind;
var isTopTest = operation.DoLoopKind;
foreach (var local in operation.Locals)
{
// empty loop body, just want to make sure it won't crash.
}
}
public override void VisitDoLoopStatement(IDoLoopStatement operation)
{
var doLoopKind = operation.DoLoopKind;
WalkLoopStatement(operation);
base.VisitDoLoopStatement(operation);
}
public override void VisitWhileLoopStatement(IWhileLoopStatement operation)
{
var loopKind = operation.LoopKind;
WalkLoopStatement(operation);
base.VisitWhileLoopStatement(operation);
}
public override void VisitForLoopStatement(IForLoopStatement operation)
{
var loopKind = operation.LoopKind;
foreach (var local in operation.Locals)
{
// empty loop body, just want to make sure it won't crash.
}
WalkLoopStatement(operation);
base.VisitForLoopStatement(operation);
}
public override void VisitForToLoopStatement(IForToLoopStatement operation)
{
var loopKind = operation.LoopKind;
var iteraionVariable = operation.IterationVariable;
WalkLoopStatement(operation);
base.VisitForToLoopStatement(operation);
}
public override void VisitForEachLoopStatement(IForEachLoopStatement operation)
{
var loopKind = operation.LoopKind;
var iteraionVariable = operation.IterationVariable;
WalkLoopStatement(operation);
base.VisitForEachLoopStatement(operation);
}
......@@ -266,13 +269,6 @@ public override void VisitParameterReferenceExpression(IParameterReferenceExpres
base.VisitParameterReferenceExpression(operation);
}
public override void VisitSyntheticLocalReferenceExpression(ISyntheticLocalReferenceExpression operation)
{
var syntheticLocalKind = operation.SyntheticLocalKind;
base.VisitSyntheticLocalReferenceExpression(operation);
}
public override void VisitInstanceReferenceExpression(IInstanceReferenceExpression operation)
{
var instanceReferenceKind = operation.InstanceReferenceKind;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册