Browse Source

implemented CC after Imports

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6099 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
8695eb0004
  1. 35
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCodeCompletionDataProvider.cs
  2. 20
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs
  3. 7
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBindingOld.cs
  4. 3
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Block.cs
  5. 13
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg
  6. 170
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs
  7. 46
      src/Libraries/NRefactory/Test/Lexer/VBNet/LexerContextTests.cs
  8. 4
      src/Main/Base/Test/VBExpressionFinderTests.cs
  9. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
  10. 9
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  11. 490
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/ExpressionFinder.cs
  12. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

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

@ -8,8 +8,10 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.Parser.VB; using ICSharpCode.NRefactory.Parser.VB;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver; using ICSharpCode.SharpDevelop.Dom.NRefactoryResolver;
using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor;
@ -20,11 +22,13 @@ namespace ICSharpCode.VBNetBinding
public class VBNetCodeCompletionDataProvider : NRefactoryCtrlSpaceCompletionItemProvider public class VBNetCodeCompletionDataProvider : NRefactoryCtrlSpaceCompletionItemProvider
{ {
ExpressionResult result; ExpressionResult result;
char pressed = '\0';
public VBNetCodeCompletionDataProvider(ExpressionResult result) public VBNetCodeCompletionDataProvider(ExpressionResult result, char ch)
: base(LanguageProperties.VBNet, result.Context) : base(LanguageProperties.VBNet, result.Context)
{ {
this.result = result; this.result = result;
pressed = ch;
} }
protected override List<ICompletionEntry> CtrlSpace(ITextEditor editor, ExpressionContext context) protected override List<ICompletionEntry> CtrlSpace(ITextEditor editor, ExpressionContext context)
@ -41,13 +45,40 @@ namespace ICSharpCode.VBNetBinding
} }
if (ExpressionContext.MethodBody == context) {
}
return list; 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) static void AddVBNetKeywords(List<ICompletionEntry> ar, BitArray keywords)
{ {
for (int i = 0; i < keywords.Length; i++) { for (int i = 0; i < keywords.Length; i++) {
if (keywords[i] && i >= Tokens.AddHandler) { if (keywords[i] && i >= Tokens.AddHandler && i < Tokens.MaxToken) {
ar.Add(new KeywordEntry(Tokens.GetTokenString(i))); ar.Add(new KeywordEntry(Tokens.GetTokenString(i)));
} }
} }

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

@ -53,10 +53,16 @@ namespace ICSharpCode.VBNetBinding
switch (ch) { switch (ch) {
case '\n': case '\n':
break; 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, '.');
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)) { if (HasKeywordsOnly(result.Tag as BitArray) || result.Context == ExpressionContext.Importable) {
ShowCodeCompletion(editor, result, false); LoggingService.Debug("CC: After space, result=" + result + ", context=" + result.Context);
ShowCodeCompletion(editor, result, false, ' ');
return CodeCompletionKeyPressResult.Completed; return CodeCompletionKeyPressResult.Completed;
} }
break; break;
@ -74,7 +80,8 @@ namespace ICSharpCode.VBNetBinding
if ((result.Context != ExpressionContext.IdentifierExpected) && if ((result.Context != ExpressionContext.IdentifierExpected) &&
(!char.IsLetterOrDigit(prevChar) && prevChar != '.')) { (!char.IsLetterOrDigit(prevChar) && prevChar != '.')) {
ShowCodeCompletion(editor, result, afterUnderscore); LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context);
ShowCodeCompletion(editor, result, afterUnderscore, ch);
return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion; return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
} }
} }
@ -84,10 +91,9 @@ namespace ICSharpCode.VBNetBinding
return CodeCompletionKeyPressResult.None; return CodeCompletionKeyPressResult.None;
} }
void ShowCodeCompletion(ITextEditor editor, ExpressionResult result, bool afterUnderscore) void ShowCodeCompletion(ITextEditor editor, ExpressionResult result, bool afterUnderscore, char ch)
{ {
LoggingService.Debug("CC: Beginning to type a word, result=" + result + ", context=" + result.Context); var provider = new VBNetCodeCompletionDataProvider(result, ch);
var provider = new VBNetCodeCompletionDataProvider(result);
provider.ShowTemplates = true; provider.ShowTemplates = true;
provider.AllowCompleteExistingExpression = afterUnderscore; provider.AllowCompleteExistingExpression = afterUnderscore;
provider.ShowCompletion(editor); provider.ShowCompletion(editor);
@ -175,7 +181,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); var provider = new VBNetCodeCompletionDataProvider(result, ' ');
provider.ShowTemplates = true; provider.ShowTemplates = true;
provider.AllowCompleteExistingExpression = afterUnderscore; provider.AllowCompleteExistingExpression = afterUnderscore;
provider.ShowCompletion(editor); provider.ShowCompletion(editor);

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

@ -78,9 +78,10 @@ namespace ICSharpCode.VBNetBinding
bool IsInComment(ITextEditor editor) bool IsInComment(ITextEditor editor)
{ {
VBExpressionFinder ef = new VBExpressionFinder(); // VBExpressionFinder ef = new VBExpressionFinder();
int cursor = editor.Caret.Offset - 1; // int cursor = editor.Caret.Offset - 1;
return ef.FilterComments(editor.Document.GetText(0, cursor + 1), ref cursor) == null; // return ef.FilterComments(editor.Document.GetText(0, cursor + 1), ref cursor) == null;
return false;
} }
sealed class GlobalCompletionItemProvider : CodeCompletionItemProvider sealed class GlobalCompletionItemProvider : CodeCompletionItemProvider

3
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Block.cs

@ -15,12 +15,13 @@ namespace ICSharpCode.NRefactory.Parser.VB
public enum Context public enum Context
{ {
Global, Global,
Type, TypeDeclaration,
Member, Member,
IdentifierExpected, IdentifierExpected,
Body, Body,
Xml, Xml,
Attribute, Attribute,
Importable,
Query, Query,
Expression, Expression,
Debug, Debug,

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

@ -275,15 +275,22 @@ OptionStatement =
"Option" ( ( "Explicit" | "Strict" | "Infer" ) [ "Off" | "On" ] | "Compare" ( "Text" | "Binary" ) ) StatementTerminator "Option" ( ( "Explicit" | "Strict" | "Infer" ) [ "Off" | "On" ] | "Compare" ( "Text" | "Binary" ) ) StatementTerminator
. .
ImportsStatement = ImportsStatement
(. PushContext(Context.Importable, la, t); .)
=
"Imports" "Imports"
(. (.
nextTokenIsStartOfImportsOrAccessExpression = true; nextTokenIsStartOfImportsOrAccessExpression = true;
if (la != null) if (la != null)
CurrentBlock.lastExpressionStart = la.Location; CurrentBlock.lastExpressionStart = la.Location;
.) .)
{ ANY } (
( "Global" | Identifier | PrimitiveTypeName ) { TypeSuffix } [ ( "." | "=" ) TypeName ]
| XmlOpenTag Identifier "=" LiteralString XmlCloseTag
)
StatementTerminator StatementTerminator
(. PopContext(); .)
. .
AttributeBlock = AttributeBlock =
@ -313,7 +320,7 @@ ClassOrModuleOrStructureTypeDeclaration =
[ "(" "Of" [ "Out" | "In" ] IdentifierExceptOut [ "As" GenericConstraintList ] { "," [ "Out" | "In" ] IdentifierExceptOut [ "As" GenericConstraintList ] } ")" ] { ANY } [ StatementTerminator ] [ "(" "Of" [ "Out" | "In" ] IdentifierExceptOut [ "As" GenericConstraintList ] { "," [ "Out" | "In" ] IdentifierExceptOut [ "As" GenericConstraintList ] } ")" ] { ANY } [ StatementTerminator ]
[ "Inherits" { ANY } StatementTerminator ] [ "Inherits" { ANY } StatementTerminator ]
[ "Implements" { ANY } StatementTerminator ] [ "Implements" { ANY } StatementTerminator ]
(. PushContext(Context.Type, la, t); .) (. PushContext(Context.TypeDeclaration, la, t); .)
{ MemberDeclaration } { MemberDeclaration }
"End" ( "Module" | "Class" | "Structure" ) StatementTerminator "End" ( "Module" | "Class" | "Structure" ) StatementTerminator
(. PopContext(); .) (. PopContext(); .)

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

@ -23,6 +23,7 @@ partial class ExpressionFinder {
case 1: case 1:
return set[0]; return set[0];
case 2: case 2:
case 483:
return set[1]; return set[1];
case 3: case 3:
case 4: case 4:
@ -74,8 +75,6 @@ partial class ExpressionFinder {
case 463: case 463:
case 475: case 475:
case 476: case 476:
case 480:
case 481:
return set[6]; return set[6];
case 12: case 12:
case 13: case 13:
@ -114,6 +113,7 @@ partial class ExpressionFinder {
case 418: case 418:
case 421: case 421:
case 447: case 447:
case 482:
{ {
BitArray a = new BitArray(239); BitArray a = new BitArray(239);
a.Set(1, true); a.Set(1, true);
@ -143,6 +143,7 @@ partial class ExpressionFinder {
case 431: case 431:
case 451: case 451:
case 460: case 460:
case 489:
return set[8]; return set[8];
case 19: case 19:
case 22: case 22:
@ -321,6 +322,7 @@ partial class ExpressionFinder {
case 159: case 159:
case 161: case 161:
case 256: case 256:
case 485:
{ {
BitArray a = new BitArray(239); BitArray a = new BitArray(239);
a.Set(20, true); a.Set(20, true);
@ -655,6 +657,7 @@ partial class ExpressionFinder {
case 366: case 366:
case 423: case 423:
case 435: case 435:
case 484:
return set[28]; return set[28];
case 136: case 136:
{ {
@ -1101,6 +1104,7 @@ partial class ExpressionFinder {
} }
case 438: case 438:
case 440: case 440:
case 486:
{ {
BitArray a = new BitArray(239); BitArray a = new BitArray(239);
a.Set(3, true); a.Set(3, true);
@ -1163,23 +1167,34 @@ partial class ExpressionFinder {
a.Set(137, true); a.Set(137, true);
return a; return a;
} }
case 482: case 480:
case 481:
return set[95];
case 487:
{
BitArray a = new BitArray(239);
a.Set(11, true);
return a;
}
case 488:
return set[96];
case 490:
{ {
BitArray a = new BitArray(239); BitArray a = new BitArray(239);
a.Set(173, true); a.Set(173, true);
return a; return a;
} }
case 483: case 491:
return set[95]; return set[97];
case 484: case 492:
{ {
BitArray a = new BitArray(239); BitArray a = new BitArray(239);
a.Set(67, true); a.Set(67, true);
a.Set(213, true); a.Set(213, true);
return a; return a;
} }
case 485: case 493:
return set[96]; return set[98];
default: throw new InvalidOperationException(); default: throw new InvalidOperationException();
} }
} }
@ -1234,7 +1249,7 @@ partial class ExpressionFinder {
if (la == null) { currentState = 1; break; } if (la == null) { currentState = 1; break; }
if (la.kind == 173) { if (la.kind == 173) {
stateStack.Push(1); stateStack.Push(1);
goto case 482; goto case 490;
} else { } else {
goto case 2; goto case 2;
} }
@ -1243,6 +1258,7 @@ partial class ExpressionFinder {
if (la == null) { currentState = 2; break; } if (la == null) { currentState = 2; break; }
if (la.kind == 137) { if (la.kind == 137) {
stateStack.Push(2); stateStack.Push(2);
PushContext(Context.Importable, la, t);
goto case 479; goto case 479;
} else { } else {
goto case 3; goto case 3;
@ -1297,7 +1313,7 @@ partial class ExpressionFinder {
} }
case 8: { case 8: {
if (la == null) { currentState = 8; break; } if (la == null) { currentState = 8; break; }
if (set[97].Get(la.kind)) { if (set[99].Get(la.kind)) {
currentState = 8; currentState = 8;
break; break;
} else { } else {
@ -1392,7 +1408,7 @@ partial class ExpressionFinder {
currentState = 19; currentState = 19;
break; break;
} else { } else {
if (set[98].Get(la.kind)) { if (set[100].Get(la.kind)) {
currentState = 19; currentState = 19;
break; break;
} else { } else {
@ -1527,7 +1543,7 @@ partial class ExpressionFinder {
} }
case 36: { case 36: {
if (la == null) { currentState = 36; break; } if (la == null) { currentState = 36; break; }
if (set[99].Get(la.kind)) { if (set[101].Get(la.kind)) {
currentState = 35; currentState = 35;
break; break;
} else { } else {
@ -1546,7 +1562,7 @@ partial class ExpressionFinder {
} }
case 39: { case 39: {
if (la == null) { currentState = 39; break; } if (la == null) { currentState = 39; break; }
if (set[100].Get(la.kind)) { if (set[102].Get(la.kind)) {
currentState = 38; currentState = 38;
break; break;
} else { } else {
@ -2832,7 +2848,7 @@ partial class ExpressionFinder {
currentState = 112; currentState = 112;
break; break;
} else { } else {
if (set[101].Get(la.kind)) { if (set[103].Get(la.kind)) {
currentState = 108; currentState = 108;
break; break;
} else { } else {
@ -2904,7 +2920,7 @@ partial class ExpressionFinder {
} }
case 117: { case 117: {
if (la == null) { currentState = 117; break; } if (la == null) { currentState = 117; break; }
if (set[102].Get(la.kind)) { if (set[104].Get(la.kind)) {
currentState = 118; currentState = 118;
break; break;
} else { } else {
@ -2912,11 +2928,11 @@ partial class ExpressionFinder {
currentState = 374; currentState = 374;
break; break;
} else { } else {
if (set[103].Get(la.kind)) { if (set[105].Get(la.kind)) {
currentState = 118; currentState = 118;
break; break;
} else { } else {
if (set[101].Get(la.kind)) { if (set[103].Get(la.kind)) {
currentState = 370; currentState = 370;
break; break;
} else { } else {
@ -3011,7 +3027,7 @@ partial class ExpressionFinder {
} }
case 126: { case 126: {
if (la == null) { currentState = 126; break; } if (la == null) { currentState = 126; break; }
if (set[104].Get(la.kind)) { if (set[106].Get(la.kind)) {
currentState = 131; currentState = 131;
break; break;
} else { } else {
@ -3610,7 +3626,7 @@ partial class ExpressionFinder {
} }
case 202: { case 202: {
if (la == null) { currentState = 202; break; } if (la == null) { currentState = 202; break; }
if (set[105].Get(la.kind)) { if (set[107].Get(la.kind)) {
if (set[57].Get(la.kind)) { if (set[57].Get(la.kind)) {
if (set[39].Get(la.kind)) { if (set[39].Get(la.kind)) {
stateStack.Push(200); stateStack.Push(200);
@ -3728,7 +3744,7 @@ partial class ExpressionFinder {
currentState = 224; currentState = 224;
break; break;
} else { } else {
if (set[106].Get(la.kind)) { if (set[108].Get(la.kind)) {
if (la.kind == 132) { if (la.kind == 132) {
currentState = 221; currentState = 221;
break; break;
@ -3767,7 +3783,7 @@ partial class ExpressionFinder {
currentState = 209; currentState = 209;
break; break;
} else { } else {
if (set[107].Get(la.kind)) { if (set[109].Get(la.kind)) {
if (la.kind == 73) { if (la.kind == 73) {
currentState = 34; currentState = 34;
break; break;
@ -4348,7 +4364,7 @@ partial class ExpressionFinder {
} }
case 286: { case 286: {
if (la == null) { currentState = 286; break; } if (la == null) { currentState = 286; break; }
if (set[108].Get(la.kind)) { if (set[110].Get(la.kind)) {
if (la.kind == 144) { if (la.kind == 144) {
currentState = 288; currentState = 288;
break; break;
@ -4753,7 +4769,7 @@ partial class ExpressionFinder {
} }
case 337: { case 337: {
if (la == null) { currentState = 337; break; } if (la == null) { currentState = 337; break; }
if (set[109].Get(la.kind)) { if (set[111].Get(la.kind)) {
currentState = 337; currentState = 337;
break; break;
} else { } else {
@ -4800,7 +4816,7 @@ partial class ExpressionFinder {
} }
case 344: { case 344: {
if (la == null) { currentState = 344; break; } if (la == null) { currentState = 344; break; }
if (set[110].Get(la.kind)) { if (set[112].Get(la.kind)) {
currentState = 344; currentState = 344;
break; break;
} else { } else {
@ -4910,8 +4926,8 @@ partial class ExpressionFinder {
} }
case 358: { case 358: {
if (la == null) { currentState = 358; break; } if (la == null) { currentState = 358; break; }
if (set[111].Get(la.kind)) { if (set[113].Get(la.kind)) {
if (set[112].Get(la.kind)) { if (set[114].Get(la.kind)) {
currentState = 358; currentState = 358;
break; break;
} else { } else {
@ -4939,8 +4955,8 @@ partial class ExpressionFinder {
} }
case 359: { case 359: {
if (la == null) { currentState = 359; break; } if (la == null) { currentState = 359; break; }
if (set[113].Get(la.kind)) { if (set[115].Get(la.kind)) {
if (set[114].Get(la.kind)) { if (set[116].Get(la.kind)) {
currentState = 359; currentState = 359;
break; break;
} else { } else {
@ -4965,8 +4981,8 @@ partial class ExpressionFinder {
} }
case 360: { case 360: {
if (la == null) { currentState = 360; break; } if (la == null) { currentState = 360; break; }
if (set[115].Get(la.kind)) { if (set[117].Get(la.kind)) {
if (set[116].Get(la.kind)) { if (set[118].Get(la.kind)) {
currentState = 360; currentState = 360;
break; break;
} else { } else {
@ -5149,7 +5165,7 @@ partial class ExpressionFinder {
} }
case 387: { case 387: {
if (la == null) { currentState = 387; break; } if (la == null) { currentState = 387; break; }
if (set[117].Get(la.kind)) { if (set[119].Get(la.kind)) {
currentState = 387; currentState = 387;
break; break;
} else { } else {
@ -5180,7 +5196,7 @@ partial class ExpressionFinder {
} }
} }
case 390: { case 390: {
PushContext(Context.Type, la, t); PushContext(Context.TypeDeclaration, la, t);
goto case 391; goto case 391;
} }
case 391: { case 391: {
@ -5235,7 +5251,7 @@ partial class ExpressionFinder {
} }
case 396: { case 396: {
if (la == null) { currentState = 396; break; } if (la == null) { currentState = 396; break; }
if (set[118].Get(la.kind)) { if (set[120].Get(la.kind)) {
currentState = 396; currentState = 396;
break; break;
} else { } else {
@ -5470,7 +5486,7 @@ partial class ExpressionFinder {
currentState = 431; currentState = 431;
break; break;
} else { } else {
if (set[119].Get(la.kind)) { if (set[121].Get(la.kind)) {
if (la.kind == 37) { if (la.kind == 37) {
currentState = 429; currentState = 429;
break; break;
@ -5729,7 +5745,7 @@ partial class ExpressionFinder {
} }
case 461: { case 461: {
if (la == null) { currentState = 461; break; } if (la == null) { currentState = 461; break; }
if (set[103].Get(la.kind)) { if (set[105].Get(la.kind)) {
currentState = stateStack.Pop(); currentState = stateStack.Pop();
break; break;
} else { } else {
@ -6002,6 +6018,7 @@ partial class ExpressionFinder {
} }
case 480: { case 480: {
nextTokenIsStartOfImportsOrAccessExpression = true; nextTokenIsStartOfImportsOrAccessExpression = true;
if (la != null) if (la != null)
CurrentBlock.lastExpressionStart = la.Location; CurrentBlock.lastExpressionStart = la.Location;
@ -6009,35 +6026,90 @@ partial class ExpressionFinder {
} }
case 481: { case 481: {
if (la == null) { currentState = 481; break; } if (la == null) { currentState = 481; break; }
if (set[38].Get(la.kind)) { if (set[8].Get(la.kind)) {
currentState = 481; currentState = 488;
break; break;
} else { } else {
goto case 15; if (la.kind == 10) {
currentState = 484;
break;
} else {
Error(la);
goto case 482;
}
} }
} }
case 482: { case 482: {
if (la == null) { currentState = 482; break; } stateStack.Push(483);
goto case 15;
}
case 483: {
PopContext();
currentState = stateStack.Pop();
goto switchlbl;
}
case 484: {
stateStack.Push(485);
goto case 146;
}
case 485: {
if (la == null) { currentState = 485; break; }
Expect(20, la); // "="
currentState = 486;
break;
}
case 486: {
if (la == null) { currentState = 486; break; }
Expect(3, la); // LiteralString
currentState = 487;
break;
}
case 487: {
if (la == null) { currentState = 487; break; }
Expect(11, la); // XmlCloseTag
currentState = 482;
break;
}
case 488: {
if (la == null) { currentState = 488; break; }
if (la.kind == 37) {
stateStack.Push(488);
goto case 23;
} else {
if (la.kind == 20 || la.kind == 26) {
currentState = 489;
break;
} else {
goto case 482;
}
}
}
case 489: {
stateStack.Push(482);
goto case 18;
}
case 490: {
if (la == null) { currentState = 490; break; }
Expect(173, la); // "Option" Expect(173, la); // "Option"
currentState = 483; currentState = 491;
break; break;
} }
case 483: { case 491: {
if (la == null) { currentState = 483; break; } if (la == null) { currentState = 491; break; }
if (la.kind == 121 || la.kind == 139 || la.kind == 207) { if (la.kind == 121 || la.kind == 139 || la.kind == 207) {
currentState = 485; currentState = 493;
break; break;
} else { } else {
if (la.kind == 87) { if (la.kind == 87) {
currentState = 484; currentState = 492;
break; break;
} else { } else {
goto case 450; goto case 450;
} }
} }
} }
case 484: { case 492: {
if (la == null) { currentState = 484; break; } if (la == null) { currentState = 492; break; }
if (la.kind == 213) { if (la.kind == 213) {
currentState = 15; currentState = 15;
break; break;
@ -6050,8 +6122,8 @@ partial class ExpressionFinder {
} }
} }
} }
case 485: { case 493: {
if (la == null) { currentState = 485; break; } if (la == null) { currentState = 493; break; }
if (la.kind == 170 || la.kind == 171) { if (la.kind == 170 || la.kind == 171) {
currentState = 15; currentState = 15;
break; break;
@ -6168,6 +6240,8 @@ partial class ExpressionFinder {
new BitArray(new int[] {4, 1140850696, 9699551, 1108355356, 9218084, 17106180, -533524976, 67}), new BitArray(new int[] {4, 1140850696, 9699551, 1108355356, 9218084, 17106180, -533524976, 67}),
new BitArray(new int[] {4, 1140850688, 9699551, 1108355356, 9218084, 17106180, -533524976, 67}), new BitArray(new int[] {4, 1140850688, 9699551, 1108355356, 9218084, 17106180, -533524976, 67}),
new BitArray(new int[] {0, 256, 1048576, 537002112, 134217728, 436207617, 131200, 0}), new BitArray(new int[] {0, 256, 1048576, 537002112, 134217728, 436207617, 131200, 0}),
new BitArray(new int[] {1028, 1140850688, 8650975, 1108355356, 9218084, 17106176, -533656048, 67}),
new BitArray(new int[] {70254594, 32, 0, 0, 0, 0, 0, 0}),
new BitArray(new int[] {0, 0, 8388608, 33554432, 2048, 0, 32768, 0}), new BitArray(new int[] {0, 0, 8388608, 33554432, 2048, 0, 32768, 0}),
new BitArray(new int[] {2097154, 0, 0, 0, 0, 3072, 0, 0}), new BitArray(new int[] {2097154, 0, 0, 0, 0, 3072, 0, 0}),
new BitArray(new int[] {0, 0, 0, 536870912, 0, 436207616, 128, 0}), new BitArray(new int[] {0, 0, 0, 536870912, 0, 436207616, 128, 0}),

46
src/Libraries/NRefactory/Test/Lexer/VBNet/LexerContextTests.cs

@ -41,7 +41,7 @@ End Class
@"enter Global @"enter Global
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -58,7 +58,7 @@ End Class
exit Expression exit Expression
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
" "
); );
@ -79,7 +79,7 @@ End Class
@"enter Global @"enter Global
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -108,7 +108,7 @@ End Class
exit Expression exit Expression
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
" "
); );
@ -130,7 +130,7 @@ End Class
exit Attribute exit Attribute
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -145,7 +145,7 @@ End Class
exit Expression exit Expression
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
" "
); );
@ -167,7 +167,7 @@ End Class
exit Attribute exit Attribute
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -182,7 +182,7 @@ End Class
exit Expression exit Expression
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
" "
); );
@ -202,7 +202,7 @@ End Class
@"enter Global @"enter Global
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter Attribute enter Attribute
exit Attribute exit Attribute
@ -219,7 +219,7 @@ End Class
exit Expression exit Expression
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
" "
); );
@ -240,7 +240,7 @@ End Class
@"enter Global @"enter Global
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -255,7 +255,7 @@ End Class
exit Body exit Body
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
" "
); );
@ -286,7 +286,7 @@ End Class
@"enter Global @"enter Global
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -327,7 +327,7 @@ End Class
exit Body exit Body
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
" "
); );
@ -348,7 +348,7 @@ End Class",
@"enter Global @"enter Global
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -381,7 +381,7 @@ End Class",
exit Body exit Body
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
"); ");
} }
@ -416,9 +416,13 @@ Module Program
End Sub End Sub
End Module", End Module",
@"enter Global @"enter Global
enter Importable
exit Importable
enter Importable
exit Importable
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type enter TypeDeclaration
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
@ -507,7 +511,7 @@ End Module",
exit Expression exit Expression
exit Body exit Body
exit Member exit Member
exit Type exit TypeDeclaration
exit Global exit Global
"); ");
} }
@ -519,6 +523,12 @@ exit Global
Imports System.Linq Imports System.Linq
Imports System.Collections.Generic", Imports System.Collections.Generic",
@"enter Global @"enter Global
enter Importable
exit Importable
enter Importable
exit Importable
enter Importable
exit Importable
exit Global exit Global
"); ");
} }

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

@ -145,13 +145,13 @@ End Class
[Test] [Test]
public void Imports1() public void Imports1()
{ {
FindFull(program1, "ystem", "System", ExpressionContext.Global); FindFull(program1, "ystem", "System", ExpressionContext.Importable);
} }
[Test] [Test]
public void Imports2() public void Imports2()
{ {
FindFull(program1, "inq", "System.Linq", ExpressionContext.Global); FindFull(program1, "inq", "System.Linq", ExpressionContext.Importable);
} }
[Test] [Test]

1
src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj

@ -190,7 +190,6 @@
<Compile Include="Src\Ambience.cs" /> <Compile Include="Src\Ambience.cs" />
<Compile Include="Src\CSharp\ExpressionFinder.cs" /> <Compile Include="Src\CSharp\ExpressionFinder.cs" />
<Compile Include="Src\VBNet\VBNetAmbience.cs" /> <Compile Include="Src\VBNet\VBNetAmbience.cs" />
<Compile Include="Src\VBNet\ExpressionFinder.cs" />
<Compile Include="Src\EasyCodeDom.cs" /> <Compile Include="Src\EasyCodeDom.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

9
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -1139,15 +1139,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
List<ICompletionEntry> result = new List<ICompletionEntry>(); List<ICompletionEntry> result = new List<ICompletionEntry>();
if (language == NR.SupportedLanguage.VBNet) { if (language == NR.SupportedLanguage.VBNet) {
// if (context == ExpressionContext.TypeDeclaration) {
// } else if (context == ExpressionContext.Global) {
// } else if (context == ExpressionContext.MethodBody) {
// CtrlSpaceInternal(result, fileContent, showEntriesFromAllNamespaces);
// } else {
// AddVBNetPrimitiveTypes(result);
// CtrlSpaceInternal(result, fileContent, showEntriesFromAllNamespaces);
// }
} else { } else {
if (context == ExpressionContext.TypeDeclaration) { if (context == ExpressionContext.TypeDeclaration) {
AddCSharpKeywords(result, NR.Parser.CSharp.Tokens.TypeLevel); AddCSharpKeywords(result, NR.Parser.CSharp.Tokens.TypeLevel);

490
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/ExpressionFinder.cs

@ -1,490 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Markus Palme" email="MarkusPalme@gmx.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Text;
namespace ICSharpCode.SharpDevelop.Dom.VBNet
{
public class VBExpressionFinder : IExpressionFinder
{
ExpressionResult CreateResult(string expression)
{
if (expression == null)
return ExpressionResult.Empty;
if (expression.Length > 8 && expression.Substring(0, 8).Equals("Imports ", StringComparison.InvariantCultureIgnoreCase))
return new ExpressionResult(expression.Substring(8).TrimStart(), ExpressionContext.Type);
if (expression.Length > 4 && expression.Substring(0, 4).Equals("New ", StringComparison.InvariantCultureIgnoreCase))
return new ExpressionResult(expression.Substring(4).TrimStart(), ExpressionContext.ObjectCreation);
if (curTokenType == Ident && lastIdentifier.Equals("as", StringComparison.InvariantCultureIgnoreCase))
return new ExpressionResult(expression, ExpressionContext.Type);
return new ExpressionResult(expression);
}
public ExpressionResult FindExpression(string inText, int offset)
{
return CreateResult(FindExpressionInternal(inText, offset));
}
public string FindExpressionInternal(string inText, int offset)
{
offset--; // earlier all ExpressionFinder calls had an inexplicable "cursor - 1".
// The IExpressionFinder API now uses normal cursor offsets, so we need to adjust the offset
// because VBExpressionFinder still uses an implementation that expects old offsets
this.text = FilterComments(inText, ref offset);
this.offset = this.lastAccept = offset;
this.state = START;
if (this.text == null)
{
return null;
}
//Console.WriteLine("---------------");
while (state != ERROR)
{
ReadNextToken();
//Console.WriteLine("cur state {0} got token {1}/{3} going to {2}", GetStateName(state), GetTokenName(curTokenType), GetStateName(stateTable[state, curTokenType]), curTokenType);
state = stateTable[state, curTokenType];
if (state == ACCEPT || state == ACCEPT2 || state == DOT)
{
lastAccept = this.offset;
}
if (state == ACCEPTNOMORE)
{
return this.text.Substring(this.offset + 1, offset - this.offset);
}
}
return this.text.Substring(this.lastAccept + 1, offset - this.lastAccept);
}
internal int LastExpressionStartPosition {
get {
return ((state == ACCEPTNOMORE) ? offset : lastAccept) + 1;
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId = "0#")]
public ExpressionResult FindFullExpression(string inText, int offset)
{
if (inText == null)
throw new ArgumentNullException("inText");
string expressionBeforeOffset = FindExpressionInternal(inText, offset + 1);
if (expressionBeforeOffset == null || expressionBeforeOffset.Length == 0)
return CreateResult(null);
StringBuilder b = new StringBuilder(expressionBeforeOffset);
// append characters after expression
for (int i = offset + 1; i < inText.Length; ++i) {
char c = inText[i];
if (Char.IsLetterOrDigit(c) || c == '_') {
if (Char.IsWhiteSpace(inText, i - 1))
break;
b.Append(c);
} else if (c == ' ') {
b.Append(c);
} else if (c == '(') {
int otherBracket = SearchBracketForward(inText, i + 1, '(', ')');
if (otherBracket < 0)
break;
b.Append(inText, i, otherBracket - i + 1);
break;
} else {
break;
}
}
// remove space from end:
if (b.Length > 0 && b[b.Length - 1] == ' ') {
b.Length -= 1;
}
return CreateResult(b.ToString());
}
// Like VBNetFormattingStrategy.SearchBracketForward, but operates on a string.
static int SearchBracketForward(string text, int offset, char openBracket, char closingBracket)
{
bool inString = false;
bool inComment = false;
int brackets = 1;
for (int i = offset; i < text.Length; ++i) {
char ch = text[i];
if (ch == '\n') {
inString = false;
inComment = false;
}
if (inComment) continue;
if (ch == '"') inString = !inString;
if (inString) continue;
if (ch == '\'') {
inComment = true;
} else if (ch == openBracket) {
++brackets;
} else if (ch == closingBracket) {
--brackets;
if (brackets == 0) return i;
}
}
return -1;
}
/// <summary>
/// Removed the last part of the expression.
/// </summary>
/// <example>
/// "obj.Field" => "obj"
/// "obj.Method(args,...)" => "obj.Method"
/// </example>
public string RemoveLastPart(string expression)
{
if (expression == null)
throw new ArgumentNullException("expression");
text = expression;
offset = text.Length - 1;
ReadNextToken();
if (curTokenType == Ident && Peek() == '.')
GetNext();
return text.Substring(0, offset + 1);
}
#region Comment Filter and 'inside string watcher'
int initialOffset;
public string FilterComments(string text, ref int offset)
{
if (text == null)
throw new ArgumentNullException("text");
if (text.Length <= offset)
return null;
this.initialOffset = offset;
StringBuilder outText = new StringBuilder();
int curOffset = 0;
while (curOffset <= initialOffset)
{
char ch = text[curOffset];
switch (ch)
{
case '@':
if (curOffset + 1 < text.Length && text[curOffset + 1] == '"')
{
outText.Append(text[curOffset++]); // @
outText.Append(text[curOffset++]); // "
if (!ReadVerbatimString(outText, text, ref curOffset))
{
return null;
}
}
else
{
outText.Append(ch);
++curOffset;
}
break;
case '"':
outText.Append(ch);
curOffset++;
if (!ReadString(outText, text, ref curOffset))
{
return null;
}
break;
case '\'':
offset -= 1;
curOffset += 1;
if (!ReadToEOL(text, ref curOffset, ref offset))
{
return null;
}
break;
default:
outText.Append(ch);
++curOffset;
break;
}
}
return outText.ToString();
}
bool ReadToEOL(string text, ref int curOffset, ref int offset)
{
while (curOffset <= initialOffset)
{
char ch = text[curOffset++];
--offset;
if (ch == '\n')
{
return true;
}
}
return false;
}
bool ReadString(StringBuilder outText, string text, ref int curOffset)
{
while (curOffset <= initialOffset)
{
char ch = text[curOffset++];
outText.Append(ch);
if (ch == '"')
{
return true;
}
}
return false;
}
bool ReadVerbatimString(StringBuilder outText, string text, ref int curOffset)
{
while (curOffset <= initialOffset)
{
char ch = text[curOffset++];
outText.Append(ch);
if (ch == '"')
{
if (curOffset < text.Length && text[curOffset] == '"')
{
outText.Append(text[curOffset++]);
}
else
{
return true;
}
}
}
return false;
}
#endregion
#region mini backward lexer
string text;
int offset;
char GetNext()
{
if (offset >= 0)
{
return text[offset--];
}
return '\0';
}
char Peek()
{
if (offset >= 0)
{
return text[offset];
}
return '\0';
}
// void UnGet()
// {
// ++offset;
// }
// tokens for our lexer
const int Err = 0;
const int Dot = 1;
const int StrLit = 2;
const int Ident = 3;
const int New = 4;
// const int Bracket = 5;
const int Parent = 6;
const int Curly = 7;
const int Using = 8;
int curTokenType;
string lastIdentifier;
void ReadNextToken()
{
char ch = GetNext();
curTokenType = Err;
if (ch == '\0' || ch == '\n' || ch == '\r')
{
return;
}
while (Char.IsWhiteSpace(ch))
{
ch = GetNext();
if (ch == '\n' || ch == '\r')
{
return;
}
}
switch (ch)
{
case '}':
if (ReadBracket('{'))
{
curTokenType = Curly;
}
break;
case ')':
if (ReadBracket('('))
{
curTokenType = Parent;
}
break;
case ']':
if (ReadBracket('['))
{
curTokenType = Ident;
}
break;
case '.':
curTokenType = Dot;
break;
case '\'':
case '"':
if (ReadStringLiteral(ch))
{
curTokenType = StrLit;
}
break;
default:
if (IsIdentifierPart(ch))
{
string ident = ReadIdentifier(ch);
if (ident != null) {
if (string.Equals(ident, "new", StringComparison.InvariantCultureIgnoreCase)) {
curTokenType = New;
} else if (string.Equals(ident, "imports", StringComparison.InvariantCultureIgnoreCase)) {
curTokenType = Using;
} else {
lastIdentifier = ident;
curTokenType = Ident;
}
}
}
break;
}
}
bool ReadStringLiteral(char litStart)
{
while (true)
{
char ch = GetNext();
if (ch == '\0')
{
return false;
}
if (ch == litStart)
{
if (Peek() == '@' && litStart == '"')
{
GetNext();
}
return true;
}
}
}
bool ReadBracket(char openBracket)
{
int curlyBraceLevel = 0;
int squareBracketLevel = 0;
int parenthesisLevel = 0;
switch (openBracket)
{
case '(':
parenthesisLevel++;
break;
case '[':
squareBracketLevel++;
break;
case '{':
curlyBraceLevel++;
break;
}
while (parenthesisLevel != 0 || squareBracketLevel != 0 || curlyBraceLevel != 0)
{
char ch = GetNext();
if (ch == '\0')
{
return false;
}
switch (ch)
{
case '(':
parenthesisLevel--;
break;
case '[':
squareBracketLevel--;
break;
case '{':
curlyBraceLevel--;
break;
case ')':
parenthesisLevel++;
break;
case ']':
squareBracketLevel++;
break;
case '}':
curlyBraceLevel++;
break;
}
}
return true;
}
string ReadIdentifier(char ch)
{
string identifier = ch.ToString();
while (IsIdentifierPart(Peek()))
{
identifier = GetNext() + identifier;
}
return identifier;
}
static bool IsIdentifierPart(char ch)
{
return Char.IsLetterOrDigit(ch) || ch == '_';
}
#endregion
#region finite state machine
const int ERROR = 0;
const int START = 1;
const int DOT = 2;
const int MORE = 3;
const int CURLY = 4;
const int CURLY2 = 5;
const int CURLY3 = 6;
const int ACCEPT = 7;
const int ACCEPTNOMORE = 8;
const int ACCEPT2 = 9;
int state;
int lastAccept;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", MessageId = "Member")]
static int[,] stateTable = new int[,] {
// Err, Dot, Str, ID, New, Brk, Par, Cur, Using
/*ERROR*/ { ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR},
/*START*/ { ERROR, ERROR, ACCEPT, ACCEPT, ERROR, MORE, ACCEPT2, CURLY, ACCEPTNOMORE},
/*DOT*/ { ERROR, ERROR, ACCEPT, ACCEPT, ERROR, MORE, ACCEPT2, CURLY, ERROR},
/*MORE*/ { ERROR, ERROR, ACCEPT, ACCEPT, ERROR, MORE, ACCEPT2, CURLY, ERROR},
/*CURLY*/ { ERROR, ERROR, ERROR, ERROR, ERROR, CURLY2, ERROR, ERROR, ERROR},
/*CURLY2*/ { ERROR, ERROR, ERROR, CURLY3, ERROR, ERROR, ERROR, ERROR, ERROR},
/*CURLY3*/ { ERROR, ERROR, ERROR, ERROR, ACCEPTNOMORE, ERROR, ERROR, ERROR, ERROR},
/*ACCEPT*/ { ERROR, DOT, ERROR, ERROR, ACCEPT, ERROR, ERROR, ERROR, ACCEPTNOMORE},
/*ACCEPTNOMORE*/ { ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR, ERROR},
/*ACCEPT2*/ { ERROR, DOT, ERROR, ACCEPT, ACCEPT, ERROR, ERROR, ERROR, ERROR},
};
#endregion
}
}

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

@ -128,10 +128,12 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
return ExpressionContext.Global; return ExpressionContext.Global;
case Context.IdentifierExpected: case Context.IdentifierExpected:
return ExpressionContext.IdentifierExpected; return ExpressionContext.IdentifierExpected;
case Context.Type: case Context.TypeDeclaration:
return ExpressionContext.TypeDeclaration; return ExpressionContext.TypeDeclaration;
case Context.Body: case Context.Body:
return ExpressionContext.MethodBody; return ExpressionContext.MethodBody;
case Context.Importable:
return ExpressionContext.Importable;
} }
return ExpressionContext.Default; return ExpressionContext.Default;

Loading…
Cancel
Save