blob: 583117e03aa617a01de62826c172bd42ccbb5042 [file] [log] [blame]
/*
* Copyright (c) 2012, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.engine.ast.visitor;
import com.google.dart.engine.ast.*;
import com.google.dart.engine.scanner.Token;
import com.google.dart.engine.utilities.dart.ParameterKind;
import java.io.PrintWriter;
/**
* Instances of the class {@code ToSourceVisitor} write a source representation of a visited AST
* node (and all of it's children) to a writer.
*
* @coverage dart.engine.ast
*/
public class ToSourceVisitor implements AstVisitor<Void> {
/**
* The writer to which the source is to be written.
*/
private PrintWriter writer;
/**
* Initialize a newly created visitor to write source code representing the visited nodes to the
* given writer.
*
* @param writer the writer to which the source is to be written
*/
public ToSourceVisitor(PrintWriter writer) {
this.writer = writer;
}
@Override
public Void visitAdjacentStrings(AdjacentStrings node) {
visitNodeListWithSeparator(node.getStrings(), " ");
return null;
}
@Override
public Void visitAnnotation(Annotation node) {
writer.print('@');
visitNode(node.getName());
visitNodeWithPrefix(".", node.getConstructorName());
visitNode(node.getArguments());
return null;
}
@Override
public Void visitArgumentList(ArgumentList node) {
writer.print('(');
visitNodeListWithSeparator(node.getArguments(), ", ");
writer.print(')');
return null;
}
@Override
public Void visitAsExpression(AsExpression node) {
visitNode(node.getExpression());
writer.print(" as ");
visitNode(node.getType());
return null;
}
@Override
public Void visitAssertStatement(AssertStatement node) {
writer.print("assert (");
visitNode(node.getCondition());
writer.print(");");
return null;
}
@Override
public Void visitAssignmentExpression(AssignmentExpression node) {
visitNode(node.getLeftHandSide());
writer.print(' ');
writer.print(node.getOperator().getLexeme());
writer.print(' ');
visitNode(node.getRightHandSide());
return null;
}
@Override
public Void visitAwaitExpression(AwaitExpression node) {
writer.print("await ");
visitNode(node.getExpression());
writer.print(";"); // TODO (brianwilkerson) This line probably needs to be removed.
return null;
}
@Override
public Void visitBinaryExpression(BinaryExpression node) {
visitNode(node.getLeftOperand());
writer.print(' ');
writer.print(node.getOperator().getLexeme());
writer.print(' ');
visitNode(node.getRightOperand());
return null;
}
@Override
public Void visitBlock(Block node) {
writer.print('{');
visitNodeListWithSeparator(node.getStatements(), " ");
writer.print('}');
return null;
}
@Override
public Void visitBlockFunctionBody(BlockFunctionBody node) {
Token keyword = node.getKeyword();
if (keyword != null) {
writer.print(keyword.getLexeme());
if (node.getStar() != null) {
writer.print('*');
}
writer.print(' ');
}
visitNode(node.getBlock());
return null;
}
@Override
public Void visitBooleanLiteral(BooleanLiteral node) {
writer.print(node.getLiteral().getLexeme());
return null;
}
@Override
public Void visitBreakStatement(BreakStatement node) {
writer.print("break");
visitNodeWithPrefix(" ", node.getLabel());
writer.print(";");
return null;
}
@Override
public Void visitCascadeExpression(CascadeExpression node) {
visitNode(node.getTarget());
visitNodeList(node.getCascadeSections());
return null;
}
@Override
public Void visitCatchClause(CatchClause node) {
visitNodeWithPrefix("on ", node.getExceptionType());
if (node.getCatchKeyword() != null) {
if (node.getExceptionType() != null) {
writer.print(' ');
}
writer.print("catch (");
visitNode(node.getExceptionParameter());
visitNodeWithPrefix(", ", node.getStackTraceParameter());
writer.print(") ");
} else {
writer.print(" ");
}
visitNode(node.getBody());
return null;
}
@Override
public Void visitClassDeclaration(ClassDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitTokenWithSuffix(node.getAbstractKeyword(), " ");
writer.print("class ");
visitNode(node.getName());
visitNode(node.getTypeParameters());
visitNodeWithPrefix(" ", node.getExtendsClause());
visitNodeWithPrefix(" ", node.getWithClause());
visitNodeWithPrefix(" ", node.getImplementsClause());
writer.print(" {");
visitNodeListWithSeparator(node.getMembers(), " ");
writer.print("}");
return null;
}
@Override
public Void visitClassTypeAlias(ClassTypeAlias node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
if (node.getAbstractKeyword() != null) {
writer.print("abstract ");
}
writer.print("class ");
visitNode(node.getName());
visitNode(node.getTypeParameters());
writer.print(" = ");
visitNode(node.getSuperclass());
visitNodeWithPrefix(" ", node.getWithClause());
visitNodeWithPrefix(" ", node.getImplementsClause());
writer.print(";");
return null;
}
@Override
public Void visitComment(Comment node) {
// We don't print comments.
return null;
}
@Override
public Void visitCommentReference(CommentReference node) {
// We don't print comment references.
return null;
}
@Override
public Void visitCompilationUnit(CompilationUnit node) {
ScriptTag scriptTag = node.getScriptTag();
NodeList<Directive> directives = node.getDirectives();
visitNode(scriptTag);
String prefix = scriptTag == null ? "" : " ";
visitNodeListWithSeparatorAndPrefix(prefix, directives, " ");
prefix = scriptTag == null && directives.isEmpty() ? "" : " ";
visitNodeListWithSeparatorAndPrefix(prefix, node.getDeclarations(), " ");
return null;
}
@Override
public Void visitConditionalExpression(ConditionalExpression node) {
visitNode(node.getCondition());
writer.print(" ? ");
visitNode(node.getThenExpression());
writer.print(" : ");
visitNode(node.getElseExpression());
return null;
}
@Override
public Void visitConstructorDeclaration(ConstructorDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitTokenWithSuffix(node.getExternalKeyword(), " ");
visitTokenWithSuffix(node.getConstKeyword(), " ");
visitTokenWithSuffix(node.getFactoryKeyword(), " ");
visitNode(node.getReturnType());
visitNodeWithPrefix(".", node.getName());
visitNode(node.getParameters());
visitNodeListWithSeparatorAndPrefix(" : ", node.getInitializers(), ", ");
visitNodeWithPrefix(" = ", node.getRedirectedConstructor());
visitFunctionWithPrefix(" ", node.getBody());
return null;
}
@Override
public Void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
visitTokenWithSuffix(node.getKeyword(), ".");
visitNode(node.getFieldName());
writer.print(" = ");
visitNode(node.getExpression());
return null;
}
@Override
public Void visitConstructorName(ConstructorName node) {
visitNode(node.getType());
visitNodeWithPrefix(".", node.getName());
return null;
}
@Override
public Void visitContinueStatement(ContinueStatement node) {
writer.print("continue");
visitNodeWithPrefix(" ", node.getLabel());
writer.print(";");
return null;
}
@Override
public Void visitDeclaredIdentifier(DeclaredIdentifier node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitTokenWithSuffix(node.getKeyword(), " ");
visitNodeWithSuffix(node.getType(), " ");
visitNode(node.getIdentifier());
return null;
}
@Override
public Void visitDefaultFormalParameter(DefaultFormalParameter node) {
visitNode(node.getParameter());
if (node.getSeparator() != null) {
writer.print(" ");
writer.print(node.getSeparator().getLexeme());
visitNodeWithPrefix(" ", node.getDefaultValue());
}
return null;
}
@Override
public Void visitDoStatement(DoStatement node) {
writer.print("do ");
visitNode(node.getBody());
writer.print(" while (");
visitNode(node.getCondition());
writer.print(");");
return null;
}
@Override
public Void visitDoubleLiteral(DoubleLiteral node) {
writer.print(node.getLiteral().getLexeme());
return null;
}
@Override
public Void visitEmptyFunctionBody(EmptyFunctionBody node) {
writer.print(';');
return null;
}
@Override
public Void visitEmptyStatement(EmptyStatement node) {
writer.print(';');
return null;
}
@Override
public Void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitNode(node.getName());
return null;
}
@Override
public Void visitEnumDeclaration(EnumDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
writer.print("enum ");
visitNode(node.getName());
writer.print(" {");
visitNodeListWithSeparator(node.getConstants(), ", ");
writer.print("}");
return null;
}
@Override
public Void visitExportDirective(ExportDirective node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
writer.print("export ");
visitNode(node.getUri());
visitNodeListWithSeparatorAndPrefix(" ", node.getCombinators(), " ");
writer.print(';');
return null;
}
@Override
public Void visitExpressionFunctionBody(ExpressionFunctionBody node) {
Token keyword = node.getKeyword();
if (keyword != null) {
writer.print(keyword.getLexeme());
writer.print(' ');
}
writer.print("=> ");
visitNode(node.getExpression());
if (node.getSemicolon() != null) {
writer.print(';');
}
return null;
}
@Override
public Void visitExpressionStatement(ExpressionStatement node) {
visitNode(node.getExpression());
writer.print(';');
return null;
}
@Override
public Void visitExtendsClause(ExtendsClause node) {
writer.print("extends ");
visitNode(node.getSuperclass());
return null;
}
@Override
public Void visitFieldDeclaration(FieldDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitTokenWithSuffix(node.getStaticKeyword(), " ");
visitNode(node.getFields());
writer.print(";");
return null;
}
@Override
public Void visitFieldFormalParameter(FieldFormalParameter node) {
visitTokenWithSuffix(node.getKeyword(), " ");
visitNodeWithSuffix(node.getType(), " ");
writer.print("this.");
visitNode(node.getIdentifier());
visitNode(node.getParameters());
return null;
}
@Override
public Void visitForEachStatement(ForEachStatement node) {
DeclaredIdentifier loopVariable = node.getLoopVariable();
if (node.getAwaitKeyword() != null) {
writer.print("await ");
}
writer.print("for (");
if (loopVariable == null) {
visitNode(node.getIdentifier());
} else {
visitNode(loopVariable);
}
writer.print(" in ");
visitNode(node.getIterator());
writer.print(") ");
visitNode(node.getBody());
return null;
}
@Override
public Void visitFormalParameterList(FormalParameterList node) {
String groupEnd = null;
writer.print('(');
NodeList<FormalParameter> parameters = node.getParameters();
int size = parameters.size();
for (int i = 0; i < size; i++) {
FormalParameter parameter = parameters.get(i);
if (i > 0) {
writer.print(", ");
}
if (groupEnd == null && parameter instanceof DefaultFormalParameter) {
if (parameter.getKind() == ParameterKind.NAMED) {
groupEnd = "}";
writer.print('{');
} else {
groupEnd = "]";
writer.print('[');
}
}
parameter.accept(this);
}
if (groupEnd != null) {
writer.print(groupEnd);
}
writer.print(')');
return null;
}
@Override
public Void visitForStatement(ForStatement node) {
Expression initialization = node.getInitialization();
writer.print("for (");
if (initialization != null) {
visitNode(initialization);
} else {
visitNode(node.getVariables());
}
writer.print(";");
visitNodeWithPrefix(" ", node.getCondition());
writer.print(";");
visitNodeListWithSeparatorAndPrefix(" ", node.getUpdaters(), ", ");
writer.print(") ");
visitNode(node.getBody());
return null;
}
@Override
public Void visitFunctionDeclaration(FunctionDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitNodeWithSuffix(node.getReturnType(), " ");
visitTokenWithSuffix(node.getPropertyKeyword(), " ");
visitNode(node.getName());
visitNode(node.getFunctionExpression());
return null;
}
@Override
public Void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
visitNode(node.getFunctionDeclaration());
return null;
}
@Override
public Void visitFunctionExpression(FunctionExpression node) {
visitNode(node.getParameters());
writer.print(' ');
visitNode(node.getBody());
return null;
}
@Override
public Void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
visitNode(node.getFunction());
visitNode(node.getArgumentList());
return null;
}
@Override
public Void visitFunctionTypeAlias(FunctionTypeAlias node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
writer.print("typedef ");
visitNodeWithSuffix(node.getReturnType(), " ");
visitNode(node.getName());
visitNode(node.getTypeParameters());
visitNode(node.getParameters());
writer.print(";");
return null;
}
@Override
public Void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
visitNodeWithSuffix(node.getReturnType(), " ");
visitNode(node.getIdentifier());
visitNode(node.getParameters());
return null;
}
@Override
public Void visitHideCombinator(HideCombinator node) {
writer.print("hide ");
visitNodeListWithSeparator(node.getHiddenNames(), ", ");
return null;
}
@Override
public Void visitIfStatement(IfStatement node) {
writer.print("if (");
visitNode(node.getCondition());
writer.print(") ");
visitNode(node.getThenStatement());
visitNodeWithPrefix(" else ", node.getElseStatement());
return null;
}
@Override
public Void visitImplementsClause(ImplementsClause node) {
writer.print("implements ");
visitNodeListWithSeparator(node.getInterfaces(), ", ");
return null;
}
@Override
public Void visitImportDirective(ImportDirective node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
writer.print("import ");
visitNode(node.getUri());
if (node.getDeferredToken() != null) {
writer.print(" deferred");
}
visitNodeWithPrefix(" as ", node.getPrefix());
visitNodeListWithSeparatorAndPrefix(" ", node.getCombinators(), " ");
writer.print(';');
return null;
}
@Override
public Void visitIndexExpression(IndexExpression node) {
if (node.isCascaded()) {
writer.print("..");
} else {
visitNode(node.getTarget());
}
writer.print('[');
visitNode(node.getIndex());
writer.print(']');
return null;
}
@Override
public Void visitInstanceCreationExpression(InstanceCreationExpression node) {
visitTokenWithSuffix(node.getKeyword(), " ");
visitNode(node.getConstructorName());
visitNode(node.getArgumentList());
return null;
}
@Override
public Void visitIntegerLiteral(IntegerLiteral node) {
writer.print(node.getLiteral().getLexeme());
return null;
}
@Override
public Void visitInterpolationExpression(InterpolationExpression node) {
if (node.getRightBracket() != null) {
writer.print("${");
visitNode(node.getExpression());
writer.print("}");
} else {
writer.print("$");
visitNode(node.getExpression());
}
return null;
}
@Override
public Void visitInterpolationString(InterpolationString node) {
writer.print(node.getContents().getLexeme());
return null;
}
@Override
public Void visitIsExpression(IsExpression node) {
visitNode(node.getExpression());
if (node.getNotOperator() == null) {
writer.print(" is ");
} else {
writer.print(" is! ");
}
visitNode(node.getType());
return null;
}
@Override
public Void visitLabel(Label node) {
visitNode(node.getLabel());
writer.print(":");
return null;
}
@Override
public Void visitLabeledStatement(LabeledStatement node) {
visitNodeListWithSeparatorAndSuffix(node.getLabels(), " ", " ");
visitNode(node.getStatement());
return null;
}
@Override
public Void visitLibraryDirective(LibraryDirective node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
writer.print("library ");
visitNode(node.getName());
writer.print(';');
return null;
}
@Override
public Void visitLibraryIdentifier(LibraryIdentifier node) {
writer.print(node.getName());
return null;
}
@Override
public Void visitListLiteral(ListLiteral node) {
if (node.getConstKeyword() != null) {
writer.print(node.getConstKeyword().getLexeme());
writer.print(' ');
}
visitNodeWithSuffix(node.getTypeArguments(), " ");
writer.print("[");
visitNodeListWithSeparator(node.getElements(), ", ");
writer.print("]");
return null;
}
@Override
public Void visitMapLiteral(MapLiteral node) {
if (node.getConstKeyword() != null) {
writer.print(node.getConstKeyword().getLexeme());
writer.print(' ');
}
visitNodeWithSuffix(node.getTypeArguments(), " ");
writer.print("{");
visitNodeListWithSeparator(node.getEntries(), ", ");
writer.print("}");
return null;
}
@Override
public Void visitMapLiteralEntry(MapLiteralEntry node) {
visitNode(node.getKey());
writer.print(" : ");
visitNode(node.getValue());
return null;
}
@Override
public Void visitMethodDeclaration(MethodDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitTokenWithSuffix(node.getExternalKeyword(), " ");
visitTokenWithSuffix(node.getModifierKeyword(), " ");
visitNodeWithSuffix(node.getReturnType(), " ");
visitTokenWithSuffix(node.getPropertyKeyword(), " ");
visitTokenWithSuffix(node.getOperatorKeyword(), " ");
visitNode(node.getName());
if (!node.isGetter()) {
visitNode(node.getParameters());
}
visitFunctionWithPrefix(" ", node.getBody());
return null;
}
@Override
public Void visitMethodInvocation(MethodInvocation node) {
if (node.isCascaded()) {
writer.print("..");
} else {
visitNodeWithSuffix(node.getTarget(), ".");
}
visitNode(node.getMethodName());
visitNode(node.getArgumentList());
return null;
}
@Override
public Void visitNamedExpression(NamedExpression node) {
visitNode(node.getName());
visitNodeWithPrefix(" ", node.getExpression());
return null;
}
@Override
public Void visitNativeClause(NativeClause node) {
writer.print("native ");
visitNode(node.getName());
return null;
}
@Override
public Void visitNativeFunctionBody(NativeFunctionBody node) {
writer.print("native ");
visitNode(node.getStringLiteral());
writer.print(';');
return null;
}
@Override
public Void visitNullLiteral(NullLiteral node) {
writer.print("null");
return null;
}
@Override
public Void visitParenthesizedExpression(ParenthesizedExpression node) {
writer.print('(');
visitNode(node.getExpression());
writer.print(')');
return null;
}
@Override
public Void visitPartDirective(PartDirective node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
writer.print("part ");
visitNode(node.getUri());
writer.print(';');
return null;
}
@Override
public Void visitPartOfDirective(PartOfDirective node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
writer.print("part of ");
visitNode(node.getLibraryName());
writer.print(';');
return null;
}
@Override
public Void visitPostfixExpression(PostfixExpression node) {
visitNode(node.getOperand());
writer.print(node.getOperator().getLexeme());
return null;
}
@Override
public Void visitPrefixedIdentifier(PrefixedIdentifier node) {
visitNode(node.getPrefix());
writer.print('.');
visitNode(node.getIdentifier());
return null;
}
@Override
public Void visitPrefixExpression(PrefixExpression node) {
writer.print(node.getOperator().getLexeme());
visitNode(node.getOperand());
return null;
}
@Override
public Void visitPropertyAccess(PropertyAccess node) {
if (node.isCascaded()) {
writer.print("..");
} else {
visitNode(node.getTarget());
writer.print('.');
}
visitNode(node.getPropertyName());
return null;
}
@Override
public Void visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
writer.print("this");
visitNodeWithPrefix(".", node.getConstructorName());
visitNode(node.getArgumentList());
return null;
}
@Override
public Void visitRethrowExpression(RethrowExpression node) {
writer.print("rethrow");
return null;
}
@Override
public Void visitReturnStatement(ReturnStatement node) {
Expression expression = node.getExpression();
if (expression == null) {
writer.print("return;");
} else {
writer.print("return ");
expression.accept(this);
writer.print(";");
}
return null;
}
@Override
public Void visitScriptTag(ScriptTag node) {
writer.print(node.getScriptTag().getLexeme());
return null;
}
@Override
public Void visitShowCombinator(ShowCombinator node) {
writer.print("show ");
visitNodeListWithSeparator(node.getShownNames(), ", ");
return null;
}
@Override
public Void visitSimpleFormalParameter(SimpleFormalParameter node) {
visitTokenWithSuffix(node.getKeyword(), " ");
visitNodeWithSuffix(node.getType(), " ");
visitNode(node.getIdentifier());
return null;
}
@Override
public Void visitSimpleIdentifier(SimpleIdentifier node) {
writer.print(node.getToken().getLexeme());
return null;
}
@Override
public Void visitSimpleStringLiteral(SimpleStringLiteral node) {
writer.print(node.getLiteral().getLexeme());
return null;
}
@Override
public Void visitStringInterpolation(StringInterpolation node) {
visitNodeList(node.getElements());
return null;
}
@Override
public Void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
writer.print("super");
visitNodeWithPrefix(".", node.getConstructorName());
visitNode(node.getArgumentList());
return null;
}
@Override
public Void visitSuperExpression(SuperExpression node) {
writer.print("super");
return null;
}
@Override
public Void visitSwitchCase(SwitchCase node) {
visitNodeListWithSeparatorAndSuffix(node.getLabels(), " ", " ");
writer.print("case ");
visitNode(node.getExpression());
writer.print(": ");
visitNodeListWithSeparator(node.getStatements(), " ");
return null;
}
@Override
public Void visitSwitchDefault(SwitchDefault node) {
visitNodeListWithSeparatorAndSuffix(node.getLabels(), " ", " ");
writer.print("default: ");
visitNodeListWithSeparator(node.getStatements(), " ");
return null;
}
@Override
public Void visitSwitchStatement(SwitchStatement node) {
writer.print("switch (");
visitNode(node.getExpression());
writer.print(") {");
visitNodeListWithSeparator(node.getMembers(), " ");
writer.print("}");
return null;
}
@Override
public Void visitSymbolLiteral(SymbolLiteral node) {
writer.print("#");
Token[] components = node.getComponents();
for (int i = 0; i < components.length; i++) {
if (i > 0) {
writer.print(".");
}
writer.print(components[i].getLexeme());
}
return null;
}
@Override
public Void visitThisExpression(ThisExpression node) {
writer.print("this");
return null;
}
@Override
public Void visitThrowExpression(ThrowExpression node) {
writer.print("throw ");
visitNode(node.getExpression());
return null;
}
@Override
public Void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
visitNodeWithSuffix(node.getVariables(), ";");
return null;
}
@Override
public Void visitTryStatement(TryStatement node) {
writer.print("try ");
visitNode(node.getBody());
visitNodeListWithSeparatorAndPrefix(" ", node.getCatchClauses(), " ");
visitNodeWithPrefix(" finally ", node.getFinallyBlock());
return null;
}
@Override
public Void visitTypeArgumentList(TypeArgumentList node) {
writer.print('<');
visitNodeListWithSeparator(node.getArguments(), ", ");
writer.print('>');
return null;
}
@Override
public Void visitTypeName(TypeName node) {
visitNode(node.getName());
visitNode(node.getTypeArguments());
return null;
}
@Override
public Void visitTypeParameter(TypeParameter node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitNode(node.getName());
visitNodeWithPrefix(" extends ", node.getBound());
return null;
}
@Override
public Void visitTypeParameterList(TypeParameterList node) {
writer.print('<');
visitNodeListWithSeparator(node.getTypeParameters(), ", ");
writer.print('>');
return null;
}
@Override
public Void visitVariableDeclaration(VariableDeclaration node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitNode(node.getName());
visitNodeWithPrefix(" = ", node.getInitializer());
return null;
}
@Override
public Void visitVariableDeclarationList(VariableDeclarationList node) {
visitNodeListWithSeparatorAndSuffix(node.getMetadata(), " ", " ");
visitTokenWithSuffix(node.getKeyword(), " ");
visitNodeWithSuffix(node.getType(), " ");
visitNodeListWithSeparator(node.getVariables(), ", ");
return null;
}
@Override
public Void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
visitNode(node.getVariables());
writer.print(";");
return null;
}
@Override
public Void visitWhileStatement(WhileStatement node) {
writer.print("while (");
visitNode(node.getCondition());
writer.print(") ");
visitNode(node.getBody());
return null;
}
@Override
public Void visitWithClause(WithClause node) {
writer.print("with ");
visitNodeListWithSeparator(node.getMixinTypes(), ", ");
return null;
}
@Override
public Void visitYieldStatement(YieldStatement node) {
if (node.getStar() != null) {
writer.print("yield* ");
} else {
writer.print("yield ");
}
visitNode(node.getExpression());
writer.print(";");
return null;
}
/**
* Visit the given function body, printing the prefix before if given body is not empty.
*
* @param prefix the prefix to be printed if there is a node to visit
* @param body the function body to be visited
*/
private void visitFunctionWithPrefix(String prefix, FunctionBody body) {
if (!(body instanceof EmptyFunctionBody)) {
writer.print(prefix);
}
visitNode(body);
}
/**
* Safely visit the given node.
*
* @param node the node to be visited
*/
private void visitNode(AstNode node) {
if (node != null) {
node.accept(this);
}
}
/**
* Print a list of nodes without any separation.
*
* @param nodes the nodes to be printed
* @param separator the separator to be printed between adjacent nodes
*/
private void visitNodeList(NodeList<? extends AstNode> nodes) {
visitNodeListWithSeparator(nodes, "");
}
/**
* Print a list of nodes, separated by the given separator.
*
* @param nodes the nodes to be printed
* @param separator the separator to be printed between adjacent nodes
*/
private void visitNodeListWithSeparator(NodeList<? extends AstNode> nodes, String separator) {
if (nodes != null) {
int size = nodes.size();
for (int i = 0; i < size; i++) {
if (i > 0) {
writer.print(separator);
}
nodes.get(i).accept(this);
}
}
}
/**
* Print a list of nodes, separated by the given separator.
*
* @param prefix the prefix to be printed if the list is not empty
* @param nodes the nodes to be printed
* @param separator the separator to be printed between adjacent nodes
*/
private void visitNodeListWithSeparatorAndPrefix(String prefix,
NodeList<? extends AstNode> nodes, String separator) {
if (nodes != null) {
int size = nodes.size();
if (size > 0) {
writer.print(prefix);
for (int i = 0; i < size; i++) {
if (i > 0) {
writer.print(separator);
}
nodes.get(i).accept(this);
}
}
}
}
/**
* Print a list of nodes, separated by the given separator.
*
* @param nodes the nodes to be printed
* @param separator the separator to be printed between adjacent nodes
* @param suffix the suffix to be printed if the list is not empty
*/
private void visitNodeListWithSeparatorAndSuffix(NodeList<? extends AstNode> nodes,
String separator, String suffix) {
if (nodes != null) {
int size = nodes.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
if (i > 0) {
writer.print(separator);
}
nodes.get(i).accept(this);
}
writer.print(suffix);
}
}
}
/**
* Safely visit the given node, printing the prefix before the node if it is non-{@code null}.
*
* @param prefix the prefix to be printed if there is a node to visit
* @param node the node to be visited
*/
private void visitNodeWithPrefix(String prefix, AstNode node) {
if (node != null) {
writer.print(prefix);
node.accept(this);
}
}
/**
* Safely visit the given node, printing the suffix after the node if it is non-{@code null}.
*
* @param suffix the suffix to be printed if there is a node to visit
* @param node the node to be visited
*/
private void visitNodeWithSuffix(AstNode node, String suffix) {
if (node != null) {
node.accept(this);
writer.print(suffix);
}
}
/**
* Safely visit the given node, printing the suffix after the node if it is non-{@code null}.
*
* @param suffix the suffix to be printed if there is a node to visit
* @param node the node to be visited
*/
private void visitTokenWithSuffix(Token token, String suffix) {
if (token != null) {
writer.print(token.getLexeme());
writer.print(suffix);
}
}
}