Browse Source

[CodeIssue] CompareFloatWithEqualityOperatorIssue: handle double.NaN case

newNRvisualizers
Mansheng Yang 13 years ago
parent
commit
b14db35ce2
  1. 44
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CompareFloatWithEqualityOperatorIssue.cs
  2. 24
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CompareFloatWithEqualityOperatorIssueTests.cs

44
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/CompareFloatWithEqualityOperatorIssue.cs

@ -48,16 +48,41 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -48,16 +48,41 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{
}
bool IsFloatingPoint(Expression expr)
static bool IsFloatingPointType (IType type)
{
var resolveResult = ctx.Resolve (expr);
if (resolveResult == null)
return false;
var typeDef = resolveResult.Type.GetDefinition ();
return typeDef != null &&
var typeDef = type.GetDefinition ();
return typeDef != null &&
(typeDef.KnownTypeCode == KnownTypeCode.Single || typeDef.KnownTypeCode == KnownTypeCode.Double);
}
bool IsFloatingPoint(AstNode node)
{
return IsFloatingPointType (ctx.Resolve (node).Type);
}
bool IsNaN (AstNode node)
{
var memberReferenceExpr = node as MemberReferenceExpression;
if (memberReferenceExpr == null)
return false;
var typeReferenceExpr = memberReferenceExpr.Target as TypeReferenceExpression;
if (typeReferenceExpr == null)
return false;
return IsFloatingPointType (ctx.ResolveType (typeReferenceExpr.Type)) &&
memberReferenceExpr.MemberName == "NaN";
}
void AddIsNaNIssue(BinaryOperatorExpression binaryOperatorExpr, Expression argExpr)
{
AddIssue (binaryOperatorExpr, ctx.TranslateString ("Use double.IsNan()"), script => {
Expression expr = new InvocationExpression (new MemberReferenceExpression (
new TypeReferenceExpression (new PrimitiveType ("double")), "IsNaN"), argExpr.Clone ());
if (binaryOperatorExpr.Operator == BinaryOperatorType.InEquality)
expr = new UnaryOperatorExpression (UnaryOperatorType.Not, expr);
script.Replace (binaryOperatorExpr, expr);
});
}
public override void VisitBinaryOperatorExpression (BinaryOperatorExpression binaryOperatorExpression)
{
base.VisitBinaryOperatorExpression (binaryOperatorExpression);
@ -65,7 +90,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring @@ -65,7 +90,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (binaryOperatorExpression.Operator != BinaryOperatorType.Equality &&
binaryOperatorExpression.Operator != BinaryOperatorType.InEquality)
return;
if (IsFloatingPoint(binaryOperatorExpression.Left) || IsFloatingPoint(binaryOperatorExpression.Right)) {
if (IsNaN(binaryOperatorExpression.Left)) {
AddIsNaNIssue (binaryOperatorExpression, binaryOperatorExpression.Right);
} else if (IsNaN (binaryOperatorExpression.Right)) {
AddIsNaNIssue (binaryOperatorExpression, binaryOperatorExpression.Left);
} else if (IsFloatingPoint(binaryOperatorExpression.Left) || IsFloatingPoint(binaryOperatorExpression.Right)) {
AddIssue (binaryOperatorExpression, ctx.TranslateString ("Compare a difference with EPSILON"),
script =>
{

24
ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/CompareFloatWithEqualityOperatorIssueTests.cs

@ -66,5 +66,29 @@ class TestClass @@ -66,5 +66,29 @@ class TestClass
{
Test ("!=", ">");
}
[Test]
public void TestNaN ()
{
var input = @"
class TestClass
{
void TestMethod (double x)
{
bool test = x == double.NaN;
bool test2 = x != double.NaN;
}
}";
var output = @"
class TestClass
{
void TestMethod (double x)
{
bool test = double.IsNaN (x);
bool test2 = !double.IsNaN (x);
}
}";
Test<CompareFloatWithEqualityOperatorIssue> (input, 2, output);
}
}
}

Loading…
Cancel
Save