Browse Source

- fixed bug in ExpressionFinder

- removed the need for CompletionDataProvider infrastructure

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6103 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
c60157c9a4
  1. 69
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/CompletionDataHelper.cs
  2. 87
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCodeCompletionDataProvider.cs
  3. 28
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs
  4. 4
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBindingOld.cs
  5. 2
      src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.csproj
  6. 9
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg
  7. 3874
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs
  8. 16
      src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs
  9. 6
      src/Main/Base/Test/VBExpressionFinderTests.cs

69
src/AddIns/BackendBindings/VBNetBinding/Project/Src/CompletionDataHelper.cs

@ -0,0 +1,69 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision: 6077 $</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
namespace ICSharpCode.VBNetBinding
{
public static class CompletionDataHelper
{
public static ICompletionItemList GenerateCompletionData(this ExpressionResult expressionResult, ITextEditor editor)
{
var result = new NRefactoryCompletionItemList();
IResolver resolver = ParserService.CreateResolver(editor.FileName);
ParseInformation info = ParserService.GetParseInformation(editor.FileName);
if (info == null)
return result;
List<ICompletionEntry> data = new List<ICompletionEntry>();
if (string.IsNullOrEmpty(expressionResult.Expression)) {
data = new NRefactoryResolver(LanguageProperties.VBNet)
.CtrlSpace(editor.Caret.Line, editor.Caret.Column, info, editor.Document.Text, expressionResult.Context, result.ContainsItemsFromAllNamespaces);
} else {
if (expressionResult.Context != ExpressionContext.Global && expressionResult.Context != ExpressionContext.TypeDeclaration) {
if (expressionResult.Context == ExpressionContext.Importable && expressionResult.Expression == "Imports") {
expressionResult.Expression = "Global";
}
var rr = resolver.Resolve(expressionResult, info, editor.Document.Text);
if (rr == null)
return result;
data = rr.GetCompletionData(info.CompilationUnit.ProjectContent, result.ContainsItemsFromAllNamespaces);
}
}
if (expressionResult.Tag != null && (expressionResult.Context != ExpressionContext.Importable))
AddVBNetKeywords(data, (BitArray)expressionResult.Tag);
return CodeCompletionItemProvider.ConvertCompletionData(result, data, expressionResult.Context);
}
static void AddVBNetKeywords(List<ICompletionEntry> ar, BitArray keywords)
{
for (int i = 0; i < keywords.Length; i++) {
if (keywords[i] && i >= Tokens.AddHandler && i < Tokens.MaxToken) {
ar.Add(new KeywordEntry(Tokens.GetTokenString(i)));
}
}
}
}
}

87
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCodeCompletionDataProvider.cs

@ -1,87 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision: 6077 $</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;
namespace ICSharpCode.VBNetBinding
{
public class VBNetCodeCompletionDataProvider : NRefactoryCtrlSpaceCompletionItemProvider
{
ExpressionResult result;
char pressed = '\0';
public VBNetCodeCompletionDataProvider(ExpressionResult result, char ch)
: base(LanguageProperties.VBNet, result.Context)
{
this.result = result;
pressed = ch;
}
protected override List<ICompletionEntry> CtrlSpace(ITextEditor editor, ExpressionContext context)
{
var list = base.CtrlSpace(editor, context);
BitArray expectedSet = result.Tag as BitArray;
if (expectedSet != null)
AddVBNetKeywords(list, expectedSet);
// Inherits, Implements
if (ExpressionContext.Type == context) {
}
if (ExpressionContext.MethodBody == context) {
}
return list;
}
public override ICompletionItemList GenerateCompletionList(ITextEditor editor)
{
if (result.Context == ExpressionContext.Importable && result.Expression == "Imports")
return new CodeCompletionItemProvider().GenerateCompletionListForExpression(editor, new ExpressionResult("Global") { Context = ExpressionContext.Importable });
if (pressed == '.')
return new VBNetDotCodeCompletionItemProvider().GenerateCompletionList(editor);
return base.GenerateCompletionList(editor);
}
class VBNetDotCodeCompletionItemProvider : DotCodeCompletionItemProvider
{
public override ResolveResult Resolve(ITextEditor editor, ExpressionResult expressionResult)
{
// bypass ParserService.Resolve and set resolver.LimitMethodExtractionUntilCaretLine
ParseInformation parseInfo = ParserService.GetParseInformation(editor.FileName);
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.VBNet);
resolver.LimitMethodExtractionUntilLine = editor.Caret.Line;
return resolver.Resolve(expressionResult, parseInfo, editor.Document.Text);
}
}
static void AddVBNetKeywords(List<ICompletionEntry> ar, BitArray keywords)
{
for (int i = 0; i < keywords.Length; i++) {
if (keywords[i] && i >= Tokens.AddHandler && i < Tokens.MaxToken) {
ar.Add(new KeywordEntry(Tokens.GetTokenString(i)));
}
}
}
}
}

28
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs

