Browse Source

fixed bugs in ExpressionFinder and inconsistent completion results

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6154 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
1e1e4cd46b
  1. 22
      src/AddIns/BackendBindings/VBNetBinding/Project/Src/CompletionDataHelper.cs
  2. 28
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg
  3. 6
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs
  4. 5096
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs
  5. 13
      src/Main/Base/Test/VBExpressionFinderTests.cs
  6. 47
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

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

@ -39,16 +39,18 @@ namespace ICSharpCode.VBNetBinding @@ -39,16 +39,18 @@ namespace ICSharpCode.VBNetBinding
if (expressionResult.Context != ExpressionContext.Global && expressionResult.Context != ExpressionContext.TypeDeclaration) {
if (expressionResult.Context == ExpressionContext.Importable && string.IsNullOrWhiteSpace(expressionResult.Expression)) {
expressionResult.Expression = "Global";
}
int idx = string.IsNullOrWhiteSpace(expressionResult.Expression)
? -1
: expressionResult.Expression.LastIndexOf('.');
if (idx > -1) {
expressionResult.Expression = expressionResult.Expression.Substring(0, idx);
// its the same as if . was pressed
completingDotExpression = true;
} else if (pressedKey != '.') {
int idx = string.IsNullOrWhiteSpace(expressionResult.Expression)
? -1
: expressionResult.Expression.LastIndexOf('.');
if (idx > -1) {
expressionResult.Expression = expressionResult.Expression.Substring(0, idx);
// its the same as if . was pressed
completingDotExpression = true;
} else {
expressionResult.Expression = "";
}
}
var rr = resolver.Resolve(expressionResult, info, editor.Document.Text);

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

@ -366,7 +366,7 @@ InterfaceSubOrFunction = @@ -366,7 +366,7 @@ InterfaceSubOrFunction =
("Sub" | "Function")
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) ANY (. PopContext(); .)
{ "(" [ ( "Of" GenericTypeParameterDeclaration | ParameterList ) ] ")" }
[ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ]
[ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ]
StatementTerminator
.
@ -379,14 +379,14 @@ GenericConstraintList = @@ -379,14 +379,14 @@ GenericConstraintList =
.
GenericTypeParameterDeclaration =
[ "Out" | "In" ] (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) IdentifierExceptOut (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" GenericConstraintList (. PopContext(); .) ]
{ "," [ "Out" | "In" ] (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) IdentifierExceptOut (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" GenericConstraintList (. PopContext(); .) ] }
[ "Out" | "In" ] (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) IdentifierExceptOut (. PopContext(); .) [ "As" (. PushContext(Context.Type, la, t); .) GenericConstraintList (. PopContext(); .) ]
{ "," [ "Out" | "In" ] (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) IdentifierExceptOut (. PopContext(); .) [ "As" (. PushContext(Context.Type, la, t); .) GenericConstraintList (. PopContext(); .) ] }
.
DelegateTypeDeclaration =
"Delegate" ("Sub" | "Function")
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) ANY (. PopContext(); .)
[ "(" [ ParameterList ] ")" ] [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] StatementTerminator
[ "(" [ ParameterList ] ")" ] [ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ] StatementTerminator
.
MemberDeclaration =
@ -406,18 +406,18 @@ SubOrFunctionDeclaration = @@ -406,18 +406,18 @@ SubOrFunctionDeclaration =
("Sub" | "Function")
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) ANY (. PopContext(); .)
{ "(" [ ( "Of" GenericTypeParameterDeclaration | ParameterList ) ] ")" }
[ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ]
[ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ]
StatementTerminatorAndBlock
"End" ("Sub" | "Function") StatementTerminator
.
ExternalMemberDeclaration =
"Declare" [ "Ansi" | "Unicode" | "Auto" ] ( "Sub" | "Function" ) (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .)
"Lib" LiteralString [ "Alias" LiteralString ] [ "(" [ ParameterList ] ")" ] [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] StatementTerminator
"Lib" LiteralString [ "Alias" LiteralString ] [ "(" [ ParameterList ] ")" ] [ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ] StatementTerminator
.
EventMemberDeclaration =
"Event" (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .) ( (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) | [ "(" [ ParameterList ] ")" ] )
"Event" (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .) ( "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) | [ "(" [ ParameterList ] ")" ] )
[ "Implements" TypeName /*"." IdentifierOrKeyword*/ { "," TypeName /*"." IdentifierOrKeyword*/ } ]
/* the TypeName production already allows the "." IdentifierOrKeyword syntax, so to avoid an ambiguous grammer we just leave that out */
StatementTerminator
@ -441,7 +441,7 @@ OperatorDeclaration = @@ -441,7 +441,7 @@ OperatorDeclaration =
MemberVariableOrConstantDeclaration =
[ "Const" ]
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) IdentifierForFieldDeclaration (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] [ "=" Expression ] StatementTerminator
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) IdentifierForFieldDeclaration (. PopContext(); .) [ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ] [ "=" Expression ] StatementTerminator
.
ParameterList =
@ -452,7 +452,7 @@ Parameter = @@ -452,7 +452,7 @@ Parameter =
(. PushContext(Context.Parameter, la, t); .)
{ AttributeBlock } { ParameterModifier }
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .)
[ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ]
[ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ]
[ "=" Expression ]
(. PopContext(); .)
.
@ -616,7 +616,7 @@ SubLambdaExpression = @@ -616,7 +616,7 @@ SubLambdaExpression =
FunctionLambdaExpression =
"Function" "(" [ ParameterList ] ")"
( GREEDY Expression | [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] StatementTerminatorAndBlock "End" "Function" )
( GREEDY Expression | [ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ] StatementTerminatorAndBlock "End" "Function" )
.
QueryExpression
@ -703,7 +703,7 @@ ExpressionRangeVariable = @@ -703,7 +703,7 @@ ExpressionRangeVariable =
(
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .)
(
(. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) "="
"As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) "="
| "="
| (.
currentState = endOfStatementTerminatorAndBlock; /* leave this block */
@ -720,7 +720,7 @@ ExpressionRangeVariable = @@ -720,7 +720,7 @@ ExpressionRangeVariable =
.
CollectionRangeVariable =
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] "In" Expression
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .) [ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ] "In" Expression
.
/* semantic action will be inserted on all paths that possibly lead to XmlLiteral */
@ -1091,7 +1091,7 @@ ForEachLoopStatement = @@ -1091,7 +1091,7 @@ ForEachLoopStatement =
.
ForLoopVariable =
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) SimpleExpression (. PopContext(); .) [ "?" ] { ExpressionSuffix } [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ]
(. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) SimpleExpression (. PopContext(); .) [ "?" ] { ExpressionSuffix } [ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ]
.
ErrorHandlingStatement =
@ -1108,7 +1108,7 @@ TryStatement = @@ -1108,7 +1108,7 @@ TryStatement =
StatementTerminatorAndBlock
{
"Catch"
[ (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .) [ (. PushContext(Context.Type, la, t); .) "As" TypeName (. PopContext(); .) ] ]
[ (. PushContext(Context.Identifier, la, t); .) (.OnEachPossiblePath: SetIdentifierExpected(la); .) Identifier (. PopContext(); .) [ "As" (. PushContext(Context.Type, la, t); .) TypeName (. PopContext(); .) ] ]
[ "When" Expression ]
StatementTerminatorAndBlock
}

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

