Browse Source

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
pull/1/head
Martin Koníček 15 years ago
parent
commit
8bebbe33fc
  1. 7
      src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
  2. 11
      src/Main/Base/Project/Src/Editor/CodeCompletion/CtrlSpaceCompletionItemProvider.cs
  3. 2
      src/Main/Base/Project/Src/Editor/CodeCompletion/NRefactoryCodeCompletionBinding.cs
  4. 11
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CtrlSpaceResolveHelper.cs
  5. 30
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  6. 24
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs

7
src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs

@ -49,6 +49,11 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
/// </summary> /// </summary>
public class CodeCompletionItemProvider : AbstractCompletionItemProvider public class CodeCompletionItemProvider : AbstractCompletionItemProvider
{ {
/// <summary>
/// Gets/Sets whether items from all namespaces should be included in code completion, regardless of imports.
/// </summary>
public bool ShowItemsFromAllNamespaces { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
public override ICompletionItemList GenerateCompletionList(ITextEditor editor) public override ICompletionItemList GenerateCompletionList(ITextEditor editor)
{ {
@ -103,7 +108,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
if (rr == null) if (rr == null)
return null; return null;
IProjectContent callingContent = rr.CallingClass != null ? rr.CallingClass.ProjectContent : null; IProjectContent callingContent = rr.CallingClass != null ? rr.CallingClass.ProjectContent : null;
List<ICompletionEntry> arr = rr.GetCompletionData(callingContent ?? ParserService.CurrentProjectContent); List<ICompletionEntry> arr = rr.GetCompletionData(callingContent ?? ParserService.CurrentProjectContent, this.ShowItemsFromAllNamespaces);
return GenerateCompletionListForCompletionData(arr, context); return GenerateCompletionListForCompletionData(arr, context);
} }

11
src/Main/Base/Project/Src/Editor/CodeCompletion/CtrlSpaceCompletionItemProvider.cs

@ -27,17 +27,12 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
ExpressionContext overrideContext; ExpressionContext overrideContext;
bool allowCompleteExistingExpression;
/// <summary> /// <summary>
/// Gets/Sets whether completing an old expression is allowed. /// Gets/Sets whether completing an old expression is allowed.
/// You have to set this property to true to let the provider run FindExpression, when /// 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). /// set to false it will use ExpressionContext.Default (unless the constructor with "overrideContext" was used).
/// </summary> /// </summary>
public bool AllowCompleteExistingExpression { public bool AllowCompleteExistingExpression { get; set; }
get { return allowCompleteExistingExpression; }
set { allowCompleteExistingExpression = value; }
}
/// <summary> /// <summary>
/// Gets/Sets whether code templates should be included in code completion. /// Gets/Sets whether code templates should be included in code completion.
@ -67,7 +62,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
ICompletionItemList GenerateCompletionListCore(ITextEditor editor) ICompletionItemList GenerateCompletionListCore(ITextEditor editor)
{ {
preselectionLength = 0; preselectionLength = 0;
if (!allowCompleteExistingExpression) { if (!AllowCompleteExistingExpression) {
ExpressionContext context = overrideContext ?? ExpressionContext.Default; ExpressionContext context = overrideContext ?? ExpressionContext.Default;
var ctrlSpace = CtrlSpace(editor, context); var ctrlSpace = CtrlSpace(editor, context);
return GenerateCompletionListForCompletionData(ctrlSpace, context); return GenerateCompletionListForCompletionData(ctrlSpace, context);
@ -128,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
editor.Caret.Line, editor.Caret.Column, editor.Caret.Line, editor.Caret.Column,
ParserService.GetParseInformation(editor.FileName), ParserService.GetParseInformation(editor.FileName),
editor.Document.Text, editor.Document.Text,
context); context, this.ShowItemsFromAllNamespaces);
} }
} }
} }

2
src/Main/Base/Project/Src/Editor/CodeCompletion/NRefactoryCodeCompletionBinding.cs

