Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1389 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
29 changed files with 565 additions and 175 deletions
@ -0,0 +1,129 @@
@@ -0,0 +1,129 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.NRefactory.Parser.AST; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using NR = ICSharpCode.NRefactory.Parser; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Refactoring |
||||
{ |
||||
public class NRefactoryRefactoringProvider : RefactoringProvider |
||||
{ |
||||
public static readonly NRefactoryRefactoringProvider NRefactoryProviderInstance = new NRefactoryRefactoringProvider(); |
||||
|
||||
protected class PossibleTypeReference |
||||
{ |
||||
internal string Name; |
||||
internal bool Global; |
||||
internal int TypeParameterCount; |
||||
|
||||
public PossibleTypeReference(string name) |
||||
{ |
||||
this.Name = name; |
||||
} |
||||
|
||||
public PossibleTypeReference(TypeReference tr) |
||||
{ |
||||
this.Name = tr.SystemType; |
||||
this.Global = tr.IsGlobal; |
||||
this.TypeParameterCount = tr.GenericTypes.Count; |
||||
} |
||||
|
||||
public override int GetHashCode() |
||||
{ |
||||
return Name.GetHashCode() ^ Global.GetHashCode() ^ TypeParameterCount.GetHashCode(); |
||||
} |
||||
|
||||
public override bool Equals(object obj) |
||||
{ |
||||
if (!(obj is PossibleTypeReference)) return false; |
||||
if (this == obj) return true; |
||||
PossibleTypeReference myPossibleTypeReference = (PossibleTypeReference)obj; |
||||
return this.Name == myPossibleTypeReference.Name && this.Global == myPossibleTypeReference.Global && this.TypeParameterCount == myPossibleTypeReference.TypeParameterCount; |
||||
} |
||||
} |
||||
|
||||
private class FindPossibleTypeReferencesVisitor : NR.AbstractAstVisitor |
||||
{ |
||||
internal Dictionary<PossibleTypeReference, object> list = new Dictionary<PossibleTypeReference, object>(); |
||||
|
||||
public override object Visit(IdentifierExpression identifierExpression, object data) |
||||
{ |
||||
list[new PossibleTypeReference(identifierExpression.Identifier)] = data; |
||||
return base.Visit(identifierExpression, data); |
||||
} |
||||
|
||||
public override object Visit(TypeReference typeReference, object data) |
||||
{ |
||||
list[new PossibleTypeReference(typeReference)] = data; |
||||
return base.Visit(typeReference, data); |
||||
} |
||||
} |
||||
|
||||
protected Dictionary<PossibleTypeReference, object> FindPossibleTypeReferences(string extension, string fileContent) |
||||
{ |
||||
NR.IParser parser; |
||||
if (extension.Equals(".cs", StringComparison.InvariantCultureIgnoreCase)) |
||||
parser = NR.ParserFactory.CreateParser(NR.SupportedLanguage.CSharp, new StringReader(fileContent)); |
||||
else if (extension.Equals(".vb", StringComparison.InvariantCultureIgnoreCase)) |
||||
parser = NR.ParserFactory.CreateParser(NR.SupportedLanguage.VBNet, new StringReader(fileContent)); |
||||
else |
||||
return null; |
||||
parser.Parse(); |
||||
if (parser.Errors.count > 0) { |
||||
MessageService.ShowMessage("The operation cannot be performed because your sourcecode contains errors:\n" + parser.Errors.ErrorOutput); |
||||
return null; |
||||
} else { |
||||
FindPossibleTypeReferencesVisitor visitor = new FindPossibleTypeReferencesVisitor(); |
||||
parser.CompilationUnit.AcceptVisitor(visitor, null); |
||||
return visitor.list; |
||||
} |
||||
} |
||||
|
||||
public override bool SupportsFindUnusedUsingDeclarations { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public override IList<IUsing> FindUnusedUsingDeclarations(string fileName, string fileContent, ICompilationUnit cu) |
||||
{ |
||||
IClass @class = cu.Classes.Count == 0 ? null : cu.Classes[0]; |
||||
|
||||
Dictionary<PossibleTypeReference, object> references = FindPossibleTypeReferences(Path.GetExtension(fileName), fileContent); |
||||
if (references == null) return new IUsing[0]; |
||||
|
||||
Dictionary<IUsing, object> dict = new Dictionary<IUsing, object>(); |
||||
foreach (PossibleTypeReference tr in references.Keys) { |
||||
SearchTypeRequest request = new SearchTypeRequest(tr.Name, tr.TypeParameterCount, @class, cu, 1, 1); |
||||
SearchTypeResult response = cu.ProjectContent.SearchType(request); |
||||
if (response.UsedUsing != null) { |
||||
dict[response.UsedUsing] = null; |
||||
} |
||||
} |
||||
|
||||
List<IUsing> list = new List<IUsing>(); |
||||
foreach (IUsing import in cu.Usings) { |
||||
if (!dict.ContainsKey(import)) { |
||||
if (import.HasAliases) { |
||||
foreach (string key in import.Aliases.Keys) { |
||||
if (references.ContainsKey(new PossibleTypeReference(key))) |
||||
goto checkNextImport; |
||||
} |
||||
} |
||||
list.Add(import); // this using is unused
|
||||
} |
||||
checkNextImport:; |
||||
} |
||||
return list; |
||||
} |
||||
} |
||||
} |
@ -1,16 +0,0 @@
@@ -1,16 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Refactoring |
||||
{ |
||||
public static class NamespaceRefactoring |
||||
{ |
||||
|
||||
} |
||||
} |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.TextEditor.Document; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Refactoring |
||||
{ |
||||
public static class NamespaceRefactoringService |
||||
{ |
||||
static int CompareUsings(IUsing a, IUsing b) |
||||
{ |
||||
if (a.HasAliases != b.HasAliases) |
||||
return a.HasAliases ? 1 : -1; |
||||
if (a.Usings.Count != 0 && b.Usings.Count != 0) { |
||||
string u1 = a.Usings[0]; |
||||
string u2 = b.Usings[0]; |
||||
if (u1.StartsWith("System.") || u1 == "System") { |
||||
if (!(u2.StartsWith("System.") || u2 == "System")) |
||||
return -1; |
||||
} else { |
||||
if (u2.StartsWith("System.") || u2 == "System") |
||||
return 1; |
||||
} |
||||
return a.Usings[0].CompareTo(b.Usings[0]); |
||||
} |
||||
if (a.Aliases.Count != 0 && b.Aliases.Count != 0) { |
||||
return a.Aliases.Keys[0].CompareTo(b.Aliases.Keys[0]); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
public static void ManageUsings(string fileName, IDocument document, bool sort, bool removedUnused) |
||||
{ |
||||
ParseInformation info = ParserService.ParseFile(fileName, document.TextContent); |
||||
if (info == null) return; |
||||
ICompilationUnit cu = info.MostRecentCompilationUnit; |
||||
|
||||
List<IUsing> newUsings = new List<IUsing>(cu.Usings); |
||||
if (sort) { |
||||
newUsings.Sort(CompareUsings); |
||||
} |
||||
|
||||
if (removedUnused) { |
||||
IList<IUsing> decl = cu.ProjectContent.Language.RefactoringProvider.FindUnusedUsingDeclarations(fileName, document.TextContent, cu); |
||||
if (decl != null && decl.Count > 0) { |
||||
foreach (IUsing u in decl) { |
||||
string ns = null; |
||||
for (int i = 0; i < u.Usings.Count; i++) { |
||||
ns = u.Usings[i]; |
||||
if (ns == "System") break; |
||||
} |
||||
if (ns != "System") { // never remove "using System;"
|
||||
newUsings.Remove(u); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
cu.ProjectContent.Language.CodeGenerator.ReplaceUsings(document, cu.Usings, newUsings); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Reflection; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.TextEditor; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Refactoring |
||||
{ |
||||
/// <summary>
|
||||
/// Tests if the refactoring provider for the current document
|
||||
/// supports the specified option.
|
||||
/// </summary>
|
||||
/// <attribute name="supports">
|
||||
/// Same of the action that should be supported.
|
||||
/// "*" to test if refactoring is supported at all.
|
||||
/// </attribute>
|
||||
/// <example title="Test if refactoring is supported">
|
||||
/// <Condition name="RefactoringProviderSupports" supports="*">
|
||||
/// </example>
|
||||
/// <example title="Test if managing imports is supported">
|
||||
/// <Condition name="RefactoringProviderSupports" supports="FindUnusedUsingDeclarations">
|
||||
/// </example>
|
||||
public class RefactoringProviderSupportsConditionEvaluator : IConditionEvaluator |
||||
{ |
||||
public bool IsValid(object caller, Condition condition) |
||||
{ |
||||
if (WorkbenchSingleton.Workbench == null || WorkbenchSingleton.Workbench.ActiveWorkbenchWindow == null) { |
||||
return false; |
||||
} |
||||
ITextEditorControlProvider provider = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ActiveViewContent as ITextEditorControlProvider; |
||||
if (provider == null) return false; |
||||
LanguageProperties language = ParserService.CurrentProjectContent.Language; |
||||
if (language == null) return false; |
||||
|
||||
string supports = condition.Properties["supports"]; |
||||
if (supports == "*") return true; |
||||
RefactoringProvider rp = language.RefactoringProvider; |
||||
Type t = rp.GetType(); |
||||
try { |
||||
return (bool)t.InvokeMember("Supports" + supports, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty, null, rp, null); |
||||
} catch (Exception ex) { |
||||
LoggingService.Warn(ex.ToString()); |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public abstract class AbstractRefactoringCommand : AbstractMenuCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
if (ParserService.LoadSolutionProjectsThreadRunning) { |
||||
return; |
||||
} |
||||
if (WorkbenchSingleton.Workbench == null || WorkbenchSingleton.Workbench.ActiveWorkbenchWindow == null) { |
||||
return; |
||||
} |
||||
ITextEditorControlProvider provider = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow.ActiveViewContent as ITextEditorControlProvider; |
||||
if (provider == null) return; |
||||
LanguageProperties language = ParserService.CurrentProjectContent.Language; |
||||
if (language == null) return; |
||||
|
||||
RefactoringProvider rp = language.RefactoringProvider; |
||||
Run(provider.TextEditorControl, rp); |
||||
provider.TextEditorControl.Refresh(); |
||||
} |
||||
|
||||
protected abstract void Run(TextEditorControl textEditor, RefactoringProvider provider); |
||||
} |
||||
|
||||
public class RemoveUnusedUsingsCommand : AbstractRefactoringCommand |
||||
{ |
||||
protected override void Run(TextEditorControl textEditor, RefactoringProvider provider) |
||||
{ |
||||
NamespaceRefactoringService.ManageUsings(textEditor.FileName, textEditor.Document, true, true); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Refactoring |
||||
{ |
||||
public class RefactoringProvider |
||||
{ |
||||
/// <summary>
|
||||
/// A RefactoringProvider instance that supports no refactorings.
|
||||
/// </summary>
|
||||
public static readonly RefactoringProvider DummyProvider = new RefactoringProvider(); |
||||
|
||||
protected RefactoringProvider() {} |
||||
|
||||
public virtual bool SupportsFindUnusedUsingDeclarations { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public virtual IList<IUsing> FindUnusedUsingDeclarations(string fileName, string fileContent, ICompilationUnit compilationUnit) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue