Refactor IVariableDeclaration to allow for multiple levels of initializers.

上级 d81e2206
......@@ -1424,7 +1424,7 @@ private ICatchClause CreateBoundCatchBlockOperation(BoundCatchBlock boundCatchBl
private IFixedStatement CreateBoundFixedStatementOperation(BoundFixedStatement boundFixedStatement)
{
Lazy<IVariableDeclarationStatement> variables = new Lazy<IVariableDeclarationStatement>(() => (IVariableDeclarationStatement)Create(boundFixedStatement.Declarations));
Lazy<IVariableDeclarationGroup> variables = new Lazy<IVariableDeclarationGroup>(() => (IVariableDeclarationGroup)Create(boundFixedStatement.Declarations));
Lazy<IOperation> body = new Lazy<IOperation>(() => Create(boundFixedStatement.Body));
SyntaxNode syntax = boundFixedStatement.Syntax;
ITypeSymbol type = null;
......@@ -1548,7 +1548,7 @@ private IOperation CreateBoundLocalDeclarationOperation(BoundLocalDeclaration bo
return new LazyVariableDeclarationStatement(declarations, _semanticModel, varStatement, type, constantValue, isImplicit);
}
private IVariableDeclarationStatement CreateBoundMultipleLocalDeclarationsOperation(BoundMultipleLocalDeclarations boundMultipleLocalDeclarations)
private IVariableDeclarationGroup CreateBoundMultipleLocalDeclarationsOperation(BoundMultipleLocalDeclarations boundMultipleLocalDeclarations)
{
Lazy<ImmutableArray<IVariableDeclaration>> declarations = new Lazy<ImmutableArray<IVariableDeclaration>>(() =>
boundMultipleLocalDeclarations.LocalDeclarations.SelectAsArray(declaration => (IVariableDeclaration)CreateVariableDeclaration(declaration)));
......
......@@ -58,7 +58,7 @@ private IVariableDeclaration CreateVariableDeclarationInternal(BoundLocalDeclara
{
IOperation initializerValue = Create(boundLocalDeclaration.InitializerOpt);
SyntaxNode initializerSyntax = null;
bool isImplicit = false;
bool initializerIsImplicit = false;
if (syntax is VariableDeclaratorSyntax variableDeclarator)
{
initializerSyntax = variableDeclarator.Initializer;
......@@ -72,18 +72,24 @@ private IVariableDeclaration CreateVariableDeclarationInternal(BoundLocalDeclara
{
// There is no explicit syntax for the initializer, so we use the initializerValue's syntax and mark the operation as implicit.
initializerSyntax = initializerValue.Syntax;
isImplicit = true;
initializerIsImplicit = true;
}
initializer = OperationFactory.CreateVariableInitializer(initializerSyntax, initializerValue, _semanticModel, isImplicit);
initializer = OperationFactory.CreateVariableInitializer(initializerSyntax, initializerValue, _semanticModel, initializerIsImplicit);
}
return OperationFactory.CreateVariableDeclaration(boundLocalDeclaration.LocalSymbol, initializer, _semanticModel, syntax);
ILocalSymbol symbol = boundLocalDeclaration.LocalSymbol;
SyntaxNode syntaxNode = boundLocalDeclaration.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default;
bool isImplicit = false;
return new SingleVariableDeclaration(symbol, initializer, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IVariableDeclaration CreateVariableDeclaration(BoundLocal boundLocal)
{
return OperationFactory.CreateVariableDeclaration(boundLocal.LocalSymbol, initializer: null, semanticModel: _semanticModel, syntax: boundLocal.Syntax);
return new SingleVariableDeclaration(boundLocal.LocalSymbol, initializer: null, semanticModel: _semanticModel, syntax: boundLocal.Syntax, type: null, constantValue: default, isImplicit: false);
}
private IOperation CreateBoundCallInstanceOperation(BoundCall boundCall)
......
......@@ -1995,7 +1995,7 @@ void MixMethod()
compilation.VerifyDiagnostics();
var syntaxKinds = ImmutableArray.Create(SyntaxKind.VariableDeclaration);
var operationKinds = ImmutableArray.Create(OperationKind.VariableDeclaration);
var operationKinds = ImmutableArray.Create(OperationKind.SingleVariableDeclaration);
var analyzers = new DiagnosticAnalyzer[] { new GeneratedCodeSyntaxAndOperationAnalyzer(GeneratedCodeAnalysisFlags.None, syntaxKinds, operationKinds) };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
......
......@@ -383,7 +383,7 @@ static void F()
var variableDeclaration = syntaxTree.GetRoot().DescendantNodes().OfType<LocalDeclarationStatementSyntax>().Single();
var lambdaSyntax = (LambdaExpressionSyntax)variableDeclaration.Declaration.Variables.Single().Initializer.Value;
var variableDeclarationOperation = (IVariableDeclarationStatement)semanticModel.GetOperationInternal(variableDeclaration);
var variableDeclarationOperation = (IVariableDeclarationGroup)semanticModel.GetOperationInternal(variableDeclaration);
var variableTreeLambdaOperation = (IAnonymousFunctionExpression)variableDeclarationOperation.Declarations.Single().Initializer.Value;
var lambdaOperation = (IAnonymousFunctionExpression)semanticModel.GetOperationInternal(lambdaSyntax);
......@@ -391,7 +391,7 @@ static void F()
// return the same bound node.
Assert.Same(variableTreeLambdaOperation, lambdaOperation);
var variableDeclarationOperationSecondRequest = (IVariableDeclarationStatement)semanticModel.GetOperationInternal(variableDeclaration);
var variableDeclarationOperationSecondRequest = (IVariableDeclarationGroup)semanticModel.GetOperationInternal(variableDeclaration);
var variableTreeLambdaOperationSecondRequest = (IAnonymousFunctionExpression)variableDeclarationOperation.Declarations.Single().Initializer.Value;
var lambdaOperationSecondRequest = (IAnonymousFunctionExpression)semanticModel.GetOperationInternal(lambdaSyntax);
......
......@@ -5152,7 +5152,7 @@ private class ExpectedSymbolVerifier
public static SyntaxNode ReturnStatementSelector(SyntaxNode syntaxNode) => ((ReturnStatementSyntax)syntaxNode).Expression;
public static IOperation IVariableDeclarationStatementSelector(IOperation operation) =>
((IVariableDeclarationStatement)operation).Declarations.Single().Initializer;
((IVariableDeclarationGroup)operation).Declarations.Single().Initializer;
public static IOperation IVariableDeclarationSelector(IOperation operation) =>
((IVariableDeclaration)operation).Initializer.Value;
......@@ -5235,7 +5235,7 @@ private IOperation GetAndInvokeOperationSelector(IOperation operation)
switch (operation)
{
case IVariableDeclarationStatement _:
case IVariableDeclarationGroup _:
return IVariableDeclarationStatementSelector(operation);
case IVariableDeclaration _:
return IVariableDeclarationSelector(operation);
......
......@@ -1904,7 +1904,7 @@ internal abstract partial class BaseFixedStatement : Operation, IFixedStatement
{
}
protected abstract IVariableDeclarationStatement VariablesImpl { get; }
protected abstract IVariableDeclarationGroup VariablesImpl { get; }
protected abstract IOperation BodyImpl { get; }
public override IEnumerable<IOperation> Children
{
......@@ -1923,7 +1923,7 @@ public override IEnumerable<IOperation> Children
/// <summary>
/// Variables to be fixed.
/// </summary>
public IVariableDeclarationStatement Variables => Operation.SetParentOperation(VariablesImpl, this);
public IVariableDeclarationGroup Variables => Operation.SetParentOperation(VariablesImpl, this);
/// <summary>
/// Body of the fixed, over which the variables are fixed.
/// </summary>
......@@ -1943,14 +1943,14 @@ public override void Accept(OperationVisitor visitor)
/// </summary>
internal sealed partial class FixedStatement : BaseFixedStatement, IFixedStatement
{
public FixedStatement(IVariableDeclarationStatement variables, IOperation body, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
public FixedStatement(IVariableDeclarationGroup variables, IOperation body, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(semanticModel, syntax, type, constantValue, isImplicit)
{
VariablesImpl = variables;
BodyImpl = body;
}
protected override IVariableDeclarationStatement VariablesImpl { get; }
protected override IVariableDeclarationGroup VariablesImpl { get; }
protected override IOperation BodyImpl { get; }
}
......@@ -1959,16 +1959,16 @@ internal sealed partial class FixedStatement : BaseFixedStatement, IFixedStateme
/// </summary>
internal sealed partial class LazyFixedStatement : BaseFixedStatement, IFixedStatement
{
private readonly Lazy<IVariableDeclarationStatement> _lazyVariables;
private readonly Lazy<IVariableDeclarationGroup> _lazyVariables;
private readonly Lazy<IOperation> _lazyBody;
public LazyFixedStatement(Lazy<IVariableDeclarationStatement> variables, Lazy<IOperation> body, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit)
public LazyFixedStatement(Lazy<IVariableDeclarationGroup> variables, Lazy<IOperation> body, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyVariables = variables ?? throw new System.ArgumentNullException(nameof(variables));
_lazyBody = body ?? throw new System.ArgumentNullException(nameof(body));
}
protected override IVariableDeclarationStatement VariablesImpl => _lazyVariables.Value;
protected override IVariableDeclarationGroup VariablesImpl => _lazyVariables.Value;
protected override IOperation BodyImpl => _lazyBody.Value;
}
......@@ -5568,17 +5568,28 @@ public LazyUsingStatement(Lazy<IOperation> resources, Lazy<IOperation> body, Sem
/// </summary>
internal abstract partial class BaseVariableDeclaration : Operation, IVariableDeclaration
{
protected BaseVariableDeclaration(ImmutableArray<ILocalSymbol> variables, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.VariableDeclaration, semanticModel, syntax, type, constantValue, isImplicit)
protected BaseVariableDeclaration(OperationKind kind, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(kind, semanticModel, syntax, type, constantValue, isImplicit)
{
Variables = variables;
}
protected abstract IVariableInitializer InitializerImpl { get; }
/// <summary>
/// Symbols declared by the declaration. In VB, it's possible to declare multiple variables with the
/// same initializer. In C#, this will always have a single symbol.
/// Optional initializer of the variable.
/// </summary>
public ImmutableArray<ILocalSymbol> Variables { get; }
protected abstract IVariableInitializer InitializerImpl { get; }
public IVariableInitializer Initializer => Operation.SetParentOperation(InitializerImpl, this);
}
internal abstract partial class BaseSingleVariableDeclaration : BaseVariableDeclaration, ISingleVariableDeclaration
{
protected BaseSingleVariableDeclaration(ILocalSymbol symbol, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.SingleVariableDeclaration, semanticModel, syntax, type, constantValue, isImplicit)
{
Symbol = symbol;
}
public ILocalSymbol Symbol { get; }
public override IEnumerable<IOperation> Children
{
get
......@@ -5590,27 +5601,24 @@ public override IEnumerable<IOperation> Children
}
}
/// <summary>
/// Optional initializer of the variable.
/// </summary>
public IVariableInitializer Initializer => Operation.SetParentOperation(InitializerImpl, this);
public override void Accept(OperationVisitor visitor)
{
visitor.VisitVariableDeclaration(this);
visitor.VisitSingleVariableDeclaration(this);
}
public override TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitVariableDeclaration(this, argument);
return visitor.VisitSingleVariableDeclaration(this, argument);
}
}
/// <summary>
/// Represents a local variable declaration.
/// </summary>
internal sealed partial class VariableDeclaration : BaseVariableDeclaration, IVariableDeclaration
internal sealed partial class SingleVariableDeclaration : BaseSingleVariableDeclaration
{
public VariableDeclaration(ImmutableArray<ILocalSymbol> variables, IVariableInitializer initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(variables, semanticModel, syntax, type, constantValue, isImplicit)
public SingleVariableDeclaration(ILocalSymbol symbol, IVariableInitializer initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(symbol, semanticModel, syntax, type, constantValue, isImplicit)
{
InitializerImpl = initializer;
}
......@@ -5621,11 +5629,12 @@ internal sealed partial class VariableDeclaration : BaseVariableDeclaration, IVa
/// <summary>
/// Represents a local variable declaration.
/// </summary>
internal sealed partial class LazyVariableDeclaration : BaseVariableDeclaration, IVariableDeclaration
internal sealed partial class LazySingleVariableDeclaration : BaseSingleVariableDeclaration
{
private readonly Lazy<IVariableInitializer> _lazyInitializer;
public LazyVariableDeclaration(ImmutableArray<ILocalSymbol> variables, Lazy<IVariableInitializer> initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(variables, semanticModel, syntax, type, constantValue, isImplicit)
public LazySingleVariableDeclaration(ILocalSymbol symbol, Lazy<IVariableInitializer> initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(symbol, semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyInitializer = initializer ?? throw new System.ArgumentNullException(nameof(initializer));
}
......@@ -5633,10 +5642,77 @@ public LazyVariableDeclaration(ImmutableArray<ILocalSymbol> variables, Lazy<IVar
protected override IVariableInitializer InitializerImpl => _lazyInitializer.Value;
}
internal abstract partial class BaseMultiVariableDeclaration : BaseVariableDeclaration, IMultiVariableDeclaration
{
protected BaseMultiVariableDeclaration(SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.MultiVariableDeclaration, semanticModel, syntax, type, constantValue, isImplicit)
{
}
public ImmutableArray<ISingleVariableDeclaration> Declarations => Operation.SetParentOperation(DeclarationsImpl, this);
protected abstract ImmutableArray<ISingleVariableDeclaration> DeclarationsImpl { get; }
public override IEnumerable<IOperation> Children
{
get
{
foreach (var declaration in Declarations)
{
yield return declaration;
}
if (Initializer != null)
{
yield return Initializer;
}
}
}
public override void Accept(OperationVisitor visitor)
{
visitor.VisitMultiVariableDeclaration(this);
}
public override TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitMultiVariableDeclaration(this, argument);
}
}
internal partial class MultiVariableDeclaration : BaseMultiVariableDeclaration
{
public MultiVariableDeclaration(ImmutableArray<ISingleVariableDeclaration> declarations, IVariableInitializer initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(semanticModel, syntax, type, constantValue, isImplicit)
{
DeclarationsImpl = declarations;
InitializerImpl = initializer;
}
protected override ImmutableArray<ISingleVariableDeclaration> DeclarationsImpl { get; }
protected override IVariableInitializer InitializerImpl { get; }
}
internal partial class LazyMultiVariableDeclaration : BaseMultiVariableDeclaration
{
private readonly Lazy<ImmutableArray<ISingleVariableDeclaration>> _lazyDeclarations;
private readonly Lazy<IVariableInitializer> _lazyInitializer;
public LazyMultiVariableDeclaration(Lazy<ImmutableArray<ISingleVariableDeclaration>> declarations, Lazy<IVariableInitializer> initializer, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyDeclarations = declarations;
_lazyInitializer = initializer;
}
protected override ImmutableArray<ISingleVariableDeclaration> DeclarationsImpl => _lazyDeclarations.Value;
protected override IVariableInitializer InitializerImpl => _lazyInitializer.Value;
}
/// <summary>
/// Represents a local variable declaration statement.
/// </summary>
internal abstract partial class BaseVariableDeclarationStatement : Operation, IVariableDeclarationStatement
internal abstract partial class BaseVariableDeclarationStatement : Operation, IVariableDeclarationGroup
{
protected BaseVariableDeclarationStatement(SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.VariableDeclarationStatement, semanticModel, syntax, type, constantValue, isImplicit)
......@@ -5663,18 +5739,18 @@ public override IEnumerable<IOperation> Children
public ImmutableArray<IVariableDeclaration> Declarations => Operation.SetParentOperation(DeclarationsImpl, this);
public override void Accept(OperationVisitor visitor)
{
visitor.VisitVariableDeclarationStatement(this);
visitor.VisitVariableDeclarationGroup(this);
}
public override TResult Accept<TArgument, TResult>(OperationVisitor<TArgument, TResult> visitor, TArgument argument)
{
return visitor.VisitVariableDeclarationStatement(this, argument);
return visitor.VisitVariableDeclarationGroup(this, argument);
}
}
/// <summary>
/// Represents a local variable declaration statement.
/// </summary>
internal sealed partial class VariableDeclarationStatement : BaseVariableDeclarationStatement, IVariableDeclarationStatement
internal sealed partial class VariableDeclarationStatement : BaseVariableDeclarationStatement, IVariableDeclarationGroup
{
public VariableDeclarationStatement(ImmutableArray<IVariableDeclaration> declarations, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(semanticModel, syntax, type, constantValue, isImplicit)
......@@ -5688,7 +5764,7 @@ internal sealed partial class VariableDeclarationStatement : BaseVariableDeclara
/// <summary>
/// Represents a local variable declaration statement.
/// </summary>
internal sealed partial class LazyVariableDeclarationStatement : BaseVariableDeclarationStatement, IVariableDeclarationStatement
internal sealed partial class LazyVariableDeclarationStatement : BaseVariableDeclarationStatement, IVariableDeclarationGroup
{
private readonly Lazy<ImmutableArray<IVariableDeclaration>> _lazyDeclarations;
......
......@@ -17,7 +17,7 @@ internal interface IFixedStatement : IOperation
/// <summary>
/// Variables to be fixed.
/// </summary>
IVariableDeclarationStatement Variables { get; }
IVariableDeclarationGroup Variables { get; }
/// <summary>
/// Body of the fixed, over which the variables are fixed.
/// </summary>
......
// 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 multiple declared variables in a single declarator.
/// </summary>
/// <para>
/// Current Usage:
/// (1) VB As New statements
/// (2) VB multiple declarations in a single declarator
/// </para>
public interface IMultiVariableDeclaration : IVariableDeclaration
{
/// <summary>
/// Individual variable declarations declared by this multiple declaration.
/// </summary>
ImmutableArray<ISingleVariableDeclaration> Declarations { 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 a single variable declaration and initializer.
/// </summary>
/// <para>
/// Current Usage:
/// (1) C# variable declarator
/// (2) VB single variable declaration
/// </para>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
public interface ISingleVariableDeclaration : IVariableDeclaration
{
/// <summary>
/// Symbol declared by this variable declaration
/// </summary>
ILocalSymbol Symbol { get; }
}
}
......@@ -13,16 +13,9 @@ namespace Microsoft.CodeAnalysis.Semantics
/// </remarks>
public interface IVariableDeclaration : IOperation
{
/// <summary>
/// Symbols declared by the declaration. In VB, it's possible to declare multiple variables with the
/// same initializer. In C#, this will always have a single symbol.
/// </summary>
ImmutableArray<ILocalSymbol> Variables { get; }
/// <summary>
/// Optional initializer of the variable.
/// </summary>
IVariableInitializer Initializer { get; }
}
}
......@@ -7,11 +7,16 @@ namespace Microsoft.CodeAnalysis.Semantics
/// <summary>
/// Represents a local variable declaration statement.
/// </summary>
/// <para>
/// Current Usage:
/// (1) C# Local declaration statement
/// (2) VB Dim statement
/// </para>
/// <remarks>
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
public interface IVariableDeclarationStatement : IOperation
public interface IVariableDeclarationGroup : IOperation
{
/// <summary>
/// Variables declared by the statement.
......@@ -19,4 +24,3 @@ public interface IVariableDeclarationStatement : IOperation
ImmutableArray<IVariableDeclaration> Declarations { get; }
}
}
......@@ -39,14 +39,19 @@ public override IOperation VisitBlockStatement(IBlockStatement operation, object
return new BlockStatement(VisitArray(operation.Statements), operation.Locals, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitVariableDeclarationStatement(IVariableDeclarationStatement operation, object argument)
public override IOperation VisitVariableDeclarationGroup(IVariableDeclarationGroup operation, object argument)
{
return new VariableDeclarationStatement(VisitArray(operation.Declarations), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitVariableDeclaration(IVariableDeclaration operation, object argument)
public override IOperation VisitSingleVariableDeclaration(ISingleVariableDeclaration operation, object argument)
{
return new VariableDeclaration(operation.Variables, Visit(operation.Initializer), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
return new SingleVariableDeclaration(operation.Symbol, Visit(operation.Initializer), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitMultiVariableDeclaration(IMultiVariableDeclaration operation, object argument)
{
return new MultiVariableDeclaration(VisitArray(operation.Declarations), Visit(operation.Initializer), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitSwitchStatement(ISwitchStatement operation, object argument)
......
......@@ -99,7 +99,7 @@ private static IEnumerable<IOperation> Descendants(IOperation operation, bool in
/// Gets all the declared local variables in the given <paramref name="declarationStatement"/>.
/// </summary>
/// <param name="declarationStatement">Variable declaration statement</param>
public static ImmutableArray<ILocalSymbol> GetDeclaredVariables(this IVariableDeclarationStatement declarationStatement)
public static ImmutableArray<ILocalSymbol> GetDeclaredVariables(this IVariableDeclarationGroup declarationStatement)
{
if (declarationStatement == null)
{
......@@ -109,10 +109,31 @@ public static ImmutableArray<ILocalSymbol> GetDeclaredVariables(this IVariableDe
var arrayBuilder = ArrayBuilder<ILocalSymbol>.GetInstance();
foreach (IVariableDeclaration group in declarationStatement.Declarations)
{
foreach (ILocalSymbol symbol in group.Variables)
{
arrayBuilder.Add(symbol);
}
arrayBuilder.AddRange(group.GetDeclaredVariables());
}
return arrayBuilder.ToImmutableAndFree();
}
public static ImmutableArray<ILocalSymbol> GetDeclaredVariables(this IVariableDeclaration declaration)
{
if (declaration == null)
{
throw new ArgumentNullException(nameof(declaration));
}
var arrayBuilder = ArrayBuilder<ILocalSymbol>.GetInstance();
switch (declaration.Kind)
{
case OperationKind.SingleVariableDeclaration:
arrayBuilder.Add(((ISingleVariableDeclaration)declaration).Symbol);
break;
case OperationKind.MultiVariableDeclaration:
foreach (var decl in ((IMultiVariableDeclaration)declaration).Declarations)
{
arrayBuilder.Add(decl.Symbol);
}
break;
}
return arrayBuilder.ToImmutableAndFree();
......
......@@ -6,23 +6,6 @@ namespace Microsoft.CodeAnalysis.Semantics
{
internal static class OperationFactory
{
public static IVariableDeclaration CreateVariableDeclaration(ILocalSymbol variable, IVariableInitializer initializer, SemanticModel semanticModel, SyntaxNode syntax)
{
return CreateVariableDeclaration(ImmutableArray.Create(variable), initializer, semanticModel, syntax);
}
public static VariableDeclaration CreateVariableDeclaration(ImmutableArray<ILocalSymbol> variables, IVariableInitializer initializer, SemanticModel semanticModel, SyntaxNode syntax)
{
return new VariableDeclaration(
variables,
initializer,
semanticModel,
syntax,
type: null,
constantValue: default(Optional<object>),
isImplicit: false); // variable declaration is always explicit
}
public static IVariableInitializer CreateVariableInitializer(SyntaxNode syntax, IOperation initializerValue, SemanticModel semanticModel, bool isImplicit)
{
return new VariableInitializer(initializerValue, semanticModel, syntax, type: null, constantValue: default, isImplicit: isImplicit);
......
......@@ -20,7 +20,7 @@ public enum OperationKind
InvalidStatement = 0x1,
/// <summary>Indicates an <see cref="IBlockStatement"/>.</summary>
BlockStatement = 0x2,
/// <summary>Indicates an <see cref="IVariableDeclarationStatement"/>.</summary>
/// <summary>Indicates an <see cref="IVariableDeclarationGroup"/>.</summary>
VariableDeclarationStatement = 0x3,
/// <summary>Indicates an <see cref="ISwitchStatement"/>.</summary>
SwitchStatement = 0x4,
......@@ -210,8 +210,7 @@ public enum OperationKind
/// <summary>Indicates an <see cref="IArrayInitializer"/>.</summary>
ArrayInitializer = 0x405,
/// <summary>Indicates an <see cref="IVariableDeclaration"/>.</summary>
VariableDeclaration = 0x406,
// Unused 0x406
/// <summary>Indicates an <see cref="IArgument"/>.</summary>
Argument = 0x407,
......@@ -233,5 +232,10 @@ public enum OperationKind
ConstantPattern = 0x40d,
/// <summary>Indicates an <see cref="IDeclarationPattern"/>.</summary>
DeclarationPattern = 0x40e,
/// <summary>Indicates an <see cref="ISingleVariableDeclaration"/>.</summary>
SingleVariableDeclaration = 0x40f,
/// <summary>Indicates an <see cref="IMultiVariableDeclaration"/>.</summary>
MultiVariableDeclaration = 0x410
}
}
......@@ -30,12 +30,17 @@ public virtual void VisitBlockStatement(IBlockStatement operation)
DefaultVisit(operation);
}
public virtual void VisitVariableDeclarationStatement(IVariableDeclarationStatement operation)
public virtual void VisitVariableDeclarationGroup(IVariableDeclarationGroup operation)
{
DefaultVisit(operation);
}
public virtual void VisitVariableDeclaration(IVariableDeclaration operation)
public virtual void VisitSingleVariableDeclaration(ISingleVariableDeclaration operation)
{
DefaultVisit(operation);
}
public virtual void VisitMultiVariableDeclaration(IMultiVariableDeclaration operation)
{
DefaultVisit(operation);
}
......@@ -504,7 +509,7 @@ public virtual void VisitTranslatedQueryExpression(ITranslatedQueryExpression op
{
DefaultVisit(operation);
}
public virtual void VisitRaiseEventStatement(IRaiseEventStatement operation)
{
DefaultVisit(operation);
......@@ -545,12 +550,17 @@ public virtual TResult VisitBlockStatement(IBlockStatement operation, TArgument
return DefaultVisit(operation, argument);
}
public virtual TResult VisitVariableDeclarationStatement(IVariableDeclarationStatement operation, TArgument argument)
public virtual TResult VisitVariableDeclarationGroup(IVariableDeclarationGroup operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitVariableDeclaration(IVariableDeclaration operation, TArgument argument)
public virtual TResult VisitSingleVariableDeclaration(ISingleVariableDeclaration operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitMultiVariableDeclaration(IMultiVariableDeclaration operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
......@@ -1019,10 +1029,10 @@ public virtual TResult VisitTranslatedQueryExpression(ITranslatedQueryExpression
{
return DefaultVisit(operation, argument);
}
public virtual TResult VisitRaiseEventStatement(IRaiseEventStatement operation, TArgument argument)
{
return DefaultVisit(operation, argument);
return DefaultVisit(operation, argument);
}
}
}
......@@ -109,6 +109,7 @@ Microsoft.CodeAnalysis.OperationKind.LockStatement = 13 -> Microsoft.CodeAnalysi
Microsoft.CodeAnalysis.OperationKind.LoopStatement = 6 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.MemberInitializerExpression = 289 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.MethodReferenceExpression = 265 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.MultiVariableDeclaration = 1040 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.NameOfExpression = 291 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.None = 0 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.ObjectCreationExpression = 274 -> Microsoft.CodeAnalysis.OperationKind
......@@ -122,6 +123,7 @@ Microsoft.CodeAnalysis.OperationKind.PropertyReferenceExpression = 266 -> Micros
Microsoft.CodeAnalysis.OperationKind.RaiseEventStatement = 83 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.ReturnStatement = 11 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.SimpleAssignmentExpression = 280 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.SingleVariableDeclaration = 1039 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.SizeOfExpression = 514 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.StopStatement = 80 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.SwitchCase = 1033 -> Microsoft.CodeAnalysis.OperationKind
......@@ -134,7 +136,6 @@ Microsoft.CodeAnalysis.OperationKind.TypeOfExpression = 513 -> Microsoft.CodeAna
Microsoft.CodeAnalysis.OperationKind.TypeParameterObjectCreationExpression = 275 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.UnaryOperatorExpression = 269 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.UsingStatement = 15 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.VariableDeclaration = 1030 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.VariableDeclarationStatement = 3 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.VariableInitializer = 1026 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.YieldBreakStatement = 12 -> Microsoft.CodeAnalysis.OperationKind
......@@ -391,6 +392,8 @@ Microsoft.CodeAnalysis.Semantics.IMemberReferenceExpression.Member.get -> Micros
Microsoft.CodeAnalysis.Semantics.IMethodReferenceExpression
Microsoft.CodeAnalysis.Semantics.IMethodReferenceExpression.IsVirtual.get -> bool
Microsoft.CodeAnalysis.Semantics.IMethodReferenceExpression.Method.get -> Microsoft.CodeAnalysis.IMethodSymbol
Microsoft.CodeAnalysis.Semantics.IMultiVariableDeclaration
Microsoft.CodeAnalysis.Semantics.IMultiVariableDeclaration.Declarations.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Semantics.ISingleVariableDeclaration>
Microsoft.CodeAnalysis.Semantics.INameOfExpression
Microsoft.CodeAnalysis.Semantics.INameOfExpression.Argument.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IObjectCreationExpression
......@@ -430,6 +433,8 @@ Microsoft.CodeAnalysis.Semantics.IReturnStatement.ReturnedValue.get -> Microsoft
Microsoft.CodeAnalysis.Semantics.ISimpleAssignmentExpression
Microsoft.CodeAnalysis.Semantics.ISingleValueCaseClause
Microsoft.CodeAnalysis.Semantics.ISingleValueCaseClause.Value.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ISingleVariableDeclaration
Microsoft.CodeAnalysis.Semantics.ISingleVariableDeclaration.Symbol.get -> Microsoft.CodeAnalysis.ILocalSymbol
Microsoft.CodeAnalysis.Semantics.ISizeOfExpression
Microsoft.CodeAnalysis.Semantics.ISizeOfExpression.TypeOperand.get -> Microsoft.CodeAnalysis.ITypeSymbol
Microsoft.CodeAnalysis.Semantics.IStopStatement
......@@ -466,9 +471,8 @@ Microsoft.CodeAnalysis.Semantics.IUsingStatement.Body.get -> Microsoft.CodeAnaly
Microsoft.CodeAnalysis.Semantics.IUsingStatement.Resources.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IVariableDeclaration
Microsoft.CodeAnalysis.Semantics.IVariableDeclaration.Initializer.get -> Microsoft.CodeAnalysis.Semantics.IVariableInitializer
Microsoft.CodeAnalysis.Semantics.IVariableDeclaration.Variables.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement
Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement.Declarations.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Semantics.IVariableDeclaration>
Microsoft.CodeAnalysis.Semantics.IVariableDeclarationGroup
Microsoft.CodeAnalysis.Semantics.IVariableDeclarationGroup.Declarations.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Semantics.IVariableDeclaration>
Microsoft.CodeAnalysis.Semantics.IVariableInitializer
Microsoft.CodeAnalysis.Semantics.IWhileLoopStatement
Microsoft.CodeAnalysis.Semantics.IWhileLoopStatement.Condition.get -> Microsoft.CodeAnalysis.IOperation
......@@ -519,7 +523,8 @@ static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetArgumentName(this
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetArgumentRefKind(this Microsoft.CodeAnalysis.Semantics.IDynamicIndexerAccessExpression dynamicExpression, int index) -> Microsoft.CodeAnalysis.RefKind?
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetArgumentRefKind(this Microsoft.CodeAnalysis.Semantics.IDynamicInvocationExpression dynamicExpression, int index) -> Microsoft.CodeAnalysis.RefKind?
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetArgumentRefKind(this Microsoft.CodeAnalysis.Semantics.IDynamicObjectCreationExpression dynamicExpression, int index) -> Microsoft.CodeAnalysis.RefKind?
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetDeclaredVariables(this Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement declarationStatement) -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetDeclaredVariables(this Microsoft.CodeAnalysis.Semantics.IVariableDeclaration declaration) -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
static Microsoft.CodeAnalysis.Semantics.OperationExtensions.GetDeclaredVariables(this Microsoft.CodeAnalysis.Semantics.IVariableDeclarationGroup declarationStatement) -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
virtual Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterOperationAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.OperationAnalysisContext> action, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.OperationKind> operationKinds) -> void
virtual Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterOperationBlockAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.OperationBlockAnalysisContext> action) -> void
virtual Microsoft.CodeAnalysis.Diagnostics.AnalysisContext.RegisterOperationBlockStartAction(System.Action<Microsoft.CodeAnalysis.Diagnostics.OperationBlockStartAnalysisContext> action) -> void
......@@ -587,6 +592,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitLocalReferenceExp
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitLockStatement(Microsoft.CodeAnalysis.Semantics.ILockStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitMemberInitializerExpression(Microsoft.CodeAnalysis.Semantics.IMemberInitializerExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitMethodReferenceExpression(Microsoft.CodeAnalysis.Semantics.IMethodReferenceExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitMultiVariableDeclaration(Microsoft.CodeAnalysis.Semantics.IMultiVariableDeclaration operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitNameOfExpression(Microsoft.CodeAnalysis.Semantics.INameOfExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.IObjectCreationExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitObjectOrCollectionInitializerExpression(Microsoft.CodeAnalysis.Semantics.IObjectOrCollectionInitializerExpression operation) -> void
......@@ -603,6 +609,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitRelationalCaseCla
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitReturnStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSimpleAssignmentExpression(Microsoft.CodeAnalysis.Semantics.ISimpleAssignmentExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSingleValueCaseClause(Microsoft.CodeAnalysis.Semantics.ISingleValueCaseClause operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSingleVariableDeclaration(Microsoft.CodeAnalysis.Semantics.ISingleVariableDeclaration operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSizeOfExpression(Microsoft.CodeAnalysis.Semantics.ISizeOfExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitStopStatement(Microsoft.CodeAnalysis.Semantics.IStopStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSwitchCase(Microsoft.CodeAnalysis.Semantics.ISwitchCase operation) -> void
......@@ -615,8 +622,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTypeOfExpression(
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTypeParameterObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.ITypeParameterObjectCreationExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitUnaryOperatorExpression(Microsoft.CodeAnalysis.Semantics.IUnaryOperatorExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitUsingStatement(Microsoft.CodeAnalysis.Semantics.IUsingStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitVariableDeclaration(Microsoft.CodeAnalysis.Semantics.IVariableDeclaration operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitVariableDeclarationStatement(Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitVariableDeclarationGroup(Microsoft.CodeAnalysis.Semantics.IVariableDeclarationGroup operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitVariableInitializer(Microsoft.CodeAnalysis.Semantics.IVariableInitializer operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitWhileLoopStatement(Microsoft.CodeAnalysis.Semantics.IWhileLoopStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitYieldBreakStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation) -> void
......@@ -681,6 +687,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.Vi
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitLockStatement(Microsoft.CodeAnalysis.Semantics.ILockStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitMemberInitializerExpression(Microsoft.CodeAnalysis.Semantics.IMemberInitializerExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitMethodReferenceExpression(Microsoft.CodeAnalysis.Semantics.IMethodReferenceExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitMultiVariableDeclaration(Microsoft.CodeAnalysis.Semantics.IMultiVariableDeclaration operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitNameOfExpression(Microsoft.CodeAnalysis.Semantics.INameOfExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.IObjectCreationExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitObjectOrCollectionInitializerExpression(Microsoft.CodeAnalysis.Semantics.IObjectOrCollectionInitializerExpression operation, TArgument argument) -> TResult
......@@ -697,6 +704,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.Vi
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitReturnStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSimpleAssignmentExpression(Microsoft.CodeAnalysis.Semantics.ISimpleAssignmentExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSingleValueCaseClause(Microsoft.CodeAnalysis.Semantics.ISingleValueCaseClause operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSingleVariableDeclaration(Microsoft.CodeAnalysis.Semantics.ISingleVariableDeclaration operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSizeOfExpression(Microsoft.CodeAnalysis.Semantics.ISizeOfExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitStopStatement(Microsoft.CodeAnalysis.Semantics.IStopStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSwitchCase(Microsoft.CodeAnalysis.Semantics.ISwitchCase operation, TArgument argument) -> TResult
......@@ -709,8 +717,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.Vi
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTypeParameterObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.ITypeParameterObjectCreationExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitUnaryOperatorExpression(Microsoft.CodeAnalysis.Semantics.IUnaryOperatorExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitUsingStatement(Microsoft.CodeAnalysis.Semantics.IUsingStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitVariableDeclaration(Microsoft.CodeAnalysis.Semantics.IVariableDeclaration operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitVariableDeclarationStatement(Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitVariableDeclarationGroup(Microsoft.CodeAnalysis.Semantics.IVariableDeclarationGroup operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitVariableInitializer(Microsoft.CodeAnalysis.Semantics.IVariableInitializer operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitWhileLoopStatement(Microsoft.CodeAnalysis.Semantics.IWhileLoopStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitYieldBreakStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation, TArgument argument) -> TResult
......@@ -1154,7 +1154,7 @@ Namespace Microsoft.CodeAnalysis.Semantics
If boundCatchBlock.LocalOpt IsNot Nothing AndAlso
boundCatchBlock.ExceptionSourceOpt?.Kind = BoundKind.Local AndAlso
boundCatchBlock.LocalOpt Is DirectCast(boundCatchBlock.ExceptionSourceOpt, BoundLocal).LocalSymbol Then
Return OperationFactory.CreateVariableDeclaration(boundCatchBlock.LocalOpt, initializer:=Nothing, semanticModel:=_semanticModel, syntax:=boundCatchBlock.ExceptionSourceOpt.Syntax)
Return New SingleVariableDeclaration(boundCatchBlock.LocalOpt, initializer:=Nothing, semanticModel:=_semanticModel, syntax:=boundCatchBlock.ExceptionSourceOpt.Syntax, type:=Nothing, constantValue:=Nothing, isImplicit:=False)
Else
Return Create(boundCatchBlock.ExceptionSourceOpt)
End If
......@@ -1251,7 +1251,7 @@ Namespace Microsoft.CodeAnalysis.Semantics
Return New LazyWhileLoopStatement(condition, body, locals, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundDimStatementOperation(boundDimStatement As BoundDimStatement) As IVariableDeclarationStatement
Private Function CreateBoundDimStatementOperation(boundDimStatement As BoundDimStatement) As IVariableDeclarationGroup
Dim declarations As Lazy(Of ImmutableArray(Of IVariableDeclaration)) = New Lazy(Of ImmutableArray(Of IVariableDeclaration))(Function() GetVariableDeclarationStatementVariables(boundDimStatement.LocalDeclarations))
Dim syntax As SyntaxNode = boundDimStatement.Syntax
Dim type As ITypeSymbol = Nothing
......
......@@ -232,21 +232,43 @@ Namespace Microsoft.CodeAnalysis.Semantics
End Function
Private Function GetVariableDeclarationStatementVariables(declarations As ImmutableArray(Of BoundLocalDeclarationBase)) As ImmutableArray(Of IVariableDeclaration)
' Group the declarations by their VariableDeclaratorSyntaxes. The issue we're compensating for here is that the
' the declarations that are BoundLocalDeclaration nodes have a ModifiedIdentifierSyntax as their syntax nodes,
' not a VariableDeclaratorSyntax. We want to group BoundLocalDeclarations by their parent VariableDeclaratorSyntax
' nodes, and deduplicate based on that. As an example:
'
' Dim x, y = 1
'
' This is an error scenario, but if we just use the BoundLocalDeclaration.Syntax.Parent directly, without deduplicating,
' we'll end up with two ISingleVariableDeclarations that have the same syntax node. So, we group by VariableDeclaratorSyntax
' to put x and y in the same IMutliVariableDeclaration
Dim groupedDeclarations = declarations.GroupBy(Function(declaration)
If declaration.Kind = BoundKind.LocalDeclaration AndAlso
declaration.Syntax.IsKind(SyntaxKind.ModifiedIdentifier) Then
Debug.Assert(declaration.Syntax.Parent.IsKind(SyntaxKind.VariableDeclarator))
Return declaration.Syntax.Parent
Else
Return declaration.Syntax
End If
End Function)
Dim builder = ArrayBuilder(Of IVariableDeclaration).GetInstance()
For Each base In declarations
If base.Kind = BoundKind.LocalDeclaration Then
Dim declaration = DirectCast(base, BoundLocalDeclaration)
Dim initializer As IVariableInitializer = Nothing
If declaration.InitializerOpt IsNot Nothing Then
Debug.Assert(TypeOf declaration.Syntax Is ModifiedIdentifierSyntax)
Dim initializerValue As IOperation = Create(declaration.InitializerOpt)
Dim variableDeclaratorSyntax = TryCast(declaration.Syntax.Parent, VariableDeclaratorSyntax)
Dim initializerSyntax As SyntaxNode = Nothing
If variableDeclaratorSyntax IsNot Nothing Then
initializerSyntax = If(declaration.InitializedByAsNew,
DirectCast(variableDeclaratorSyntax.AsClause, SyntaxNode),
variableDeclaratorSyntax.Initializer)
End If
For Each declarationGroup In groupedDeclarations
Dim first = declarationGroup.First()
Dim singleDeclarations As ImmutableArray(Of ISingleVariableDeclaration) = Nothing
Dim initializer As IVariableInitializer = Nothing
If first.Kind = BoundKind.LocalDeclaration Then
singleDeclarations = declarationGroup.Cast(Of BoundLocalDeclaration).SelectAsArray(AddressOf GetSingleVariableDeclaration)
' The initializer we use for this group is the initializer attached to the last declaration in this declarator, as that's
' where it will be parsed in an error case.
' Initializer is only created if it's not the array initializer for the variable. That initializer is the initializer
' of the SingleVariableDeclaration child.
Dim last = DirectCast(declarationGroup.Last(), BoundLocalDeclaration)
If last.InitializerOpt IsNot Nothing AndAlso last.InitializerOpt IsNot last.ArrayCreationOpt Then
Debug.Assert(TypeOf last.Syntax Is ModifiedIdentifierSyntax)
Dim initializerValue As IOperation = Create(last.InitializerOpt)
Dim initializerSyntax As SyntaxNode = DirectCast(last.Syntax.Parent, VariableDeclaratorSyntax).Initializer
Dim isImplicit As Boolean = False
If initializerSyntax Is Nothing Then
......@@ -256,21 +278,42 @@ Namespace Microsoft.CodeAnalysis.Semantics
End If
initializer = OperationFactory.CreateVariableInitializer(initializerSyntax, initializerValue, _semanticModel, isImplicit)
End If
builder.Add(OperationFactory.CreateVariableDeclaration(declaration.LocalSymbol, initializer, _semanticModel, declaration.Syntax))
ElseIf base.Kind = BoundKind.AsNewLocalDeclarations Then
Dim asNewDeclarations = DirectCast(base, BoundAsNewLocalDeclarations)
Dim localSymbols = asNewDeclarations.LocalDeclarations.SelectAsArray(Of ILocalSymbol)(Function(declaration) declaration.LocalSymbol)
ElseIf first.Kind = BoundKind.AsNewLocalDeclarations Then
Dim asNewDeclarations = DirectCast(first, BoundAsNewLocalDeclarations)
singleDeclarations = asNewDeclarations.LocalDeclarations.SelectAsArray(AddressOf GetSingleVariableDeclaration)
Dim initializerSyntax As AsClauseSyntax = DirectCast(asNewDeclarations.Syntax, VariableDeclaratorSyntax).AsClause
Dim initializerValue As IOperation = Create(asNewDeclarations.Initializer)
Dim initializer As IVariableInitializer = OperationFactory.CreateVariableInitializer(initializerSyntax, initializerValue, _semanticModel, isImplicit:=False)
builder.Add(OperationFactory.CreateVariableDeclaration(localSymbols, initializer, _semanticModel, asNewDeclarations.Syntax))
initializer = OperationFactory.CreateVariableInitializer(initializerSyntax, initializerValue, _semanticModel, isImplicit:=False)
End If
builder.Add(New MultiVariableDeclaration(singleDeclarations,
initializer,
_semanticModel,
declarationGroup.Key,
type:=Nothing,
constantValue:=Nothing,
isImplicit:=False))
Next
Return builder.ToImmutableAndFree()
End Function
Private Function GetUsingStatementDeclaration(resourceList As ImmutableArray(Of BoundLocalDeclarationBase), syntax As SyntaxNode) As IVariableDeclarationStatement
Private Function GetSingleVariableDeclaration(boundLocalDeclaration As BoundLocalDeclaration) As ISingleVariableDeclaration
Dim initializer As Lazy(Of IVariableInitializer) = New Lazy(Of IVariableInitializer)(
Function()
If boundLocalDeclaration.ArrayCreationOpt IsNot Nothing Then
Dim arrayBoundsSyntax = DirectCast(boundLocalDeclaration.Syntax, ModifiedIdentifierSyntax).ArrayBounds
Dim initializerValue As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundLocalDeclaration.ArrayCreationOpt))
Return New LazyVariableInitializer(initializerValue, _semanticModel, arrayBoundsSyntax, type:=Nothing, constantValue:=Nothing, isImplicit:=True)
Else
Return Nothing
End If
End Function)
Return New LazySingleVariableDeclaration(boundLocalDeclaration.LocalSymbol, initializer, _semanticModel, boundLocalDeclaration.Syntax, type:=Nothing, constantValue:=Nothing, isImplicit:=boundLocalDeclaration.WasCompilerGenerated)
End Function
Private Function GetUsingStatementDeclaration(resourceList As ImmutableArray(Of BoundLocalDeclarationBase), syntax As SyntaxNode) As IVariableDeclarationGroup
Return New VariableDeclarationStatement(
GetVariableDeclarationStatementVariables(resourceList),
_semanticModel,
......
......@@ -2389,7 +2389,7 @@ BC30512: Option Strict On disallows implicit conversions from 'Integer' to 'SByt
Dim verifier = New ExpectedSymbolVerifier(operationSelector:=
Function(operation As IOperation) As IConversionExpression
Dim initializer As IVariableInitializer = DirectCast(operation, IVariableDeclarationStatement).Declarations.Single().Initializer
Dim initializer As IVariableInitializer = DirectCast(operation, IVariableDeclarationGroup).Declarations.Single().Initializer
Dim initializerValue As IOperation = initializer.Value
Return DirectCast(initializerValue, IInvalidExpression).Children.Cast(Of IConversionExpression).Single()
End Function)
......@@ -2833,7 +2833,7 @@ BC36755: 'Action(Of Object)' cannot be converted to 'Action(Of Integer)' because
Else
Select Case operation.Kind
Case OperationKind.VariableDeclarationStatement
Return DirectCast(operation, IVariableDeclarationStatement).Declarations.Single().Initializer.Value
Return DirectCast(operation, IVariableDeclarationGroup).Declarations.Single().Initializer.Value
Case OperationKind.ReturnStatement
Return DirectCast(operation, IReturnStatement).ReturnedValue
Case Else
......
......@@ -387,23 +387,32 @@ public override void VisitBlockStatement(IBlockStatement operation)
base.VisitBlockStatement(operation);
}
public override void VisitVariableDeclarationStatement(IVariableDeclarationStatement operation)
public override void VisitVariableDeclarationGroup(IVariableDeclarationGroup operation)
{
var variablesCountStr = $"{operation.Declarations.Length} declarations";
LogString($"{nameof(IVariableDeclarationStatement)} ({variablesCountStr})");
LogString($"{nameof(IVariableDeclarationGroup)} ({variablesCountStr})");
LogCommonPropertiesAndNewLine(operation);
base.VisitVariableDeclarationStatement(operation);
base.VisitVariableDeclarationGroup(operation);
}
public override void VisitVariableDeclaration(IVariableDeclaration operation)
public override void VisitSingleVariableDeclaration(ISingleVariableDeclaration operation)
{
var symbolsCountStr = $"{operation.Variables.Length} variables";
LogString($"{nameof(IVariableDeclaration)} ({symbolsCountStr})");
LogString($"{nameof(ISingleVariableDeclaration)} (");
LogSymbol(operation.Symbol, "Symbol");
LogString(")");
LogCommonPropertiesAndNewLine(operation);
LogLocals(operation.Variables, header: "Variables");
Visit(operation.Initializer, "Initializer");
}
public override void VisitMultiVariableDeclaration(IMultiVariableDeclaration operation)
{
var variableCount = operation.Declarations.Length;
LogString($"{nameof(IMultiVariableDeclaration)} ({variableCount} declarations)");
LogCommonPropertiesAndNewLine(operation);
VisitArray(operation.Declarations, "Declarations", false);
Visit(operation.Initializer, "Initializer");
}
......
......@@ -55,19 +55,21 @@ public override void VisitBlockStatement(IBlockStatement operation)
base.VisitBlockStatement(operation);
}
public override void VisitVariableDeclarationStatement(IVariableDeclarationStatement operation)
public override void VisitVariableDeclarationGroup(IVariableDeclarationGroup operation)
{
base.VisitVariableDeclarationStatement(operation);
base.VisitVariableDeclarationGroup(operation);
}
public override void VisitVariableDeclaration(IVariableDeclaration operation)
public override void VisitSingleVariableDeclaration(ISingleVariableDeclaration operation)
{
foreach (var symbol in operation.Variables)
{
// empty loop body, just want to make sure it won't crash.
}
var symbol = operation.Symbol;
base.VisitVariableDeclaration(operation);
base.VisitSingleVariableDeclaration(operation);
}
public override void VisitMultiVariableDeclaration(IMultiVariableDeclaration operation)
{
base.VisitMultiVariableDeclaration(operation);
}
public override void VisitSwitchStatement(ISwitchStatement operation)
......
......@@ -98,7 +98,7 @@ public sealed override void Initialize(AnalysisContext context)
IVariableInitializer initializer = (IVariableInitializer)operationContext.Operation;
if (initializer.Parent is IVariableDeclaration variableDeclaration)
{
foreach (ILocalSymbol local in variableDeclaration.Variables)
foreach (ILocalSymbol local in variableDeclaration.GetDeclaredVariables())
{
AssignTo(local, local.Type, localsSourceTypes, initializer.Value);
}
......
......@@ -75,10 +75,10 @@ public sealed override void Initialize(AnalysisContext context)
operationBlockContext.RegisterOperationAction(
(operationContext) =>
{
IVariableDeclarationStatement declaration = (IVariableDeclarationStatement)operationContext.Operation;
IVariableDeclarationGroup declaration = (IVariableDeclarationGroup)operationContext.Operation;
foreach (IVariableDeclaration variable in declaration.Declarations)
{
foreach (ILocalSymbol local in variable.Variables)
foreach (ILocalSymbol local in variable.GetDeclaredVariables())
{
if (!local.IsConst && !assignedToLocals.Contains(local))
{
......
......@@ -850,7 +850,7 @@ public sealed override void Initialize(AnalysisContext context)
context.RegisterOperationAction(
(operationContext) =>
{
var declarationStatement = (IVariableDeclarationStatement)operationContext.Operation;
var declarationStatement = (IVariableDeclarationGroup)operationContext.Operation;
if (declarationStatement.GetDeclaredVariables().Count() > 3)
{
Report(operationContext, declarationStatement.Syntax, TooManyLocalVarDeclarationsDescriptor);
......@@ -860,7 +860,7 @@ public sealed override void Initialize(AnalysisContext context)
{
if (decl.Initializer != null && !decl.Initializer.HasErrors(operationContext.Compilation, operationContext.CancellationToken))
{
foreach (var symbol in decl.Variables)
foreach (var symbol in decl.GetDeclaredVariables())
{
Report(operationContext, symbol.DeclaringSyntaxReferences.Single().GetSyntax(), LocalVarInitializedDeclarationDescriptor);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册