@ -51,18 +51,27 @@ namespace ICSharpCode.VBNetBinding
ExpressionResult result; ExpressionResult result;
switch (ch) { switch (ch) {
case '(':
if (CodeCompletionOptions.InsightEnabled) {
IInsightWindow insightWindow = editor.ShowInsightWindow(new MethodInsightProvider().ProvideInsight(editor));
// if (insightWindow != null)
// InitializeOpenedInsightWindow(editor, insightWindow);
return CodeCompletionKeyPressResult.Completed;
}
break;
case '"':
case '\n': case '\n':
break; break;
case '.': case '.':
result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset); result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset);
LoggingService.Debug("CC: After dot, result=" + result + ", context=" + result.Context); LoggingService.Debug("CC: After dot, result=" + result + ", context=" + result.Context);
ShowCodeCompletion(editor, result, false, '.'); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor));
return CodeCompletionKeyPressResult.Completed; return CodeCompletionKeyPressResult.Completed;
case ' ': case ' ':
result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset); result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset);
if (HasKeywordsOnly(result.Tag as BitArray) || result.Context == ExpressionContext.Importable) { if (HasKeywordsOnly(result.Tag as BitArray) || result.Context == ExpressionContext.Importable) {
LoggingService.Debug("CC: After space, result=" + result + ", context=" + result.Context); LoggingService.Debug("CC: After space, result=" + result + ", context=" + result.Context);
ShowCodeCompletion(editor, result, false, ' '); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor));
return CodeCompletionKeyPressResult.Completed; return CodeCompletionKeyPressResult.Completed;
} }
break; break;
@ -81,7 +90,7 @@ namespace ICSharpCode.VBNetBinding
if ((result.Context != ExpressionContext.IdentifierExpected) && if ((result.Context != ExpressionContext.IdentifierExpected) &&
(!char.IsLetterOrDigit(prevChar) && prevChar != '.')) { (!char.IsLetterOrDigit(prevChar) && prevChar != '.')) {
LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context); LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context);
ShowCodeCompletion(editor, result, afterUnderscore, ch); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor));
return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion; return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
} }
} }
@ -91,14 +100,6 @@ namespace ICSharpCode.VBNetBinding
return CodeCompletionKeyPressResult.None; return CodeCompletionKeyPressResult.None;
} }
void ShowCodeCompletion(ITextEditor editor, ExpressionResult result, bool afterUnderscore, char ch)
{
var provider = new VBNetCodeCompletionDataProvider(result, ch);
provider.ShowTemplates = true;
provider.AllowCompleteExistingExpression = afterUnderscore;
provider.ShowCompletion(editor);
}
bool HasKeywordsOnly(BitArray array) bool HasKeywordsOnly(BitArray array)
{ {
if (array == null) if (array == null)
@ -181,10 +182,7 @@ namespace ICSharpCode.VBNetBinding
ExpressionResult result = ef.FindExpression(editor.Document.Text, cursor); ExpressionResult result = ef.FindExpression(editor.Document.Text, cursor);
LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context); LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context);
if (result.Context != ExpressionContext.IdentifierExpected) { if (result.Context != ExpressionContext.IdentifierExpected) {
var provider = new VBNetCodeCompletionDataProvider(result, ' '); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor));
provider.ShowTemplates = true;
provider.AllowCompleteExistingExpression = afterUnderscore;
provider.ShowCompletion(editor);
return true; return true;
} }
} }

4
src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBindingOld.cs