@ -38,12 +38,6 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -38,12 +38,6 @@ namespace ICSharpCode.NRefactory.Parser.VB
Print(indent + "enter " + context);
}
void SetContext(Context context, Token la, Token t)
{
PopContext();
PushContext(context, la, t);
}
public ExpressionFinder(ExpressionFinderState state)
{
wasQualifierTokenAtStart = state.WasQualifierTokenAtStart;

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

File diff suppressed because it is too large Load Diff

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

@ -187,8 +187,7 @@ End Class", "Test2", 5, "Test2", ExpressionContext.Default); @@ -187,8 +187,7 @@ End Class", "Test2", 5, "Test2", ExpressionContext.Default);
End Module", @"Module Test
", @"Module Test
".Length, ExpressionContext.TypeDeclaration);
".Length, ExpressionContext.TypeDeclaration);
}
#endregion
@ -247,6 +246,16 @@ End Module", @"Module Test @@ -247,6 +246,16 @@ End Module", @"Module Test
FindFull(program1, "omeMe", "SomeMethod", ExpressionContext.Default);
}
[Test]
public void ParameterName()
{
FindFull(@"Module Test
Function Fibo(x As Integer) As Integer
End Function
End Module", "x", "x", ExpressionContext.Default);
}
#region Old Tests
void OldTest(string expr, int offset)
{

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

@ -103,11 +103,42 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -103,11 +103,42 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
ExpressionResult MakeResult(string text, int startOffset, int endOffset, ExpressionContext context, BitArray expectedKeywords)
{
return new ExpressionResult(text.Substring(startOffset, endOffset - startOffset).Trim(),
return new ExpressionResult(TrimComment(text.Substring(startOffset, endOffset - startOffset)).Trim(),
DomRegion.FromLocation(OffsetToLocation(startOffset), OffsetToLocation(endOffset)),
context, expectedKeywords);
}
string TrimComment(string text)
{
bool inString = false;
int i = 0;
while (i < text.Length) {
char ch = text[i];
if (ch == '"')
inString = !inString;
if (ch == '\'' && !inString) {
int eol = text.IndexOfAny(new[] { '\r', '\n' }, i);
if (eol > -1) {
if(text[eol] == '\r' && eol + 1 < text.Length && text[eol + 1] == '\n')
eol++;
text = text.Remove(i, eol - i);
} else {
text = text.Remove(i);
}
continue;
}
i++;
}
return text;
}
void Init(string text, int offset)
{
lineOffsets = new List<int>();
@ -167,12 +198,20 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -167,12 +198,20 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
t = lexer.NextToken();
p.InformToken(t);
if (block == null && t.EndLocation >= targetPosition)
if (block == null && t.EndLocation > targetPosition)
block = p.CurrentBlock;
if (block != null && (block.isClosed || expressionDelimiters.Contains(t.Kind) && block == p.CurrentBlock))
break;
}
BitArray expectedSet;
try {
expectedSet = p.GetExpectedSet();
} catch (InvalidOperationException) {
expectedSet = null;
}
int tokenOffset;
if (t == null || t.Kind == Tokens.EOF)
tokenOffset = text.Length;
@ -183,10 +222,10 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -183,10 +222,10 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
if (lastExpressionStartOffset >= 0) {
if (offset < tokenOffset) {
// offset is in front of this token
return MakeResult(text, lastExpressionStartOffset, tokenOffset, GetContext(block), p.GetExpectedSet());
return MakeResult(text, lastExpressionStartOffset, tokenOffset, GetContext(block), expectedSet);
} else {
// offset is IN this token
return MakeResult(text, lastExpressionStartOffset, offset, GetContext(block), p.GetExpectedSet());
return MakeResult(text, lastExpressionStartOffset, offset, GetContext(block), expectedSet);
}
} else {
return new ExpressionResult(null, GetContext(block));

Loading…
Cancel
Save