From dc2fe064ad7d1ccd484fddfc8d6643d4d7eb036c Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 1 Nov 2016 12:47:26 -0700 Subject: [PATCH 1/8] WIP on syntax --- .../CSharp/Portable/CSharpCodeAnalysis.csproj | 1 - .../CSharp/Portable/Parser/LanguageParser.cs | 71 ++-- .../CSharp/Portable/PublicAPI.Unshipped.txt | 91 +---- .../Portable/Syntax/ForStatementSyntax.cs | 70 ---- .../CSharp/Portable/Syntax/Syntax.xml | 53 +-- .../CSharp/Portable/Syntax/SyntaxKind.cs | 4 - .../Syntax/Parsing/DeclarationParsingTests.cs | 15 +- .../Syntax/Parsing/DeconstructionTests.cs | 372 ++++++++++-------- 8 files changed, 269 insertions(+), 408 deletions(-) delete mode 100644 src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs diff --git a/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj b/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj index 16d05094db28f..c8cfd0c168146 100644 --- a/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj +++ b/src/Compilers/CSharp/Portable/CSharpCodeAnalysis.csproj @@ -770,7 +770,6 @@ - diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index fee6a48f28d0e..cf52ff3729b29 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -2413,8 +2413,7 @@ private MemberDeclarationSyntax ParseMemberDeclarationOrStatement(SyntaxKind par if (deconstruction != null) { var semicolon = this.EatToken(SyntaxKind.SemicolonToken); - return _syntaxFactory.GlobalStatement(_syntaxFactory.DeconstructionDeclarationStatement( - new SyntaxList(), deconstruction, semicolon)); + return _syntaxFactory.GlobalStatement(_syntaxFactory.ExpressionStatement(deconstruction, semicolon)); } } @@ -7533,7 +7532,6 @@ private StatementSyntax ParseEmbeddedStatement(bool complexCheck) case SyntaxKind.LabeledStatement: case SyntaxKind.LocalDeclarationStatement: case SyntaxKind.LocalFunctionStatement: - case SyntaxKind.DeconstructionDeclarationStatement: statement = this.AddError(statement, ErrorCode.ERR_BadEmbeddedStmt); break; } @@ -7848,7 +7846,7 @@ private ForStatementSyntax ParseForStatement() { // Here can be either a declaration or an expression statement list. Scan // for a declaration first. - VariableComponentAssignmentSyntax deconstruction = null; + AssignmentExpressionSyntax deconstruction = null; VariableDeclarationSyntax decl = null; bool isDeclaration = false; if (this.CurrentToken.Kind == SyntaxKind.RefKeyword) @@ -7867,6 +7865,10 @@ private ForStatementSyntax ParseForStatement() this.Reset(ref resetPoint); } + else + { + initializers.Add(deconstruction); + } } if (isDeclaration) @@ -7895,7 +7897,7 @@ private ForStatementSyntax ParseForStatement() var closeParen = this.EatToken(SyntaxKind.CloseParenToken); var statement = ParseEmbeddedStatement(true); - return _syntaxFactory.ForStatement(forToken, openParen, deconstruction, decl, initializers, semi, condition, semi2, incrementors, closeParen, statement); + return _syntaxFactory.ForStatement(forToken, openParen, decl, initializers, semi, condition, semi2, incrementors, closeParen, statement); } finally { @@ -8413,7 +8415,7 @@ private StatementSyntax ParseLocalDeclarationStatement() if (deconstruction != null) { var semicolon = this.EatToken(SyntaxKind.SemicolonToken); - var result = _syntaxFactory.DeconstructionDeclarationStatement(mods.ToList(), deconstruction, semicolon); + var result = _syntaxFactory.ExpressionStatement(deconstruction, semicolon); _pool.Free(mods); return result; } @@ -8469,7 +8471,7 @@ private StatementSyntax ParseLocalDeclarationStatement() /// /// Returns null and resets the pointer if this does not look like a deconstruction-declaration after all. /// - private VariableComponentAssignmentSyntax TryParseDeconstructionDeclarationAssignment() + private AssignmentExpressionSyntax TryParseDeconstructionDeclarationAssignment() { if (this.CurrentToken.Kind == SyntaxKind.OpenParenToken || CurrentToken.IsVarOrPredefinedType() && this.PeekToken(1).Kind == SyntaxKind.OpenParenToken) @@ -8502,7 +8504,7 @@ private VariableComponentAssignmentSyntax TryParseDeconstructionDeclarationAssig /// /// Returns null and resets the pointer if this does not look like a deconstruction-declaration after all. /// - private VariableComponentSyntax TryParseDeconstructionDeclaration(SyntaxKind nextExpectedKind) + private ExpressionSyntax TryParseDeconstructionDeclaration(SyntaxKind nextExpectedKind) { if (this.CurrentToken.Kind == SyntaxKind.OpenParenToken || CurrentToken.IsVarOrPredefinedType() && this.PeekToken(1).Kind == SyntaxKind.OpenParenToken) @@ -8511,7 +8513,7 @@ private VariableComponentSyntax TryParseDeconstructionDeclaration(SyntaxKind nex try { - var deconstruction = ParseDeconstructionComponent(true); + var deconstruction = ParseDeconstructionDeclarationVariables(true); if (deconstruction == null || CurrentToken.Kind != nextExpectedKind) { this.Reset(ref resetPoint); @@ -8538,13 +8540,13 @@ private VariableComponentSyntax TryParseDeconstructionDeclaration(SyntaxKind nex /// The syntax is either var form: `var (deconstruction-declaration, ...) = expression` or list form `(deconstruction-declaration, ...) = expression`. /// Cannot return null, except at the top-level. /// - private VariableComponentAssignmentSyntax ParseDeconstructionDeclarationAssignment() + private AssignmentExpressionSyntax ParseDeconstructionDeclarationAssignment() { var component = TryParseDeconstructionDeclaration(SyntaxKind.EqualsToken); if (component == null) return null; var equalsToken = this.EatToken(SyntaxKind.EqualsToken); var value = this.ParseExpressionCore(); - return _syntaxFactory.VariableComponentAssignment(component, equalsToken, value); + return _syntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, component, equalsToken, value); } /// @@ -8555,7 +8557,7 @@ private VariableComponentAssignmentSyntax ParseDeconstructionDeclarationAssignme /// Cannot return null, except at the top-level. /// /// Specifies whether to parse the terminal form of a deconstruction-declaration (which can't appear at the top-level). - private VariableComponentSyntax ParseDeconstructionComponent(bool topLevel = false) + private ExpressionSyntax ParseDeconstructionDeclarationVariables(bool topLevel = false) { if (topLevel && !(CurrentToken.IsVarOrPredefinedType() && this.PeekToken(1).Kind == SyntaxKind.OpenParenToken || this.CurrentToken.Kind == SyntaxKind.OpenParenToken)) @@ -8565,18 +8567,18 @@ private VariableComponentSyntax ParseDeconstructionComponent(bool topLevel = fal // the two forms of component are // (1) type designator - // (2) ( component ... ) - VariableComponentSyntax result; + // (2) ( decl-expr, ... ) + ExpressionSyntax result; if (this.CurrentToken.Kind == SyntaxKind.OpenParenToken) { var openParen = this.EatToken(SyntaxKind.OpenParenToken); - var listOfComponents = _pool.AllocateSeparated(); + var listOfDeclarations = _pool.AllocateSeparated(); while (true) { - listOfComponents.Add(ParseDeconstructionComponent()); + listOfDeclarations.Add(_syntaxFactory.Argument(nameColon: null, refOrOutKeyword: null, expression: ParseDeconstructionDeclarationVariables())); if (this.CurrentToken.Kind == SyntaxKind.CommaToken) { - listOfComponents.AddSeparator(this.EatToken(SyntaxKind.CommaToken)); + listOfDeclarations.AddSeparator(this.EatToken(SyntaxKind.CommaToken)); } else { @@ -8584,9 +8586,8 @@ private VariableComponentSyntax ParseDeconstructionComponent(bool topLevel = fal } } var closeParen = this.EatToken(SyntaxKind.CloseParenToken); - SeparatedSyntaxList components = listOfComponents; - result = _syntaxFactory.ParenthesizedVariableComponent(openParen, listOfComponents, closeParen); - _pool.Free(listOfComponents); + result = _syntaxFactory.TupleExpression(openParen, listOfDeclarations, closeParen); + _pool.Free(listOfDeclarations); } else { @@ -8610,31 +8611,32 @@ private VariableComponentSyntax ParseDeconstructionComponent(bool topLevel = fal designation = this.AddError(designation, ErrorCode.ERR_TypeExpected); } - result = _syntaxFactory.TypedVariableComponent(type, designation); + result = _syntaxFactory.DeclarationExpression(type, designation); } return - topLevel ? (ComponentHasTypes(result) ? CheckFeatureAvailability(result, MessageID.IDS_FeatureTuples) : null) : result; + topLevel ? (TypeFoundInDeconstructionDeclarationVariables(result) ? CheckFeatureAvailability(result, MessageID.IDS_FeatureTuples) : null) : result; } - private static bool ComponentHasTypes(VariableComponentSyntax node) + // Check if we can find at least one type in the deconstruction variables + private static bool TypeFoundInDeconstructionDeclarationVariables(ExpressionSyntax node) { switch (node.Kind) { - case SyntaxKind.ParenthesizedVariableComponent: + case SyntaxKind.TupleExpression: { - var syntax = (ParenthesizedVariableComponentSyntax)node; - if (syntax.Variables.Count <= 1) return false; // don't count 1ples - for (int i = 0; i < syntax.Variables.Count; i++) + var syntax = (TupleExpressionSyntax)node; + if (syntax.Arguments.Count <= 1) return false; // don't count 1ples + for (int i = 0; i < syntax.Arguments.Count; i++) { - if (ComponentHasTypes(syntax.Variables[i])) return true; + if (TypeFoundInDeconstructionDeclarationVariables(syntax.Arguments[i].Expression)) return true; } return false; } - case SyntaxKind.TypedVariableComponent: + case SyntaxKind.DeclarationExpression: { - var syntax = (TypedVariableComponentSyntax)node; + var syntax = (DeclarationExpressionSyntax)node; if (syntax.Type.IsMissing || syntax.Designation.IsMissing) return false; if (syntax.Designation.Kind == SyntaxKind.ParenthesizedVariableDesignation) { @@ -8697,7 +8699,7 @@ private bool IsPossibleDeconstructionDeclaration() try { var assignment = ParseDeconstructionDeclarationAssignment(); - return assignment != null && !assignment.equalsToken.IsMissing; + return assignment != null && assignment.operatorToken.Kind == SyntaxKind.EqualsToken; } finally { @@ -9932,10 +9934,9 @@ private ArgumentSyntax ParseArgumentExpression(bool isIndexer) { TypeSyntax typeSyntax = ParseType(); SyntaxToken identifier = CheckFeatureAvailability(this.ParseIdentifierToken(), MessageID.IDS_FeatureOutVar); - var declarationSyntax = _syntaxFactory.TypedVariableComponent( - typeSyntax, - _syntaxFactory.SingleVariableDesignation(identifier)); - expression = _syntaxFactory.DeclarationExpression(declarationSyntax); + expression = _syntaxFactory.DeclarationExpression( + typeSyntax, + _syntaxFactory.SingleVariableDesignation(identifier)); } else { diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index 7e87a5eeb7890..0bb78f91c2a20 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -34,39 +34,29 @@ Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax.WithExpression(Micros Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax initializer, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax.WithExpressionBody(Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.VariableComponent.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.WithVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.Designation.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.Type.get -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.WithDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.WithType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.Identifier.get -> Microsoft.CodeAnalysis.SyntaxToken Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.Type.get -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.WithIdentifier(Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.WithType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.AddModifiers(params Microsoft.CodeAnalysis.SyntaxToken[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.Assignment.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.Modifiers.get -> Microsoft.CodeAnalysis.SyntaxTokenList -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.SemicolonToken.get -> Microsoft.CodeAnalysis.SyntaxToken -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.Update(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax assignment, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.WithAssignment(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax assignment) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.WithSemicolonToken(Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken tildeToken, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax.WithExpressionBody(Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.VariableComponent.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.VariableComponent.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithCloseParenToken(Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithForEachKeyword(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithInKeyword(Microsoft.CodeAnalysis.SyntaxToken inKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithOpenParenToken(Microsoft.CodeAnalysis.SyntaxToken openParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithStatement(Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForStatementSyntax.Deconstruction.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForStatementSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken forKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax deconstruction, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration, Microsoft.CodeAnalysis.SeparatedSyntaxList initializers, Microsoft.CodeAnalysis.SyntaxToken firstSemicolonToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax condition, Microsoft.CodeAnalysis.SyntaxToken secondSemicolonToken, Microsoft.CodeAnalysis.SeparatedSyntaxList incrementors, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForStatementSyntax.WithDeconstruction(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax deconstruction) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax.Expression.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax.IsKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken @@ -100,15 +90,6 @@ Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithParameterL Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithReturnType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithSemicolonToken(Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.WithTypeParameterList(Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax typeParameterList) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.AddVariables(params Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.OpenParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.SeparatedSyntaxList variables, Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.Variables.get -> Microsoft.CodeAnalysis.SeparatedSyntaxList -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.WithCloseParenToken(Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.WithOpenParenToken(Microsoft.CodeAnalysis.SyntaxToken openParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.WithVariables(Microsoft.CodeAnalysis.SeparatedSyntaxList variables) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax.AddVariables(params Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken @@ -165,21 +146,6 @@ Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.Update(Microsoft.CodeAnalys Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.WithCloseParenToken(Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.WithElements(Microsoft.CodeAnalysis.SeparatedSyntaxList elements) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.WithOpenParenToken(Microsoft.CodeAnalysis.SyntaxToken openParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax.Designation.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax.Type.get -> Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax.WithDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax.WithType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.EqualsToken.get -> Microsoft.CodeAnalysis.SyntaxToken -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.Update(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken equalsToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax value) -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.Value.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.VariableComponent.get -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.WithEqualsToken(Microsoft.CodeAnalysis.SyntaxToken equalsToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.WithValue(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax value) -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.WithVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent) -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax.Condition.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax @@ -191,11 +157,9 @@ Microsoft.CodeAnalysis.CSharp.SyntaxKind.CasePatternSwitchLabel = 9009 -> Micros Microsoft.CodeAnalysis.CSharp.SyntaxKind.ConstantPattern = 9002 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.DeclarationExpression = 9040 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.DeclarationPattern = 9000 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.DeconstructionDeclarationStatement = 8932 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.ForEachComponentStatement = 8934 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.IsPatternExpression = 8657 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.LocalFunctionStatement = 8830 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.ParenthesizedVariableComponent = 8929 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.ParenthesizedVariableDesignation = 8931 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.RefExpression = 9050 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.RefType = 9051 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind @@ -204,8 +168,6 @@ Microsoft.CodeAnalysis.CSharp.SyntaxKind.ThrowExpression = 9052 -> Microsoft.Cod Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleElement = 8926 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleExpression = 8927 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleType = 8925 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.TypedVariableComponent = 8928 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.VariableComponentAssignment = 8933 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.WhenClause = 9013 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseMethodDeclarationSyntax.ExpressionBody.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax abstract Microsoft.CodeAnalysis.CSharp.Syntax.CommonForEachStatementSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken @@ -220,11 +182,9 @@ override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitCasePatternSwit override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitConstantPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitDeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitDeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode -override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitDeconstructionDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitIsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode -override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitParenthesizedVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitParenthesizedVariableDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitRefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.RefExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitRefType(Microsoft.CodeAnalysis.CSharp.Syntax.RefTypeSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode @@ -233,8 +193,6 @@ override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitThrowExpression override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitTupleElement(Microsoft.CodeAnalysis.CSharp.Syntax.TupleElementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitTupleExpression(Microsoft.CodeAnalysis.CSharp.Syntax.TupleExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitTupleType(Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode -override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitTypedVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode -override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitVariableComponentAssignment(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitWhenClause(Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.Syntax.CasePatternSwitchLabelSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.CasePatternSwitchLabelSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult @@ -248,8 +206,6 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.Accept override Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult -override Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void -override Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax.ExpressionBody.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult @@ -271,8 +227,6 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Accep override Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax.ExpressionBody.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax override Microsoft.CodeAnalysis.CSharp.Syntax.OperatorDeclarationSyntax.ExpressionBody.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax -override Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void -override Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.RefExpressionSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void @@ -289,10 +243,6 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.TupleExpressionSyntax.Accept(Micro override Microsoft.CodeAnalysis.CSharp.Syntax.TupleExpressionSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult -override Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void -override Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult -override Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void -override Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult static Microsoft.CodeAnalysis.CSharp.CSharpExtensions.GetDeclaredSymbol(this Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax declarationSyntax, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Microsoft.CodeAnalysis.ISymbol @@ -312,27 +262,21 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Micros static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax initializer, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax initializer, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax initializer, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeconstructionDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax assignment) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeconstructionDeclarationStatement(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax assignment) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeconstructionDeclarationStatement(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax assignment, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken tildeToken, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken tildeToken, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachComponentStatement(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForStatement(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax deconstruction, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration, Microsoft.CodeAnalysis.SeparatedSyntaxList initializers, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax condition, Microsoft.CodeAnalysis.SeparatedSyntaxList incrementors, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForStatementSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForStatement(Microsoft.CodeAnalysis.SyntaxToken forKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax deconstruction, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDeclarationSyntax declaration, Microsoft.CodeAnalysis.SeparatedSyntaxList initializers, Microsoft.CodeAnalysis.SyntaxToken firstSemicolonToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax condition, Microsoft.CodeAnalysis.SyntaxToken secondSemicolonToken, Microsoft.CodeAnalysis.SeparatedSyntaxList incrementors, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForStatementSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachComponentStatement(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.IsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.IsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken isKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, string identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax typeParameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.SyntaxList constraintClauses, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.TypeParameterListSyntax typeParameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.SyntaxList constraintClauses, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParenthesizedVariableComponent(Microsoft.CodeAnalysis.SeparatedSyntaxList variables = default(Microsoft.CodeAnalysis.SeparatedSyntaxList)) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParenthesizedVariableComponent(Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.SeparatedSyntaxList variables, Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParenthesizedVariableDesignation(Microsoft.CodeAnalysis.SeparatedSyntaxList variables = default(Microsoft.CodeAnalysis.SeparatedSyntaxList)) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParenthesizedVariableDesignation(Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.SeparatedSyntaxList variables, Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.RefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.RefExpressionSyntax @@ -348,20 +292,15 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TupleExpression(Microsoft.Cod static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TupleExpression(Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.SeparatedSyntaxList arguments, Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TupleType(Microsoft.CodeAnalysis.SeparatedSyntaxList elements = default(Microsoft.CodeAnalysis.SeparatedSyntaxList)) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TupleType(Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.SeparatedSyntaxList elements, Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.TypedVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.VariableComponentAssignment(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax value) -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.VariableComponentAssignment(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken equalsToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax value) -> Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.WhenClause(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax condition) -> Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.WhenClause(Microsoft.CodeAnalysis.SyntaxToken whenKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax condition) -> Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitCasePatternSwitchLabel(Microsoft.CodeAnalysis.CSharp.Syntax.CasePatternSwitchLabelSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitConstantPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax node) -> void -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeconstructionDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitIsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> void -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedVariableDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.RefExpressionSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRefType(Microsoft.CodeAnalysis.CSharp.Syntax.RefTypeSyntax node) -> void @@ -370,18 +309,14 @@ virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitThrowExpression(M virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTupleElement(Microsoft.CodeAnalysis.CSharp.Syntax.TupleElementSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTupleExpression(Microsoft.CodeAnalysis.CSharp.Syntax.TupleExpressionSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTupleType(Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax node) -> void -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTypedVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax node) -> void -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitVariableComponentAssignment(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitWhenClause(Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitCasePatternSwitchLabel(Microsoft.CodeAnalysis.CSharp.Syntax.CasePatternSwitchLabelSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitConstantPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax node) -> TResult -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeconstructionDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.DeconstructionDeclarationStatementSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitIsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> TResult -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableComponentSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedVariableDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRefExpression(Microsoft.CodeAnalysis.CSharp.Syntax.RefExpressionSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitRefType(Microsoft.CodeAnalysis.CSharp.Syntax.RefTypeSyntax node) -> TResult @@ -390,6 +325,4 @@ virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitThrowExp virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTupleElement(Microsoft.CodeAnalysis.CSharp.Syntax.TupleElementSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTupleExpression(Microsoft.CodeAnalysis.CSharp.Syntax.TupleExpressionSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTupleType(Microsoft.CodeAnalysis.CSharp.Syntax.TupleTypeSyntax node) -> TResult -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitTypedVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.TypedVariableComponentSyntax node) -> TResult -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitVariableComponentAssignment(Microsoft.CodeAnalysis.CSharp.Syntax.VariableComponentAssignmentSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitWhenClause(Microsoft.CodeAnalysis.CSharp.Syntax.WhenClauseSyntax node) -> TResult \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs b/src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs deleted file mode 100644 index f13c3f013fdd7..0000000000000 --- a/src/Compilers/CSharp/Portable/Syntax/ForStatementSyntax.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Microsoft.CodeAnalysis.CSharp.Syntax -{ - public partial class ForStatementSyntax - { - public ForStatementSyntax Update(SyntaxToken forKeyword, SyntaxToken openParenToken, VariableDeclarationSyntax declaration, SeparatedSyntaxList initializers, SyntaxToken firstSemicolonToken, ExpressionSyntax condition, SyntaxToken secondSemicolonToken, SeparatedSyntaxList incrementors, SyntaxToken closeParenToken, StatementSyntax statement) - { - return Update(ForKeyword, openParenToken, null, declaration, initializers, firstSemicolonToken, condition, secondSemicolonToken, incrementors, closeParenToken, statement); - } - } -} - -namespace Microsoft.CodeAnalysis.CSharp -{ - public partial class SyntaxFactory - { - /// Creates a new ForStatementSyntax instance. - public static ForStatementSyntax ForStatement( - SyntaxToken forKeyword, - SyntaxToken openParenToken, - VariableDeclarationSyntax declaration, - SeparatedSyntaxList initializers, - SyntaxToken firstSemicolonToken, - ExpressionSyntax condition, - SyntaxToken secondSemicolonToken, - SeparatedSyntaxList incrementors, - SyntaxToken closeParenToken, - StatementSyntax statement) - { - return ForStatement( - forKeyword, openParenToken, null, declaration, initializers, - firstSemicolonToken, condition, secondSemicolonToken, incrementors, - closeParenToken, statement); - } - } -} - -namespace Microsoft.CodeAnalysis.CSharp -{ - public partial class SyntaxFactory - { - /// Creates a new ForStatementSyntax instance. - public static ForStatementSyntax ForStatement( - VariableDeclarationSyntax declaration, - SeparatedSyntaxList initializers, - ExpressionSyntax condition, - SeparatedSyntaxList incrementors, - StatementSyntax statement) - { - return SyntaxFactory.ForStatement( - SyntaxFactory.Token(SyntaxKind.ForKeyword), - SyntaxFactory.Token(SyntaxKind.OpenParenToken), - null, - declaration, - initializers, - SyntaxFactory.Token(SyntaxKind.SemicolonToken), - condition, - SyntaxFactory.Token(SyntaxKind.SemicolonToken), - incrementors, - SyntaxFactory.Token(SyntaxKind.CloseParenToken), - statement); - } - } -} diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index 7e97a8f8ddd50..1539dbba065b3 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -1131,7 +1131,8 @@ - + + Declaration representing the variable declared in an out parameter. @@ -1841,32 +1842,6 @@ - - - - - - - - - - - - - - - - - - - @@ -1894,23 +1869,6 @@ --> - - - - - - - - - - - - - - - - - @@ -2089,8 +2047,7 @@ - - + @@ -2153,7 +2110,7 @@ - + @@ -2161,7 +2118,7 @@ - + diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs index cfddab9d09339..ba8abb57cf2a9 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs @@ -542,12 +542,8 @@ public enum SyntaxKind : ushort TupleType = 8925, TupleElement = 8926, TupleExpression = 8927, - TypedVariableComponent = 8928, - ParenthesizedVariableComponent = 8929, SingleVariableDesignation = 8930, ParenthesizedVariableDesignation = 8931, - DeconstructionDeclarationStatement = 8932, - VariableComponentAssignment = 8933, ForEachComponentStatement = 8934, // patterns (for pattern-matching) diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs index f470f8f908d0f..5db51000a9e65 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs @@ -5769,16 +5769,13 @@ void Foo() N(SyntaxKind.OutKeyword); N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.IdentifierName); { - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "var"); - } - N(SyntaxKind.SingleVariableDesignation); - { - N(SyntaxKind.IdentifierToken, "x"); - } + N(SyntaxKind.IdentifierToken, "var"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "x"); } } } diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs index 3ab6d1df5af1a..50aab9c19d589 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs @@ -10,12 +10,12 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Parsing { // Some examples of parsing subtleties: - // `(T id, ...) = ...;` is a deconstruction-declaration - // `var (id, ...) = ...;` is a deconstruction-declaration + // `(T id, ...) = ...` is a deconstruction-assignment into a tuple expression with declaration expressions + // `var (id, ...) = ...` is a deconstruction-assignment // `(T id, ...) id;` starts with a tuple type // `(T, ...) id;` starts with tuple type // `(T, ...)[] id;` starts with a tuple type array - // `(E, ...) = ...;` is a deconstruction-assignment, which starts with a tuple literal/expression + // `(E, ...) = ...;` is a deconstruction-assignment // `(E, ...).Foo();` starts with a tuple literal/expression // `(E, ...) + ...` also starts with a tuple literal/expression // `(T, ...)? id;` starts with a tuple type @@ -694,7 +694,7 @@ void Foo() N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); - N(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { @@ -711,34 +711,40 @@ void Foo() N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); - N(SyntaxKind.DeconstructionDeclarationStatement); + N(SyntaxKind.ExpressionStatement); { - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.TupleExpression); { N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "Int32"); - } - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "a"); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int32"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "a"); + } } } N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "Int64"); - } - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "b"); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int64"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "b"); + } } } N(SyntaxKind.CloseParenToken); @@ -795,52 +801,64 @@ void Foo() N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); - N(SyntaxKind.DeconstructionDeclarationStatement); + N(SyntaxKind.ExpressionStatement); { - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.TupleExpression); { N(SyntaxKind.OpenParenToken); - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.TupleExpression); { - N(SyntaxKind.IdentifierName); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierToken, "Int32"); + N(SyntaxKind.DeclarationExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int32"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "a"); + } + } } - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.CommaToken); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierToken, "a"); + N(SyntaxKind.DeclarationExpression); + { + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int64"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "b"); + } + } } + N(SyntaxKind.CloseParenToken); } - N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.Argument); + { + N(SyntaxKind.DeclarationExpression); { N(SyntaxKind.IdentifierName); { - N(SyntaxKind.IdentifierToken, "Int64"); + N(SyntaxKind.IdentifierToken, "Int32"); } N(SyntaxKind.SingleVariableDesignation); { - N(SyntaxKind.IdentifierToken, "b"); + N(SyntaxKind.IdentifierToken, "c"); } } - N(SyntaxKind.CloseParenToken); - } - N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); - { - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "Int32"); - } - N(SyntaxKind.SingleVariableDesignation); - { - N(SyntaxKind.IdentifierToken, "c"); - } } N(SyntaxKind.CloseParenToken); } @@ -896,11 +914,11 @@ void Foo() N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); - N(SyntaxKind.DeconstructionDeclarationStatement); + N(SyntaxKind.ExpressionStatement); { - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.DeclarationExpression); { N(SyntaxKind.IdentifierName); { @@ -973,11 +991,11 @@ void Foo() N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); - N(SyntaxKind.DeconstructionDeclarationStatement); + N(SyntaxKind.ExpressionStatement); { - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.DeclarationExpression); { N(SyntaxKind.IdentifierName); { @@ -1007,11 +1025,11 @@ void Foo() } N(SyntaxKind.CloseParenToken); } - N(SyntaxKind.EqualsToken); - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "foo"); - } + } + N(SyntaxKind.EqualsToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "foo"); } } N(SyntaxKind.SemicolonToken); @@ -1043,7 +1061,7 @@ void Foo() N(SyntaxKind.ClassDeclaration); { N(SyntaxKind.ClassKeyword); - N(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "C"); N(SyntaxKind.OpenBraceToken); N(SyntaxKind.MethodDeclaration); { @@ -1051,7 +1069,7 @@ void Foo() { N(SyntaxKind.VoidKeyword); } - N(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "Foo"); N(SyntaxKind.ParameterList); { N(SyntaxKind.OpenParenToken); @@ -1066,7 +1084,7 @@ void Foo() { N(SyntaxKind.IdentifierName); { - N(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "var"); } N(SyntaxKind.ArgumentList); { @@ -1075,7 +1093,7 @@ void Foo() { N(SyntaxKind.IdentifierName); { - N(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "a"); } } N(SyntaxKind.CommaToken); @@ -1083,7 +1101,7 @@ void Foo() { N(SyntaxKind.IdentifierName); { - N(SyntaxKind.IdentifierToken); + N(SyntaxKind.IdentifierToken, "b"); } } N(SyntaxKind.CloseParenToken); @@ -1134,53 +1152,59 @@ void Foo() N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); - N(SyntaxKind.DeconstructionDeclarationStatement); + N(SyntaxKind.ExpressionStatement); { - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.TupleExpression); { N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierName); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "Int32"); - } - N(SyntaxKind.SingleVariableDesignation); - { - N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int32"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "x"); + } } } N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "var"); - } - N(SyntaxKind.ParenthesizedVariableDesignation); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.OpenParenToken); - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.IdentifierName); { - N(SyntaxKind.IdentifierToken, "y"); + N(SyntaxKind.IdentifierToken, "var"); } - N(SyntaxKind.CommaToken); - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.ParenthesizedVariableDesignation); { - N(SyntaxKind.IdentifierToken, "z"); + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "y"); + } + N(SyntaxKind.CommaToken); + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "z"); + } + N(SyntaxKind.CloseParenToken); } - N(SyntaxKind.CloseParenToken); } } N(SyntaxKind.CloseParenToken); } - } - N(SyntaxKind.EqualsToken); - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "foo"); + N(SyntaxKind.EqualsToken); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "foo"); + } } N(SyntaxKind.SemicolonToken); } @@ -1231,32 +1255,38 @@ void Foo() { N(SyntaxKind.ForKeyword); N(SyntaxKind.OpenParenToken); - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.TupleExpression); { N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierName); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "Int32"); - } - N(SyntaxKind.SingleVariableDesignation); - { - N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int32"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "x"); + } } } N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierName); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "Int64"); - } - N(SyntaxKind.SingleVariableDesignation); - { - N(SyntaxKind.IdentifierToken, "y"); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "Int64"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "y"); + } } } N(SyntaxKind.CloseParenToken); @@ -1278,12 +1308,12 @@ void Foo() } N(SyntaxKind.CloseBraceToken); } - N(SyntaxKind.CloseBraceToken); } - N(SyntaxKind.EndOfFileToken); + N(SyntaxKind.CloseBraceToken); } - EOF(); + N(SyntaxKind.EndOfFileToken); } + EOF(); } [Fact] @@ -1323,9 +1353,9 @@ void Foo() { N(SyntaxKind.ForKeyword); N(SyntaxKind.OpenParenToken); - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.DeclarationExpression); { N(SyntaxKind.IdentifierName); { @@ -1361,8 +1391,8 @@ void Foo() N(SyntaxKind.CloseBraceToken); } } + N(SyntaxKind.CloseBraceToken); } - N(SyntaxKind.CloseBraceToken); } N(SyntaxKind.CloseBraceToken); } @@ -1408,30 +1438,36 @@ void Foo() { N(SyntaxKind.ForEachKeyword); N(SyntaxKind.OpenParenToken); - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.TupleExpression); { N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.PredefinedType); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IntKeyword); - } - N(SyntaxKind.SingleVariableDesignation); - { - N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "x"); + } } } N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.IdentifierName); - { - N(SyntaxKind.IdentifierToken, "var"); - } - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "y"); + N(SyntaxKind.IdentifierName); + { + N(SyntaxKind.IdentifierToken, "var"); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "y"); + } } } N(SyntaxKind.CloseParenToken); @@ -1495,7 +1531,7 @@ void Foo() { N(SyntaxKind.ForEachKeyword); N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.DeclarationExpression); { N(SyntaxKind.IdentifierName); { @@ -1546,34 +1582,40 @@ public void DeconstructionInScript() { N(SyntaxKind.GlobalStatement); { - N(SyntaxKind.DeconstructionDeclarationStatement); + N(SyntaxKind.ExpressionStatement); { - N(SyntaxKind.VariableComponentAssignment); + N(SyntaxKind.SimpleAssignmentExpression); { - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.TupleExpression); { N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.PredefinedType); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IntKeyword); - } - N(SyntaxKind.SingleVariableDesignation); - { - N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "x"); + } } } N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.PredefinedType); - { - N(SyntaxKind.IntKeyword); - } - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "y"); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "y"); + } } } N(SyntaxKind.CloseParenToken); @@ -1621,30 +1663,36 @@ public void DeconstructionForEachInScript() { N(SyntaxKind.ForEachKeyword); N(SyntaxKind.OpenParenToken); - N(SyntaxKind.ParenthesizedVariableComponent); + N(SyntaxKind.TupleExpression); { N(SyntaxKind.OpenParenToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.PredefinedType); - { - N(SyntaxKind.IntKeyword); - } - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "x"); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "x"); + } } } N(SyntaxKind.CommaToken); - N(SyntaxKind.TypedVariableComponent); + N(SyntaxKind.Argument); { - N(SyntaxKind.PredefinedType); - { - N(SyntaxKind.IntKeyword); - } - N(SyntaxKind.SingleVariableDesignation); + N(SyntaxKind.DeclarationExpression); { - N(SyntaxKind.IdentifierToken, "y"); + N(SyntaxKind.PredefinedType); + { + N(SyntaxKind.IntKeyword); + } + N(SyntaxKind.SingleVariableDesignation); + { + N(SyntaxKind.IdentifierToken, "y"); + } } } N(SyntaxKind.CloseParenToken); From d0f94c3656e2be374363f2b6f183a29e1197a0a1 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Wed, 2 Nov 2016 16:30:31 -0700 Subject: [PATCH 2/8] Updating binding and semantic model to new syntax --- .../Portable/Binder/Binder_Deconstruct.cs | 76 +++--- .../Portable/Binder/Binder_Expressions.cs | 9 +- .../Portable/Binder/Binder_Statements.cs | 10 +- .../Binder/ExpressionVariableFinder.cs | 128 ++++++++- .../Portable/Binder/ForEachLoopBinder.cs | 84 +++++- .../CSharp/Portable/Binder/ForLoopBinder.cs | 26 +- .../Portable/Binder/LocalBinderFactory.cs | 8 +- .../Portable/Binder/LocalScopeBinder.cs | 85 +----- .../BoundTree/OutVariablePendingInference.cs | 8 +- .../Compilation/CSharpSemanticModel.cs | 9 +- .../Compilation/MemberSemanticModel.cs | 82 ++++-- .../FlowAnalysis/VariablesDeclaredWalker.cs | 2 +- .../AsyncExceptionHandlerRewriter.cs | 2 +- .../Instrumentation/DebugInfoInjector.cs | 10 +- .../Lowering/Instrumentation/Instrumenter.cs | 2 +- .../Lowering/LambdaRewriter/LambdaRewriter.cs | 2 +- .../LocalRewriter_FixedStatement.cs | 2 +- .../LocalRewriter_ForEachStatement.cs | 2 +- .../CSharp/Portable/Parser/LanguageParser.cs | 17 +- .../CSharp/Portable/PublicAPI.Unshipped.txt | 48 ++-- .../Portable/Symbols/LocalDeclarationKind.cs | 7 +- .../CSharp/Portable/Symbols/LocalSymbol.cs | 11 - .../Source/GlobalExpressionVariable.cs | 17 +- .../Symbols/Source/SourceLocalSymbol.cs | 33 +-- .../Source/SourceMemberContainerSymbol.cs | 71 ----- .../CSharp/Portable/Syntax/LambdaUtilities.cs | 2 +- .../CSharp/Portable/Syntax/LookupPosition.cs | 7 +- .../CSharp/Portable/Syntax/Syntax.xml | 18 +- .../Portable/Syntax/SyntaxExtensions.cs | 41 ++- .../CSharp/Portable/Syntax/SyntaxFacts.cs | 10 +- .../CSharp/Portable/Syntax/SyntaxKind.cs | 2 +- .../Emit/CodeGen/CodeGenDeconstructTests.cs | 258 ++++++++++++++---- .../Test/Emit/CodeGen/CodeGenTupleTest.cs | 8 +- .../DiagnosticAnalyzerTests.AllInOne.cs | 6 +- .../Semantic/Semantics/DeconstructionTests.cs | 72 ++++- .../Test/Semantic/Semantics/OutVarTests.cs | 131 +++++---- .../Semantics/PatternMatchingTests_Scope.cs | 5 +- .../Syntax/Parsing/DeconstructionTests.cs | 6 +- .../KeywordHighlighters/LoopHighlighter.cs | 2 +- .../DiagnosticAnalyzerDriverTests.cs | 2 +- .../CSharpAddBracesCodeFixProvider.cs | 2 +- .../CSharpAddBracesDiagnosticAnalyzer.cs | 4 +- .../EditAndContinue/BreakpointSpans.cs | 4 +- .../CSharpEditAndContinueAnalyzer.cs | 6 +- .../StatementSyntaxComparer.cs | 4 +- .../Providers/BlockSyntaxStructureProvider.cs | 2 +- ...SharpProximityExpressionsService.Worker.cs | 4 +- .../ContextQuery/SyntaxTokenExtensions.cs | 2 +- .../ContextQuery/SyntaxTreeExtensions.cs | 2 +- .../ForEachStatementSyntaxExtensions.cs | 2 +- ...ParenthesizedExpressionSyntaxExtensions.cs | 2 +- .../Extensions/SyntaxNodeExtensions.cs | 4 +- .../Rules/NewLineUserSettingFormattingRule.cs | 2 +- .../Formatting/Rules/SpacingFormattingRule.cs | 2 +- .../Utilities/FormattingRangeHelper.cs | 2 +- 55 files changed, 789 insertions(+), 576 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs index c5c19d2331d1f..900844049d7ca 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs @@ -11,22 +11,51 @@ namespace Microsoft.CodeAnalysis.CSharp { /// - /// This portion of the binder converts deconstruction-assignment syntax (AssignmentExpressionSyntax nodes with the left being a tuple expression) - /// into a BoundDeconstructionAssignmentOperator (or bad node). + /// This portion of the binder converts deconstruction-assignment syntax (AssignmentExpressionSyntax nodes with the left + /// being a tuple expression or declaration expression) into a BoundDeconstructionAssignmentOperator (or bad node). /// internal partial class Binder { - private BoundExpression BindDeconstructionAssignment(AssignmentExpressionSyntax node, DiagnosticBag diagnostics) + private BoundExpression BindDeconstruction(AssignmentExpressionSyntax node, DiagnosticBag diagnostics) { - var left = (TupleExpressionSyntax)node.Left; - ArrayBuilder checkedVariables = BindDeconstructionAssignmentVariables(left.Arguments, left, diagnostics); + var left = node.Left; + var right = node.Right; + if (node.IsDeconstructionDeclaration()) + { + return BindDeconstructionDeclaration(node, left, right, diagnostics); + } + + // We only parse assignment-only or declaration-only deconstructions at this point + AssertDeconstructionIsAssignment(left); + + var tuple = (TupleExpressionSyntax)left; + ArrayBuilder checkedVariables = BindDeconstructionAssignmentVariables(tuple.Arguments, tuple, diagnostics); var result = BindDeconstructionAssignment(node, node.Right, checkedVariables, diagnostics, isDeclaration: false); FreeDeconstructionVariables(checkedVariables); - return result; } + [Conditional("DEBUG")] + private void AssertDeconstructionIsAssignment(ExpressionSyntax expression) + { + switch (expression.Kind()) + { + case SyntaxKind.DeclarationExpression: + Debug.Assert(false); + break; + case SyntaxKind.TupleExpression: + var tuple = (TupleExpressionSyntax)expression; + foreach (var arg in tuple.Arguments) + { + AssertDeconstructionIsAssignment(arg.Expression); + } + break; + default: + return; + } + } + private static void FreeDeconstructionVariables(ArrayBuilder variables) { foreach (var v in variables) @@ -606,24 +635,7 @@ private static void FlattenDeconstructVariables(ArrayBuilder private DeconstructionVariable BindDeconstructionDeclarationVariables( - VariableComponentSyntax node, + ExpressionSyntax node, DiagnosticBag diagnostics) { switch (node.Kind()) { - case SyntaxKind.TypedVariableComponent: + case SyntaxKind.DeclarationExpression: { - var component = (TypedVariableComponentSyntax)node; + var component = (DeclarationExpressionSyntax)node; return BindDeconstructionDeclarationVariables(component.Type, component.Designation, diagnostics); } - case SyntaxKind.ParenthesizedVariableComponent: + case SyntaxKind.TupleExpression: { - var component = (ParenthesizedVariableComponentSyntax)node; - var builder = ArrayBuilder.GetInstance(component.Variables.Count); - foreach (var n in component.Variables) + var component = (TupleExpressionSyntax)node; + var builder = ArrayBuilder.GetInstance(component.Arguments.Count); + foreach (var arg in component.Arguments) { - builder.Add(BindDeconstructionDeclarationVariables(n, diagnostics)); + builder.Add(BindDeconstructionDeclarationVariables(arg.Expression, diagnostics)); } return new DeconstructionVariable(builder, node); } diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs index 5373fa4d13f85..d0803afa56ae4 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Expressions.cs @@ -2095,11 +2095,12 @@ private BoundExpression BindArgumentValue(DiagnosticBag diagnostics, ArgumentSyn private BoundExpression BindOutVariableArgument(DeclarationExpressionSyntax declarationExpression, DiagnosticBag diagnostics) { - var typeSyntax = declarationExpression.Type(); + TypeSyntax typeSyntax = declarationExpression.Type; + var designation = (SingleVariableDesignationSyntax)declarationExpression.Designation; bool isVar; // Is this a local? - SourceLocalSymbol localSymbol = this.LookupLocal(declarationExpression.Identifier()); + SourceLocalSymbol localSymbol = this.LookupLocal(designation.Identifier); if ((object)localSymbol != null) { @@ -2130,7 +2131,7 @@ private BoundExpression BindOutVariableArgument(DeclarationExpressionSyntax decl } // Is this a field? - GlobalExpressionVariable expressionVariableField = LookupDeclaredField(declarationExpression.VariableDesignation()); + GlobalExpressionVariable expressionVariableField = LookupDeclaredField(designation); if ((object)expressionVariableField == null) { @@ -2138,7 +2139,7 @@ private BoundExpression BindOutVariableArgument(DeclarationExpressionSyntax decl throw ExceptionUtilities.Unreachable; } - BoundExpression receiver = SynthesizeReceiver(declarationExpression.VariableDesignation(), expressionVariableField, diagnostics); + BoundExpression receiver = SynthesizeReceiver(designation, expressionVariableField, diagnostics); if (typeSyntax.IsVar) { diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index e485fc418255f..316f534fc9c83 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -43,9 +43,6 @@ public virtual BoundStatement BindStatement(StatementSyntax node, DiagnosticBag case SyntaxKind.LocalDeclarationStatement: result = BindLocalDeclarationStatement((LocalDeclarationStatementSyntax)node, diagnostics); break; - case SyntaxKind.DeconstructionDeclarationStatement: - result = BindDeconstructionDeclarationStatement((DeconstructionDeclarationStatementSyntax)node, diagnostics); - break; case SyntaxKind.LocalFunctionStatement: result = BindLocalFunctionStatement((LocalFunctionStatementSyntax)node, diagnostics); break; @@ -68,7 +65,7 @@ public virtual BoundStatement BindStatement(StatementSyntax node, DiagnosticBag result = BindFor((ForStatementSyntax)node, diagnostics); break; case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: result = BindForEach((CommonForEachStatementSyntax)node, diagnostics); break; case SyntaxKind.BreakStatement: @@ -283,7 +280,6 @@ internal BoundStatement BindPossibleEmbeddedStatement(StatementSyntax node, Diag case SyntaxKind.IfStatement: case SyntaxKind.YieldReturnStatement: case SyntaxKind.LocalDeclarationStatement: - case SyntaxKind.DeconstructionDeclarationStatement: case SyntaxKind.ReturnStatement: case SyntaxKind.ThrowStatement: binder = this.GetBinder(node); @@ -1729,9 +1725,9 @@ private BoundExpression BindAssignment(AssignmentExpressionSyntax node, Diagnost Debug.Assert(node.Left != null); Debug.Assert(node.Right != null); - if (node.Left.Kind() == SyntaxKind.TupleExpression) + if (node.Left.Kind() == SyntaxKind.TupleExpression || node.Left.Kind() == SyntaxKind.DeclarationExpression) { - return BindDeconstructionAssignment(node, diagnostics); + return BindDeconstruction(node, diagnostics); } var op1 = BindValue(node.Left, diagnostics, BindValueKind.Assignment); // , BIND_MEMBERSET); diff --git a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs index d1ee953d6d178..8421f63797b38 100644 --- a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs @@ -210,16 +210,16 @@ public override void VisitDeclarationPattern(DeclarationPatternSyntax node) public override void VisitQueryExpression(QueryExpressionSyntax node) { - // Variables declared in [in] expressions of top level from clause and - // join clauses are in scope + // Variables declared in [in] expressions of top level from clause and + // join clauses are in scope VisitNodeToBind(node.FromClause.Expression); Visit(node.Body); } public override void VisitQueryBody(QueryBodySyntax node) { - // Variables declared in [in] expressions of top level from clause and - // join clauses are in scope + // Variables declared in [in] expressions of top level from clause and + // join clauses are in scope foreach (var clause in node.Clauses) { if (clause.Kind() == SyntaxKind.JoinClause) @@ -268,7 +268,83 @@ public override void VisitDeclarationExpression(DeclarationExpressionSyntax node } } + public override void VisitAssignmentExpression(AssignmentExpressionSyntax node) + { + if (node.IsDeconstructionDeclaration()) + { + CollectVariablesFromDeconstruction(node.Left, node); + } + else + { + Visit(node.Left); + } + + Visit(node.Right); + } + + private void CollectVariablesFromDeconstruction( + ExpressionSyntax declaration, + AssignmentExpressionSyntax deconstruction) + { + switch (declaration.Kind()) + { + case SyntaxKind.TupleExpression: + { + var tuple = (TupleExpressionSyntax)declaration; + foreach (var arg in tuple.Arguments) + { + CollectVariablesFromDeconstruction(arg.Expression, deconstruction); + } + break; + } + case SyntaxKind.DeclarationExpression: + { + var declarationExpression = (DeclarationExpressionSyntax)declaration; + CollectVariablesFromDeconstruction(declarationExpression.Designation, declarationExpression.Type, deconstruction); + break; + } + default: + throw ExceptionUtilities.UnexpectedValue(declaration.Kind()); + } + } + + private void CollectVariablesFromDeconstruction( + VariableDesignationSyntax designation, + TypeSyntax closestTypeSyntax, + AssignmentExpressionSyntax deconstruction) + { + switch (designation.Kind()) + { + case SyntaxKind.SingleVariableDesignation: + { + var single = (SingleVariableDesignationSyntax)designation; + var variable = MakeDeconstructionVariable(closestTypeSyntax, single, deconstruction); + if ((object)variable != null) + { + _localsBuilder.Add(variable); + } + break; + } + case SyntaxKind.ParenthesizedVariableDesignation: + { + var tuple = (ParenthesizedVariableDesignationSyntax)designation; + foreach (var d in tuple.Variables) + { + CollectVariablesFromDeconstruction(d, closestTypeSyntax, deconstruction); + } + break; + } + default: + throw ExceptionUtilities.UnexpectedValue(designation.Kind()); + } + } + protected abstract TFieldOrLocalSymbol MakeOutVariable(DeclarationExpressionSyntax node, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind); + + protected abstract TFieldOrLocalSymbol MakeDeconstructionVariable( + TypeSyntax closestTypeSyntax, + SingleVariableDesignationSyntax designation, + AssignmentExpressionSyntax deconstruction); } internal class ExpressionVariableFinder : ExpressionVariableFinder @@ -344,9 +420,10 @@ protected override LocalSymbol MakePatternVariable(DeclarationPatternSyntax node protected override LocalSymbol MakeOutVariable(DeclarationExpressionSyntax node, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind) { NamedTypeSymbol container = _scopeBinder.ContainingType; + var designation = (SingleVariableDesignationSyntax)node.Designation; - if ((object)container != null && container.IsScriptClass && - (object)_scopeBinder.LookupDeclaredField(node.VariableDesignation()) != null) + if ((object)container != null && container.IsScriptClass && + (object)_scopeBinder.LookupDeclaredField(designation) != null) { // This is a field declaration return null; @@ -356,13 +433,28 @@ protected override LocalSymbol MakeOutVariable(DeclarationExpressionSyntax node, containingSymbol: _scopeBinder.ContainingMemberOrLambda, scopeBinder: _scopeBinder, nodeBinder: _enclosingBinder, - typeSyntax: node.Type(), - identifierToken: node.Identifier(), + typeSyntax: node.Type, + identifierToken: designation.Identifier, kind: LocalDeclarationKind.RegularVariable, nodeToBind: nodeToBind, forbiddenZone: argumentListSyntax); } + protected override LocalSymbol MakeDeconstructionVariable( + TypeSyntax closestTypeSyntax, + SingleVariableDesignationSyntax designation, + AssignmentExpressionSyntax deconstruction) + { + return SourceLocalSymbol.MakeDeconstructionLocal( + containingSymbol: _scopeBinder.ContainingMemberOrLambda, + scopeBinder: _scopeBinder, + nodeBinder: _enclosingBinder, + closestTypeSyntax: closestTypeSyntax, + identifierToken: designation.Identifier, + kind: LocalDeclarationKind.RegularVariable, + deconstruction: deconstruction); + } + #region pool private static readonly ObjectPool s_poolInstance = CreatePool(); @@ -414,13 +506,29 @@ protected override Symbol MakePatternVariable(DeclarationPatternSyntax node, Syn protected override Symbol MakeOutVariable(DeclarationExpressionSyntax node, BaseArgumentListSyntax argumentListSyntax, SyntaxNode nodeToBind) { - var designation = node.VariableDesignation(); + var designation = (SingleVariableDesignationSyntax)node.Designation; return GlobalExpressionVariable.Create( - _containingType, _modifiers, node.Type(), + _containingType, _modifiers, node.Type, designation.Identifier.ValueText, designation, designation.Identifier.GetLocation(), _containingFieldOpt, nodeToBind); } + protected override Symbol MakeDeconstructionVariable( + TypeSyntax closestTypeSyntax, + SingleVariableDesignationSyntax designation, + AssignmentExpressionSyntax deconstruction) + { + return GlobalExpressionVariable.Create( + containingType: _containingType, + modifiers: DeclarationModifiers.Private, + typeSyntax: closestTypeSyntax, + name: designation.Identifier.ValueText, + syntax: designation, + location: designation.Location, + containingFieldOpt: null, + nodeToBind: deconstruction); + } + #region pool private static readonly ObjectPool s_poolInstance = CreatePool(); diff --git a/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs b/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs index 87e902682d579..9df66381a91d2 100644 --- a/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs @@ -42,12 +42,12 @@ protected override ImmutableArray BuildLocals() { switch (_syntax.Kind()) { - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: { - var syntax = (ForEachComponentStatementSyntax)_syntax; + var syntax = (ForEachVariableStatementSyntax)_syntax; var locals = ArrayBuilder.GetInstance(); CollectLocalsFromDeconstruction( - syntax.VariableComponent, + syntax.Variable, LocalDeclarationKind.ForEachIterationVariable, locals, syntax); @@ -69,6 +69,76 @@ protected override ImmutableArray BuildLocals() } } + internal void CollectLocalsFromDeconstruction( + ExpressionSyntax declaration, + LocalDeclarationKind kind, + ArrayBuilder locals, + SyntaxNode deconstructionStatement, + Binder enclosingBinderOpt = null) + { + switch (declaration.Kind()) + { + case SyntaxKind.TupleExpression: + { + var tuple = (TupleExpressionSyntax)declaration; + foreach (var arg in tuple.Arguments) + { + CollectLocalsFromDeconstruction(arg.Expression, kind, locals, deconstructionStatement, enclosingBinderOpt); + } + break; + } + case SyntaxKind.DeclarationExpression: + { + var declarationExpression = (DeclarationExpressionSyntax)declaration; + CollectLocalsFromDeconstruction( + declarationExpression.Designation, declarationExpression.Type, + kind, locals, deconstructionStatement, enclosingBinderOpt); + + break; + } + default: + throw ExceptionUtilities.UnexpectedValue(declaration.Kind()); + } + } + + internal void CollectLocalsFromDeconstruction( + VariableDesignationSyntax designation, + TypeSyntax closestTypeSyntax, + LocalDeclarationKind kind, + ArrayBuilder locals, + SyntaxNode deconstructionStatement, + Binder enclosingBinderOpt) + { + switch (designation.Kind()) + { + case SyntaxKind.SingleVariableDesignation: + { + var single = (SingleVariableDesignationSyntax)designation; + SourceLocalSymbol localSymbol = SourceLocalSymbol.MakeDeconstructionLocal( + this.ContainingMemberOrLambda, + this, + enclosingBinderOpt ?? this, + closestTypeSyntax, + single.Identifier, + kind, + deconstructionStatement); + locals.Add(localSymbol); + break; + } + case SyntaxKind.ParenthesizedVariableDesignation: + { + var tuple = (ParenthesizedVariableDesignationSyntax)designation; + foreach (var d in tuple.Variables) + { + CollectLocalsFromDeconstruction(d, closestTypeSyntax, kind, locals, deconstructionStatement, enclosingBinderOpt); + } + break; + } + default: + throw ExceptionUtilities.UnexpectedValue(designation.Kind()); + } + } + /// /// Bind the ForEachStatementSyntax at the root of this binder. /// @@ -90,7 +160,7 @@ internal override BoundStatement BindForEachDeconstruction(DiagnosticBag diagnos TypeSymbol inferredType; bool hasErrors = !GetEnumeratorInfoAndInferCollectionElementType(ref builder, ref collectionExpr, diagnostics, out inferredType); - VariableComponentSyntax variables = ((ForEachComponentStatementSyntax)_syntax).VariableComponent; + ExpressionSyntax variables = ((ForEachVariableStatementSyntax)_syntax).Variable; var valuePlaceholder = new BoundDeconstructValuePlaceholder(_syntax.Expression, inferredType ?? CreateErrorType("var")); BoundDeconstructionAssignmentOperator deconstruction = BindDeconstructionDeclaration( variables, @@ -151,12 +221,12 @@ private BoundForEachStatement BindForEachPartsWorker(DiagnosticBag diagnostics, this.IterationVariable.SetType(iterationVariableType); break; } - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: { - var node = (ForEachComponentStatementSyntax)_syntax; + var node = (ForEachVariableStatementSyntax)_syntax; iterationVariableType = inferredType ?? CreateErrorType("var"); - var variables = node.VariableComponent; + var variables = node.Variable; var valuePlaceholder = new BoundDeconstructValuePlaceholder(_syntax.Expression, iterationVariableType); BoundDeconstructionAssignmentOperator deconstruction = BindDeconstructionDeclaration( variables, diff --git a/src/Compilers/CSharp/Portable/Binder/ForLoopBinder.cs b/src/Compilers/CSharp/Portable/Binder/ForLoopBinder.cs index 2d2230be655aa..cedb78603144d 100644 --- a/src/Compilers/CSharp/Portable/Binder/ForLoopBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ForLoopBinder.cs @@ -24,21 +24,12 @@ override protected ImmutableArray BuildLocals() { var locals = ArrayBuilder.GetInstance(); - // Deconstruction, Declaration, and Initializers are mutually exclusive. - if (_syntax.Deconstruction != null) - { - CollectLocalsFromDeconstruction( - _syntax.Deconstruction.VariableComponent, - LocalDeclarationKind.ForInitializerVariable, - locals, - _syntax); - ExpressionVariableFinder.FindExpressionVariables(this, locals, _syntax.Deconstruction.Value); - } - else if (_syntax.Declaration != null) + // Declaration and Initializers are mutually exclusive. + if (_syntax.Declaration != null) { foreach (var vdecl in _syntax.Declaration.Variables) { - var localSymbol = MakeLocal(_syntax.Declaration, vdecl, LocalDeclarationKind.ForInitializerVariable); + var localSymbol = MakeLocal(_syntax.Declaration, vdecl, LocalDeclarationKind.RegularVariable); locals.Add(localSymbol); // also gather expression-declared variables from the bracketed argument lists and the initializers @@ -64,16 +55,11 @@ internal override BoundForStatement BindForParts(DiagnosticBag diagnostics, Bind private BoundForStatement BindForParts(ForStatementSyntax node, Binder originalBinder, DiagnosticBag diagnostics) { BoundStatement initializer; - // Deconstruction, Declaration, and Initializers are mutually exclusive. - if (_syntax.Deconstruction != null) - { - var assignment = originalBinder.BindDeconstructionDeclaration(node.Deconstruction, node.Deconstruction.VariableComponent, node.Deconstruction.Value, diagnostics); - initializer = new BoundLocalDeconstructionDeclaration(node, assignment); - } - else if (_syntax.Declaration != null) + // Declaration and Initializers are mutually exclusive. + if (_syntax.Declaration != null) { ImmutableArray unused; - initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.ForInitializerVariable, diagnostics, out unused); + initializer = originalBinder.BindForOrUsingOrFixedDeclarations(node.Declaration, LocalDeclarationKind.RegularVariable, diagnostics, out unused); } else { diff --git a/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs b/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs index 95a36b442e7eb..2d685410aefbf 100644 --- a/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs +++ b/src/Compilers/CSharp/Portable/Binder/LocalBinderFactory.cs @@ -441,7 +441,7 @@ public override void VisitForEachStatement(ForEachStatementSyntax node) VisitCommonForEachStatement(node); } - public override void VisitForEachComponentStatement(ForEachComponentStatementSyntax node) + public override void VisitForEachVariableStatement(ForEachVariableStatementSyntax node) { VisitCommonForEachStatement(node); } @@ -662,11 +662,6 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) Visit(node.Initializer?.Value); } - public override void VisitDeconstructionDeclarationStatement(DeconstructionDeclarationStatementSyntax node) - { - Visit(node.Assignment.Value, _enclosing); - } - public override void VisitReturnStatement(ReturnStatementSyntax node) { if (node.Expression != null) @@ -746,7 +741,6 @@ private Binder GetBinderForPossibleEmbeddedStatement(StatementSyntax statement, switch (statement.Kind()) { case SyntaxKind.LocalDeclarationStatement: - case SyntaxKind.DeconstructionDeclarationStatement: case SyntaxKind.LabeledStatement: case SyntaxKind.LocalFunctionStatement: // It is an error to have a declaration or a label in an embedded statement, diff --git a/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs b/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs index 5bc469ab3608e..546904e8f9ad5 100644 --- a/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/LocalScopeBinder.cs @@ -169,21 +169,6 @@ protected ImmutableArray BuildLocals(SyntaxList st switch (innerStatement.Kind()) { - case SyntaxKind.DeconstructionDeclarationStatement: - { - var decl = (DeconstructionDeclarationStatementSyntax)innerStatement; - Binder deconstructionDeclarationBinder = enclosingBinder.GetBinder(innerStatement) ?? enclosingBinder; - - CollectLocalsFromDeconstruction( - decl.Assignment.VariableComponent, - LocalDeclarationKind.RegularVariable, - locals, - innerStatement, - deconstructionDeclarationBinder); - - ExpressionVariableFinder.FindExpressionVariables(this, locals, decl.Assignment.Value, deconstructionDeclarationBinder); - break; - } case SyntaxKind.LocalDeclarationStatement: { Binder localDeclarationBinder = enclosingBinder.GetBinder(innerStatement) ?? enclosingBinder; @@ -230,74 +215,6 @@ protected ImmutableArray BuildLocals(SyntaxList st return locals.ToImmutableAndFree(); } - - internal void CollectLocalsFromDeconstruction( - VariableComponentSyntax declaration, - LocalDeclarationKind kind, - ArrayBuilder locals, - SyntaxNode deconstructionStatement, - Binder enclosingBinderOpt = null) - { - switch (declaration.Kind()) - { - case SyntaxKind.ParenthesizedVariableComponent: - { - var component = (ParenthesizedVariableComponentSyntax)declaration; - foreach (var decl in component.Variables) - { - CollectLocalsFromDeconstruction(decl, kind, locals, deconstructionStatement, enclosingBinderOpt); - } - break; - } - case SyntaxKind.TypedVariableComponent: - { - var component = (TypedVariableComponentSyntax)declaration; - CollectLocalsFromDeconstruction(component.Designation, component.Type, kind, locals, deconstructionStatement, enclosingBinderOpt); - break; - } - default: - throw ExceptionUtilities.UnexpectedValue(declaration.Kind()); - } - } - - internal void CollectLocalsFromDeconstruction( - VariableDesignationSyntax designation, - TypeSyntax closestTypeSyntax, - LocalDeclarationKind kind, - ArrayBuilder locals, - SyntaxNode deconstructionStatement, - Binder enclosingBinderOpt) - { - switch (designation.Kind()) - { - case SyntaxKind.SingleVariableDesignation: - { - var single = (SingleVariableDesignationSyntax)designation; - SourceLocalSymbol localSymbol = SourceLocalSymbol.MakeDeconstructionLocal( - this.ContainingMemberOrLambda, - this, - enclosingBinderOpt ?? this, - closestTypeSyntax, - single.Identifier, - kind, - deconstructionStatement); - locals.Add(localSymbol); - break; - } - case SyntaxKind.ParenthesizedVariableDesignation: - { - var tuple = (ParenthesizedVariableDesignationSyntax)designation; - foreach (var d in tuple.Variables) - { - CollectLocalsFromDeconstruction(d, closestTypeSyntax, kind, locals, deconstructionStatement, enclosingBinderOpt); - } - break; - } - default: - throw ExceptionUtilities.UnexpectedValue(designation.Kind()); - } - } - protected ImmutableArray BuildLocalFunctions(SyntaxList statements) { ArrayBuilder locals = null; @@ -504,7 +421,7 @@ protected override void AddLookupSymbolsInfoInSingleBinder(LookupSymbolsInfo res private bool ReportConflictWithLocal(Symbol local, Symbol newSymbol, string name, Location newLocation, DiagnosticBag diagnostics) { - // Quirk of the way we represent lambda parameters. + // Quirk of the way we represent lambda parameters. SymbolKind newSymbolKind = (object)newSymbol == null ? SymbolKind.Parameter : newSymbol.Kind; if (newSymbolKind == SymbolKind.ErrorType) return true; diff --git a/src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs b/src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs index 8042224b2c512..885a8ac6d74ec 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs +++ b/src/Compilers/CSharp/Portable/BoundTree/OutVariablePendingInference.cs @@ -43,7 +43,7 @@ private BoundExpression SetInferredType(TypeSymbol type, Binder binderOpt, Diagn ((MethodSymbol)localSymbol.ContainingSymbol).IsAsync && type.IsRestrictedType()) { - var declaration = (TypedVariableComponentSyntax)((DeclarationExpressionSyntax)this.Syntax).VariableComponent; + var declaration = (DeclarationExpressionSyntax)this.Syntax; Binder.Error(diagnosticsOpt, ErrorCode.ERR_BadSpecialByRefLocal, declaration.Type, type); } } @@ -76,10 +76,10 @@ private BoundExpression SetInferredType(TypeSymbol type, Binder binderOpt, Diagn private void ReportInferenceFailure(DiagnosticBag diagnostics) { - var declaration = (DeclarationExpressionSyntax)this.Syntax; + var designation = (SingleVariableDesignationSyntax)((DeclarationExpressionSyntax)this.Syntax).Designation; Binder.Error( - diagnostics, ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable, declaration.Identifier(), - declaration.Identifier().ValueText); + diagnostics, ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedOutVariable, designation.Identifier, + designation.Identifier.ValueText); } public BoundExpression FailInference(Binder binder, DiagnosticBag diagnosticsOpt) diff --git a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs index 4aac950a7c83e..3ce9f042bd6fd 100644 --- a/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs @@ -510,7 +510,7 @@ public SymbolInfo GetSymbolInfo(ExpressionSyntax expression, CancellationToken c { CheckSyntaxNode(expression); - SyntaxNode parent; + DeclarationExpressionSyntax parent; if (!CanGetSemanticInfo(expression, allowNamedArgumentName: true)) { @@ -521,15 +521,14 @@ public SymbolInfo GetSymbolInfo(ExpressionSyntax expression, CancellationToken c // Named arguments handled in special way. return this.GetNamedArgumentSymbolInfo((IdentifierNameSyntax)expression, cancellationToken); } - else if (SyntaxFacts.IsVariableComponentType(expression, out parent)) + else if (SyntaxFacts.IsDeclarationExpressionType(expression, out parent)) { - var declaration = (TypedVariableComponentSyntax)parent; - if (declaration.Designation.Kind() != SyntaxKind.SingleVariableDesignation) + if (parent.Designation.Kind() != SyntaxKind.SingleVariableDesignation) { return SymbolInfo.None; } - return TypeFromVariable((SingleVariableDesignationSyntax)declaration.Designation, cancellationToken); + return TypeFromVariable((SingleVariableDesignationSyntax)parent.Designation, cancellationToken); } return this.GetSymbolInfoWorker(expression, SymbolInfoOptions.DefaultOptions, cancellationToken); diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs index 19adb9deb9d6c..ddff5f3fae0af 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs @@ -163,6 +163,8 @@ private static Binder GetEnclosingBinder(SyntaxNode node, int position, Binder r Debug.Assert(current != null); // Why were we asked for an enclosing binder for a node outside our root? StatementSyntax stmt = current as StatementSyntax; TypeOfExpressionSyntax typeOfExpression; + SyntaxKind kind = current.Kind(); + if (stmt != null) { if (LookupPosition.IsInStatementScope(position, stmt)) @@ -175,14 +177,14 @@ private static Binder GetEnclosingBinder(SyntaxNode node, int position, Binder r } } } - else if (current.Kind() == SyntaxKind.CatchClause) + else if (kind == SyntaxKind.CatchClause) { if (LookupPosition.IsInCatchBlockScope(position, (CatchClauseSyntax)current)) { binder = rootBinder.GetBinder(current); } } - else if (current.Kind() == SyntaxKind.CatchFilterClause) + else if (kind == SyntaxKind.CatchFilterClause) { if (LookupPosition.IsInCatchFilterScope(position, (CatchFilterClauseSyntax)current)) { @@ -205,7 +207,7 @@ private static Binder GetEnclosingBinder(SyntaxNode node, int position, Binder r } } } - else if (current.Kind() == SyntaxKind.TypeOfExpression && + else if (kind == SyntaxKind.TypeOfExpression && typeOfArgument == null && LookupPosition.IsBetweenTokens( position, @@ -215,14 +217,14 @@ private static Binder GetEnclosingBinder(SyntaxNode node, int position, Binder r typeOfArgument = typeOfExpression.Type; typeOfEncounteredBeforeUnexpectedAnonymousFunction = unexpectedAnonymousFunction == null; } - else if (current.Kind() == SyntaxKind.SwitchSection) + else if (kind == SyntaxKind.SwitchSection) { if (LookupPosition.IsInSwitchSectionScope(position, (SwitchSectionSyntax)current)) { binder = rootBinder.GetBinder(current); } } - else if (current.Kind() == SyntaxKind.ArgumentList) + else if (kind == SyntaxKind.ArgumentList) { var argList = (ArgumentListSyntax)current; @@ -231,39 +233,33 @@ private static Binder GetEnclosingBinder(SyntaxNode node, int position, Binder r binder = rootBinder.GetBinder(current); } } - else if (current.Kind() == SyntaxKind.EqualsValueClause) + else if (kind == SyntaxKind.EqualsValueClause) { binder = rootBinder.GetBinder(current); } - else if (current.Kind() == SyntaxKind.Attribute) + else if (kind == SyntaxKind.Attribute) { binder = rootBinder.GetBinder(current); } - else if (current.Kind() == SyntaxKind.ArrowExpressionClause) + else if (kind == SyntaxKind.ArrowExpressionClause) { binder = rootBinder.GetBinder(current); } - else if (current is ExpressionSyntax && + else if (current is ExpressionSyntax && ((current.Parent as LambdaExpressionSyntax)?.Body == current || (current.Parent as SwitchStatementSyntax)?.Expression == current || (current.Parent as CommonForEachStatementSyntax)?.Expression == current)) { binder = rootBinder.GetBinder(current); } - else if (current is VariableComponentSyntax && - (current.Parent as ForEachComponentStatementSyntax)?.VariableComponent == current) + else if ((kind == SyntaxKind.DeclarationExpression || kind == SyntaxKind.TupleExpression) && + (current.Parent as ForEachVariableStatementSyntax)?.Variable == current) { binder = rootBinder.GetBinder(current.Parent); } - else if (current is VariableComponentSyntax && - (current.Parent is VariableComponentAssignmentSyntax) && - (current.Parent.Parent as ForStatementSyntax)?.Deconstruction == current) - { - binder = rootBinder.GetBinder(current.Parent.Parent); - } - else if (current is VariableComponentSyntax && - (current.Parent is VariableComponentAssignmentSyntax) && - (current.Parent.Parent as DeconstructionDeclarationStatementSyntax)?.Assignment.VariableComponent == current) + else if ((kind == SyntaxKind.DeclarationExpression || kind == SyntaxKind.TupleExpression) && + (current.Parent is AssignmentExpressionSyntax) && + (current.Parent.Parent as ForStatementSyntax)?.Initializers.Contains(current.Parent) == true) { binder = rootBinder.GetBinder(current.Parent.Parent); } @@ -323,7 +319,7 @@ private static Binder AdjustBinderForPositionWithinStatement(int position, Binde break; case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: var foreachStmt = (CommonForEachStatementSyntax)stmt; if (LookupPosition.IsBetweenTokens(position, foreachStmt.OpenParenToken, foreachStmt.Statement.GetFirstToken())) { @@ -1454,14 +1450,14 @@ private static Binder GetQueryEnclosingBinder(int position, CSharpSyntaxNode sta position, unbound.BindForErrorRecovery().Binder, unbound.Syntax); case BoundKind.Lambda: var lambda = (BoundLambda)n; - return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, lambda.Body.Syntax), + return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, lambda.Body.Syntax), position, lambda.Binder, lambda.Body.Syntax); default: goto done; } } -done: + done: return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, queryClause.Syntax), position, queryClause.Binder, queryClause.Syntax); } @@ -1642,6 +1638,18 @@ internal protected virtual CSharpSyntaxNode GetBindableSyntaxNode(CSharpSyntaxNo case SyntaxKind.AnonymousObjectMemberDeclarator: return GetBindableSyntaxNode(parent); + case SyntaxKind.DeclarationExpression: + case SyntaxKind.TupleExpression: + var assignment = GetContainingDeconstruction((ExpressionSyntax)node); + if (assignment != null) + { + return assignment; + } + else + { + goto default; + } + case SyntaxKind.VariableDeclarator: // declarators are mapped in SyntaxBinder // When a local variable declaration contains a single declarator, the bound node @@ -1678,6 +1686,34 @@ internal protected virtual CSharpSyntaxNode GetBindableSyntaxNode(CSharpSyntaxNo return node; } + /// + /// If this declaration is part of a deconstruction, find the deconstruction. + /// Returns null otherwise. + /// + private AssignmentExpressionSyntax GetContainingDeconstruction(ExpressionSyntax expr) + { + Debug.Assert(expr.Kind() == SyntaxKind.TupleExpression || expr.Kind() == SyntaxKind.DeclarationExpression); + + if (expr.Parent.Kind() == SyntaxKind.Argument) + { + if (expr.Parent.Parent.Kind() == SyntaxKind.TupleExpression) + { + return GetContainingDeconstruction((TupleExpressionSyntax)expr.Parent.Parent); + } + else + { + return null; + } + } + else if (expr.Parent.Kind() == SyntaxKind.SimpleAssignmentExpression && + (object)((AssignmentExpressionSyntax)expr.Parent).Left == expr) + { + return (AssignmentExpressionSyntax)expr.Parent; + } + + return null; + } + /// /// If the node is an expression, return the nearest parent node /// with semantic meaning. Otherwise return null. diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs index 9b4e6bcf0fad5..1ada036ea507a 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs @@ -171,7 +171,7 @@ private void CheckOutVarDeclaration(BoundLocal node) { if (IsInside && !node.WasCompilerGenerated && node.Syntax.Kind() == SyntaxKind.DeclarationExpression && - ((DeclarationExpressionSyntax)node.Syntax).Identifier() == node.LocalSymbol.IdentifierToken) + ((SingleVariableDesignationSyntax)((DeclarationExpressionSyntax)node.Syntax).Designation).Identifier == node.LocalSymbol.IdentifierToken) { _variablesDeclared.Add(node.LocalSymbol); } diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs index d8f934c91eba7..b67c1f92ea91c 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs @@ -137,7 +137,7 @@ public override BoundNode VisitTryStatement(BoundTryStatement node) tryStatementSyntax.IsKind(SyntaxKind.TryStatement) || tryStatementSyntax.IsKind(SyntaxKind.UsingStatement) || tryStatementSyntax.IsKind(SyntaxKind.ForEachStatement) || - tryStatementSyntax.IsKind(SyntaxKind.ForEachComponentStatement)); + tryStatementSyntax.IsKind(SyntaxKind.ForEachVariableStatement)); BoundStatement finalizedRegion; BoundBlock rewrittenFinally; diff --git a/src/Compilers/CSharp/Portable/Lowering/Instrumentation/DebugInfoInjector.cs b/src/Compilers/CSharp/Portable/Lowering/Instrumentation/DebugInfoInjector.cs index 575a70298dcd5..4264e847c7960 100644 --- a/src/Compilers/CSharp/Portable/Lowering/Instrumentation/DebugInfoInjector.cs +++ b/src/Compilers/CSharp/Portable/Lowering/Instrumentation/DebugInfoInjector.cs @@ -202,8 +202,8 @@ public override BoundStatement InstrumentForEachStatementCollectionVarDeclaratio public override BoundStatement InstrumentForEachStatementDeconstructionVariablesDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl) { - var forEachSyntax = (ForEachComponentStatementSyntax)original.Syntax; - return new BoundSequencePointWithSpan(forEachSyntax, base.InstrumentForEachStatementDeconstructionVariablesDeclaration(original, iterationVarDecl), forEachSyntax.VariableComponent.Span); + var forEachSyntax = (ForEachVariableStatementSyntax)original.Syntax; + return new BoundSequencePointWithSpan(forEachSyntax, base.InstrumentForEachStatementDeconstructionVariablesDeclaration(original, iterationVarDecl), forEachSyntax.Variable.Span); } public override BoundStatement InstrumentLocalDeconstructionDeclaration(BoundLocalDeconstructionDeclaration original, BoundStatement rewritten) @@ -247,10 +247,10 @@ public override BoundStatement InstrumentForEachStatementIterationVarDeclaration iterationVarDeclSpan = TextSpan.FromBounds(forEachSyntax.Type.SpanStart, forEachSyntax.Identifier.Span.End); break; } - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: { - var forEachSyntax = (ForEachComponentStatementSyntax)original.Syntax; - iterationVarDeclSpan = forEachSyntax.VariableComponent.Span; + var forEachSyntax = (ForEachVariableStatementSyntax)original.Syntax; + iterationVarDeclSpan = forEachSyntax.Variable.Span; break; } default: diff --git a/src/Compilers/CSharp/Portable/Lowering/Instrumentation/Instrumenter.cs b/src/Compilers/CSharp/Portable/Lowering/Instrumentation/Instrumenter.cs index bdac2d784cef9..1f067ec2f0c2f 100644 --- a/src/Compilers/CSharp/Portable/Lowering/Instrumentation/Instrumenter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/Instrumentation/Instrumenter.cs @@ -156,7 +156,7 @@ public virtual BoundStatement InstrumentForEachStatementIterationVarDeclaration( public virtual BoundStatement InstrumentForEachStatementDeconstructionVariablesDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl) { Debug.Assert(!original.WasCompilerGenerated); - Debug.Assert(original.Syntax.Kind() == SyntaxKind.ForEachComponentStatement); + Debug.Assert(original.Syntax.Kind() == SyntaxKind.ForEachVariableStatement); return iterationVarDecl; } diff --git a/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.cs index 3840746da3606..f26208021920a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter/LambdaRewriter.cs @@ -1579,7 +1579,7 @@ private static bool InLoopOrLambda(SyntaxNode lambdaSyntax, SyntaxNode scopeSynt { case SyntaxKind.ForStatement: case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: case SyntaxKind.WhileStatement: case SyntaxKind.DoStatement: case SyntaxKind.SimpleLambdaExpression: diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs index 69d7cc4f9a335..b54ecb30ac672 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs @@ -111,7 +111,7 @@ private static bool IsInTryBlock(BoundFixedStatement boundFixed) // } return true; case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: // We're being conservative here - there's actually only // a try block if the enumerator is disposable, but we // can't tell that from the syntax. Dev11 checks in the diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs index 3fa5b2acdbcac..39539524546b5 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs @@ -937,7 +937,7 @@ private void InstrumentForEachStatementIterationVarDeclaration(BoundForEachState if (this.Instrument) { CommonForEachStatementSyntax forEachSyntax = (CommonForEachStatementSyntax)original.Syntax; - if (forEachSyntax is ForEachComponentStatementSyntax) + if (forEachSyntax is ForEachVariableStatementSyntax) { iterationVarDecl = _instrumenter.InstrumentForEachStatementDeconstructionVariablesDeclaration(original, iterationVarDecl); } diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index cf52ff3729b29..51ace3a34fa98 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -7849,6 +7849,7 @@ private ForStatementSyntax ParseForStatement() AssignmentExpressionSyntax deconstruction = null; VariableDeclarationSyntax decl = null; bool isDeclaration = false; + bool isDeconstruction = false; if (this.CurrentToken.Kind == SyntaxKind.RefKeyword) { isDeclaration = true; @@ -7868,6 +7869,7 @@ private ForStatementSyntax ParseForStatement() else { initializers.Add(deconstruction); + isDeconstruction = true; } } @@ -7875,7 +7877,7 @@ private ForStatementSyntax ParseForStatement() { decl = ParseVariableDeclaration(); } - else if (this.CurrentToken.Kind != SyntaxKind.SemicolonToken) + else if (this.CurrentToken.Kind != SyntaxKind.SemicolonToken && !isDeconstruction) { // Not a type followed by an identifier, and not a deconstruction-declaration, so it must be an expression list. this.ParseForStatementExpressionList(ref openParen, initializers); @@ -8011,7 +8013,7 @@ private CommonForEachStatementSyntax ParseForEachStatement() return (deconstruction == null) ? (CommonForEachStatementSyntax)_syntaxFactory.ForEachStatement(@foreach, openParen, type, name, @in, expression, closeParen, statement) - : (CommonForEachStatementSyntax)_syntaxFactory.ForEachComponentStatement(@foreach, openParen, deconstruction, @in, expression, closeParen, statement); + : (CommonForEachStatementSyntax)_syntaxFactory.ForEachVariableStatement(@foreach, openParen, deconstruction, @in, expression, closeParen, statement); } private GotoStatementSyntax ParseGotoStatement() @@ -8408,18 +8410,17 @@ private LabeledStatementSyntax ParseLabeledStatement() /// private StatementSyntax ParseLocalDeclarationStatement() { - var mods = _pool.Allocate(); - this.ParseDeclarationModifiers(mods); - var deconstruction = TryParseDeconstructionDeclarationAssignment(); if (deconstruction != null) { var semicolon = this.EatToken(SyntaxKind.SemicolonToken); var result = _syntaxFactory.ExpressionStatement(deconstruction, semicolon); - _pool.Free(mods); return result; } + var mods = _pool.Allocate(); + this.ParseDeclarationModifiers(mods); + var variables = _pool.AllocateSeparated(); try { @@ -8618,7 +8619,9 @@ private ExpressionSyntax ParseDeconstructionDeclarationVariables(bool topLevel = topLevel ? (TypeFoundInDeconstructionDeclarationVariables(result) ? CheckFeatureAvailability(result, MessageID.IDS_FeatureTuples) : null) : result; } - // Check if we can find at least one type in the deconstruction variables + /// + /// Checks if we can find at least one type in the deconstruction variables + /// private static bool TypeFoundInDeconstructionDeclarationVariables(ExpressionSyntax node) { switch (node.Kind) diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index 0bb78f91c2a20..e3959c6129d36 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -47,16 +47,16 @@ Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.WithIdentifier(Mic Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.WithType(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken tildeToken, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax.WithExpressionBody(Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.VariableComponent.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithCloseParenToken(Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithForEachKeyword(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithInKeyword(Microsoft.CodeAnalysis.SyntaxToken inKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithOpenParenToken(Microsoft.CodeAnalysis.SyntaxToken openParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithStatement(Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.WithVariableComponent(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variable, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.Variable.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.WithCloseParenToken(Microsoft.CodeAnalysis.SyntaxToken closeParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.WithExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.WithForEachKeyword(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.WithInKeyword(Microsoft.CodeAnalysis.SyntaxToken inKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.WithOpenParenToken(Microsoft.CodeAnalysis.SyntaxToken openParenToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.WithStatement(Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.WithVariable(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variable) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax.Expression.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax.IsKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken @@ -157,7 +157,7 @@ Microsoft.CodeAnalysis.CSharp.SyntaxKind.CasePatternSwitchLabel = 9009 -> Micros Microsoft.CodeAnalysis.CSharp.SyntaxKind.ConstantPattern = 9002 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.DeclarationExpression = 9040 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.DeclarationPattern = 9000 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.ForEachComponentStatement = 8934 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.ForEachVariableStatement = 8934 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.IsPatternExpression = 8657 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.LocalFunctionStatement = 8830 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.ParenthesizedVariableDesignation = 8931 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind @@ -182,7 +182,7 @@ override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitCasePatternSwit override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitConstantPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitDeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitDeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode -override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode +override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitForEachVariableStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitIsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitParenthesizedVariableDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode @@ -207,20 +207,20 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax.Accept override Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax.ExpressionBody.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Expression.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.ForEachKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.InKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.OpenParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken -override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax.Statement.get -> Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax.Expression.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax.ForEachKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax.InKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax.OpenParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachStatementSyntax.Statement.get -> Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.Expression.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.ForEachKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.InKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.OpenParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken +override Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax.Statement.get -> Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax override Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void override Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> TResult override Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void @@ -269,8 +269,8 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microso static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken tildeToken, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken tildeToken, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachComponentStatement(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variableComponent, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachVariableStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variable, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax +static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ForEachVariableStatement(Microsoft.CodeAnalysis.SyntaxToken forEachKeyword, Microsoft.CodeAnalysis.SyntaxToken openParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax variable, Microsoft.CodeAnalysis.SyntaxToken inKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken closeParenToken, Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statement) -> Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.IsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.IsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, Microsoft.CodeAnalysis.SyntaxToken isKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.PatternSyntax pattern) -> Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax returnType, Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax @@ -298,7 +298,7 @@ virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitCasePatternSwitch virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitConstantPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax node) -> void -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax node) -> void +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitForEachVariableStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitIsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> void virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedVariableDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax node) -> void @@ -314,7 +314,7 @@ virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitCasePatt virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitConstantPattern(Microsoft.CodeAnalysis.CSharp.Syntax.ConstantPatternSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitDeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax node) -> TResult -virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitForEachComponentStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachComponentStatementSyntax node) -> TResult +virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitForEachVariableStatement(Microsoft.CodeAnalysis.CSharp.Syntax.ForEachVariableStatementSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitIsPatternExpression(Microsoft.CodeAnalysis.CSharp.Syntax.IsPatternExpressionSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalFunctionStatementSyntax node) -> TResult virtual Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.VisitParenthesizedVariableDesignation(Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedVariableDesignationSyntax node) -> TResult diff --git a/src/Compilers/CSharp/Portable/Symbols/LocalDeclarationKind.cs b/src/Compilers/CSharp/Portable/Symbols/LocalDeclarationKind.cs index 5af66795c5568..cbf56927c0b8a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/LocalDeclarationKind.cs +++ b/src/Compilers/CSharp/Portable/Symbols/LocalDeclarationKind.cs @@ -41,12 +41,7 @@ internal enum LocalDeclarationKind : byte CatchVariable, /// - /// User defined local variable declared by in . - /// - ForInitializerVariable, - - /// - /// User defined local variable declared by or . + /// User defined local variable declared by or . /// ForEachIterationVariable, diff --git a/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs index c387395859b17..843d695f58585 100644 --- a/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs @@ -227,17 +227,6 @@ public bool IsFixed } } - /// - /// Returns true if this local variable is declared in for-initializer - /// - public bool IsFor - { - get - { - return this.DeclarationKind == LocalDeclarationKind.ForInitializerVariable; - } - } - /// /// Returns true if this local variable is declared as iteration variable /// diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/GlobalExpressionVariable.cs b/src/Compilers/CSharp/Portable/Symbols/Source/GlobalExpressionVariable.cs index b7b4b67711a3d..87213c87acd21 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/GlobalExpressionVariable.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/GlobalExpressionVariable.cs @@ -40,9 +40,8 @@ internal class GlobalExpressionVariable : SourceMemberFieldSymbol FieldSymbol containingFieldOpt, SyntaxNode nodeToBind) { - Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator - || nodeToBind is ExpressionSyntax - || nodeToBind.Kind() == SyntaxKind.VariableComponentAssignment); + Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax); + var syntaxReference = syntax.GetReference(); return typeSyntax.IsVar ? new InferrableGlobalExpressionVariable(containingType, modifiers, typeSyntax, name, syntaxReference, location, containingFieldOpt, nodeToBind) @@ -155,9 +154,7 @@ private class InferrableGlobalExpressionVariable : GlobalExpressionVariable SyntaxNode nodeToBind) : base(containingType, modifiers, typeSyntax, name, syntax, location) { - Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator - || nodeToBind is ExpressionSyntax - || nodeToBind.Kind() == SyntaxKind.VariableComponentAssignment); + Debug.Assert(nodeToBind.Kind() == SyntaxKind.VariableDeclarator || nodeToBind is ExpressionSyntax); _containingFieldOpt = containingFieldOpt; _nodeToBind = nodeToBind.GetReference(); @@ -186,14 +183,6 @@ protected override void InferFieldType(ConsList fieldsBeingBound, B binder.BindDeclaratorArguments((VariableDeclaratorSyntax)nodeToBind, diagnostics); break; - case SyntaxKind.VariableComponentAssignment: - var deconstruction = (VariableComponentAssignmentSyntax)nodeToBind; - - binder.BindDeconstructionDeclaration(deconstruction, deconstruction.VariableComponent, - deconstruction.Value, diagnostics); - - break; - default: binder.BindExpression((ExpressionSyntax)nodeToBind, diagnostics); break; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs index 9a6d57b4ee1da..5205ef7142a26 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs @@ -154,7 +154,7 @@ internal new string GetDebuggerDisplay() Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || - nodeToBind.Kind() == SyntaxKind.VariableDeclarator && + nodeToBind.Kind() == SyntaxKind.VariableDeclarator && new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement, SyntaxKind.FixedStatement }. Contains(nodeToBind.Ancestors().OfType().First().Kind()) || nodeToBind is ExpressionSyntax); @@ -406,7 +406,6 @@ public override ImmutableArray DeclaringSyntaxReferences switch (_declarationKind) { case LocalDeclarationKind.RegularVariable: - case LocalDeclarationKind.ForInitializerVariable: Debug.Assert(node is VariableDeclaratorSyntax || node is SingleVariableDesignationSyntax); break; @@ -646,6 +645,8 @@ private class DeconstructionLocalSymbol : SourceLocalSymbol SyntaxNode deconstruction) : base(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, declarationKind) { + Debug.Assert(deconstruction.Kind() == SyntaxKind.SimpleAssignmentExpression || deconstruction.Kind() == SyntaxKind.ForEachVariableStatement); + _deconstruction = deconstruction; _nodeBinder = nodeBinder; } @@ -655,19 +656,14 @@ protected override TypeSymbol InferTypeOfVarVariable(DiagnosticBag diagnostics) // Try binding enclosing deconstruction-declaration (the top-level VariableDeclaration), this should force the inference. switch (_deconstruction.Kind()) { - case SyntaxKind.DeconstructionDeclarationStatement: - var localDecl = (DeconstructionDeclarationStatementSyntax)_deconstruction; - _nodeBinder.BindDeconstructionDeclaration(localDecl, localDecl.Assignment.VariableComponent, localDecl.Assignment.Value, diagnostics); - break; - - case SyntaxKind.ForStatement: - var forStatement = (ForStatementSyntax)_deconstruction; - Debug.Assert(this.ScopeBinder.GetBinder(forStatement) == _nodeBinder); - _nodeBinder.BindDeconstructionDeclaration(forStatement, forStatement.Deconstruction.VariableComponent, forStatement.Deconstruction.Value, diagnostics); + case SyntaxKind.SimpleAssignmentExpression: + var assignment = (AssignmentExpressionSyntax)_deconstruction; + Debug.Assert(assignment.IsDeconstructionDeclaration()); + _nodeBinder.BindDeconstructionDeclaration(assignment, assignment.Left, assignment.Right, diagnostics); break; - case SyntaxKind.ForEachComponentStatement: - Debug.Assert(this.ScopeBinder.GetBinder((ForEachComponentStatementSyntax)_deconstruction) == _nodeBinder); + case SyntaxKind.ForEachVariableStatement: + Debug.Assert(this.ScopeBinder.GetBinder((ForEachVariableStatementSyntax)_deconstruction) == _nodeBinder); _nodeBinder.BindForEachDeconstruction(diagnostics, _nodeBinder); break; @@ -686,15 +682,10 @@ internal override SyntaxNode ForbiddenZone { switch (_deconstruction.Kind()) { - case SyntaxKind.DeconstructionDeclarationStatement: - var localDecl = (DeconstructionDeclarationStatementSyntax)_deconstruction; - return localDecl.Assignment.Value; - - case SyntaxKind.ForStatement: - var forStatement = (ForStatementSyntax)_deconstruction; - return forStatement.Deconstruction; + case SyntaxKind.SimpleAssignmentExpression: + return ((AssignmentExpressionSyntax)_deconstruction).Right; - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: // There is no forbidden zone for a foreach statement, because the // variables are not in scope in the expression. return null; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index fa4cf44a5235b..27efd725e9dcb 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -3145,20 +3145,6 @@ private static bool HasNonConstantInitializer(ArrayBuilder builder, VariableComponentSyntax variableComponent, - VariableComponentAssignmentSyntax assignment) - { - switch (variableComponent.Kind()) - { - case SyntaxKind.TypedVariableComponent: - var typed = (TypedVariableComponentSyntax)variableComponent; - CollectFieldsFromGlobalDeconstruction( - builder, - typed.Designation, - typed.Type, - assignment); - break; - - case SyntaxKind.ParenthesizedVariableComponent: - foreach (VariableComponentSyntax variable in ((ParenthesizedVariableComponentSyntax)variableComponent).Variables) - { - CollectFieldsFromGlobalDeconstruction(builder, variable, assignment); - } - break; - - default: - throw ExceptionUtilities.UnexpectedValue(variableComponent.Kind()); - } - } - - private void CollectFieldsFromGlobalDeconstruction(ArrayBuilder builder, VariableDesignationSyntax designation, - TypeSyntax type, VariableComponentAssignmentSyntax assignment) - { - switch (designation.Kind()) - { - case SyntaxKind.SingleVariableDesignation: - var single = (SingleVariableDesignationSyntax)designation; - var field = GlobalExpressionVariable.Create( - containingType: this, - modifiers: DeclarationModifiers.Private, - typeSyntax: type, - name: single.Identifier.ValueText, - syntax: designation, - location: designation.Location, - containingFieldOpt: null, - nodeToBind: assignment); - builder.Add(field); - break; - - case SyntaxKind.ParenthesizedVariableDesignation: - foreach (VariableDesignationSyntax variable in ((ParenthesizedVariableDesignationSyntax)designation).Variables) - { - CollectFieldsFromGlobalDeconstruction(builder, variable, type, assignment); - } - break; - - default: - throw ExceptionUtilities.UnexpectedValue(designation.Kind()); - } - } - private static bool IsGlobalCodeAllowed(CSharpSyntaxNode parent) { var parentKind = parent.Kind(); diff --git a/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs b/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs index 5aea240209e51..b3c5a4171d0cb 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LambdaUtilities.cs @@ -367,7 +367,7 @@ internal static bool IsClosureScope(SyntaxNode node) case SyntaxKind.CatchClause: case SyntaxKind.ForStatement: case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: case SyntaxKind.UsingStatement: // ctor parameter captured by a lambda in a ctor initializer diff --git a/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs b/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs index 1e280c3059854..5fe4fd5928053 100644 --- a/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs +++ b/src/Compilers/CSharp/Portable/Syntax/LookupPosition.cs @@ -283,7 +283,6 @@ private static SyntaxToken GetFirstIncludedToken(StatementSyntax statement) return ((ContinueStatementSyntax)statement).ContinueKeyword; case SyntaxKind.ExpressionStatement: case SyntaxKind.LocalDeclarationStatement: - case SyntaxKind.DeconstructionDeclarationStatement: return statement.GetFirstToken(); case SyntaxKind.DoStatement: return ((DoStatementSyntax)statement).DoKeyword; @@ -292,7 +291,7 @@ private static SyntaxToken GetFirstIncludedToken(StatementSyntax statement) case SyntaxKind.FixedStatement: return ((FixedStatementSyntax)statement).FixedKeyword; case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: return ((CommonForEachStatementSyntax)statement).OpenParenToken.GetNextToken(); case SyntaxKind.ForStatement: return ((ForStatementSyntax)statement).OpenParenToken.GetNextToken(); @@ -346,8 +345,6 @@ private static SyntaxToken GetFirstExcludedToken(StatementSyntax statement) return ((ContinueStatementSyntax)statement).SemicolonToken; case SyntaxKind.LocalDeclarationStatement: return ((LocalDeclarationStatementSyntax)statement).SemicolonToken; - case SyntaxKind.DeconstructionDeclarationStatement: - return ((DeconstructionDeclarationStatementSyntax)statement).SemicolonToken; case SyntaxKind.DoStatement: return ((DoStatementSyntax)statement).SemicolonToken; case SyntaxKind.EmptyStatement: @@ -357,7 +354,7 @@ private static SyntaxToken GetFirstExcludedToken(StatementSyntax statement) case SyntaxKind.FixedStatement: return GetFirstExcludedToken(((FixedStatementSyntax)statement).Statement); case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: return GetFirstExcludedToken(((CommonForEachStatementSyntax)statement).Statement); case SyntaxKind.ForStatement: return GetFirstExcludedToken(((ForStatementSyntax)statement).Statement); diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index 1539dbba065b3..9a7ccaf2a99c1 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -1134,11 +1134,11 @@ - Declaration representing the variable declared in an out parameter. + Declaration representing the variable declared in an out parameter or deconstruction. - Class which represents the syntax node for the variable declaration in an out var declaration. + Class which represents the syntax node for the variable declaration in an out var declaration or a deconstruction declaration. Creates a DeclarationExpression node. @@ -1860,14 +1860,6 @@ - @@ -2110,15 +2102,15 @@ - - + + - + diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs index b4ff5999a73f6..dc9d9761078e9 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs @@ -67,32 +67,12 @@ public static SyntaxToken NormalizeWhitespace(this SyntaxToken token, string ind return SyntaxNormalizer.Normalize(token, indentation, Microsoft.CodeAnalysis.SyntaxNodeExtensions.DefaultEOL, elasticTrivia); } - /// - /// Return the type syntax of an out declaration argument expression. - /// - internal static TypeSyntax Type(this DeclarationExpressionSyntax self) - { - var component = (TypedVariableComponentSyntax)self.VariableComponent; - return component.Type; - } - - /// - /// Return the variable designation of an out declaration argument expression. - /// - internal static SingleVariableDesignationSyntax VariableDesignation(this DeclarationExpressionSyntax self) - { - var component = (TypedVariableComponentSyntax)self.VariableComponent; - return (SingleVariableDesignationSyntax)component.Designation; - } - /// /// Return the identifier of an out declaration argument expression. /// internal static SyntaxToken Identifier(this DeclarationExpressionSyntax self) { - var component = (TypedVariableComponentSyntax)self.VariableComponent; - var designation = (SingleVariableDesignationSyntax)component.Designation; - return designation.Identifier; + return ((SingleVariableDesignationSyntax)self.Designation).Identifier; } /// @@ -226,6 +206,25 @@ internal static SyntaxNode SkipParens(this SyntaxNode expression) return expression; } + private static bool IsDeconstructionDeclaration(this ExpressionSyntax self) + { + switch (self.Kind()) + { + case SyntaxKind.DeclarationExpression: + return true; + case SyntaxKind.TupleExpression: + var tuple = (TupleExpressionSyntax)self; + return tuple.Arguments.All(a => IsDeconstructionDeclaration(a.Expression)); + default: + return false; + } + } + + internal static bool IsDeconstructionDeclaration(this AssignmentExpressionSyntax self) + { + return self.Left.IsDeconstructionDeclaration(); + } + private static bool IsInContextWhichNeedsDynamicAttribute(CSharpSyntaxNode node) { Debug.Assert(node != null); diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs index 8d7840a0cde0e..ab293071094ee 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs @@ -193,8 +193,8 @@ public static bool IsInTypeOnlyContext(ExpressionSyntax node) case TupleElement: return ((TupleElementSyntax)parent).Type == node; - case TypedVariableComponent: - return ((TypedVariableComponentSyntax)parent).Type == node; + case DeclarationExpression: + return ((DeclarationExpressionSyntax)parent).Type == node; case IncompleteMember: return ((IncompleteMemberSyntax)parent).Type == node; @@ -399,10 +399,10 @@ internal static bool IsVarOrPredefinedType(this Syntax.InternalSyntax.SyntaxToke return node.IsVar() || IsPredefinedType(node.Kind); } - internal static bool IsVariableComponentType(SyntaxNode node, out SyntaxNode parent) + internal static bool IsDeclarationExpressionType(SyntaxNode node, out DeclarationExpressionSyntax parent) { - var component = node.Parent as TypedVariableComponentSyntax; - parent = component; + var component = node.Parent as DeclarationExpressionSyntax; + parent = component as DeclarationExpressionSyntax; return node == component?.Type; } } diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs index ba8abb57cf2a9..217dc04c617d0 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs @@ -544,7 +544,7 @@ public enum SyntaxKind : ushort TupleExpression = 8927, SingleVariableDesignation = 8930, ParenthesizedVariableDesignation = 8931, - ForEachComponentStatement = 8934, + ForEachVariableStatement = 8934, // patterns (for pattern-matching) DeclarationPattern = 9000, diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs index 5b56ce1d33237..274eebdfd4d75 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs @@ -82,7 +82,19 @@ public void Deconstruct(out int a, out string b) } "; - var comp = CompileAndVerify(source, expectedOutput: "1 hello", additionalRefs: s_valueTupleRefs); + Action validator = (ModuleSymbol module) => + { + var sourceModule = (SourceModuleSymbol)module; + var compilation = sourceModule.DeclaringCompilation; + var tree = compilation.SyntaxTrees.First(); + var model = compilation.GetSemanticModel(tree); + + var lhs = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal(@"(x, y)", lhs.ToString()); + Assert.Equal("(System.Int64, System.String)", model.GetTypeInfo(lhs).Type.ToTestDisplayString()); + }; + + var comp = CompileAndVerify(source, expectedOutput: "1 hello", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); comp.VerifyIL("C.Main", @" { @@ -1118,6 +1130,93 @@ .maxstack 3 }"); } + [Fact] + public void DeconstructionDeclarationCanOnlyBeParsedAsStatement() + { + string source = @" +class C +{ + public static void Main() + { + var z = ((var x, int y) = new C()); + } + + public void Deconstruct(out int a, out int b) + { + a = 1; + b = 2; + } +} +"; + + var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }); + comp.VerifyDiagnostics( + // (6,33): error CS1003: Syntax error, '=>' expected + // var z = ((var x, int y) = new C()); + Diagnostic(ErrorCode.ERR_SyntaxError, "=").WithArguments("=>", "=").WithLocation(6, 33), + // (6,33): error CS1525: Invalid expression term '=' + // var z = ((var x, int y) = new C()); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(6, 33), + // (6,19): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // var z = ((var x, int y) = new C()); + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(6, 19) + ); + } + + [Fact] + public void DeconstructionWithTupleNamesCannotBeParsed() + { + string source = @" +class C +{ + public static void Main() + { + (Alice: var x, Bob: int y) = (1, 2); + } +} +"; + + var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }); + comp.VerifyDiagnostics( + // (6,9): error CS8124: Tuple must contain at least two elements. + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_TupleTooFewElements, "(Alice: var ").WithLocation(6, 9), + // (6,21): error CS1026: ) expected + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_CloseParenExpected, "x").WithLocation(6, 21), + // (6,21): error CS1002: ; expected + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_SemicolonExpected, "x").WithLocation(6, 21), + // (6,22): error CS1002: ; expected + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_SemicolonExpected, ",").WithLocation(6, 22), + // (6,22): error CS1513: } expected + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_RbraceExpected, ",").WithLocation(6, 22), + // (6,34): error CS1002: ; expected + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_SemicolonExpected, ")").WithLocation(6, 34), + // (6,34): error CS1513: } expected + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(6, 34), + // (6,36): error CS1525: Invalid expression term '=' + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(6, 36), + // (6,17): error CS0103: The name 'var' does not exist in the current context + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_NameNotInContext, "var").WithArguments("var").WithLocation(6, 17), + // (6,21): error CS0103: The name 'x' does not exist in the current context + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(6, 21), + // (6,24): warning CS0164: This label has not been referenced + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.WRN_UnreferencedLabel, "Bob").WithLocation(6, 24), + // (6,33): warning CS0168: The variable 'y' is declared but never used + // (Alice: var x, Bob: int y) = (1, 2); + Diagnostic(ErrorCode.WRN_UnreferencedVar, "y").WithArguments("y").WithLocation(6, 33) + ); + } + [Fact] public void ValueTupleReturnIsEmittedIfUsedInLambda() { @@ -1278,7 +1377,7 @@ static void Main() } "; - var comp = CompileAndVerify(source, expectedOutput: "(1, 1) 2", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular.WithRefsFeature()); + var comp = CompileAndVerify(source, expectedOutput: "(1, 1) 2", additionalRefs: s_valueTupleRefs, parseOptions: TestOptions.Regular.WithRefsFeature()); comp.VerifyDiagnostics(); } @@ -1304,7 +1403,7 @@ static void Main() } "; - var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular.WithRefsFeature()); + var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: s_valueTupleRefs, parseOptions: TestOptions.Regular.WithRefsFeature()); comp.VerifyDiagnostics(); } @@ -1326,7 +1425,7 @@ static void Main() } "; - var comp = CompileAndVerify(source, expectedOutput: "1 hello world", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular.WithRefsFeature()); + var comp = CompileAndVerify(source, expectedOutput: "1 hello world", additionalRefs: s_valueTupleRefs, parseOptions: TestOptions.Regular.WithRefsFeature()); comp.VerifyDiagnostics(); } @@ -1348,7 +1447,7 @@ static void Main() } "; - var comp = CompileAndVerify(source, expectedOutput: "1 hello world", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular.WithRefsFeature()); + var comp = CompileAndVerify(source, expectedOutput: "1 hello world", additionalRefs: s_valueTupleRefs, parseOptions: TestOptions.Regular.WithRefsFeature()); comp.VerifyDiagnostics(); } @@ -1372,7 +1471,7 @@ static void Main() } "; - var comp = CompileAndVerify(source, expectedOutput: "override", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular.WithRefsFeature()); + var comp = CompileAndVerify(source, expectedOutput: "override", additionalRefs: s_valueTupleRefs, parseOptions: TestOptions.Regular.WithRefsFeature()); comp.VerifyDiagnostics(); } @@ -1400,7 +1499,7 @@ static void Main() var expected = String.Join(" ", Enumerable.Range(1, i).Select(n => n)); var source = template.Replace("VARIABLES", variables).Replace("TUPLE", tuple).Replace("OUTPUT", output); - var comp = CompileAndVerify(source, expectedOutput: expected, additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular.WithRefsFeature()); + var comp = CompileAndVerify(source, expectedOutput: expected, additionalRefs: s_valueTupleRefs, parseOptions: TestOptions.Regular.WithRefsFeature()); comp.VerifyDiagnostics(); } } @@ -1616,7 +1715,19 @@ static void Main() } } "; - var comp = CompileAndVerify(source, expectedOutput: "1 a b", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }); + Action validator = (ModuleSymbol module) => + { + var sourceModule = (SourceModuleSymbol)module; + var compilation = sourceModule.DeclaringCompilation; + var tree = compilation.SyntaxTrees.First(); + var model = compilation.GetSemanticModel(tree); + + var lhs = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal(@"(x, (y, z))", lhs.ToString()); + Assert.Equal("(System.Int32, (System.String, System.String))", model.GetTypeInfo(lhs).Type.ToTestDisplayString()); + }; + + var comp = CompileAndVerify(source, expectedOutput: "1 a b", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -1917,7 +2028,7 @@ static void Main() } "; - var comp = CompileAndVerify(source, additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, expectedOutput: "1 hello"); + var comp = CompileAndVerify(source, additionalRefs: s_valueTupleRefs, expectedOutput: "1 hello"); comp.VerifyDiagnostics(); comp.VerifyIL("C.Main", @" { @@ -1968,6 +2079,10 @@ static void Main() var tree = compilation.SyntaxTrees.First(); var model = compilation.GetSemanticModel(tree); + var lhs = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal(@"var (x1, (x2, x3))", lhs.ToString()); + Assert.Null(model.GetTypeInfo(lhs).Type); + var x1 = GetDeconstructionVariable(tree, "x1"); var x1Ref = GetReference(tree, "x1"); VerifyModelForDeconstructionLocal(model, x1, x1Ref); @@ -1981,7 +2096,7 @@ static void Main() VerifyModelForDeconstructionLocal(model, x3, x3Ref); }; - var comp = CompileAndVerify(source, expectedOutput: "1 2 hello", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2 hello", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2019,7 +2134,7 @@ static void Main() VerifyModelForDeconstructionLocal(model, x3, x3Ref); }; - var comp = CompileAndVerify(source, expectedOutput: "1 2 hello", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2 hello", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2081,14 +2196,18 @@ static void Main() var tree = compilation.SyntaxTrees.First(); var model = compilation.GetSemanticModel(tree); - var literal = tree.GetRoot().DescendantNodes().OfType().Single(); + var lhs = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal(@"(string x1, byte x2, var x3)", lhs.ToString()); + Assert.Equal("System.Void", model.GetTypeInfo(lhs).Type.ToTestDisplayString()); + + var literal = tree.GetRoot().DescendantNodes().OfType().Skip(1).First(); Assert.Equal(@"(null, 2, 3)", literal.ToString()); Assert.Null(model.GetTypeInfo(literal).Type); Assert.Equal("(System.String, System.Byte, System.Int32)", model.GetTypeInfo(literal).ConvertedType.ToTestDisplayString()); Assert.Equal(ConversionKind.ImplicitTupleLiteral, model.GetConversion(literal).Kind); }; - var comp = CompileAndVerify(source, expectedOutput: " 2 3", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: " 2 3", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2113,7 +2232,11 @@ static void Main() var tree = compilation.SyntaxTrees.First(); var model = compilation.GetSemanticModel(tree); - var literal = tree.GetRoot().DescendantNodes().OfType().First(); + var lhs = tree.GetRoot().DescendantNodes().OfType().First(); + Assert.Equal(@"(string x1, var x2)", lhs.ToString()); + Assert.Equal("System.Void", model.GetTypeInfo(lhs).Type.ToTestDisplayString()); + + var literal = tree.GetRoot().DescendantNodes().OfType().Skip(1).First(); Assert.Equal(@"(null, (1, 2))", literal.ToString()); Assert.Null(model.GetTypeInfo(literal).Type); Assert.Equal("(System.String, (System.Int32, System.Int32))", model.GetTypeInfo(literal).ConvertedType.ToTestDisplayString()); @@ -2125,7 +2248,7 @@ static void Main() Assert.Equal("(System.Int32, System.Int32)", model.GetTypeInfo(nestedLiteral).ConvertedType.ToTestDisplayString()); }; - var comp = CompileAndVerify(source, expectedOutput: " (1, 2)", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: " (1, 2)", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2195,11 +2318,6 @@ private static void VerifyModelForDeconstructionLocal(SemanticModel model, Singl VerifyModelForDeconstruction(model, decl, LocalDeclarationKind.RegularVariable, references); } - private static void VerifyModelForDeconstructionFor(SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references) - { - VerifyModelForDeconstruction(model, decl, LocalDeclarationKind.ForInitializerVariable, references); - } - private static void VerifyModelForDeconstructionForeach(SemanticModel model, SingleVariableDesignationSyntax decl, params IdentifierNameSyntax[] references) { VerifyModelForDeconstruction(model, decl, LocalDeclarationKind.ForEachIterationVariable, references); @@ -2258,7 +2376,7 @@ private static void VerifyModelForDeconstructionField(SemanticModel model, Singl private static TypeSyntax GetTypeSyntax(SingleVariableDesignationSyntax decl) { - return (decl.Parent as TypedVariableComponentSyntax)?.Type; + return (decl.Parent as DeclarationExpressionSyntax)?.Type; } private static SingleVariableDesignationSyntax GetDeconstructionVariable(SyntaxTree tree, string name) @@ -2327,7 +2445,7 @@ class var Assert.Equal("int", model.GetSymbolInfo(x2Type).Symbol.ToDisplayString()); }; - var comp = CompileAndVerify(source, expectedOutput: "var 2", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "var 2", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2375,12 +2493,12 @@ static void Main() Assert.Equal("int", model.GetSymbolInfo(x1Type).Symbol.ToDisplayString()); Assert.Null(model.GetAliasInfo(x1Type)); - var x34Var = (TypedVariableComponentSyntax)x3.Parent.Parent; + var x34Var = (DeclarationExpressionSyntax)x3.Parent.Parent; Assert.Equal("var", x34Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x34Var.Type).Symbol); // The var in `var (x3, x4)` has no symbol }; - var comp = CompileAndVerify(source, expectedOutput: "1 2 3 4", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2 3 4", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2433,7 +2551,7 @@ class D Assert.Null(model.GetAliasInfo(x2Type)); }; - var comp = CompileAndVerify(source, expectedOutput: "var 2", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "var 2", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2462,22 +2580,60 @@ static void Main() var x1 = GetDeconstructionVariable(tree, "x1"); var x1Ref = GetReferences(tree, "x1", 4); - VerifyModelForDeconstructionFor(model, x1, x1Ref); + VerifyModelForDeconstructionLocal(model, x1, x1Ref); var x2 = GetDeconstructionVariable(tree, "x2"); var x2Ref = GetReferences(tree, "x2", 3); - VerifyModelForDeconstructionFor(model, x2, x2Ref); + VerifyModelForDeconstructionLocal(model, x2, x2Ref); // extra check on var - var x12Var = (TypedVariableComponentSyntax)x1.Parent.Parent; + var x12Var = (DeclarationExpressionSyntax)x1.Parent.Parent; Assert.Equal("var", x12Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x12Var.Type).Symbol); // The var in `var (x1, x2)` has no symbol }; - var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } + [Fact] + public void ForWithBadInitializersCannotParse() + { + string source = @" +class C +{ + static void Main() + { + for (var (x1, x2) = (1, 2), x1 = 0; ; ) + { + } + } +} +"; + + var comp = CreateCompilationWithMscorlib(source, references: s_valueTupleRefs); + comp.VerifyDiagnostics( + // (6,35): error CS1002: ; expected + // for (var (x1, x2) = (1, 2), x1 = 0; ; ) + Diagnostic(ErrorCode.ERR_SemicolonExpected, ",").WithLocation(6, 35), + // (6,35): error CS1525: Invalid expression term ',' + // for (var (x1, x2) = (1, 2), x1 = 0; ; ) + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ",").WithArguments(",").WithLocation(6, 35), + // (6,35): error CS1002: ; expected + // for (var (x1, x2) = (1, 2), x1 = 0; ; ) + Diagnostic(ErrorCode.ERR_SemicolonExpected, ",").WithLocation(6, 35), + // (6,35): error CS1525: Invalid expression term ',' + // for (var (x1, x2) = (1, 2), x1 = 0; ; ) + Diagnostic(ErrorCode.ERR_InvalidExprTerm, ",").WithArguments(",").WithLocation(6, 35), + // (6,43): error CS1026: ) expected + // for (var (x1, x2) = (1, 2), x1 = 0; ; ) + Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(6, 43), + // (6,47): error CS1513: } expected + // for (var (x1, x2) = (1, 2), x1 = 0; ; ) + Diagnostic(ErrorCode.ERR_RbraceExpected, ")").WithLocation(6, 47) + ); + } + [Fact] public void ForWithActualVarType() { @@ -2507,11 +2663,11 @@ class var var x1 = GetDeconstructionVariable(tree, "x1"); var x1Ref = GetReferences(tree, "x1", 3); - VerifyModelForDeconstructionFor(model, x1, x1Ref); + VerifyModelForDeconstructionLocal(model, x1, x1Ref); var x2 = GetDeconstructionVariable(tree, "x2"); var x2Ref = GetReference(tree, "x2"); - VerifyModelForDeconstructionFor(model, x2, x2Ref); + VerifyModelForDeconstructionLocal(model, x2, x2Ref); // extra checks on x1 var x1Type = GetTypeSyntax(x1); @@ -2524,7 +2680,7 @@ class var Assert.Equal("var", model.GetSymbolInfo(x2Type).Symbol.ToDisplayString()); }; - var comp = CompileAndVerify(source, expectedOutput: "1 var", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 var", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2553,11 +2709,11 @@ static void Main() var x1 = GetDeconstructionVariable(tree, "x1"); var x1Ref = GetReferences(tree, "x1", 3); - VerifyModelForDeconstructionFor(model, x1, x1Ref); + VerifyModelForDeconstructionLocal(model, x1, x1Ref); var x2 = GetDeconstructionVariable(tree, "x2"); var x2Ref = GetReference(tree, "x2"); - VerifyModelForDeconstructionFor(model, x2, x2Ref); + VerifyModelForDeconstructionLocal(model, x2, x2Ref); // extra checks on x1 var x1Type = GetTypeSyntax(x1); @@ -2570,7 +2726,7 @@ static void Main() Assert.Equal("int", model.GetSymbolInfo(x2Type).Symbol.ToDisplayString()); }; - var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -2609,12 +2765,12 @@ static void Main() VerifyModelForDeconstructionForeach(model, x2, x2Ref); // extra check on var - var x12Var = (TypedVariableComponentSyntax)x1.Parent.Parent; + var x12Var = (DeclarationExpressionSyntax)x1.Parent.Parent; Assert.Equal("var", x12Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x12Var.Type).Symbol); // The var in `var (x1, x2)` has no symbol }; - var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); comp.VerifyIL("C.Main", @@ -2698,12 +2854,12 @@ static void Main() VerifyModelForDeconstructionForeach(model, x2, x2Ref); // extra check on var - var x12Var = (TypedVariableComponentSyntax)x1.Parent.Parent; + var x12Var = (DeclarationExpressionSyntax)x1.Parent.Parent; Assert.Equal("var", x12Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x12Var.Type).Symbol); // The var in `var (x1, x2)` has no symbol }; - var comp = CompileAndVerify(source, expectedOutput: "1 2 - 3 4 -", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2 - 3 4 -", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); comp.VerifyIL("C.Main", @"{ @@ -2798,12 +2954,12 @@ static void Main() VerifyModelForDeconstructionForeach(model, x2, x2Ref); // extra check on var - var x12Var = (TypedVariableComponentSyntax)x1.Parent.Parent; + var x12Var = (DeclarationExpressionSyntax)x1.Parent.Parent; Assert.Equal("var", x12Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x12Var.Type).Symbol); // The var in `var (x1, x2)` has no symbol }; - var comp = CompileAndVerify(source, expectedOutput: "1 2 - 3 4 - 5 6 - 7 8 -", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2 - 3 4 - 5 6 - 7 8 -", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); comp.VerifyIL("C.Main", @"{ @@ -2912,7 +3068,7 @@ public static void Deconstruct(this char value, out int item1, out int item2) VerifyModelForDeconstructionForeach(model, x2, x2Ref); // extra check on var - var x12Var = (TypedVariableComponentSyntax)x1.Parent.Parent; + var x12Var = (DeclarationExpressionSyntax)x1.Parent.Parent; Assert.Equal("var", x12Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x12Var.Type).Symbol); // The var in `var (x1, x2)` has no symbol }; @@ -3007,12 +3163,12 @@ static void Main() VerifyModelForDeconstructionForeach(model, x5, x5Ref); // extra check on var - var x23Var = (TypedVariableComponentSyntax)x2.Parent.Parent; + var x23Var = (DeclarationExpressionSyntax)x2.Parent.Parent; Assert.Equal("var", x23Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x23Var.Type).Symbol); // The var in `var (x2, x3)` has no symbol }; - var comp = CompileAndVerify(source, expectedOutput: "1 2 3 4 5 - 6 7 8 9 10 -", additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: "1 2 3 4 5 - 6 7 8 9 10 -", additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); } @@ -3126,7 +3282,7 @@ static void Main() VerifyModelForDeconstructionForeach(model, x3, x3Ref); // extra check on var - var x23Var = (TypedVariableComponentSyntax)x2.Parent.Parent; + var x23Var = (DeclarationExpressionSyntax)x2.Parent.Parent; Assert.Equal("var", x23Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x23Var.Type).Symbol); // The var in `var (x2, x3)` has no symbol }; @@ -3139,7 +3295,7 @@ static void Main() Deconstructing (5, 6) 4 5 6"; - var comp = CompileAndVerify(source, expectedOutput: expected, additionalRefs: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, sourceSymbolValidator: validator); + var comp = CompileAndVerify(source, expectedOutput: expected, additionalRefs: s_valueTupleRefs, sourceSymbolValidator: validator); comp.VerifyDiagnostics(); comp.VerifyIL("C.Main", @@ -3528,7 +3684,7 @@ class C ); var nodes = comp.SyntaxTrees[0].GetCompilationUnitRoot().DescendantNodesAndSelf(); - Assert.False(nodes.Any(n => n.Kind() == SyntaxKind.DeconstructionDeclarationStatement)); + Assert.False(nodes.Any(n => n.Kind() == SyntaxKind.SimpleAssignmentExpression)); } [Fact] @@ -3671,7 +3827,7 @@ public void NoGlobalDeconstructionOutsideScript() ); var nodes = comp.SyntaxTrees[0].GetCompilationUnitRoot().DescendantNodesAndSelf(); - Assert.False(nodes.Any(n => n.Kind() == SyntaxKind.DeconstructionDeclarationStatement)); + Assert.False(nodes.Any(n => n.Kind() == SyntaxKind.SimpleAssignmentExpression)); } [Fact] @@ -3737,7 +3893,7 @@ public void NestedVarDeconstructionInScript() Assert.Null(model.GetAliasInfo(x1Type)); // extra check on x2 and x3's var - var x23Var = (TypedVariableComponentSyntax)x2.Parent.Parent; + var x23Var = (DeclarationExpressionSyntax)x2.Parent.Parent; Assert.Equal("var", x23Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x23Var.Type).Symbol); // The var in `var (x2, x3)` has no symbol }; @@ -4261,7 +4417,7 @@ public void VarAliasInVarDeconstructionInScript() VerifyModelForDeconstructionField(model, x3, x3Ref); // extra check on var - var x123Var = (TypedVariableComponentSyntax)x1.Parent.Parent; + var x123Var = (DeclarationExpressionSyntax)x1.Parent.Parent; Assert.Equal("var", x123Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x123Var.Type).Symbol); // The var in `var (x1, x2)` has no symbol } @@ -4308,7 +4464,7 @@ class var VerifyModelForDeconstructionField(model, x3, x3Ref); // extra check on var - var x123Var = (TypedVariableComponentSyntax)x1.Parent.Parent; + var x123Var = (DeclarationExpressionSyntax)x1.Parent.Parent; Assert.Equal("var", x123Var.Type.ToString()); Assert.Null(model.GetSymbolInfo(x123Var.Type).Symbol); // The var in `var (x1, x2)` has no symbol } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs index c44bcdaa3c17f..9becaeed18bed 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs @@ -18676,16 +18676,16 @@ public void PrintCoordinates() comp.VerifyEmitDiagnostics( // (25,9): error CS8128: Member 'Item1' was not found on type 'ValueTuple' from assembly 'comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. // (int x1, int y1) = GetCoordinates(); - Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x1, int y1) = GetCoordinates();").WithArguments("Item1", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(25, 9), + Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x1, int y1) = GetCoordinates()").WithArguments("Item1", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(25, 9), // (25,9): error CS8128: Member 'Item2' was not found on type 'ValueTuple' from assembly 'comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. // (int x1, int y1) = GetCoordinates(); - Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x1, int y1) = GetCoordinates();").WithArguments("Item2", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(25, 9), + Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x1, int y1) = GetCoordinates()").WithArguments("Item2", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(25, 9), // (26,9): error CS8128: Member 'Item1' was not found on type 'ValueTuple' from assembly 'comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. // (int x2, int y2) = GetCoordinates2(); - Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x2, int y2) = GetCoordinates2();").WithArguments("Item1", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(26, 9), + Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x2, int y2) = GetCoordinates2()").WithArguments("Item1", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(26, 9), // (26,9): error CS8128: Member 'Item2' was not found on type 'ValueTuple' from assembly 'comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. // (int x2, int y2) = GetCoordinates2(); - Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x2, int y2) = GetCoordinates2();").WithArguments("Item2", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(26, 9) + Diagnostic(ErrorCode.ERR_PredefinedTypeMemberNotFoundInAssembly, "(int x2, int y2) = GetCoordinates2()").WithArguments("Item2", "System.ValueTuple", "comp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(26, 9) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs index 8f621e06245b9..c3fec6d3eebae 100644 --- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs +++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs @@ -28,13 +28,9 @@ public void DiagnosticAnalyzerAllInOne() var syntaxKindsMissing = new HashSet(); // AllInOneCSharpCode has no deconstruction or declaration expression - syntaxKindsMissing.Add(SyntaxKind.TypedVariableComponent); - syntaxKindsMissing.Add(SyntaxKind.ParenthesizedVariableComponent); syntaxKindsMissing.Add(SyntaxKind.SingleVariableDesignation); syntaxKindsMissing.Add(SyntaxKind.ParenthesizedVariableDesignation); - syntaxKindsMissing.Add(SyntaxKind.DeconstructionDeclarationStatement); - syntaxKindsMissing.Add(SyntaxKind.VariableComponentAssignment); - syntaxKindsMissing.Add(SyntaxKind.ForEachComponentStatement); + syntaxKindsMissing.Add(SyntaxKind.ForEachVariableStatement); syntaxKindsMissing.Add(SyntaxKind.DeclarationExpression); var analyzer = new CSharpTrackingDiagnosticAnalyzer(); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs index d71cb63cfa3bc..0ea0808711de5 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs @@ -1660,7 +1660,7 @@ static void Main() comp.VerifyDiagnostics( // (6,9): error CS8132: Cannot deconstruct a tuple of '2' elements into '3' variables. // (string x1, var x2, int x3) = (null, "hello"); - Diagnostic(ErrorCode.ERR_DeconstructWrongCardinality, @"(string x1, var x2, int x3) = (null, ""hello"");").WithArguments("2", "3").WithLocation(6, 9) + Diagnostic(ErrorCode.ERR_DeconstructWrongCardinality, @"(string x1, var x2, int x3) = (null, ""hello"")").WithArguments("2", "3").WithLocation(6, 9) ); } @@ -1681,7 +1681,7 @@ static void Main() comp.VerifyDiagnostics( // (6,9): error CS8132: Cannot deconstruct a tuple of '3' elements into '2' variables. // (string x1, var y1) = (null, "hello", 3); - Diagnostic(ErrorCode.ERR_DeconstructWrongCardinality, @"(string x1, var y1) = (null, ""hello"", 3);").WithArguments("3", "2").WithLocation(6, 9), + Diagnostic(ErrorCode.ERR_DeconstructWrongCardinality, @"(string x1, var y1) = (null, ""hello"", 3)").WithArguments("3", "2").WithLocation(6, 9), // (7,47): error CS8131: Deconstruct assignment requires an expression with a type on the right-hand-side. // (string x2, var y2) = (null, "hello", null); Diagnostic(ErrorCode.ERR_DeconstructRequiresExpression, "null").WithLocation(7, 47), @@ -1774,7 +1774,7 @@ static void Main() comp.VerifyDiagnostics( // (6,9): error CS8132: Cannot deconstruct a tuple of '3' elements into '2' variables. // (var (x1, x2), var x3) = (1, 2, 3); - Diagnostic(ErrorCode.ERR_DeconstructWrongCardinality, "(var (x1, x2), var x3) = (1, 2, 3);").WithArguments("3", "2").WithLocation(6, 9), + Diagnostic(ErrorCode.ERR_DeconstructWrongCardinality, "(var (x1, x2), var x3) = (1, 2, 3)").WithArguments("3", "2").WithLocation(6, 9), // (6,15): error CS8130: Cannot infer the type of implicitly-typed deconstruction variable 'x1'. // (var (x1, x2), var x3) = (1, 2, 3); Diagnostic(ErrorCode.ERR_TypeInferenceFailedForImplicitlyTypedDeconstructionVariable, "x1").WithArguments("x1").WithLocation(6, 15), @@ -2434,7 +2434,7 @@ static void Test(int arg1, (byte, byte) arg2) } [Fact] - public void DeclarationCannotBeEmbedded() + public void DeclarationCanBeEmbedded() { var source = @" class C1 @@ -2445,12 +2445,30 @@ void M() var (x, y) = (1, 2); } } +"; + var comp = CreateCompilationWithMscorlib(source, references: s_valueTupleRefs); + comp.VerifyDiagnostics(); + } + + [Fact] + public void EmbeddedDeclarationIsScoped() + { + var source = @" +class C1 +{ + void M() + { + if (true) + var (x, y) = (1, 2); + System.Console.WriteLine(x); + } +} "; var comp = CreateCompilationWithMscorlib(source, references: s_valueTupleRefs); comp.VerifyDiagnostics( - // (7,13): error CS1023: Embedded statement cannot be a declaration or labeled statement - // var (x, y) = (1, 2); - Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "var (x, y) = (1, 2);").WithLocation(7, 13) + // (8,34): error CS0103: The name 'x' does not exist in the current context + // System.Console.WriteLine(x); + Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(8, 34) ); } @@ -2552,9 +2570,12 @@ static void Main() var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (6,15): error CS0106: The modifier 'const' is not valid for this item + // (6,30): error CS1001: Identifier expected // const (int x, int y) = (1, 2); - Diagnostic(ErrorCode.ERR_BadMemberFlag, "(int x, int y)").WithArguments("const").WithLocation(6, 15) + Diagnostic(ErrorCode.ERR_IdentifierExpected, "=").WithLocation(6, 30), + // (6,15): error CS0283: The type '(int x, int y)' cannot be declared const + // const (int x, int y) = (1, 2); + Diagnostic(ErrorCode.ERR_BadConstType, "(int x, int y)").WithArguments("(int x, int y)").WithLocation(6, 15) ); } @@ -2573,10 +2594,37 @@ static void Main() var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }); comp.VerifyDiagnostics( - // (6,15): error CS0106: The modifier 'const' is not valid for this item + // (6,9): error CS0106: The modifier 'const' is not valid for this item // const var (x, y) = (1, 2); - Diagnostic(ErrorCode.ERR_BadMemberFlag, "var (x, y)").WithArguments("const").WithLocation(6, 15) - ); + Diagnostic(ErrorCode.ERR_BadMemberFlag, "const").WithArguments("const").WithLocation(6, 9), + // (6,19): error CS1001: Identifier expected + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(6, 19), + // (6,21): error CS1001: Identifier expected + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_IdentifierExpected, ",").WithLocation(6, 21), + // (6,24): error CS1001: Identifier expected + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(6, 24), + // (6,26): error CS1002: ; expected + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_SemicolonExpected, "=").WithLocation(6, 26), + // (6,26): error CS1525: Invalid expression term '=' + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_InvalidExprTerm, "=").WithArguments("=").WithLocation(6, 26), + // (6,19): error CS0501: '(x, y)' must declare a body because it is not marked abstract, extern, or partial + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "").WithArguments("(x, y)").WithLocation(6, 19), + // (6,20): error CS0246: The type or namespace name 'x' could not be found (are you missing a using directive or an assembly reference?) + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "x").WithArguments("x").WithLocation(6, 20), + // (6,23): error CS0246: The type or namespace name 'y' could not be found (are you missing a using directive or an assembly reference?) + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "y").WithArguments("y").WithLocation(6, 23), + // (6,15): error CS0825: The contextual keyword 'var' may only appear within a local variable declaration or in script code + // const var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_TypeVarNotFound, "var").WithLocation(6, 15) + ); } } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs index 95a7c73221294..345d8dfe24d94 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs @@ -273,7 +273,7 @@ static object Test1(out int x) return null; } }"; - var compilation = CreateCompilationWithMscorlib(text, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib(text, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular); compilation.VerifyDiagnostics( @@ -629,7 +629,7 @@ static object Test1(int x) compilation.VerifyDiagnostics(); - CompileAndVerify(compilation, expectedOutput: + CompileAndVerify(compilation, expectedOutput: @"124 123"); @@ -721,7 +721,7 @@ private static IdentifierNameSyntax GetReference(SyntaxTree tree, string name) { return GetReferences(tree, name).Single(); } - + private static IdentifierNameSyntax[] GetReferences(SyntaxTree tree, string name, int count) { var nameRef = GetReferences(tree, name).ToArray(); @@ -741,12 +741,21 @@ private static DeclarationExpressionSyntax GetOutVarDeclaration(SyntaxTree tree, private static IEnumerable GetOutVarDeclarations(SyntaxTree tree, string name) { - return tree.GetRoot().DescendantNodes().OfType().Where(p => p.Identifier().ValueText == name); + return tree.GetRoot().DescendantNodes().OfType() + .Where(p => IsOutVarDeclaration(p) && p.Identifier().ValueText == name); + } + + private static bool IsOutVarDeclaration(DeclarationExpressionSyntax p) + { + return p.Designation.Kind() == SyntaxKind.SingleVariableDesignation + && p.Parent.Kind() == SyntaxKind.Argument + && ((ArgumentSyntax)p.Parent).RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword; } private static IEnumerable GetOutVarDeclarations(SyntaxTree tree) { - return tree.GetRoot().DescendantNodes().OfType(); + return tree.GetRoot().DescendantNodes().OfType() + .Where(p => IsOutVarDeclaration(p)); } [Fact] @@ -838,7 +847,7 @@ private static void VerifyModelForOutVarInNotExecutableCode(SemanticModel model, Assert.True(model.LookupNames(decl.SpanStart).Contains(decl.Identifier().ValueText)); var local = (SourceLocalSymbol)symbol; - var typeSyntax = decl.Type(); + var typeSyntax = decl.Type; Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax)); Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax)); @@ -952,13 +961,13 @@ private static void VerifyModelForOutVarDuplicateInSameScope(SemanticModel model var local = (SourceLocalSymbol)symbol; - if (decl.Type().IsVar && local.IsVar && local.Type.IsErrorType()) + if (decl.Type.IsVar && local.IsVar && local.Type.IsErrorType()) { - Assert.Null(model.GetSymbolInfo(decl.Type()).Symbol); + Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); } else { - Assert.Equal(local.Type, model.GetSymbolInfo(decl.Type()).Symbol); + Assert.Equal(local.Type, model.GetSymbolInfo(decl.Type).Symbol); } } @@ -978,7 +987,7 @@ private static void VerifyNotAnOutLocal(SemanticModel model, IdentifierNameSynta var local = (SourceLocalSymbol)symbol; var parent = local.IdentifierToken.Parent; - Assert.Empty(parent.Ancestors().OfType()); + Assert.Empty(parent.Ancestors().OfType().Where(e => IsOutVarDeclaration(e))); if (parent.Kind() == SyntaxKind.VariableDeclarator) { @@ -1002,8 +1011,7 @@ private static void VerifyNotAnOutLocal(SemanticModel model, IdentifierNameSynta private static SingleVariableDesignationSyntax GetVariableDesignation(DeclarationExpressionSyntax decl) { - var component = (TypedVariableComponentSyntax)decl.VariableComponent; - return (SingleVariableDesignationSyntax)component.Designation; + return (SingleVariableDesignationSyntax)decl.Designation; } private static bool FlowsIn(ExpressionSyntax dataFlowParent, DeclarationExpressionSyntax decl, IdentifierNameSyntax[] references) @@ -1089,7 +1097,7 @@ private static bool FlowsOut(ExpressionSyntax dataFlowParent, DeclarationExpress MethodDeclarationSyntax methodDeclParent; - if (containingReturnOrThrow != null && decl.Identifier().ValueText == "x1" && + if (containingReturnOrThrow != null && decl.Identifier().ValueText == "x1" && ((methodDeclParent = containingReturnOrThrow.Parent.Parent as MethodDeclarationSyntax) == null || methodDeclParent.Body.Statements.First() != containingReturnOrThrow)) { @@ -1098,9 +1106,9 @@ private static bool FlowsOut(ExpressionSyntax dataFlowParent, DeclarationExpress foreach (var reference in references) { - if (!dataFlowParent.Span.Contains(reference.Span) && + if (!dataFlowParent.Span.Contains(reference.Span) && (containingReturnOrThrow == null || containingReturnOrThrow.Span.Contains(reference.SpanStart)) && - (reference.SpanStart > decl.SpanStart || + (reference.SpanStart > decl.SpanStart || (containingReturnOrThrow == null && reference.Ancestors().OfType().Join( decl.Ancestors().OfType(), d => d, d => d, (d1, d2) => true).Any()))) @@ -1502,8 +1510,8 @@ static void Test2(object x, object y) } }"; var compilation = CreateCompilationWithMscorlib(text, - references: new MetadataReference[] { CSharpRef, SystemCoreRef }, - options: TestOptions.ReleaseExe, + references: new MetadataReference[] { CSharpRef, SystemCoreRef }, + options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation, expectedOutput: @"123").VerifyDiagnostics(); @@ -4583,7 +4591,7 @@ static bool TakeOutParam(object y, out int x) Assert.True(success); Assert.NotNull(model); tree = statement.SyntaxTree; - + var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); var x1Ref = GetReferences(tree, "x1").ToArray(); Assert.Equal(1, x1Ref.Length); @@ -8591,7 +8599,7 @@ static bool TakeOutParam(object y, out object x) } } "; - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation.VerifyDiagnostics( // (19,51): error CS0128: A local variable named 'x4' is already defined in this scope @@ -8919,13 +8927,13 @@ static bool TakeOutParam(object y, out int x) } } "; - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); - var statement = (DeconstructionDeclarationStatementSyntax)SyntaxFactory.ParseStatement(@" + var statement = (ExpressionStatementSyntax)SyntaxFactory.ParseStatement(@" var (y1, dd) = (TakeOutParam(true, out var x1), x1); "); @@ -8942,7 +8950,7 @@ static bool TakeOutParam(object y, out int x) Assert.Equal("System.Boolean y1", model.LookupSymbols(x1Ref[0].SpanStart, name: "y1").Single().ToTestDisplayString()); } - + [Fact] [CompilerTrait(CompilerFeature.Tuples)] public void Scope_DeconstructionDeclarationStmt_06() @@ -8970,12 +8978,9 @@ static bool TakeOutParam(object y, out object x) } } "; - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation.VerifyDiagnostics( - // (11,13): error CS1023: Embedded statement cannot be a declaration or labeled statement - // var (d, dd) = (TakeOutParam(true, out var x1), x1); - Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "var (d, dd) = (TakeOutParam(true, out var x1), x1);").WithLocation(11, 13), // (13,9): error CS0103: The name 'x1' does not exist in the current context // x1++; Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(13, 9) @@ -12496,7 +12501,7 @@ static bool TakeOutParam(T y, out T x) } VerifyModelForOutVarDuplicateInSameScope(model, x15Decl[1]); } - + [Fact] public void Scope_SwitchLabelGuard_02() { @@ -12829,7 +12834,7 @@ static bool TakeOutParam(T y, out T x) "; var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); - CompileAndVerify(compilation, expectedOutput: + CompileAndVerify(compilation, expectedOutput: @"123 1").VerifyDiagnostics(); @@ -13035,7 +13040,7 @@ static bool TakeOutParam(T y, out T x) } } "; - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation, expectedOutput: @@ -14859,7 +14864,7 @@ static bool TakeOutParam(T y, out T x) 1 2 2"); - + var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); @@ -15808,7 +15813,7 @@ static void Test(out int x, ref int y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); } - + [Fact] public void DataFlow_03() { @@ -16016,7 +16021,7 @@ static object Test1(out int x) var x1Decl = GetOutVarDeclaration(tree, "x1"); VerifyModelForOutVar(model, x1Decl); - Assert.Equal("a=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); + Assert.Equal("a=System.Int32", model.GetAliasInfo(x1Decl.Type).ToTestDisplayString()); } @@ -16049,7 +16054,7 @@ static object Test1(out int x) var x1Decl = GetOutVarDeclaration(tree, "x1"); VerifyModelForOutVar(model, x1Decl); - Assert.Equal("var=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); + Assert.Equal("var=System.Int32", model.GetAliasInfo(x1Decl.Type).ToTestDisplayString()); } [Fact] @@ -16166,7 +16171,7 @@ static void Test2(object x, object y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); } [Fact] @@ -16201,7 +16206,7 @@ static void Test2(object x, object y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); } [Fact] @@ -16240,7 +16245,7 @@ static object Test1(out int x, out int x2) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); Assert.Equal("System.Int32 x1", model.GetDeclaredSymbol(GetVariableDesignation(x1Decl)).ToTestDisplayString()); } @@ -16281,7 +16286,7 @@ static object Test1(out int x, int x2) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); Assert.Equal("System.Int32 x1", model.GetDeclaredSymbol(GetVariableDesignation(x1Decl)).ToTestDisplayString()); } @@ -16324,7 +16329,7 @@ static void Test2(object x, object y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); Assert.Equal("System.Int32 x1", model.GetDeclaredSymbol(GetVariableDesignation(x1Decl)).ToTestDisplayString()); } @@ -16367,10 +16372,10 @@ static void Test2(object x, object y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); Assert.Equal("System.Int32 x1", model.GetDeclaredSymbol(GetVariableDesignation(x1Decl)).ToTestDisplayString()); } - + [Fact] public void SimpleVar_07() { @@ -16406,7 +16411,7 @@ static void Test2(object x, object y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); Assert.Equal("var x1", model.GetDeclaredSymbol(GetVariableDesignation(x1Decl)).ToTestDisplayString()); } @@ -16482,7 +16487,7 @@ static void Test2(object x, object y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, true, true, false, true, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); Assert.Equal("var x1", model.GetDeclaredSymbol(GetVariableDesignation(x1Decl)).ToTestDisplayString()); } @@ -16714,7 +16719,7 @@ static void Test2(object x, object y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); Assert.Equal("dynamic x1", model.GetDeclaredSymbol(GetVariableDesignation(x1Decl)).ToTestDisplayString()); } @@ -16755,7 +16760,7 @@ static void Test2(object x, object y) var varRef = GetReferences(tree, "var").Skip(1).Single(); VerifyModelForOutVar(model, varDecl, varRef); } - + [Fact] public void SimpleVar_16() { @@ -16792,7 +16797,7 @@ static bool Test1(out int x) VerifyModelForOutVar(model, x1Decl, x1Ref); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); } [Fact] @@ -17019,7 +17024,7 @@ static void Test2(object x, System.ArgIterator y) var x1Ref = GetReference(tree, "x1"); VerifyModelForOutVar(model, x1Decl, x1Ref); } - + [Fact] public void RestrictedTypes_04() { @@ -18026,7 +18031,7 @@ private static void AssertContainedInDeclaratorArguments(DeclarationExpressionSy Assert.True(decl.Ancestors().OfType().First().ArgumentList.Contains(decl)); } - private static void AssertContainedInDeclaratorArguments(params DeclarationExpressionSyntax [] decls) + private static void AssertContainedInDeclaratorArguments(params DeclarationExpressionSyntax[] decls) { foreach (var decl in decls) { @@ -18991,7 +18996,7 @@ static bool TakeOutParam(T y, out T x) var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); int[] exclude = new int[] { (int)ErrorCode.ERR_BadVarDecl, (int)ErrorCode.ERR_SyntaxError, - (int)ErrorCode.WRN_UnreferencedVar, + (int)ErrorCode.WRN_UnreferencedVar, (int)ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, (int)ErrorCode.ERR_FixedMustInit, (int)ErrorCode.ERR_ImplicitlyTypedVariableWithNoInitializer, @@ -19724,7 +19729,7 @@ static bool TakeOutParam(object y, out int x) Assert.False(model.LookupSymbols(decl.SpanStart, name: identifierText).Any()); Assert.False(model.LookupNames(decl.SpanStart).Contains(identifierText)); - Assert.Null(model.GetSymbolInfo(decl.Type()).Symbol); + Assert.Null(model.GetSymbolInfo(decl.Type).Symbol); AssertInfoForDeclarationExpressionSyntax(model, decl); @@ -23097,7 +23102,7 @@ public static bool TakeOutParam(T y, out T x) } "; { - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); compilation.VerifyDiagnostics( @@ -23983,7 +23988,7 @@ public static bool TakeOutParam(T y, out T x) } "; { - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); compilation.VerifyDiagnostics( @@ -24150,7 +24155,7 @@ public static bool TakeOutParam(T y, out T x) } "; { - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); compilation.VerifyDiagnostics( @@ -24307,7 +24312,7 @@ public static bool TakeOutParam(T y, out T x) } "; - var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, + var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); CompileAndVerify(compilation, expectedOutput: @@ -26417,7 +26422,7 @@ public static int TakeOutParam(T y, out T x) } "; { - var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), + var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), parseOptions: TestOptions.Script); compilation.VerifyDiagnostics( @@ -26858,7 +26863,7 @@ public static bool TakeOutParam(T y, out T x) var model = compilation.GetSemanticModel(tree); var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); } [Fact] @@ -26887,7 +26892,7 @@ public static bool TakeOutParam(T y, out T x) var model = compilation.GetSemanticModel(tree); var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); - Assert.Equal("var=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); + Assert.Equal("var=System.Int32", model.GetAliasInfo(x1Decl.Type).ToTestDisplayString()); } [Fact] @@ -26916,7 +26921,7 @@ public static bool TakeOutParam(T y, out T x) var model = compilation.GetSemanticModel(tree); var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); - Assert.Equal("a=System.Int32", model.GetAliasInfo(x1Decl.Type()).ToTestDisplayString()); + Assert.Equal("a=System.Int32", model.GetAliasInfo(x1Decl.Type).ToTestDisplayString()); } [Fact] @@ -26943,7 +26948,7 @@ public static bool TakeOutParam(T y, out T x) var model = compilation.GetSemanticModel(tree); var x1Decl = GetOutVarDeclarations(tree, "x1").Single(); - Assert.Null(model.GetAliasInfo(x1Decl.Type())); + Assert.Null(model.GetAliasInfo(x1Decl.Type)); } [Fact, WorkItem(14717, "https://github.com/dotnet/roslyn/issues/14717")] @@ -27071,7 +27076,7 @@ static void Main(string[] args) Assert.Contains(decl.Identifier().ValueText, names); var local = (FieldSymbol)symbol; - var typeSyntax = decl.Type(); + var typeSyntax = decl.Type; Assert.True(SyntaxFacts.IsInNamespaceOrTypeContext(typeSyntax)); Assert.True(SyntaxFacts.IsInTypeOnlyContext(typeSyntax)); @@ -27283,4 +27288,12 @@ public void Test() Assert.Equal("System.String", model.GetTypeInfo(x1Ref).Type.ToTestDisplayString()); } } + + internal static class OutVarTestsExtensions + { + internal static SingleVariableDesignationSyntax VariableDesignation(this DeclarationExpressionSyntax self) + { + return (SingleVariableDesignationSyntax)self.Designation; + } + } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs index 98f42ea387233..d0e1ea399ef10 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs @@ -6714,7 +6714,7 @@ void Test1() var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); - var statement = (DeconstructionDeclarationStatementSyntax)SyntaxFactory.ParseStatement(@" + var statement = (ExpressionStatementSyntax)SyntaxFactory.ParseStatement(@" var (y1, dd) = ((123 is var x1), x1); "); @@ -6756,9 +6756,6 @@ void Test1() var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation.VerifyDiagnostics( - // (11,13): error CS1023: Embedded statement cannot be a declaration or labeled statement - // var (d, dd) = ((true is var x1), x1); - Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "var (d, dd) = ((true is var x1), x1);").WithLocation(11, 13), // (13,9): error CS0103: The name 'x1' does not exist in the current context // x1++; Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(13, 9) diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs index 50aab9c19d589..5075de47c2d16 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTests.cs @@ -1434,7 +1434,7 @@ void Foo() N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); - N(SyntaxKind.ForEachComponentStatement); + N(SyntaxKind.ForEachVariableStatement); { N(SyntaxKind.ForEachKeyword); N(SyntaxKind.OpenParenToken); @@ -1527,7 +1527,7 @@ void Foo() N(SyntaxKind.Block); { N(SyntaxKind.OpenBraceToken); - N(SyntaxKind.ForEachComponentStatement); + N(SyntaxKind.ForEachVariableStatement); { N(SyntaxKind.ForEachKeyword); N(SyntaxKind.OpenParenToken); @@ -1659,7 +1659,7 @@ public void DeconstructionForEachInScript() { N(SyntaxKind.GlobalStatement); { - N(SyntaxKind.ForEachComponentStatement); + N(SyntaxKind.ForEachVariableStatement); { N(SyntaxKind.ForEachKeyword); N(SyntaxKind.OpenParenToken); diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs index ef61ebd918d33..cafdd7b12aaa1 100644 --- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs +++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/LoopHighlighter.cs @@ -45,7 +45,7 @@ private IEnumerable KeywordHighlightsForLoop(SyntaxNode loopNode) break; case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: HighlightForEachStatement((CommonForEachStatementSyntax)loopNode, spans); break; diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs index 011e5a346ce68..5f7f1f25bc5c8 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs @@ -38,7 +38,7 @@ public async Task DiagnosticAnalyzerDriverAllInOne() syntaxKindsMissing.Add(SyntaxKind.ParenthesizedVariableDesignation); syntaxKindsMissing.Add(SyntaxKind.DeconstructionDeclarationStatement); syntaxKindsMissing.Add(SyntaxKind.VariableComponentAssignment); - syntaxKindsMissing.Add(SyntaxKind.ForEachComponentStatement); + syntaxKindsMissing.Add(SyntaxKind.ForEachVariableStatement); syntaxKindsMissing.Add(SyntaxKind.DeclarationExpression); var analyzer = new CSharpTrackingDiagnosticAnalyzer(); diff --git a/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs b/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs index 5d4094a02f75c..f26193c766dbd 100644 --- a/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesCodeFixProvider.cs @@ -59,7 +59,7 @@ private SyntaxNode GetReplacementNode(SyntaxNode statement) return GetNewBlock(statement, forSyntax.Statement); case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: var forEachSyntax = (CommonForEachStatementSyntax)statement; return GetNewBlock(statement, forEachSyntax.Statement); diff --git a/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesDiagnosticAnalyzer.cs b/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesDiagnosticAnalyzer.cs index 65ac60094e132..8238d30dd56b5 100644 --- a/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesDiagnosticAnalyzer.cs +++ b/src/Features/CSharp/Portable/AddBraces/CSharpAddBracesDiagnosticAnalyzer.cs @@ -35,7 +35,7 @@ public override void Initialize(AnalysisContext context) SyntaxKind.ElseClause, SyntaxKind.ForStatement, SyntaxKind.ForEachStatement, - SyntaxKind.ForEachComponentStatement, + SyntaxKind.ForEachVariableStatement, SyntaxKind.WhileStatement, SyntaxKind.DoStatement, SyntaxKind.UsingStatement, @@ -80,7 +80,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context) } } - if (node.IsKind(SyntaxKind.ForEachStatement) || node.IsKind(SyntaxKind.ForEachComponentStatement)) + if (node.IsKind(SyntaxKind.ForEachStatement) || node.IsKind(SyntaxKind.ForEachVariableStatement)) { var forEachStatement = (CommonForEachStatementSyntax)node; if (AnalyzeForEachStatement(forEachStatement)) diff --git a/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs b/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs index 963ebc9c8d4f0..d2c5d63bbffb9 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs @@ -456,7 +456,7 @@ private static TextSpan CreateSpanForBlock(BlockSyntax block, int position) } case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: // Note: if the user was in the body of the foreach, then we would have hit its // nested statement on the way up. If they were in the expression then we would // have hit that on the way up as well. In "foreach(var f in expr)" we allow a @@ -733,7 +733,7 @@ private static bool IsBreakableExpression(ExpressionSyntax expression) forStatement.Incrementors.Contains(expression); case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: var forEachStatement = (CommonForEachStatementSyntax)parent; return forEachStatement.Expression == expression; diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index fa3f66cc41427..877543a3e9cd8 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -1345,7 +1345,7 @@ internal static TextSpan GetDiagnosticSpanImpl(SyntaxKind kind, SyntaxNode node, case SyntaxKind.GroupClause: return ((GroupClauseSyntax)node).GroupKeyword.Span; - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: return ((ForEachComponentStatementSyntax)node).VariableComponent.Span; case SyntaxKind.IsPatternExpression: @@ -1608,7 +1608,7 @@ internal static string GetStatementDisplayNameImpl(SyntaxNode node) return CSharpFeaturesResources.is_pattern; case SyntaxKind.DeconstructionDeclarationStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: case SyntaxKind.ParenthesizedVariableComponent: case SyntaxKind.TypedVariableComponent: case SyntaxKind.VariableComponentAssignment: @@ -3108,7 +3108,7 @@ private static bool IsUnsupportedCSharp7EnCNode(SyntaxNode n) case SyntaxKind.IsPatternExpression: case SyntaxKind.DeconstructionDeclarationStatement: case SyntaxKind.VariableComponentAssignment: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: case SyntaxKind.ParenthesizedVariableComponent: case SyntaxKind.TypedVariableComponent: case SyntaxKind.TupleType: diff --git a/src/Features/CSharp/Portable/EditAndContinue/StatementSyntaxComparer.cs b/src/Features/CSharp/Portable/EditAndContinue/StatementSyntaxComparer.cs index d45138c5b5b7d..ef81424e7958a 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/StatementSyntaxComparer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/StatementSyntaxComparer.cs @@ -336,7 +336,7 @@ internal static Label Classify(SyntaxKind kind, SyntaxNode nodeOpt, out bool isL case SyntaxKind.ForEachStatement: return Label.ForEachStatement; - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: return Label.ForEachComponentStatement; case SyntaxKind.UsingStatement: @@ -776,7 +776,7 @@ private bool TryComputeWeightedDistance(BlockSyntax leftBlock, BlockSyntax right { case SyntaxKind.IfStatement: case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: case SyntaxKind.ForStatement: case SyntaxKind.WhileStatement: case SyntaxKind.DoStatement: diff --git a/src/Features/CSharp/Portable/Structure/Providers/BlockSyntaxStructureProvider.cs b/src/Features/CSharp/Portable/Structure/Providers/BlockSyntaxStructureProvider.cs index c426a2ba53086..8c10d5c3b41e4 100644 --- a/src/Features/CSharp/Portable/Structure/Providers/BlockSyntaxStructureProvider.cs +++ b/src/Features/CSharp/Portable/Structure/Providers/BlockSyntaxStructureProvider.cs @@ -120,7 +120,7 @@ private string GetType(SyntaxNode parent) { case SyntaxKind.ForStatement: return BlockTypes.Loop; case SyntaxKind.ForEachStatement: return BlockTypes.Loop; - case SyntaxKind.ForEachComponentStatement: return BlockTypes.Loop; + case SyntaxKind.ForEachVariableStatement: return BlockTypes.Loop; case SyntaxKind.WhileStatement: return BlockTypes.Loop; case SyntaxKind.DoStatement: return BlockTypes.Loop; diff --git a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.Worker.cs b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.Worker.cs index a6c086a6d3617..c728f143438c5 100644 --- a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.Worker.cs +++ b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.Worker.cs @@ -198,7 +198,7 @@ private void AddPrecedingRelevantExpressions() break; case SyntaxKind.ForStatement: case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: case SyntaxKind.IfStatement: case SyntaxKind.CheckedStatement: case SyntaxKind.UncheckedStatement: @@ -252,7 +252,7 @@ private void AddLastStatementOfConstruct(StatementSyntax statement) AddLastStatementOfConstruct((statement as ForStatementSyntax).Statement); break; case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: AddLastStatementOfConstruct((statement as CommonForEachStatementSyntax).Statement); break; case SyntaxKind.IfStatement: diff --git a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTokenExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTokenExtensions.cs index 0ffb6f4616521..a19307b6465b2 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTokenExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTokenExtensions.cs @@ -170,7 +170,7 @@ public static bool IsBeginningOfStatementContext(this SyntaxToken token) var parent = token.Parent; if (parent.IsKind(SyntaxKind.ForStatement) || parent.IsKind(SyntaxKind.ForEachStatement) || - parent.IsKind(SyntaxKind.ForEachComponentStatement) || + parent.IsKind(SyntaxKind.ForEachVariableStatement) || parent.IsKind(SyntaxKind.WhileStatement) || parent.IsKind(SyntaxKind.IfStatement) || parent.IsKind(SyntaxKind.LockStatement) || diff --git a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs index 1d38e04088c72..7b6d0f9f4bcce 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs @@ -2043,7 +2043,7 @@ public static bool IsLabelContext(this SyntaxTree syntaxTree, int position, Canc if (token.IsKind(SyntaxKind.InKeyword)) { if (token.Parent.IsKind(SyntaxKind.ForEachStatement, - SyntaxKind.ForEachComponentStatement, + SyntaxKind.ForEachVariableStatement, SyntaxKind.FromClause, SyntaxKind.JoinClause)) { diff --git a/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs index 1ead6fdbf9de9..bd771dd594069 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs @@ -20,7 +20,7 @@ public static bool IsTypeInferred(this CommonForEachStatementSyntax forEachState { case SyntaxKind.ForEachStatement: return ((ForEachStatementSyntax)forEachStatement).Type.IsTypeInferred(semanticModel); - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: return (((ForEachComponentStatementSyntax)forEachStatement).VariableComponent as TypedVariableComponentSyntax)?.Type.IsTypeInferred(semanticModel) == true; default: return false; diff --git a/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs index 4983744154719..39b11da8509f8 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs @@ -59,7 +59,7 @@ public static bool CanRemoveParentheses(this ParenthesizedExpressionSyntax node) (node.IsParentKind(SyntaxKind.WhileStatement) && ((WhileStatementSyntax)node.Parent).Condition == node) || (node.IsParentKind(SyntaxKind.DoStatement) && ((DoStatementSyntax)node.Parent).Condition == node) || (node.IsParentKind(SyntaxKind.ForStatement) && ((ForStatementSyntax)node.Parent).Condition == node) || - (node.IsParentKind(SyntaxKind.ForEachStatement, SyntaxKind.ForEachComponentStatement) && ((CommonForEachStatementSyntax)node.Parent).Expression == node) || + (node.IsParentKind(SyntaxKind.ForEachStatement, SyntaxKind.ForEachVariableStatement) && ((CommonForEachStatementSyntax)node.Parent).Expression == node) || (node.IsParentKind(SyntaxKind.LockStatement) && ((LockStatementSyntax)node.Parent).Expression == node) || (node.IsParentKind(SyntaxKind.UsingStatement) && ((UsingStatementSyntax)node.Parent).Expression == node) || (node.IsParentKind(SyntaxKind.CatchFilterClause) && ((CatchFilterClauseSyntax)node.Parent).FilterExpression == node)) diff --git a/src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs index c3c996938cca3..b3fb35ea14c9d 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs @@ -267,7 +267,7 @@ public static bool IsBreakableConstruct(this SyntaxNode node) case SyntaxKind.SwitchStatement: case SyntaxKind.ForStatement: case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: return true; } @@ -282,7 +282,7 @@ public static bool IsContinuableConstruct(this SyntaxNode node) case SyntaxKind.WhileStatement: case SyntaxKind.ForStatement: case SyntaxKind.ForEachStatement: - case SyntaxKind.ForEachComponentStatement: + case SyntaxKind.ForEachVariableStatement: return true; } diff --git a/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs b/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs index 433b970e6aa6c..efd265871ca03 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/Rules/NewLineUserSettingFormattingRule.cs @@ -17,7 +17,7 @@ private bool IsControlBlock(SyntaxNode node) (parent != null && (parent.Kind() == SyntaxKind.IfStatement || parent.Kind() == SyntaxKind.ElseClause || parent.Kind() == SyntaxKind.WhileStatement || parent.Kind() == SyntaxKind.DoStatement || - parent.Kind() == SyntaxKind.ForEachStatement || parent.Kind() == SyntaxKind.ForEachComponentStatement || + parent.Kind() == SyntaxKind.ForEachStatement || parent.Kind() == SyntaxKind.ForEachVariableStatement || parent.Kind() == SyntaxKind.UsingStatement || parent.Kind() == SyntaxKind.ForStatement || parent.Kind() == SyntaxKind.TryStatement || parent.Kind() == SyntaxKind.CatchClause || parent.Kind() == SyntaxKind.FinallyClause || diff --git a/src/Workspaces/CSharp/Portable/Formatting/Rules/SpacingFormattingRule.cs b/src/Workspaces/CSharp/Portable/Formatting/Rules/SpacingFormattingRule.cs index 45eac55d19114..e69848ebb4bed 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/Rules/SpacingFormattingRule.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/Rules/SpacingFormattingRule.cs @@ -377,7 +377,7 @@ private bool IsFunctionLikeKeywordExpressionKind(SyntaxKind syntaxKind) private bool IsControlFlowLikeKeywordStatementKind(SyntaxKind syntaxKind) { return (syntaxKind == SyntaxKind.IfStatement || syntaxKind == SyntaxKind.WhileStatement || syntaxKind == SyntaxKind.SwitchStatement || - syntaxKind == SyntaxKind.ForStatement || syntaxKind == SyntaxKind.ForEachStatement || syntaxKind == SyntaxKind.ForEachComponentStatement || + syntaxKind == SyntaxKind.ForStatement || syntaxKind == SyntaxKind.ForEachStatement || syntaxKind == SyntaxKind.ForEachVariableStatement || syntaxKind == SyntaxKind.DoStatement || syntaxKind == SyntaxKind.CatchDeclaration || syntaxKind == SyntaxKind.UsingStatement || syntaxKind == SyntaxKind.LockStatement || syntaxKind == SyntaxKind.FixedStatement || syntaxKind == SyntaxKind.CatchFilterClause); diff --git a/src/Workspaces/CSharp/Portable/Utilities/FormattingRangeHelper.cs b/src/Workspaces/CSharp/Portable/Utilities/FormattingRangeHelper.cs index 3bf4ec9354ebc..ec175aa278fc9 100644 --- a/src/Workspaces/CSharp/Portable/Utilities/FormattingRangeHelper.cs +++ b/src/Workspaces/CSharp/Portable/Utilities/FormattingRangeHelper.cs @@ -353,7 +353,7 @@ private static bool IsSpecialContainingNode(SyntaxNode node) node.Kind() == SyntaxKind.WhileStatement || node.Kind() == SyntaxKind.ForStatement || node.Kind() == SyntaxKind.ForEachStatement || - node.Kind() == SyntaxKind.ForEachComponentStatement || + node.Kind() == SyntaxKind.ForEachVariableStatement || node.Kind() == SyntaxKind.UsingStatement || node.Kind() == SyntaxKind.DoStatement || node.Kind() == SyntaxKind.TryStatement || From ecce74d17667bdfb138d9a596483391d0bef537e Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 3 Nov 2016 17:40:20 -0700 Subject: [PATCH 3/8] Updating editor features to adopt new syntax model --- .../DiagnosticAnalyzerDriverTests.cs | 4 - .../EditAndContinue/ActiveStatementTests.cs | 6 +- .../ExpressionCompiler/CompilationContext.cs | 2 +- .../ExpressionCompiler/EvaluationContext.cs | 3 +- .../InKeywordRecommender.cs | 4 +- .../EditAndContinue/BreakpointSpans.cs | 3 +- .../CSharpEditAndContinueAnalyzer.cs | 34 ++++---- ...CodeGenerator.CallSiteContainerRewriter.cs | 4 +- ...harpMethodExtractor.CSharpCodeGenerator.cs | 15 ++-- .../CSharpInlineDeclarationCodeFixProvider.cs | 3 +- .../InternalUtilities/InternalExtensions.cs | 4 +- ...onsService.RelevantExpressionsCollector.cs | 19 ++--- .../Classifiers/NameSyntaxClassifier.cs | 2 +- .../Extensions/ExpressionSyntaxExtensions.cs | 13 +-- .../ForEachStatementSyntaxExtensions.cs | 3 +- ...ParenthesizedExpressionSyntaxExtensions.cs | 1 - .../Extensions/SemanticModelExtensions.cs | 3 +- .../Portable/Formatting/FormattingHelpers.cs | 2 +- ...CSharpTypeInferenceService.TypeInferrer.cs | 79 ++++++++++--------- 19 files changed, 99 insertions(+), 105 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs index 5f7f1f25bc5c8..ecb04ba3478d7 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs @@ -32,12 +32,8 @@ public async Task DiagnosticAnalyzerDriverAllInOne() var syntaxKindsMissing = new HashSet(); // AllInOneCSharpCode has no deconstruction or declaration expression - syntaxKindsMissing.Add(SyntaxKind.TypedVariableComponent); - syntaxKindsMissing.Add(SyntaxKind.ParenthesizedVariableComponent); syntaxKindsMissing.Add(SyntaxKind.SingleVariableDesignation); syntaxKindsMissing.Add(SyntaxKind.ParenthesizedVariableDesignation); - syntaxKindsMissing.Add(SyntaxKind.DeconstructionDeclarationStatement); - syntaxKindsMissing.Add(SyntaxKind.VariableComponentAssignment); syntaxKindsMissing.Add(SyntaxKind.ForEachVariableStatement); syntaxKindsMissing.Add(SyntaxKind.DeclarationExpression); diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs index e8731033bcbfe..7f2914542f6ec 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs @@ -8155,7 +8155,7 @@ static void F(object x) var active = GetActiveStatements(src1, src2); edits.VerifyRudeDiagnostics(active, - Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "var (x, y) = x;", CSharpFeaturesResources.deconstruction)); + Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "var (x, y) = x", CSharpFeaturesResources.deconstruction)); } [Fact] @@ -8424,7 +8424,7 @@ static void F(object o1, object o2) var active = GetActiveStatements(src1, src2); edits.VerifyRudeDiagnostics(active, - Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "var (x, y) = o2;", CSharpFeaturesResources.deconstruction)); + Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "var (x, y) = o2", CSharpFeaturesResources.deconstruction)); } [Fact] @@ -8456,7 +8456,7 @@ static void F(object o1, object o2) var active = GetActiveStatements(src1, src2); edits.VerifyRudeDiagnostics(active, - Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "(x, y)", CSharpFeaturesResources.tuple)); + Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "(x, y) = o2", CSharpFeaturesResources.deconstruction)); } [Fact] diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs index d74889c58a21d..590cb1168de38 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs @@ -53,7 +53,7 @@ internal sealed class CompilationContext MethodDebugInfo methodDebugInfo, CSharpSyntaxNode syntax) { - Debug.Assert((syntax == null) || (syntax is ExpressionSyntax) || (syntax is LocalDeclarationStatementSyntax) || (syntax is DeconstructionDeclarationStatementSyntax)); + Debug.Assert((syntax == null) || (syntax is ExpressionSyntax) || (syntax is LocalDeclarationStatementSyntax)); // TODO: syntax.SyntaxTree should probably be added to the compilation, // but it isn't rooted by a CompilationUnitSyntax so it doesn't work (yet). diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs index cd0ed71fe05c4..4e74717b4c7d9 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs @@ -305,8 +305,7 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui { formatSpecifiers = null; - if (statementSyntax.IsKind(SyntaxKind.LocalDeclarationStatement) || - statementSyntax.IsKind(SyntaxKind.DeconstructionDeclarationStatement)) + if (statementSyntax.IsKind(SyntaxKind.LocalDeclarationStatement)) { return statementSyntax; } diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs index 17cbdd0eec119..c7ec5f5d6b5f3 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/InKeywordRecommender.cs @@ -43,8 +43,8 @@ private bool IsValidContextInForEachClause(CSharpSyntaxContext context) } else if (token.Kind() == SyntaxKind.CloseParenToken) { - var statement = token.GetAncestor(); - if (statement != null && token.Span.End == statement.VariableComponent.Span.End) + var statement = token.GetAncestor(); + if (statement != null && token.Span.End == statement.Variable.Span.End) { return true; } diff --git a/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs b/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs index d2c5d63bbffb9..eab8940b3e576 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/BreakpointSpans.cs @@ -475,7 +475,7 @@ private static TextSpan CreateSpanForBlock(BlockSyntax block, int position) } else { - return ((ForEachComponentStatementSyntax)statement).VariableComponent.Span; + return ((ForEachVariableStatementSyntax)statement).Variable.Span; } } else if (position < forEachStatement.Expression.FullSpan.Start) @@ -554,7 +554,6 @@ private static TextSpan CreateSpanForBlock(BlockSyntax block, int position) case SyntaxKind.ThrowStatement: case SyntaxKind.ExpressionStatement: case SyntaxKind.EmptyStatement: - case SyntaxKind.DeconstructionDeclarationStatement: default: // Fallback case. If it was none of the above types of statements, then we make a span // over the entire statement. Note: this is not a very desirable thing to do (as diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index 877543a3e9cd8..6bf26ef17ab71 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -1346,19 +1346,16 @@ internal static TextSpan GetDiagnosticSpanImpl(SyntaxKind kind, SyntaxNode node, return ((GroupClauseSyntax)node).GroupKeyword.Span; case SyntaxKind.ForEachVariableStatement: - return ((ForEachComponentStatementSyntax)node).VariableComponent.Span; + return ((ForEachVariableStatementSyntax)node).Variable.Span; case SyntaxKind.IsPatternExpression: - case SyntaxKind.DeconstructionDeclarationStatement: - case SyntaxKind.ParenthesizedVariableComponent: - case SyntaxKind.TypedVariableComponent: case SyntaxKind.TupleType: case SyntaxKind.TupleExpression: case SyntaxKind.DeclarationExpression: case SyntaxKind.RefType: case SyntaxKind.RefExpression: case SyntaxKind.DeclarationPattern: - case SyntaxKind.VariableComponentAssignment: + case SyntaxKind.SimpleAssignmentExpression: return node.Span; default: @@ -1607,13 +1604,19 @@ internal static string GetStatementDisplayNameImpl(SyntaxNode node) case SyntaxKind.IsPatternExpression: return CSharpFeaturesResources.is_pattern; - case SyntaxKind.DeconstructionDeclarationStatement: case SyntaxKind.ForEachVariableStatement: - case SyntaxKind.ParenthesizedVariableComponent: - case SyntaxKind.TypedVariableComponent: - case SyntaxKind.VariableComponentAssignment: return CSharpFeaturesResources.deconstruction; + case SyntaxKind.SimpleAssignmentExpression: + if (IsDeconstruction((AssignmentExpressionSyntax)node)) + { + return CSharpFeaturesResources.deconstruction; + } + else + { + goto default; + } + case SyntaxKind.TupleType: case SyntaxKind.TupleExpression: return CSharpFeaturesResources.tuple; @@ -3106,11 +3109,7 @@ private static bool IsUnsupportedCSharp7EnCNode(SyntaxNode n) switch (n.Kind()) { case SyntaxKind.IsPatternExpression: - case SyntaxKind.DeconstructionDeclarationStatement: - case SyntaxKind.VariableComponentAssignment: case SyntaxKind.ForEachVariableStatement: - case SyntaxKind.ParenthesizedVariableComponent: - case SyntaxKind.TypedVariableComponent: case SyntaxKind.TupleType: case SyntaxKind.TupleExpression: case SyntaxKind.LocalFunctionStatement: @@ -3119,12 +3118,19 @@ private static bool IsUnsupportedCSharp7EnCNode(SyntaxNode n) case SyntaxKind.RefExpression: case SyntaxKind.DeclarationPattern: return true; - + case SyntaxKind.SimpleAssignmentExpression: + return IsDeconstruction((AssignmentExpressionSyntax)n); default: return false; } } + private static bool IsDeconstruction(AssignmentExpressionSyntax assignment) + { + return assignment.Left.Kind() == SyntaxKind.TupleExpression || + assignment.Left.Kind() == SyntaxKind.DeclarationExpression; + } + private void ReportRudeEditsForCheckedStatements( List diagnostics, SyntaxNode oldActiveStatement, diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.CallSiteContainerRewriter.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.CallSiteContainerRewriter.cs index 1998990a34405..d39906528d522 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.CallSiteContainerRewriter.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.CallSiteContainerRewriter.cs @@ -223,11 +223,11 @@ public override SyntaxNode VisitForEachStatement(ForEachStatementSyntax node) .WithStatement(ReplaceStatementIfNeeded(node.Statement)); } - public override SyntaxNode VisitForEachComponentStatement(ForEachComponentStatementSyntax node) + public override SyntaxNode VisitForEachVariableStatement(ForEachVariableStatementSyntax node) { if (node != this.ContainerOfStatementsOrFieldToReplace) { - return base.VisitForEachComponentStatement(node); + return base.VisitForEachVariableStatement(node); } return node.WithExpression(VisitNode(node.Expression)) diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs index 98582280b1947..cbdec3b8de83c 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs @@ -420,25 +420,20 @@ yield return switch (node.Kind()) { case SyntaxKind.DeclarationExpression: - var declaration = (DeclarationExpressionSyntax)node; - if (declaration.VariableComponent.Kind() != SyntaxKind.TypedVariableComponent) - { - break; - } - var variableComponent = (TypedVariableComponentSyntax)declaration.VariableComponent; - if (variableComponent.Designation.Kind() != SyntaxKind.SingleVariableDesignation) + var declaration = (DeclarationExpressionSyntax)node; + if (declaration.Designation.Kind() != SyntaxKind.SingleVariableDesignation) { break; } - var designation = (SingleVariableDesignationSyntax)variableComponent.Designation; + var designation = (SingleVariableDesignationSyntax)declaration.Designation; var name = designation.Identifier.ValueText; if (variablesToRemove.HasSyntaxAnnotation(designation)) { var newLeadingTrivia = new SyntaxTriviaList(); - newLeadingTrivia = newLeadingTrivia.AddRange(variableComponent.Type.GetLeadingTrivia()); - newLeadingTrivia = newLeadingTrivia.AddRange(variableComponent.Type.GetTrailingTrivia()); + newLeadingTrivia = newLeadingTrivia.AddRange(declaration.Type.GetLeadingTrivia()); + newLeadingTrivia = newLeadingTrivia.AddRange(declaration.Type.GetTrailingTrivia()); newLeadingTrivia = newLeadingTrivia.AddRange(designation.GetLeadingTrivia()); replacements.Add(declaration, SyntaxFactory.IdentifierName(designation.Identifier) diff --git a/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs b/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs index b4de45d457eb7..ec3bc95d5234e 100644 --- a/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs @@ -200,8 +200,7 @@ private Task FixAsync(Document document, Diagnostic diagnostic, Cancel } } - return SyntaxFactory.DeclarationExpression( - SyntaxFactory.TypedVariableComponent(newType, designation)); + return SyntaxFactory.DeclarationExpression(newType, designation); } private static IEnumerable MassageTrivia(IEnumerable triviaList) diff --git a/src/Features/CSharp/Portable/InternalUtilities/InternalExtensions.cs b/src/Features/CSharp/Portable/InternalUtilities/InternalExtensions.cs index f9ece11798def..56f784d5b0802 100644 --- a/src/Features/CSharp/Portable/InternalUtilities/InternalExtensions.cs +++ b/src/Features/CSharp/Portable/InternalUtilities/InternalExtensions.cs @@ -23,9 +23,7 @@ internal static class InternalExtensions if (argument.Expression.Kind() == SyntaxKind.DeclarationExpression) { var decl = (DeclarationExpressionSyntax)argument.Expression; - var component = decl.VariableComponent as TypedVariableComponentSyntax; - if (component == null) return semanticModel.Compilation.ObjectType; - typeInfo = semanticModel.GetTypeInfo(component.Type); + typeInfo = semanticModel.GetTypeInfo(decl.Type); return typeInfo.Type?.IsErrorType() == false ? typeInfo.Type : semanticModel.Compilation.ObjectType; } diff --git a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs index 50ed307e75645..3a1f6c1374bf3 100644 --- a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs +++ b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs @@ -85,9 +85,9 @@ public override void VisitForEachStatement(ForEachStatementSyntax node) AddExpressionTerms(node.Expression, _expressions); } - public override void VisitForEachComponentStatement(ForEachComponentStatementSyntax node) + public override void VisitForEachVariableStatement(ForEachVariableStatementSyntax node) { - AddVariableExpressions(node.VariableComponent, _expressions); + AddVariableExpressions(node.Variable, _expressions); AddExpressionTerms(node.Expression, _expressions); } @@ -125,22 +125,23 @@ public override void VisitSwitchStatement(SwitchStatementSyntax node) } private void AddVariableExpressions( - VariableComponentSyntax component, + ExpressionSyntax component, IList expressions) { if (!_includeDeclarations) return; switch (component.Kind()) { - case SyntaxKind.ParenthesizedVariableComponent: + case SyntaxKind.TupleExpression: { - var t = (ParenthesizedVariableComponentSyntax)component; - foreach (var v in t.Variables) AddVariableExpressions(component, expressions); + var t = (TupleExpressionSyntax)component; + foreach (ArgumentSyntax a in t.Arguments) AddVariableExpressions(a.Expression, expressions); + // TODO REVIEW I think there was a bug there. Are we missing tests? break; } - case SyntaxKind.TypedVariableComponent: + case SyntaxKind.DeclarationExpression: { - var t = (TypedVariableComponentSyntax)component; + var t = (DeclarationExpressionSyntax)component; AddVariableExpressions(t.Designation, expressions); break; } @@ -158,7 +159,7 @@ public override void VisitSwitchStatement(SwitchStatementSyntax node) case SyntaxKind.ParenthesizedVariableDesignation: { var t = (ParenthesizedVariableDesignationSyntax)component; - foreach (var v in t.Variables) AddVariableExpressions(component, expressions); + foreach (VariableDesignationSyntax v in t.Variables) AddVariableExpressions(v, expressions); break; } case SyntaxKind.SingleVariableDesignation: diff --git a/src/Workspaces/CSharp/Portable/Classification/Classifiers/NameSyntaxClassifier.cs b/src/Workspaces/CSharp/Portable/Classification/Classifiers/NameSyntaxClassifier.cs index 90a912c891385..e256961d14487 100644 --- a/src/Workspaces/CSharp/Portable/Classification/Classifiers/NameSyntaxClassifier.cs +++ b/src/Workspaces/CSharp/Portable/Classification/Classifiers/NameSyntaxClassifier.cs @@ -185,7 +185,7 @@ private bool IsInVarContext(NameSyntax name) return name.CheckParent(v => v.Type == name) || name.CheckParent(f => f.Type == name) || - name.CheckParent(f => f.Type == name); + name.CheckParent(f => f.Type == name); } private static ISymbol TryGetSymbol(NameSyntax name, SymbolInfo symbolInfo, SemanticModel semanticModel) diff --git a/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs index c9fea753ce054..7232086bf8c29 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs @@ -2161,12 +2161,13 @@ private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberA return true; } - if (simpleName.IsParentKind(SyntaxKind.TypedVariableComponent)) - { - replacementNode = candidateReplacementNode; - issueSpan = candidateIssueSpan; - return true; - } + //if (simpleName.IsParentKind(SyntaxKind.TypedVariableComponent)) + //{ + // replacementNode = candidateReplacementNode; + // issueSpan = candidateIssueSpan; + // return true; + //} + // TODO REVIEW Are we lacking tests? It seems this code should be needed for DeclarationExpression return false; } diff --git a/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs index bd771dd594069..d7cab5a956616 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ForEachStatementSyntaxExtensions.cs @@ -21,7 +21,8 @@ public static bool IsTypeInferred(this CommonForEachStatementSyntax forEachState case SyntaxKind.ForEachStatement: return ((ForEachStatementSyntax)forEachStatement).Type.IsTypeInferred(semanticModel); case SyntaxKind.ForEachVariableStatement: - return (((ForEachComponentStatementSyntax)forEachStatement).VariableComponent as TypedVariableComponentSyntax)?.Type.IsTypeInferred(semanticModel) == true; + return (((ForEachVariableStatementSyntax)forEachStatement).Variable as DeclarationExpressionSyntax)?.Type + .IsTypeInferred(semanticModel) == true; default: return false; } diff --git a/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs index 39b11da8509f8..7dd46dbbe15ca 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ParenthesizedExpressionSyntaxExtensions.cs @@ -50,7 +50,6 @@ public static bool CanRemoveParentheses(this ParenthesizedExpressionSyntax node) // using ((x)) -> using (x) // catch when ((x)) -> catch when (x) if ((node.IsParentKind(SyntaxKind.EqualsValueClause) && ((EqualsValueClauseSyntax)node.Parent).Value == node) || - (node.IsParentKind(SyntaxKind.VariableComponentAssignment) && ((VariableComponentAssignmentSyntax)node.Parent).Value == node) || (node.IsParentKind(SyntaxKind.IfStatement) && ((IfStatementSyntax)node.Parent).Condition == node) || (node.IsParentKind(SyntaxKind.ReturnStatement) && ((ReturnStatementSyntax)node.Parent).Expression == node) || (node.IsParentKind(SyntaxKind.YieldReturnStatement) && ((YieldStatementSyntax)node.Parent).Expression == node) || diff --git a/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs index ca065b64fe50b..d7f7df570feda 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs @@ -235,8 +235,7 @@ private static bool CanBindToken(SyntaxToken token) else if (current is DeclarationExpressionSyntax) { var decl = (DeclarationExpressionSyntax)current; - var component = decl.VariableComponent as TypedVariableComponentSyntax; - var name = component?.Designation as SingleVariableDesignationSyntax; + var name = decl.Designation as SingleVariableDesignationSyntax; if (name == null) break; return name.Identifier.ValueText.ToCamelCase(); } diff --git a/src/Workspaces/CSharp/Portable/Formatting/FormattingHelpers.cs b/src/Workspaces/CSharp/Portable/Formatting/FormattingHelpers.cs index 8924973a953e3..d2c2fb7e1c236 100644 --- a/src/Workspaces/CSharp/Portable/Formatting/FormattingHelpers.cs +++ b/src/Workspaces/CSharp/Portable/Formatting/FormattingHelpers.cs @@ -580,7 +580,7 @@ public static bool IsOpenParenInVarDeconstructionDeclaration(this SyntaxToken cu { return currentToken.Kind() == SyntaxKind.OpenParenToken && currentToken.Parent is ParenthesizedVariableDesignationSyntax && - currentToken.Parent.Parent is TypedVariableComponentSyntax; + currentToken.Parent.Parent is DeclarationExpressionSyntax; } } } diff --git a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index cbd52c1923f0c..dae1b6011ed26 100644 --- a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -160,7 +160,6 @@ private IEnumerable GetTypesSimple(ExpressionSyntax expressio (SwitchStatementSyntax switchStatement) => InferTypeInSwitchStatement(switchStatement), (ThrowStatementSyntax throwStatement) => InferTypeInThrowStatement(throwStatement), (UsingStatementSyntax usingStatement) => InferTypeInUsingStatement(usingStatement), - (VariableComponentAssignmentSyntax variableComponentAssignment) => InferTypeInVariableComponentAssignment(variableComponentAssignment, expression), (WhileStatementSyntax whileStatement) => InferTypeInWhileStatement(whileStatement), (YieldStatementSyntax yieldStatement) => InferTypeInYieldStatement(yieldStatement), _ => SpecializedCollections.EmptyEnumerable()); @@ -876,6 +875,15 @@ private IEnumerable InferTypeInBinaryOrAssignmentExpression(E return SpecializedCollections.SingletonEnumerable(new TypeInferenceInfo(this.Compilation.GetSpecialType(SpecialType.System_Boolean))); } + // Infer type for deconstruction declaration + if (operatorToken.Kind() == SyntaxKind.EqualsToken && + (left.Kind() == SyntaxKind.TupleExpression || left.Kind() == SyntaxKind.DeclarationExpression)) + { + // TODO REVIEW Once GetTypeInfo works on the left-hand-side expression in a deconstruction declaration, + // this may not be needed + return InferTypeInVariableComponentAssignment(left); + } + // Try to figure out what's on the other side of the binop. If we can, then just that // type. This is often a reasonable heuristics to use for most operators. NOTE(cyrusn): // we could try to bind the token to see what overloaded operators it corresponds to. @@ -1951,31 +1959,24 @@ private IEnumerable InferTypeInVariableDeclarator(VariableDec return types; } - private IEnumerable InferTypeInVariableComponentAssignment( - VariableComponentAssignmentSyntax variableComponentAssigment, ExpressionSyntax expression) + private IEnumerable InferTypeInVariableComponentAssignment(ExpressionSyntax left) { - if (expression == variableComponentAssigment.Value) + if (left.IsKind(SyntaxKind.DeclarationExpression)) { - var variableComponent = variableComponentAssigment.VariableComponent; - if (variableComponent.IsKind(SyntaxKind.TypedVariableComponent)) - { - var typedVariable = (TypedVariableComponentSyntax)variableComponent; - return GetTypes(typedVariable.Type); - } - else if (variableComponent.IsKind(SyntaxKind.ParenthesizedVariableComponent)) - { - // We have something of the form: - // (int a, int b) = ... - // - // This is a deconstruction, and a decent deconstructable type we can infer here - // is ValueTuple. - var parenthesizedVariable = (ParenthesizedVariableComponentSyntax)variableComponent; - var tupleType = GetTupleType(parenthesizedVariable); + return GetTypes(((DeclarationExpressionSyntax)left).Type); + } + else if (left.IsKind(SyntaxKind.TupleExpression)) + { + // We have something of the form: + // (int a, int b) = ... + // + // This is a deconstruction, and a decent deconstructable type we can infer here + // is ValueTuple. + var tupleType = GetTupleType((TupleExpressionSyntax)left); - if (tupleType != null) - { - return SpecializedCollections.SingletonEnumerable(new TypeInferenceInfo(tupleType)); - } + if (tupleType != null) + { + return SpecializedCollections.SingletonEnumerable(new TypeInferenceInfo(tupleType)); } } @@ -1983,13 +1984,12 @@ private IEnumerable InferTypeInVariableDeclarator(VariableDec } private ITypeSymbol GetTupleType( - ParenthesizedVariableComponentSyntax parenthesizedVariableComponent) + TupleExpressionSyntax tuple) { ImmutableArray elementTypes; ImmutableArray elementNames; - if (!TryGetTupleTypesAndNames(parenthesizedVariableComponent.Variables, - out elementTypes, out elementNames)) + if (!TryGetTupleTypesAndNames(tuple.Arguments, out elementTypes, out elementNames)) { return null; } @@ -1998,7 +1998,7 @@ private IEnumerable InferTypeInVariableDeclarator(VariableDec } private bool TryGetTupleTypesAndNames( - SeparatedSyntaxList variables, + SeparatedSyntaxList arguments, out ImmutableArray elementTypes, out ImmutableArray elementNames) { @@ -2009,15 +2009,16 @@ private IEnumerable InferTypeInVariableDeclarator(VariableDec var elementNamesBuilder = ArrayBuilder.GetInstance(); try { - foreach (var component in variables) + foreach (var arg in arguments) { - if (component.IsKind(SyntaxKind.TypedVariableComponent)) + var expr = arg.Expression; + if (expr.IsKind(SyntaxKind.DeclarationExpression)) { - AddTypeAndName((TypedVariableComponentSyntax)component, elementTypesBuilder, elementNamesBuilder); + AddTypeAndName((DeclarationExpressionSyntax)expr, elementTypesBuilder, elementNamesBuilder); } - else if (component.IsKind(SyntaxKind.ParenthesizedVariableComponent)) + else if (expr.IsKind(SyntaxKind.TupleExpression)) { - AddTypeAndName((ParenthesizedVariableComponentSyntax)component, elementTypesBuilder, elementNamesBuilder); + AddTypeAndName((TupleExpressionSyntax)expr, elementTypesBuilder, elementNamesBuilder); } } @@ -2038,13 +2039,13 @@ private IEnumerable InferTypeInVariableDeclarator(VariableDec } private void AddTypeAndName( - TypedVariableComponentSyntax component, - ArrayBuilder elementTypesBuilder, + DeclarationExpressionSyntax declaration, + ArrayBuilder elementTypesBuilder, ArrayBuilder elementNamesBuilder) { - elementTypesBuilder.Add(GetTypes(component.Type).FirstOrDefault().InferredType); + elementTypesBuilder.Add(GetTypes(declaration.Type).FirstOrDefault().InferredType); - var designation = component.Designation; + var designation = declaration.Designation; if (designation.IsKind(SyntaxKind.SingleVariableDesignation)) { var singleVariable = (SingleVariableDesignationSyntax)designation; @@ -2057,11 +2058,11 @@ private IEnumerable InferTypeInVariableDeclarator(VariableDec } private void AddTypeAndName( - ParenthesizedVariableComponentSyntax component, - ArrayBuilder elementTypesBuilder, + TupleExpressionSyntax tuple, + ArrayBuilder elementTypesBuilder, ArrayBuilder elementNamesBuilder) { - var tupleType = GetTupleType(component); + var tupleType = GetTupleType(tuple); elementTypesBuilder.Add(tupleType); elementNamesBuilder.Add(null); } From 31e942139d9b8041de6b43dd609d7c85aeddd4a5 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 4 Nov 2016 17:18:23 -0700 Subject: [PATCH 4/8] Fix issue with EE scenario --- .../ExpressionCompiler/CompilationContext.cs | 2 +- .../ExpressionCompiler/EvaluationContext.cs | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs index 590cb1168de38..95208aaf919d2 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationContext.cs @@ -53,7 +53,7 @@ internal sealed class CompilationContext MethodDebugInfo methodDebugInfo, CSharpSyntaxNode syntax) { - Debug.Assert((syntax == null) || (syntax is ExpressionSyntax) || (syntax is LocalDeclarationStatementSyntax)); + Debug.Assert((syntax == null) || (syntax is ExpressionSyntax) || (syntax is LocalDeclarationStatementSyntax) || (syntax is ExpressionStatementSyntax)); // TODO: syntax.SyntaxTree should probably be added to the compilation, // but it isn't rooted by a CompilationUnitSyntax so it doesn't work (yet). diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs index 4e74717b4c7d9..eacb1dcfbbfc6 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs @@ -12,6 +12,7 @@ using System.Threading; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.ExpressionEvaluator; using Microsoft.DiaSymReader; @@ -301,11 +302,17 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui Debug.Assert((statementSyntax == null) || !statementDiagnostics.HasAnyErrors()); statementDiagnostics.Free(); - if (statementSyntax != null && !statementSyntax.IsKind(SyntaxKind.ExpressionStatement)) // Prefer to parse expression statements as expressions. + // Prefer to parse expression statements (except deconstruction-declarations) as expressions. + var isExpressionStatement = statementSyntax.IsKind(SyntaxKind.ExpressionStatement); + var isDeconstructionDeclaration = isExpressionStatement && + IsDeconstructionDeclaration((ExpressionStatementSyntax)statementSyntax); + + if (statementSyntax != null && (!isExpressionStatement || isDeconstructionDeclaration)) { formatSpecifiers = null; - if (statementSyntax.IsKind(SyntaxKind.LocalDeclarationStatement)) + if (statementSyntax.IsKind(SyntaxKind.LocalDeclarationStatement) || + isDeconstructionDeclaration) { return statementSyntax; } @@ -318,6 +325,15 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui return expr.ParseExpression(diagnostics, allowFormatSpecifiers: true, formatSpecifiers: out formatSpecifiers); } + private static bool IsDeconstructionDeclaration(ExpressionStatementSyntax expressionStatement) + { + if (!expressionStatement.Expression.IsKind(SyntaxKind.SimpleAssignmentExpression)) + { + return false; + } + return ((AssignmentExpressionSyntax)expressionStatement.Expression).IsDeconstructionDeclaration(); + } + internal override CompileResult CompileAssignment( string target, string expr, From 7400a9fbe2f460317f924f6ca6b794d36c046db3 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 7 Nov 2016 10:32:17 -0800 Subject: [PATCH 5/8] PR feedback (1) --- .../Portable/Binder/Binder_Deconstruct.cs | 5 +- .../Binder/ExpressionVariableFinder.cs | 9 ++++ .../Compilation/MemberSemanticModel.cs | 52 +++++++++---------- .../FlowAnalysis/VariablesDeclaredWalker.cs | 10 ++-- .../CSharp/Portable/Parser/LanguageParser.cs | 14 +++++ .../CSharp/Portable/PublicAPI.Unshipped.txt | 12 ++--- .../CSharp/Portable/Syntax/Syntax.xml | 5 +- .../Portable/Syntax/SyntaxExtensions.cs | 9 ++-- .../CSharp/Portable/Syntax/SyntaxFacts.cs | 5 +- .../CSharp/Portable/Syntax/SyntaxKind.cs | 12 ++--- .../Emit/CodeGen/CodeGenDeconstructTests.cs | 34 ++++++++++++ .../Semantic/Semantics/DeconstructionTests.cs | 26 ++-------- .../Test/Semantic/Semantics/OutVarTests.cs | 3 ++ .../Semantics/PatternMatchingTests_Scope.cs | 3 ++ .../ExpressionCompiler/EvaluationContext.cs | 1 + ...CSharpTypeInferenceService.TypeInferrer.cs | 2 - 16 files changed, 127 insertions(+), 75 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs index 900844049d7ca..322bf0061e311 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Deconstruct.cs @@ -16,6 +16,10 @@ namespace Microsoft.CodeAnalysis.CSharp /// internal partial class Binder { + /// + /// Only handles assignment-only or declaration-only deconstructions at this point. + /// Issue https://github.com/dotnet/roslyn/issues/15050 tracks allowing mixed deconstructions + /// private BoundExpression BindDeconstruction(AssignmentExpressionSyntax node, DiagnosticBag diagnostics) { var left = node.Left; @@ -26,7 +30,6 @@ private BoundExpression BindDeconstruction(AssignmentExpressionSyntax node, Diag return BindDeconstructionDeclaration(node, left, right, diagnostics); } - // We only parse assignment-only or declaration-only deconstructions at this point AssertDeconstructionIsAssignment(left); var tuple = (TupleExpressionSyntax)left; diff --git a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs index 8421f63797b38..b10a6c90eb35e 100644 --- a/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ExpressionVariableFinder.cs @@ -445,6 +445,15 @@ protected override LocalSymbol MakeOutVariable(DeclarationExpressionSyntax node, SingleVariableDesignationSyntax designation, AssignmentExpressionSyntax deconstruction) { + NamedTypeSymbol container = _scopeBinder.ContainingType; + + if ((object)container != null && container.IsScriptClass && + (object)_scopeBinder.LookupDeclaredField(designation) != null) + { + // This is a field declaration + return null; + } + return SourceLocalSymbol.MakeDeconstructionLocal( containingSymbol: _scopeBinder.ContainingMemberOrLambda, scopeBinder: _scopeBinder, diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs index ddff5f3fae0af..d3fa565c35c13 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs @@ -252,17 +252,6 @@ private static Binder GetEnclosingBinder(SyntaxNode node, int position, Binder r { binder = rootBinder.GetBinder(current); } - else if ((kind == SyntaxKind.DeclarationExpression || kind == SyntaxKind.TupleExpression) && - (current.Parent as ForEachVariableStatementSyntax)?.Variable == current) - { - binder = rootBinder.GetBinder(current.Parent); - } - else if ((kind == SyntaxKind.DeclarationExpression || kind == SyntaxKind.TupleExpression) && - (current.Parent is AssignmentExpressionSyntax) && - (current.Parent.Parent as ForStatementSyntax)?.Initializers.Contains(current.Parent) == true) - { - binder = rootBinder.GetBinder(current.Parent.Parent); - } else { // If this ever breaks, make sure that all callers of @@ -321,7 +310,8 @@ private static Binder AdjustBinderForPositionWithinStatement(int position, Binde case SyntaxKind.ForEachStatement: case SyntaxKind.ForEachVariableStatement: var foreachStmt = (CommonForEachStatementSyntax)stmt; - if (LookupPosition.IsBetweenTokens(position, foreachStmt.OpenParenToken, foreachStmt.Statement.GetFirstToken())) + var start = stmt.Kind() == SyntaxKind.ForEachVariableStatement ? foreachStmt.InKeyword : foreachStmt.OpenParenToken; + if (LookupPosition.IsBetweenTokens(position, start, foreachStmt.Statement.GetFirstToken())) { binder = binder.GetBinder(foreachStmt.Expression); Debug.Assert(binder != null); @@ -1457,7 +1447,7 @@ private static Binder GetQueryEnclosingBinder(int position, CSharpSyntaxNode sta } } - done: +done: return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, queryClause.Syntax), position, queryClause.Binder, queryClause.Syntax); } @@ -1690,28 +1680,34 @@ internal protected virtual CSharpSyntaxNode GetBindableSyntaxNode(CSharpSyntaxNo /// If this declaration is part of a deconstruction, find the deconstruction. /// Returns null otherwise. /// - private AssignmentExpressionSyntax GetContainingDeconstruction(ExpressionSyntax expr) + private static AssignmentExpressionSyntax GetContainingDeconstruction(ExpressionSyntax expr) { - Debug.Assert(expr.Kind() == SyntaxKind.TupleExpression || expr.Kind() == SyntaxKind.DeclarationExpression); - - if (expr.Parent.Kind() == SyntaxKind.Argument) + while (true) { - if (expr.Parent.Parent.Kind() == SyntaxKind.TupleExpression) + Debug.Assert(expr.Kind() == SyntaxKind.TupleExpression || expr.Kind() == SyntaxKind.DeclarationExpression); + var parent = expr.Parent; + if (parent == null) { return null; } + + if (parent.Kind() == SyntaxKind.Argument) { - return GetContainingDeconstruction((TupleExpressionSyntax)expr.Parent.Parent); + if (parent.Parent?.Kind() == SyntaxKind.TupleExpression) + { + expr = (TupleExpressionSyntax)parent.Parent; + continue; + } + else + { + return null; + } } - else + else if (parent.Kind() == SyntaxKind.SimpleAssignmentExpression && + (object)((AssignmentExpressionSyntax)parent).Left == expr) { - return null; + return (AssignmentExpressionSyntax)parent; } - } - else if (expr.Parent.Kind() == SyntaxKind.SimpleAssignmentExpression && - (object)((AssignmentExpressionSyntax)expr.Parent).Left == expr) - { - return (AssignmentExpressionSyntax)expr.Parent; - } - return null; + return null; + } } /// diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs index 1ada036ea507a..502d282d9ee69 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs @@ -170,10 +170,14 @@ protected override void VisitLvalue(BoundLocal node) private void CheckOutVarDeclaration(BoundLocal node) { if (IsInside && - !node.WasCompilerGenerated && node.Syntax.Kind() == SyntaxKind.DeclarationExpression && - ((SingleVariableDesignationSyntax)((DeclarationExpressionSyntax)node.Syntax).Designation).Identifier == node.LocalSymbol.IdentifierToken) + !node.WasCompilerGenerated && node.Syntax.Kind() == SyntaxKind.DeclarationExpression) { - _variablesDeclared.Add(node.LocalSymbol); + var declaration = (DeclarationExpressionSyntax)node.Syntax; + if (((SingleVariableDesignationSyntax)declaration.Designation).Identifier == node.LocalSymbol.IdentifierToken && + ((ArgumentSyntax)declaration.Parent).RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword) + { + _variablesDeclared.Add(node.LocalSymbol); + } } } diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 51ace3a34fa98..3b3ed301b1cda 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -11,6 +11,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax { using Microsoft.CodeAnalysis.Syntax.InternalSyntax; + using System.Linq; internal partial class LanguageParser : SyntaxParser { @@ -7534,6 +7535,19 @@ private StatementSyntax ParseEmbeddedStatement(bool complexCheck) case SyntaxKind.LocalFunctionStatement: statement = this.AddError(statement, ErrorCode.ERR_BadEmbeddedStmt); break; + case SyntaxKind.ExpressionStatement: + // Deconstruction-declaration is only allowed as top-level statement + // see https://github.com/dotnet/roslyn/issues/15049 + var expression = ((ExpressionStatementSyntax)statement).Expression; + if (expression.Kind == SyntaxKind.SimpleAssignmentExpression) + { + var assignment = (AssignmentExpressionSyntax)expression; + if (assignment.Left.EnumerateNodes().Any(x => x.RawKind == (int)SyntaxKind.DeclarationExpression)) + { + statement = this.AddError(statement, ErrorCode.ERR_BadEmbeddedStmt); + } + } + break; } return statement; diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index e3959c6129d36..dc898854a46c6 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -157,17 +157,17 @@ Microsoft.CodeAnalysis.CSharp.SyntaxKind.CasePatternSwitchLabel = 9009 -> Micros Microsoft.CodeAnalysis.CSharp.SyntaxKind.ConstantPattern = 9002 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.DeclarationExpression = 9040 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.DeclarationPattern = 9000 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.ForEachVariableStatement = 8934 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.ForEachVariableStatement = 8929 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.IsPatternExpression = 8657 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.LocalFunctionStatement = 8830 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.ParenthesizedVariableDesignation = 8931 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.ParenthesizedVariableDesignation = 8928 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.RefExpression = 9050 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.RefType = 9051 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleVariableDesignation = 8930 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.SingleVariableDesignation = 8927 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.ThrowExpression = 9052 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleElement = 8926 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleExpression = 8927 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind -Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleType = 8925 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleElement = 8925 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleExpression = 8926 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind +Microsoft.CodeAnalysis.CSharp.SyntaxKind.TupleType = 8924 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind Microsoft.CodeAnalysis.CSharp.SyntaxKind.WhenClause = 9013 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind abstract Microsoft.CodeAnalysis.CSharp.Syntax.BaseMethodDeclarationSyntax.ExpressionBody.get -> Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax abstract Microsoft.CodeAnalysis.CSharp.Syntax.CommonForEachStatementSyntax.CloseParenToken.get -> Microsoft.CodeAnalysis.SyntaxToken diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index 9a7ccaf2a99c1..f156a84e9133b 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -2110,7 +2110,10 @@ - + + + + diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs index dc9d9761078e9..33a7df4b0cdd4 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs @@ -206,7 +206,10 @@ internal static SyntaxNode SkipParens(this SyntaxNode expression) return expression; } - private static bool IsDeconstructionDeclaration(this ExpressionSyntax self) + /// + /// Is this expression composed only of declaration expressions nested in tuple expressions? + /// + private static bool IsDeconstructionDeclarationLeft(this ExpressionSyntax self) { switch (self.Kind()) { @@ -214,7 +217,7 @@ private static bool IsDeconstructionDeclaration(this ExpressionSyntax self) return true; case SyntaxKind.TupleExpression: var tuple = (TupleExpressionSyntax)self; - return tuple.Arguments.All(a => IsDeconstructionDeclaration(a.Expression)); + return tuple.Arguments.All(a => IsDeconstructionDeclarationLeft(a.Expression)); default: return false; } @@ -222,7 +225,7 @@ private static bool IsDeconstructionDeclaration(this ExpressionSyntax self) internal static bool IsDeconstructionDeclaration(this AssignmentExpressionSyntax self) { - return self.Left.IsDeconstructionDeclaration(); + return self.Left.IsDeconstructionDeclarationLeft(); } private static bool IsInContextWhichNeedsDynamicAttribute(CSharpSyntaxNode node) diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs index ab293071094ee..e320389a42bbd 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFacts.cs @@ -401,9 +401,8 @@ internal static bool IsVarOrPredefinedType(this Syntax.InternalSyntax.SyntaxToke internal static bool IsDeclarationExpressionType(SyntaxNode node, out DeclarationExpressionSyntax parent) { - var component = node.Parent as DeclarationExpressionSyntax; - parent = component as DeclarationExpressionSyntax; - return node == component?.Type; + parent = node.Parent as DeclarationExpressionSyntax; + return node == parent?.Type; } } } \ No newline at end of file diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs index 217dc04c617d0..670594c473c54 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs @@ -539,12 +539,12 @@ public enum SyntaxKind : ushort // Changes after C# 6 // tuples - TupleType = 8925, - TupleElement = 8926, - TupleExpression = 8927, - SingleVariableDesignation = 8930, - ParenthesizedVariableDesignation = 8931, - ForEachVariableStatement = 8934, + TupleType = 8924, + TupleElement = 8925, + TupleExpression = 8926, + SingleVariableDesignation = 8927, + ParenthesizedVariableDesignation = 8928, + ForEachVariableStatement = 8929, // patterns (for pattern-matching) DeclarationPattern = 9000, diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs index 274eebdfd4d75..4adb04a7b7f43 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs @@ -1163,6 +1163,40 @@ public void Deconstruct(out int a, out int b) ); } + [Fact] + public void MixedDeconstructionCannotBeParsed() + { + string source = @" +class C +{ + public static void Main() + { + int x; + (x, int y) = new C(); + } + + public void Deconstruct(out int a, out int b) + { + a = 1; + b = 2; + } +} +"; + + var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }); + comp.VerifyDiagnostics( + // (7,10): error CS1031: Type expected + // (x, int y) = new C(); + Diagnostic(ErrorCode.ERR_TypeExpected, "x").WithLocation(7, 10), + // (7,10): error CS0128: A local variable or function named 'x' is already defined in this scope + // (x, int y) = new C(); + Diagnostic(ErrorCode.ERR_LocalDuplicate, "x").WithArguments("x").WithLocation(7, 10), + // (6,13): warning CS0168: The variable 'x' is declared but never used + // int x; + Diagnostic(ErrorCode.WRN_UnreferencedVar, "x").WithArguments("x").WithLocation(6, 13) + ); + } + [Fact] public void DeconstructionWithTupleNamesCannotBeParsed() { diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs index 0ea0808711de5..6af5812985acd 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs @@ -2434,7 +2434,7 @@ static void Test(int arg1, (byte, byte) arg2) } [Fact] - public void DeclarationCanBeEmbedded() + public void DeclarationCannotBeEmbedded() { var source = @" class C1 @@ -2445,30 +2445,12 @@ void M() var (x, y) = (1, 2); } } -"; - var comp = CreateCompilationWithMscorlib(source, references: s_valueTupleRefs); - comp.VerifyDiagnostics(); - } - - [Fact] - public void EmbeddedDeclarationIsScoped() - { - var source = @" -class C1 -{ - void M() - { - if (true) - var (x, y) = (1, 2); - System.Console.WriteLine(x); - } -} "; var comp = CreateCompilationWithMscorlib(source, references: s_valueTupleRefs); comp.VerifyDiagnostics( - // (8,34): error CS0103: The name 'x' does not exist in the current context - // System.Console.WriteLine(x); - Diagnostic(ErrorCode.ERR_NameNotInContext, "x").WithArguments("x").WithLocation(8, 34) + // (7,13): error CS1023: Embedded statement cannot be a declaration or labeled statement + // var (x, y) = (1, 2); + Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "var (x, y) = (1, 2);").WithLocation(7, 13) ); } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs index 345d8dfe24d94..6754ed0a7d027 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs @@ -8981,6 +8981,9 @@ static bool TakeOutParam(object y, out object x) var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation.VerifyDiagnostics( + // (11,13): error CS1023: Embedded statement cannot be a declaration or labeled statement + // var (d, dd) = (TakeOutParam(true, out var x1), x1); + Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "var (d, dd) = (TakeOutParam(true, out var x1), x1);").WithLocation(11, 13), // (13,9): error CS0103: The name 'x1' does not exist in the current context // x1++; Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(13, 9) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs index d0e1ea399ef10..6c75f3301f6c9 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs @@ -6756,6 +6756,9 @@ void Test1() var compilation = CreateCompilationWithMscorlib45(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation.VerifyDiagnostics( + // (11,13): error CS1023: Embedded statement cannot be a declaration or labeled statement + // var (d, dd) = ((true is var x1), x1); + Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "var (d, dd) = ((true is var x1), x1);").WithLocation(11, 13), // (13,9): error CS0103: The name 'x1' does not exist in the current context // x1++; Diagnostic(ErrorCode.ERR_NameNotInContext, "x1").WithArguments("x1").WithLocation(13, 9) diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs index eacb1dcfbbfc6..2402708b8a884 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EvaluationContext.cs @@ -303,6 +303,7 @@ private static MethodSymbol GetSynthesizedMethod(CommonPEModuleBuilder moduleBui statementDiagnostics.Free(); // Prefer to parse expression statements (except deconstruction-declarations) as expressions. + // Once https://github.com/dotnet/roslyn/issues/15049 is fixed, we should parse d-declarations as expressions. var isExpressionStatement = statementSyntax.IsKind(SyntaxKind.ExpressionStatement); var isDeconstructionDeclaration = isExpressionStatement && IsDeconstructionDeclaration((ExpressionStatementSyntax)statementSyntax); diff --git a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index dae1b6011ed26..9f3adf5152a86 100644 --- a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -879,8 +879,6 @@ private IEnumerable InferTypeInBinaryOrAssignmentExpression(E if (operatorToken.Kind() == SyntaxKind.EqualsToken && (left.Kind() == SyntaxKind.TupleExpression || left.Kind() == SyntaxKind.DeclarationExpression)) { - // TODO REVIEW Once GetTypeInfo works on the left-hand-side expression in a deconstruction declaration, - // this may not be needed return InferTypeInVariableComponentAssignment(left); } From d5bede6863a9e8af7984e812111b0e30ed676573 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 8 Nov 2016 11:55:39 -0800 Subject: [PATCH 6/8] PR feedback (2) --- .../FlowAnalysis/VariablesDeclaredWalker.cs | 5 +++- .../CSharp/Portable/Parser/LanguageParser.cs | 25 +++++++++++++++++-- .../CSharp/Portable/PublicAPI.Unshipped.txt | 1 - .../CSharp/Portable/Syntax/Syntax.xml | 2 +- .../Semantic/Semantics/DeconstructionTests.cs | 18 +++++++++++++ ...onsService.RelevantExpressionsCollector.cs | 1 - .../Extensions/ExpressionSyntaxExtensions.cs | 8 ------ 7 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs index 502d282d9ee69..d21a75dfad64b 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/VariablesDeclaredWalker.cs @@ -173,7 +173,10 @@ private void CheckOutVarDeclaration(BoundLocal node) !node.WasCompilerGenerated && node.Syntax.Kind() == SyntaxKind.DeclarationExpression) { var declaration = (DeclarationExpressionSyntax)node.Syntax; - if (((SingleVariableDesignationSyntax)declaration.Designation).Identifier == node.LocalSymbol.IdentifierToken && + if (declaration.Designation.Kind() == SyntaxKind.SingleVariableDesignation && + ((SingleVariableDesignationSyntax)declaration.Designation).Identifier == node.LocalSymbol.IdentifierToken && + declaration.Parent != null && + declaration.Parent.Kind() == SyntaxKind.Argument && ((ArgumentSyntax)declaration.Parent).RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword) { _variablesDeclared.Add(node.LocalSymbol); diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 3b3ed301b1cda..b05b4e5c2c176 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -11,7 +11,6 @@ namespace Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax { using Microsoft.CodeAnalysis.Syntax.InternalSyntax; - using System.Linq; internal partial class LanguageParser : SyntaxParser { @@ -7542,7 +7541,7 @@ private StatementSyntax ParseEmbeddedStatement(bool complexCheck) if (expression.Kind == SyntaxKind.SimpleAssignmentExpression) { var assignment = (AssignmentExpressionSyntax)expression; - if (assignment.Left.EnumerateNodes().Any(x => x.RawKind == (int)SyntaxKind.DeclarationExpression)) + if (IsDeconstructionDeclarationLeft(assignment.Left)) { statement = this.AddError(statement, ErrorCode.ERR_BadEmbeddedStmt); } @@ -8668,6 +8667,28 @@ private static bool TypeFoundInDeconstructionDeclarationVariables(ExpressionSynt } } + /// + /// Returns true if the expression is composed only of nested tuple and declaration expressions. + /// + private static bool IsDeconstructionDeclarationLeft(ExpressionSyntax node) + { + switch (node.Kind) + { + case SyntaxKind.TupleExpression: + var arguments = ((TupleExpressionSyntax)node).Arguments; + for (int i = 0; i < arguments.Count; i++) + { + if (!IsDeconstructionDeclarationLeft(arguments[i].Expression)) return false; + } + + return true; + case SyntaxKind.DeclarationExpression: + return true; + default: + return false; + } + } + private VariableDesignationSyntax ParseDeconstructionDesignation(bool topLevel = false) { // the two forms of designation are diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt index dc898854a46c6..2758e7b4a85e3 100644 --- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt @@ -263,7 +263,6 @@ static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Micros static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax initializer, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ConstructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorInitializerSyntax initializer, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody, Microsoft.CodeAnalysis.SyntaxToken semicolonToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax -static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeclarationExpression(Microsoft.CodeAnalysis.CSharp.Syntax.VariableDesignationSyntax designation) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationExpressionSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DeclarationPattern(Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier) -> Microsoft.CodeAnalysis.CSharp.Syntax.DeclarationPatternSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.DestructorDeclaration(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax body, Microsoft.CodeAnalysis.CSharp.Syntax.ArrowExpressionClauseSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax diff --git a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml index f156a84e9133b..deb3bc1265830 100644 --- a/src/Compilers/CSharp/Portable/Syntax/Syntax.xml +++ b/src/Compilers/CSharp/Portable/Syntax/Syntax.xml @@ -1131,7 +1131,7 @@ - + Declaration representing the variable declared in an out parameter or deconstruction. diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs index 6af5812985acd..3f6ad8d3e8986 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs @@ -2454,6 +2454,24 @@ void M() ); } + [Fact] + public void AssignmentExpressionCanBeUsedInEmbeddedStatement() + { + var source = @" +class C1 +{ + void M() + { + int x, y; + if (true) + (x, y) = (1, 2); + } +} +"; + var comp = CreateCompilationWithMscorlib(source, references: s_valueTupleRefs); + comp.VerifyDiagnostics(); + } + [Fact] public void DeconstructObsoleteWarning() { diff --git a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs index 3a1f6c1374bf3..f52cde4ce8696 100644 --- a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs +++ b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs @@ -136,7 +136,6 @@ public override void VisitSwitchStatement(SwitchStatementSyntax node) { var t = (TupleExpressionSyntax)component; foreach (ArgumentSyntax a in t.Arguments) AddVariableExpressions(a.Expression, expressions); - // TODO REVIEW I think there was a bug there. Are we missing tests? break; } case SyntaxKind.DeclarationExpression: diff --git a/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs index 7232086bf8c29..d2988bbc1ca93 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ExpressionSyntaxExtensions.cs @@ -2161,14 +2161,6 @@ private static bool IsThisOrTypeOrNamespace(MemberAccessExpressionSyntax memberA return true; } - //if (simpleName.IsParentKind(SyntaxKind.TypedVariableComponent)) - //{ - // replacementNode = candidateReplacementNode; - // issueSpan = candidateIssueSpan; - // return true; - //} - // TODO REVIEW Are we lacking tests? It seems this code should be needed for DeclarationExpression - return false; } From 7e4ea6efb73e58128ec26b645de53bc444583227 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 8 Nov 2016 12:16:44 -0800 Subject: [PATCH 7/8] Moving IsDeconstructionDeclarationLeft method --- .../CSharp/Portable/Parser/LanguageParser.cs | 24 +------------------ .../Portable/Syntax/SyntaxExtensions.cs | 22 +++++++++++++++++ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index b05b4e5c2c176..e3ad397ba8b2a 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -7541,7 +7541,7 @@ private StatementSyntax ParseEmbeddedStatement(bool complexCheck) if (expression.Kind == SyntaxKind.SimpleAssignmentExpression) { var assignment = (AssignmentExpressionSyntax)expression; - if (IsDeconstructionDeclarationLeft(assignment.Left)) + if (assignment.Left.IsDeconstructionDeclarationLeft()) { statement = this.AddError(statement, ErrorCode.ERR_BadEmbeddedStmt); } @@ -8667,28 +8667,6 @@ private static bool TypeFoundInDeconstructionDeclarationVariables(ExpressionSynt } } - /// - /// Returns true if the expression is composed only of nested tuple and declaration expressions. - /// - private static bool IsDeconstructionDeclarationLeft(ExpressionSyntax node) - { - switch (node.Kind) - { - case SyntaxKind.TupleExpression: - var arguments = ((TupleExpressionSyntax)node).Arguments; - for (int i = 0; i < arguments.Count; i++) - { - if (!IsDeconstructionDeclarationLeft(arguments[i].Expression)) return false; - } - - return true; - case SyntaxKind.DeclarationExpression: - return true; - default: - return false; - } - } - private VariableDesignationSyntax ParseDeconstructionDesignation(bool topLevel = false) { // the two forms of designation are diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs index 33a7df4b0cdd4..965ec4b2db4e6 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxExtensions.cs @@ -223,6 +223,28 @@ private static bool IsDeconstructionDeclarationLeft(this ExpressionSyntax self) } } + /// + /// Returns true if the expression is composed only of nested tuple and declaration expressions. + /// + internal static bool IsDeconstructionDeclarationLeft(this Syntax.InternalSyntax.ExpressionSyntax node) + { + switch (node.Kind) + { + case SyntaxKind.TupleExpression: + var arguments = ((Syntax.InternalSyntax.TupleExpressionSyntax)node).Arguments; + for (int i = 0; i < arguments.Count; i++) + { + if (!IsDeconstructionDeclarationLeft(arguments[i].Expression)) return false; + } + + return true; + case SyntaxKind.DeclarationExpression: + return true; + default: + return false; + } + } + internal static bool IsDeconstructionDeclaration(this AssignmentExpressionSyntax self) { return self.Left.IsDeconstructionDeclarationLeft(); From d39e75ee13984c89b96f74b7f0941c524afa9994 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Tue, 8 Nov 2016 13:58:15 -0800 Subject: [PATCH 8/8] IDE feedback (1) --- .../CSharpEditAndContinueAnalyzer.cs | 12 +++------- ...onsService.RelevantExpressionsCollector.cs | 6 ++++- .../CSharp/Portable/CSharpWorkspace.csproj | 1 + .../AssignmentExpressionSyntaxExtensions.cs | 24 +++++++++++++++++++ .../Extensions/SemanticModelExtensions.cs | 6 ++++- ...CSharpTypeInferenceService.TypeInferrer.cs | 6 ++--- 6 files changed, 41 insertions(+), 14 deletions(-) create mode 100644 src/Workspaces/CSharp/Portable/Extensions/AssignmentExpressionSyntaxExtensions.cs diff --git a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index 6bf26ef17ab71..9a7a7682ea0c7 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -1608,13 +1608,13 @@ internal static string GetStatementDisplayNameImpl(SyntaxNode node) return CSharpFeaturesResources.deconstruction; case SyntaxKind.SimpleAssignmentExpression: - if (IsDeconstruction((AssignmentExpressionSyntax)node)) + if (((AssignmentExpressionSyntax)node).IsDeconstruction()) { return CSharpFeaturesResources.deconstruction; } else { - goto default; + throw ExceptionUtilities.UnexpectedValue(node.Kind()); } case SyntaxKind.TupleType: @@ -3119,18 +3119,12 @@ private static bool IsUnsupportedCSharp7EnCNode(SyntaxNode n) case SyntaxKind.DeclarationPattern: return true; case SyntaxKind.SimpleAssignmentExpression: - return IsDeconstruction((AssignmentExpressionSyntax)n); + return ((AssignmentExpressionSyntax)n).IsDeconstruction(); default: return false; } } - private static bool IsDeconstruction(AssignmentExpressionSyntax assignment) - { - return assignment.Left.Kind() == SyntaxKind.TupleExpression || - assignment.Left.Kind() == SyntaxKind.DeclarationExpression; - } - private void ReportRudeEditsForCheckedStatements( List diagnostics, SyntaxNode oldActiveStatement, diff --git a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs index f52cde4ce8696..acf6f98f485d5 100644 --- a/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs +++ b/src/VisualStudio/CSharp/Impl/Debugging/CSharpProximityExpressionsService.RelevantExpressionsCollector.cs @@ -135,7 +135,11 @@ public override void VisitSwitchStatement(SwitchStatementSyntax node) case SyntaxKind.TupleExpression: { var t = (TupleExpressionSyntax)component; - foreach (ArgumentSyntax a in t.Arguments) AddVariableExpressions(a.Expression, expressions); + foreach (ArgumentSyntax a in t.Arguments) + { + AddVariableExpressions(a.Expression, expressions); + } + break; } case SyntaxKind.DeclarationExpression: diff --git a/src/Workspaces/CSharp/Portable/CSharpWorkspace.csproj b/src/Workspaces/CSharp/Portable/CSharpWorkspace.csproj index a5e23d9d30768..8efaa424b2f5b 100644 --- a/src/Workspaces/CSharp/Portable/CSharpWorkspace.csproj +++ b/src/Workspaces/CSharp/Portable/CSharpWorkspace.csproj @@ -95,6 +95,7 @@ + diff --git a/src/Workspaces/CSharp/Portable/Extensions/AssignmentExpressionSyntaxExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/AssignmentExpressionSyntaxExtensions.cs new file mode 100644 index 0000000000000..c22ec4cf86c2e --- /dev/null +++ b/src/Workspaces/CSharp/Portable/Extensions/AssignmentExpressionSyntaxExtensions.cs @@ -0,0 +1,24 @@ +// 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.Linq; +using System.Threading; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Text; + +namespace Microsoft.CodeAnalysis.CSharp.Extensions +{ + internal static class AssignmentExpressionSyntaxExtensions + { + internal static bool IsDeconstruction(this AssignmentExpressionSyntax assignment) + { + var left = assignment.Left; + return assignment.Kind() == SyntaxKind.SimpleAssignmentExpression && + assignment.OperatorToken.Kind() == SyntaxKind.EqualsToken && + (left.Kind() == SyntaxKind.TupleExpression || left.Kind() == SyntaxKind.DeclarationExpression); + } + } +} diff --git a/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs index d7f7df570feda..c9005c2cbb1bd 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/SemanticModelExtensions.cs @@ -236,7 +236,11 @@ private static bool CanBindToken(SyntaxToken token) { var decl = (DeclarationExpressionSyntax)current; var name = decl.Designation as SingleVariableDesignationSyntax; - if (name == null) break; + if (name == null) + { + break; + } + return name.Identifier.ValueText.ToCamelCase(); } else diff --git a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index 9f3adf5152a86..8c9dea1c71dc1 100644 --- a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -875,9 +875,9 @@ private IEnumerable InferTypeInBinaryOrAssignmentExpression(E return SpecializedCollections.SingletonEnumerable(new TypeInferenceInfo(this.Compilation.GetSpecialType(SpecialType.System_Boolean))); } - // Infer type for deconstruction declaration - if (operatorToken.Kind() == SyntaxKind.EqualsToken && - (left.Kind() == SyntaxKind.TupleExpression || left.Kind() == SyntaxKind.DeclarationExpression)) + // Infer type for deconstruction + if (binop.Kind() == SyntaxKind.SimpleAssignmentExpression && + ((AssignmentExpressionSyntax)binop).IsDeconstruction()) { return InferTypeInVariableComponentAssignment(left); }