提交 21c77954 编写于 作者: M Manish Vasani 提交者: GitHub

Merge pull request #21791 from mavasani/LoopStatements

Changes to the IOperation API shape for loop statements
......@@ -1156,62 +1156,73 @@ private IIfStatement CreateBoundIfStatementOperation(BoundIfStatement boundIfSta
return new LazyIfStatement(condition, ifTrueStatement, ifFalseStatement, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IWhileUntilLoopStatement CreateBoundWhileStatementOperation(BoundWhileStatement boundWhileStatement)
private IWhileLoopStatement CreateBoundWhileStatementOperation(BoundWhileStatement boundWhileStatement)
{
bool isTopTest = true;
bool isWhile = true;
Lazy<IOperation> condition = new Lazy<IOperation>(() => Create(boundWhileStatement.Condition));
LoopKind loopKind = LoopKind.WhileUntil;
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 LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, loopKind, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyWhileLoopStatement(condition, body, locals, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IWhileUntilLoopStatement CreateBoundDoStatementOperation(BoundDoStatement boundDoStatement)
private IDoLoopStatement CreateBoundDoStatementOperation(BoundDoStatement boundDoStatement)
{
bool isTopTest = false;
bool isWhile = true;
DoLoopKind doLoopKind = DoLoopKind.DoWhileBottomLoop;
Lazy<IOperation> condition = new Lazy<IOperation>(() => Create(boundDoStatement.Condition));
LoopKind loopKind = LoopKind.WhileUntil;
Lazy<IOperation> body = new Lazy<IOperation>(() => Create(boundDoStatement.Body));
Lazy<IOperation> ignoredCondition = 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 LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, loopKind, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyDoLoopStatement(doLoopKind, condition, body, ignoredCondition, locals, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IForLoopStatement CreateBoundForStatementOperation(BoundForStatement boundForStatement)
{
Lazy<ImmutableArray<IOperation>> before = new Lazy<ImmutableArray<IOperation>>(() => ToStatements(boundForStatement.Initializer));
Lazy<IOperation> condition = new Lazy<IOperation>(() => Create(boundForStatement.Condition));
Lazy<ImmutableArray<IOperation>> atLoopBottom = new Lazy<ImmutableArray<IOperation>>(() => ToStatements(boundForStatement.Increment));
ImmutableArray<ILocalSymbol> locals = boundForStatement.OuterLocals.As<ILocalSymbol>();
Lazy<IOperation> condition = new Lazy<IOperation>(() => Create(boundForStatement.Condition));
LoopKind loopKind = LoopKind.For;
Lazy<IOperation> body = new Lazy<IOperation>(() => Create(boundForStatement.Body));
SyntaxNode syntax = boundForStatement.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundForStatement.WasCompilerGenerated;
return new LazyForLoopStatement(before, atLoopBottom, locals, condition, loopKind, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyForLoopStatement(before, condition, atLoopBottom, locals, body, _semanticModel, syntax, type, constantValue, isImplicit);
}
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();
bool isDeclaration = true;
loopControlVariable = new Lazy<IOperation>(() => new LocalReferenceExpression(local, isDeclaration, _semanticModel, local.GetDeclaratorSyntax(), local.Type, local.ConstantValue, local.IsImplicitlyDeclared));
}
else
{
loopControlVariable = new Lazy<IOperation>(() => null);
}
Lazy<IOperation> collection = new Lazy<IOperation>(() => Create(boundForEachStatement.Expression));
LoopKind loopKind = LoopKind.ForEach;
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, loopKind, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyForEachLoopStatement(locals, loopControlVariable, collection, nextVariables, body, _semanticModel, syntax, type, constantValue, isImplicit);
}
private ISwitchStatement CreateBoundSwitchStatementOperation(BoundSwitchStatement boundSwitchStatement)
......
......@@ -993,7 +993,9 @@ static IEnumerable<T> MyIterator<T>(IEnumerable<T> source, Func<T, bool> predica
string expectedOperationTree = @"
ILocalFunctionStatement (Symbol: 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;')
IForEachLoopStatement (LoopKind.ForEach) (OperationKind.LoopStatement) (Syntax: 'foreach (va ... rn element;')
Locals: Local_1: T element
LoopControlVariable: ILocalReferenceExpression: element (IsDeclaration: True) (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,6 +1010,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
NextVariables(0)
IReturnStatement (OperationKind.YieldBreakStatement) (Syntax: '{ ... }')
ReturnedValue: null
";
......
......@@ -984,7 +984,10 @@ public void M()
}
";
string expectedOperationTree = @"
IForEachLoopStatement (Iteration variable: null) (LoopKind.ForEach) (OperationKind.LoopStatement) (Syntax: 'foreach (va ... }')
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) }')
......@@ -1004,6 +1007,7 @@ public void M()
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer: null
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
NextVariables(0)
";
var expectedDiagnostics = DiagnosticDescription.None;
......
......@@ -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; }
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Represents different kinds of do loop statements.
/// </summary>
public enum DoLoopKind
{
None = 0x0,
/// <summary>
/// Indicates a C# 'do while' or a VB 'Do While' loop where the loop condition is executed at the bottom of the loop, i.e. end of the loop iteration.
/// Loop executes while the loop condition evaluates to <code>true</code>.
/// </summary>
DoWhileBottomLoop = 0x1,
/// <summary>
/// Indicates a VB 'Do While' loop with the loop condition executed at the top of the loop, i.e. beginning of the loop iteration.
/// Loop executes while the loop condition evaluates to <code>true</code>.
/// </summary>
DoWhileTopLoop = 0x2,
/// <summary>
/// Indicates a VB 'Do Until' loop with the loop condition executed at the bottom of the loop, i.e. end of the loop iteration.
/// Loop executes while the loop condition evaluates to <code>false</code>.
/// </summary>
DoUntilBottomLoop = 0x3,
/// <summary>
/// Indicates a VB 'Do Until' loop with the loop condition executed at the top of the loop, i.e. beginning of the loop iteration.
/// 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,
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Represents a C# 'do while' or VB 'Do While' or 'Do Until' loop statement.
/// </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 IDoLoopStatement : ILoopStatement
{
/// <summary>
/// Condition of the loop.
/// </summary>
IOperation Condition { get; }
/// <summary>
/// Represents kind of do loop statement.
/// </summary>
DoLoopKind DoLoopKind { get; }
/// <summary>
/// Additional conditional supplied for loop in error cases, which is ignored by the compiler.
/// 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 ignored and exposed by this property.
/// This property should be null for all non-error cases.
/// </summary>
IOperation IgnoredCondition { 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,20 @@ namespace Microsoft.CodeAnalysis.Semantics
public interface IForEachLoopStatement : ILoopStatement
{
/// <summary>
/// Iteration variable of the loop.
/// Refers to the operation for declaring a new local variable or reference an existing variable or an expression.
/// </summary>
ILocalSymbol IterationVariable { get; }
IOperation LoopControlVariable { get; }
/// <summary>
/// Collection value over which the loop iterates.
/// </summary>
IOperation Collection { get; }
/// <summary>
/// Optional list of comma separated next variables at loop bottom in VB.
/// This list is always empty for C#.
/// </summary>
ImmutableArray<IOperation> NextVariables { get; }
}
}
......@@ -5,26 +5,28 @@
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Represents a C# for statement or a VB For statement.
/// Represents a C# 'for' loop statement.
/// </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 IForLoopStatement : IForWhileUntilLoopStatement
public interface IForLoopStatement : ILoopStatement
{
/// <summary>
/// Statements to execute before entry to the loop. For C# these come from the first clause of the for statement. For VB these initialize the index variable of the For statement.
/// List of operations to execute before entry to the loop. This comes from the first clause of the for statement.
/// </summary>
ImmutableArray<IOperation> Before { get; }
/// <summary>
/// Statements to execute at the bottom of the loop. For C# these come from the third clause of the for statement. For VB these increment the index variable of the For statement.
/// Condition of the loop. This comes from the second clause of the for statement.
/// </summary>
ImmutableArray<IOperation> AtLoopBottom { get; }
IOperation Condition { get; }
/// <summary>
/// Declarations local to the loop.
/// List of operations to execute at the bottom of the loop. This comes from the third clause of the for statement.
/// </summary>
ImmutableArray<ILocalSymbol> Locals { get; }
ImmutableArray<IOperation> AtLoopBottom { get; }
}
}
......@@ -5,22 +5,37 @@
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
/// Represents a C# while or do statement, or a VB While or Do statement.
/// Represents a VB 'For To' loop statement.
/// </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 IWhileUntilLoopStatement : IForWhileUntilLoopStatement
public interface IForToLoopStatement : ILoopStatement
{
/// <summary>
/// True if the loop test executes at the top of the loop; false if the loop test executes at the bottom of the loop.
/// Refers to the operation for declaring a new local variable or reference an existing variable or an expression.
/// </summary>
bool IsTopTest { get; }
IOperation LoopControlVariable { 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>
IOperation InitialValue { get; }
/// <summary>
/// True if the loop is a while loop; false if the loop is an until loop.
/// Operation for the limit value of the loop control variable. This comes from the expression after the 'To' keyword.
/// </summary>
bool IsWhile { get; }
IOperation LimitValue { get; }
/// <summary>
/// Optional operation for the step value of the loop control variable. This comes from the expression after the 'Step' keyword.
/// </summary>
IOperation StepValue { get; }
/// <summary>
/// Optional list of comma separated next variables at loop bottom.
/// </summary>
ImmutableArray<IOperation> NextVariables { get; }
}
}
......@@ -21,6 +21,10 @@ public interface ILoopStatement : IOperation
/// Body of the loop.
/// </summary>
IOperation Body { get; }
/// <summary>
/// Declared locals.
/// </summary>
ImmutableArray<ILocalSymbol> Locals { 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>
/// Represents a C# while, for, or do statement, or a VB While, For, or Do statement.
/// Represents a C# 'while' or a VB 'While' loop statement.
/// </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 IForWhileUntilLoopStatement : ILoopStatement
public interface IWhileLoopStatement : ILoopStatement
{
/// <summary>
/// Condition of the loop.
......
// 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 loops.
/// Kinds of loop statements.
/// </summary>
public enum LoopKind
{
None = 0x0,
/// <summary>
/// Indicates a C# while or do loop, or a VB While or Do loop.
/// Represents a <see cref="IDoLoopStatement"/> in C# or VB.
/// </summary>
Do = 0x1,
/// <summary>
/// Represents a <see cref="IWhileLoopStatement"/> in C# or VB.
/// </summary>
While = 0x2,
/// <summary>
/// Indicates a <see cref="IForLoopStatement"/> in C#.
/// </summary>
WhileUntil = 0x1,
For = 0x3,
/// <summary>
/// Indicates a C# for loop or a VB For loop.
/// Indicates a <see cref="IForToLoopStatement"/> in VB.
/// </summary>
For = 0x2,
ForTo = 0x4,
/// <summary>
/// Indicates a C# foreach loop or a VB For Each loop.
/// Indicates a <see cref="IForEachLoopStatement"/> in C# or VB.
/// </summary>
ForEach = 0x3
ForEach = 0x5
}
}
......@@ -84,19 +84,29 @@ public override IOperation VisitIfStatement(IIfStatement operation, object argum
return new IfStatement(Visit(operation.Condition), Visit(operation.IfTrueStatement), Visit(operation.IfFalseStatement), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitWhileUntilLoopStatement(IWhileUntilLoopStatement operation, object argument)
public override IOperation VisitDoLoopStatement(IDoLoopStatement operation, object argument)
{
return new WhileUntilLoopStatement(operation.IsTopTest, operation.IsWhile, Visit(operation.Condition), operation.LoopKind, 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.IgnoredCondition), 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.Locals, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitForLoopStatement(IForLoopStatement operation, object argument)
{
return new ForLoopStatement(VisitArray(operation.Before), VisitArray(operation.AtLoopBottom), operation.Locals, Visit(operation.Condition), operation.LoopKind, Visit(operation.Body), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
return new ForLoopStatement(VisitArray(operation.Before), Visit(operation.Condition), VisitArray(operation.AtLoopBottom), operation.Locals, Visit(operation.Body), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitForToLoopStatement(IForToLoopStatement operation, object argument)
{
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.Collection), operation.LoopKind, 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 VisitLabeledStatement(ILabeledStatement operation, object argument)
......@@ -200,11 +210,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)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
......
......@@ -80,8 +80,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>
......
......@@ -75,7 +75,12 @@ public virtual void VisitIfStatement(IIfStatement operation)
DefaultVisit(operation);
}
public virtual void VisitWhileUntilLoopStatement(IWhileUntilLoopStatement operation)
public virtual void VisitDoLoopStatement(IDoLoopStatement operation)
{
DefaultVisit(operation);
}
public virtual void VisitWhileLoopStatement(IWhileLoopStatement operation)
{
DefaultVisit(operation);
}
......@@ -85,6 +90,11 @@ public virtual void VisitForLoopStatement(IForLoopStatement operation)
DefaultVisit(operation);
}
public virtual void VisitForToLoopStatement(IForToLoopStatement operation)
{
DefaultVisit(operation);
}
public virtual void VisitForEachLoopStatement(IForEachLoopStatement operation)
{
DefaultVisit(operation);
......@@ -198,11 +208,6 @@ public virtual void VisitParameterReferenceExpression(IParameterReferenceExpress
DefaultVisit(operation);
}
public virtual void VisitSyntheticLocalReferenceExpression(ISyntheticLocalReferenceExpression operation)
{
DefaultVisit(operation);
}
public virtual void VisitInstanceReferenceExpression(IInstanceReferenceExpression operation)
{
DefaultVisit(operation);
......@@ -543,7 +548,12 @@ public virtual TResult VisitIfStatement(IIfStatement operation, TArgument argume
return DefaultVisit(operation, argument);
}
public virtual TResult VisitWhileUntilLoopStatement(IWhileUntilLoopStatement operation, TArgument argument)
public virtual TResult VisitDoLoopStatement(IDoLoopStatement operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitWhileLoopStatement(IWhileLoopStatement operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
......@@ -553,6 +563,11 @@ public virtual TResult VisitForLoopStatement(IForLoopStatement operation, TArgum
return DefaultVisit(operation, argument);
}
public virtual TResult VisitForToLoopStatement(IForToLoopStatement operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitForEachLoopStatement(IForEachLoopStatement operation, TArgument argument)
{
return DefaultVisit(operation, argument);
......@@ -666,11 +681,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
}
}
......@@ -920,63 +920,89 @@ Namespace Microsoft.CodeAnalysis.Semantics
Return New LazyRelationalCaseClause(value, relation, CaseKind, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundDoLoopStatementOperation(boundDoLoopStatement As BoundDoLoopStatement) As IWhileUntilLoopStatement
Dim isTopTest As Boolean = boundDoLoopStatement.ConditionIsTop
Dim isWhile As Boolean = Not boundDoLoopStatement.ConditionIsUntil
Private Function CreateBoundDoLoopStatementOperation(boundDoLoopStatement As BoundDoLoopStatement) As IDoLoopStatement
Dim doLoopKind As DoLoopKind = GetDoLoopKind(boundDoLoopStatement)
Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.ConditionOpt))
Dim LoopKind As LoopKind = LoopKind.WhileUntil
Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundDoLoopStatement.Body))
Dim ignoredConditionOpt 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 LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, LoopKind, body, _semanticModel, syntax, type, constantValue, isImplicit)
Return New LazyDoLoopStatement(doLoopKind, condition, body, ignoredConditionOpt, locals, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundForToStatementOperation(boundForToStatement As BoundForToStatement) As IForLoopStatement
Dim before As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Function()
Return GetForLoopStatementBefore(
boundForToStatement.ControlVariable,
boundForToStatement.InitialValue,
_semanticModel.CloneOperation(Create(boundForToStatement.LimitValue)),
_semanticModel.CloneOperation(Create(boundForToStatement.StepValue)))
End Function)
Dim atLoopBottom As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Function()
Return GetForLoopStatementAtLoopBottom(
_semanticModel.CloneOperation(Create(boundForToStatement.ControlVariable)),
boundForToStatement.StepValue,
boundForToStatement.OperatorsOpt)
End Function)
Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty
Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(
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
Else
Return DoLoopKind.DoWhileTopLoop
End If
Else
If boundDoLoopStatement.ConditionIsUntil Then
Return DoLoopKind.DoUntilBottomLoop
Else
Return DoLoopKind.DoWhileBottomLoop
End If
End If
End Function
Private Function CreateBoundForToStatementOperation(boundForToStatement As BoundForToStatement) As IForToLoopStatement
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 nextVariables As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Function()
Return GetForWhileUntilLoopStatementCondition(
boundForToStatement.ControlVariable,
boundForToStatement.LimitValue,
boundForToStatement.StepValue,
boundForToStatement.OperatorsOpt)
Return If(boundForToStatement.NextVariablesOpt.IsDefault,
ImmutableArray(Of IOperation).Empty,
boundForToStatement.NextVariablesOpt.SelectAsArray(Function(n) Create(n)))
End Function)
Dim LoopKind As LoopKind = LoopKind.For
Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForToStatement.Body))
Dim syntax As SyntaxNode = boundForToStatement.Syntax
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
Dim isImplicit As Boolean = boundForToStatement.WasCompilerGenerated
Return New LazyForLoopStatement(before, atLoopBottom, locals, condition, LoopKind, body, _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 = Nothing ' Manual
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 LoopKind As LoopKind = LoopKind.ForEach
Dim body As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundForEachStatement.Body))
Dim nextVariables As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(
Function()
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, collection, LoopKind, 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
......@@ -1057,17 +1083,15 @@ Namespace Microsoft.CodeAnalysis.Semantics
Return New ExpressionStatement(throwExpression, _semanticModel, syntax, statementType, constantValue, isImplicit)
End Function
Private Function CreateBoundWhileStatementOperation(boundWhileStatement As BoundWhileStatement) As IWhileUntilLoopStatement
Dim isTopTest As Boolean = True
Dim isWhile As Boolean = True
Private Function CreateBoundWhileStatementOperation(boundWhileStatement As BoundWhileStatement) As IWhileLoopStatement
Dim condition As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundWhileStatement.Condition))
Dim LoopKind As LoopKind = LoopKind.WhileUntil
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 LazyWhileUntilLoopStatement(isTopTest, isWhile, condition, LoopKind, 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
......
......@@ -240,155 +240,6 @@ Namespace Microsoft.CodeAnalysis.Semantics
Return Nothing
End Function
Private Function GetForLoopStatementBefore(
controlVariable As BoundExpression,
initialValue As BoundExpression,
limitValue As IOperation,
stepValue As IOperation) As ImmutableArray(Of IOperation)
Dim statements As ArrayBuilder(Of IOperation) = ArrayBuilder(Of IOperation).GetInstance()
' ControlVariable = InitialValue
If controlVariable IsNot Nothing Then
statements.Add(OperationFactory.CreateSimpleAssignmentExpressionStatement(Create(controlVariable), Create(initialValue), _semanticModel, initialValue.Syntax, isImplicit:=controlVariable.WasCompilerGenerated))
End If
' T0 = LimitValue
If Not limitValue.ConstantValue.HasValue Then
statements.Add(
OperationFactory.CreateSimpleAssignmentExpressionStatement(
New SyntheticLocalReferenceExpression(
SyntheticLocalKind.ForLoopLimitValue,
_semanticModel,
limitValue.Syntax,
limitValue.Type,
constantValue:=Nothing,
isImplicit:=limitValue.IsImplicit), limitValue, _semanticModel, limitValue.Syntax, limitValue.IsImplicit))
End If
' T1 = StepValue
If stepValue IsNot Nothing AndAlso Not stepValue.ConstantValue.HasValue Then
statements.Add(
OperationFactory.CreateSimpleAssignmentExpressionStatement(
New SyntheticLocalReferenceExpression(
SyntheticLocalKind.ForLoopStepValue,
_semanticModel,
stepValue.Syntax,
stepValue.Type,
constantValue:=Nothing,
isImplicit:=stepValue.IsImplicit), stepValue, _semanticModel, stepValue.Syntax, stepValue.IsImplicit))
End If
Return statements.ToImmutableAndFree()
End Function
Private Function GetForLoopStatementAtLoopBottom(
controlVariable As IOperation,
stepValue As BoundExpression,
operatorsOpt As BoundForToUserDefinedOperators) As ImmutableArray(Of IOperation)
Dim statements As ArrayBuilder(Of IOperation) = ArrayBuilder(Of IOperation).GetInstance()
If operatorsOpt IsNot Nothing Then
' Use the operator methods. Figure out the precise rules first.
Else
If controlVariable IsNot Nothing Then
' ControlVariable += StepValue
Dim controlType = DirectCast(controlVariable.Type, VisualBasic.Symbols.TypeSymbol)
Dim stepValueExpression As BoundExpression = If(stepValue, New BoundLiteral(Nothing, Semantics.Expression.SynthesizeNumeric(controlType, 1), controlType))
Dim value = Create(stepValueExpression)
Dim stepOperand As IOperation =
If(stepValueExpression.IsConstant,
value,
New SyntheticLocalReferenceExpression(
SyntheticLocalKind.ForLoopStepValue,
_semanticModel,
value.Syntax,
value.Type,
constantValue:=Nothing,
isImplicit:=value.IsImplicit))
statements.Add(OperationFactory.CreateCompoundAssignmentExpressionStatement(
controlVariable, stepOperand,
BinaryOperatorKind.Add, controlType.IsNullableType(), False,
Nothing, _semanticModel, stepValueExpression.Syntax, value.IsImplicit))
End If
End If
Return statements.ToImmutableAndFree()
End Function
Private Function GetForWhileUntilLoopStatementCondition(
controlVariable As BoundExpression,
limitValue As BoundExpression,
stepValue As BoundExpression,
operatorsOpt As BoundForToUserDefinedOperators) As IOperation
Dim limitValueOperation = Create(limitValue)
Dim limitValueReference As IOperation =
If(limitValue.IsConstant,
limitValueOperation,
New SyntheticLocalReferenceExpression(
SyntheticLocalKind.ForLoopLimitValue,
_semanticModel,
limitValueOperation.Syntax,
limitValueOperation.Type,
constantValue:=Nothing,
isImplicit:=limitValueOperation.IsImplicit))
' controlVariable can be a BoundBadExpression in case of error
Dim booleanType As ITypeSymbol = controlVariable.ExpressionSymbol?.DeclaringCompilation.GetSpecialType(SpecialType.System_Boolean)
If operatorsOpt IsNot Nothing Then
' Use the operator methods. Figure out the precise rules first.
Return Nothing
Else
' We are comparing the control variable against the limit value. Using
' either the default stepping constant, or a user supplied constant.
' This will be a lifted comparison if either the control variable or
' limit value is nullable itself.
Dim isLifted = controlVariable.Type.IsNullableType() OrElse
limitValue.Type.IsNullableType()
If stepValue Is Nothing OrElse (stepValue.IsConstant AndAlso stepValue.ConstantValueOpt IsNot Nothing) Then
' Either ControlVariable <= LimitValue or ControlVariable >= LimitValue, depending on whether the step value is negative.
Dim relationalCode As BinaryOperatorKind =
If(stepValue IsNot Nothing AndAlso stepValue.ConstantValueOpt.IsNegativeNumeric, BinaryOperatorKind.GreaterThanOrEqual, BinaryOperatorKind.LessThanOrEqual)
Return OperationFactory.CreateBinaryOperatorExpression(
relationalCode, _semanticModel.CloneOperation(Create(controlVariable)), limitValueReference, booleanType, _semanticModel, limitValueReference.Syntax, isLifted, isChecked:=False, isCompareText:=False, isImplicit:=limitValueReference.IsImplicit)
Else
' If(StepValue >= 0, ControlVariable <= LimitValue, ControlVariable >= LimitValue)
Dim value = Create(stepValue)
Dim stepValueReference As IOperation = New SyntheticLocalReferenceExpression(
SyntheticLocalKind.ForLoopStepValue,
_semanticModel,
value.Syntax,
value.Type,
constantValue:=Nothing,
isImplicit:=value.IsImplicit)
Dim stepRelationalCode As BinaryOperatorKind = BinaryOperatorKind.GreaterThanOrEqual
Dim stepConditionIsLifted = stepValue.Type.IsNullableType()
Dim stepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(stepRelationalCode,
stepValueReference,
OperationFactory.CreateLiteralExpression(Semantics.Expression.SynthesizeNumeric(stepValueReference.Type, 0), stepValue.Type, _semanticModel, stepValue.Syntax, stepValueReference.IsImplicit),
booleanType,
_semanticModel,
stepValue.Syntax,
stepConditionIsLifted,
isChecked:=False,
isCompareText:=False,
isImplicit:=stepValue.WasCompilerGenerated)
Dim positiveStepRelationalCode As BinaryOperatorKind = BinaryOperatorKind.LessThanOrEqual
Dim positiveStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(positiveStepRelationalCode, _semanticModel.CloneOperation(Create(controlVariable)), limitValueReference, booleanType, _semanticModel, limitValueReference.Syntax, isLifted, isChecked:=False, isCompareText:=False, isImplicit:=limitValueReference.IsImplicit)
Dim negativeStepRelationalCode As BinaryOperatorKind = BinaryOperatorKind.GreaterThanOrEqual
Dim negativeStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(negativeStepRelationalCode, _semanticModel.CloneOperation(Create(controlVariable)), _semanticModel.CloneOperation(limitValueReference), booleanType, _semanticModel, limitValueReference.Syntax, isLifted, isChecked:=False, isCompareText:=False, isImplicit:=limitValueReference.IsImplicit)
Return OperationFactory.CreateConditionalExpression(stepCondition, positiveStepCondition, negativeStepCondition, booleanType, _semanticModel, limitValueReference.Syntax, limitValueReference.IsImplicit)
End If
End If
End Function
Private Function GetVariableDeclarationStatementVariables(statement As BoundDimStatement) As ImmutableArray(Of IVariableDeclaration)
Dim builder = ArrayBuilder(Of IVariableDeclaration).GetInstance()
For Each base In statement.LocalDeclarations
......
......@@ -138,31 +138,6 @@ End Class
Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "").WithLocation(8, 13))
End Sub
<Fact>
Public Sub BigForVisualBasic()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Class C
Public Sub M1()
Dim x as Integer
For x = 1 To 200000 : Next
For x = 1 To 2000000 : Next
For x = 1500000 To 0 Step -2 : Next
For x = 3000000 To 0 Step -2 : Next
End Sub
End Class
]]>
</file>
</compilation>
Dim comp = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(source, parseOptions:=TestOptions.RegularWithIOperationFeature)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New BigForTestAnalyzer}, Nothing, Nothing, False,
Diagnostic(BigForTestAnalyzer.BigForDescriptor.Id, "For x = 1 To 2000000 : Next").WithLocation(5, 9),
Diagnostic(BigForTestAnalyzer.BigForDescriptor.Id, "For x = 3000000 To 0 Step -2 : Next").WithLocation(7, 9))
End Sub
<Fact>
Public Sub SwitchVisualBasic()
Dim source = <compilation>
......
......@@ -268,22 +268,14 @@ Class C
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IForLoopStatement (LoopKind.For) (OperationKind.LoopStatement) (Syntax: 'For i = 0 T ... Next')
Condition: IBinaryOperatorExpression (BinaryOperatorKind.LessThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: '10')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10')
Before:
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: '0')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: '0')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
AtLoopBottom:
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'For i = 0 T ... Next')
Expression: ICompoundAssignmentExpression (BinaryOperatorKind.Add) (OperationKind.CompoundAssignmentExpression, Type: System.Int32) (Syntax: 'For i = 0 T ... Next')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 1) (Syntax: 'For i = 0 T ... Next')
Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (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')
StepValue: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 1) (Syntax: 'For i = 0 T ... Next')
Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: 'For i = 0 T ... Next')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'For i = 0 T ... Next')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'System.Console.Write(i)')
Expression: IInvocationExpression (Sub System.Console.Write(value As System.Int32)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'System.Console.Write(i)')
......@@ -293,6 +285,7 @@ IForLoopStatement (LoopKind.For) (OperationKind.LoopStatement) (Syntax: 'For i =
ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
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
......@@ -205,29 +205,19 @@ Module Program
End Module
]]>.Value
Dim expectedOperationTree = <![CDATA[
IForLoopStatement (LoopKind.For) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
Condition: IBinaryOperatorExpression (BinaryOperatorKind.LessThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, IsInvalid) (Syntax: '')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
Right: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: null, IsInvalid) (Syntax: '')
Before:
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: '0')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, IsInvalid) (Syntax: '0')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0, IsInvalid) (Syntax: '0')
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: '')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: null, IsInvalid) (Syntax: '')
Left: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: null, IsInvalid) (Syntax: '')
Right: IInvalidExpression (OperationKind.InvalidExpression, Type: null, IsInvalid) (Syntax: '')
Children(0)
AtLoopBottom:
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
Expression: ICompoundAssignmentExpression (BinaryOperatorKind.Add) (OperationKind.CompoundAssignmentExpression, Type: System.Int32, IsInvalid) (Syntax: 'For i As In ... Next i')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
Right: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 1, IsInvalid) (Syntax: 'For i As In ... Next i')
Conversion: CommonConversion (Exists: True, IsIdentity: True, 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')
Dim expectedOperationTree = <![CDATA[
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: IInvalidExpression (OperationKind.InvalidExpression, Type: null, IsInvalid) (Syntax: '')
Children(0)
StepValue: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 1, IsInvalid) (Syntax: 'For i As In ... Next i')
Conversion: CommonConversion (Exists: True, IsIdentity: True, 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')
NextVariables(1):
ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
]]>.Value
Dim expectedDiagnostics = <![CDATA[
......@@ -254,41 +244,19 @@ Module Program
End Function
End Module]]>.Value
Dim expectedOperationTree = <![CDATA[
IForLoopStatement (LoopKind.For) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For Step (M ... Next')
Condition: IConditionalExpression (OperationKind.ConditionalExpression, Type: System.Boolean, IsInvalid) (Syntax: '')
Condition: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, IsInvalid) (Syntax: 'For Step (M ... Next')
Left: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopStepValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: 'For Step (M ... Next')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Object, Constant: 1, IsInvalid) (Syntax: 'For Step (M ... Next')
WhenTrue: IBinaryOperatorExpression (BinaryOperatorKind.LessThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, IsInvalid) (Syntax: '')
Left: ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: '')
Right: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: null, IsInvalid) (Syntax: '')
WhenFalse: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, IsInvalid) (Syntax: '')
Left: ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: '')
Right: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: null, IsInvalid) (Syntax: '')
Before:
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: '')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Object, IsInvalid) (Syntax: '')
Left: ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: '')
Right: IInvalidExpression (OperationKind.InvalidExpression, Type: null, IsInvalid) (Syntax: '')
Children(0)
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: '')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: null, IsInvalid) (Syntax: '')
Left: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: null, IsInvalid) (Syntax: '')
Right: IInvalidExpression (OperationKind.InvalidExpression, Type: null, IsInvalid) (Syntax: '')
Children(0)
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'For Step (M ... Next')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Object, IsInvalid) (Syntax: 'For Step (M ... Next')
Left: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopStepValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: 'For Step (M ... Next')
Right: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, IsInvalid) (Syntax: 'For Step (M ... Next')
Conversion: CommonConversion (Exists: True, 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')
AtLoopBottom:
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'For Step (M ... Next')
Expression: ICompoundAssignmentExpression (BinaryOperatorKind.Add) (OperationKind.CompoundAssignmentExpression, Type: System.Object, IsInvalid) (Syntax: 'For Step (M ... Next')
Left: ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: '')
Right: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopStepValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Object, IsInvalid) (Syntax: 'For Step (M ... Next')
Dim expectedOperationTree = <![CDATA[
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: IInvalidExpression (OperationKind.InvalidExpression, Type: null, IsInvalid) (Syntax: '')
Children(0)
LimitValue: IInvalidExpression (OperationKind.InvalidExpression, Type: null, IsInvalid) (Syntax: '')
Children(0)
StepValue: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, IsInvalid) (Syntax: 'For Step (M ... Next')
Conversion: CommonConversion (Exists: True, 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')
NextVariables(0)
]]>.Value
Dim expectedDiagnostics = <![CDATA[
......@@ -321,41 +289,20 @@ Module Program
End Module]]>.Value
Dim expectedOperationTree = <![CDATA[
IForLoopStatement (LoopKind.For) (OperationKind.LoopStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
Condition: IConditionalExpression (OperationKind.ConditionalExpression, Type: System.Boolean, IsInvalid) (Syntax: 'Program')
Condition: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, IsInvalid) (Syntax: 'x')
Left: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopStepValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0, IsInvalid) (Syntax: 'x')
WhenTrue: IBinaryOperatorExpression (BinaryOperatorKind.LessThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, IsInvalid) (Syntax: 'Program')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
Right: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'Program')
WhenFalse: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, IsInvalid) (Syntax: 'Program')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
Right: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'Program')
Before:
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: '0')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: '0')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'Program')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, IsInvalid) (Syntax: 'Program')
Left: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopLimitValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'Program')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) (Syntax: 'Program')
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'Program')
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'x')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Left: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopStepValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'x')
Children(0)
AtLoopBottom:
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'x')
Expression: ICompoundAssignmentExpression (BinaryOperatorKind.Add) (OperationKind.CompoundAssignmentExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Left: ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i As Integer')
Right: ISyntheticLocalReferenceExpression (SynthesizedLocalKind.ForLoopStepValue) (OperationKind.SyntheticLocalReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
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')
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'Program')
StepValue: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'x')
Children(0)
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'For i As In ... Next i')
NextVariables(1):
ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'i')
]]>.Value
Dim expectedDiagnostics = <![CDATA[
......
......@@ -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));
}
......@@ -724,45 +725,49 @@ private static bool IsIgnoredNode(SyntaxNode node)
}
}
var vbNode = (VisualBasic.VisualBasicSyntaxNode)node;
switch (vbNode.Kind())
{
case VisualBasic.SyntaxKind.SimpleArgument:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.ArgumentList ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.TupleExpression;
case VisualBasic.SyntaxKind.VariableDeclarator:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.LocalDeclarationStatement ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.FieldDeclaration;
case VisualBasic.SyntaxKind.EqualsValue:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.VariableDeclarator;
case VisualBasic.SyntaxKind.NamedFieldInitializer:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.ObjectMemberInitializer;
case VisualBasic.SyntaxKind.ObjectMemberInitializer:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.AnonymousObjectCreationExpression;
case VisualBasic.SyntaxKind.SelectStatement:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.SelectBlock;
case VisualBasic.SyntaxKind.CollectionInitializer:
case VisualBasic.SyntaxKind.ModifiedIdentifier:
case VisualBasic.SyntaxKind.CaseBlock:
case VisualBasic.SyntaxKind.CaseElseBlock:
case VisualBasic.SyntaxKind.CaseStatement:
case VisualBasic.SyntaxKind.CaseElseStatement:
case VisualBasic.SyntaxKind.WhileClause:
case VisualBasic.SyntaxKind.ArgumentList:
case VisualBasic.SyntaxKind.FromClause:
case VisualBasic.SyntaxKind.ExpressionRangeVariable:
case VisualBasic.SyntaxKind.LetClause:
case VisualBasic.SyntaxKind.JoinCondition:
case VisualBasic.SyntaxKind.AsNewClause:
case VisualBasic.SyntaxKind.ForStepClause:
case VisualBasic.SyntaxKind.UntilClause:
case VisualBasic.SyntaxKind.InterpolationAlignmentClause:
return true;
default:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.AddHandlerStatement ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.RemoveHandlerStatement ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.RaiseEventStatement;
if (node is VisualBasic.VisualBasicSyntaxNode vbNode)
{
switch (vbNode.Kind())
{
case VisualBasic.SyntaxKind.SimpleArgument:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.ArgumentList ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.TupleExpression;
case VisualBasic.SyntaxKind.VariableDeclarator:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.LocalDeclarationStatement ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.FieldDeclaration;
case VisualBasic.SyntaxKind.EqualsValue:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.VariableDeclarator;
case VisualBasic.SyntaxKind.NamedFieldInitializer:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.ObjectMemberInitializer;
case VisualBasic.SyntaxKind.ObjectMemberInitializer:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.AnonymousObjectCreationExpression;
case VisualBasic.SyntaxKind.SelectStatement:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.SelectBlock;
case VisualBasic.SyntaxKind.CollectionInitializer:
case VisualBasic.SyntaxKind.ModifiedIdentifier:
case VisualBasic.SyntaxKind.CaseBlock:
case VisualBasic.SyntaxKind.CaseElseBlock:
case VisualBasic.SyntaxKind.CaseStatement:
case VisualBasic.SyntaxKind.CaseElseStatement:
case VisualBasic.SyntaxKind.WhileClause:
case VisualBasic.SyntaxKind.ArgumentList:
case VisualBasic.SyntaxKind.FromClause:
case VisualBasic.SyntaxKind.ExpressionRangeVariable:
case VisualBasic.SyntaxKind.LetClause:
case VisualBasic.SyntaxKind.JoinCondition:
case VisualBasic.SyntaxKind.AsNewClause:
case VisualBasic.SyntaxKind.ForStepClause:
case VisualBasic.SyntaxKind.UntilClause:
case VisualBasic.SyntaxKind.InterpolationAlignmentClause:
return true;
default:
return vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.AddHandlerStatement ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.RemoveHandlerStatement ||
vbNode.Parent?.Kind() == VisualBasic.SyntaxKind.RaiseEventStatement;
}
}
throw ExceptionUtilities.Unreachable;
}
#endregion
}
......
......@@ -1942,15 +1942,15 @@ public sealed override void Initialize(AnalysisContext context)
(operationContext) =>
{
ILoopStatement loop = (ILoopStatement)operationContext.Operation;
if (loop.LoopKind == LoopKind.For)
if (loop.LoopKind == LoopKind.ForTo)
{
IForLoopStatement forLoop = (IForLoopStatement)loop;
var forCondition = forLoop.Condition;
var forLoop = (IForToLoopStatement)loop;
var forCondition = forLoop.LimitValue;
if (forCondition.HasErrors(operationContext.Compilation, operationContext.CancellationToken))
{
// Generate a warning to prove we didn't crash
operationContext.ReportDiagnostic(Diagnostic.Create(ForLoopConditionCrashDescriptor, forLoop.Condition.Syntax.GetLocation()));
operationContext.ReportDiagnostic(Diagnostic.Create(ForLoopConditionCrashDescriptor, forLoop.LimitValue.Syntax.GetLocation()));
}
}
},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册