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 @@ @@ -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 @@ @@ -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 @@ -51,18 +51,27 @@ namespace ICSharpCode.VBNetBinding
ExpressionResult result;
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':
break;
case '.':
result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset);
LoggingService.Debug("CC: After dot, result=" + result + ", context=" + result.Context);
ShowCodeCompletion(editor, result, false, '.');
editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor));
return CodeCompletionKeyPressResult.Completed;
case ' ':
result = ef.FindExpression(editor.Document.Text, editor.Caret.Offset);
if (HasKeywordsOnly(result.Tag as BitArray) || result.Context == ExpressionContext.Importable) {
LoggingService.Debug("CC: After space, result=" + result + ", context=" + result.Context);
ShowCodeCompletion(editor, result, false, ' ');
editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor));
return CodeCompletionKeyPressResult.Completed;
}
break;
@ -81,7 +90,7 @@ namespace ICSharpCode.VBNetBinding @@ -81,7 +90,7 @@ namespace ICSharpCode.VBNetBinding
if ((result.Context != ExpressionContext.IdentifierExpected) &&
(!char.IsLetterOrDigit(prevChar) && prevChar != '.')) {
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;
}
}
@ -91,14 +100,6 @@ namespace ICSharpCode.VBNetBinding @@ -91,14 +100,6 @@ namespace ICSharpCode.VBNetBinding
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)
{
if (array == null)
@ -181,10 +182,7 @@ namespace ICSharpCode.VBNetBinding @@ -181,10 +182,7 @@ namespace ICSharpCode.VBNetBinding
ExpressionResult result = ef.FindExpression(editor.Document.Text, cursor);
LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context);
if (result.Context != ExpressionContext.IdentifierExpected) {
var provider = new VBNetCodeCompletionDataProvider(result, ' ');
provider.ShowTemplates = true;
provider.AllowCompleteExistingExpression = afterUnderscore;
provider.ShowCompletion(editor);
editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor));
return true;
}
}

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

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

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

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

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

@ -269,7 +269,11 @@ ExpressionFinder = @@ -269,7 +269,11 @@ ExpressionFinder =
(. PopContext(); .)
.
StatementTerminator = EOL | ":" .
StatementTerminator
(. if (la != null) CurrentBlock.lastExpressionStart = la.Location; .)
=
EOL | ":"
.
OptionStatement =
"Option" ( ( "Explicit" | "Strict" | "Infer" ) [ "Off" | "On" ] | "Compare" ( "Text" | "Binary" ) ) StatementTerminator
@ -289,8 +293,9 @@ ImportsStatement @@ -289,8 +293,9 @@ ImportsStatement
( "Global" | Identifier | PrimitiveTypeName ) { TypeSuffix } [ ( "." | "=" ) TypeName ]
| XmlOpenTag Identifier "=" LiteralString XmlCloseTag
)
StatementTerminator
(. PopContext(); .)
StatementTerminator
.
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 @@ -114,7 +114,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
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)
return new DefaultCompletionItemList();
}
@ -125,11 +125,18 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -125,11 +125,18 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
}
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)
return null;
return result;
DefaultCompletionItemList result = CreateCompletionItemList();
Dictionary<string, CodeCompletionItem> methodItems = new Dictionary<string, CodeCompletionItem>();
foreach (ICompletionEntry o in arr) {
if (context != null && !context.ShowEntry(o))
@ -155,7 +162,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -155,7 +162,6 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
result.SuggestedItem = item;
}
}
InitializeCompletionItemList(result);
if (context.SuggestedItem != null) {
if (result.SuggestedItem == null) {
@ -168,7 +174,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -168,7 +174,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
return result;
}
public virtual ICompletionItem CreateCompletionItem(object o, ExpressionContext context)
public static ICompletionItem CreateCompletionItem(object o, ExpressionContext context)
{
IEntity entity = o as IEntity;
if (entity != null) {

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

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

Loading…
Cancel
Save