提交 ab93813b 编写于 作者: H Heejae Chang

fixed merge conflict

......@@ -782,7 +782,7 @@ private ICompoundAssignmentExpression CreateBoundCompoundAssignmentOperatorOpera
SyntaxNode syntax = boundCompoundAssignmentOperator.Syntax;
ITypeSymbol type = boundCompoundAssignmentOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundCompoundAssignmentOperator.ConstantValue);
return new LazyCompoundAssignmentExpression(binaryOperationKind, target, value, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue);
return new LazyCompoundAssignmentExpression(binaryOperationKind, boundCompoundAssignmentOperator.Type.IsNullableType(), target, value, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue);
}
private IIncrementExpression CreateBoundIncrementOperatorOperation(BoundIncrementOperator boundIncrementOperator)
......@@ -824,7 +824,8 @@ private IUnaryOperatorExpression CreateBoundUnaryOperatorOperation(BoundUnaryOpe
SyntaxNode syntax = boundUnaryOperator.Syntax;
ITypeSymbol type = boundUnaryOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundUnaryOperator.ConstantValue);
return new LazyUnaryOperatorExpression(unaryOperationKind, operand, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue);
bool isLifted = boundUnaryOperator.OperatorKind.IsLifted();
return new LazyUnaryOperatorExpression(unaryOperationKind, operand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue);
}
private IBinaryOperatorExpression CreateBoundBinaryOperatorOperation(BoundBinaryOperator boundBinaryOperator)
......@@ -837,7 +838,8 @@ private IBinaryOperatorExpression CreateBoundBinaryOperatorOperation(BoundBinary
SyntaxNode syntax = boundBinaryOperator.Syntax;
ITypeSymbol type = boundBinaryOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundBinaryOperator.ConstantValue);
return new LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue);
bool isLifted = boundBinaryOperator.OperatorKind.IsLifted();
return new LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue);
}
private IConditionalChoiceExpression CreateBoundConditionalOperatorOperation(BoundConditionalOperator boundConditionalOperator)
......
// 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.Syntax;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public partial class IOperationTests : SemanticModelTestBase
{
[Fact]
public void VerifyLiftedBinaryOperators1()
{
var source = @"
class C
{
void F(int? x, int? y)
{
var z = /*<bind>*/x + y/*</bind>*/;
}
}";
string expectedOperationTree =
@"IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd-IsLifted) (OperationKind.BinaryOperatorExpression, Type: System.Int32?) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32?) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32?) (Syntax: 'y')";
VerifyOperationTreeForTest<BinaryExpressionSyntax>(source, expectedOperationTree);
}
[Fact]
public void VerifyNonLiftedBinaryOperators1()
{
var source = @"
class C
{
void F(int x, int y)
{
var z = /*<bind>*/x + y/*</bind>*/;
}
}";
string expectedOperationTree =
@"IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')";
VerifyOperationTreeForTest<BinaryExpressionSyntax>(source, expectedOperationTree);
}
[Fact]
public void VerifyLiftedUserDefinedBinaryOperators1()
{
var source = @"
struct C
{
public static C operator +(C c1, C c2) { }
void F(C? x, C? y)
{
var z = /*<bind>*/x + y/*</bind>*/;
}
}";
string expectedOperationTree =
@"IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodAdd-IsLifted) (OperatorMethod: C C.op_Addition(C c1, C c2)) (OperationKind.BinaryOperatorExpression, Type: C?) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C?) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: C?) (Syntax: 'y')";
VerifyOperationTreeForTest<BinaryExpressionSyntax>(source, expectedOperationTree);
}
[Fact]
public void VerifyNonLiftedUserDefinedBinaryOperators1()
{
var source = @"
struct C
{
public static C operator +(C c1, C c2) { }
void F(C x, C y)
{
var z = /*<bind>*/x + y/*</bind>*/;
}
}";
string expectedOperationTree =
@"IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodAdd) (OperatorMethod: C C.op_Addition(C c1, C c2)) (OperationKind.BinaryOperatorExpression, Type: C) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'y')";
VerifyOperationTreeForTest<BinaryExpressionSyntax>(source, expectedOperationTree);
}
}
}
......@@ -1155,12 +1155,12 @@ class C
{
static void Main(string[] args)
{
/*<bind>*/for (Foo f = new Foo { i = 0, s = ""abc"" }; f.i < 5; f.i = f.i + 1)
/*<bind>*/for (F f = new F { i = 0, s = ""abc"" }; f.i < 5; f.i = f.i + 1)
{
}/*</bind>*/
}
}
public class Foo
public class F
{
public int i;
public string s;
......@@ -1168,39 +1168,38 @@ public class Foo
";
string expectedOperationTree = @"
IForLoopStatement (LoopKind.For) (OperationKind.LoopStatement) (Syntax: 'for (Foo f ... }')
IForLoopStatement (LoopKind.For) (OperationKind.LoopStatement) (Syntax: 'for (F f = ... }')
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerLessThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'f.i < 5')
Left: IFieldReferenceExpression: System.Int32 Foo.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'f.i')
Instance Receiver: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: Foo) (Syntax: 'f')
Left: IFieldReferenceExpression: System.Int32 F.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'f.i')
Instance Receiver: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: F) (Syntax: 'f')
Right: ILiteralExpression (Text: 5) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 5) (Syntax: '5')
Locals: Local_1: Foo f
Locals: Local_1: F f
Before:
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'f = new Foo ... s = ""abc"" }')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'f = new Foo ... s = ""abc"" }')
Variables: Local_1: Foo f
Initializer: IObjectCreationExpression (Constructor: Foo..ctor()) (OperationKind.ObjectCreationExpression, Type: Foo) (Syntax: 'new Foo { i ... s = ""abc"" }')
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'f = new F { ... s = ""abc"" }')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'f = new F { ... s = ""abc"" }')
Variables: Local_1: F f
Initializer: IObjectCreationExpression (Constructor: F..ctor()) (OperationKind.ObjectCreationExpression, Type: F) (Syntax: 'new F { i = ... s = ""abc"" }')
Arguments(0)
Initializer: IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: Foo) (Syntax: '{ i = 0, s = ""abc"" }')
Initializer: IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: F) (Syntax: '{ i = 0, s = ""abc"" }')
Initializers(2):
ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'i = 0')
Left: IFieldReferenceExpression: System.Int32 Foo.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'i')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Foo) (Syntax: 'i')
Left: IFieldReferenceExpression: System.Int32 F.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'i')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: F) (Syntax: 'i')
Right: ILiteralExpression (Text: 0) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String) (Syntax: 's = ""abc""')
Left: IFieldReferenceExpression: System.String Foo.s (OperationKind.FieldReferenceExpression, Type: System.String) (Syntax: 's')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Foo) (Syntax: 's')
Left: IFieldReferenceExpression: System.String F.s (OperationKind.FieldReferenceExpression, Type: System.String) (Syntax: 's')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: F) (Syntax: 's')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""abc"") (Syntax: '""abc""')
AtLoopBottom:
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'f.i = f.i + 1')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'f.i = f.i + 1')
Left: IFieldReferenceExpression: System.Int32 Foo.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'f.i')
Instance Receiver: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: Foo) (Syntax: 'f')
Left: IFieldReferenceExpression: System.Int32 F.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'f.i')
Instance Receiver: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: F) (Syntax: 'f')
Right: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'f.i + 1')
Left: IFieldReferenceExpression: System.Int32 Foo.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'f.i')
Instance Receiver: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: Foo) (Syntax: 'f')
Left: IFieldReferenceExpression: System.Int32 F.i (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'f.i')
Instance Receiver: ILocalReferenceExpression: f (OperationKind.LocalReferenceExpression, Type: F) (Syntax: 'f')
Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
";
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')";
VerifyOperationTreeForTest<ForStatementSyntax>(source, expectedOperationTree);
}
......@@ -1265,8 +1264,8 @@ Type Arguments(0)
IDynamicMemberReferenceExpression (Member Name: ""Next"", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: dynamic) (Syntax: 'd.Next')
Type Arguments(0)
Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
";
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')";
VerifyOperationTreeForTest<ForStatementSyntax>(source, expectedOperationTree);
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// 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.Syntax;
using Microsoft.CodeAnalysis.Test.Utilities;
......@@ -262,14 +262,14 @@ class C
{
void M()
{
Foo();
F();
int x = 0;
/*<bind>*/void Foo() => x++;/*</bind>*/
/*<bind>*/void F() => x++;/*</bind>*/
}
}
";
string expectedOperationTree = @"
ILocalFunctionStatement (Local Function: void Foo()) (OperationKind.LocalFunctionStatement) (Syntax: 'void Foo() => x++;')
ILocalFunctionStatement (Local Function: void F()) (OperationKind.LocalFunctionStatement) (Syntax: 'void F() => x++;')
IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '=> x++')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'x++')
Expression: IIncrementExpression (UnaryOperandKind.IntegerPostfixIncrement) (OperationKind.IncrementExpression, Type: System.Int32) (Syntax: 'x++')
......@@ -279,8 +279,8 @@ void M()
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0165: Use of unassigned local variable 'x'
// Foo();
Diagnostic(ErrorCode.ERR_UseDefViolation, "Foo()").WithArguments("x").WithLocation(6, 9)
// F();
Diagnostic(ErrorCode.ERR_UseDefViolation, "F()").WithArguments("x").WithLocation(6, 9)
};
VerifyOperationTreeAndDiagnosticsForTest<LocalFunctionStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
......@@ -295,21 +295,20 @@ class C
void M(int p)
{
int x;
/*<bind>*/void Foo(out int y) => y = p;/*</bind>*/
Foo(out x);
/*<bind>*/void F(out int y) => y = p;/*</bind>*/
F(out x);
}
}
";
string expectedOperationTree = @"
ILocalFunctionStatement (Local Function: void Foo(out System.Int32 y)) (OperationKind.LocalFunctionStatement) (Syntax: 'void Foo(ou ... ) => y = p;')
ILocalFunctionStatement (Local Function: void F(out System.Int32 y)) (OperationKind.LocalFunctionStatement) (Syntax: 'void F(out ... ) => y = p;')
IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '=> y = p')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'y = p')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'y = p')
Left: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')
Right: IParameterReferenceExpression: p (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'p')
IReturnStatement (OperationKind.ReturnStatement) (Syntax: '=> y = p')
ReturnedValue: null
";
ReturnedValue: null";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<LocalFunctionStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
......@@ -323,12 +322,12 @@ class C
{
void M(int p)
{
/*<bind>*/void Foo(out int y) => ;/*</bind>*/
/*<bind>*/void F(out int y) => ;/*</bind>*/
}
}
";
string expectedOperationTree = @"
ILocalFunctionStatement (Local Function: void Foo(out System.Int32 y)) (OperationKind.LocalFunctionStatement, IsInvalid) (Syntax: 'void Foo(out int y) => ;')
ILocalFunctionStatement (Local Function: void F(out System.Int32 y)) (OperationKind.LocalFunctionStatement, IsInvalid) (Syntax: 'void F(out int y) => ;')
IBlockStatement (2 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: '=> ')
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: '')
Expression: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '')
......@@ -337,15 +336,15 @@ void M(int p)
ReturnedValue: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS1525: Invalid expression term ';'
// /*<bind>*/void Foo(out int y) => ;/*</bind>*/
Diagnostic(ErrorCode.ERR_InvalidExprTerm, ";").WithArguments(";").WithLocation(6, 42),
// CS0177: The out parameter 'y' must be assigned to before control leaves the current method
// /*<bind>*/void Foo(out int y) => ;/*</bind>*/
Diagnostic(ErrorCode.ERR_ParamUnassigned, "Foo").WithArguments("y").WithLocation(6, 24),
// CS8321: The local function 'Foo' is declared but never used
// /*<bind>*/void Foo(out int y) => ;/*</bind>*/
Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Foo").WithArguments("Foo").WithLocation(6, 24)
// file.cs(6,40): error CS1525: Invalid expression term ';'
// /*<bind>*/void F(out int y) => ;/*</bind>*/
Diagnostic(ErrorCode.ERR_InvalidExprTerm, ";").WithArguments(";").WithLocation(6, 40),
// file.cs(6,24): error CS0177: The out parameter 'y' must be assigned to before control leaves the current method
// /*<bind>*/void F(out int y) => ;/*</bind>*/
Diagnostic(ErrorCode.ERR_ParamUnassigned, "F").WithArguments("y").WithLocation(6, 24),
// file.cs(6,24): warning CS8321: The local function 'F' is declared but never used
// /*<bind>*/void F(out int y) => ;/*</bind>*/
Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(6, 24)
};
VerifyOperationTreeAndDiagnosticsForTest<LocalFunctionStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
......@@ -359,23 +358,23 @@ class C
{
void M(int p)
{
/*<bind>*/void Foo( { }/*</bind>*/;
/*<bind>*/void F( { }/*</bind>*/;
}
}
";
string expectedOperationTree = @"
ILocalFunctionStatement (Local Function: void Foo()) (OperationKind.LocalFunctionStatement, IsInvalid) (Syntax: 'void Foo( { }')
ILocalFunctionStatement (Local Function: void F()) (OperationKind.LocalFunctionStatement, IsInvalid) (Syntax: 'void F( { }')
IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: '{ }')
IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: '{ }')
ReturnedValue: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS1026: ) expected
// /*<bind>*/void Foo( { }/*</bind>*/;
Diagnostic(ErrorCode.ERR_CloseParenExpected, "{").WithLocation(6, 29),
// CS8321: The local function 'Foo' is declared but never used
// /*<bind>*/void Foo( { }/*</bind>*/;
Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Foo").WithArguments("Foo").WithLocation(6, 24)
// file.cs(6,27): error CS1026: ) expected
// /*<bind>*/void F( { }/*</bind>*/;
Diagnostic(ErrorCode.ERR_CloseParenExpected, "{").WithLocation(6, 27),
// file.cs(6,24): warning CS8321: The local function 'F' is declared but never used
// /*<bind>*/void F( { }/*</bind>*/;
Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(6, 24)
};
VerifyOperationTreeAndDiagnosticsForTest<LocalFunctionStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
......@@ -389,24 +388,24 @@ class C
{
void M(int p)
{
/*<bind>*/X Foo() { }/*</bind>*/;
/*<bind>*/X F() { }/*</bind>*/;
}
}
";
string expectedOperationTree = @"
ILocalFunctionStatement (Local Function: X Foo()) (OperationKind.LocalFunctionStatement, IsInvalid) (Syntax: 'X Foo() { }')
ILocalFunctionStatement (Local Function: X F()) (OperationKind.LocalFunctionStatement, IsInvalid) (Syntax: 'X F() { }')
IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ }')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0161: 'Foo()': not all code paths return a value
// /*<bind>*/X Foo() { }/*</bind>*/;
Diagnostic(ErrorCode.ERR_ReturnExpected, "Foo").WithArguments("Foo()").WithLocation(6, 21),
// CS0161: 'F()': not all code paths return a value
// /*<bind>*/X F() { }/*</bind>*/;
Diagnostic(ErrorCode.ERR_ReturnExpected, "F").WithArguments("F()").WithLocation(6, 21),
// CS0246: The type or namespace name 'X' could not be found (are you missing a using directive or an assembly reference?)
// /*<bind>*/X Foo() { }/*</bind>*/;
// /*<bind>*/X F() { }/*</bind>*/;
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "X").WithArguments("X").WithLocation(6, 19),
// CS8321: The local function 'Foo' is declared but never used
// /*<bind>*/X Foo() { }/*</bind>*/;
Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "Foo").WithArguments("Foo").WithLocation(6, 21)
// CS8321: The local function 'F' is declared but never used
// /*<bind>*/X F() { }/*</bind>*/;
Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "F").WithArguments("F").WithLocation(6, 21)
};
VerifyOperationTreeAndDiagnosticsForTest<LocalFunctionStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
......
......@@ -2958,5 +2958,83 @@ unsafe void Method()
VerifyOperationTreeForTest<PrefixUnaryExpressionSyntax>(source, expectedOperationTree);
}
[Fact]
public void VerifyLiftedUnaryOperators1()
{
var source = @"
class C
{
void F(int? x)
{
var y = /*<bind>*/-x/*</bind>*/;
}
}";
string expectedOperationTree =
@"IUnaryOperatorExpression (UnaryOperationKind.IntegerMinus-IsLifted) (OperationKind.UnaryOperatorExpression, Type: System.Int32?) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32?) (Syntax: 'x')";
VerifyOperationTreeForTest<PrefixUnaryExpressionSyntax>(source, expectedOperationTree);
}
[Fact]
public void VerifyNonLiftedUnaryOperators1()
{
var source = @"
class C
{
void F(int x)
{
var y = /*<bind>*/-x/*</bind>*/;
}
}";
string expectedOperationTree =
@"IUnaryOperatorExpression (UnaryOperationKind.IntegerMinus) (OperationKind.UnaryOperatorExpression, Type: System.Int32) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')";
VerifyOperationTreeForTest<PrefixUnaryExpressionSyntax>(source, expectedOperationTree);
}
[Fact]
public void VerifyLiftedUserDefinedUnaryOperators1()
{
var source = @"
struct C
{
public static C operator -(C c) { }
void F(C? x)
{
var y = /*<bind>*/-x/*</bind>*/;
}
}";
string expectedOperationTree =
@"IUnaryOperatorExpression (UnaryOperationKind.OperatorMethodMinus-IsLifted) (OperatorMethod: C C.op_UnaryNegation(C c)) (OperationKind.UnaryOperatorExpression, Type: C?) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C?) (Syntax: 'x')";
VerifyOperationTreeForTest<PrefixUnaryExpressionSyntax>(source, expectedOperationTree);
}
[Fact]
public void VerifyNonLiftedUserDefinedUnaryOperators1()
{
var source = @"
struct C
{
public static C operator -(C c) { }
void F(C x)
{
var y = /*<bind>*/-x/*</bind>*/;
}
}";
string expectedOperationTree =
@"IUnaryOperatorExpression (UnaryOperationKind.OperatorMethodMinus) (OperatorMethod: C C.op_UnaryNegation(C c)) (OperationKind.UnaryOperatorExpression, Type: C) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'x')";
VerifyOperationTreeForTest<PrefixUnaryExpressionSyntax>(source, expectedOperationTree);
}
}
}
......@@ -647,12 +647,13 @@ public LazyAwaitExpression(Lazy<IOperation> awaitedValue, SemanticModel semantic
/// </summary>
internal abstract partial class BaseBinaryOperatorExpression : Operation, IHasOperatorMethodExpression, IBinaryOperatorExpression
{
protected BaseBinaryOperatorExpression(BinaryOperationKind binaryOperationKind, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
protected BaseBinaryOperatorExpression(BinaryOperationKind binaryOperationKind, bool isLifted, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(OperationKind.BinaryOperatorExpression, semanticModel, syntax, type, constantValue)
{
BinaryOperationKind = binaryOperationKind;
UsesOperatorMethod = usesOperatorMethod;
OperatorMethod = operatorMethod;
IsLifted = isLifted;
}
/// <summary>
/// Kind of binary operation.
......@@ -668,6 +669,9 @@ internal abstract partial class BaseBinaryOperatorExpression : Operation, IHasOp
/// Operation method used by the operation, null if the operation does not use an operator method.
/// </summary>
public IMethodSymbol OperatorMethod { get; }
public bool IsLifted { get; }
public override IEnumerable<IOperation> Children
{
get
......@@ -699,8 +703,8 @@ public override void Accept(OperationVisitor visitor)
/// </summary>
internal sealed partial class BinaryOperatorExpression : BaseBinaryOperatorExpression, IHasOperatorMethodExpression, IBinaryOperatorExpression
{
public BinaryOperatorExpression(BinaryOperationKind binaryOperationKind, IOperation leftOperand, IOperation rightOperand, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(binaryOperationKind, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
public BinaryOperatorExpression(BinaryOperationKind binaryOperationKind, IOperation leftOperand, IOperation rightOperand, bool isLifted, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(binaryOperationKind, isLifted, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
{
LeftOperandImpl = leftOperand;
RightOperandImpl = rightOperand;
......@@ -718,7 +722,8 @@ internal sealed partial class LazyBinaryOperatorExpression : BaseBinaryOperatorE
private readonly Lazy<IOperation> _lazyLeftOperand;
private readonly Lazy<IOperation> _lazyRightOperand;
public LazyBinaryOperatorExpression(BinaryOperationKind binaryOperationKind, Lazy<IOperation> leftOperand, Lazy<IOperation> rightOperand, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) : base(binaryOperationKind, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
public LazyBinaryOperatorExpression(BinaryOperationKind binaryOperationKind, Lazy<IOperation> leftOperand, Lazy<IOperation> rightOperand, bool isLifted, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(binaryOperationKind, isLifted, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
{
_lazyLeftOperand = leftOperand ?? throw new System.ArgumentNullException(nameof(leftOperand));
_lazyRightOperand = rightOperand ?? throw new System.ArgumentNullException(nameof(rightOperand));
......@@ -938,10 +943,11 @@ public LazyCatchClause(Lazy<IBlockStatement> handler, ITypeSymbol caughtType, La
/// </summary>
internal abstract partial class BaseCompoundAssignmentExpression : AssignmentExpression, IHasOperatorMethodExpression, ICompoundAssignmentExpression
{
protected BaseCompoundAssignmentExpression(BinaryOperationKind binaryOperationKind, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
protected BaseCompoundAssignmentExpression(BinaryOperationKind binaryOperationKind, bool isLifted, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(OperationKind.CompoundAssignmentExpression, semanticModel, syntax, type, constantValue)
{
BinaryOperationKind = binaryOperationKind;
IsLifted = isLifted;
UsesOperatorMethod = usesOperatorMethod;
OperatorMethod = operatorMethod;
}
......@@ -950,6 +956,10 @@ internal abstract partial class BaseCompoundAssignmentExpression : AssignmentExp
/// </summary>
public BinaryOperationKind BinaryOperationKind { get; }
/// <summary>
/// <code>true</code> if this assignment contains a 'lifted' binary operation.
/// </summary>
public bool IsLifted { get; }
/// <summary>
/// True if and only if the operation is performed by an operator method.
/// </summary>
public bool UsesOperatorMethod { get; }
......@@ -981,8 +991,8 @@ public override void Accept(OperationVisitor visitor)
/// </summary>
internal sealed partial class CompoundAssignmentExpression : BaseCompoundAssignmentExpression, IHasOperatorMethodExpression, ICompoundAssignmentExpression
{
public CompoundAssignmentExpression(BinaryOperationKind binaryOperationKind, IOperation target, IOperation value, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(binaryOperationKind, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
public CompoundAssignmentExpression(BinaryOperationKind binaryOperationKind, bool isLifted, IOperation target, IOperation value, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(binaryOperationKind, isLifted, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
{
TargetImpl = target;
ValueImpl = value;
......@@ -999,8 +1009,8 @@ internal sealed partial class LazyCompoundAssignmentExpression : BaseCompoundAss
private readonly Lazy<IOperation> _lazyTarget;
private readonly Lazy<IOperation> _lazyValue;
public LazyCompoundAssignmentExpression(BinaryOperationKind binaryOperationKind, Lazy<IOperation> target, Lazy<IOperation> value, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(binaryOperationKind, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
public LazyCompoundAssignmentExpression(BinaryOperationKind binaryOperationKind, bool isLifted, Lazy<IOperation> target, Lazy<IOperation> value, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(binaryOperationKind, isLifted, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
{
_lazyTarget = target ?? throw new System.ArgumentNullException(nameof(target));
_lazyValue = value ?? throw new System.ArgumentNullException(nameof(value));
......@@ -4709,12 +4719,13 @@ internal sealed partial class LazyDynamicObjectCreationExpression : BaseDynamicO
/// </summary>
internal abstract partial class BaseUnaryOperatorExpression : Operation, IHasOperatorMethodExpression, IUnaryOperatorExpression
{
protected BaseUnaryOperatorExpression(UnaryOperationKind unaryOperationKind, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
protected BaseUnaryOperatorExpression(UnaryOperationKind unaryOperationKind, bool isLifted, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(OperationKind.UnaryOperatorExpression, semanticModel, syntax, type, constantValue)
{
UnaryOperationKind = unaryOperationKind;
UsesOperatorMethod = usesOperatorMethod;
OperatorMethod = operatorMethod;
IsLifted = isLifted;
}
/// <summary>
/// Kind of unary operation.
......@@ -4729,6 +4740,9 @@ internal abstract partial class BaseUnaryOperatorExpression : Operation, IHasOpe
/// Operation method used by the operation, null if the operation does not use an operator method.
/// </summary>
public IMethodSymbol OperatorMethod { get; }
public bool IsLifted { get; }
public override IEnumerable<IOperation> Children
{
get
......@@ -4755,8 +4769,8 @@ public override void Accept(OperationVisitor visitor)
/// </summary>
internal sealed partial class UnaryOperatorExpression : BaseUnaryOperatorExpression, IHasOperatorMethodExpression, IUnaryOperatorExpression
{
public UnaryOperatorExpression(UnaryOperationKind unaryOperationKind, IOperation operand, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(unaryOperationKind, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
public UnaryOperatorExpression(UnaryOperationKind unaryOperationKind, IOperation operand, bool isLifted, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(unaryOperationKind, isLifted, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
{
OperandImpl = operand;
}
......@@ -4771,7 +4785,8 @@ internal sealed partial class LazyUnaryOperatorExpression : BaseUnaryOperatorExp
{
private readonly Lazy<IOperation> _lazyOperand;
public LazyUnaryOperatorExpression(UnaryOperationKind unaryOperationKind, Lazy<IOperation> operand, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) : base(unaryOperationKind, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
public LazyUnaryOperatorExpression(UnaryOperationKind unaryOperationKind, Lazy<IOperation> operand, bool isLifted, bool usesOperatorMethod, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue) :
base(unaryOperationKind, isLifted, usesOperatorMethod, operatorMethod, semanticModel, syntax, type, constantValue)
{
_lazyOperand = operand ?? throw new System.ArgumentNullException(nameof(operand));
}
......
......@@ -25,6 +25,12 @@ public interface IBinaryOperatorExpression : IHasOperatorMethodExpression
/// Right operand.
/// </summary>
IOperation RightOperand { get; }
/// <summary>
/// <code>true</code> if this is a 'lifted' binary operator. When there is an
/// operator that is defined to work on a value type, 'lifted' operators are
/// created to work on the <see cref="System.Nullable{T}"/> versions of those
/// value types.
/// </summary>
bool IsLifted { get; }
}
}
......@@ -17,5 +17,9 @@ public interface ICompoundAssignmentExpression : IAssignmentExpression, IHasOper
/// Kind of binary operation.
/// </summary>
BinaryOperationKind BinaryOperationKind { get; }
/// <summary>
/// <code>true</code> if this assignment contains a 'lifted' binary operation.
/// </summary>
bool IsLifted { get; }
}
}
\ No newline at end of file
}
......@@ -21,6 +21,13 @@ public interface IUnaryOperatorExpression : IHasOperatorMethodExpression
/// Single operand.
/// </summary>
IOperation Operand { get; }
/// <summary>
/// <code>true</code> if this is a 'lifted' unary operator. When there is an
/// operator that is defined to work on a value type, 'lifted' operators are
/// created to work on the <see cref="System.Nullable{T}"/> versions of those
/// value types.
/// </summary>
bool IsLifted { get; }
}
}
......@@ -260,12 +260,12 @@ public override IOperation VisitPlaceholderExpression(IPlaceholderExpression ope
public override IOperation VisitUnaryOperatorExpression(IUnaryOperatorExpression operation, object argument)
{
return new UnaryOperatorExpression(operation.UnaryOperationKind, Visit(operation.Operand), operation.UsesOperatorMethod, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
return new UnaryOperatorExpression(operation.UnaryOperationKind, Visit(operation.Operand), operation.IsLifted, operation.UsesOperatorMethod, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
}
public override IOperation VisitBinaryOperatorExpression(IBinaryOperatorExpression operation, object argument)
{
return new BinaryOperatorExpression(operation.BinaryOperationKind, Visit(operation.LeftOperand), Visit(operation.RightOperand), operation.UsesOperatorMethod, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
return new BinaryOperatorExpression(operation.BinaryOperationKind, Visit(operation.LeftOperand), Visit(operation.RightOperand), operation.IsLifted, operation.UsesOperatorMethod, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
}
public override IOperation VisitConversionExpression(IConversionExpression operation, object argument)
......@@ -385,7 +385,7 @@ public override IOperation VisitSimpleAssignmentExpression(ISimpleAssignmentExpr
public override IOperation VisitCompoundAssignmentExpression(ICompoundAssignmentExpression operation, object argument)
{
return new CompoundAssignmentExpression(operation.BinaryOperationKind, Visit(operation.Target), Visit(operation.Value), operation.UsesOperatorMethod, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
return new CompoundAssignmentExpression(operation.BinaryOperationKind, operation.IsLifted, Visit(operation.Target), Visit(operation.Value), operation.UsesOperatorMethod, operation.OperatorMethod, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue);
}
public override IOperation VisitIncrementExpression(IIncrementExpression operation, object argument)
......
......@@ -42,10 +42,11 @@ public static IExpressionStatement CreateSimpleAssignmentExpressionStatement(IOp
}
public static IExpressionStatement CreateCompoundAssignmentExpressionStatement(
IOperation target, IOperation value, BinaryOperationKind binaryOperationKind, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax)
IOperation target, IOperation value, BinaryOperationKind binaryOperationKind, bool isLifted, IMethodSymbol operatorMethod, SemanticModel semanticModel, SyntaxNode syntax)
{
var expression = new CompoundAssignmentExpression(
binaryOperationKind,
isLifted,
target,
value,
operatorMethod != null,
......@@ -69,12 +70,12 @@ public static ILiteralExpression CreateLiteralExpression(ConstantValue value, IT
}
public static IBinaryOperatorExpression CreateBinaryOperatorExpression(
BinaryOperationKind binaryOperationKind, IOperation left, IOperation right, ITypeSymbol resultType, SemanticModel semanticModel, SyntaxNode syntax)
BinaryOperationKind binaryOperationKind, IOperation left, IOperation right, ITypeSymbol resultType, SemanticModel semanticModel, SyntaxNode syntax, bool isLifted)
{
return new BinaryOperatorExpression(
binaryOperationKind, left, right,
usesOperatorMethod: false, operatorMethod: null,
semanticModel: semanticModel, syntax: syntax, type: resultType, constantValue: default(Optional<object>));
isLifted: isLifted, usesOperatorMethod: false, operatorMethod: null,
semanticModel: semanticModel, syntax: syntax, type: resultType, constantValue: default);
}
public static IArrayCreationExpression CreateArrayCreationExpression(
......
......@@ -359,6 +359,7 @@ Microsoft.CodeAnalysis.Semantics.IBinaryOperatorExpression
Microsoft.CodeAnalysis.Semantics.IBinaryOperatorExpression.BinaryOperationKind.get -> Microsoft.CodeAnalysis.Semantics.BinaryOperationKind
Microsoft.CodeAnalysis.Semantics.IBinaryOperatorExpression.LeftOperand.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IBinaryOperatorExpression.RightOperand.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IBinaryOperatorExpression.IsLifted.get -> bool
Microsoft.CodeAnalysis.Semantics.IBlockStatement
Microsoft.CodeAnalysis.Semantics.IBlockStatement.Locals.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
Microsoft.CodeAnalysis.Semantics.IBlockStatement.Statements.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
......@@ -378,6 +379,7 @@ Microsoft.CodeAnalysis.Semantics.ICollectionElementInitializerExpression.Argumen
Microsoft.CodeAnalysis.Semantics.ICollectionElementInitializerExpression.IsDynamic.get -> bool
Microsoft.CodeAnalysis.Semantics.ICompoundAssignmentExpression
Microsoft.CodeAnalysis.Semantics.ICompoundAssignmentExpression.BinaryOperationKind.get -> Microsoft.CodeAnalysis.Semantics.BinaryOperationKind
Microsoft.CodeAnalysis.Semantics.ICompoundAssignmentExpression.IsLifted.get -> bool
Microsoft.CodeAnalysis.Semantics.IConditionalAccessExpression
Microsoft.CodeAnalysis.Semantics.IConditionalAccessExpression.ConditionalInstance.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IConditionalAccessExpression.ConditionalValue.get -> Microsoft.CodeAnalysis.IOperation
......@@ -570,6 +572,7 @@ Microsoft.CodeAnalysis.Semantics.ITypeParameterObjectCreationExpression.Initiali
Microsoft.CodeAnalysis.Semantics.IUnaryOperatorExpression
Microsoft.CodeAnalysis.Semantics.IUnaryOperatorExpression.Operand.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IUnaryOperatorExpression.UnaryOperationKind.get -> Microsoft.CodeAnalysis.Semantics.UnaryOperationKind
Microsoft.CodeAnalysis.Semantics.IUnaryOperatorExpression.IsLifted.get -> bool
Microsoft.CodeAnalysis.Semantics.IUsingStatement
Microsoft.CodeAnalysis.Semantics.IUsingStatement.Body.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.IUsingStatement.Declaration.get -> Microsoft.CodeAnalysis.Semantics.IVariableDeclarationStatement
......
......@@ -4,6 +4,7 @@ Imports System.Collections.Concurrent
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.Semantics
......@@ -271,7 +272,7 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim syntax As SyntaxNode = boundAssignmentOperator.Syntax
Dim type As ITypeSymbol = boundAssignmentOperator.Type
Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundAssignmentOperator.ConstantValueOpt)
Return New LazyCompoundAssignmentExpression(binaryOperationKind, target, value, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
Return New LazyCompoundAssignmentExpression(binaryOperationKind, boundAssignmentOperator.Type.IsNullableType(), target, value, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
Else
Dim target As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAssignmentOperator.Left))
Dim value As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundAssignmentOperator.Right))
......@@ -394,7 +395,8 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim syntax As SyntaxNode = boundUnaryOperator.Syntax
Dim type As ITypeSymbol = boundUnaryOperator.Type
Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUnaryOperator.ConstantValueOpt)
Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
Dim isLifted = (boundUnaryOperator.OperatorKind And UnaryOperatorKind.Lifted) <> 0
Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
End Function
Private Function CreateBoundUserDefinedUnaryOperatorOperation(boundUserDefinedUnaryOperator As BoundUserDefinedUnaryOperator) As IUnaryOperatorExpression
......@@ -411,7 +413,8 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim syntax As SyntaxNode = boundUserDefinedUnaryOperator.Syntax
Dim type As ITypeSymbol = boundUserDefinedUnaryOperator.Type
Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedUnaryOperator.ConstantValueOpt)
Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
Dim isLifted = (boundUserDefinedUnaryOperator.OperatorKind And UnaryOperatorKind.Lifted) <> 0
Return New LazyUnaryOperatorExpression(unaryOperationKind, operand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
End Function
Private Function CreateBoundBinaryOperatorOperation(boundBinaryOperator As BoundBinaryOperator) As IBinaryOperatorExpression
......@@ -423,7 +426,8 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim syntax As SyntaxNode = boundBinaryOperator.Syntax
Dim type As ITypeSymbol = boundBinaryOperator.Type
Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundBinaryOperator.ConstantValueOpt)
Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
Dim isLifted = (boundBinaryOperator.OperatorKind And BinaryOperatorKind.Lifted) <> 0
Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
End Function
Private Function CreateBoundUserDefinedBinaryOperatorOperation(boundUserDefinedBinaryOperator As BoundUserDefinedBinaryOperator) As IBinaryOperatorExpression
......@@ -435,7 +439,8 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim syntax As SyntaxNode = boundUserDefinedBinaryOperator.Syntax
Dim type As ITypeSymbol = boundUserDefinedBinaryOperator.Type
Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedBinaryOperator.ConstantValueOpt)
Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
Dim isLifted = (boundUserDefinedBinaryOperator.OperatorKind And BinaryOperatorKind.Lifted) <> 0
Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
End Function
Private Function CreateBoundBinaryConditionalExpressionOperation(boundBinaryConditionalExpression As BoundBinaryConditionalExpression) As INullCoalescingExpression
......@@ -456,7 +461,8 @@ Namespace Microsoft.CodeAnalysis.Semantics
Dim syntax As SyntaxNode = boundUserDefinedShortCircuitingOperator.Syntax
Dim type As ITypeSymbol = boundUserDefinedShortCircuitingOperator.Type
Dim constantValue As [Optional](Of Object) = ConvertToOptional(boundUserDefinedShortCircuitingOperator.ConstantValueOpt)
Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
Dim isLifted = (boundUserDefinedShortCircuitingOperator.BitwiseOperator.OperatorKind And BinaryOperatorKind.Lifted) <> 0
Return New LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue)
End Function
Private Function CreateBoundBadExpressionOperation(boundBadExpression As BoundBadExpression) As IInvalidExpression
......
......@@ -3,6 +3,7 @@
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.Semantics
......@@ -316,7 +317,10 @@ Namespace Microsoft.CodeAnalysis.Semantics
value.Syntax,
value.Type,
constantValue:=Nothing))
statements.Add(OperationFactory.CreateCompoundAssignmentExpressionStatement(controlVariable, stepOperand, Semantics.Expression.DeriveAdditionKind(controlType), Nothing, _semanticModel, stepValueExpression.Syntax))
statements.Add(OperationFactory.CreateCompoundAssignmentExpressionStatement(
controlVariable, stepOperand,
Expression.DeriveAdditionKind(controlType.GetNullableUnderlyingTypeOrSelf()), controlType.IsNullableType(),
Nothing, _semanticModel, stepValueExpression.Syntax))
End If
End If
......@@ -347,12 +351,20 @@ Namespace Microsoft.CodeAnalysis.Semantics
' Use the operator methods. Figure out the precise rules first.
Return Nothing
Else
' We are comparing the control variable against the limit value. Using
' either the default stepping constant, or a user supplied constant.
' This will be a lifted comparison if either the control variable or
' limit value is nullable itself.
Dim isLifted = controlVariable.Type.IsNullableType() OrElse
limitValue.Type.IsNullableType()
If stepValue Is Nothing OrElse (stepValue.IsConstant AndAlso stepValue.ConstantValueOpt IsNot Nothing) Then
' Either ControlVariable <= LimitValue or ControlVariable >= LimitValue, depending on whether the step value is negative.
Dim relationalCode As BinaryOperationKind = Helper.DeriveBinaryOperationKind(
If(stepValue IsNot Nothing AndAlso stepValue.ConstantValueOpt.IsNegativeNumeric, BinaryOperatorKind.GreaterThanOrEqual, BinaryOperatorKind.LessThanOrEqual), controlVariable)
Return OperationFactory.CreateBinaryOperatorExpression(relationalCode, Create(controlVariable).Clone(), limitValueReference, booleanType, _semanticModel, limitValueReference.Syntax)
Return OperationFactory.CreateBinaryOperatorExpression(
relationalCode, Create(controlVariable).Clone(), limitValueReference, booleanType, _semanticModel, limitValueReference.Syntax, isLifted)
Else
' If(StepValue >= 0, ControlVariable <= LimitValue, ControlVariable >= LimitValue)
Dim value = Create(stepValue)
......@@ -364,18 +376,20 @@ Namespace Microsoft.CodeAnalysis.Semantics
constantValue:=Nothing)
Dim stepRelationalCode As BinaryOperationKind = Helper.DeriveBinaryOperationKind(BinaryOperatorKind.GreaterThanOrEqual, stepValue)
Dim stepConditionIsLifted = stepValue.Type.IsNullableType()
Dim stepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(stepRelationalCode,
stepValueReference,
OperationFactory.CreateLiteralExpression(Semantics.Expression.SynthesizeNumeric(stepValueReference.Type, 0), stepValue.Type, _semanticModel, stepValue.Syntax),
booleanType,
_semanticModel,
stepValue.Syntax)
stepValue.Syntax,
stepConditionIsLifted)
Dim positiveStepRelationalCode As BinaryOperationKind = Helper.DeriveBinaryOperationKind(BinaryOperatorKind.LessThanOrEqual, controlVariable)
Dim positiveStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(positiveStepRelationalCode, Create(controlVariable).Clone(), limitValueReference, booleanType, _semanticModel, limitValueReference.Syntax)
Dim positiveStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(positiveStepRelationalCode, Create(controlVariable).Clone(), limitValueReference, booleanType, _semanticModel, limitValueReference.Syntax, isLifted)
Dim negativeStepRelationalCode As BinaryOperationKind = Helper.DeriveBinaryOperationKind(BinaryOperatorKind.GreaterThanOrEqual, controlVariable)
Dim negativeStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(negativeStepRelationalCode, Create(controlVariable).Clone(), limitValueReference.Clone(), booleanType, _semanticModel, limitValueReference.Syntax)
Dim negativeStepCondition As IOperation = OperationFactory.CreateBinaryOperatorExpression(negativeStepRelationalCode, Create(controlVariable).Clone(), limitValueReference.Clone(), booleanType, _semanticModel, limitValueReference.Syntax, isLifted)
Return OperationFactory.CreateConditionalChoiceExpression(stepCondition, positiveStepCondition, negativeStepCondition, booleanType, _semanticModel, limitValueReference.Syntax)
End If
......@@ -470,7 +484,8 @@ Namespace Microsoft.CodeAnalysis.Semantics
End Function
Friend Shared Function DeriveUnaryOperationKind(operatorKind As UnaryOperatorKind, operand As BoundExpression) As UnaryOperationKind
Select Case operand.Type.SpecialType
Dim type = operand.Type.GetNullableUnderlyingTypeOrSelf()
Select Case type.SpecialType
Case SpecialType.System_Byte, SpecialType.System_Int16, SpecialType.System_Int32, SpecialType.System_Int64, SpecialType.System_SByte, SpecialType.System_UInt16, SpecialType.System_UInt32, SpecialType.System_UInt64
Select Case operatorKind And UnaryOperatorKind.OpMask
Case UnaryOperatorKind.Plus
......@@ -561,7 +576,8 @@ Namespace Microsoft.CodeAnalysis.Semantics
End Function
Friend Shared Function DeriveBinaryOperationKind(operatorKind As BinaryOperatorKind, left As BoundExpression) As BinaryOperationKind
Select Case left.Type.SpecialType
Dim type = left.Type.GetNullableUnderlyingTypeOrSelf()
Select Case type.SpecialType
Case SpecialType.System_SByte, SpecialType.System_Int16, SpecialType.System_Int32, SpecialType.System_Int64
Select Case operatorKind And BinaryOperatorKind.OpMask
......@@ -764,7 +780,7 @@ Namespace Microsoft.CodeAnalysis.Semantics
End Select
End Select
If left.Type.TypeKind = TypeKind.Enum Then
If type.TypeKind = TypeKind.Enum Then
Select Case operatorKind And BinaryOperatorKind.OpMask
Case BinaryOperatorKind.Add
Return BinaryOperationKind.EnumAdd
......
......@@ -222,7 +222,7 @@ IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'a += b')
Public Sub VerifyOperationTree_IfStatement()
Dim source = <![CDATA[
Class C
Sub Foo(x As Integer)
Sub F(x As Integer)
If x <> 0 Then'BIND:"If x <> 0 Then"
System.Console.Write(x)
End If
......@@ -230,7 +230,7 @@ Class C
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
Dim expectedOperationTree = <![CDATA[
IIfStatement (OperationKind.IfStatement) (Syntax: 'If x <> 0 T ... End If')
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerNotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'x <> 0')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
......@@ -256,7 +256,7 @@ IIfStatement (OperationKind.IfStatement) (Syntax: 'If x <> 0 T ... End If')
Public Sub VerifyOperationTree_ForStatement()
Dim source = <![CDATA[
Class C
Sub Foo()
Sub F()
For i = 0 To 10'BIND:"For i = 0 To 10"
System.Console.Write(i)
Next
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics
Partial Public Class IOperationTests
Inherits SemanticModelTestBase
<Fact>
Public Sub VerifyLiftedBinaryOperators1()
Dim source = <![CDATA[
Class C
Sub F(x as Integer?, y as Integer?)
dim z = x + y 'BIND:"x + y"
End Sub
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd-IsLifted) (OperationKind.BinaryOperatorExpression, Type: System.Nullable(Of System.Int32)) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of System.Int32)) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of System.Int32)) (Syntax: 'y')]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyNonLiftedBinaryOperators1()
Dim source = <![CDATA[
Class C
Sub F(x as Integer, y as Integer)
dim z = x + y 'BIND:"x + y"
End Sub
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')
]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyLiftedUserDefinedShortCircuitBinaryOperators1()
Dim source = <![CDATA[
Structure C
Public Shared Operator And(c1 as C, cs as C) as C
End Operator
Public Shared Operator IsFalse(c1 as C) as Boolean
End Operator
Sub F(x as C?, y as C?)
dim z = x And y 'BIND:"x And y"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodAnd-IsLifted) (OperatorMethod: Function C.op_BitwiseAnd(c1 As C, cs As C) As C) (OperationKind.BinaryOperatorExpression, Type: System.Nullable(Of C)) (Syntax: 'x And y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of C)) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of C)) (Syntax: 'y')
]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyLiftedUserDefinedShortCircuitBinaryOperators2()
Dim source = <![CDATA[
Structure C
Public Shared Operator And(c1 as C, cs as C) as C
End Operator
Public Shared Operator IsFalse(c1 as C) as Boolean
End Operator
Sub F(x as C?, y as C?)
dim z = x AndAlso y 'BIND:"x AndAlso y"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodConditionalAnd-IsLifted) (OperatorMethod: Function C.op_BitwiseAnd(c1 As C, cs As C) As C) (OperationKind.BinaryOperatorExpression, Type: System.Nullable(Of C)) (Syntax: 'x AndAlso y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of C)) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of C)) (Syntax: 'y')
]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyNonLiftedUserDefinedShortCircuitBinaryOperators1()
Dim source = <![CDATA[
Structure C
Public Shared Operator And(c1 as C, cs as C) as C
End Operator
Public Shared Operator IsFalse(c1 as C) as Boolean
End Operator
Sub F(x as C, y as C)
dim z = x And y 'BIND:"x And y"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodAnd) (OperatorMethod: Function C.op_BitwiseAnd(c1 As C, cs As C) As C) (OperationKind.BinaryOperatorExpression, Type: C) (Syntax: 'x And y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'y')
]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyNonLiftedUserDefinedShortCircuitBinaryOperators2()
Dim source = <![CDATA[
Structure C
Public Shared Operator And(c1 as C, cs as C) as C
End Operator
Public Shared Operator IsFalse(c1 as C) as Boolean
End Operator
Sub F(x as C, y as C)
dim z = x AndAlso y 'BIND:"x AndAlso y"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodConditionalAnd) (OperatorMethod: Function C.op_BitwiseAnd(c1 As C, cs As C) As C) (OperationKind.BinaryOperatorExpression, Type: C) (Syntax: 'x AndAlso y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'y')]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyLiftedUserDefinedBinaryOperators1()
Dim source = <![CDATA[
Structure C
Public Shared Operator + (c1 as C, c2 as C) as C
End Operator
Sub F(x as C?, y as C?)
dim z = x + y 'BIND:"x + y"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodAdd-IsLifted) (OperatorMethod: Function C.op_Addition(c1 As C, c2 As C) As C) (OperationKind.BinaryOperatorExpression, Type: System.Nullable(Of C)) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of C)) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of C)) (Syntax: 'y')
]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyNonLiftedUserDefinedBinaryOperators1()
Dim source = <![CDATA[
Structure C
Public Shared Operator + (c1 as C, c2 as C) as C
End Operator
Sub F(x as C, y as C)
dim z = x + y 'BIND:"x + y"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperationKind.OperatorMethodAdd) (OperatorMethod: Function C.op_Addition(c1 As C, c2 As C) As C) (OperationKind.BinaryOperatorExpression, Type: C) (Syntax: 'x + y')
Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'x')
Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'y')
]]>.Value
VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree)
End Sub
End Class
End Namespace
......@@ -13,15 +13,15 @@ Option Strict Off
Module Program
Sub Main(args As String())
Dim d = Nothing
d.Foo'BIND:"d.Foo"
d.F'BIND:"d.F"
End Sub
End Module
]]>.Value
Dim expectedOperationTree = <![CDATA[
IOperation: (OperationKind.None) (Syntax: 'd.Foo')
IOperation: (OperationKind.None) (Syntax: 'd.F')
Children(1):
IDynamicMemberReferenceExpression (Member Name: "Foo", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.Foo')
IDynamicMemberReferenceExpression (Member Name: "F", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.F')
Type Arguments(0)
Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'd')
]]>.Value
......@@ -38,15 +38,15 @@ Option Strict Off
Module Program
Sub Main(args As String())
Dim d = Nothing
d.Foo(Of String)'BIND:"d.Foo(Of String)"
d.F(Of String)'BIND:"d.F(Of String)"
End Sub
End Module
]]>.Value
Dim expectedOperationTree = <![CDATA[
IOperation: (OperationKind.None) (Syntax: 'd.Foo(Of String)')
IOperation: (OperationKind.None) (Syntax: 'd.F(Of String)')
Children(1):
IDynamicMemberReferenceExpression (Member Name: "Foo", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.Foo(Of String)')
IDynamicMemberReferenceExpression (Member Name: "F", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.F(Of String)')
Type Arguments(1):
Symbol: System.String
Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'd')
......@@ -64,15 +64,15 @@ Option Strict Off
Module Program
Sub Main(args As String())
Dim d = Nothing
d.Foo(Of)'BIND:"d.Foo(Of)"
d.F(Of)'BIND:"d.F(Of)"
End Sub
End Module
]]>.Value
Dim expectedOperationTree = <![CDATA[
IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.Foo(Of)')
IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.F(Of)')
Children(1):
IDynamicMemberReferenceExpression (Member Name: "Foo", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object, IsInvalid) (Syntax: 'd.Foo(Of)')
IDynamicMemberReferenceExpression (Member Name: "F", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object, IsInvalid) (Syntax: 'd.F(Of)')
Type Arguments(1):
Symbol: ?
Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'd')
......@@ -80,8 +80,8 @@ IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.Foo(Of)')
Dim expectedDiagnostics = <![CDATA[
BC30182: Type expected.
d.Foo(Of)'BIND:"d.Foo(Of)"
~
d.F(Of)'BIND:"d.F(Of)"
~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of InvocationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
......@@ -94,15 +94,15 @@ Option Strict Off
Module Program
Sub Main(args As String())
Dim d = Nothing
d.Foo()'BIND:"d.Foo()"
d.F()'BIND:"d.F()"
End Sub
End Module
]]>.Value
Dim expectedOperationTree = <![CDATA[
IOperation: (OperationKind.None) (Syntax: 'd.Foo()')
IOperation: (OperationKind.None) (Syntax: 'd.F()')
Children(1):
IDynamicMemberReferenceExpression (Member Name: "Foo", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.Foo')
IDynamicMemberReferenceExpression (Member Name: "F", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.F')
Type Arguments(0)
Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'd')
]]>.Value
......@@ -119,15 +119,15 @@ Option Strict Off
Module Program
Sub Main(args As String())
Dim d = Nothing
d.Foo('BIND:"d.Foo("
d.F('BIND:"d.F("
End Sub
End Module
]]>.Value
Dim expectedOperationTree = <![CDATA[
IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.Foo(')
IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.F(')
Children(2):
IDynamicMemberReferenceExpression (Member Name: "Foo", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.Foo')
IDynamicMemberReferenceExpression (Member Name: "F", Containing Type: null) (OperationKind.DynamicMemberReferenceExpression, Type: System.Object) (Syntax: 'd.F')
Type Arguments(0)
Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'd')
IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: System.Object, IsInvalid) (Syntax: '')
......@@ -137,11 +137,11 @@ IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.Foo(')
Dim expectedDiagnostics = <![CDATA[
BC30198: ')' expected.
d.Foo('BIND:"d.Foo("
~
d.F('BIND:"d.F("
~
BC30201: Expression expected.
d.Foo('BIND:"d.Foo("
~
d.F('BIND:"d.F("
~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of InvocationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
......
......@@ -1861,5 +1861,79 @@ IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.Conversi
VerifyOperationTreeForTest(Of UnaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyLiftedUnaryOperators1()
Dim source = <![CDATA[
Class C
Sub F(x as Integer?)
dim y = -x 'BIND:"-x"
End Sub
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IUnaryOperatorExpression (UnaryOperationKind.IntegerMinus-IsLifted) (OperationKind.UnaryOperatorExpression, Type: System.Nullable(Of System.Int32)) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of System.Int32)) (Syntax: 'x')]]>.Value
VerifyOperationTreeForTest(Of UnaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyNonLiftedUnaryOperators1()
Dim source = <![CDATA[
Class C
Sub F(x as Integer)
dim y = -x 'BIND:"-x"
End Sub
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IUnaryOperatorExpression (UnaryOperationKind.IntegerMinus) (OperationKind.UnaryOperatorExpression, Type: System.Int32) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x')]]>.Value
VerifyOperationTreeForTest(Of UnaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyLiftedUserDefinedUnaryOperators1()
Dim source = <![CDATA[
Structure C
Public Shared Operator -(c as C) as C
End Operator
Sub F(x as C?)
dim y = -x 'BIND:"-x"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IUnaryOperatorExpression (UnaryOperationKind.OperatorMethodMinus-IsLifted) (OperatorMethod: Function C.op_UnaryNegation(c As C) As C) (OperationKind.UnaryOperatorExpression, Type: System.Nullable(Of C)) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Nullable(Of C)) (Syntax: 'x')]]>.Value
VerifyOperationTreeForTest(Of UnaryExpressionSyntax)(source, expectedOperationTree)
End Sub
<Fact>
Public Sub VerifyNonLiftedUserDefinedUnaryOperators1()
Dim source = <![CDATA[
Structure C
Public Shared Operator -(c as C) as C
End Operator
Sub F(x as C)
dim y = -x 'BIND:"-x"
End Sub
End Structure
]]>.Value
Dim expectedOperationTree = <![CDATA[
IUnaryOperatorExpression (UnaryOperationKind.OperatorMethodMinus) (OperatorMethod: Function C.op_UnaryNegation(c As C) As C) (OperationKind.UnaryOperatorExpression, Type: C) (Syntax: '-x')
Operand: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'x')]]>.Value
VerifyOperationTreeForTest(Of UnaryExpressionSyntax)(source, expectedOperationTree)
End Sub
End Class
End Namespace
......@@ -55,6 +55,7 @@ public static void Verify(string expectedOperationTree, string actualOperationTr
string actual = actualOperationTree.Trim(newLineChars);
expectedOperationTree = expectedOperationTree.Trim(newLineChars);
expectedOperationTree = Regex.Replace(expectedOperationTree, "([^\r])\n", "$1" + Environment.NewLine);
AssertEx.AreEqual(expectedOperationTree, actual);
}
......@@ -758,7 +759,14 @@ public override void VisitUnaryOperatorExpression(IUnaryOperatorExpression opera
LogString(nameof(IUnaryOperatorExpression));
var kindStr = $"{nameof(UnaryOperationKind)}.{operation.UnaryOperationKind}";
LogString($" ({kindStr})");
if (operation.IsLifted)
{
LogString($" ({kindStr}-IsLifted)");
}
else
{
LogString($" ({kindStr})");
}
LogHasOperatorMethodExpressionCommon(operation);
LogCommonPropertiesAndNewLine(operation);
......@@ -770,7 +778,14 @@ public override void VisitBinaryOperatorExpression(IBinaryOperatorExpression ope
LogString(nameof(IBinaryOperatorExpression));
var kindStr = $"{nameof(BinaryOperationKind)}.{operation.BinaryOperationKind}";
LogString($" ({kindStr})");
if (operation.IsLifted)
{
LogString($" ({kindStr}-IsLifted)");
}
else
{
LogString($" ({kindStr})");
}
LogHasOperatorMethodExpressionCommon(operation);
LogCommonPropertiesAndNewLine(operation);
......@@ -1059,7 +1074,14 @@ public override void VisitCompoundAssignmentExpression(ICompoundAssignmentExpres
LogString(nameof(ICompoundAssignmentExpression));
var kindStr = $"{nameof(BinaryOperationKind)}.{operation.BinaryOperationKind}";
LogString($" ({kindStr})");
if (operation.IsLifted)
{
LogString($" ({kindStr}-IsLifted)");
}
else
{
LogString($" ({kindStr})");
}
LogHasOperatorMethodExpressionCommon(operation);
LogCommonPropertiesAndNewLine(operation);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册