Browse Source

extracted insight window handling to InsightWindowHandler

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6324 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
c7e652c78a
  1. 2
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs
  2. 9
      src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionBinding.cs
  3. 207
      src/Main/Base/Project/Src/Editor/CodeCompletion/NRefactoryCodeCompletionBinding.cs

2
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs

@ -45,7 +45,7 @@ namespace CSharpBinding @@ -45,7 +45,7 @@ namespace CSharpBinding
return true;
}*/
} else if (ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled) {
if (InsightRefreshOnComma(editor, ch))
if (insightHandler.InsightRefreshOnComma(editor, ch))
return CodeCompletionKeyPressResult.Completed;
} else if(ch == '=') {
var curLine = editor.Document.GetLineForOffset(cursor);

9
src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionBinding.cs

@ -131,6 +131,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -131,6 +131,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
bool enableIndexerInsight = true;
bool enableXmlCommentCompletion = true;
bool enableDotCompletion = true;
protected InsightWindowHandler insightHandler;
public bool EnableMethodInsight {
get {
@ -168,10 +169,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -168,10 +169,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
}
}
protected virtual void InitializeOpenedInsightWindow(ITextEditor editor, IInsightWindow insightWindow)
{
}
public virtual CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
{
switch (ch) {
@ -179,7 +176,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -179,7 +176,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
if (enableMethodInsight && CodeCompletionOptions.InsightEnabled) {
IInsightWindow insightWindow = editor.ShowInsightWindow(new MethodInsightProvider().ProvideInsight(editor));
if (insightWindow != null)
InitializeOpenedInsightWindow(editor, insightWindow);
insightHandler.InitializeOpenedInsightWindow(editor, insightWindow);
return CodeCompletionKeyPressResult.Completed;
}
break;
@ -187,7 +184,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -187,7 +184,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
if (enableIndexerInsight && CodeCompletionOptions.InsightEnabled) {
IInsightWindow insightWindow = editor.ShowInsightWindow(new IndexerInsightProvider().ProvideInsight(editor));
if (insightWindow != null)
InitializeOpenedInsightWindow(editor, insightWindow);
insightHandler.InitializeOpenedInsightWindow(editor, insightWindow);
return CodeCompletionKeyPressResult.Completed;
}
break;

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

@ -26,37 +26,18 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -26,37 +26,18 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
public abstract class NRefactoryCodeCompletionBinding : DefaultCodeCompletionBinding
{
readonly SupportedLanguage language;
readonly int eofToken, commaToken, openParensToken, closeParensToken, openBracketToken, closeBracketToken, openBracesToken, closeBracesToken, statementEndToken;
readonly LanguageProperties languageProperties;
protected NRefactoryCodeCompletionBinding(SupportedLanguage language)
{
this.language = language;
if (language == SupportedLanguage.CSharp) {
eofToken = CSTokens.EOF;
commaToken = CSTokens.Comma;
openParensToken = CSTokens.OpenParenthesis;
closeParensToken = CSTokens.CloseParenthesis;
openBracketToken = CSTokens.OpenSquareBracket;
closeBracketToken = CSTokens.CloseSquareBracket;
openBracesToken = CSTokens.OpenCurlyBrace;
closeBracesToken = CSTokens.CloseCurlyBrace;
statementEndToken = CSTokens.Semicolon;
languageProperties = LanguageProperties.CSharp;
} else {
eofToken = VBTokens.EOF;
commaToken = VBTokens.Comma;
openParensToken = VBTokens.OpenParenthesis;
closeParensToken = VBTokens.CloseParenthesis;
openBracketToken = -1;
closeBracketToken = -1;
openBracesToken = VBTokens.OpenCurlyBrace;
closeBracesToken = VBTokens.CloseCurlyBrace;
statementEndToken = VBTokens.EOL;
languageProperties = LanguageProperties.VBNet;
}
insightHandler = new InsightWindowHandler(language);
}
public override bool CtrlSpace(ITextEditor editor)
@ -69,98 +50,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -69,98 +50,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
return true;
}
#region Comma Insight refresh
protected class InspectedCall
{
/// <summary>
/// position of the '('
/// </summary>
internal Location start;
/// <summary>
/// list of location of the comma tokens.
/// </summary>
internal List<Location> commas = new List<Location>();
/// <summary>
/// reference back to parent call - used to create a stack of inspected calls
/// </summary>
internal InspectedCall parent;
public InspectedCall(Location start, InspectedCall parent)
{
this.start = start;
this.parent = parent;
}
}
protected IList<ResolveResult> ResolveCallParameters(ITextEditor editor, InspectedCall call)
{
List<ResolveResult> rr = new List<ResolveResult>();
int offset = LocationToOffset(editor, call.start);
string documentText = editor.Document.Text;
int newOffset;
foreach (Location loc in call.commas) {
newOffset = LocationToOffset(editor, loc);
if (newOffset < 0) break;
string text = editor.Document.GetText(offset+1,newOffset-(offset+1));
rr.Add(ParserService.Resolve(new ExpressionResult(text), loc.Line, loc.Column, editor.FileName, documentText));
}
// the last argument is between the last comma and the caret position
newOffset = editor.Caret.Offset;
if (offset < newOffset) {
string text = editor.Document.GetText(offset+1,newOffset-(offset+1));
rr.Add(ParserService.Resolve(new ExpressionResult(text),
editor.Caret.Line,
editor.Caret.Column,
editor.FileName, documentText));
}
return rr;
}
protected bool InsightRefreshOnComma(ITextEditor editor, char ch)
{
// Show MethodInsightWindow or IndexerInsightWindow
NRefactoryResolver r = new NRefactoryResolver(languageProperties);
Location cursorLocation = editor.Caret.Position;
if (r.Initialize(ParserService.GetParseInformation(editor.FileName), cursorLocation.Y, cursorLocation.X)) {
TextReader currentMethod = r.ExtractCurrentMethod(editor.Document.Text);
if (currentMethod != null) {
ILexer lexer = ParserFactory.CreateLexer(language, currentMethod);
Token token;
InspectedCall call = new InspectedCall(Location.Empty, null);
call.parent = call;
while ((token = lexer.NextToken()) != null
&& token.Kind != eofToken
&& token.Location < cursorLocation)
{
if (token.Kind == commaToken) {
call.commas.Add(token.Location);
} else if (token.Kind == openParensToken || token.Kind == openBracketToken || token.Kind == openBracesToken) {
call = new InspectedCall(token.Location, call);
} else if (token.Kind == closeParensToken || token.Kind == closeBracketToken || token.Kind == closeBracesToken) {
call = call.parent;
}
}
int offset = LocationToOffset(editor, call.start);
if (offset >= 0 && offset < editor.Document.TextLength) {
char c = editor.Document.GetCharAt(offset);
if (c == '(' || c == '[') {
var insightProvider = new MethodInsightProvider { LookupOffset = offset };
var insightItems = insightProvider.ProvideInsight(editor);
ShowInsight(editor,
insightItems,
ResolveCallParameters(editor, call),
ch);
return true;
} else {
LoggingService.Warn("Expected '(' or '[' at start position");
}
}
}
}
return false;
}
#endregion
protected bool ProvideContextCompletion(ITextEditor editor, IReturnType expected, char charTyped)
{
if (expected == null) return false;
@ -202,62 +91,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -202,62 +91,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
}
}
protected void ShowInsight(ITextEditor editor, IList<IInsightItem> insightItems, ICollection<ResolveResult> parameters, char charTyped)
{
int paramCount = parameters.Count;
if (insightItems == null || insightItems.Count == 0)
return;
bool overloadIsSure;
int defaultIndex;
if (insightItems.Count == 1) {
overloadIsSure = true;
defaultIndex = 0;
} else {
var methods = insightItems.Select(item => GetMethodFromInsightItem(item)).ToList();
IReturnType[] argumentTypes = new IReturnType[paramCount + 1];
int i = 0;
foreach (ResolveResult rr in parameters) {
if (rr != null) {
argumentTypes[i] = rr.ResolvedType;
}
i++;
}
IMethodOrProperty result = Dom.CSharp.OverloadResolution.FindOverload(
methods.Where(m => m != null), argumentTypes, true, false, out overloadIsSure);
defaultIndex = methods.IndexOf(result);
}
IInsightWindow insightWindow = editor.ShowInsightWindow(insightItems);
if (insightWindow != null) {
InitializeOpenedInsightWindow(editor, insightWindow);
insightWindow.SelectedItem = insightItems[defaultIndex];
}
if (overloadIsSure) {
IMethodOrProperty method = GetMethodFromInsightItem(insightItems[defaultIndex]);
if (method != null && paramCount < method.Parameters.Count) {
IParameter param = method.Parameters[paramCount];
ProvideContextCompletion(editor, param.ReturnType, charTyped);
}
}
}
IMethodOrProperty GetMethodFromInsightItem(IInsightItem item)
{
MethodInsightItem mii = item as MethodInsightItem;
if (mii != null) {
return mii.Entity as IMethodOrProperty;
} else {
return null;
}
}
protected int LocationToOffset(ITextEditor editor, Location loc)
{
if (loc.IsEmpty || loc.Line > editor.Document.TotalNumberOfLines)
return -1;
IDocumentLine seg = editor.Document.GetLine(loc.Line);
return seg.Offset + Math.Min(loc.Column, seg.Length) - 1;
}
protected IMember GetCurrentMember(ITextEditor editor)
{
var caret = editor.Caret;
@ -268,41 +101,5 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -268,41 +101,5 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
return null;
}
}
protected override void InitializeOpenedInsightWindow(ITextEditor editor, IInsightWindow insightWindow)
{
EventHandler<TextChangeEventArgs> onDocumentChanged = delegate {
// whenever the document is changed, recalculate EndOffset
var remainingDocument = editor.Document.CreateReader(insightWindow.StartOffset, editor.Document.TextLength - insightWindow.StartOffset);
using (ILexer lexer = ParserFactory.CreateLexer(language, remainingDocument)) {
lexer.SetInitialLocation(editor.Document.OffsetToPosition(insightWindow.StartOffset));
Token token;
int bracketCount = 0;
while ((token = lexer.NextToken()) != null && token.Kind != eofToken) {
if (token.Kind == openParensToken || token.Kind == openBracketToken || token.Kind == openBracketToken) {
bracketCount++;
} else if (token.Kind == closeParensToken || token.Kind == closeBracketToken || token.Kind == closeBracesToken) {
bracketCount--;
if (bracketCount <= 0) {
MarkInsightWindowEndOffset(insightWindow, editor, token.Location);
break;
}
} else if (token.Kind == statementEndToken) {
MarkInsightWindowEndOffset(insightWindow, editor, token.Location);
break;
}
}
}
};
insightWindow.DocumentChanged += onDocumentChanged;
onDocumentChanged(null, null);
}
void MarkInsightWindowEndOffset(IInsightWindow insightWindow, ITextEditor editor, Location endLocation)
{
insightWindow.EndOffset = editor.Document.PositionToOffset(endLocation.Line, endLocation.Column);
if (editor.Caret.Offset > insightWindow.EndOffset)
insightWindow.Close();
}
}
}

Loading…
Cancel
Save