Browse Source

implement conversion of switch to Select Case

pull/254/head
Siegfried Pammer 14 years ago
parent
commit
45999f4358
  1. 102
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs
  2. 26
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs
  3. 25
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs
  4. 4
      NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs
  5. 82
      NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs
  6. 114
      NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

102
NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/SelectStatement.cs

@ -32,14 +32,116 @@ namespace ICSharpCode.NRefactory.VB.Ast
{ {
public static readonly Role<CaseStatement> CaseStatementRole = new Role<CaseStatement>("CaseStatement"); public static readonly Role<CaseStatement> CaseStatementRole = new Role<CaseStatement>("CaseStatement");
public AstNodeCollection<CaseClause> Clauses {
get { return GetChildrenByRole(CaseClause.CaseClauseRole); }
}
public BlockStatement Body {
get { return GetChildByRole(Roles.Body); }
set { SetChildByRole(Roles.Body, value); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitCaseStatement(this, data);
}
}
public abstract class CaseClause : AstNode
{
#region Null
public new static readonly CaseClause Null = new NullCaseClause();
sealed class NullCaseClause : CaseClause
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
public static readonly Role<CaseClause> CaseClauseRole = new Role<CaseClause>("CaseClause", CaseClause.Null);
public Expression Expression {
get { return GetChildByRole(Roles.Expression); }
set { SetChildByRole(Roles.Expression, value); }
}
}
public class SimpleCaseClause : CaseClause
{
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitSimpleCaseClause(this, data);
}
}
public class RangeCaseClause : CaseClause
{
public static readonly Role<Expression> ToExpressionRole = ForStatement.ToExpressionRole;
public Expression ToExpression {
get { return GetChildByRole(ToExpressionRole); }
set { SetChildByRole(ToExpressionRole, value); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
throw new NotImplementedException();
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitRangeCaseClause(this, data);
}
}
public class ComparisonCaseClause : CaseClause
{
public static readonly Role<VBTokenNode> OperatorRole = BinaryOperatorExpression.OperatorRole;
public ComparisonOperator Operator { get; set; }
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
throw new NotImplementedException();
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitComparisonCaseClause(this, data);
}
}
public enum ComparisonOperator
{
Equality = BinaryOperatorType.Equality,
InEquality = BinaryOperatorType.InEquality,
LessThan = BinaryOperatorType.LessThan,
GreaterThan = BinaryOperatorType.GreaterThan,
LessThanOrEqual = BinaryOperatorType.LessThanOrEqual,
GreaterThanOrEqual = BinaryOperatorType.GreaterThanOrEqual
} }
} }

26
NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs

@ -115,18 +115,18 @@ namespace ICSharpCode.NRefactory.VB.Ast
} }
// Make debugging easier by giving Statements a ToString() implementation // Make debugging easier by giving Statements a ToString() implementation
public override string ToString() // public override string ToString()
{ // {
// if (IsNull) //// if (IsNull)
// return "Null"; //// return "Null";
// StringWriter w = new StringWriter(); //// StringWriter w = new StringWriter();
// AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null); //// AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null);
// string text = w.ToString().TrimEnd().Replace("\t", "").Replace(w.NewLine, " "); //// string text = w.ToString().TrimEnd().Replace("\t", "").Replace(w.NewLine, " ");
// if (text.Length > 100) //// if (text.Length > 100)
// return text.Substring(0, 97) + "..."; //// return text.Substring(0, 97) + "...";
// else //// else
// return text; //// return text;
throw new NotImplementedException(); // throw new NotImplementedException();
} // }
} }
} }

25
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/FieldDeclaration.cs

