Browse Source

[CodeIssue] Fixed bug in redundant type cast issue.

newNRvisualizers
mkrueger 14 years ago
parent
commit
bb8df03211
  1. 36
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantTypeCastIssue.cs
  2. 24
      ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/RedundantTypeCastIssueTests.cs

36
ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/RedundantTypeCastIssue.cs

@ -28,6 +28,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.CSharp.Refactoring namespace ICSharpCode.NRefactory.CSharp.Refactoring
{ {
@ -73,17 +74,45 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
var invocationExpr = memberRefExpr.Parent as InvocationExpression; var invocationExpr = memberRefExpr.Parent as InvocationExpression;
if (invocationExpr != null && invocationExpr.Target == memberRefExpr) { if (invocationExpr != null && invocationExpr.Target == memberRefExpr) {
var invocationResolveResult = ctx.Resolve (invocationExpr) as InvocationResolveResult; var invocationResolveResult = ctx.Resolve (invocationExpr) as InvocationResolveResult;
if (invocationResolveResult != null) if (invocationResolveResult != null) {
return invocationResolveResult.Member.DeclaringType; return invocationResolveResult.Member.DeclaringType;
}
} else { } else {
var memberResolveResult = ctx.Resolve (memberRefExpr) as MemberResolveResult; var memberResolveResult = ctx.Resolve (memberRefExpr) as MemberResolveResult;
if (memberResolveResult != null) if (memberResolveResult != null) {
return memberResolveResult.Member.DeclaringType; return memberResolveResult.Member.DeclaringType;
}
} }
} }
return ctx.GetExpectedType (typeCastNode); return ctx.GetExpectedType (typeCastNode);
} }
bool IsExplicitImplementation(IType exprType, IType interfaceType, Expression typeCastNode)
{
var memberRefExpr = typeCastNode.Parent as MemberReferenceExpression;
if (memberRefExpr != null) {
var rr = ctx.Resolve(memberRefExpr);
var memberResolveResult = rr as MemberResolveResult;
if (memberResolveResult != null) {
foreach (var member in exprType.GetMembers (m => m.EntityType == memberResolveResult.Member.EntityType)) {
if (member.IsExplicitInterfaceImplementation && member.ImplementedInterfaceMembers.Contains (memberResolveResult.Member)) {
return true;
}
}
}
var methodGroupResolveResult = rr as MethodGroupResolveResult;
if (methodGroupResolveResult != null) {
foreach (var member in exprType.GetMethods ()) {
if (member.IsExplicitInterfaceImplementation && member.ImplementedInterfaceMembers.Any (m => methodGroupResolveResult.Methods.Contains ((IMethod)m))) {
return true;
}
}
}
}
return false;
}
void AddIssue (Expression typeCastNode, Expression expr, TextLocation start, TextLocation end) void AddIssue (Expression typeCastNode, Expression expr, TextLocation start, TextLocation end)
{ {
AddIssue (start, end, ctx.TranslateString ("Remove redundant type cast"), AddIssue (start, end, ctx.TranslateString ("Remove redundant type cast"),
@ -94,9 +123,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{ {
while (typeCastNode.Parent != null && typeCastNode.Parent is ParenthesizedExpression) while (typeCastNode.Parent != null && typeCastNode.Parent is ParenthesizedExpression)
typeCastNode = (Expression)typeCastNode.Parent; typeCastNode = (Expression)typeCastNode.Parent;
var expectedType = GetExpectedType (typeCastNode); var expectedType = GetExpectedType (typeCastNode);
var exprType = ctx.Resolve (expr).Type; var exprType = ctx.Resolve (expr).Type;
if (expectedType.Kind == TypeKind.Interface && IsExplicitImplementation (exprType, expectedType, typeCastNode))
return;
if (exprType.GetAllBaseTypes ().Any (t => t.Equals(expectedType))) if (exprType.GetAllBaseTypes ().Any (t => t.Equals(expectedType)))
AddIssue (typeCastNode, expr, castStart, castEnd); AddIssue (typeCastNode, expr, castStart, castEnd);
} }

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

@ -146,5 +146,29 @@ class TestClass
}"; }";
Test<RedundantTypeCastIssue> (input, 0); Test<RedundantTypeCastIssue> (input, 0);
} }
/// <summary>
/// Bug 7065 - "remove redundant type cast" false positive for explicit interface implementation
/// </summary>
[Test]
public void TestBug7065 ()
{
var input = @"
using System;
public class TestClass : IDisposable
{
void IDisposable.Dispose()
{
}
void Foo()
{
((IDisposable)this).Dispose();
}
}
";
Test<RedundantTypeCastIssue> (input, 0);
}
} }
} }

Loading…
Cancel
Save