未验证 提交 0b90e960 编写于 作者: D David Poeschl 提交者: GitHub

Merge pull request #30217 from mavasani/Issue29373

Add IOperation/CFG support for VB ReDim statement
......@@ -65,8 +65,7 @@ public C() : base()
compilation.VerifyOperationTree(node1, expectedOperationTree:
@"
IConstructorBodyOperation (OperationKind.ConstructorBodyOperation, Type: null, IsInvalid) (Syntax: 'public C() : base()
')
IConstructorBodyOperation (OperationKind.ConstructorBodyOperation, Type: null, IsInvalid) (Syntax: 'public C() : base()')
Initializer:
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsInvalid, IsImplicit) (Syntax: ': base()')
Expression:
......
......@@ -208,8 +208,7 @@ public void M()
}
";
string expectedOperationTree = @"
ILockOperation (OperationKind.Lock, Type: null, IsInvalid) (Syntax: 'lock (o)
')
ILockOperation (OperationKind.Lock, Type: null, IsInvalid) (Syntax: 'lock (o)')
Expression:
ILocalReferenceOperation: o (OperationKind.LocalReference, Type: System.Object) (Syntax: 'o')
Body:
......
......@@ -7185,4 +7185,126 @@ internal sealed class LazyRangeOperation : BaseRangeOperation
public override IOperation LeftOperand => this._leftOperand.Value;
public override IOperation RightOperand => this._rightOperand.Value;
}
internal abstract class BaseReDimOperation : Operation, IReDimOperation
{
protected BaseReDimOperation(bool preserve, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.ReDim, semanticModel, syntax, type, constantValue, isImplicit)
{
Preserve = preserve;
}
public abstract ImmutableArray<IReDimClauseOperation> Clauses { get; }
public bool Preserve { get; }
public sealed override IEnumerable<IOperation> Children
{
get
{
foreach (var clause in Clauses)
{
yield return clause;
}
}
}
public sealed override void Accept(OperationVisitor visitor)
{
visitor.VisitReDim(this);
}
public sealed override TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitReDim(this, argument);
}
}
internal sealed class ReDimOperation : BaseReDimOperation
{
public ReDimOperation(ImmutableArray<IReDimClauseOperation> clauses, bool preserve, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(preserve, semanticModel, syntax, type, constantValue, isImplicit)
{
Clauses = SetParentOperation(clauses, this);
}
public override ImmutableArray<IReDimClauseOperation> Clauses { get; }
}
internal sealed class LazyReDimOperation : BaseReDimOperation
{
private readonly Lazy<ImmutableArray<IReDimClauseOperation>> _lazyClauses;
public LazyReDimOperation(Lazy<ImmutableArray<IReDimClauseOperation>> clauses, bool preserve, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(preserve, semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyClauses = clauses;
}
public override ImmutableArray<IReDimClauseOperation> Clauses => SetParentOperation(_lazyClauses.Value, this);
}
internal abstract class BaseReDimClauseOperation : Operation, IReDimClauseOperation
{
protected BaseReDimClauseOperation(SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.ReDimClause, semanticModel, syntax, type, constantValue, isImplicit)
{
}
public abstract IOperation Operand { get; }
public abstract ImmutableArray<IOperation> DimensionSizes { get; }
public sealed override IEnumerable<IOperation> Children
{
get
{
Debug.Assert(Operand != null);
yield return Operand;
foreach (var index in DimensionSizes)
{
Debug.Assert(index != null);
yield return index;
}
}
}
public sealed override void Accept(OperationVisitor visitor)
{
visitor.VisitReDimClause(this);
}
public sealed override TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitReDimClause(this, argument);
}
}
internal sealed class ReDimClauseOperation : BaseReDimClauseOperation
{
public ReDimClauseOperation(IOperation operand, ImmutableArray<IOperation> dimensionSizes, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(semanticModel, syntax, type, constantValue, isImplicit)
{
Operand = SetParentOperation(operand, this);
DimensionSizes = SetParentOperation(dimensionSizes, this);
}
public override IOperation Operand { get; }
public override ImmutableArray<IOperation> DimensionSizes { get; }
}
internal sealed class LazyReDimClauseOperation : BaseReDimClauseOperation
{
private readonly Lazy<IOperation> _lazyOperand;
private readonly Lazy<ImmutableArray<IOperation>> _lazyDimensionSizes;
public LazyReDimClauseOperation(Lazy<IOperation> lazyOperand, Lazy<ImmutableArray<IOperation>> lazyDimensionSizes, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyOperand = lazyOperand;
_lazyDimensionSizes = lazyDimensionSizes;
}
public override IOperation Operand => SetParentOperation(_lazyOperand.Value, this);
public override ImmutableArray<IOperation> DimensionSizes => SetParentOperation(_lazyDimensionSizes.Value, this);
}
}
......@@ -6500,6 +6500,43 @@ IOperation visitInvalidOperationExpression(IInvalidOperation invalidOperation)
}
}
public override IOperation VisitReDim(IReDimOperation operation, int? argument)
{
StartVisitingStatement(operation);
// We split the ReDim clauses into separate ReDim operations to ensure that we preserve the evaluation order,
// i.e. each ReDim clause operand is re-allocated prior to evaluating the next clause.
// Mark the split ReDim operations as implicit if we have more than one ReDim clause.
bool isImplicit = operation.Clauses.Length > 1 || IsImplicit(operation);
foreach (var clause in operation.Clauses)
{
EvalStackFrame frame = PushStackFrame();
var visitedReDimClause = visitReDimClause(clause);
var visitedReDimOperation = new ReDimOperation(ImmutableArray.Create(visitedReDimClause), operation.Preserve,
semanticModel: null, operation.Syntax, operation.Type, operation.ConstantValue, isImplicit);
AddStatement(visitedReDimOperation);
PopStackFrameAndLeaveRegion(frame);
}
return FinishVisitingStatement(operation);
IReDimClauseOperation visitReDimClause(IReDimClauseOperation clause)
{
PushOperand(Visit(clause.Operand));
var visitedDimensionSizes = VisitArray(clause.DimensionSizes);
var visitedOperand = PopOperand();
return new ReDimClauseOperation(visitedOperand, visitedDimensionSizes, semanticModel: null,
clause.Syntax, clause.Type, clause.ConstantValue, IsImplicit(clause));
}
}
public override IOperation VisitReDimClause(IReDimClauseOperation operation, int? argument)
{
throw ExceptionUtilities.Unreachable;
}
public override IOperation VisitTranslatedQuery(ITranslatedQueryOperation operation, int? captureIdForResult)
{
return new TranslatedQueryExpression(Visit(operation.Operation), semanticModel: null, operation.Syntax, operation.Type, operation.ConstantValue, IsImplicit(operation));
......
// 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.Operations
{
/// <summary>
/// Represents an individual clause of an <see cref="IReDimOperation"/> to re-allocate storage space for a single array variable.
/// <para>
/// Current usage:
/// (1) VB ReDim clause.
/// </para>
/// </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 IReDimClauseOperation : IOperation
{
/// <summary>
/// Operand whose storage space needs to be re-allocated.
/// </summary>
IOperation Operand { get; }
/// <summary>
/// Sizes of the dimensions of the created array instance.
/// </summary>
ImmutableArray<IOperation> DimensionSizes { 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.Operations
{
/// <summary>
/// Represents the ReDim operation to re-allocate storage space for array variables.
/// <para>
/// Current usage:
/// (1) VB ReDim statement.
/// </para>
/// </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 IReDimOperation : IOperation
{
/// <summary>
/// Individual clauses of the ReDim operation.
/// </summary>
ImmutableArray<IReDimClauseOperation> Clauses { get; }
/// <summary>
/// Modifier used to preserve the data in the existing array when you change the size of only the last dimension.
/// </summary>
bool Preserve { get; }
}
}
......@@ -596,5 +596,15 @@ public override IOperation VisitRangeOperation(IRangeOperation operation, object
{
return new RangeOperation(operation.IsLifted, operation.IsImplicit, ((Operation)operation).OwningSemanticModel, operation.Syntax, operation.Type, Visit(operation.LeftOperand), Visit(operation.RightOperand), operation.Method);
}
public override IOperation VisitReDim(IReDimOperation operation, object argument)
{
return new ReDimOperation(VisitArray(operation.Clauses), operation.Preserve, ((Operation)operation).OwningSemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitReDimClause(IReDimClauseOperation operation, object argument)
{
return new ReDimClauseOperation(Visit(operation.Operand), VisitArray(operation.DimensionSizes), ((Operation)operation).OwningSemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
}
}
......@@ -209,9 +209,13 @@ public enum OperationKind
/// <summary>Indicates an <see cref="ISuppressNullableWarningOperation"/>.</summary>
SuppressNullableWarning = 0x62,
/// <summary>Indicates an <see cref="IRangeOperation"/>.</summary>
Range = 0x62,
Range = 0x63,
/// <summary>Indicates an <see cref="IFromEndIndexOperation"/>.</summary>
FromEndIndex = 0x63,
FromEndIndex = 0x64,
/// <summary>Indicates an <see cref="IReDimOperation"/>.</summary>
ReDim = 0x65,
/// <summary>Indicates an <see cref="IReDimClauseOperation"/>.</summary>
ReDimClause = 0x66,
// /// <summary>Indicates an <see cref="IFixedOperation"/>.</summary>
// https://github.com/dotnet/roslyn/issues/21281
......
......@@ -579,6 +579,16 @@ public virtual void VisitRangeOperation(IRangeOperation operation)
{
DefaultVisit(operation);
}
public virtual void VisitReDim(IReDimOperation operation)
{
DefaultVisit(operation);
}
public virtual void VisitReDimClause(IReDimClauseOperation operation)
{
DefaultVisit(operation);
}
}
/// <summary>
......@@ -1162,5 +1172,15 @@ public virtual TResult VisitRangeOperation(IRangeOperation operation, TArgument
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitReDim(IReDimOperation operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitReDimClause(IReDimClauseOperation operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
}
}
*REMOVED*Microsoft.CodeAnalysis.Operations.IEventAssignmentOperation.EventReference.get -> Microsoft.CodeAnalysis.Operations.IEventReferenceOperation
Microsoft.CodeAnalysis.OperationKind.FromEndIndex = 99 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.Range = 98 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.FromEndIndex = 100 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.Range = 99 -> Microsoft.CodeAnalysis.OperationKind
abstract Microsoft.CodeAnalysis.Compilation.ClassifyCommonConversion(Microsoft.CodeAnalysis.ITypeSymbol source, Microsoft.CodeAnalysis.ITypeSymbol destination) -> Microsoft.CodeAnalysis.Operations.CommonConversion
abstract Microsoft.CodeAnalysis.Compilation.ContainsSymbolsWithName(string name, Microsoft.CodeAnalysis.SymbolFilter filter = Microsoft.CodeAnalysis.SymbolFilter.TypeAndMember, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> bool
abstract Microsoft.CodeAnalysis.Compilation.GetSymbolsWithName(string name, Microsoft.CodeAnalysis.SymbolFilter filter = Microsoft.CodeAnalysis.SymbolFilter.TypeAndMember, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.ISymbol>
......@@ -107,6 +107,14 @@ Microsoft.CodeAnalysis.FlowAnalysis.IFlowCaptureReferenceOperation
Microsoft.CodeAnalysis.FlowAnalysis.IFlowCaptureReferenceOperation.Id.get -> Microsoft.CodeAnalysis.FlowAnalysis.CaptureId
Microsoft.CodeAnalysis.FlowAnalysis.IIsNullOperation
Microsoft.CodeAnalysis.FlowAnalysis.IIsNullOperation.Operand.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.OperationKind.ReDim = 101 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.ReDimClause = 102 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.Operations.IReDimClauseOperation
Microsoft.CodeAnalysis.Operations.IReDimClauseOperation.DimensionSizes.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Operations.IReDimClauseOperation.Operand.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Operations.IReDimOperation
Microsoft.CodeAnalysis.Operations.IReDimOperation.Clauses.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Operations.IReDimClauseOperation>
Microsoft.CodeAnalysis.Operations.IReDimOperation.Preserve.get -> bool
Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation
Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation.Local.get -> Microsoft.CodeAnalysis.ILocalSymbol
Microsoft.CodeAnalysis.ILocalSymbol.IsFixed.get -> bool
......@@ -169,6 +177,8 @@ virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitFlowCaptureRefer
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitFromEndIndexOperation(Microsoft.CodeAnalysis.Operations.IFromEndIndexOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitIsNull(Microsoft.CodeAnalysis.FlowAnalysis.IIsNullOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitRangeOperation(Microsoft.CodeAnalysis.Operations.IRangeOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitReDim(Microsoft.CodeAnalysis.Operations.IReDimOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitReDimClause(Microsoft.CodeAnalysis.Operations.IReDimClauseOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitStaticLocalInitializationSemaphore(Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor.VisitSuppressNullableWarningExpression(Microsoft.CodeAnalysis.Operations.ISuppressNullableWarningOperation operation) -> void
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitCaughtException(Microsoft.CodeAnalysis.FlowAnalysis.ICaughtExceptionOperation operation, TArgument argument) -> TResult
......@@ -179,5 +189,7 @@ virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.V
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitFromEndIndexOperation(Microsoft.CodeAnalysis.Operations.IFromEndIndexOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitIsNull(Microsoft.CodeAnalysis.FlowAnalysis.IIsNullOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitRangeOperation(Microsoft.CodeAnalysis.Operations.IRangeOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitReDim(Microsoft.CodeAnalysis.Operations.IReDimOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitReDimClause(Microsoft.CodeAnalysis.Operations.IReDimClauseOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitStaticLocalInitializationSemaphore(Microsoft.CodeAnalysis.FlowAnalysis.IStaticLocalInitializationSemaphoreOperation operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Operations.OperationVisitor<TArgument, TResult>.VisitSuppressNullableWarningExpression(Microsoft.CodeAnalysis.Operations.ISuppressNullableWarningOperation operation, TArgument argument) -> TResult
......@@ -53,22 +53,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Property
End Class
Partial Friend Class BoundRedimStatement
Protected Overrides ReadOnly Property Children As ImmutableArray(Of BoundNode)
Get
Return StaticCast(Of BoundNode).From(Me.Clauses)
End Get
End Property
End Class
Partial Friend Class BoundRedimClause
Protected Overrides ReadOnly Property Children As ImmutableArray(Of BoundNode)
Get
Return StaticCast(Of BoundNode).From(Me.Indices.Insert(0, Me.Operand))
End Get
End Property
End Class
Partial Friend Class BoundEraseStatement
Protected Overrides ReadOnly Property Children As ImmutableArray(Of BoundNode)
Get
......
......@@ -294,6 +294,10 @@ Namespace Microsoft.CodeAnalysis.Operations
Return Create(DirectCast(boundNode, BoundBadVariable).Expression)
Case BoundKind.NullableIsTrueOperator
Return CreateBoundNullableIsTrueOperator(DirectCast(boundNode, BoundNullableIsTrueOperator))
Case BoundKind.RedimStatement
Return CreateBoundReDimOperation(DirectCast(boundNode, BoundRedimStatement))
Case BoundKind.RedimClause
Return CreateBoundReDimClauseOperation(DirectCast(boundNode, BoundRedimClause))
Case BoundKind.AddressOfOperator,
BoundKind.ArrayLiteral,
......@@ -309,8 +313,6 @@ Namespace Microsoft.CodeAnalysis.Operations
BoundKind.OnErrorStatement,
BoundKind.PropertyGroup,
BoundKind.RangeVariable,
BoundKind.RedimClause,
BoundKind.RedimStatement,
BoundKind.ResumeStatement,
BoundKind.TypeAsValueExpression,
BoundKind.TypeExpression,
......@@ -1765,6 +1767,32 @@ Namespace Microsoft.CodeAnalysis.Operations
Return New LazyInvalidOperation(children, _semanticModel, syntax, type, constantValue, isImplicit)
End If
End Function
Private Function CreateBoundReDimOperation(boundRedimStatement As BoundRedimStatement) As IReDimOperation
Dim preserve As Boolean = boundRedimStatement.Syntax.Kind = SyntaxKind.ReDimPreserveStatement
Dim clauses As Lazy(Of ImmutableArray(Of IReDimClauseOperation)) = New Lazy(Of ImmutableArray(Of IReDimClauseOperation))(
Function()
Return boundRedimStatement.Clauses.SelectAsArray(Function(n)
Debug.Assert(preserve = n.Preserve)
Return DirectCast(Create(n), IReDimClauseOperation)
End Function)
End Function)
Dim syntax As SyntaxNode = boundRedimStatement.Syntax
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = Nothing
Dim isImplicit As Boolean = boundRedimStatement.WasCompilerGenerated
Return New LazyReDimOperation(clauses, preserve, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundReDimClauseOperation(boundRedimClause As BoundRedimClause) As IReDimClauseOperation
Dim operand As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundRedimClause.Operand))
Dim dimensionSizes As Lazy(Of ImmutableArray(Of IOperation)) = New Lazy(Of ImmutableArray(Of IOperation))(Function() boundRedimClause.Indices.SelectAsArray(Function(n) Create(n)))
Dim syntax As SyntaxNode = boundRedimClause.Syntax
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = Nothing
Dim isImplicit As Boolean = boundRedimClause.WasCompilerGenerated
Return New LazyReDimClauseOperation(operand, dimensionSizes, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
End Class
End Namespace
......
......@@ -770,11 +770,12 @@ Friend Class [Class]
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IOperation: (OperationKind.None, Type: null) (Syntax: 'ReDim intArray(x, x, x)')
Children(1):
IOperation: (OperationKind.None, Type: null) (Syntax: 'intArray(x, x, x)')
Children(4):
ILocalReferenceOperation: intArray (OperationKind.LocalReference, Type: System.Int32(,,)) (Syntax: 'intArray')
IReDimOperation (OperationKind.ReDim, Type: null) (Syntax: 'ReDim intArray(x, x, x)')
Clauses(1):
IReDimClauseOperation (OperationKind.ReDimClause, Type: null) (Syntax: 'intArray(x, x, x)')
Operand:
ILocalReferenceOperation: intArray (OperationKind.LocalReference, Type: System.Int32(,,)) (Syntax: 'intArray')
DimensionSizes(3):
IBinaryOperation (BinaryOperatorKind.Add, Checked) (OperationKind.BinaryOperator, Type: System.Int32, IsImplicit) (Syntax: 'x')
Left:
IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32) (Syntax: 'x')
......
......@@ -892,6 +892,48 @@ End Class",
Sub Goo()
_goo = 0
End Sub
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
<WorkItem(29373, "https://github.com/dotnet/roslyn/issues/29373")>
Public Async Function FieldIsReDimOperand() As Task
Await TestMissingInRegularAndScriptAsync(
"Class C
Private [|_goo()|] As Integer
Private Sub M()
Redim _goo(5)
End Sub
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
<WorkItem(29373, "https://github.com/dotnet/roslyn/issues/29373")>
Public Async Function FieldIsReDimPreserveOperand() As Task
Await TestMissingInRegularAndScriptAsync(
"Class C
Private [|_goo()|] As Integer
Private Sub M()
Redim Preserve _goo(5)
End Sub
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsMakeFieldReadonly)>
<WorkItem(29373, "https://github.com/dotnet/roslyn/issues/29373")>
Public Async Function FieldIsRedimIndex() As Task
Await TestInRegularAndScriptAsync(
"Class C
Private [|_goo()|] As Integer
Private Sub M(a() As Integer)
Redim a(_goo)
End Sub
End Class",
"Class C
Private ReadOnly _goo() As Integer
Private Sub M(a() As Integer)
Redim a(_goo)
End Sub
End Class")
End Function
End Class
......
......@@ -1764,6 +1764,8 @@ private static bool CanBeInControlFlowGraph(IOperation n)
case OperationKind.CaughtException:
case OperationKind.StaticLocalInitializationSemaphore:
case OperationKind.Discard:
case OperationKind.ReDim:
case OperationKind.ReDimClause:
return true;
}
......
......@@ -111,7 +111,7 @@ private static string GetSnippetFromSyntax(SyntaxNode syntax)
return "null";
}
var text = syntax.ToString();
var text = syntax.ToString().Trim(Environment.NewLine.ToCharArray());
var lines = text.Split(new[] { Environment.NewLine, "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()).ToArray();
if (lines.Length <= 1 && text.Length < 25)
{
......@@ -1825,6 +1825,25 @@ public override void VisitRangeOperation(IRangeOperation operation)
Visit(operation.RightOperand, nameof(operation.RightOperand));
}
public override void VisitReDim(IReDimOperation operation)
{
LogString(nameof(IReDimOperation));
if (operation.Preserve)
{
LogString(" (Preserve)");
}
LogCommonPropertiesAndNewLine(operation);
VisitArray(operation.Clauses, "Clauses", logElementCount: true);
}
public override void VisitReDimClause(IReDimClauseOperation operation)
{
LogString(nameof(IReDimClauseOperation));
LogCommonPropertiesAndNewLine(operation);
Visit(operation.Operand, "Operand");
VisitArray(operation.DimensionSizes, "DimensionSizes", logElementCount: true);
}
#endregion
}
}
......@@ -11,6 +11,7 @@
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.VisualBasic;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Test.Utilities
......@@ -1322,5 +1323,18 @@ public override void VisitRangeOperation(IRangeOperation operation)
Assert.Equal(index, children.Length);
}
public override void VisitReDim(IReDimOperation operation)
{
Assert.Equal(OperationKind.ReDim, operation.Kind);
AssertEx.Equal(operation.Clauses, operation.Children);
var preserve = operation.Preserve;
}
public override void VisitReDimClause(IReDimClauseOperation operation)
{
Assert.Equal(OperationKind.ReDimClause, operation.Kind);
AssertEx.Equal(SpecializedCollections.SingletonEnumerable(operation.Operand).Concat(operation.DimensionSizes), operation.Children);
}
}
}
......@@ -85,6 +85,13 @@ public static ValueUsageInfo GetValueUsageInfo(this IOperation operation)
return ValueUsageInfo.Read;
}
}
else if (operation.Parent is IReDimClauseOperation reDimClauseOperation &&
reDimClauseOperation.Operand == operation)
{
return (reDimClauseOperation.Parent as IReDimOperation)?.Preserve == true
? ValueUsageInfo.ReadWrite
: ValueUsageInfo.Write;
}
else if (IsInLeftOfDeconstructionAssignment(operation))
{
return ValueUsageInfo.Write;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册