@ -32,7 +32,30 @@ namespace ICSharpCode.NRefactory.VB.Ast
/// </remarks> /// </remarks>
public class VariableIdentifier : AstNode public class VariableIdentifier : AstNode
{ {
public static readonly Role<VariableIdentifier> VariableIdentifierRole = new Role<VariableIdentifier>("VariableIdentifier"); #region Null
public new static readonly VariableIdentifier Null = new NullVariableIdentifier();
sealed class NullVariableIdentifier : VariableIdentifier
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
public static readonly Role<VariableIdentifier> VariableIdentifierRole = new Role<VariableIdentifier>("VariableIdentifier", VariableIdentifier.Null);
public Identifier Name { public Identifier Name {
get { return GetChildByRole(Roles.Identifier); } get { return GetChildByRole(Roles.Identifier); }

4
NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs

@ -97,5 +97,9 @@ namespace ICSharpCode.NRefactory.VB {
S VisitSimpleType(SimpleType simpleType, T data); S VisitSimpleType(SimpleType simpleType, T data);
S VisitVariableInitializer(VariableInitializer variableInitializer, T data); S VisitVariableInitializer(VariableInitializer variableInitializer, T data);
S VisitRangeCaseClause(RangeCaseClause rangeCaseClause, T data);
S VisitComparisonCaseClause(ComparisonCaseClause comparisonCaseClause, T data);
S VisitSimpleCaseClause(SimpleCaseClause simpleCaseClause, T data);
S VisitCaseStatement(CaseStatement caseStatement, T data);
} }
} }

82
NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs

@ -2064,9 +2064,89 @@ namespace ICSharpCode.NRefactory.VB
public object VisitSelectStatement(SelectStatement selectStatement, object data) public object VisitSelectStatement(SelectStatement selectStatement, object data)
{ {
throw new NotImplementedException(); StartNode(selectStatement);
WriteKeyword("Select");
WriteKeyword("Case");
selectStatement.Expression.AcceptVisitor(this, data);
NewLine();
Indent();
foreach (CaseStatement stmt in selectStatement.Cases) {
stmt.AcceptVisitor(this, data);
}
Unindent();
WriteKeyword("End");
WriteKeyword("Select");
return EndNode(selectStatement);
} }
public object VisitCaseStatement(CaseStatement caseStatement, object data)
{
StartNode(caseStatement);
WriteKeyword("Case");
if (caseStatement.Clauses.Count == 1 && caseStatement.Clauses.First().Expression.IsNull)
WriteKeyword("Else");
else
WriteCommaSeparatedList(caseStatement.Clauses);
NewLine();
Indent();
caseStatement.Body.AcceptVisitor(this, data);
Unindent();
return EndNode(caseStatement);
}
public object VisitSimpleCaseClause(SimpleCaseClause simpleCaseClause, object data)
{
StartNode(simpleCaseClause);
simpleCaseClause.Expression.AcceptVisitor(this, data);
return EndNode(simpleCaseClause);
}
public object VisitRangeCaseClause(RangeCaseClause rangeCaseClause, object data)
{
StartNode(rangeCaseClause);
rangeCaseClause.Expression.AcceptVisitor(this, data);
WriteKeyword("To");
rangeCaseClause.ToExpression.AcceptVisitor(this, data);
return EndNode(rangeCaseClause);
}
public object VisitComparisonCaseClause(ComparisonCaseClause comparisonCaseClause, object data)
{
StartNode(comparisonCaseClause);
switch (comparisonCaseClause.Operator) {
case ComparisonOperator.Equality:
WriteToken("=", ComparisonCaseClause.OperatorRole);
break;
case ComparisonOperator.InEquality:
WriteToken("<>", ComparisonCaseClause.OperatorRole);
break;
case ComparisonOperator.LessThan:
WriteToken("<", ComparisonCaseClause.OperatorRole);
break;
case ComparisonOperator.GreaterThan:
WriteToken(">", ComparisonCaseClause.OperatorRole);
break;
case ComparisonOperator.LessThanOrEqual:
WriteToken("<=", ComparisonCaseClause.OperatorRole);
break;
case ComparisonOperator.GreaterThanOrEqual:
WriteToken(">=", ComparisonCaseClause.OperatorRole);
break;
default:
throw new Exception("Invalid value for ComparisonOperator");
}
Space();
comparisonCaseClause.Expression.AcceptVisitor(this, data);
return EndNode(comparisonCaseClause);
}
public object VisitYieldStatement(YieldStatement yieldStatement, object data) public object VisitYieldStatement(YieldStatement yieldStatement, object data)
{ {
StartNode(yieldStatement); StartNode(yieldStatement);

114
NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

@ -77,6 +77,7 @@ namespace ICSharpCode.NRefactory.VB.Visitors
{ {
var left = (Expression)assignmentExpression.Left.AcceptVisitor(this, data); var left = (Expression)assignmentExpression.Left.AcceptVisitor(this, data);
var op = AssignmentOperatorType.None; var op = AssignmentOperatorType.None;
var right = (Expression)assignmentExpression.Right.AcceptVisitor(this, data);
switch (assignmentExpression.Operator) { switch (assignmentExpression.Operator) {
case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Assign: case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Assign:
@ -88,36 +89,38 @@ namespace ICSharpCode.NRefactory.VB.Visitors
case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Subtract: case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Subtract:
op = AssignmentOperatorType.Subtract; op = AssignmentOperatorType.Subtract;
break; break;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Multiply: case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Multiply:
// op = AssignmentOperatorType.Multiply;
// break; break;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Divide: case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Divide:
// op = AssignmentOperatorType.Divide;
// break; break;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Modulus: case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.Modulus:
// op = AssignmentOperatorType.Assign;
// break; right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.Modulus, right);
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftLeft: break;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftLeft:
// break; op = AssignmentOperatorType.ShiftLeft;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftRight: break;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ShiftRight:
// break; op = AssignmentOperatorType.ShiftRight;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseAnd: break;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseAnd:
// break; op = AssignmentOperatorType.Assign;
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseOr: right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.BitwiseAnd, right);
// break;
// break; case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.BitwiseOr:
// case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ExclusiveOr: op = AssignmentOperatorType.Assign;
// right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.BitwiseOr, right);
// break; break;
case ICSharpCode.NRefactory.CSharp.AssignmentOperatorType.ExclusiveOr:
op = AssignmentOperatorType.Assign;
right = new BinaryOperatorExpression((Expression)left.Clone(), BinaryOperatorType.ExclusiveOr, right);
break;
default: default:
throw new Exception("Invalid value for AssignmentOperatorType: " + assignmentExpression.Operator); throw new Exception("Invalid value for AssignmentOperatorType: " + assignmentExpression.Operator);
} }
var right = (Expression)assignmentExpression.Right.AcceptVisitor(this, data);
var expr = new AssignmentExpression(left, op, right); var expr = new AssignmentExpression(left, op, right);
return EndNode(assignmentExpression, expr); return EndNode(assignmentExpression, expr);
} }
@ -222,10 +225,38 @@ namespace ICSharpCode.NRefactory.VB.Visitors
return CastType.CType; return CastType.CType;
switch (primType.Keyword) { switch (primType.Keyword) {
case "Boolean":
return CastType.CBool;
case "Byte":
return CastType.CByte;
case "Char":
return CastType.CChar;
case "Date":
return CastType.CDate;
case "Double":
return CastType.CDbl;
case "Decimal":
return CastType.CDec;
case "Integer": case "Integer":
return CastType.CInt; return CastType.CInt;
case "Long":
return CastType.CLng;
case "Object":
return CastType.CObj;
case "SByte":
return CastType.CSByte;
case "Short":
return CastType.CShort;
case "Single":
return CastType.CSng;
case "String": case "String":
return CastType.CStr; return CastType.CStr;
case "UInteger":
return CastType.CUInt;
case "ULong":
return CastType.CULng;
case "UShort":
return CastType.CUShort;
} }
return CastType.CType; return CastType.CType;
@ -367,8 +398,8 @@ namespace ICSharpCode.NRefactory.VB.Visitors
{ {
Expression expr; Expression expr;
if (primitiveExpression.Value is string && ((string)primitiveExpression.Value).IndexOfAny(new[] {'\r', '\n'}) > -1) if ((primitiveExpression.Value is string || primitiveExpression.Value is char) && primitiveExpression.Value.ToString().IndexOfAny(new[] {'\r', '\n'}) > -1)
expr = ConvertToConcat((string)primitiveExpression.Value); expr = ConvertToConcat(primitiveExpression.Value.ToString());
else else
expr = new PrimitiveExpression(primitiveExpression.Value); expr = new PrimitiveExpression(primitiveExpression.Value);
@ -383,6 +414,7 @@ namespace ICSharpCode.NRefactory.VB.Visitors
for (int i = 0; i < literal.Length; i++) { for (int i = 0; i < literal.Length; i++) {
if (literal[i] == '\r') { if (literal[i] == '\r') {
string part = literal.Substring(start, i - start); string part = literal.Substring(start, i - start);
if (!string.IsNullOrEmpty(part))
parts.Push(new PrimitiveExpression(part)); parts.Push(new PrimitiveExpression(part));
if (i + 1 < literal.Length && literal[i + 1] == '\n') { if (i + 1 < literal.Length && literal[i + 1] == '\n') {
i++; i++;
@ -392,9 +424,16 @@ namespace ICSharpCode.NRefactory.VB.Visitors
start = i + 1; start = i + 1;
} else if (literal[i] == '\n') { } else if (literal[i] == '\n') {
string part = literal.Substring(start, i - start); string part = literal.Substring(start, i - start);
if (!string.IsNullOrEmpty(part))
parts.Push(new PrimitiveExpression(part)); parts.Push(new PrimitiveExpression(part));
parts.Push(new IdentifierExpression() { Identifier = "vbLf" }); parts.Push(new IdentifierExpression() { Identifier = "vbLf" });
start = i + 1; start = i + 1;
} else if (literal[i] == '\t') {
string part = literal.Substring(start, i - start);
if (!string.IsNullOrEmpty(part))
parts.Push(new PrimitiveExpression(part));
parts.Push(new IdentifierExpression() { Identifier = "vbTab" });
start = i + 1;
} }
} }
@ -850,17 +889,30 @@ namespace ICSharpCode.NRefactory.VB.Visitors
public AstNode VisitSwitchStatement(CSharp.SwitchStatement switchStatement, object data) public AstNode VisitSwitchStatement(CSharp.SwitchStatement switchStatement, object data)
{ {
throw new NotImplementedException(); var stmt = new SelectStatement() { Expression = (Expression)switchStatement.Expression.AcceptVisitor(this, data) };
ConvertNodes(switchStatement.SwitchSections, stmt.Cases);
return EndNode(switchStatement, stmt);
} }
public AstNode VisitSwitchSection(CSharp.SwitchSection switchSection, object data) public AstNode VisitSwitchSection(CSharp.SwitchSection switchSection, object data)
{ {
throw new NotImplementedException(); var caseStmt = new CaseStatement();
ConvertNodes(switchSection.CaseLabels, caseStmt.Clauses);
if (switchSection.Statements.Count == 1 && switchSection.Statements.FirstOrDefault() is CSharp.BlockStatement)
caseStmt.Body = (BlockStatement)switchSection.Statements.FirstOrDefault().AcceptVisitor(this, data);
else {
caseStmt.Body = new BlockStatement();
ConvertNodes(switchSection.Statements, caseStmt.Body.Statements);
}
if (caseStmt.Body.LastOrDefault() is ExitStatement && ((ExitStatement)caseStmt.Body.LastOrDefault()).ExitKind == ExitKind.Select)
caseStmt.Body.LastOrDefault().Remove();
return EndNode(switchSection, caseStmt);
} }
public AstNode VisitCaseLabel(CSharp.CaseLabel caseLabel, object data) public AstNode VisitCaseLabel(CSharp.CaseLabel caseLabel, object data)
{ {
throw new NotImplementedException(); return EndNode(caseLabel, new SimpleCaseClause() { Expression = (Expression)caseLabel.Expression.AcceptVisitor(this, data) });
} }
public AstNode VisitThrowStatement(CSharp.ThrowStatement throwStatement, object data) public AstNode VisitThrowStatement(CSharp.ThrowStatement throwStatement, object data)

Loading…
Cancel
Save