From a50b205d6b15b973e43e1b00ae9a2f1ca70de102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Fri, 5 Oct 2012 09:45:29 +0200 Subject: [PATCH] [CodeIssues] Fixed unused parameters for methods used as delegates and event handlers. --- .../ParameterNotUsedIssue.cs | 47 +++++++++++++++++-- .../CodeIssues/ParameterNotUsedIssueTests.cs | 16 +++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableNotUsedIssues/ParameterNotUsedIssue.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableNotUsedIssues/ParameterNotUsedIssue.cs index cb9a51d76d..adf2b0cc69 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableNotUsedIssues/ParameterNotUsedIssue.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeIssues/VariableNotUsedIssues/ParameterNotUsedIssue.cs @@ -28,6 +28,8 @@ using ICSharpCode.NRefactory.Semantics; using System.Linq; using ICSharpCode.NRefactory.TypeSystem; using System.Collections.Generic; +using ICSharpCode.NRefactory.CSharp.Resolver; +using System; namespace ICSharpCode.NRefactory.CSharp.Refactoring { @@ -41,15 +43,48 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring #region ICodeIssueProvider implementation public IEnumerable GetIssues(BaseRefactoringContext context) { - return new GatherVisitor (context).GetIssues (); + var delegateVisitor = new GetDelgateUsagesVisitor (context); + context.RootNode.AcceptVisitor (delegateVisitor); + + return new GatherVisitor (context, delegateVisitor).GetIssues (); } #endregion + // Collect all methods that are used as delegate + class GetDelgateUsagesVisitor : DepthFirstAstVisitor + { + BaseRefactoringContext ctx; + public readonly List UsedMethods = new List (); + + public GetDelgateUsagesVisitor(BaseRefactoringContext ctx) + { + this.ctx = ctx; + } + + public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) + { + var mgr = ctx.Resolve (identifierExpression) as MethodGroupResolveResult; + if (mgr != null) + UsedMethods.AddRange (mgr.Methods); + base.VisitIdentifierExpression(identifierExpression); + } + + public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) + { + var mgr = ctx.Resolve (memberReferenceExpression) as MethodGroupResolveResult; + if (mgr != null) + UsedMethods.AddRange (mgr.Methods); + base.VisitMemberReferenceExpression(memberReferenceExpression); + } + } + class GatherVisitor : GatherVisitorBase { - public GatherVisitor (BaseRefactoringContext ctx) + GetDelgateUsagesVisitor usedDelegates; + public GatherVisitor (BaseRefactoringContext ctx, GetDelgateUsagesVisitor usedDelegates) : base (ctx) { + this.usedDelegates = usedDelegates; } public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) @@ -66,13 +101,15 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring return; if (member.ImplementedInterfaceMembers.Any ()) return; - - base.VisitMethodDeclaration(methodDeclaration); + if (usedDelegates.UsedMethods.Any (m => m.Region.Begin == methodDeclaration.StartLocation)) + return; + foreach (var parameter in methodDeclaration.Parameters) + parameter.AcceptVisitor (this); } public override void VisitParameterDeclaration (ParameterDeclaration parameterDeclaration) { - base.VisitParameterDeclaration (parameterDeclaration); + base.VisitParameterDeclaration (parameterDeclaration); if (!(parameterDeclaration.Parent is MethodDeclaration)) return; diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterNotUsedIssueTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterNotUsedIssueTests.cs index e939c3cfa0..5b47df9c4e 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterNotUsedIssueTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeIssues/ParameterNotUsedIssueTests.cs @@ -114,5 +114,21 @@ class TestClass { }"; Test (input, 0); } + + + [Test] + public void TestMethodUsedAsDelegateMethod () + { + var input = @"using System; +class TestClass { + public event EventHandler FooEvt; + void TestMethod () + { + FooEvt += FooBar; + } + void FooBar (object sender, EventArgs e) {} +}"; + Test (input, 0); + } } }