Skip to content

Commit

Permalink
PR feedback (4)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv committed Jun 23, 2016
1 parent db860b6 commit e96585a
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7780,7 +7780,7 @@ private ForStatementSyntax ParseForStatement()
}
else if (decl == null)
{
// Not a type followed by an identifier, so it must be an expression list.
// Not a type followed by an identifier, and not a deconstruction-declaration, so it must be an expression list.
if (this.CurrentToken.Kind != SyntaxKind.SemicolonToken)
{
this.ParseForStatementExpressionList(ref openParen, initializers);
Expand Down Expand Up @@ -8585,10 +8585,11 @@ private bool IsPossibleDeconstructionDeclaration()
var resetPoint = this.GetResetPoint();
try
{
// We don't need to parse the expression following the equals token
var variables = ParseDeconstructionDeclaration(withEquals: false);
var equalsToken = this.EatToken(SyntaxKind.EqualsToken);

// We need the equals token and one other confirmation that this is a deconstruction syntax
// We just need the equals token and one other confirmation that this is a deconstruction syntax
return DeconstructionVariableLooksGood(variables, withEquals: false) && !equalsToken.IsMissing;
}
finally
Expand Down Expand Up @@ -8620,7 +8621,8 @@ private static bool DeconstructionVariableLooksGood(VariableDeclarationSyntax no

if (node.Type != null)
{
if (node.Type.Kind == SyntaxKind.IdentifierName && ((IdentifierNameSyntax)node.Type).Identifier.IsVar() && node.Deconstruction != null && !node.Deconstruction.OpenParenToken.IsMissing && !node.Deconstruction.CloseParenToken.IsMissing)
if (node.Type.Kind == SyntaxKind.IdentifierName && ((IdentifierNameSyntax)node.Type).Identifier.IsVar()
&& node.Deconstruction != null && !node.Deconstruction.OpenParenToken.IsMissing && !node.Deconstruction.CloseParenToken.IsMissing)
{
// `var (..., ....)` with var and both parens present
return true;
Expand Down
46 changes: 46 additions & 0 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2577,5 +2577,51 @@ static void Main()
// expect ERR_DeconstructTooFewElements
);
}

[Fact]
public void DeconstructionDeclarationInCSharp6()
{
string source = @"
class C
{
static void Main()
{
var (x1, x2) = null;
//(int x3, int x4) = null;
//foreach ((int x5, var (x6, x7)) in null) { }
//for ((int x8, var (x9, x10)) = null; ; ) { }
}
}
";

// PROTOTYPE(tuples) uncomment above once binding is fixed
var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular);
comp.VerifyDiagnostics(
// (6,9): error CS8058: Feature 'tuples' is experimental and unsupported; use '/features:tuples' to enable.
// var (x1, x2) = null;
Diagnostic(ErrorCode.ERR_FeatureIsExperimental, "var (x1, x2) = null").WithArguments("tuples", "tuples").WithLocation(6, 9)
);
}

[Fact]
public void DeconstructionDeclarationInCSharp7()
{
string source = @"
class C
{
static void Main()
{
var (x1, x2) = null;
//(int x3, int x4) = null;
//foreach ((int x5, var (x6, x7)) in null) { }
//for ((int x8, var (x9, x10)) = null; ; ) { }
}
}
";

// PROTOTYPE(tuples) uncomment above once binding is fixed
var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef }, parseOptions: TestOptions.Regular.WithTuplesFeature());
comp.VerifyDiagnostics();
}
}
}
75 changes: 75 additions & 0 deletions src/Compilers/CSharp/Test/Syntax/Parsing/DeconstructionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,81 @@ void Foo()
EOF();
}

[Fact]
public void SimpleDeclaration()
{
var tree = UsingTree(@"
class C
{
void Foo()
{
for(Int32 x = foo; ; ) { }
}
}", options: TestOptions.Regular.WithTuplesFeature());
N(SyntaxKind.CompilationUnit);
{
N(SyntaxKind.ClassDeclaration);
{
N(SyntaxKind.ClassKeyword);
N(SyntaxKind.IdentifierToken, "C");
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.MethodDeclaration);
{
N(SyntaxKind.PredefinedType);
{
N(SyntaxKind.VoidKeyword);
}
N(SyntaxKind.IdentifierToken, "Foo");
N(SyntaxKind.ParameterList);
{
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.CloseParenToken);
}
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.ForStatement);
{
N(SyntaxKind.ForKeyword);
N(SyntaxKind.OpenParenToken);
N(SyntaxKind.VariableDeclaration);
{
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "Int32");
}
N(SyntaxKind.VariableDeclarator);
{
N(SyntaxKind.IdentifierToken, "x");
N(SyntaxKind.EqualsValueClause);
{
N(SyntaxKind.EqualsToken);
N(SyntaxKind.IdentifierName);
{
N(SyntaxKind.IdentifierToken, "foo");
}
}
}
}
N(SyntaxKind.SemicolonToken);
N(SyntaxKind.SemicolonToken);
N(SyntaxKind.CloseParenToken);
N(SyntaxKind.Block);
{
N(SyntaxKind.OpenBraceToken);
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
}
N(SyntaxKind.CloseBraceToken);
}
N(SyntaxKind.EndOfFileToken);
}
EOF();
}

[Fact]
public void NestedDeconstructionAssignment()
{
Expand Down

0 comments on commit e96585a

Please sign in to comment.