Browse Source

- implemented ObjectCreation and Type context

- fixed bugs in ExpressionFinder

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6117 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
cca4d61806
  1. 51
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/CompletionDataHelper.cs
  2. 11
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/VBNetCompletionBinding.cs
  3. 2
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Block.cs
  4. 45
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg
  5. 2
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs
  6. 1
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  7. 4422
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs
  8. 22
      src/Libraries/NRefactory/Test/Lexer/VBNet/LexerContextTests.cs
  9. 28
      src/Main/Base/Test/VBExpressionFinderTests.cs
  10. 3
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  11. 28
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

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

@ -21,9 +21,9 @@ namespace ICSharpCode.VBNetBinding
{ {
public static class CompletionDataHelper public static class CompletionDataHelper
{ {
public static ICompletionItemList GenerateCompletionData(this ExpressionResult expressionResult, ITextEditor editor) public static ICompletionItemList GenerateCompletionData(this ExpressionResult expressionResult, ITextEditor editor, char pressedKey)
{ {
var result = new NRefactoryCompletionItemList(); DefaultCompletionItemList result = new NRefactoryCompletionItemList();
IResolver resolver = ParserService.CreateResolver(editor.FileName); IResolver resolver = ParserService.CreateResolver(editor.FileName);
ParseInformation info = ParserService.GetParseInformation(editor.FileName); ParseInformation info = ParserService.GetParseInformation(editor.FileName);
@ -33,12 +33,12 @@ namespace ICSharpCode.VBNetBinding
List<ICompletionEntry> data = new List<ICompletionEntry>(); List<ICompletionEntry> data = new List<ICompletionEntry>();
if (string.IsNullOrEmpty(expressionResult.Expression)) { if (expressionResult.Context != ExpressionContext.Global && expressionResult.Context != ExpressionContext.TypeDeclaration) {
data = new NRefactoryResolver(LanguageProperties.VBNet) if (string.IsNullOrEmpty(expressionResult.Expression) || IdentifierExpected(expressionResult.Tag)) {
.CtrlSpace(editor.Caret.Line, editor.Caret.Column, info, editor.Document.Text, expressionResult.Context, result.ContainsItemsFromAllNamespaces); data = new NRefactoryResolver(LanguageProperties.VBNet)
} else { .CtrlSpace(editor.Caret.Line, editor.Caret.Column, info, editor.Document.Text, expressionResult.Context, ((NRefactoryCompletionItemList)result).ContainsItemsFromAllNamespaces);
if (expressionResult.Context != ExpressionContext.Global && expressionResult.Context != ExpressionContext.TypeDeclaration) { } else {
if (expressionResult.Context == ExpressionContext.Importable && expressionResult.Expression == "Imports") { if (expressionResult.Context == ExpressionContext.Importable && expressionResult.Expression.Equals("Imports", StringComparison.OrdinalIgnoreCase)) {
expressionResult.Expression = "Global"; expressionResult.Expression = "Global";
} }
@ -47,14 +47,33 @@ namespace ICSharpCode.VBNetBinding
if (rr == null) if (rr == null)
return result; return result;
data = rr.GetCompletionData(info.CompilationUnit.ProjectContent, result.ContainsItemsFromAllNamespaces); data = rr.GetCompletionData(info.CompilationUnit.ProjectContent, ((NRefactoryCompletionItemList)result).ContainsItemsFromAllNamespaces);
} }
} }
if (expressionResult.Tag != null && (expressionResult.Context != ExpressionContext.Importable))
bool addedKeywords = false;
if (expressionResult.Tag != null && (expressionResult.Context != ExpressionContext.Importable) && pressedKey != '.') {
AddVBNetKeywords(data, (BitArray)expressionResult.Tag); AddVBNetKeywords(data, (BitArray)expressionResult.Tag);
if (((BitArray)expressionResult.Tag)[Tokens.New])
data.Add(new KeywordEntry("New"));
addedKeywords = true;
}
return CodeCompletionItemProvider.ConvertCompletionData(result, data, expressionResult.Context); result = CodeCompletionItemProvider.ConvertCompletionData(result, data, expressionResult.Context);
if (addedKeywords)
AddTemplates(editor, result);
return result;
}
static bool IdentifierExpected(object tag)
{
if (tag is BitArray)
return (tag as BitArray)[2];
return false;
} }
static void AddVBNetKeywords(List<ICompletionEntry> ar, BitArray keywords) static void AddVBNetKeywords(List<ICompletionEntry> ar, BitArray keywords)
@ -65,5 +84,15 @@ namespace ICSharpCode.VBNetBinding
} }
} }
} }
static void AddTemplates(ITextEditor editor, DefaultCompletionItemList list)
{
if (list == null)
return;
List<ICompletionItem> snippets = editor.GetSnippets().ToList();
list.Items.RemoveAll(item => item.Image == ClassBrowserIconService.Keyword && snippets.Exists(i => i.Text == item.Text));
list.Items.AddRange(snippets);
list.SortItems();
}
} }
} }

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