@ -37,8 +37,8 @@ namespace ICSharpCode.VBNetBinding
InitializeOpenedInsightWindow(editor, insightWindow); InitializeOpenedInsightWindow(editor, insightWindow);
return CodeCompletionKeyPressResult.Completed; return CodeCompletionKeyPressResult.Completed;
} else if(ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled) { } else if(ch == ',' && CodeCompletionOptions.InsightRefreshOnComma && CodeCompletionOptions.InsightEnabled) {
if (InsightRefreshOnComma(editor, ch)) // if (InsightRefreshOnComma(editor, ch))
return CodeCompletionKeyPressResult.Completed; // return CodeCompletionKeyPressResult.Completed;
} else if (ch == '\n') { } else if (ch == '\n') {
TryDeclarationTypeInference(editor, editor.Document.GetLineForOffset(editor.Caret.Offset)); TryDeclarationTypeInference(editor, editor.Document.GetLineForOffset(editor.Caret.Offset));
} else if (char.IsLetter(ch) && CodeCompletionOptions.CompleteWhenTyping) { } else if (char.IsLetter(ch) && CodeCompletionOptions.CompleteWhenTyping) {

2
src/AddIns/BackendBindings/VBNetBinding/Project/VBNetBinding.csproj

@ -54,7 +54,7 @@
<Compile Include="Src\Extensions.cs" /> <Compile Include="Src\Extensions.cs" />
<Compile Include="Src\FormattingStrategy\VBStatement.cs" /> <Compile Include="Src\FormattingStrategy\VBStatement.cs" />
<Compile Include="Src\VBNetBracketSearcher.cs" /> <Compile Include="Src\VBNetBracketSearcher.cs" />
<Compile Include="Src\VBNetCodeCompletionDataProvider.cs" /> <Compile Include="Src\CompletionDataHelper.cs" />
<Compile Include="Src\VBNetCompletionBindingOld.cs" /> <Compile Include="Src\VBNetCompletionBindingOld.cs" />
<Compile Include="Src\VBNetLanguageBinding.cs" /> <Compile Include="Src\VBNetLanguageBinding.cs" />
<Compile Include="Src\VBNetProjectBinding.cs" /> <Compile Include="Src\VBNetProjectBinding.cs" />

9
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg

@ -269,7 +269,11 @@ ExpressionFinder =
(. PopContext(); .) (. PopContext(); .)
. .
StatementTerminator = EOL | ":" . StatementTerminator
(. if (la != null) CurrentBlock.lastExpressionStart = la.Location; .)
=
EOL | ":"
.
OptionStatement = OptionStatement =
"Option" ( ( "Explicit" | "Strict" | "Infer" ) [ "Off" | "On" ] | "Compare" ( "Text" | "Binary" ) ) StatementTerminator "Option" ( ( "Explicit" | "Strict" | "Infer" ) [ "Off" | "On" ] | "Compare" ( "Text" | "Binary" ) ) StatementTerminator
@ -289,8 +293,9 @@ ImportsStatement
( "Global" | Identifier | PrimitiveTypeName ) { TypeSuffix } [ ( "." | "=" ) TypeName ] ( "Global" | Identifier | PrimitiveTypeName ) { TypeSuffix } [ ( "." | "=" ) TypeName ]
| XmlOpenTag Identifier "=" LiteralString XmlCloseTag | XmlOpenTag Identifier "=" LiteralString XmlCloseTag
) )
StatementTerminator
(. PopContext(); .) (. PopContext(); .)
StatementTerminator
. .
AttributeBlock = AttributeBlock =

3874
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

16
src/Main/Base/Project/Src/Editor/CodeCompletion/CodeCompletionItemProvider.cs

@ -114,7 +114,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
protected virtual DefaultCompletionItemList CreateCompletionItemList() protected virtual DefaultCompletionItemList CreateCompletionItemList()
{ {
// This is overriden in DotCodeCompletionItemProvider (C# and VB dot completion) // This is overriden in DotCodeCompletionItemProvider (C# and VB dot completion)
// and NRefactoryCtrlSpaceCompletionItemProvider (C# and VB Ctrl+Space completion) // and NRefactoryCtrlSpaceCompletionItemProvider (C# and VB Ctrl+Space completion)
return new DefaultCompletionItemList(); return new DefaultCompletionItemList();
} }
@ -125,11 +125,18 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
} }
public virtual ICompletionItemList GenerateCompletionListForCompletionData(List<ICompletionEntry> arr, ExpressionContext context) public virtual ICompletionItemList GenerateCompletionListForCompletionData(List<ICompletionEntry> arr, ExpressionContext context)
{
var list = ConvertCompletionData(CreateCompletionItemList(), arr, context);
InitializeCompletionItemList(list);
return list;
}
public static DefaultCompletionItemList ConvertCompletionData(DefaultCompletionItemList result, List<ICompletionEntry> arr, ExpressionContext context)
{ {
if (arr == null) if (arr == null)
return null; return result;
DefaultCompletionItemList result = CreateCompletionItemList();
Dictionary<string, CodeCompletionItem> methodItems = new Dictionary<string, CodeCompletionItem>(); Dictionary<string, CodeCompletionItem> methodItems = new Dictionary<string, CodeCompletionItem>();
foreach (ICompletionEntry o in arr) { foreach (ICompletionEntry o in arr) {
if (context != null && !context.ShowEntry(o)) if (context != null && !context.ShowEntry(o))
@ -155,7 +162,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
result.SuggestedItem = item; result.SuggestedItem = item;
} }
} }
InitializeCompletionItemList(result);
if (context.SuggestedItem != null) { if (context.SuggestedItem != null) {
if (result.SuggestedItem == null) { if (result.SuggestedItem == null) {
@ -168,7 +174,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
return result; return result;
} }
public virtual ICompletionItem CreateCompletionItem(object o, ExpressionContext context) public static ICompletionItem CreateCompletionItem(object o, ExpressionContext context)
{ {
IEntity entity = o as IEntity; IEntity entity = o as IEntity;
if (entity != null) { if (entity != null) {

6
src/Main/Base/Test/VBExpressionFinderTests.cs

@ -109,6 +109,12 @@ End Class
{ {
Find(program1, "loopVarName", 4, "loop", ExpressionContext.Default); Find(program1, "loopVarName", 4, "loop", ExpressionContext.Default);
} }
[Test]
public void FindEmptyAfterImports()
{
Find(program1, " ", 1, "", ExpressionContext.Global);
}
#endregion #endregion
#region FindFull #region FindFull

Loading…
Cancel
Save