@ -64,6 +64,8 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
{ {
NRefactoryCtrlSpaceCompletionItemProvider provider = new NRefactoryCtrlSpaceCompletionItemProvider(languageProperties); NRefactoryCtrlSpaceCompletionItemProvider provider = new NRefactoryCtrlSpaceCompletionItemProvider(languageProperties);
provider.AllowCompleteExistingExpression = true; provider.AllowCompleteExistingExpression = true;
// on Ctrl+Space, include members (e.g. extension methods) from all namespaces, regardless of imports
provider.ShowItemsFromAllNamespaces = true;
provider.ShowCompletion(editor); provider.ShowCompletion(editor);
return true; return true;
} }

11
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CtrlSpaceResolveHelper.cs

@ -235,7 +235,7 @@ namespace ICSharpCode.SharpDevelop.Dom
return null; return null;
} }
public static IList<IMethodOrProperty> FindAllExtensions(LanguageProperties language, IClass callingClass) public static IList<IMethodOrProperty> FindAllExtensions(LanguageProperties language, IClass callingClass, bool searchInAllNamespaces = false)
{ {
if (language == null) if (language == null)
throw new ArgumentNullException("language"); throw new ArgumentNullException("language");
@ -251,9 +251,12 @@ namespace ICSharpCode.SharpDevelop.Dom
IMethod dummyMethod = new DefaultMethod("dummy", callingClass.ProjectContent.SystemTypes.Void, IMethod dummyMethod = new DefaultMethod("dummy", callingClass.ProjectContent.SystemTypes.Void,
ModifierEnum.Static, DomRegion.Empty, DomRegion.Empty, callingClass); ModifierEnum.Static, DomRegion.Empty, DomRegion.Empty, callingClass);
CtrlSpaceResolveHelper.AddContentsFromCalling(list, callingClass, dummyMethod); CtrlSpaceResolveHelper.AddContentsFromCalling(list, callingClass, dummyMethod);
CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass); if (searchInAllNamespaces) {
// search extension methods in all referenced projects, no matter the using section // search extension methods in all referenced projects, no matter the using section
//CtrlSpaceResolveHelper.AddReferencedProjectsContents(list, callingClass.CompilationUnit, callingClass); CtrlSpaceResolveHelper.AddReferencedProjectsContents(list, callingClass.CompilationUnit, callingClass);
} else {
CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, callingClass.CompilationUnit, callingClass);
}
bool searchExtensionsInClasses = language.SearchExtensionsInClasses; bool searchExtensionsInClasses = language.SearchExtensionsInClasses;
foreach (object o in list) { foreach (object o in list) {

30
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -1010,13 +1010,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
ReadOnlyCollection<IMethodOrProperty> cachedExtensionMethods; ReadOnlyCollection<IMethodOrProperty> cachedExtensionMethods;
IClass cachedExtensionMethods_LastClass; // invalidate cache when callingClass != LastClass IClass cachedExtensionMethods_LastClass; // invalidate cache when callingClass != LastClass
public ReadOnlyCollection<IMethodOrProperty> SearchAllExtensionMethods() public ReadOnlyCollection<IMethodOrProperty> SearchAllExtensionMethods(bool searchInAllNamespaces = false)
{ {
if (callingClass == null) if (callingClass == null)
return EmptyList<IMethodOrProperty>.Instance; return EmptyList<IMethodOrProperty>.Instance;
if (callingClass != cachedExtensionMethods_LastClass) { if (callingClass != cachedExtensionMethods_LastClass) {
cachedExtensionMethods_LastClass = callingClass; cachedExtensionMethods_LastClass = callingClass;
cachedExtensionMethods = new ReadOnlyCollection<IMethodOrProperty>(CtrlSpaceResolveHelper.FindAllExtensions(languageProperties, callingClass)); cachedExtensionMethods = new ReadOnlyCollection<IMethodOrProperty>(CtrlSpaceResolveHelper.FindAllExtensions(languageProperties, callingClass, searchInAllNamespaces));
} }
return cachedExtensionMethods; return cachedExtensionMethods;
} }
@ -1122,7 +1122,17 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
} }
public List<ICompletionEntry> CtrlSpace(int caretLine, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext context) /// <summary>
/// Returns code completion entries for given context.
/// </summary>
/// <param name="caretLine"></param>
/// <param name="caretColumn"></param>
/// <param name="parseInfo"></param>
/// <param name="fileContent"></param>
/// <param name="context"></param>
/// <param name="showEntriesFromAllNamespaces">If true, returns entries from all namespaces, regardless of current imports.</param>
/// <returns></returns>
public List<ICompletionEntry> CtrlSpace(int caretLine, int caretColumn, ParseInformation parseInfo, string fileContent, ExpressionContext context, bool showEntriesFromAllNamespaces = false)
{ {
if (!Initialize(parseInfo, caretLine, caretColumn)) if (!Initialize(parseInfo, caretLine, caretColumn))
return null; return null;
@ -1231,7 +1241,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} }
} }
void CtrlSpaceInternal(List<ICompletionEntry> result, string fileContent) void CtrlSpaceInternal(List<ICompletionEntry> result, string fileContent, bool showEntriesFromAllNamespaces = true)
{ {
lookupTableVisitor = new LookupTableVisitor(language); lookupTableVisitor = new LookupTableVisitor(language);
@ -1265,11 +1275,13 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
result.Add(new DefaultField.ParameterField(callingMember.ReturnType, "value", callingMember.Region, callingClass)); result.Add(new DefaultField.ParameterField(callingMember.ReturnType, "value", callingMember.Region, callingClass));
} }
// CC contains contents of all imported namespaces if (showEntriesFromAllNamespaces) {
//CtrlSpaceResolveHelper.AddImportedNamespaceContents(result, cu, callingClass); // FindReferences to AddImportedNamespaceContents results in OutOfMemory // CC contains contents of all referenced assemblies
CtrlSpaceResolveHelper.AddReferencedProjectsContents(result, cu, callingClass);
// CC contains contents of all referenced assemblies } else {
CtrlSpaceResolveHelper.AddReferencedProjectsContents(result, cu, callingClass); // CC contains contents of all imported namespaces
CtrlSpaceResolveHelper.AddImportedNamespaceContents(result, cu, callingClass);
}
} }
sealed class CompareLambdaByLocation : IEqualityComparer<LambdaExpression> sealed class CompareLambdaByLocation : IEqualityComparer<LambdaExpression>

