diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs index f97cac0190..7718388afc 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/Parser/ExpressionFinder.cs @@ -32,7 +32,7 @@ namespace VBNetBinding.Parser return CreateResult(FindExpressionInternal(inText, offset)); } - string FindExpressionInternal(string inText, int offset) + public string FindExpressionInternal(string inText, int offset) { this.text = FilterComments(inText, ref offset); this.offset = this.lastAccept = offset; @@ -59,6 +59,12 @@ namespace VBNetBinding.Parser return this.text.Substring(this.lastAccept + 1, offset - this.lastAccept); } + internal int LastExpressionStartPosition { + get { + return ((state == ACCEPTNOMORE) ? offset : lastAccept) + 1; + } + } + public ExpressionResult FindFullExpression(string inText, int offset) { string expressionBeforeOffset = FindExpressionInternal(inText, offset); diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs index 506ce9db11..0866d17bf5 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs @@ -1,12 +1,18 @@ // // 2002-2005 AlphaSierraPapa // GNU General Public License -// +// // $Revision$ // 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; @@ -20,6 +26,138 @@ namespace VBNetBinding this.EnableXmlCommentCompletion = true; } + public override bool HandleKeyPress(SharpDevelopTextAreaControl editor, char ch) + { + if (!CheckExtension(editor)) + { + return false; + } + + VBNetBinding.Parser.ExpressionFinder ef = new VBNetBinding.Parser.ExpressionFinder(); + int cursor = editor.ActiveTextAreaControl.Caret.Offset; + ExpressionContext context = null; + + if (ch == ' ') { + if(CodeCompletionOptions.KeywordCompletionEnabled) { + switch (editor.GetWordBeforeCaret().Trim().ToLower()) { + case "synclock": + context = ExpressionContext.Default; + break; + case "using": + context = ExpressionContext.TypeDerivingFrom(ReflectionReturnType.Disposable.GetUnderlyingClass(), false); + break; + case "catch": + context = ExpressionContext.TypeDerivingFrom(ReflectionReturnType.Exception.GetUnderlyingClass(), false); + break; + } + } + if(context != null) { + editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(context), ch); + return true; + } + } + else if(ch == '(' && EnableMethodInsight && CodeCompletionOptions.InsightEnabled) + { + editor.ShowInsightWindow(new MethodInsightDataProvider()); + 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 parameters = new Stack(); + 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 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); + } + } + } + + void ShowInsight(SharpDevelopTextAreaControl editor, MethodInsightDataProvider dp, Stack parameters, char charTyped) + { + int paramCount = parameters.Count; + dp.SetupDataProvider(editor.FileName, editor.ActiveTextAreaControl.TextArea); + List 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(new ArrayList(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); + } + } + } + public override bool HandleKeyword(SharpDevelopTextAreaControl editor, string word) { // TODO: Assistance writing Methods/Fields/Properties/Events: @@ -31,12 +169,17 @@ namespace VBNetBinding editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Namespace), ' '); return true; case "as": - System.Windows.Forms.MessageBox.Show("as"); editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Type), ' '); return true; case "new": editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.ObjectCreation), ' '); return true; + case "inherits": + editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Type), ' '); + return true; + case "implements": + editor.ShowCompletionWindow(new CtrlSpaceCompletionDataProvider(ExpressionContext.Interface), ' '); + return true; default: return base.HandleKeyword(editor, word); } diff --git a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetLanguageBinding.cs b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetLanguageBinding.cs index 985ba2d4c8..9c341351e5 100644 --- a/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetLanguageBinding.cs +++ b/src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetLanguageBinding.cs @@ -1,7 +1,7 @@ // // 2002-2005 AlphaSierraPapa // GNU General Public License -// +// // $Revision$ // @@ -27,7 +27,8 @@ namespace VBNetBinding { public const string LanguageName = "VBNet"; - public string Language { + public string Language + { get { return LanguageName; } diff --git a/src/Main/Base/Project/Src/Dom/ExpressionContext.cs b/src/Main/Base/Project/Src/Dom/ExpressionContext.cs index 6bb8e3dad0..df407e3846 100644 --- a/src/Main/Base/Project/Src/Dom/ExpressionContext.cs +++ b/src/Main/Base/Project/Src/Dom/ExpressionContext.cs @@ -52,6 +52,10 @@ namespace ICSharpCode.SharpDevelop.Dom { return new TypeExpressionContext(baseClass, mustBeConstructable); } + + /// Context expeacts an interface + public static InterfaceExpressionContext Interface = new InterfaceExpressionContext(); + #endregion #region DefaultExpressionContext @@ -176,5 +180,32 @@ namespace ICSharpCode.SharpDevelop.Dom } } #endregion + + #region InterfaceExpressionContext + public class InterfaceExpressionContext : ExpressionContext + { + IClass baseClass; + + public InterfaceExpressionContext() + { + } + + public override bool ShowEntry(object o) + { + if (o is string) + return true; + IClass c = o as IClass; + if (c == null) + return false; + + return c.ClassType == ClassType.Interface; + } + + public override string ToString() + { + return "[" + GetType().Name + "]"; + } + } + #endregion } }