|
|
|
@ -29,6 +29,8 @@ using ICSharpCode.NRefactory.PatternMatching; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using ICSharpCode.NRefactory.TypeSystem; |
|
|
|
using ICSharpCode.NRefactory.TypeSystem; |
|
|
|
using ICSharpCode.NRefactory.Semantics; |
|
|
|
using ICSharpCode.NRefactory.Semantics; |
|
|
|
|
|
|
|
using ICSharpCode.NRefactory.CSharp.Resolver; |
|
|
|
|
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
|
|
|
namespace ICSharpCode.NRefactory.CSharp.Refactoring |
|
|
|
{ |
|
|
|
{ |
|
|
|
@ -37,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring |
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public class RedundantUsingInspector : IInspector |
|
|
|
public class RedundantUsingInspector : IInspector |
|
|
|
{ |
|
|
|
{ |
|
|
|
string title = "Remove redundant using"; |
|
|
|
string title = "Remove redundant usings"; |
|
|
|
|
|
|
|
|
|
|
|
public string Title { |
|
|
|
public string Title { |
|
|
|
get { |
|
|
|
get { |
|
|
|
@ -52,26 +54,77 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring |
|
|
|
{ |
|
|
|
{ |
|
|
|
var visitor = new GatherVisitor (context, this); |
|
|
|
var visitor = new GatherVisitor (context, this); |
|
|
|
context.RootNode.AcceptVisitor (visitor); |
|
|
|
context.RootNode.AcceptVisitor (visitor); |
|
|
|
|
|
|
|
visitor.Collect (); |
|
|
|
return visitor.FoundIssues; |
|
|
|
return visitor.FoundIssues; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class GatherVisitor : GatherVisitorBase |
|
|
|
class GatherVisitor : GatherVisitorBase |
|
|
|
{ |
|
|
|
{ |
|
|
|
readonly RedundantUsingInspector inspector; |
|
|
|
readonly RedundantUsingInspector inspector; |
|
|
|
|
|
|
|
Dictionary<UsingDeclaration, bool> usingDeclarations = new Dictionary<UsingDeclaration, bool> (); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Stack<List<UsingDeclaration>> usingStack = new Stack<List<UsingDeclaration>> (); |
|
|
|
|
|
|
|
|
|
|
|
public GatherVisitor (BaseRefactoringContext ctx, RedundantUsingInspector inspector) : base (ctx) |
|
|
|
public GatherVisitor (BaseRefactoringContext ctx, RedundantUsingInspector inspector) : base (ctx) |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.inspector = inspector; |
|
|
|
this.inspector = inspector; |
|
|
|
|
|
|
|
usingStack.Push (new List<UsingDeclaration> ()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Collect () |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
foreach (var u in usingDeclarations.Where (u => !u.Value)) { |
|
|
|
|
|
|
|
var decl = u.Key; |
|
|
|
|
|
|
|
AddIssue (decl, inspector.Title, delegate { |
|
|
|
|
|
|
|
using (var script = ctx.StartScript ()) { |
|
|
|
|
|
|
|
foreach (var u2 in usingDeclarations.Where (a => !a.Value)) { |
|
|
|
|
|
|
|
script.Remove (u2.Key); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration) |
|
|
|
public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration) |
|
|
|
{ |
|
|
|
{ |
|
|
|
base.VisitUsingDeclaration(usingDeclaration); |
|
|
|
base.VisitUsingDeclaration(usingDeclaration); |
|
|
|
// TODO
|
|
|
|
usingDeclarations [usingDeclaration] = false; |
|
|
|
// return cSharpResolver.usedScopes
|
|
|
|
usingStack.Peek().Add(usingDeclaration); |
|
|
|
// .OfType<ITypeOrNamespaceReference> ()
|
|
|
|
|
|
|
|
// .Any (u => u.ResolveNamespace (ctx).NamespaceName == ns) || additionalNamespaces.Contains (ns);
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
usingStack.Push(new List<UsingDeclaration> (usingStack.Peek())); |
|
|
|
|
|
|
|
base.VisitNamespaceDeclaration(namespaceDeclaration); |
|
|
|
|
|
|
|
usingStack.Pop(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UseNamespace(string ns) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
foreach (var u in usingStack.Peek ()) { |
|
|
|
|
|
|
|
if (u.Namespace == ns) { |
|
|
|
|
|
|
|
usingDeclarations [u] = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.VisitIdentifierExpression(identifierExpression); |
|
|
|
|
|
|
|
UseNamespace(ctx.Resolve(identifierExpression).Type.Namespace); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void VisitInvocationExpression (InvocationExpression invocationExpression) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.VisitInvocationExpression (invocationExpression); |
|
|
|
|
|
|
|
var mg = ctx.Resolve (invocationExpression) as CSharpInvocationResolveResult; |
|
|
|
|
|
|
|
if (mg == null || !mg.IsExtensionMethodInvocation) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
UseNamespace (mg.Member.DeclaringType.Namespace); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|