24
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs

@ -78,6 +78,24 @@ namespace ICSharpCode.SharpDevelop.Dom
return this.Clone(); return this.Clone();
} }
bool showAllNamespacesContentsInCC = false;
/// <summary>
/// Gets code completion data for this ResolveResult.
/// </summary>
/// <param name="projectContent"></param>
/// <param name="showItemsFromAllNamespaces">If true, items (e.g. extension methods) from all namespaces are returned, regardless current imports. Default is false.</param>
/// <returns></returns>
public List<ICompletionEntry> 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<ICompletionEntry> GetCompletionData(IProjectContent projectContent) public virtual List<ICompletionEntry> GetCompletionData(IProjectContent projectContent)
{ {
return GetCompletionData(projectContent.Language, false); return GetCompletionData(projectContent.Language, false);
@ -94,7 +112,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
if (!showStatic && callingClass != null) { if (!showStatic && callingClass != null) {
AddExtensions(language, res.Add, callingClass, resolvedType); AddExtensions(language, res.Add, callingClass, resolvedType, this.showAllNamespacesContentsInCC);
} }
return res; return res;
@ -103,7 +121,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <summary> /// <summary>
/// Adds extension methods to <paramref name="res"/>. /// Adds extension methods to <paramref name="res"/>.
/// </summary> /// </summary>
public static void AddExtensions(LanguageProperties language, Action<IMethodOrProperty> methodFound, IClass callingClass, IReturnType resolvedType) public static void AddExtensions(LanguageProperties language, Action<IMethodOrProperty> methodFound, IClass callingClass, IReturnType resolvedType, bool searchInAllNamespaces = false)
{ {
if (language == null) if (language == null)
throw new ArgumentNullException("language"); throw new ArgumentNullException("language");
@ -117,7 +135,7 @@ namespace ICSharpCode.SharpDevelop.Dom
// convert resolvedType into direct type to speed up the IsApplicable lookups // convert resolvedType into direct type to speed up the IsApplicable lookups
resolvedType = resolvedType.GetDirectReturnType(); 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); TryAddExtension(language, methodFound, mp, resolvedType);
} }
} }

Loading…
Cancel
Save