You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
7.4 KiB
199 lines
7.4 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright> |
|
// <license see="prj:///doc/license.txt">GNU General Public License</license> |
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
|
|
using System; |
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using ICSharpCode.Core; |
|
using ICSharpCode.TextEditor.Gui.CompletionWindow; |
|
using ICSharpCode.TextEditor.Document; |
|
using ICSharpCode.SharpDevelop; |
|
using ICSharpCode.SharpDevelop.Dom; |
|
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
|
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver; |
|
|
|
namespace CSharpBinding |
|
{ |
|
public class CSharpCompletionBinding : DefaultCodeCompletionBinding |
|
{ |
|
public CSharpCompletionBinding() : base(".cs") |
|
{ |
|
this.EnableXmlCommentCompletion = true; |
|
} |
|
|
|
public override bool HandleKeyPress(SharpDevelopTextAreaControl editor, char ch) |
|
{ |
|
if (!CheckExtension(editor)) |
|
return false; |
|
Parser.ExpressionFinder ef = new Parser.ExpressionFinder(editor.FileName); |
|
int cursor = editor.ActiveTextAreaControl.Caret.Offset; |
|
ExpressionContext context = null; |
|
if (ch == '(') { |
|
if (CodeCompletionOptions.KeywordCompletionEnabled) { |
|
switch (editor.GetWordBeforeCaret().Trim()) { |
|
case "for": |
|
case "lock": |
|
context = ExpressionContext.Default; |
|
break; |
|
case "using": |
|
context = ExpressionContext.TypeDerivingFrom(ReflectionReturnType.Disposable.GetUnderlyingClass(), false); |
|
break; |
|
case "catch": |
|
context = ExpressionContext.TypeDerivingFrom(ReflectionReturnType.Exception.GetUnderlyingClass(), false); |
|
break; |
|
case "foreach": |
|
case "typeof": |
|
case "sizeof": |
|
case "default": |
|
context = ExpressionContext.Type; |
|
break; |
|
} |
|
} |
|
if (context != null) { |
|
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(context), ch); |
|
return true; |
|
} else if (EnableMethodInsight && CodeCompletionOptions.InsightEnabled) { |
|
editor.ShowInsightWindow(new MethodInsightDataProvider()); |
|
return true; |
|
} |
|
return false; |
|
} else if (ch == '[') { |
|
LineSegment line = editor.Document.GetLineSegmentForOffset(cursor); |
|
if (TextUtilities.FindPrevWordStart(editor.Document, cursor) <= line.Offset) { |
|
// [ is first character on the line |
|
// -> Attribute completion |
|
editor.ShowCompletionWindow(new AttributesDataProvider(), ch); |
|
return true; |
|
} |
|
} else if (ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled) { |
|
// Show MethodInsightWindow or IndexerInsightWindow |
|
string documentText = editor.Text; |
|
int oldCursor = cursor; |
|
string textWithoutComments = ef.FilterComments(documentText, ref cursor); |
|
int commentLength = oldCursor - cursor; |
|
if (textWithoutComments != null) { |
|
Stack<ResolveResult> parameters = new Stack<ResolveResult>(); |
|
char c = '\0'; |
|
while (cursor > 0) { |
|
while (--cursor > 0 && |
|
((c = textWithoutComments[cursor]) == ',' || |
|
char.IsWhiteSpace(c))); |
|
if (c == '(') { |
|
ShowInsight(editor, new MethodInsightDataProvider(cursor + commentLength, true), parameters, ch); |
|
return true; |
|
} else if (c == '[') { |
|
ShowInsight(editor, new IndexerInsightDataProvider(cursor + commentLength, true), parameters, ch); |
|
return true; |
|
} |
|
string expr = ef.FindExpressionInternal(textWithoutComments, cursor); |
|
if (expr == null || expr.Length == 0) |
|
break; |
|
parameters.Push(ParserService.Resolve(new ExpressionResult(expr), |
|
editor.ActiveTextAreaControl.Caret.Line, |
|
editor.ActiveTextAreaControl.Caret.Column, |
|
editor.FileName, |
|
documentText)); |
|
cursor = ef.LastExpressionStartPosition; |
|
} |
|
} |
|
} |
|
return base.HandleKeyPress(editor, ch); |
|
} |
|
|
|
void ShowInsight(SharpDevelopTextAreaControl editor, MethodInsightDataProvider dp, Stack<ResolveResult> parameters, char charTyped) |
|
{ |
|
int paramCount = parameters.Count; |
|
dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea); |
|
List<IMethodOrIndexer> methods = dp.Methods; |
|
if (methods.Count == 0) return; |
|
bool overloadIsSure; |
|
if (methods.Count == 1) { |
|
overloadIsSure = true; |
|
dp.DefaultIndex = 0; |
|
} else { |
|
IReturnType[] parameterTypes = new IReturnType[paramCount + 1]; |
|
for (int i = 0; i < paramCount; i++) { |
|
ResolveResult rr = parameters.Pop(); |
|
if (rr != null) { |
|
parameterTypes[i] = rr.ResolvedType; |
|
} |
|
} |
|
dp.DefaultIndex = TypeVisitor.FindOverload(methods, parameterTypes, false, out overloadIsSure); |
|
} |
|
editor.ShowInsightWindow(dp); |
|
if (overloadIsSure) { |
|
IMethodOrIndexer method = methods[dp.DefaultIndex]; |
|
if (paramCount < method.Parameters.Count) { |
|
IParameter param = method.Parameters[paramCount]; |
|
ProvideContextCompletion(editor, param.ReturnType, charTyped); |
|
} |
|
} |
|
} |
|
|
|
void ProvideContextCompletion(SharpDevelopTextAreaControl editor, IReturnType expected, char charTyped) |
|
{ |
|
IClass c = expected.GetUnderlyingClass(); |
|
if (c == null) return; |
|
if (c.ClassType == ClassType.Enum) { |
|
CtrlSpaceCompletionDataProvider cdp = new CtrlSpaceCompletionDataProvider(); |
|
cdp.ForceNewExpression = true; |
|
CachedCompletionDataProvider cache = new CachedCompletionDataProvider(cdp); |
|
cache.GenerateCompletionData(editor.FileName, editor.ActiveTextAreaControl.TextArea, charTyped); |
|
ICompletionData[] completionData = cache.CompletionData; |
|
Array.Sort(completionData); |
|
for (int i = 0; i < completionData.Length; i++) { |
|
CodeCompletionData ccd = completionData[i] as CodeCompletionData; |
|
if (ccd != null && ccd.Class != null) { |
|
if (ccd.Class.FullyQualifiedName == expected.FullyQualifiedName) { |
|
cache.DefaultIndex = i; |
|
break; |
|
} |
|
} |
|
} |
|
if (cache.DefaultIndex >= 0) { |
|
editor.ShowCompletionWindow(cache, charTyped); |
|
} |
|
} |
|
} |
|
|
|
public override bool HandleKeyword(SharpDevelopTextAreaControl editor, string word) |
|
{ |
|
// TODO: Assistance writing Methods/Fields/Properties/Events: |
|
// use public/static/etc. as keywords to display a list with other modifiers |
|
// and possible return types. |
|
switch (word) { |
|
case "using": |
|
// TODO: check if we are inside class/namespace |
|
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Namespace), ' '); |
|
return true; |
|
case "as": |
|
case "is": |
|
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Type), ' '); |
|
return true; |
|
case "new": |
|
return ShowNewCompletion(editor); |
|
case "override": |
|
// TODO: Suggest list of virtual methods to override |
|
return false; |
|
default: |
|
return base.HandleKeyword(editor, word); |
|
} |
|
} |
|
|
|
bool ShowNewCompletion(SharpDevelopTextAreaControl editor) |
|
{ |
|
Parser.ExpressionFinder ef = new Parser.ExpressionFinder(editor.FileName); |
|
int cursor = editor.ActiveTextAreaControl.Caret.Offset; |
|
ExpressionContext context = ef.FindExpression(editor.Document.GetText(0, cursor) + " T.", cursor + 2).Context; |
|
if (context.IsObjectCreation) { |
|
editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(context), ' '); |
|
return true; |
|
} |
|
return false; |
|
} |
|
} |
|
}
|
|
|