Browse Source

- fixed LL1 conflict with CollectionInitializer

- added more unit tests
- extended VBNetExpressionFinder

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/vbnet@6071 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Siegfried Pammer 16 years ago
parent
commit
3f161c463c
  1. 6
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.atg
  2. 6
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/ExpressionFinder.cs
  3. 2
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Lexer.cs
  4. 2695
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/Parser.cs
  5. 10
      src/Libraries/NRefactory/Project/Src/Lexer/VBNet/PushParser.frame
  6. 72
      src/Main/Base/Test/VBExpressionFinderTests.cs
  7. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  8. 13
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetExpressionFinder.cs

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

@ -504,11 +504,11 @@ ObjectInitializer =
. .
CollectionInitializer = CollectionInitializer =
"{" ( Expression | GREEDY CollectionInitializer ) { "," ( Expression | GREEDY CollectionInitializer ) } "}" "{" Expression { "," Expression } "}"
. .
ExpressionSuffix = ExpressionSuffix =
"(" ( "Of" TypeName { "," TypeName } ")" | [ ArgumentList ] ")" ) "(" ( "Of" TypeName { "," TypeName } ")" | [ ArgumentList ] ")" )
| ( "." | "!" | ".@" | "..." ) (. nextTokenIsStartOfImportsOrAccessExpression = true; .) [ XmlOpenTag ] IdentifierOrKeyword [ XmlCloseTag ] | ( "." | "!" | ".@" | "..." ) (. nextTokenIsStartOfImportsOrAccessExpression = true; .) [ XmlOpenTag ] IdentifierOrKeyword [ XmlCloseTag ]
. .
@ -663,7 +663,7 @@ CollectionRangeVariable =
/* 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 */
XmlLiteral XmlLiteral
(.OnEachPossiblePath: nextTokenIsPotentialStartOfXmlMode = true; .) (.OnEachPossiblePath: nextTokenIsPotentialStartOfExpression = true; .)
= =
(. PushContext(Context.Xml, la, t); .) (. PushContext(Context.Xml, la, t); .)
{ ( XmlComment | XmlProcessingInstruction ) [ XmlContent ] } XmlElement { XmlComment [ XmlContent ] } { ( XmlComment | XmlProcessingInstruction ) [ XmlContent ] } XmlElement { XmlComment [ XmlContent ] }

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

