提交 758e1591 编写于 作者: J Julien 提交者: GitHub

Handling remaining PROTOTYPE markers in features/tuples branch (#12411)

上级 1cf2e50f
......@@ -21,7 +21,7 @@ private BoundExpression BindDeconstructionAssignment(AssignmentExpressionSyntax
var left = (TupleExpressionSyntax)node.Left;
ArrayBuilder<DeconstructionVariable> checkedVariables = BindDeconstructionAssignmentVariables(left.Arguments, left, diagnostics);
var result = BindDeconstructionAssignment(node, node.Right, checkedVariables, diagnostics);
var result = BindDeconstructionAssignment(node, node.Right, checkedVariables, diagnostics, isDeclaration: false);
FreeDeconstructionVariables(checkedVariables);
return result;
......@@ -47,7 +47,7 @@ private static void FreeDeconstructionVariables(ArrayBuilder<DeconstructionVaria
/// Deconstruct steps for tuples have no invocation to Deconstruct, but steps for non-tuples do.
/// The caller is responsible for releasing all the ArrayBuilders in checkedVariables.
/// </summary>
private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment(CSharpSyntaxNode node, ExpressionSyntax right, ArrayBuilder<DeconstructionVariable> checkedVariables, DiagnosticBag diagnostics, BoundDeconstructValuePlaceholder rhsPlaceholder = null)
private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment(CSharpSyntaxNode node, ExpressionSyntax right, ArrayBuilder<DeconstructionVariable> checkedVariables, DiagnosticBag diagnostics, bool isDeclaration, BoundDeconstructValuePlaceholder rhsPlaceholder = null)
{
TypeSymbol voidType = GetSpecialType(SpecialType.System_Void, diagnostics, node);
......@@ -56,7 +56,7 @@ private BoundDeconstructionAssignmentOperator BindDeconstructionAssignment(CShar
if ((object)boundRHS.Type == null)
{
if (boundRHS.Kind == BoundKind.TupleLiteral)
if (boundRHS.Kind == BoundKind.TupleLiteral && !isDeclaration)
{
// tuple literal without type such as `(null, null)`, let's fix it up by peeking at the LHS
TypeSymbol lhsAsTuple = MakeTupleTypeFromDeconstructionLHS(checkedVariables, diagnostics, Compilation);
......@@ -496,7 +496,7 @@ internal BoundDeconstructionAssignmentOperator BindDeconstructionDeclaration(CSh
{
ArrayBuilder<DeconstructionVariable> locals = BindDeconstructionDeclarationLocals(declaration, declaration.Type, diagnostics);
var result = BindDeconstructionAssignment(node, right, locals, diagnostics, rightPlaceholder);
var result = BindDeconstructionAssignment(node, right, locals, diagnostics, isDeclaration: true, rhsPlaceholder: rightPlaceholder);
FreeDeconstructionVariables(locals);
return result;
......
......@@ -761,7 +761,10 @@
<Compile Include="Syntax\DeclarationStatementSyntax.cs" />
<Compile Include="Syntax\DelegateDeclarationSyntax.cs" />
<Compile Include="Syntax\DirectiveTriviaSyntax.cs" />
<Compile Include="Syntax\EventFieldDeclarationSyntax.cs" />
<Compile Include="Syntax\ExpressionStatementSyntax.cs" />
<Compile Include="Syntax\FieldDeclarationSyntax.cs" />
<Compile Include="Syntax\FixedStatementSyntax.cs" />
<Compile Include="Syntax\ForEachStatementSyntax.cs" />
<Compile Include="Syntax\GenericNameSyntax.cs" />
<Compile Include="Syntax\InternalSyntax\BinaryExpressionSyntax.cs" />
......
......@@ -73,7 +73,6 @@ private ImmutableArray<BoundExpression> LeftHandSideSideEffects(ImmutableArray<B
foreach (var variable in variables)
{
// PROTOTYPE(tuples) should the dynamic flag always be false?
lhsReceivers.Add(TransformCompoundAssignmentLHS(variable, stores, temps, isDynamicAssignment: false));
}
......
......@@ -8558,7 +8558,6 @@ private VariableDeclarationSyntax ParseDeconstructionTypeIdPart()
/// <summary>
/// Check ahead for a deconstruction declaration. This requires at least one good-looking variable and the presence of an equals sign.
/// Doesn't move the cursor.
/// PROTOTYPE(tuples) Can this be done without allocations?
/// </summary>
private bool IsPossibleDeconstructionDeclaration()
{
......

namespace Microsoft.CodeAnalysis.CSharp.Syntax
{
public sealed partial class EventFieldDeclarationSyntax : BaseFieldDeclarationSyntax
{
public EventFieldDeclarationSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
}
\ No newline at end of file

namespace Microsoft.CodeAnalysis.CSharp.Syntax
{
public sealed partial class FieldDeclarationSyntax : BaseFieldDeclarationSyntax
{
public FieldDeclarationSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
}
\ No newline at end of file

namespace Microsoft.CodeAnalysis.CSharp.Syntax
{
public sealed partial class FixedStatementSyntax : StatementSyntax
{
public FixedStatementSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
}
\ No newline at end of file
// 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 Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Syntax
{
......@@ -12,6 +10,11 @@ public LocalDeclarationStatementSyntax Update(SyntaxTokenList modifiers, Variabl
{
return Update(modifiers, this.RefKeyword, declaration, semicolonToken);
}
public LocalDeclarationStatementSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
}
......
......@@ -2650,39 +2650,3 @@ internal partial class ContextAwareSyntax
#endif
}
}
// PROTOTYPE(tuples) Move this to a better place
namespace Microsoft.CodeAnalysis.CSharp.Syntax
{
public sealed partial class EventFieldDeclarationSyntax : BaseFieldDeclarationSyntax
{
public EventFieldDeclarationSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
public sealed partial class FieldDeclarationSyntax : BaseFieldDeclarationSyntax
{
public FieldDeclarationSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
public sealed partial class FixedStatementSyntax : StatementSyntax
{
public FixedStatementSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
public sealed partial class LocalDeclarationStatementSyntax : StatementSyntax
{
public LocalDeclarationStatementSyntax AddDeclarationVariables(params VariableDeclaratorSyntax[] items)
{
return this.WithDeclaration(this.Declaration.WithVariables(this.Declaration.Variables.AddRange(items)));
}
}
}
\ No newline at end of file
......@@ -1284,6 +1284,28 @@ static void Main()
);
}
[Fact]
public void ErrorRight()
{
string source = @"
class C
{
static void Main()
{
int x;
(x, x) = undeclared;
}
}
";
var comp = CreateCompilationWithMscorlib(source, parseOptions: TestOptions.Regular.WithRefsFeature());
comp.VerifyDiagnostics(
// (7,18): error CS0103: The name 'undeclared' does not exist in the current context
// (x, x) = undeclared;
Diagnostic(ErrorCode.ERR_NameNotInContext, "undeclared").WithArguments("undeclared").WithLocation(7, 18)
);
}
[Fact]
public void VoidRight()
{
......@@ -2484,7 +2506,8 @@ public void Deconstruct(out int a, out string b)
comp.VerifyDiagnostics();
}
[Fact(Skip = "PROTOTYPE(tuples)")]
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/12400")]
[WorkItem(12400, "https://github.com/dotnet/roslyn/issues/12400")]
public void AssignWithPostfixOperator()
{
string source = @"
......@@ -2513,7 +2536,8 @@ public void Deconstruct(out int a, out string b)
}
}
";
// PROTOTYPE(tuples) we expect "2 hello" instead, which means the evaluation order is wrong
// https://github.com/dotnet/roslyn/issues/12400
// we expect "2 hello" instead, which means the evaluation order is wrong
var comp = CompileAndVerify(source, expectedOutput: "1 hello");
comp.VerifyDiagnostics();
}
......@@ -2936,7 +2960,7 @@ static void Main()
);
}
[Fact(Skip = "PROTOTYPE(tuples)")]
[Fact]
public void TypelessDeclaration()
{
string source = @"
......@@ -2948,13 +2972,15 @@ static void Main()
}
}
";
// crash
var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyDiagnostics(
// (6,24): error CS8210: Deconstruct assignment requires an expression with a type on the right-hand-side.
// var (x1, x2) = (1, null);
Diagnostic(ErrorCode.ERR_DeconstructRequiresExpression, "(1, null)").WithLocation(6, 24)
);
}
[Fact(Skip = "PROTOTYPE(tuples)")]
[Fact]
public void InferTypeOfTypelessDeclaration()
{
string source = @"
......@@ -2967,9 +2993,12 @@ static void Main()
}
}
";
// crash
var comp = CompileAndVerify(source, expectedOutput: "1 2 ");
comp.VerifyDiagnostics();
var comp = CreateCompilationWithMscorlib(source, references: new[] { ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyDiagnostics(
// (6,37): error CS8210: Deconstruct assignment requires an expression with a type on the right-hand-side.
// (var (x1, x2), string x3) = ((1, 2), null);
Diagnostic(ErrorCode.ERR_DeconstructRequiresExpression, "((1, 2), null)").WithLocation(6, 37)
);
}
[Fact]
......
......@@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
using Roslyn.Test.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Parsing
{
......@@ -1728,7 +1729,8 @@ public void InvalidStatement()
Assert.True(statement.HasErrors);
}
[Fact(Skip = "PROTOTYPE(tuples)")]
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/12402")]
[WorkItem(12402, "https://github.com/dotnet/roslyn/issues/12402")]
public void ConfusedForWithDeconstruction()
{
var text = "for ((int x, var (y, z)) in foo) { }";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册