From 1710bc93343255435bf2ca0dfbec94d621a28dbc Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Mon, 6 Oct 2008 15:44:58 +0000 Subject: [PATCH] Implemented Code Completion support of -> Operator git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3591 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/CSharpCompletionBinding.cs | 39 ++++++++++++++++++- .../AbstractCompletionDataProvider.cs | 2 +- .../Project/Src/CSharp/ExpressionFinder.cs | 7 ++-- .../Src/NRefactoryResolver/ResolveVisitor.cs | 12 ++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs index a24953710f..50302da7a4 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpCompletionBinding.cs @@ -95,6 +95,15 @@ namespace CSharpBinding } else if (ch == '.') { editor.ShowCompletionWindow(new CSharpCodeCompletionDataProvider(), ch); return true; + } else if (ch == '>') { + if (IsInComment(editor)) return false; + LineSegment segment = editor.Document.GetLineSegmentForOffset(editor.ActiveTextAreaControl.Caret.Offset); + TextWord sign = segment.GetWord(editor.ActiveTextAreaControl.Caret.Column - 1); + if (sign.Word == "-") { + editor.ShowCompletionWindow(new PointerArrowCompletionDataProvider(), ch); + + return true; + } } if (char.IsLetter(ch) && CodeCompletionOptions.CompleteWhenTyping) { @@ -108,7 +117,7 @@ namespace CSharpBinding ExpressionResult result = ef.FindExpression(editor.Text, cursor); LoggingService.Debug("CC: Beginning to type a word, result=" + result); if (result.Context != ExpressionContext.IdentifierExpected) { - editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(result.Context) { + editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(result.Context) { ShowTemplates = true, AllowCompleteExistingExpression = afterUnderscore }, '\0'); @@ -131,6 +140,34 @@ namespace CSharpBinding } } + class PointerArrowCompletionDataProvider : CodeCompletionDataProvider + { + protected override ResolveResult Resolve(ExpressionResult expressionResult, int caretLineNumber, int caretColumn, string fileName, string fileContent) + { + ResolveResult rr = base.Resolve(expressionResult, caretLineNumber, caretColumn, fileName, fileContent); + if (rr != null && rr.ResolvedType != null) { + PointerReturnType prt = rr.ResolvedType.CastToDecoratingReturnType(); + if (prt != null) + return new ResolveResult(rr.CallingClass, rr.CallingMember, prt.BaseType); + } + return null; + } + + protected override ExpressionResult GetExpression(ICSharpCode.TextEditor.TextArea textArea) + { + ICSharpCode.TextEditor.Document.IDocument document = textArea.Document; + IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName); + if (expressionFinder == null) { + return new ExpressionResult(TextUtilities.GetExpressionBeforeOffset(textArea, textArea.Caret.Offset - 1)); + } else { + ExpressionResult res = expressionFinder.FindExpression(document.GetText(0, textArea.Caret.Offset - 1), textArea.Caret.Offset - 1); + if (overrideContext != null) + res.Context = overrideContext; + return res; + } + } + } + bool IsInComment(SharpDevelopTextAreaControl editor) { CSharpExpressionFinder ef = CreateExpressionFinder(editor.FileName); diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs index 3e089902eb..184282aa56 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/AbstractCompletionDataProvider.cs @@ -128,7 +128,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor return completionData.ToArray(); } - protected ExpressionResult GetExpression(TextArea textArea) + protected virtual ExpressionResult GetExpression(TextArea textArea) { IDocument document = textArea.Document; IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(fileName); diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs index d557093489..3424fe1f5b 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs @@ -492,13 +492,14 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp // do not reset context - TrackCurrentContext will take care of this frame.lastExpressionStart = Location.Empty; break; + case Tokens.Pointer: case Tokens.Dot: case Tokens.DoubleColon: // let the current expression continue break; default: if (Tokens.IdentifierTokens[token.kind]) { - if (lastToken != Tokens.Dot && lastToken != Tokens.DoubleColon) { + if (lastToken != Tokens.Dot && lastToken != Tokens.DoubleColon && lastToken != Tokens.Pointer) { if (Tokens.ValidInsideTypeName[lastToken]) { frame.SetDefaultContext(); } @@ -821,7 +822,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp resultStartOffset = lastExpressionStartOffset; if (resultFrame.type == FrameType.Popped || lastExpressionStartOffset != resultStartOffset || - token.kind == Tokens.Dot || token.kind == Tokens.DoubleColon) + token.kind == Tokens.Dot || token.kind == Tokens.DoubleColon || token.kind == Tokens.Pointer) { // now we can change the context based on the next token @@ -865,7 +866,7 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp if (token.kind == Tokens.EOF) break; if (frame.parent == null) { - if (token.kind == Tokens.Dot || token.kind == Tokens.DoubleColon + if (token.kind == Tokens.Dot || token.kind == Tokens.DoubleColon || token.kind == Tokens.Pointer || token.kind == Tokens.OpenParenthesis || token.kind == Tokens.OpenSquareBracket) { lastValidPos = LocationToOffset(token.Location); diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs index aaac809d46..e4bb5ffac2 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs @@ -522,6 +522,18 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver public override object VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, object data) { + ResolveResult targetRR = Resolve(pointerReferenceExpression.TargetObject); + if (targetRR == null) + return null; + PointerReturnType type = targetRR.ResolvedType.CastToDecoratingReturnType(); + if (type != null) { + TypeResolveResult typeRR = targetRR as TypeResolveResult; + return resolver.ResolveMember(type.BaseType, pointerReferenceExpression.Identifier, + pointerReferenceExpression.TypeArguments, + NRefactoryResolver.IsInvoked(pointerReferenceExpression), + true, null + ); + } return null; }