@ -19,7 +19,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
void PopContext() void PopContext()
{ {
if (stack.Count > 0) { if (stack.Any()) {
string indent = new string('\t', stack.Count - 1); string indent = new string('\t', stack.Count - 1);
var item = stack.Pop(); var item = stack.Pop();
item.isClosed = true; item.isClosed = true;
@ -112,8 +112,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
get { return stack.Any() ? stack.Peek() : Block.Default; } get { return stack.Any() ? stack.Peek() : Block.Default; }
} }
public bool NextTokenIsPotentialStartOfXmlMode { public bool NextTokenIsPotentialStartOfExpression {
get { return nextTokenIsPotentialStartOfXmlMode; } get { return nextTokenIsPotentialStartOfExpression; }
} }
public bool ReadXmlIdentifier { public bool ReadXmlIdentifier {

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

@ -318,7 +318,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
return new Token(Tokens.XmlEndInlineVB, new Location(x, y), new Location(Col, Line)); return new Token(Tokens.XmlEndInlineVB, new Location(x, y), new Location(Col, Line));
} }
#endregion #endregion
if (ch == '<' && (ef.NextTokenIsPotentialStartOfXmlMode || ef.NextTokenIsStartOfImportsOrAccessExpression)) { if (ch == '<' && (ef.NextTokenIsPotentialStartOfExpression || ef.NextTokenIsStartOfImportsOrAccessExpression)) {
xmlModeStack.Push(new XmlModeStackInfo(ef.NextTokenIsStartOfImportsOrAccessExpression)); xmlModeStack.Push(new XmlModeStackInfo(ef.NextTokenIsStartOfImportsOrAccessExpression));
XmlModeStackInfo info = xmlModeStack.Peek(); XmlModeStackInfo info = xmlModeStack.Peek();
int x = Col - 1; int x = Col - 1;

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

File diff suppressed because it is too large Load Diff

10
src/Libraries/NRefactory/Project/Src/Lexer/VBNet/PushParser.frame

@ -35,7 +35,7 @@ partial class ExpressionFinder {
-->declarations -->declarations
readonly Stack<int> stateStack = new Stack<int>(); readonly Stack<int> stateStack = new Stack<int>();
bool wasQualifierTokenAtStart = false; bool wasQualifierTokenAtStart = false;
bool nextTokenIsPotentialStartOfXmlMode = false; bool nextTokenIsPotentialStartOfExpression = false;
bool readXmlIdentifier = false; bool readXmlIdentifier = false;
bool nextTokenIsStartOfImportsOrAccessExpression = false; bool nextTokenIsStartOfImportsOrAccessExpression = false;
List<Token> errors = new List<Token>(); List<Token> errors = new List<Token>();
@ -50,14 +50,14 @@ partial class ExpressionFinder {
if (la.kind != expectedKind) { if (la.kind != expectedKind) {
Error(la); Error(la);
output.AppendLine("expected: " + expectedKind); output.AppendLine("expected: " + expectedKind);
Console.WriteLine("expected: " + expectedKind); //Console.WriteLine("expected: " + expectedKind);
} }
} }
void Error(Token la) void Error(Token la)
{ {
output.AppendLine("not expected: " + la); output.AppendLine("not expected: " + la);
Console.WriteLine("not expected: " + la); //Console.WriteLine("not expected: " + la);
errors.Add(la); errors.Add(la);
} }
@ -65,7 +65,7 @@ partial class ExpressionFinder {
public void InformToken(Token la) public void InformToken(Token la)
{ {
nextTokenIsPotentialStartOfXmlMode = false; nextTokenIsPotentialStartOfExpression = false;
readXmlIdentifier = false; readXmlIdentifier = false;
nextTokenIsStartOfImportsOrAccessExpression = false; nextTokenIsStartOfImportsOrAccessExpression = false;
wasQualifierTokenAtStart = false; wasQualifierTokenAtStart = false;
@ -76,7 +76,7 @@ partial class ExpressionFinder {
public void Advance() public void Advance()
{ {
Console.WriteLine("Advance"); //Console.WriteLine("Advance");
InformToken(null); InformToken(null);
} }

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

@ -33,6 +33,22 @@ Class MainClass ' a comment
End Class End Class
"; ";
const string program2 = @"
Class MainClass
Sub A
Console.WriteLine(""Hello World!"")
End Sub
End Class
";
const string program3 = @"
Class MainClass
Sub A
Console.WriteLine
End Sub
End Class
";
VBNetExpressionFinder ef; VBNetExpressionFinder ef;
[SetUp] [SetUp]
@ -54,6 +70,42 @@ End Class
Assert.AreEqual(expectedContext.ToString(), er.Context.ToString()); Assert.AreEqual(expectedContext.ToString(), er.Context.ToString());
} }
void Find(string program, string location, int offset, string expectedExpression, ExpressionContext expectedContext)
{
int pos = program.IndexOf(location);
if (pos < 0) Assert.Fail("location not found in program");
ExpressionResult er = ef.FindExpression(program, pos + offset);
Assert.AreEqual(expectedExpression, er.Expression);
Assert.AreEqual(expectedContext.ToString(), er.Context.ToString());
}
#region Find
[Test]
public void FindSimple()
{
Find(program2, "sole", 0,"Console", ExpressionContext.Default);
}
[Test]
public void FindSimple2()
{
Find(program2, "Wri", 0, "Console.WriteLine", ExpressionContext.Default);
}
[Test]
public void FindSimple3()
{
Find(program3, "WriteLine", "WriteLine".Length, "Console.WriteLine", ExpressionContext.MethodBody);
}
[Test]
public void FindAfterBrace()
{
Find(program2, "WriteLine", "WriteLine(".Length, "", ExpressionContext.Default);
}
#endregion
#region FindFull
[Test] [Test]
public void Simple() public void Simple()
{ {
@ -107,6 +159,7 @@ End Class
{ {
FindFull(program1, "omeMe", "SomeMethod", ExpressionContext.IdentifierExpected); FindFull(program1, "omeMe", "SomeMethod", ExpressionContext.IdentifierExpected);
} }
#region Old Tests #region Old Tests
void OldTest(string expr, int offset) void OldTest(string expr, int offset)
{ {
@ -120,6 +173,18 @@ End Class";
".Length + offset).Expression); ".Length + offset).Expression);
} }
void OldTestFind(string expr, int offset)
{
string body = @"Class Test
Sub A
Dim x = abc + {0}
End Sub
End Class";
Assert.AreEqual(expr, ef.FindExpression(string.Format(body, expr), @"Class Test
Sub A
Dim x = abc + ".Length + offset).Expression);
}
[Test] [Test]
public void FieldReference() public void FieldReference()
{ {
@ -145,6 +210,13 @@ End Class";
{ {
OldTest("abc.Method().Method(5, a.b, 5 + a)", 16); OldTest("abc.Method().Method(5, a.b, 5 + a)", 16);
} }
[Test, Ignore]
public void PlusExpression()
{
OldTestFind("def", 2);
}
#endregion
#endregion #endregion
} }
} }

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

@ -1155,6 +1155,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
AddVBNetKeywords(result, NR.Parser.VB.Tokens.GlobalLevel); AddVBNetKeywords(result, NR.Parser.VB.Tokens.GlobalLevel);
} else if (context == ExpressionContext.MethodBody) { } else if (context == ExpressionContext.MethodBody) {
AddVBNetKeywords(result, NR.Parser.VB.Tokens.StatementStart); AddVBNetKeywords(result, NR.Parser.VB.Tokens.StatementStart);
CtrlSpaceInternal(result, fileContent, showEntriesFromAllNamespaces);
} else { } else {
AddVBNetPrimitiveTypes(result); AddVBNetPrimitiveTypes(result);
CtrlSpaceInternal(result, fileContent, showEntriesFromAllNamespaces); CtrlSpaceInternal(result, fileContent, showEntriesFromAllNamespaces);

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

@ -64,19 +64,20 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
p.InformToken(t); p.InformToken(t);
} while (t.Location < targetPosition); } while (t.Location < targetPosition);
// HACK simulate <= but avoid endless loop at file end. if (p.NextTokenIsPotentialStartOfExpression)
if (t.Location == targetPosition) { return new ExpressionResult("", GetContext(p.CurrentBlock));
t = lexer.NextToken();
p.InformToken(t);
}
Block block = p.CurrentBlock; Block block = p.CurrentBlock;
var expressionDelimiters = new[] { Tokens.EOL, Tokens.Colon, Tokens.Dot, Tokens.TripleDot, Tokens.DotAt, Tokens.OpenParenthesis };
int tokenOffset; int tokenOffset;
if (t == null || t.Kind == Tokens.EOF) if (t == null || t.Kind == Tokens.EOF)
tokenOffset = text.Length; tokenOffset = text.Length;
else else
tokenOffset = LocationToOffset(t.Location); tokenOffset = expressionDelimiters.Contains(t.Kind)
? LocationToOffset(t.Location)
: LocationToOffset(t.EndLocation);
int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart); int lastExpressionStartOffset = LocationToOffset(block.lastExpressionStart);
if (lastExpressionStartOffset >= 0) { if (lastExpressionStartOffset >= 0) {

Loading…
Cancel
Save