@ -61,17 +61,18 @@ namespace ICSharpCode.VBNetBinding
break; break;
case '"': case '"':
case '\n': case '\n':
case ')':
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);
editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor)); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor, ch));
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 || result.Context == ExpressionContext.Type || result.Context == ExpressionContext.ObjectCreation) {
LoggingService.Debug("CC: After space, result=" + result + ", context=" + result.Context); LoggingService.Debug("CC: After space, result=" + result + ", context=" + result.Context);
editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor)); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor, ch));
return CodeCompletionKeyPressResult.Completed; return CodeCompletionKeyPressResult.Completed;
} }
break; break;
@ -90,7 +91,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);
editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor)); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor, ch));
return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion; return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
} }
} }
@ -182,7 +183,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) {
editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor)); editor.ShowCompletionWindow(CompletionDataHelper.GenerateCompletionData(result, editor, ' '));
return true; return true;
} }
} }

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

@ -16,6 +16,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
{ {
Global, Global,
TypeDeclaration, TypeDeclaration,
ObjectCreation,
Type,
Member, Member,
IdentifierExpected, IdentifierExpected,
Body, Body,

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

@ -322,7 +322,7 @@ TypeDeclaration =
ClassOrModuleOrStructureTypeDeclaration = ClassOrModuleOrStructureTypeDeclaration =
( "Module" | "Class" | "Structure" ) (. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .) ( "Module" | "Class" | "Structure" ) (. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .)
[ "(" "Of" [ "Out" | "In" ] IdentifierExceptOut [ "As" GenericConstraintList ] { "," [ "Out" | "In" ] IdentifierExceptOut [ "As" GenericConstraintList ] } ")" ] { ANY } [ StatementTerminator ] [ "(" "Of" [ "Out" | "In" ] IdentifierExceptOut [ (. PushContext(Context.Type, la, t); .) "As" GenericConstraintList (. PopContext(); .) ] { "," [ "Out" | "In" ] IdentifierExceptOut [ (. PushContext(Context.Type, la, t); .) "As" GenericConstraintList (. PopContext(); .) ] } ")" ] { ANY } [ StatementTerminator ]
[ "Inherits" { ANY } StatementTerminator ] [ "Inherits" { ANY } StatementTerminator ]
[ "Implements" { ANY } StatementTerminator ] [ "Implements" { ANY } StatementTerminator ]
(. PushContext(Context.TypeDeclaration, la, t); .) (. PushContext(Context.TypeDeclaration, la, t); .)
@ -342,7 +342,7 @@ GenericConstraintList =
DelegateTypeDeclaration = DelegateTypeDeclaration =
"Delegate" ("Sub" | "Function") "Delegate" ("Sub" | "Function")
(. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .) (. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .)
[ "(" [ ParameterList ] ")" ] [ "As" TypeName ] StatementTerminator [ "(" [ ParameterList ] ")" ] [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] StatementTerminator
. .
MemberDeclaration = MemberDeclaration =
@ -362,18 +362,18 @@ MemberDeclaration =
SubOrFunctionDeclaration = SubOrFunctionDeclaration =
("Sub" | "Function") ("Sub" | "Function")
(. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .) (. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .)
[ "(" [ ParameterList ] ")" ] [ "As" TypeName ] [ "(" [ ParameterList ] ")" ] [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ]
StatementTerminatorAndBlock StatementTerminatorAndBlock
"End" ("Sub" | "Function") StatementTerminator "End" ("Sub" | "Function") StatementTerminator
. .
ExternalMemberDeclaration = ExternalMemberDeclaration =
"Declare" [ "Ansi" | "Unicode" | "Auto" ] ( "Sub" | "Function" ) (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) "Declare" [ "Ansi" | "Unicode" | "Auto" ] ( "Sub" | "Function" ) (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .)
"Lib" LiteralString [ "Alias" LiteralString ] [ "(" [ ParameterList ] ")" ] [ "As" TypeName ] StatementTerminator "Lib" LiteralString [ "Alias" LiteralString ] [ "(" [ ParameterList ] ")" ] [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] StatementTerminator
. .
EventMemberDeclaration = EventMemberDeclaration =
"Event" (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) ( "As" TypeName | [ "(" [ ParameterList ] ")" ] ) "Event" (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) ( (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) | [ "(" [ ParameterList ] ")" ] )
[ "Implements" TypeName /*"." IdentifierOrKeyword*/ { "," TypeName /*"." IdentifierOrKeyword*/ } ] [ "Implements" TypeName /*"." IdentifierOrKeyword*/ { "," TypeName /*"." IdentifierOrKeyword*/ } ]
/* the TypeName production already allows the "." IdentifierOrKeyword syntax, so to avoid an ambiguous grammer we just leave that out */ /* the TypeName production already allows the "." IdentifierOrKeyword syntax, so to avoid an ambiguous grammer we just leave that out */
StatementTerminator StatementTerminator
@ -390,14 +390,14 @@ CustomEventMemberDeclaration =
. .
OperatorDeclaration = OperatorDeclaration =
"Operator" (. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .) "(" ParameterList ")" [ "As" { AttributeBlock } TypeName ] "Operator" (. PushContext(Context.IdentifierExpected, la, t); .) ANY (. PopContext(); .) "(" ParameterList ")" [ "As" { AttributeBlock } (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ]
StatementTerminatorAndBlock StatementTerminatorAndBlock
"End" "Operator" StatementTerminator "End" "Operator" StatementTerminator
. .
MemberVariableOrConstantDeclaration = MemberVariableOrConstantDeclaration =
[ "Const" ] [ "Const" ]
(. PushContext(Context.IdentifierExpected, la, t); .) IdentifierForFieldDeclaration (. PopContext(); .) [ "As" TypeName ] [ "=" Expression ] StatementTerminator (. PushContext(Context.IdentifierExpected, la, t); .) IdentifierForFieldDeclaration (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] [ "=" Expression ] StatementTerminator
. .
ParameterList = ParameterList =
@ -405,7 +405,7 @@ ParameterList =
. .
Parameter = Parameter =
{ AttributeBlock } { ParameterModifier } (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) [ "As" TypeName ] [ "=" Expression ] { AttributeBlock } { ParameterModifier } (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] [ "=" Expression ]
. .
StatementTerminatorAndBlock = StatementTerminatorAndBlock =
@ -482,7 +482,7 @@ SimpleExpression =
. .
NewExpression = NewExpression =
"New" (. PushContext(Context.ObjectCreation, la, t); .) "New"
( (
TypeName TypeName
@ -509,6 +509,7 @@ NewExpression =
| |
"With" ObjectInitializer "With" ObjectInitializer
) )
(. PopContext(); .)
. .
ObjectInitializer = ObjectInitializer =
@ -566,7 +567,7 @@ SubLambdaExpression =
FunctionLambdaExpression = FunctionLambdaExpression =
"Function" "(" [ ParameterList ] ")" "Function" "(" [ ParameterList ] ")"
( GREEDY Expression | [ "As" TypeName ] StatementTerminatorAndBlock "End" "Function" ) ( GREEDY Expression | [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] StatementTerminatorAndBlock "End" "Function" )
. .
QueryExpression QueryExpression
@ -653,7 +654,7 @@ ExpressionRangeVariable =
( (
(. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .)
( (
"As" TypeName "=" (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) "="
| "=" | "="
| (. | (.
currentState = endOfStatementTerminatorAndBlock; /* leave this block */ currentState = endOfStatementTerminatorAndBlock; /* leave this block */
@ -670,7 +671,7 @@ ExpressionRangeVariable =
. .
CollectionRangeVariable = CollectionRangeVariable =
(. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) [ "As" TypeName ] "In" Expression (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] "In" Expression
. .
/* semantic action will be inserted on all paths that possibly lead to XmlLiteral */ /* semantic action will be inserted on all paths that possibly lead to XmlLiteral */
@ -938,7 +939,21 @@ Statement =
VariableDeclarationStatement = VariableDeclarationStatement =
( "Dim" | "Static" | "Const" ) ( "Dim" | "Static" | "Const" )
(. PushContext(Context.IdentifierExpected, la, t); .) (. PushContext(Context.IdentifierExpected, la, t); .)
Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ] { "," (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ] } [ "As" [ "New" ] TypeName ] [ "=" Expression ] Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ]
{ ","
(. PushContext(Context.IdentifierExpected, la, t); .)
Identifier (. PopContext(); .) [ "?" ] [ ( "(" { "," } ")" ) ]
}
[ (. PushContext(Context.Type, la, t); .)
"As" TypeName
[ "New" (. PushContext(Context.ObjectCreation, la, t); .) ]
TypeName
(.
if (CurrentBlock.context == Context.ObjectCreation)
PopContext();
PopContext();
.) ]
[ "=" Expression ]
. .
WithOrLockStatement = WithOrLockStatement =
@ -1027,7 +1042,7 @@ ForEachLoopStatement =
. .
ForLoopVariable = ForLoopVariable =
(. PushContext(Context.IdentifierExpected, la, t); .) SimpleExpression (. PopContext(); .) [ "?" ] { ExpressionSuffix } [ "As" TypeName ] (. PushContext(Context.IdentifierExpected, la, t); .) SimpleExpression (. PopContext(); .) [ "?" ] { ExpressionSuffix } [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ]
. .
ErrorHandlingStatement = ErrorHandlingStatement =
@ -1044,7 +1059,7 @@ TryStatement =
StatementTerminatorAndBlock StatementTerminatorAndBlock
{ {
"Catch" "Catch"
[ (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) [ "As" TypeName ] ] [ (. PushContext(Context.IdentifierExpected, la, t); .) Identifier (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] ]
[ "When" Expression ] [ "When" Expression ]
StatementTerminatorAndBlock StatementTerminatorAndBlock
} }

2
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
void PushContext(Context context, Token la, Token t) void PushContext(Context context, Token la, Token t)
{ {
string indent = new string('\t', stack.Count); string indent = new string('\t', stack.Count);
Location l = la == null ? Location.Empty : la.Location; Location l = la == null ? (t == null ? Location.Empty : t.EndLocation) : la.Location;
stack.Push(new Block() { context = context, lastExpressionStart = l }); stack.Push(new Block() { context = context, lastExpressionStart = l });
Print(indent + "enter " + context); Print(indent + "enter " + context);

1
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs

@ -389,6 +389,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
prevToken = t; prevToken = t;
} }
ef.Advance(); ef.Advance();
Debug.Assert(t != null);
return t; return t;
} }

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

File diff suppressed because it is too large Load Diff

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

@ -83,6 +83,8 @@ End Class
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type
exit Type
enter Expression enter Expression
enter Expression enter Expression
enter Expression enter Expression
@ -295,6 +297,8 @@ End Class
enter Expression enter Expression
exit Expression exit Expression
exit IdentifierExpected exit IdentifierExpected
enter Type
exit Type
enter Expression enter Expression
enter Expression enter Expression
enter Expression enter Expression
@ -311,6 +315,8 @@ End Class
enter Expression enter Expression
exit Expression exit Expression
exit IdentifierExpected exit IdentifierExpected
enter Type
exit Type
enter Expression enter Expression
enter Expression enter Expression
enter Expression enter Expression
@ -323,6 +329,8 @@ End Class
exit Body exit Body
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type
exit Type
enter Body enter Body
exit Body exit Body
exit Body exit Body
@ -352,6 +360,8 @@ End Class",
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
exit IdentifierExpected exit IdentifierExpected
enter Type
exit Type
exit Member exit Member
enter Member enter Member
enter IdentifierExpected enter IdentifierExpected
@ -465,18 +475,20 @@ End Module",
exit Expression exit Expression
enter Expression enter Expression
enter Expression enter Expression
enter Expression enter ObjectCreation
enter Expression enter Expression
enter Expression enter Expression
enter Expression
exit Expression
exit Expression exit Expression
exit Expression exit Expression
exit Expression
enter Expression
enter Expression enter Expression
enter Expression enter Expression
enter Expression
exit Expression
exit Expression exit Expression
exit Expression exit Expression
exit Expression exit ObjectCreation
exit Expression exit Expression
exit Expression exit Expression
exit Expression exit Expression
@ -522,7 +534,7 @@ exit Global
RunTest(@"Imports System RunTest(@"Imports System
Imports System.Linq Imports System.Linq
Imports System.Collections.Generic", Imports System.Collections.Generic",
@"enter Global @"enter Global
enter Importable enter Importable
exit Importable exit Importable
enter Importable enter Importable

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

@ -49,6 +49,14 @@ Class MainClass
End Class End Class
"; ";
const string program4 = @"
Class MainClass
Sub A
Dim a
End Sub
End Class
";
VBNetExpressionFinder ef; VBNetExpressionFinder ef;
[SetUp] [SetUp]
@ -83,7 +91,7 @@ End Class
[Test] [Test]
public void FindSimple() public void FindSimple()
{ {
Find(program2, "sole", 0,"Con", ExpressionContext.Default); Find(program2, "sole", 0,"Con", ExpressionContext.MethodBody);
} }
[Test] [Test]
@ -107,7 +115,7 @@ End Class
[Test] [Test]
public void ForEachLoop() public void ForEachLoop()
{ {
Find(program1, "loopVarName", 4, "loop", ExpressionContext.Default); Find(program1, "loopVarName", 4, "loop", ExpressionContext.IdentifierExpected);
} }
[Test] [Test]
@ -117,6 +125,22 @@ End Class
} }
#endregion #endregion
#region Context Tests
void ContextTest(string program, string location, int offset, ExpressionContext context)
{
int pos = program.IndexOf(location);
if (pos < 0) Assert.Fail("location not found in program");
ExpressionResult er = ef.FindExpression(program, pos + offset);
Assert.AreEqual(context.ToString(), er.Context.ToString());
}
[Test]
public void ContextAfterDimIdentifier()
{
ContextTest(program4, " a ", 3, ExpressionContext.MethodBody);
}
#endregion
#region FindFull #region FindFull
[Test] [Test]
public void Simple() public void Simple()

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

@ -1139,8 +1139,7 @@ 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.MethodBody) CtrlSpaceInternal(result, fileContent, showEntriesFromAllNamespaces);
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);

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

@ -59,18 +59,23 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
ExpressionFinder p = new ExpressionFinder(); ExpressionFinder p = new ExpressionFinder();
lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(text)); lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(text));
Token t; Token t = lexer.NextToken();
do { while (t.EndLocation < targetPosition) {
t = lexer.NextToken();
if (t.Location >= targetPosition)
break;
p.InformToken(t); p.InformToken(t);
} while (t.EndLocation < targetPosition); t = lexer.NextToken();
}
p.Advance();
var block = p.CurrentBlock; var block = p.CurrentBlock;
p.Advance(); ExpressionContext context = p.IsIdentifierExpected ? ExpressionContext.IdentifierExpected : GetContext(block);
if (t.Location < targetPosition) {
p.InformToken(t);
p.Advance();
}
BitArray expectedSet; BitArray expectedSet;
@ -81,11 +86,10 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
} }
if (p.NextTokenIsPotentialStartOfExpression) if (p.NextTokenIsPotentialStartOfExpression)
return new ExpressionResult("", DomRegion.Empty, GetContext(p.CurrentBlock), expectedSet); return new ExpressionResult("", DomRegion.Empty, GetContext(block), expectedSet);
int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart); int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart);
ExpressionContext context = p.IsIdentifierExpected ? ExpressionContext.IdentifierExpected : GetContext(block);
if (lastExpressionStartOffset < 0) if (lastExpressionStartOffset < 0)
return new ExpressionResult(null, DomRegion.Empty, context, expectedSet); return new ExpressionResult(null, DomRegion.Empty, context, expectedSet);
@ -130,10 +134,14 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
return ExpressionContext.IdentifierExpected; return ExpressionContext.IdentifierExpected;
case Context.TypeDeclaration: case Context.TypeDeclaration:
return ExpressionContext.TypeDeclaration; return ExpressionContext.TypeDeclaration;
case Context.Type:
return ExpressionContext.Type;
case Context.Body: case Context.Body:
return ExpressionContext.MethodBody; return ExpressionContext.MethodBody;
case Context.Importable: case Context.Importable:
return ExpressionContext.Importable; return ExpressionContext.Importable;
case Context.ObjectCreation:
return ExpressionContext.ObjectCreation;
} }
return ExpressionContext.Default; return ExpressionContext.Default;
@ -190,4 +198,4 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
#endregion #endregion
} }
} }
Loading…
Cancel
Save