private void print(StatementNode statement, int indent, bool format, StringBuilder sb) { if (!format) { indent = 0; } var indentText = buildIndentText(indent); switch (statement.StatementKind) { case Empty: sb.append(indentText); sb.append(";\r\n"); break; case Block: var block = (BlockStatementNode)statement; sb.append("{"); if (format) { sb.append("\r\n"); } else { sb.append(" "); } foreach (var s in block.getStatements()) { print(s, indent + 1, format, sb); if (!format) { sb.append("; "); } } sb.append(indentText); sb.append("}"); if (format) { sb.append("\r\n"); } break; case Expression: var expression = (ExpressionStatementNode)statement; sb.append(indentText); print(expression.Expression, sb); if (format) { sb.append(";\r\n"); } break; case Return: var returnStatement = (ReturnStatementNode)statement; sb.append(indentText); sb.append("return"); if (returnStatement.Value != null) { sb.append(" "); print(returnStatement.Value, sb); } if (format) { sb.append(";\r\n"); } break; case Yield: var yieldStatement = (YieldStatementNode)statement; sb.append(indentText); sb.append("yield "); if (yieldStatement.Value == null) { sb.append("break"); } else { sb.append("return "); print(yieldStatement.Value, sb); } if (format) { sb.append(";\r\n"); } break; case LocalDeclaration: var local = (LocalDeclarationStatementNode)statement; sb.append(indentText); if (local.Type == null) { sb.append("var"); } else { print(local.Type, sb); } sb.append(" "); bool first = true; foreach (var decl in local.Declarators) { if (first) { first = false; } else { sb.append(", "); } sb.append(new String(text, decl.NameOffset, decl.NameLength)); if (decl.Value != null) { sb.append(" = "); print(decl.Value, sb); } } if (format) { sb.append(";\r\n"); } break; case If: var ifStatement = (IfStatementNode)statement; sb.append(indentText); sb.append("if ("); print(ifStatement.Condition, sb); sb.append(")"); if (ifStatement.IfTrue.StatementKind != StatementKind.Block) { sb.append("\r\n"); print(ifStatement.IfTrue, indent + 1, sb); } else { sb.append(" "); print(ifStatement.IfTrue, indent, sb); } if (ifStatement.IfFalse != null) { sb.append(indentText); sb.append("else"); if (ifStatement.IfFalse.StatementKind != StatementKind.Block) { sb.append("\r\n"); print(ifStatement.IfFalse, indent + 1, sb); } else { sb.append(" "); print(ifStatement.IfFalse, indent, sb); } } break; case Do: var doStatement = (DoStatementNode)statement; sb.append(indentText); sb.append("do"); if (doStatement.Statement.StatementKind != StatementKind.Block) { sb.append("\r\n"); print(doStatement.Statement, indent + 1, sb); } else { sb.append(" "); print(doStatement.Statement, indent, sb); } sb.append(indentText); sb.append("while("); print(doStatement.Condition, sb); sb.append(");\r\n"); break; case Break: sb.append(indentText); sb.append("break"); if (format) { sb.append(";\r\n"); } break; case Continue: sb.append(indentText); sb.append("continue"); if (format) { sb.append(";\r\n"); } break; case Throw: var throwStatement = (ThrowStatementNode)statement; sb.append(indentText); sb.append("throw"); if (throwStatement.Exception != null) { sb.append(" "); print(throwStatement.Exception, sb); } if (format) { sb.append(";\r\n"); } break; case While: var whileStatement = (WhileStatementNode)statement; sb.append(indentText); sb.append("while("); print(whileStatement.Condition, sb); sb.append(")"); if (whileStatement.Statement.StatementKind != StatementKind.Block) { sb.append("\r\n"); print(whileStatement.Statement, indent + 1, sb); } else { sb.append(" "); print(whileStatement.Statement, indent, sb); } break; case Foreach: var foreachStatement = (ForeachStatementNode)statement; sb.append(indentText); sb.append("foreach ("); if (foreachStatement.Type != null) { print(foreachStatement.Type, sb); sb.append(" "); } else { sb.append("var "); } sb.append(new String(text, foreachStatement.NameOffset, foreachStatement.NameLength)); sb.append(" in "); print(foreachStatement.Source, sb); sb.append(")"); if (foreachStatement.Statement.StatementKind != StatementKind.Block) { sb.append("\r\n"); print(foreachStatement.Statement, indent + 1, sb); } else { sb.append(" "); print(foreachStatement.Statement, indent, sb); } break; case For: var forStatement = (ForStatementNode)statement; sb.append(indentText); sb.append("for ("); foreach (var init in forStatement.Initializer) { print(init, 0, false, sb); } sb.append("; "); if (forStatement.Condition != null) { print(forStatement.Condition, sb); } sb.append("; "); foreach (var iter in forStatement.Iterator) { print(iter, 0, false, sb); } sb.append(")"); if (forStatement.Statement.StatementKind != StatementKind.Block) { sb.append("\r\n"); print(forStatement.Statement, indent + 1, sb); } else { sb.append(" "); print(forStatement.Statement, indent, sb); } break; default: throw new RuntimeException("Statement not supported: " + statement.StatementKind); } }
private String statementToString(StatementNode statement) { var sb = new StringBuilder(); switch (statement.StatementKind) { case Empty: sb.append("#empty;\r\n"); break; case Expression: var expression = (ExpressionStatementNode)statement; sb.append(expressionToString(expression.Expression)); sb.append(";\r\n"); break; case Block: var block = (BlockStatementNode)statement; sb.append("{\r\n"); foreach (var s in block.Statements) { sb.append(statementToString(s)); } sb.append("}\r\n"); break; case LocalDeclaration: var locals = (LocalDeclarationStatementNode)statement; if (locals.Type == null) { sb.append("var "); } else { sb.append(typeReferenceToString(locals.Type)); sb.append(" "); } var first = true; foreach (var d in locals.Declarators) { if (first) { first = false; } else { sb.append(", "); } sb.append(new String(text, d.NameOffset, d.NameLength)); if (d.Value != null) { sb.append(" = "); sb.append(expressionToString(d.Value)); } } sb.append(";\r\n"); break; case Return: var rt = (ReturnStatementNode)statement; sb.append("return"); if (rt.Value != null) { sb.append("("); sb.append(expressionToString(rt.Value)); sb.append(")"); } sb.append(";\r\n"); break; case If: var ifStatement = (IfStatementNode)statement; sb.append("if ("); sb.append(expressionToString(ifStatement.Condition)); sb.append(")\r\n"); sb.append(statementToString(ifStatement.IfTrue)); if (ifStatement.IfFalse != null) { sb.append("else\r\n"); sb.append(statementToString(ifStatement.IfFalse)); } break; case While: var whileStatement = (WhileStatementNode)statement; sb.append("while ("); sb.append(expressionToString(whileStatement.Condition)); sb.append(")\r\n"); sb.append(statementToString(whileStatement.Statement)); break; case Do: var doStatement = (DoStatementNode)statement; sb.append("do "); sb.append(statementToString(doStatement.Statement)); sb.append("while ("); sb.append(expressionToString(doStatement.Condition)); sb.append(");\r\n"); break; case For: var forStatement = (ForStatementNode)statement; sb.append("for ("); foreach (var init in forStatement.Initializer) { sb.append(statementToString(init)); } sb.append("Condition("); if (forStatement.Condition != null) { sb.append(expressionToString(forStatement.Condition)); } sb.append(");\r\n"); foreach (var iter in forStatement.Iterator) { sb.append(statementToString(iter)); } sb.append(")\r\n"); sb.append(statementToString(forStatement.Statement)); break; case Try: var tryStatement = (TryStatementNode)statement; sb.append("try "); sb.append(statementToString(tryStatement.Block)); foreach (var cc in tryStatement.CatchClauses) { sb.append("catch "); if (cc.ExceptionType != null) { sb.append("("); sb.append(typeReferenceToString(cc.ExceptionType)); if (cc.NameLength > 0) { sb.append(" "); sb.append(new String(text, cc.NameOffset, cc.NameLength)); } sb.append(") "); } sb.append(statementToString(cc.Block)); } if (tryStatement.Finally != null) { sb.append("finally "); sb.append(statementToString(tryStatement.Finally)); } break; case Switch: var switchStatement = (SwitchStatementNode)statement; sb.append("switch ("); sb.append(expressionToString(switchStatement.Selector)); sb.append(") {\r\n"); foreach (var ss in switchStatement.Sections) { if (ss.CaseExpression != null) { sb.append("case "); sb.append(expressionToString(ss.CaseExpression)); sb.append(":\r\n"); } else { sb.append("default:\r\n"); } foreach (var s in ss.Statements) { sb.append(statementToString(s)); } } sb.append("}\r\n"); break; case Foreach: var foreachStatement = (ForeachStatementNode)statement; sb.append("foreach ("); if (foreachStatement.Type != null) { sb.append(typeReferenceToString(foreachStatement.Type)); sb.append(" "); } else { sb.append("var "); } sb.append(new String(text, foreachStatement.NameOffset, foreachStatement.NameLength)); sb.append(" in "); sb.append(expressionToString(foreachStatement.Source)); sb.append(") "); sb.append(statementToString(foreachStatement.Statement)); break; case Break: sb.append("break;\r\n"); break; case Continue: sb.append("continue;\r\n"); break; case GotoCase: var gotoCaseStatememt = (GotoCaseStatementNode)statement; sb.append("goto "); if (gotoCaseStatememt.Expression != null) { sb.append("case "); sb.append(expressionToString(gotoCaseStatememt.Expression)); } else { sb.append("default"); } sb.append(";\r\n"); break; case Using: var usingStatement = (UsingStatementNode)statement; sb.append("using ("); sb.append(statementToString(usingStatement.ResourceAcquisition)); sb.append(") "); sb.append(statementToString(usingStatement.Statement)); break; case Synchronized: var lockStatement = (SynchronizedStatementNode)statement; sb.append("synchronized ("); sb.append(expressionToString(lockStatement.Lock)); sb.append(") "); sb.append(statementToString(lockStatement.Statement)); break; case Goto: var gotoStatememt = (GotoStatementNode)statement; sb.append("goto "); sb.append(new String(text, gotoStatememt.LabelOffset, gotoStatememt.LabelLength)); sb.append(";\r\n"); break; case Labeled: var label = (LabeledStatementNode)statement; sb.append(new String(text, label.NameOffset, label.NameLength)); sb.append(": "); sb.append(statementToString(label.Statement)); sb.append(";\r\n"); break; default: throw new RuntimeException("Unhandled statement: " + statement.StatementKind); } return sb.toString(); }
private void print(StatementNode s, int indent, StringBuilder sb) { print(s, indent, true, sb); }