提交 4e6e43f9 编写于 作者: C CyrusNajmabadi

Merge branch 'addUsingOOP7' into addUsingOOP8

...@@ -479,7 +479,6 @@ private BoundExpression BindSimpleBinaryOperator(BinaryExpressionSyntax node, Di ...@@ -479,7 +479,6 @@ private BoundExpression BindSimpleBinaryOperator(BinaryExpressionSyntax node, Di
bool leftNull = left.IsLiteralNull(); bool leftNull = left.IsLiteralNull();
bool rightNull = right.IsLiteralNull(); bool rightNull = right.IsLiteralNull();
bool isEquality = kind == BinaryOperatorKind.Equal || kind == BinaryOperatorKind.NotEqual; bool isEquality = kind == BinaryOperatorKind.Equal || kind == BinaryOperatorKind.NotEqual;
if (isEquality && leftNull && rightNull) if (isEquality && leftNull && rightNull)
{ {
return new BoundLiteral(node, ConstantValue.Create(kind == BinaryOperatorKind.Equal), GetSpecialType(SpecialType.System_Boolean, diagnostics, node)); return new BoundLiteral(node, ConstantValue.Create(kind == BinaryOperatorKind.Equal), GetSpecialType(SpecialType.System_Boolean, diagnostics, node));
...@@ -625,6 +624,19 @@ private void ReportAssignmentOperatorError(AssignmentExpressionSyntax node, Diag ...@@ -625,6 +624,19 @@ private void ReportAssignmentOperatorError(AssignmentExpressionSyntax node, Diag
private static void ReportBinaryOperatorError(ExpressionSyntax node, DiagnosticBag diagnostics, SyntaxToken operatorToken, BoundExpression left, BoundExpression right, LookupResultKind resultKind) private static void ReportBinaryOperatorError(ExpressionSyntax node, DiagnosticBag diagnostics, SyntaxToken operatorToken, BoundExpression left, BoundExpression right, LookupResultKind resultKind)
{ {
if ((operatorToken.Kind() == SyntaxKind.EqualsEqualsToken || operatorToken.Kind() == SyntaxKind.ExclamationEqualsToken) &&
(left.IsLiteralDefault() && right.IsLiteralDefault()))
{
Error(diagnostics, ErrorCode.ERR_AmbigBinaryOpsOnDefault, node, operatorToken.Text);
return;
}
if (left.IsLiteralDefault() || right.IsLiteralDefault())
{
Error(diagnostics, ErrorCode.ERR_BadOpOnNullOrDefault, node, operatorToken.Text, "default");
return;
}
ErrorCode errorCode = resultKind == LookupResultKind.Ambiguous ? ErrorCode errorCode = resultKind == LookupResultKind.Ambiguous ?
ErrorCode.ERR_AmbigBinaryOps : // Operator '{0}' is ambiguous on operands of type '{1}' and '{2}' ErrorCode.ERR_AmbigBinaryOps : // Operator '{0}' is ambiguous on operands of type '{1}' and '{2}'
ErrorCode.ERR_BadBinaryOps; // Operator '{0}' cannot be applied to operands of type '{1}' and '{2}' ErrorCode.ERR_BadBinaryOps; // Operator '{0}' cannot be applied to operands of type '{1}' and '{2}'
...@@ -1023,6 +1035,13 @@ private TypeSymbol GetBinaryOperatorErrorType(BinaryOperatorKind kind, Diagnosti ...@@ -1023,6 +1035,13 @@ private TypeSymbol GetBinaryOperatorErrorType(BinaryOperatorKind kind, Diagnosti
private BinaryOperatorAnalysisResult BinaryOperatorOverloadResolution(BinaryOperatorKind kind, BoundExpression left, BoundExpression right, CSharpSyntaxNode node, DiagnosticBag diagnostics, out LookupResultKind resultKind, out ImmutableArray<MethodSymbol> originalUserDefinedOperators) private BinaryOperatorAnalysisResult BinaryOperatorOverloadResolution(BinaryOperatorKind kind, BoundExpression left, BoundExpression right, CSharpSyntaxNode node, DiagnosticBag diagnostics, out LookupResultKind resultKind, out ImmutableArray<MethodSymbol> originalUserDefinedOperators)
{ {
if (!IsDefaultLiteralAllowedInBinaryOperator(kind, left, right))
{
resultKind = LookupResultKind.OverloadResolutionFailure;
originalUserDefinedOperators = default(ImmutableArray<MethodSymbol>);
return default(BinaryOperatorAnalysisResult);
}
var result = BinaryOperatorOverloadResolutionResult.GetInstance(); var result = BinaryOperatorOverloadResolutionResult.GetInstance();
HashSet<DiagnosticInfo> useSiteDiagnostics = null; HashSet<DiagnosticInfo> useSiteDiagnostics = null;
this.OverloadResolution.BinaryOperatorOverloadResolution(kind, left, right, result, ref useSiteDiagnostics); this.OverloadResolution.BinaryOperatorOverloadResolution(kind, left, right, result, ref useSiteDiagnostics);
...@@ -1073,6 +1092,19 @@ private BinaryOperatorAnalysisResult BinaryOperatorOverloadResolution(BinaryOper ...@@ -1073,6 +1092,19 @@ private BinaryOperatorAnalysisResult BinaryOperatorOverloadResolution(BinaryOper
return possiblyBest; return possiblyBest;
} }
private bool IsDefaultLiteralAllowedInBinaryOperator(BinaryOperatorKind kind, BoundExpression left, BoundExpression right)
{
bool isEquality = kind == BinaryOperatorKind.Equal || kind == BinaryOperatorKind.NotEqual;
if (isEquality)
{
return !left.IsLiteralDefault() || !right.IsLiteralDefault();
}
else
{
return !left.IsLiteralDefault() && !right.IsLiteralDefault();
}
}
private UnaryOperatorAnalysisResult UnaryOperatorOverloadResolution( private UnaryOperatorAnalysisResult UnaryOperatorOverloadResolution(
UnaryOperatorKind kind, UnaryOperatorKind kind,
BoundExpression operand, BoundExpression operand,
...@@ -2180,12 +2212,12 @@ private BoundExpression BindUnaryOperatorCore(CSharpSyntaxNode node, string oper ...@@ -2180,12 +2212,12 @@ private BoundExpression BindUnaryOperatorCore(CSharpSyntaxNode node, string oper
{ {
UnaryOperatorKind kind = SyntaxKindToUnaryOperatorKind(node.Kind()); UnaryOperatorKind kind = SyntaxKindToUnaryOperatorKind(node.Kind());
bool isOperandTypeNull = operand.IsLiteralNull(); bool isOperandTypeNull = operand.IsLiteralNull() || operand.IsLiteralDefault();
if (isOperandTypeNull) if (isOperandTypeNull)
{ {
// Dev10 does not allow unary prefix operators to be applied to the null literal // Dev10 does not allow unary prefix operators to be applied to the null literal
// (or other typeless expressions). // (or other typeless expressions).
Error(diagnostics, ErrorCode.ERR_BadUnaryOp, node, operatorText, operand.Display); Error(diagnostics, ErrorCode.ERR_BadOpOnNullOrDefault, node, operatorText, operand.Display);
} }
// If the operand is bad, avoid generating cascading errors. // If the operand is bad, avoid generating cascading errors.
...@@ -3236,7 +3268,16 @@ internal static ConstantValue GetAsOperatorConstantResult(TypeSymbol operandType ...@@ -3236,7 +3268,16 @@ internal static ConstantValue GetAsOperatorConstantResult(TypeSymbol operandType
private BoundExpression GenerateNullCoalescingBadBinaryOpsError(BinaryExpressionSyntax node, BoundExpression leftOperand, BoundExpression rightOperand, Conversion leftConversion, DiagnosticBag diagnostics) private BoundExpression GenerateNullCoalescingBadBinaryOpsError(BinaryExpressionSyntax node, BoundExpression leftOperand, BoundExpression rightOperand, Conversion leftConversion, DiagnosticBag diagnostics)
{ {
Error(diagnostics, ErrorCode.ERR_BadBinaryOps, node, SyntaxFacts.GetText(node.OperatorToken.Kind()), leftOperand.Display, rightOperand.Display);
if (leftOperand.IsLiteralDefault() || rightOperand.IsLiteralDefault())
{
Error(diagnostics, ErrorCode.ERR_BadOpOnNullOrDefault, node, node.OperatorToken.Text, "default");
}
else
{
Error(diagnostics, ErrorCode.ERR_BadBinaryOps, node, SyntaxFacts.GetText(node.OperatorToken.Kind()), leftOperand.Display, rightOperand.Display);
}
return new BoundNullCoalescingOperator(node, leftOperand, rightOperand, return new BoundNullCoalescingOperator(node, leftOperand, rightOperand,
leftConversion, CreateErrorType(), hasErrors: true); leftConversion, CreateErrorType(), hasErrors: true);
} }
......
...@@ -304,6 +304,15 @@ internal class CSharpResources { ...@@ -304,6 +304,15 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Operator &apos;{0}&apos; is ambiguous on operands &apos;default&apos; and &apos;default&apos;.
/// </summary>
internal static string ERR_AmbigBinaryOpsOnDefault {
get {
return ResourceManager.GetString("ERR_AmbigBinaryOpsOnDefault", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to The call is ambiguous between the following methods or properties: &apos;{0}&apos; and &apos;{1}&apos;. /// Looks up a localized string similar to The call is ambiguous between the following methods or properties: &apos;{0}&apos; and &apos;{1}&apos;.
/// </summary> /// </summary>
...@@ -1735,6 +1744,15 @@ internal class CSharpResources { ...@@ -1735,6 +1744,15 @@ internal class CSharpResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Operator &apos;{0}&apos; cannot be applied to operand &apos;{1}&apos;.
/// </summary>
internal static string ERR_BadOpOnNullOrDefault {
get {
return ResourceManager.GetString("ERR_BadOpOnNullOrDefault", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to The parameter modifier &apos;out&apos; cannot be used with &apos;this&apos; . /// Looks up a localized string similar to The parameter modifier &apos;out&apos; cannot be used with &apos;this&apos; .
/// </summary> /// </summary>
......
...@@ -426,6 +426,9 @@ ...@@ -426,6 +426,9 @@
<data name="ERR_BadUnaryOp" xml:space="preserve"> <data name="ERR_BadUnaryOp" xml:space="preserve">
<value>Operator '{0}' cannot be applied to operand of type '{1}'</value> <value>Operator '{0}' cannot be applied to operand of type '{1}'</value>
</data> </data>
<data name="ERR_BadOpOnNullOrDefault" xml:space="preserve">
<value>Operator '{0}' cannot be applied to operand '{1}'</value>
</data>
<data name="ERR_ThisInStaticMeth" xml:space="preserve"> <data name="ERR_ThisInStaticMeth" xml:space="preserve">
<value>Keyword 'this' is not valid in a static property, static method, or static field initializer</value> <value>Keyword 'this' is not valid in a static property, static method, or static field initializer</value>
</data> </data>
...@@ -450,6 +453,9 @@ ...@@ -450,6 +453,9 @@
<data name="ERR_AmbigBinaryOps" xml:space="preserve"> <data name="ERR_AmbigBinaryOps" xml:space="preserve">
<value>Operator '{0}' is ambiguous on operands of type '{1}' and '{2}'</value> <value>Operator '{0}' is ambiguous on operands of type '{1}' and '{2}'</value>
</data> </data>
<data name="ERR_AmbigBinaryOpsOnDefault" xml:space="preserve">
<value>Operator '{0}' is ambiguous on operands 'default' and 'default'</value>
</data>
<data name="ERR_AmbigUnaryOp" xml:space="preserve"> <data name="ERR_AmbigUnaryOp" xml:space="preserve">
<value>Operator '{0}' is ambiguous on an operand of type '{1}'</value> <value>Operator '{0}' is ambiguous on an operand of type '{1}'</value>
</data> </data>
......
...@@ -1481,11 +1481,12 @@ internal enum ErrorCode ...@@ -1481,11 +1481,12 @@ internal enum ErrorCode
ERR_NoRefOutWhenRefOnly = 8308, ERR_NoRefOutWhenRefOnly = 8308,
ERR_NoNetModuleOutputWhenRefOutOrRefOnly = 8309, ERR_NoNetModuleOutputWhenRefOutOrRefOnly = 8309,
// Available = 8310, ERR_BadOpOnNullOrDefault = 8310,
ERR_BadDynamicMethodArgDefaultLiteral = 8311, ERR_BadDynamicMethodArgDefaultLiteral = 8311,
ERR_DefaultLiteralNotValid = 8312, ERR_DefaultLiteralNotValid = 8312,
WRN_DefaultInSwitch = 8313, WRN_DefaultInSwitch = 8313,
ERR_PatternWrongGenericTypeInVersion = 8314, ERR_PatternWrongGenericTypeInVersion = 8314,
ERR_AmbigBinaryOpsOnDefault = 8315,
#endregion diagnostics introduced for C# 7.1 #endregion diagnostics introduced for C# 7.1
} }
......
...@@ -1055,19 +1055,27 @@ object M() ...@@ -1055,19 +1055,27 @@ object M()
"; ";
CreateStandardCompilation(text).VerifyDiagnostics( CreateStandardCompilation(text).VerifyDiagnostics(
// (9,17): error CS0023: Operator '!' cannot be applied to operand of type 'object' // (9,17): error CS0023: Operator '!' cannot be applied to operand of type 'object'
Diagnostic(ErrorCode.ERR_BadUnaryOp, "!q").WithArguments("!", "object"), // if (!q) // CS0023
// (12,26): error CS0023: Operator '-' cannot be applied to operand of type '<null>' Diagnostic(ErrorCode.ERR_BadUnaryOp, "!q").WithArguments("!", "object").WithLocation(9, 17),
Diagnostic(ErrorCode.ERR_BadUnaryOp, "-null").WithArguments("-", "<null>"), // (12,26): error CS8310: Operator '-' cannot be applied to operand '<null>'
// (13,19): error CS0023: Operator '!' cannot be applied to operand of type '<null>' // object obj = -null; // CS0023
Diagnostic(ErrorCode.ERR_BadUnaryOp, "!null").WithArguments("!", "<null>"), Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "-null").WithArguments("-", "<null>").WithLocation(12, 26),
// (14,19): error CS0023: Operator '~' cannot be applied to operand of type '<null>' // (13,19): error CS8310: Operator '!' cannot be applied to operand '<null>'
Diagnostic(ErrorCode.ERR_BadUnaryOp, "~null").WithArguments("~", "<null>"), // obj = !null; // CS0023
Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "!null").WithArguments("!", "<null>").WithLocation(13, 19),
// (14,19): error CS8310: Operator '~' cannot be applied to operand '<null>'
// obj = ~null; // CS0023
Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "~null").WithArguments("~", "<null>").WithLocation(14, 19),
// (16,13): error CS0023: Operator '++' cannot be applied to operand of type 'object' // (16,13): error CS0023: Operator '++' cannot be applied to operand of type 'object'
Diagnostic(ErrorCode.ERR_BadUnaryOp, "obj++").WithArguments("++", "object"), // obj++; // CS0023
Diagnostic(ErrorCode.ERR_BadUnaryOp, "obj++").WithArguments("++", "object").WithLocation(16, 13),
// (17,13): error CS0023: Operator '--' cannot be applied to operand of type 'object' // (17,13): error CS0023: Operator '--' cannot be applied to operand of type 'object'
Diagnostic(ErrorCode.ERR_BadUnaryOp, "--obj").WithArguments("--", "object"), // --obj; // CS0023
// (18,20): error CS0023: Operator '+' cannot be applied to operand of type '<null>' Diagnostic(ErrorCode.ERR_BadUnaryOp, "--obj").WithArguments("--", "object").WithLocation(17, 13),
Diagnostic(ErrorCode.ERR_BadUnaryOp, "+null").WithArguments("+", "<null>")); // (18,20): error CS8310: Operator '+' cannot be applied to operand '<null>'
// return +null; // CS0023
Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "+null").WithArguments("+", "<null>").WithLocation(18, 20)
);
} }
[WorkItem(539590, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539590")] [WorkItem(539590, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539590")]
...@@ -1092,18 +1100,19 @@ public static void Main() ...@@ -1092,18 +1100,19 @@ public static void Main()
} }
"; ";
CreateStandardCompilation(text).VerifyDiagnostics( CreateStandardCompilation(text).VerifyDiagnostics(
// (6,19): error CS0023: Operator '!' cannot be applied to operand of type '<null>' // (6,19): error CS8310: Operator '!' cannot be applied to operand '<null>'
// bool? b = !null; // CS0023 // bool? b = !null; // CS0023
Diagnostic(ErrorCode.ERR_BadUnaryOp, "!null").WithArguments("!", "<null>"), Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "!null").WithArguments("!", "<null>").WithLocation(6, 19),
// (7,18): error CS0023: Operator '~' cannot be applied to operand of type '<null>' // (7,18): error CS8310: Operator '~' cannot be applied to operand '<null>'
// int? n = ~null; // CS0023 // int? n = ~null; // CS0023
Diagnostic(ErrorCode.ERR_BadUnaryOp, "~null").WithArguments("~", "<null>"), Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "~null").WithArguments("~", "<null>").WithLocation(7, 18),
// (8,20): error CS0023: Operator '+' cannot be applied to operand of type '<null>' // (8,20): error CS8310: Operator '+' cannot be applied to operand '<null>'
// float? f = +null; // CS0023 // float? f = +null; // CS0023
Diagnostic(ErrorCode.ERR_BadUnaryOp, "+null").WithArguments("+", "<null>"), Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "+null").WithArguments("+", "<null>").WithLocation(8, 20),
// (9,19): error CS0023: Operator '-' cannot be applied to operand of type '<null>' // (9,19): error CS8310: Operator '-' cannot be applied to operand '<null>'
// long? u = -null; // CS0023 // long? u = -null; // CS0023
Diagnostic(ErrorCode.ERR_BadUnaryOp, "-null").WithArguments("-", "<null>")); Diagnostic(ErrorCode.ERR_BadOpOnNullOrDefault, "-null").WithArguments("-", "<null>").WithLocation(9, 19)
);
} }
[WorkItem(539590, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539590")] [WorkItem(539590, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539590")]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册