Browse Source

Fixed forum-8242: VB.NET parser does not support "For Expression = Start To End" syntax.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3473 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 18 years ago
parent
commit
37537f28bf
  1. 5
      src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Statements.cs
  2. 66
      src/Libraries/NRefactory/Project/Src/Ast/Generated.cs
  3. 8
      src/Libraries/NRefactory/Project/Src/IAstVisitor.cs
  4. 522
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  5. 22
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  6. 24
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs
  7. 22
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
  8. 18
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs
  9. 10
      src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs
  10. 12
      src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs
  11. 13
      src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs
  12. 10
      src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs
  13. 8
      src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs
  14. 6
      src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs
  15. 7
      src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs
  16. 6
      src/Libraries/NRefactory/Test/Parser/Statements/ForNextStatementTests.cs

5
src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Statements.cs

@ -265,10 +265,11 @@ namespace NRefactoryASTGenerator.Ast @@ -265,10 +265,11 @@ namespace NRefactoryASTGenerator.Ast
Expression step;
List<Expression> nextExpressions;
// either use typeReference+variableName
TypeReference typeReference;
string variableName;
public ForNextStatement(TypeReference typeReference, string variableName, Expression start, Expression end, Expression step, Statement embeddedStatement, List<Expression> nextExpressions) {}
// or use loopVariableExpression:
Expression loopVariableExpression;
}
class OnErrorStatement : StatementWithEmbeddedStatement {

66
src/Libraries/NRefactory/Project/Src/Ast/Generated.cs

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:2.0.50727.3053
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
@ -1579,15 +1579,15 @@ namespace ICSharpCode.NRefactory.Ast { @@ -1579,15 +1579,15 @@ namespace ICSharpCode.NRefactory.Ast {
}
}
public bool HasRaiseRegion {
public bool HasRemoveRegion {
get {
return !raiseRegion.IsNull;
return !removeRegion.IsNull;
}
}
public bool HasRemoveRegion {
public bool HasRaiseRegion {
get {
return !removeRegion.IsNull;
return !raiseRegion.IsNull;
}
}
@ -2007,6 +2007,8 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2007,6 +2007,8 @@ namespace ICSharpCode.NRefactory.Ast {
string variableName;
Expression loopVariableExpression;
public Expression Start {
get {
return start;
@ -2064,14 +2066,24 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2064,14 +2066,24 @@ namespace ICSharpCode.NRefactory.Ast {
}
}
public ForNextStatement(TypeReference typeReference, string variableName, Expression start, Expression end, Expression step, Statement embeddedStatement, List<Expression> nextExpressions) {
TypeReference = typeReference;
VariableName = variableName;
Start = start;
End = end;
Step = step;
EmbeddedStatement = embeddedStatement;
NextExpressions = nextExpressions;
public Expression LoopVariableExpression {
get {
return loopVariableExpression;
}
set {
loopVariableExpression = value ?? Expression.Null;
if (!loopVariableExpression.IsNull) loopVariableExpression.Parent = this;
}
}
public ForNextStatement() {
start = Expression.Null;
end = Expression.Null;
step = Expression.Null;
nextExpressions = new List<Expression>();
typeReference = TypeReference.Null;
variableName = "";
loopVariableExpression = Expression.Null;
}
public override object AcceptVisitor(IAstVisitor visitor, object data) {
@ -2080,7 +2092,7 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2080,7 +2092,7 @@ namespace ICSharpCode.NRefactory.Ast {
public override string ToString() {
return string.Format("[ForNextStatement Start={0} End={1} Step={2} NextExpressions={3} TypeReference={4" +
"} VariableName={5} EmbeddedStatement={6}]", Start, End, Step, GetCollectionString(NextExpressions), TypeReference, VariableName, EmbeddedStatement);
"} VariableName={5} LoopVariableExpression={6} EmbeddedStatement={7}]", Start, End, Step, GetCollectionString(NextExpressions), TypeReference, VariableName, LoopVariableExpression, EmbeddedStatement);
}
}
@ -2428,9 +2440,9 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2428,9 +2440,9 @@ namespace ICSharpCode.NRefactory.Ast {
setRegion = PropertySetRegion.Null;
}
public bool IsReadOnly {
public bool IsWriteOnly {
get {
return HasGetRegion && !HasSetRegion;
return !HasGetRegion && HasSetRegion;
}
}
@ -2446,9 +2458,9 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2446,9 +2458,9 @@ namespace ICSharpCode.NRefactory.Ast {
}
}
public bool IsWriteOnly {
public bool IsReadOnly {
get {
return !HasGetRegion && HasSetRegion;
return HasGetRegion && !HasSetRegion;
}
}
@ -3354,6 +3366,12 @@ public Location ExtendedEndLocation { get; set; } @@ -3354,6 +3366,12 @@ public Location ExtendedEndLocation { get; set; }
}
}
public bool IsWriteOnly {
get {
return !HasGetRegion && HasSetRegion;
}
}
public bool HasSetRegion {
get {
return !setRegion.IsNull;
@ -3378,12 +3396,6 @@ public Location ExtendedEndLocation { get; set; } @@ -3378,12 +3396,6 @@ public Location ExtendedEndLocation { get; set; }
}
}
public bool IsWriteOnly {
get {
return !HasGetRegion && HasSetRegion;
}
}
public override object AcceptVisitor(IAstVisitor visitor, object data) {
return visitor.VisitPropertyDeclaration(this, data);
}

8
src/Libraries/NRefactory/Project/Src/IAstVisitor.cs

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:2.0.50727.3053
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

522
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

22
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG

@ -2883,9 +2883,16 @@ EmbeddedStatement<out Statement statement> @@ -2883,9 +2883,16 @@ EmbeddedStatement<out Statement statement>
Expression start = null;
Expression end = null;
Expression step = null;
Expression nextExpr = null;List<Expression> nextExpressions = null;
Expression variableExpr = null;
Expression nextExpr = null;
List<Expression> nextExpressions = null;
.)
LoopControlVariable<out typeReference, out typeName>
( IF (IsLoopVariableDeclaration())
LoopControlVariable<out typeReference, out typeName>
|
(. typeReference = null; typeName = null; .)
SimpleExpr<out variableExpr>
)
"=" Expr<out start> "To" Expr<out end> [ "Step" Expr<out step> ]
EndOfStmt Block<out embeddedStatement>
"Next"
@ -2898,7 +2905,16 @@ EmbeddedStatement<out Statement statement> @@ -2898,7 +2905,16 @@ EmbeddedStatement<out Statement statement>
{ "," Expr<out nextExpr> (. nextExpressions.Add(nextExpr); .) }
]
(.
statement = new ForNextStatement(typeReference, typeName, start, end, step, embeddedStatement, nextExpressions);
statement = new ForNextStatement {
TypeReference = typeReference,
VariableName = typeName,
LoopVariableExpression = variableExpr,
Start = start,
End = end,
Step = step,
EmbeddedStatement = embeddedStatement,
NextExpressions = nextExpressions
};
SetParent(nextExpressions, statement);
.)
)

24
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs

@ -108,7 +108,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -108,7 +108,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
static bool IsIdentifierToken(Token tk)
{
return Tokens.IdentifierTokens[tk.kind] || tk.kind == Tokens.Identifier;
}
}
bool IsIdentifiedExpressionRange()
{
@ -159,6 +159,26 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -159,6 +159,26 @@ namespace ICSharpCode.NRefactory.Parser.VB
return la.kind == Tokens.OpenParenthesis
&& (peek == Tokens.Comma || peek == Tokens.CloseParenthesis);
}
/*
True if the next token is an identifier
*/
bool IsLoopVariableDeclaration()
{
if (!IsIdentifierToken(la))
return false;
lexer.StartPeek();
Token x = lexer.Peek();
if (x.kind == Tokens.OpenParenthesis) {
do {
x = lexer.Peek();
} while (x.kind == Tokens.Comma);
if (x.kind != Tokens.CloseParenthesis)
return false;
x = lexer.Peek();
}
return x.kind == Tokens.As || x.kind == Tokens.Assign;
}
bool IsSize()
{
@ -258,7 +278,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -258,7 +278,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
if (!(expr is PrimitiveExpression) || (expr as PrimitiveExpression).StringValue != "0")
Error("lower bound of array must be zero");
}
/// <summary>
/// Adds a child item to a collection stored in the parent node.
/// Also set's the item's parent to <paramref name="parent"/>.

22
src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

@ -1638,18 +1638,25 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1638,18 +1638,25 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.PrintToken(Tokens.For);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.OpenParenthesis);
if (!forNextStatement.TypeReference.IsNull) {
TrackVisit(forNextStatement.TypeReference, data);
outputFormatter.Space();
if (forNextStatement.LoopVariableExpression.IsNull) {
if (!forNextStatement.TypeReference.IsNull) {
TrackVisit(forNextStatement.TypeReference, data);
outputFormatter.Space();
}
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
} else {
TrackVisit(forNextStatement.LoopVariableExpression, data);
}
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Assign);
outputFormatter.Space();
TrackVisit(forNextStatement.Start, data);
outputFormatter.PrintToken(Tokens.Semicolon);
outputFormatter.Space();
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
if (forNextStatement.LoopVariableExpression.IsNull)
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
else
TrackVisit(forNextStatement.LoopVariableExpression, data);
outputFormatter.Space();
PrimitiveExpression pe = forNextStatement.Step as PrimitiveExpression;
if ((pe == null || !(pe.Value is int) || ((int)pe.Value) >= 0)
@ -1661,7 +1668,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1661,7 +1668,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
TrackVisit(forNextStatement.End, data);
outputFormatter.PrintToken(Tokens.Semicolon);
outputFormatter.Space();
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
if (forNextStatement.LoopVariableExpression.IsNull)
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
else
TrackVisit(forNextStatement.LoopVariableExpression, data);
if (forNextStatement.Step.IsNull) {
outputFormatter.PrintToken(Tokens.Increment);
} else {

18
src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs

@ -1943,13 +1943,17 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1943,13 +1943,17 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.PrintToken(Tokens.For);
outputFormatter.Space();
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
if (!forNextStatement.TypeReference.IsNull) {
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.As);
outputFormatter.Space();
TrackedVisit(forNextStatement.TypeReference, data);
if (!forNextStatement.LoopVariableExpression.IsNull) {
TrackedVisit(forNextStatement.LoopVariableExpression, data);
} else {
outputFormatter.PrintIdentifier(forNextStatement.VariableName);
if (!forNextStatement.TypeReference.IsNull) {
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.As);
outputFormatter.Space();
TrackedVisit(forNextStatement.TypeReference, data);
}
}
outputFormatter.Space();

10
src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:2.0.50727.3053
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
@ -458,6 +458,7 @@ namespace ICSharpCode.NRefactory.Visitors { @@ -458,6 +458,7 @@ namespace ICSharpCode.NRefactory.Visitors {
Debug.Assert((forNextStatement.Step != null));
Debug.Assert((forNextStatement.NextExpressions != null));
Debug.Assert((forNextStatement.TypeReference != null));
Debug.Assert((forNextStatement.LoopVariableExpression != null));
Debug.Assert((forNextStatement.EmbeddedStatement != null));
forNextStatement.Start.AcceptVisitor(this, data);
forNextStatement.End.AcceptVisitor(this, data);
@ -467,6 +468,7 @@ namespace ICSharpCode.NRefactory.Visitors { @@ -467,6 +468,7 @@ namespace ICSharpCode.NRefactory.Visitors {
o.AcceptVisitor(this, data);
}
forNextStatement.TypeReference.AcceptVisitor(this, data);
forNextStatement.LoopVariableExpression.AcceptVisitor(this, data);
return forNextStatement.EmbeddedStatement.AcceptVisitor(this, data);
}

12
src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:2.0.50727.3053
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
@ -819,6 +819,7 @@ namespace ICSharpCode.NRefactory.Visitors { @@ -819,6 +819,7 @@ namespace ICSharpCode.NRefactory.Visitors {
Debug.Assert((forNextStatement.Step != null));
Debug.Assert((forNextStatement.NextExpressions != null));
Debug.Assert((forNextStatement.TypeReference != null));
Debug.Assert((forNextStatement.LoopVariableExpression != null));
Debug.Assert((forNextStatement.EmbeddedStatement != null));
nodeStack.Push(forNextStatement.Start);
forNextStatement.Start.AcceptVisitor(this, data);
@ -843,6 +844,9 @@ namespace ICSharpCode.NRefactory.Visitors { @@ -843,6 +844,9 @@ namespace ICSharpCode.NRefactory.Visitors {
nodeStack.Push(forNextStatement.TypeReference);
forNextStatement.TypeReference.AcceptVisitor(this, data);
forNextStatement.TypeReference = ((TypeReference)(nodeStack.Pop()));
nodeStack.Push(forNextStatement.LoopVariableExpression);
forNextStatement.LoopVariableExpression.AcceptVisitor(this, data);
forNextStatement.LoopVariableExpression = ((Expression)(nodeStack.Pop()));
nodeStack.Push(forNextStatement.EmbeddedStatement);
forNextStatement.EmbeddedStatement.AcceptVisitor(this, data);
forNextStatement.EmbeddedStatement = ((Statement)(nodeStack.Pop()));

13
src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs

@ -203,10 +203,15 @@ namespace ICSharpCode.NRefactory.Visitors @@ -203,10 +203,15 @@ namespace ICSharpCode.NRefactory.Visitors
start = assign.Right;
}
ReplaceCurrentNode(new ForNextStatement(typeReference, iteratorIdentifier.Identifier,
start, end,
(step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)),
forStatement.EmbeddedStatement, null));
ReplaceCurrentNode(
new ForNextStatement {
TypeReference = typeReference,
VariableName = iteratorIdentifier.Identifier,
Start = start,
End = end,
Step = (step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)),
EmbeddedStatement = forStatement.EmbeddedStatement
});
}
public override object VisitCastExpression(CastExpression castExpression, object data)

10
src/Libraries/NRefactory/Project/Src/Visitors/LookupTableVisitor.cs

@ -188,12 +188,20 @@ namespace ICSharpCode.NRefactory.Visitors @@ -188,12 +188,20 @@ namespace ICSharpCode.NRefactory.Visitors
public override object VisitForNextStatement(ForNextStatement forNextStatement, object data)
{
// uses LocalVariableDeclaration, we just have to put the end location on the stack
if (forNextStatement.EmbeddedStatement.EndLocation.IsEmpty) {
return base.VisitForNextStatement(forNextStatement, data);
} else {
endLocationStack.Push(forNextStatement.EmbeddedStatement.EndLocation);
AddVariable(forNextStatement.TypeReference,
forNextStatement.VariableName,
forNextStatement.StartLocation,
forNextStatement.EndLocation,
false, false,
forNextStatement.Start,
null);
base.VisitForNextStatement(forNextStatement, data);
endLocationStack.Pop();
return null;
}

8
src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs

@ -1,10 +1,10 @@ @@ -1,10 +1,10 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:2.0.50727.3053
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

6
src/Libraries/NRefactory/Test/Output/CSharp/VBNetToCSharpConverterTest.cs

@ -685,5 +685,11 @@ static int static_Test2_j = 0;"); @@ -685,5 +685,11 @@ static int static_Test2_j = 0;");
TestStatement("Dim x As Char", "char x = '\\0';");
TestStatement("Dim x As System.DateTime", "System.DateTime x = default(System.DateTime);");
}
[Test]
public void ExpressionAsLoopVariable()
{
TestStatement("For Me.Field = 1 To 10 : Next Me.Field", "for (this.Field = 1; this.Field <= 10; this.Field++) {\n}");
}
}
}

7
src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs

@ -385,6 +385,13 @@ End Using"); @@ -385,6 +385,13 @@ End Using");
TestStatement("Continue For");
}
[Test]
public void ForNextStatementWithFieldLoopVariable()
{
TestStatement("For Me.Field = 0 To 10\n" +
"Next Me.Field");
}
[Test]
public void WithStatement()
{

6
src/Libraries/NRefactory/Test/Parser/Statements/ForNextStatementTests.cs

@ -26,6 +26,12 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -26,6 +26,12 @@ namespace ICSharpCode.NRefactory.Tests.Ast
{
ForNextStatement forNextStatement = ParseUtilVBNet.ParseStatement<ForNextStatement>("For i=0 To 10 Step 2 : Next i");
}
[Test]
public void VBNetForNextStatementWithComplexExpressionTest()
{
ForNextStatement forNextStatement = ParseUtilVBNet.ParseStatement<ForNextStatement>("For SomeMethod().Property = 0 To 10 : Next SomeMethod().Property");
}
#endregion
}
}

Loading…
Cancel
Save