From 7338344014ff700717aebaf9e484657defc258a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kon=C3=AD=C4=8Dek?= Date: Sat, 24 Jul 2010 16:36:44 +0000 Subject: [PATCH] Decoupled "Add using" functionality from context menu building. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6196 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/ContextActions/Extensions.cs | 5 +- .../RefactoringMenuBuilder.cs | 44 ++++-------- .../RefactoringService/RefactoringService.cs | 69 ++++++++++++++++++- 3 files changed, 83 insertions(+), 35 deletions(-) diff --git a/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/Extensions.cs b/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/Extensions.cs index 9cb3cbb0f3..73186a2f55 100644 --- a/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/Extensions.cs +++ b/src/AddIns/Misc/SharpRefactoring/Project/Src/ContextActions/Extensions.cs @@ -36,7 +36,10 @@ namespace SharpRefactoring.ContextActions foreach (var declaration in currentLineAST.FindTypeDeclarations()) { var rr = ParserService.Resolve(new ExpressionResult(declaration.Name), editor.Caret.Line, editor.Caret.Column, editor.FileName, editor.Document.Text); if (rr != null && rr.ResolvedType != null) { - yield return rr.ResolvedType.GetUnderlyingClass(); + var foundClass = rr.ResolvedType.GetUnderlyingClass(); + if (foundClass != null) { + yield return foundClass; + } } } } diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs index 620e3c607d..59b4c267f4 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs @@ -194,7 +194,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring var item = new MenuItem { Header = MenuService.ConvertLabel(StringParser.Parse("${res:SharpDevelop.Refactoring.FindDerivedClassesCommand}")) }; item.Icon = ClassBrowserIconService.Class.CreateImage(); item.InputGestureText = new KeyGesture(Key.F9).GetDisplayStringForCulture(Thread.CurrentThread.CurrentUICulture); - item.Click += delegate { + item.Click += delegate { ContextActionsHelper.MakePopupWithDerivedClasses(baseClass).OpenAtCaretAndFocus(context.Editor); }; return item; @@ -225,57 +225,37 @@ namespace ICSharpCode.SharpDevelop.Refactoring }; return item; } - + #endregion - MenuItem MakeItemForResolveError(UnknownIdentifierResolveResult rr, ExpressionContext context, ITextEditor textArea) + MenuItem MakeItemForResolveError(UnknownIdentifierResolveResult unknownIdent, ExpressionContext context, ITextEditor textArea) { - return MakeItemForUnknownClass(rr.CallingClass, rr.Identifier, textArea); + return MakeItemForActions(RefactoringService.GetAddUsingActions(unknownIdent, textArea), unknownIdent.Identifier, unknownIdent.CallingClass); } - MenuItem MakeItemForResolveError(UnknownConstructorCallResolveResult rr, ExpressionContext context, ITextEditor textArea) + MenuItem MakeItemForResolveError(UnknownConstructorCallResolveResult unknownConstructor, ExpressionContext context, ITextEditor textArea) { - return MakeItemForUnknownClass(rr.CallingClass, rr.TypeName, textArea); + return MakeItemForActions(RefactoringService.GetAddUsingActions(unknownConstructor, textArea), unknownConstructor.TypeName, unknownConstructor.CallingClass); } - MenuItem MakeItemForUnknownClass(IClass callingClass, string unknownClassName, ITextEditor textArea) + MenuItem MakeItemForActions(IEnumerable menuActions, string unknownClassName, IClass callingClass) { - if (callingClass == null) - return null; - IProjectContent pc = callingClass.ProjectContent; - if (!pc.Language.RefactoringProvider.IsEnabledForFile(callingClass.CompilationUnit.FileName)) + var actions = menuActions.ToList(); + if (actions.Count == 0) return null; MenuItem item = MakeItemInternal(unknownClassName, ClassBrowserIconService.GotoArrow, callingClass.CompilationUnit, DomRegion.Empty); - List searchResults = new List(); - SearchAllClassesWithName(searchResults, pc, unknownClassName, pc.Language); - foreach (IProjectContent rpc in pc.ReferencedContents) { - SearchAllClassesWithName(searchResults, rpc, unknownClassName, pc.Language); - } - if (searchResults.Count == 0) - return null; - foreach (IClass c in searchResults) { - string newNamespace = c.Namespace; + foreach (var action in actions) { MenuItem subItem = new MenuItem(); - subItem.Header = "using " + newNamespace; + subItem.Header = "using " + action.NewNamespace; subItem.Icon = ClassBrowserIconService.Namespace.CreateImage(); item.Items.Add(subItem); subItem.Click += delegate { - NamespaceRefactoringService.AddUsingDeclaration(callingClass.CompilationUnit, textArea.Document, newNamespace, true); - ParserService.BeginParse(textArea.FileName, textArea.Document); + action.Execute(); }; } return item; } - void SearchAllClassesWithName(List searchResults, IProjectContent pc, string name, LanguageProperties language) - { - foreach (string ns in pc.NamespaceNames) { - IClass c = pc.GetClass(ns + "." + name, 0, language, GetClassOptions.None); - if (c != null) - searchResults.Add(c); - } - } - IMember GetCallingMember(IClass callingClass, int caretLine, int caretColumn) { if (callingClass == null) { diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs index 914de8523e..fcd6a2bd69 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs @@ -475,7 +475,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring #region Interface / abstract class implementation /// - /// Gets actions which can add implementation of interface to this class. + /// Gets actions which can add implementation of interface to given class. /// public static IEnumerable GetImplementInterfaceActions(IClass c, bool isExplicitImpl, bool returnMissingInterfacesOnly = true) { @@ -492,7 +492,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring } } /// - /// Gets actions which can add implementation of abstract classes to this class. + /// Gets actions which can add implementation of abstract class to given class. /// public static IEnumerable GetImplementAbstractClassActions(IClass c, bool returnMissingClassesOnly = true) { @@ -561,5 +561,70 @@ namespace ICSharpCode.SharpDevelop.Refactoring } } #endregion + + #region Add using + public static IEnumerable GetAddUsingActions(UnknownIdentifierResolveResult rr, ITextEditor textArea) + { + return GetAddUsingActionsForUnknownClass(rr.CallingClass, rr.Identifier, textArea); + } + + public static IEnumerable GetAddUsingActions(UnknownConstructorCallResolveResult rr, ITextEditor textArea) + { + return GetAddUsingActionsForUnknownClass(rr.CallingClass, rr.TypeName, textArea); + } + + static IEnumerable GetAddUsingActionsForUnknownClass(IClass callingClass, string unknownClassName, ITextEditor editor) + { + if (callingClass == null) + yield break; + IProjectContent pc = callingClass.ProjectContent; + if (!pc.Language.RefactoringProvider.IsEnabledForFile(callingClass.CompilationUnit.FileName)) + yield break; + List searchResults = new List(); + SearchAllClassesWithName(searchResults, pc, unknownClassName, pc.Language); + foreach (IProjectContent rpc in pc.ReferencedContents) { + SearchAllClassesWithName(searchResults, rpc, unknownClassName, pc.Language); + } + foreach (IClass c in searchResults) { + string newNamespace = c.Namespace; + yield return new AddUsingAction(callingClass.CompilationUnit, editor, newNamespace); + } + } + + static void SearchAllClassesWithName(List searchResults, IProjectContent pc, string name, LanguageProperties language) + { + foreach (string ns in pc.NamespaceNames) { + IClass c = pc.GetClass(ns + "." + name, 0, language, GetClassOptions.None); + if (c != null) + searchResults.Add(c); + } + } + + public class AddUsingAction + { + public ICompilationUnit CompilationUnit { get; private set; } + public ITextEditor Editor { get; private set; } + public string NewNamespace { get; private set; } + + public AddUsingAction(ICompilationUnit compilationUnit, ITextEditor editor, string newNamespace) + { + if (compilationUnit == null) + throw new ArgumentNullException("compilationUnit"); + if (editor == null) + throw new ArgumentNullException("editor"); + if (newNamespace == null) + throw new ArgumentNullException("newNamespace"); + this.CompilationUnit = compilationUnit; + this.Editor = editor; + this.NewNamespace = newNamespace; + } + + public void Execute() + { + NamespaceRefactoringService.AddUsingDeclaration(CompilationUnit, Editor.Document, NewNamespace, true); + ParserService.BeginParse(Editor.FileName, Editor.Document); + } + } + #endregion } }