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 = @@ -504,11 +504,11 @@ ObjectInitializer =
.
CollectionInitializer =
"{" ( Expression | GREEDY CollectionInitializer ) { "," ( Expression | GREEDY CollectionInitializer ) } "}"
"{" Expression { "," Expression } "}"
.
ExpressionSuffix =
"(" ( "Of" TypeName { "," TypeName } ")" | [ ArgumentList ] ")" )
"(" ( "Of" TypeName { "," TypeName } ")" | [ ArgumentList ] ")" )
| ( "." | "!" | ".@" | "..." ) (. nextTokenIsStartOfImportsOrAccessExpression = true; .) [ XmlOpenTag ] IdentifierOrKeyword [ XmlCloseTag ]
.
@ -663,7 +663,7 @@ CollectionRangeVariable = @@ -663,7 +663,7 @@ CollectionRangeVariable =
/* semantic action will be inserted on all paths that possibly lead to XmlLiteral */
XmlLiteral
(.OnEachPossiblePath: nextTokenIsPotentialStartOfXmlMode = true; .)
(.OnEachPossiblePath: nextTokenIsPotentialStartOfExpression = true; .)
=
(. PushContext(Context.Xml, la, t); .)
{ ( 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 @@ -19,7 +19,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
void PopContext()
{
if (stack.Count > 0) {
if (stack.Any()) {
string indent = new string('\t', stack.Count - 1);
var item = stack.Pop();
item.isClosed = true;
@ -112,8 +112,8 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -112,8 +112,8 @@ namespace ICSharpCode.NRefactory.Parser.VB
get { return stack.Any() ? stack.Peek() : Block.Default; }
}
public bool NextTokenIsPotentialStartOfXmlMode {
get { return nextTokenIsPotentialStartOfXmlMode; }
public bool NextTokenIsPotentialStartOfExpression {
get { return nextTokenIsPotentialStartOfExpression; }
}
public bool ReadXmlIdentifier {

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

@ -318,7 +318,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -318,7 +318,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
return new Token(Tokens.XmlEndInlineVB, new Location(x, y), new Location(Col, Line));
}
#endregion
if (ch == '<' && (ef.NextTokenIsPotentialStartOfXmlMode || ef.NextTokenIsStartOfImportsOrAccessExpression)) {
if (ch == '<' && (ef.NextTokenIsPotentialStartOfExpression || ef.NextTokenIsStartOfImportsOrAccessExpression)) {
xmlModeStack.Push(new XmlModeStackInfo(ef.NextTokenIsStartOfImportsOrAccessExpression));
XmlModeStackInfo info = xmlModeStack.Peek();
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 { @@ -35,7 +35,7 @@ partial class ExpressionFinder {
-->declarations
readonly Stack<int> stateStack = new Stack<int>();
bool wasQualifierTokenAtStart = false;
bool nextTokenIsPotentialStartOfXmlMode = false;
bool nextTokenIsPotentialStartOfExpression = false;
bool readXmlIdentifier = false;
bool nextTokenIsStartOfImportsOrAccessExpression = false;
List<Token> errors = new List<Token>();
@ -50,14 +50,14 @@ partial class ExpressionFinder { @@ -50,14 +50,14 @@ partial class ExpressionFinder {
if (la.kind != expectedKind) {
Error(la);
output.AppendLine("expected: " + expectedKind);
Console.WriteLine("expected: " + expectedKind);
//Console.WriteLine("expected: " + expectedKind);
}
}
void Error(Token la)
{
output.AppendLine("not expected: " + la);
Console.WriteLine("not expected: " + la);
//Console.WriteLine("not expected: " + la);
errors.Add(la);
}
@ -65,7 +65,7 @@ partial class ExpressionFinder { @@ -65,7 +65,7 @@ partial class ExpressionFinder {
public void InformToken(Token la)
{
nextTokenIsPotentialStartOfXmlMode = false;
nextTokenIsPotentialStartOfExpression = false;
readXmlIdentifier = false;
nextTokenIsStartOfImportsOrAccessExpression = false;
wasQualifierTokenAtStart = false;
@ -76,7 +76,7 @@ partial class ExpressionFinder { @@ -76,7 +76,7 @@ partial class ExpressionFinder {
public void Advance()
{
Console.WriteLine("Advance");
//Console.WriteLine("Advance");
InformToken(null);
}

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

@ -33,6 +33,22 @@ Class MainClass ' a comment @@ -33,6 +33,22 @@ Class MainClass ' a comment
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;
[SetUp]
@ -54,6 +70,42 @@ End Class @@ -54,6 +70,42 @@ End Class
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]
public void Simple()
{
@ -107,6 +159,7 @@ End Class @@ -107,6 +159,7 @@ End Class
{
FindFull(program1, "omeMe", "SomeMethod", ExpressionContext.IdentifierExpected);
}
#region Old Tests
void OldTest(string expr, int offset)
{
@ -120,6 +173,18 @@ End Class"; @@ -120,6 +173,18 @@ End Class";
".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]
public void FieldReference()
{
@ -145,6 +210,13 @@ End Class"; @@ -145,6 +210,13 @@ End Class";
{
OldTest("abc.Method().Method(5, a.b, 5 + a)", 16);
}
[Test, Ignore]
public void PlusExpression()
{
OldTestFind("def", 2);
}
#endregion
#endregion
}
}

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

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

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

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

Loading…
Cancel
Save