diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
index 2044291750..640e829325 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
@@ -261,10 +261,10 @@ namespace CSharpBinding
new ClassFinder(ParserService.GetParseInformation(editor.FileName), editor.Caret.Line, editor.Caret.Column)
), "");
if (suggestedClassName != c.Name) {
- // create an IClass instance that includes the type arguments in its name
- context.SuggestedItem = new RenamedClass(c, suggestedClassName);
+ // create a special code completion item that completes also the type arguments
+ context.SuggestedItem = new SuggestedCodeCompletionItem(c, suggestedClassName);
} else {
- context.SuggestedItem = c;
+ context.SuggestedItem = new CodeCompletionItem(c);
}
}
return context;
@@ -273,27 +273,6 @@ namespace CSharpBinding
return null;
}
- ///
- /// A class that copies the properties important for the code completion display from another class,
- /// but provides its own Name implementation.
- /// Unlike the AbstractEntity.Name implementation, here 'Name' may include the namespace or type arguments.
- ///
- sealed class RenamedClass : DefaultClass, IClass
- {
- string newName;
-
- public RenamedClass(IClass c, string newName) : base(c.CompilationUnit, c.ClassType, c.Modifiers, c.Region, c.DeclaringType)
- {
- this.newName = newName;
- CopyDocumentationFrom(c);
- this.FullyQualifiedName = c.FullyQualifiedName;
- }
-
- string ICompletionEntry.Name {
- get { return newName; }
- }
- }
-
#region "case"-keyword completion
bool DoCaseCompletion(ITextEditor editor)
{
diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
index 3187c651ff..b3a88d759e 100644
--- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
+++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
@@ -351,6 +351,7 @@
Code
+
@@ -362,7 +363,6 @@
-
diff --git a/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs b/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
index c91bf39aa3..0d7930e8dd 100644
--- a/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
+++ b/src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
@@ -154,18 +154,13 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
if (method != null && codeItem != null) {
methodItems[method.Name] = codeItem;
}
- if (o.Equals(context.SuggestedItem))
- result.SuggestedItem = item;
}
}
- if (context.SuggestedItem != null) {
- if (result.SuggestedItem == null) {
- result.SuggestedItem = CreateCompletionItem(context.SuggestedItem, context);
- if (result.SuggestedItem != null) {
- result.Items.Insert(0, result.SuggestedItem);
- }
- }
+ // Suggested entry (List a = new => suggest List).
+ if (context.SuggestedItem is SuggestedCodeCompletionItem) {
+ result.SuggestedItem = (SuggestedCodeCompletionItem)context.SuggestedItem;
+ result.Items.Insert(0, result.SuggestedItem);
}
return result;
}
@@ -238,6 +233,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
description = ambience.Convert(entity);
this.Image = ClassBrowserIconService.GetIcon(entity);
this.Overloads = 1;
+ this.InsertGenericArguments = false;
this.Priority = CodeCompletionDataUsageCache.GetPriority(entity.DotNetName, true);
}
@@ -252,6 +248,12 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
public IImage Image { get; set; }
+ ///
+ /// If true, will insert Text including generic arguments (e.g. List<T> or List<string>).
+ /// Otherwise will insert Text without generic arguments (e.g. List).
+ ///
+ public bool InsertGenericArguments { get; set; }
+
protected void MarkAsUsed()
{
CodeCompletionDataUsageCache.IncrementUsage(entity.DotNetName);
@@ -288,8 +290,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
addUsing = !IsKnownName(nameResult);
}
- //insertedText = StripGenericArgument(insertedText, context);
- InsertText(context, insertedText);
+ InsertTextStripGenericArguments(context, insertedText, this.InsertGenericArguments);
if (addUsing && nameResult != null && nameResult.CallingClass != null) {
var cu = nameResult.CallingClass.CompilationUnit;
@@ -298,15 +299,28 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
}
} else {
// Something else than a class or Extension method is being inserted - just insert text
- //insertedText = StripGenericArgument(insertedText, context);
- InsertText(context, insertedText);
+ InsertTextStripGenericArguments(context, insertedText, this.InsertGenericArguments);
+ }
+ }
+
+ ///
+ /// Inserts the given text. Strips generic arguments from it if specified.
+ ///
+ static void InsertTextStripGenericArguments(CompletionContext context, string insertedText, bool stringGenericArguments)
+ {
+ if (!stringGenericArguments) {
+ // FIXME CodeCompletionItem should contain IReturnType and decide whether to INCLUDE generic arguments
+ // or not, not strip them.
+ insertedText = StripGenericArguments(insertedText, context);
}
+ context.Editor.Document.Replace(context.StartOffset, context.Length, insertedText);
+ context.EndOffset = context.StartOffset + insertedText.Length;
}
///
/// Turns e.g. "List<T>" into "List<"
///
- string StripGenericArgument(string itemText, CompletionContext context)
+ static string StripGenericArguments(string itemText, CompletionContext context)
{
if (context == null || context.Editor == null || context.Editor.Language == null ||
context.Editor.Language.Properties != LanguageProperties.CSharp)
@@ -325,23 +339,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
return itemText;
}
- bool IsReferenceTo(ResolveResult nameResult, IClass selectedClass)
- {
- // CC list contains RenamedClass instances which are kind of hacky:
- // their name is e.g. "List" or "int[]", but they do not have any generic arguments,
- // so IsReferenceTo fails bc it compares generic argument count.
- // This compares just name and ignores generic arguments.
- return nameResult.IsReferenceTo(selectedClass) ||
- (nameResult.ResolvedType.IsConstructedReturnType &&
- nameResult.ResolvedType.FullyQualifiedName == selectedClass.FullyQualifiedName);
- }
-
- void InsertText(CompletionContext context, string insertedText)
- {
- context.Editor.Document.Replace(context.StartOffset, context.Length, insertedText);
- context.EndOffset = context.StartOffset + insertedText.Length;
- }
-
IClass GetClassOrExtensionMethodClass(IEntity selectedEntity)
{
var selectedClass = selectedEntity as IClass;
@@ -514,4 +511,18 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
}
#endregion
}
+
+ ///
+ /// CodeCompletionItem that inserts also generic arguments.
+ /// Used only when suggesting items in CC (e.g. List<int> a = new => suggest List<int>).
+ ///
+ public class SuggestedCodeCompletionItem : CodeCompletionItem
+ {
+ public SuggestedCodeCompletionItem(IEntity entity, string nameWithSpecifiedGenericArguments)
+ : base(entity)
+ {
+ this.Text = nameWithSpecifiedGenericArguments;
+ this.InsertGenericArguments = true;
+ }
+ }
}
diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
index a172c0f72d..433a9ab7b8 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
@@ -276,6 +276,12 @@ namespace ICSharpCode.SharpDevelop
return null;
}
+ public static ResolveResult Resolve(int offset, IDocument document, string fileName)
+ {
+ var position = document.OffsetToPosition(offset);
+ return Resolve(position.Line, position.Column, document, fileName);
+ }
+
public static ExpressionResult FindFullExpression(int caretLine, int caretColumn, IDocument document, string fileName)
{
IExpressionFinder expressionFinder = GetExpressionFinder(fileName);
@@ -285,12 +291,6 @@ namespace ICSharpCode.SharpDevelop
return ExpressionResult.Empty;
return expressionFinder.FindFullExpression(document.Text, document.PositionToOffset(caretLine, caretColumn));
}
-
- public static ResolveResult Resolve(int offset, IDocument document, string fileName)
- {
- var position = document.OffsetToPosition(offset);
- return Resolve(position.Line, position.Column, document, fileName);
- }
#endregion
#region GetParseableFileContent
diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActionsHelper.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHelper.cs
similarity index 100%
rename from src/Main/Base/Project/Src/Services/RefactoringService/ContextActionsHelper.cs
rename to src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/ContextActionsHelper.cs
diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs
index 3a570c0f01..b96b6d51d3 100644
--- a/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs
+++ b/src/Main/Base/Project/Src/Services/RefactoringService/ContextActions/EditorContext.cs
@@ -181,11 +181,12 @@ namespace ICSharpCode.SharpDevelop.Refactoring
----------------------
CurrentLineAST: {2}
----------------------
- AstNodeAtCaret: {3}
+ CurrentASTNode: [{3}] {4}
----------------------
- CurrentMemberAST: {4}
+ CurrentMemberAST: {5}
----------------------",
CurrentExpression, CurrentSymbol, CurrentLineAST,
+ CurrentElement == null ? "" : CurrentElement.GetType().ToString(),
CurrentElement == null ? "" : CurrentElement.ToString().TakeStartEllipsis(400),
CurrentMemberAST == null ? "" : CurrentMemberAST.ToString().TakeStartEllipsis(400)));
}