diff --git a/AddIns/ICSharpCode.SharpDevelop.addin b/AddIns/ICSharpCode.SharpDevelop.addin index f536eb4d42..a5f3f9560f 100644 --- a/AddIns/ICSharpCode.SharpDevelop.addin +++ b/AddIns/ICSharpCode.SharpDevelop.addin @@ -1260,6 +1260,16 @@ class = "ICSharpCode.SharpDevelop.Commands.ToggleFullscreenCommand" /> + + + + + + + + @@ -1339,7 +1349,7 @@ - + @@ -2070,12 +2080,12 @@ - + - + diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs index d38209faa0..5bc30aa0eb 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/BooResolver.cs @@ -10,10 +10,7 @@ using System.Collections; using System.Collections.Generic; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Dom; -using Boo.Lang.Compiler; using AST = Boo.Lang.Compiler.Ast; -using Boo.Lang.Compiler.IO; -using Boo.Lang.Compiler.Steps; using NRResolver = ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver; namespace Grunwald.BooBinding.CodeCompletion @@ -217,10 +214,10 @@ namespace Grunwald.BooBinding.CodeCompletion if (mie != null) expr = mie.Target; string name = expr.ToCodeString(); - IReturnType rt = pc.SearchType(name, 0, callingClass, cu, caretLine, caretColumn); + IReturnType rt = pc.SearchType(new SearchTypeRequest(name, 0, callingClass, cu, caretLine, caretColumn)).Result; if (rt != null && rt.GetUnderlyingClass() != null) return new TypeResolveResult(callingClass, callingMember, rt); - rt = pc.SearchType(name + "Attribute", 0, callingClass, cu, caretLine, caretColumn); + rt = pc.SearchType(new SearchTypeRequest(name + "Attribute", 0, callingClass, cu, caretLine, caretColumn)).Result; if (rt != null && rt.GetUnderlyingClass() != null) return new TypeResolveResult(callingClass, callingMember, rt); if (BooProject.BooCompilerPC != null) { diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs index 446326d53c..673c40ebe0 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs @@ -9,9 +9,9 @@ using System; using System.Collections; using System.Collections.Generic; using System.Text; +using Boo.Lang.Compiler.Ast; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Dom; -using Boo.Lang.Compiler.Ast; namespace Grunwald.BooBinding.CodeCompletion { @@ -110,7 +110,7 @@ namespace Grunwald.BooBinding.CodeCompletion ResolveResult oldResult = resolveResult; ClearResult(); // Try to resolve as type: - IReturnType t = projectContent.SearchType(identifier, 0, callingClass, cu, resolver.CaretLine, resolver.CaretColumn); + IReturnType t = projectContent.SearchType(new SearchTypeRequest(identifier, 0, callingClass, cu, resolver.CaretLine, resolver.CaretColumn)).Result; if (t != null) { MakeTypeResult(t); } else { @@ -253,8 +253,8 @@ namespace Grunwald.BooBinding.CodeCompletion LoggingService.Warn("Unknown expression in GenericReferenceExpression: " + expr); } } - IReturnType rt = projectContent.SearchType(name.ToString(), typeArguments.Count, callingClass, - cu, resolver.CaretLine, resolver.CaretColumn); + IReturnType rt = projectContent.SearchType(new SearchTypeRequest(name.ToString(), typeArguments.Count, callingClass, + cu, resolver.CaretLine, resolver.CaretColumn)).Result; return new ConstructedReturnType(rt, typeArguments); } #endregion diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs index fc267c122a..8784481ad3 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs @@ -6,26 +6,21 @@ // using System; +using System.CodeDom; +using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; -using System.Drawing; -using System.IO; using System.ComponentModel.Design; -using System.CodeDom; -using System.CodeDom.Compiler; using System.ComponentModel.Design.Serialization; +using System.Drawing; +using System.IO; using System.Windows.Forms; -using System.Windows.Forms.Design; using ICSharpCode.Core; -using ICSharpCode.TextEditor; -using ICSharpCode.TextEditor.Document; - -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.FormsDesigner.Services; using ICSharpCode.NRefactory.Parser; using ICSharpCode.NRefactory.Parser.AST; -using ICSharpCode.NRefactory.PrettyPrinter; +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.TextEditor; namespace ICSharpCode.FormsDesigner { @@ -314,7 +309,7 @@ namespace ICSharpCode.FormsDesigner FixTypeReference(tref, location, domCu); } ICSharpCode.SharpDevelop.Dom.IClass curType = domCu.GetInnermostClass(location.Y, location.X); - ICSharpCode.SharpDevelop.Dom.IReturnType rt = domCu.ProjectContent.SearchType(type.Type, type.GenericTypes.Count, curType, domCu, location.Y, location.X); + ICSharpCode.SharpDevelop.Dom.IReturnType rt = domCu.ProjectContent.SearchType(new SearchTypeRequest(type.Type, type.GenericTypes.Count, curType, domCu, location.Y, location.X)).Result; if (rt != null) { type.Type = rt.FullyQualifiedName; } diff --git a/src/AddIns/Misc/SubversionAddIn/Project/Src/Commands/AutostartCommands.cs b/src/AddIns/Misc/SubversionAddIn/Project/Src/Commands/AutostartCommands.cs index be41381cfa..c8bafc4676 100644 --- a/src/AddIns/Misc/SubversionAddIn/Project/Src/Commands/AutostartCommands.cs +++ b/src/AddIns/Misc/SubversionAddIn/Project/Src/Commands/AutostartCommands.cs @@ -6,22 +6,11 @@ // using System; -using System.Text; using System.IO; -using System.Threading; -using System.Drawing; -using System.Drawing.Printing; -using System.Collections; -using System.ComponentModel; using System.Windows.Forms; -using System.Diagnostics; using ICSharpCode.Core; -using ICSharpCode.SharpDevelop; - using ICSharpCode.SharpDevelop.Project; -using ICSharpCode.SharpDevelop.Gui; -using NSvn.Common; using NSvn.Core; namespace ICSharpCode.Svn.Commands @@ -104,6 +93,7 @@ namespace ICSharpCode.Svn.Commands switch (status.TextStatus) { case StatusKind.None: case StatusKind.Unversioned: + case StatusKind.Deleted: return; // nothing to do case StatusKind.Normal: // remove without problem diff --git a/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs b/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs index 3841c1d3e0..fa8bcda977 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs @@ -6,11 +6,10 @@ // using System; -using System.Diagnostics; -using System.Collections; using System.Collections.Generic; -using System.Text; +using System.Diagnostics; using System.Globalization; +using System.Text; namespace ICSharpCode.NRefactory.Parser.AST { @@ -20,7 +19,7 @@ namespace ICSharpCode.NRefactory.Parser.AST string systemType = ""; int pointerNestingLevel = 0; int[] rankSpecifier = null; - List genericTypes = new List(1); + List genericTypes = new List(); bool isGlobal = false; static Dictionary types = new Dictionary(); diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 24c3f36d7d..aa6cde09d9 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -502,7 +502,7 @@ - + @@ -765,7 +765,10 @@ - + + + + @@ -794,4 +797,4 @@ - \ No newline at end of file + diff --git a/src/Main/Base/Project/Src/Dom/ClassFinder.cs b/src/Main/Base/Project/Src/Dom/ClassFinder.cs index b116af081c..2c746065c1 100644 --- a/src/Main/Base/Project/Src/Dom/ClassFinder.cs +++ b/src/Main/Base/Project/Src/Dom/ClassFinder.cs @@ -87,7 +87,7 @@ namespace ICSharpCode.SharpDevelop.Dom public IReturnType SearchType(string name, int typeParameterCount) { - return projectContent.SearchType(name, typeParameterCount, callingClass, cu, caretLine, caretColumn); + return projectContent.SearchType(new SearchTypeRequest(name, typeParameterCount, callingClass, cu, caretLine, caretColumn)).Result; } public string SearchNamespace(string name) diff --git a/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs b/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs index 7e2739442b..3501ee305f 100644 --- a/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs +++ b/src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs @@ -130,7 +130,7 @@ namespace ICSharpCode.SharpDevelop.Dom return type; try { isSearching = true; - type = pc.SearchType(name, typeParameterCount, declaringClass, caretLine, caretColumn); + type = pc.SearchType(new SearchTypeRequest(name, typeParameterCount, declaringClass, caretLine, caretColumn)).Result; cache[this] = type; return type; } finally { diff --git a/src/Main/Base/Project/Src/Dom/LanguageProperties.cs b/src/Main/Base/Project/Src/Dom/LanguageProperties.cs index 8d0954479a..211eea96b3 100644 --- a/src/Main/Base/Project/Src/Dom/LanguageProperties.cs +++ b/src/Main/Base/Project/Src/Dom/LanguageProperties.cs @@ -38,6 +38,12 @@ namespace ICSharpCode.SharpDevelop.Dom } } + public virtual RefactoringProvider RefactoringProvider { + get { + return RefactoringProvider.DummyProvider; + } + } + /// /// Gets if the language supports calling C# 3-style extension methods /// (first parameter = instance parameter) @@ -154,6 +160,12 @@ namespace ICSharpCode.SharpDevelop.Dom { public CSharpProperties() : base(StringComparer.InvariantCulture, CSharpCodeGenerator.Instance) {} + public override RefactoringProvider RefactoringProvider { + get { + return NRefactoryRefactoringProvider.NRefactoryProviderInstance; + } + } + public override string ToString() { return "[LanguageProperties: C#]"; @@ -230,6 +242,12 @@ namespace ICSharpCode.SharpDevelop.Dom return u; } + public override RefactoringProvider RefactoringProvider { + get { + return NRefactoryRefactoringProvider.NRefactoryProviderInstance; + } + } + public override string ToString() { return "[LanguageProperties: VB.NET]"; diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs index ed94cfbaca..f832c02199 100644 --- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs +++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryResolver.cs @@ -11,9 +11,8 @@ using System.Collections.Generic; using System.Drawing; using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.NRefactory.Parser.AST; using ICSharpCode.NRefactory.Parser; +using ICSharpCode.NRefactory.Parser.AST; namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver { @@ -783,7 +782,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver public IReturnType SearchType(string name) { - return projectContent.SearchType(name, 0, callingClass, cu, caretLine, caretColumn); + return projectContent.SearchType(new SearchTypeRequest(name, 0, callingClass, cu, caretLine, caretColumn)).Result; } #region Helper for TypeVisitor diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs index 0e05c3e2e8..9cce8ea239 100644 --- a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs +++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs @@ -8,15 +8,12 @@ // created on 22.08.2003 at 19:02 using System; -using System.Collections; using System.Collections.Generic; +using ICSharpCode.Core; using ICSharpCode.NRefactory.Parser; using ICSharpCode.NRefactory.Parser.AST; -using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.Core; - namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver { public class TypeVisitor : AbstractAstVisitor @@ -509,7 +506,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver c = projectContent.GetClass(reference.SystemType, typeParameterCount); t = (c != null) ? c.DefaultReturnType : null; } else { - t = projectContent.SearchType(reference.SystemType, typeParameterCount, callingClass, caretLine, caretColumn); + t = projectContent.SearchType(new SearchTypeRequest(reference.SystemType, typeParameterCount, callingClass, caretLine, caretColumn)).Result; } if (t == null) { if (reference.GenericTypes.Count == 0 && !reference.IsArrayType) { diff --git a/src/Main/Base/Project/Src/Dom/ResolveResult.cs b/src/Main/Base/Project/Src/Dom/ResolveResult.cs index ce5d3de352..7797114e67 100644 --- a/src/Main/Base/Project/Src/Dom/ResolveResult.cs +++ b/src/Main/Base/Project/Src/Dom/ResolveResult.cs @@ -10,10 +10,8 @@ using System.Collections; using System.Collections.Generic; using System.Drawing; -using ICSharpCode.SharpDevelop.Project; using ICSharpCode.Core; - namespace ICSharpCode.SharpDevelop.Dom { #region ResolveResult @@ -32,8 +30,6 @@ namespace ICSharpCode.SharpDevelop.Dom public ResolveResult(IClass callingClass, IMember callingMember, IReturnType resolvedType) { -// if (callingMember != null && callingMember.DeclaringType != callingClass) -// throw new ArgumentException("callingMember.DeclaringType must be equal to callingClass"); this.callingClass = callingClass; this.callingMember = callingMember; this.resolvedType = resolvedType; @@ -498,7 +494,7 @@ namespace ICSharpCode.SharpDevelop.Dom return GetDefinitionPosition(resolvedMember); } - public static FilePosition GetDefinitionPosition(IMember resolvedMember) + internal static FilePosition GetDefinitionPosition(IMember resolvedMember) { IClass declaringType = resolvedMember.DeclaringType; if (declaringType == null) { diff --git a/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs index 1e5bda5c73..b68a8ba033 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs @@ -6,26 +6,15 @@ // using System; -using System.IO; -using System.Threading; using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters; -using System.Runtime.Serialization.Formatters.Binary; -using System.Security; -using System.Security.Permissions; -using System.Security.Policy; -using System.Xml; +using System.IO; using System.Text; +using System.Threading; -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.Project; -using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.Core { @@ -723,30 +712,23 @@ namespace ICSharpCode.Core return null; } - public IReturnType SearchType(string name, int typeParameterCount, IClass curType, int caretLine, int caretColumn) - { - if (curType == null) { - return SearchType(name, typeParameterCount, null, null, caretLine, caretColumn); - } - return SearchType(name, typeParameterCount, curType, curType.CompilationUnit, caretLine, caretColumn); - } - - public IReturnType SearchType(string name, int typeParameterCount, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn) + public SearchTypeResult SearchType(SearchTypeRequest request) { + string name = request.Name; if (name == null || name.Length == 0) { - return null; + return SearchTypeResult.Empty; } // Try if name is already the full type name - IClass c = GetClass(name, typeParameterCount); + IClass c = GetClass(name, request.TypeParameterCount); if (c != null) { - return c.DefaultReturnType; + return new SearchTypeResult(c.DefaultReturnType); } // fallback-class if the one with the right type parameter count is not found. - IReturnType fallbackClass = null; - if (curType != null) { + SearchTypeResult fallbackResult = SearchTypeResult.Empty; + if (request.CurrentType != null) { // Try parent namespaces of the current class - string fullname = curType.FullyQualifiedName; + string fullname = request.CurrentType.FullyQualifiedName; string[] namespaces = fullname.Split('.'); StringBuilder curnamespace = new StringBuilder(); for (int i = 0; i < namespaces.Length; ++i) { @@ -754,12 +736,12 @@ namespace ICSharpCode.Core curnamespace.Append('.'); curnamespace.Append(name); - c = GetClass(curnamespace.ToString(), typeParameterCount); + c = GetClass(curnamespace.ToString(), request.TypeParameterCount); if (c != null) { - if (c.TypeParameters.Count == typeParameterCount) - return c.DefaultReturnType; + if (c.TypeParameters.Count == request.TypeParameterCount) + return new SearchTypeResult(c.DefaultReturnType); else - fallbackClass = c.DefaultReturnType; + fallbackResult = new SearchTypeResult(c.DefaultReturnType); } // remove class name again to try next namespace curnamespace.Length -= name.Length; @@ -768,42 +750,42 @@ namespace ICSharpCode.Core if (name.IndexOf('.') < 0) { // Try inner classes (in full inheritance tree) // Don't use loop with cur = cur.BaseType because of inheritance cycles - foreach (IClass baseClass in curType.ClassInheritanceTree) { + foreach (IClass baseClass in request.CurrentType.ClassInheritanceTree) { if (baseClass.ClassType == ClassType.Class) { foreach (IClass innerClass in baseClass.InnerClasses) { if (language.NameComparer.Equals(innerClass.Name, name)) - return innerClass.DefaultReturnType; + return new SearchTypeResult(innerClass.DefaultReturnType); } } } } } - if (unit != null) { + if (request.CurrentCompilationUnit != null) { // Combine name with usings - foreach (IUsing u in unit.Usings) { + foreach (IUsing u in request.CurrentCompilationUnit.Usings) { if (u != null) { - IReturnType r = u.SearchType(name, typeParameterCount); + IReturnType r = u.SearchType(name, request.TypeParameterCount); if (r != null) { - if (r.TypeParameterCount == typeParameterCount) { - return r; + if (r.TypeParameterCount == request.TypeParameterCount) { + return new SearchTypeResult(r, u); } else { - fallbackClass = r; + fallbackResult = new SearchTypeResult(r, u); } } } } } if (defaultImports != null) { - IReturnType r = defaultImports.SearchType(name, typeParameterCount); + IReturnType r = defaultImports.SearchType(name, request.TypeParameterCount); if (r != null) { - if (r.TypeParameterCount == typeParameterCount) { - return r; + if (r.TypeParameterCount == request.TypeParameterCount) { + return new SearchTypeResult(r, defaultImports); } else { - fallbackClass = r; + fallbackResult = new SearchTypeResult(r, defaultImports); } } } - return fallbackClass; + return fallbackResult; } /// diff --git a/src/Main/Base/Project/Src/Services/ParserService/IProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/IProjectContent.cs index 022cb24672..e5acf5ebfd 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/IProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/IProjectContent.cs @@ -6,26 +6,11 @@ // using System; -using System.IO; -using System.Threading; using System.Collections; using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters; -using System.Runtime.Serialization.Formatters.Binary; -using System.Security; -using System.Security.Permissions; -using System.Security.Policy; -using System.Xml; -using System.Text; -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.Project; -using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.Core { @@ -89,9 +74,66 @@ namespace ICSharpCode.Core void AddNamespaceContents(ArrayList list, string subNameSpace, LanguageProperties language, bool lookInReferences); string SearchNamespace(string name, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn); - IReturnType SearchType(string name, int typeParameterCount, IClass curType, int caretLine, int caretColumn); - IReturnType SearchType(string name, int typeParameterCount, IClass curType, ICompilationUnit unit, int caretLine, int caretColumn); + SearchTypeResult SearchType(SearchTypeRequest request); Position GetPosition(string fullMemberName); } + + public struct SearchTypeRequest + { + public string Name; + public int TypeParameterCount; + public ICompilationUnit CurrentCompilationUnit; + public IClass CurrentType; + public int CaretLine; + public int CaretColumn; + + public SearchTypeRequest(string name, int typeParameterCount, IClass currentType, int caretLine, int caretColumn) + { + this.Name = name; + this.TypeParameterCount = typeParameterCount; + this.CurrentCompilationUnit = currentType.CompilationUnit; + this.CurrentType = currentType; + this.CaretLine = caretLine; + this.CaretColumn = caretColumn; + } + + public SearchTypeRequest(string name, int typeParameterCount, IClass currentType, ICompilationUnit currentCompilationUnit, int caretLine, int caretColumn) + { + this.Name = name; + this.TypeParameterCount = typeParameterCount; + this.CurrentCompilationUnit = currentCompilationUnit; + this.CurrentType = currentType; + this.CaretLine = caretLine; + this.CaretColumn = caretColumn; + } + } + + public struct SearchTypeResult + { + public static readonly SearchTypeResult Empty = new SearchTypeResult(null); + + IReturnType result; + IUsing usedUsing; + + public SearchTypeResult(IReturnType result) : this(result, null) {} + + public SearchTypeResult(IReturnType result, IUsing usedUsing) + { + this.result = result; + this.usedUsing = usedUsing; + } + + public IReturnType Result { + get { + return result; + } + } + + public IUsing UsedUsing { + get { + return usedUsing; + } + } + } } diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs index b9844cf872..48309af5b9 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs @@ -6,26 +6,16 @@ // using System; -using System.IO; -using System.Threading; using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters; -using System.Runtime.Serialization.Formatters.Binary; -using System.Security; -using System.Security.Permissions; -using System.Security.Policy; -using System.Xml; +using System.IO; using System.Text; +using System.Threading; -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop.Project; -using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.SharpDevelop.Project; namespace ICSharpCode.Core { @@ -464,6 +454,8 @@ namespace ICSharpCode.Core public static ParseInformation ParseFile(IProjectContent fileProjectContent, string fileName, string fileContent, bool updateCommentTags, bool fireUpdate) { + if (fileName == null) throw new ArgumentNullException("fileName"); + IParser parser = GetParser(fileName); if (parser == null) { return null; diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs b/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs index 9cfbb0a424..b90022eae5 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/CodeGenerator.cs @@ -6,14 +6,13 @@ // using System; -using System.Collections; using System.Collections.Generic; -using System.IO; +using System.Drawing; using System.Text; +using ICSharpCode.NRefactory.Parser.AST; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.TextEditor; using ICSharpCode.TextEditor.Document; -using ICSharpCode.NRefactory.Parser.AST; namespace ICSharpCode.SharpDevelop.Refactoring { @@ -89,6 +88,20 @@ namespace ICSharpCode.SharpDevelop.Refactoring return (ParamModifier)m; } + public static UsingDeclaration ConvertUsing(IUsing u) + { + List usings = new List(); + foreach (string name in u.Usings) { + usings.Add(new Using(name)); + } + if (u.HasAliases) { + foreach (KeyValuePair pair in u.Aliases) { + usings.Add(new Using(pair.Key, ConvertType(pair.Value, null))); + } + } + return new UsingDeclaration(usings); + } + public static List ConvertParameters(IList parameters, ClassFinder targetContext) { List l = new List(parameters.Count); @@ -515,5 +528,69 @@ namespace ICSharpCode.SharpDevelop.Refactoring return ie; } #endregion + + #region Using statements + public virtual void ReplaceUsings(IDocument document, IList oldUsings, IList newUsings) + { + if (oldUsings.Count == newUsings.Count) { + bool identical = true; + for (int i = 0; i < oldUsings.Count; i++) { + if (oldUsings[i] != newUsings[i]) { + identical = false; + break; + } + } + if (identical) return; + } + + int firstLine = int.MaxValue; + List> regions = new List>(); + foreach (IUsing u in oldUsings) { + if (u.Region.BeginLine < firstLine) + firstLine = u.Region.BeginLine; + int st = document.PositionToOffset(new Point(u.Region.BeginColumn - 1, u.Region.BeginLine - 1)); + int en = document.PositionToOffset(new Point(u.Region.EndColumn - 1, u.Region.EndLine - 1)); + regions.Add(new KeyValuePair(st, en - st)); + } + + regions.Sort(delegate(KeyValuePair a, KeyValuePair b) { + return a.Key.CompareTo(b.Key); + }); + int insertionOffset = regions.Count == 0 ? 0 : regions[0].Key; + string indentation; + if (firstLine != int.MaxValue) { + indentation = GetIndentation(document, firstLine); + insertionOffset -= indentation.Length; + } else { + indentation = ""; + } + + for (int i = regions.Count - 1; i >= 0; i--) { + document.Remove(regions[i].Key, regions[i].Value); + } + int actionCount = regions.Count; + int lastNewLine = insertionOffset; + for (int i = insertionOffset; i < document.TextLength; i++) { + char c = document.GetCharAt(i); + if (!char.IsWhiteSpace(c)) + break; + if (c == '\n') { + if (i > 0 && document.GetCharAt(i - 1) == '\r') + lastNewLine = i - 1; + else + lastNewLine = i; + } + } + if (lastNewLine != insertionOffset) { + document.Remove(insertionOffset, lastNewLine - insertionOffset); actionCount++; + } + StringBuilder txt = new StringBuilder(); + foreach (IUsing us in newUsings) { + txt.Append(GenerateCode(ConvertUsing(us), indentation)); + } + document.Insert(insertionOffset, txt.ToString()); actionCount++; + document.UndoStack.UndoLast(actionCount); + } + #endregion } } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs b/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs index 4711f8923a..d36cd1e069 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/FindReferencesAndRenameHelper.cs @@ -7,18 +7,13 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Text; -using System.Windows.Forms; using ICSharpCode.Core; -using ICSharpCode.TextEditor; -using ICSharpCode.TextEditor.Document; using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Bookmarks; using ICSharpCode.SharpDevelop.Gui; +using ICSharpCode.TextEditor; +using ICSharpCode.TextEditor.Document; using SearchAndReplace; -using ICSharpCode.SharpDevelop.DefaultEditor.Commands; namespace ICSharpCode.SharpDevelop.Refactoring { diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/LocalVariableRefactoring.cs b/src/Main/Base/Project/Src/Services/RefactoringService/LocalVariableRefactoring.cs index 4e36cb9572..5ef512e449 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/LocalVariableRefactoring.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/LocalVariableRefactoring.cs @@ -8,7 +8,6 @@ using System; using System.Collections.Generic; using ICSharpCode.Core; -using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; namespace ICSharpCode.SharpDevelop.Refactoring diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs b/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs index f57202baa7..13dfb768c6 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryCodeGenerator.cs @@ -6,8 +6,6 @@ // using System; -using System.IO; -using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.NRefactory.Parser.AST; using ICSharpCode.NRefactory.PrettyPrinter; diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryRefactoringProvider.cs b/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryRefactoringProvider.cs new file mode 100644 index 0000000000..f8e115091f --- /dev/null +++ b/src/Main/Base/Project/Src/Services/RefactoringService/NRefactoryRefactoringProvider.cs @@ -0,0 +1,129 @@ +// +// +// +// +// $Revision$ +// + +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 list = new Dictionary(); + + 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 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 FindUnusedUsingDeclarations(string fileName, string fileContent, ICompilationUnit cu) + { + IClass @class = cu.Classes.Count == 0 ? null : cu.Classes[0]; + + Dictionary references = FindPossibleTypeReferences(Path.GetExtension(fileName), fileContent); + if (references == null) return new IUsing[0]; + + Dictionary dict = new Dictionary(); + 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 list = new List(); + 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; + } + } +} diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoring.cs b/src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoring.cs deleted file mode 100644 index 8c0797ea23..0000000000 --- a/src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoring.cs +++ /dev/null @@ -1,16 +0,0 @@ -// -// -// -// -// $Revision$ -// - -using System; - -namespace ICSharpCode.SharpDevelop.Refactoring -{ - public static class NamespaceRefactoring - { - - } -} diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoringService.cs new file mode 100644 index 0000000000..8625eedf6f --- /dev/null +++ b/src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoringService.cs @@ -0,0 +1,70 @@ +// +// +// +// +// $Revision$ +// + +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 newUsings = new List(cu.Usings); + if (sort) { + newUsings.Sort(CompareUsings); + } + + if (removedUnused) { + IList 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); + } + } +} diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs new file mode 100644 index 0000000000..6a5d90f314 --- /dev/null +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs @@ -0,0 +1,87 @@ +// +// +// +// +// $Revision$ +// + +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 +{ + /// + /// Tests if the refactoring provider for the current document + /// supports the specified option. + /// + /// + /// Same of the action that should be supported. + /// "*" to test if refactoring is supported at all. + /// + /// + /// <Condition name="RefactoringProviderSupports" supports="*"> + /// + /// + /// <Condition name="RefactoringProviderSupports" supports="FindUnusedUsingDeclarations"> + /// + 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); + } + } +} diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringProvider.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringProvider.cs new file mode 100644 index 0000000000..69f2101984 --- /dev/null +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringProvider.cs @@ -0,0 +1,34 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using ICSharpCode.SharpDevelop.Dom; + +namespace ICSharpCode.SharpDevelop.Refactoring +{ + public class RefactoringProvider + { + /// + /// A RefactoringProvider instance that supports no refactorings. + /// + public static readonly RefactoringProvider DummyProvider = new RefactoringProvider(); + + protected RefactoringProvider() {} + + public virtual bool SupportsFindUnusedUsingDeclarations { + get { + return false; + } + } + + public virtual IList FindUnusedUsingDeclarations(string fileName, string fileContent, ICompilationUnit compilationUnit) + { + throw new NotSupportedException(); + } + } +} diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs index 98df9a7aa2..bb87c03149 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs @@ -9,7 +9,6 @@ using System; using System.Collections.Generic; using System.Drawing; using ICSharpCode.Core; -using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Project; @@ -309,7 +308,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring return new Point(column, line); } - public static List GetFileNames(IClass c) + static List GetFileNames(IClass c) { List list = new List(); CompoundClass cc = c as CompoundClass; @@ -407,6 +406,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring } #endregion + #region IsReferenceTo... public static bool IsReferenceToLocalVariable(ResolveResult rr, IMember variable) { LocalResolveResult local = rr as LocalResolveResult; @@ -432,7 +432,9 @@ namespace ICSharpCode.SharpDevelop.Refactoring return false; } } + #endregion + #region IsSimilarMember / FindBaseMember /// /// Gets if member1 is the same as member2 or if member1 overrides member2. /// @@ -516,5 +518,6 @@ namespace ICSharpCode.SharpDevelop.Refactoring } return null; } + #endregion } } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/Reference.cs b/src/Main/Base/Project/Src/Services/RefactoringService/Reference.cs index d3fc0c92a8..14d444cf62 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/Reference.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/Reference.cs @@ -6,7 +6,6 @@ // using System; -using System.Collections.Generic; using ICSharpCode.SharpDevelop.Dom; namespace ICSharpCode.SharpDevelop.Refactoring diff --git a/src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/CodeGenerator.cs b/src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/CodeGeneratorBase.cs similarity index 100% rename from src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/CodeGenerator.cs rename to src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/CodeGeneratorBase.cs diff --git a/src/Main/StartUp/Project/SharpDevelopMain.cs b/src/Main/StartUp/Project/SharpDevelopMain.cs index c420b82c40..54fdc1be14 100644 --- a/src/Main/StartUp/Project/SharpDevelopMain.cs +++ b/src/Main/StartUp/Project/SharpDevelopMain.cs @@ -6,18 +6,12 @@ // using System; -using System.IO; using System.Diagnostics; +using System.IO; using System.Reflection; -using System.Drawing; -using System.Collections; -using System.Collections.Generic; -using System.Windows.Forms; using System.Resources; -using System.Xml; using System.Threading; -using System.Runtime.Remoting; -using System.Security.Policy; +using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Commands; @@ -263,6 +257,7 @@ namespace ICSharpCode.SharpDevelop AddInTree.ConditionEvaluators.Add("ProjectActive", new ProjectActiveConditionEvaluator()); AddInTree.ConditionEvaluators.Add("TextContent", new ICSharpCode.SharpDevelop.DefaultEditor.Conditions.TextContentConditionEvaluator()); AddInTree.ConditionEvaluators.Add("BrowserLocation", new ICSharpCode.SharpDevelop.BrowserDisplayBinding.BrowserLocationConditionEvaluator()); + AddInTree.ConditionEvaluators.Add("RefactoringProviderSupports", new Refactoring.RefactoringProviderSupportsConditionEvaluator()); AddInTree.Doozers.Add("DialogPanel", new DialogPanelDoozer()); AddInTree.Doozers.Add("DisplayBinding", new DisplayBindingDoozer());