From 8bebbe33fc192eb397a75d5a1839548d4fa76efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kon=C3=AD=C4=8Dek?= Date: Sun, 23 May 2010 18:09:11 +0000 Subject: [PATCH] CodeCompletion after dot shows only extension methods from imported namespaces. If Ctrl+Space is pressed, all extension methods from all referenced projects are shown. Original Ctrl+Space (types shown when user starts typing in the editor) still always shows types from all referenced projects. Maybe we could change this to show only items from imported namespaces by default, and all items for Ctrl+Space press, for consistency (ReSharper-like). If we want this, NRefactoryResolver.CtrlSpace() method is ready for this change. I am not sure yet, I quite like current state (all types shown in CC don't bother me), but it is a little inconsistent. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5845 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../CodeCompletionItemProvider.cs | 7 ++++- .../CtrlSpaceCompletionItemProvider.cs | 11 ++----- .../NRefactoryCodeCompletionBinding.cs | 2 ++ .../Project/Src/CtrlSpaceResolveHelper.cs | 11 ++++--- .../NRefactoryResolver/NRefactoryResolver.cs | 30 +++++++++++++------ .../Project/Src/ResolveResult.cs | 24 +++++++++++++-- 6 files changed, 60 insertions(+), 25 deletions(-) diff --git a/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs b/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs index 5108610f1c..45aeeaadb5 100644 --- a/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs +++ b/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs @@ -49,6 +49,11 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion /// public class CodeCompletionItemProvider : AbstractCompletionItemProvider { + /// + /// Gets/Sets whether items from all namespaces should be included in code completion, regardless of imports. + /// + public bool ShowItemsFromAllNamespaces { get; set; } + /// public override ICompletionItemList GenerateCompletionList(ITextEditor editor) { @@ -103,7 +108,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion if (rr == null) return null; IProjectContent callingContent = rr.CallingClass != null ? rr.CallingClass.ProjectContent : null; - List arr = rr.GetCompletionData(callingContent ?? ParserService.CurrentProjectContent); + List arr = rr.GetCompletionData(callingContent ?? ParserService.CurrentProjectContent, this.ShowItemsFromAllNamespaces); return GenerateCompletionListForCompletionData(arr, context); } diff --git a/src/Main/Base/Project/Src/Editor/CodeCompletion/CtrlSpaceCompletionItemProvider.cs b/src/Main/Base/Project/Src/Editor/CodeCompletion/CtrlSpaceCompletionItemProvider.cs index e454b67499..f4e4a88c6a 100644 --- a/src/Main/Base/Project/Src/Editor/CodeCompletion/CtrlSpaceCompletionItemProvider.cs +++ b/src/Main/Base/Project/Src/Editor/CodeCompletion/CtrlSpaceCompletionItemProvider.cs @@ -27,17 +27,12 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion ExpressionContext overrideContext; - bool allowCompleteExistingExpression; - /// /// Gets/Sets whether completing an old expression is allowed. /// You have to set this property to true to let the provider run FindExpression, when /// set to false it will use ExpressionContext.Default (unless the constructor with "overrideContext" was used). /// - public bool AllowCompleteExistingExpression { - get { return allowCompleteExistingExpression; } - set { allowCompleteExistingExpression = value; } - } + public bool AllowCompleteExistingExpression { get; set; } /// /// Gets/Sets whether code templates should be included in code completion. @@ -67,7 +62,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion ICompletionItemList GenerateCompletionListCore(ITextEditor editor) { preselectionLength = 0; - if (!allowCompleteExistingExpression) { + if (!AllowCompleteExistingExpression) { ExpressionContext context = overrideContext ?? ExpressionContext.Default; var ctrlSpace = CtrlSpace(editor, context); return GenerateCompletionListForCompletionData(ctrlSpace, context); @@ -128,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion editor.Caret.Line, editor.Caret.Column, ParserService.GetParseInformation(editor.FileName), editor.Document.Text, - context); + context, this.ShowItemsFromAllNamespaces); } } } diff --git a/src/Main/Base/Project/Src/Editor/CodeCompletion/NRefactoryCodeCompletionBinding.cs b/src/Main/Base/Project/Src/Editor/CodeCompletion/NRefactoryCodeCompletionBinding.cs index 50a9ea0ab4..6b8a9f1c37 100644 --- a/src/Main/Base/Project/Src/Editor/CodeCompletion/NRefactoryCodeCompletionBinding.cs +++ b/src/Main/Base/Project/Src/Editor/CodeCompletion/NRefactoryCodeCompletionBinding.cs @@ -64,6 +64,8 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion { NRefactoryCtrlSpaceCompletionItemProvider provider = new NRefactoryCtrlSpaceCompletionItemProvider(languageProperties); provider.AllowCompleteExistingExpression = true; + // on Ctrl+Space, include members (e.g. extension methods) from all namespaces, regardless of imports + provider.ShowItemsFromAllNamespaces = true; provider.ShowCompletion(editor); return true; } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CtrlSpaceResolveHelper.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CtrlSpaceResolveHelper.cs index d3714bf730..38b34b7f3a 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CtrlSpaceResolveHelper.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CtrlSpaceResolveHelper.cs @@ -235,7 +235,7 @@ namespace ICSharpCode.SharpDevelop.Dom return null; } - public static IList FindAllExtensions(LanguageProperties language, IClass callingClass) + public static IList FindAllExtensions(LanguageProperties language, IClass callingClass, bool searchInAllNamespaces = false) { if (language == null) throw new ArgumentNullException("language"); @@ -251,9 +251,12 @@ namespace ICSharpCode.SharpDevelop.Dom IMethod dummyMethod = new DefaultMethod("dummy", callingClass.ProjectContent.SystemTypes.Void, ModifierEnum.Static, DomRegion.Empty, DomRegion.Empty, callingClass); CtrlSpaceResolveHelper.AddContentsFromCalling(list, callingClass, dummyMethod); - CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass); - // search extension methods in all referenced projects, no matter the using section - //CtrlSpaceResolveHelper.AddReferencedProjectsContents(list, callingClass.CompilationUnit, callingClass); + if (searchInAllNamespaces) { + // search extension methods in all referenced projects, no matter the using section + CtrlSpaceResolveHelper.AddReferencedProjectsContents(list, callingClass.CompilationUnit, callingClass); + } else { + CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass); + } bool searchExtensionsInClasses = language.SearchExtensionsInClasses; foreach (object o in list) { diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs index 946d90167c..3bc4e0318f 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs @@ -1010,13 +1010,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver ReadOnlyCollection cachedExtensionMethods; IClass cachedExtensionMethods_LastClass; // invalidate cache when callingClass != LastClass - public ReadOnlyCollection SearchAllExtensionMethods() + public ReadOnlyCollection SearchAllExtensionMethods(bool searchInAllNamespaces = false) { if (callingClass == null) return EmptyList.Instance; if (callingClass != cachedExtensionMethods_LastClass) { cachedExtensionMethods_LastClass = callingClass; - cachedExtensionMethods = new ReadOnlyCollection(CtrlSpaceResolveHelper.FindAllExtensions(languageProperties, callingClass)); + cachedExtensionMethods = new ReadOnlyCollection(CtrlSpaceResolveHelper.FindAllExtensions(languageProperties, callingClass, searchInAllNamespaces)); } return cachedExtensionMethods; } @@ -1122,7 +1122,17 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver } } - public List CtrlSpace(int caretLine, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext context) + /// + /// Returns code completion entries for given context. + /// + /// + /// + /// + /// + /// + /// If true, returns entries from all namespaces, regardless of current imports. + /// + public List CtrlSpace(int caretLine, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext context, bool showEntriesFromAllNamespaces = false) { if (!Initialize(parseInfo, caretLine, caretColumn)) return null; @@ -1231,7 +1241,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver } } - void CtrlSpaceInternal(List result, string fileContent) + void CtrlSpaceInternal(List result, string fileContent, bool showEntriesFromAllNamespaces = true) { lookupTableVisitor = new LookupTableVisitor(language); @@ -1265,11 +1275,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver result.Add(new DefaultField.ParameterField(callingMember.ReturnType, "value", callingMember.Region, callingClass)); } - // CC contains contents of all imported namespaces - //CtrlSpaceResolveHelper.AddImportedNamespaceContents(result, cu, callingClass); // FindReferences to AddImportedNamespaceContents results in OutOfMemory - - // CC contains contents of all referenced assemblies - CtrlSpaceResolveHelper.AddReferencedProjectsContents(result, cu, callingClass); + if (showEntriesFromAllNamespaces) { + // CC contains contents of all referenced assemblies + CtrlSpaceResolveHelper.AddReferencedProjectsContents(result, cu, callingClass); + } else { + // CC contains contents of all imported namespaces + CtrlSpaceResolveHelper.AddImportedNamespaceContents(result, cu, callingClass); + } } sealed class CompareLambdaByLocation : IEqualityComparer diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs index d5e5b8fa1d..2289780acf 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs @@ -78,6 +78,24 @@ namespace ICSharpCode.SharpDevelop.Dom return this.Clone(); } + bool showAllNamespacesContentsInCC = false; + /// + /// Gets code completion data for this ResolveResult. + /// + /// + /// If true, items (e.g. extension methods) from all namespaces are returned, regardless current imports. Default is false. + /// + public List GetCompletionData(IProjectContent projectContent, bool showItemsFromAllNamespaces) + { + // Little hack - store value in a property to pass it to GetCompletionData(LanguageProperties language, bool showStatic) + // Otherwise we would have to add it as a parameter to GetCompletionData(IProjectContent projectContent), + // which would change signature in classes overriding this method as well. + this.showAllNamespacesContentsInCC = showItemsFromAllNamespaces; + var result = GetCompletionData(projectContent); + this.showAllNamespacesContentsInCC = false; + return result; + } + public virtual List GetCompletionData(IProjectContent projectContent) { return GetCompletionData(projectContent.Language, false); @@ -94,7 +112,7 @@ namespace ICSharpCode.SharpDevelop.Dom } if (!showStatic && callingClass != null) { - AddExtensions(language, res.Add, callingClass, resolvedType); + AddExtensions(language, res.Add, callingClass, resolvedType, this.showAllNamespacesContentsInCC); } return res; @@ -103,7 +121,7 @@ namespace ICSharpCode.SharpDevelop.Dom /// /// Adds extension methods to . /// - public static void AddExtensions(LanguageProperties language, Action methodFound, IClass callingClass, IReturnType resolvedType) + public static void AddExtensions(LanguageProperties language, Action methodFound, IClass callingClass, IReturnType resolvedType, bool searchInAllNamespaces = false) { if (language == null) throw new ArgumentNullException("language"); @@ -117,7 +135,7 @@ namespace ICSharpCode.SharpDevelop.Dom // convert resolvedType into direct type to speed up the IsApplicable lookups resolvedType = resolvedType.GetDirectReturnType(); - foreach (IMethodOrProperty mp in CtrlSpaceResolveHelper.FindAllExtensions(language, callingClass)) { + foreach (IMethodOrProperty mp in CtrlSpaceResolveHelper.FindAllExtensions(language, callingClass, searchInAllNamespaces)) { TryAddExtension(language, methodFound, mp, resolvedType); } }