bazel syntax: consolidate syntax printing
The complete algorithm is now in NodePrinter,
rather than spread over dozens of files.
The only public API is Node.prettyPrint.
There is no change to the behavior,
and most of the code has merely moved.
Also:
- use StringBuilder, not Appendable: no more IOExceptions
- remove prettyPrint overload with indentLevel parameter
- rename FUNCTION_DEF to DEF
- hide some constants
PiperOrigin-RevId: 277052492
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Argument.java b/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
index e289b46..cc54b58 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Argument.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.base.Preconditions;
-import java.io.IOException;
import javax.annotation.Nullable;
/**
@@ -43,15 +42,9 @@
/** Syntax node for a positional argument, {@code f(expr)}. */
public static final class Positional extends Argument {
-
Positional(Expression value) {
super(value);
}
-
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- getValue().prettyPrint(buffer);
- }
}
/** Syntax node for a keyword argument, {@code f(id=expr)}. */
@@ -75,52 +68,23 @@
public String getName() {
return identifier.getName();
}
-
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append(identifier.getName());
- buffer.append(" = ");
- getValue().prettyPrint(buffer);
- }
}
/** Syntax node for an argument of the form {@code f(*expr)}. */
public static final class Star extends Argument {
-
Star(Expression value) {
super(value);
}
-
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append('*');
- getValue().prettyPrint(buffer);
- }
}
/** Syntax node for an argument of the form {@code f(**expr)}. */
public static final class StarStar extends Argument {
-
StarStar(Expression value) {
super(value);
}
-
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append("**");
- getValue().prettyPrint(buffer);
- }
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- prettyPrint(buffer);
- }
-
- @Override
- public abstract void prettyPrint(Appendable buffer) throws IOException;
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
index 64d71ba..0a6c83b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AssignmentStatement.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** Syntax node for an assignment statement. */
public final class AssignmentStatement extends Statement {
@@ -42,15 +41,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- lhs.prettyPrint(buffer, indentLevel);
- buffer.append(" = ");
- rhs.prettyPrint(buffer, indentLevel);
- buffer.append('\n');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
index 69046db..14670f3 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/AugmentedAssignmentStatement.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** Syntax node for an augmented assignment statement. */
// TODO(adonovan): merge with AssignmentStatement.
@@ -47,17 +46,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- lhs.prettyPrint(buffer);
- buffer.append(' ');
- buffer.append(op.toString());
- buffer.append("= ");
- rhs.prettyPrint(buffer);
- buffer.append('\n');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BUILD b/src/main/java/com/google/devtools/build/lib/syntax/BUILD
index d061a07..ea31774 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BUILD
@@ -54,6 +54,7 @@
"ListExpression.java",
"LoadStatement.java",
"Node.java",
+ "NodePrinter.java",
"NodeVisitor.java",
"Parameter.java",
"Parser.java",
@@ -72,10 +73,8 @@
],
deps = [
"//src/main/java/com/google/devtools/build/lib:events",
- "//src/main/java/com/google/devtools/build/lib:skylarkinterface",
"//src/main/java/com/google/devtools/build/lib:string_util",
"//src/main/java/com/google/devtools/build/lib:util",
- "//src/main/java/com/google/devtools/build/lib/collect/compacthashset",
"//src/main/java/com/google/devtools/build/lib/concurrent",
"//src/main/java/com/google/devtools/build/lib/profiler",
"//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
index ea9e553..fef702d 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
import java.util.EnumSet;
/** A BinaryExpression represents a binary operator expression 'x op y'. */
@@ -66,19 +65,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- // TODO(bazel-team): retain parentheses in the syntax tree so we needn't
- // conservatively emit them here.
- buffer.append('(');
- x.prettyPrint(buffer);
- buffer.append(' ');
- buffer.append(op.toString());
- buffer.append(' ');
- y.prettyPrint(buffer);
- buffer.append(')');
- }
-
- @Override
public String toString() {
// This omits the parentheses for brevity, but is not correct in general due to operator
// precedence rules.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Comment.java b/src/main/java/com/google/devtools/build/lib/syntax/Comment.java
index 9ca6728..161c7a4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Comment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Comment.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** Syntax node for comments. */
public final class Comment extends Node {
@@ -34,16 +33,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- // We can't really print comments in the right place anyway, due to how their relative order
- // is lost in the representation of StarlarkFile. So don't bother word-wrapping and just print
- // it on a single line.
- printIndent(buffer, indentLevel);
- buffer.append("# ");
- buffer.append(value);
- }
-
- @Override
public String toString() {
return value;
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Comprehension.java b/src/main/java/com/google/devtools/build/lib/syntax/Comprehension.java
index e07906c..771196e 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Comprehension.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Comprehension.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
/**
* Syntax node for list and dict comprehensions.
@@ -99,27 +98,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append(isDict ? '{' : '[');
- body.prettyPrint(buffer);
- for (Clause clause : clauses) {
- buffer.append(' ');
- if (clause instanceof For) {
- For forClause = (For) clause;
- buffer.append("for ");
- forClause.vars.prettyPrint(buffer);
- buffer.append(" in ");
- forClause.iterable.prettyPrint(buffer);
- } else {
- If ifClause = (If) clause;
- buffer.append("if ");
- ifClause.condition.prettyPrint(buffer);
- }
- }
- buffer.append(isDict ? '}' : ']');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
index 0ebb4f3..ffeb9ea 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ConditionalExpression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** Syntax node for an if/else expression. */
public final class ConditionalExpression extends Expression {
@@ -35,18 +34,6 @@
this.elseCase = elseCase;
}
- /**
- * Constructs a string representation of the if expression
- */
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- thenCase.prettyPrint(buffer);
- buffer.append(" if ");
- condition.prettyPrint(buffer);
- buffer.append(" else ");
- elseCase.prettyPrint(buffer);
- }
-
@Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java
index c92fcd4..5ac3926 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DefStatement.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
/** Syntax node for a 'def' statement, which defines a function. */
public final class DefStatement extends Statement {
@@ -36,40 +35,14 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- appendSignatureTo(buffer);
- buffer.append('\n');
- printSuite(buffer, statements, indentLevel);
- }
-
- @Override
public String toString() {
// "def f(...): \n"
StringBuilder buf = new StringBuilder();
- try {
- appendSignatureTo(buf);
- } catch (IOException ex) {
- throw new IllegalStateException(ex); // can't fail (StringBuilder)
- }
+ new NodePrinter(buf).printDefSignature(this);
buf.append(" ...\n");
return buf.toString();
}
- // Appends "def f(a, ..., z):" to the buffer.
- private void appendSignatureTo(Appendable buf) throws IOException {
- buf.append("def ");
- identifier.prettyPrint(buf);
- buf.append('(');
- String sep = "";
- for (Parameter param : parameters) {
- buf.append(sep);
- param.prettyPrint(buf);
- sep = ", ";
- }
- buf.append("):");
- }
-
public Identifier getIdentifier() {
return identifier;
}
@@ -93,6 +66,6 @@
@Override
public Kind kind() {
- return Kind.FUNCTION_DEF;
+ return Kind.DEF;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DictExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DictExpression.java
index a6312e0..e0b1fa3 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DictExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DictExpression.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.util.List;
/** Syntax node for dict expressions. */
@@ -40,13 +39,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- key.prettyPrint(buffer);
- buffer.append(": ");
- value.prettyPrint(buffer);
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
@@ -59,18 +51,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append("{");
- String sep = "";
- for (Entry e : entries) {
- buffer.append(sep);
- e.prettyPrint(buffer);
- sep = ", ";
- }
- buffer.append("}");
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
index 7e18593..102f1c3 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** Syntax node for a dot expression. e.g. obj.field, but not obj.method() */
public final class DotExpression extends Expression {
@@ -36,13 +35,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- object.prettyPrint(buffer);
- buffer.append('.');
- field.prettyPrint(buffer);
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Eval.java b/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
index d24e59f..d005204 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
@@ -212,7 +212,7 @@
return ((FlowStatement) st).getKind();
case FOR:
return execFor((ForStatement) st);
- case FUNCTION_DEF:
+ case DEF:
execDef((DefStatement) st);
return TokenKind.PASS;
case IF:
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Expression.java b/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
index 3ff3996..850a194 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Expression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/**
* Base class for all expression nodes in the AST.
@@ -46,18 +45,6 @@
UNARY_OPERATOR,
}
- @Override
- public final void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- prettyPrint(buffer);
- }
-
- /**
- * Expressions should implement this method instead of {@link #prettyPrint(Appendable, int)},
- * since the {@code indentLevel} argument is not needed.
- */
- @Override
- public abstract void prettyPrint(Appendable buffer) throws IOException;
-
/**
* Kind of the expression. This is similar to using instanceof, except that it's more efficient
* and can be used in a switch/case.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
index 3569b22..1ff2b21 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ExpressionStatement.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** Syntax node for a function call statement. Used for build rules. */
public final class ExpressionStatement extends Statement {
@@ -30,13 +29,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- expression.prettyPrint(buffer);
- buffer.append('\n');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
index 16a755e..b24a672 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FlowStatement.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** A class for flow statements (break, continue, and pass) */
public final class FlowStatement extends Statement {
@@ -30,12 +29,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- buffer.append(kind.toString()).append('\n');
- }
-
- @Override
public String toString() {
return kind.toString() + "\n";
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
index b228aca..5b43f75 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ForStatement.java
@@ -15,7 +15,6 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.util.List;
/** Syntax node for a for loop statement. */
@@ -48,17 +47,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- buffer.append("for ");
- lhs.prettyPrint(buffer);
- buffer.append(" in ");
- collection.prettyPrint(buffer);
- buffer.append(":\n");
- printSuite(buffer, block, indentLevel);
- }
-
- @Override
public String toString() {
return "for " + lhs + " in " + collection + ": ...\n";
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
index f210888..aebc552 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
@@ -16,7 +16,6 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
@@ -70,19 +69,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- function.prettyPrint(buffer);
- buffer.append('(');
- String sep = "";
- for (Argument arg : arguments) {
- buffer.append(sep);
- arg.prettyPrint(buffer);
- sep = ", ";
- }
- buffer.append(')');
- }
-
- @Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append(function);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java b/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
index 82cdec4..76af45b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Identifier.java
@@ -16,7 +16,6 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
-import java.io.IOException;
import javax.annotation.Nullable;
// TODO(bazel-team): For performance, avoid doing HashMap lookups at runtime, and compile local
@@ -51,11 +50,6 @@
return scope;
}
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append(name);
- }
-
void setScope(ValidationEnvironment.Scope scope) {
Preconditions.checkState(this.scope == null);
this.scope = scope;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
index e5cf5ba..378bfbd 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IfStatement.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;
@@ -60,26 +59,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- buffer.append(token == TokenKind.IF ? "if " : "elif ");
- condition.prettyPrint(buffer);
- buffer.append(":\n");
- printSuite(buffer, thenBlock, indentLevel);
- if (elseBlock != null) {
- if (elseBlock.size() == 1
- && elseBlock.get(0) instanceof IfStatement
- && ((IfStatement) elseBlock.get(0)).isElif()) {
- elseBlock.get(0).prettyPrint(buffer, indentLevel);
- } else {
- printIndent(buffer, indentLevel);
- buffer.append("else:\n");
- printSuite(buffer, elseBlock, indentLevel);
- }
- }
- }
-
- @Override
public String toString() {
return String.format("if %s: ...\n", condition);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
index 2db3a64..e3517d6 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IndexExpression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/**
* An index expression ({@code obj[field]}). Not to be confused with a slice expression ({@code
@@ -40,14 +39,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- object.prettyPrint(buffer);
- buffer.append('[');
- key.prettyPrint(buffer);
- buffer.append(']');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
index b1bee68..e909536 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/IntegerLiteral.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** Syntax node for an integer literal. */
public final class IntegerLiteral extends Expression {
@@ -28,11 +27,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append(String.valueOf(value));
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ListExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/ListExpression.java
index dd1c88f..cead487 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ListExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ListExpression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
import java.util.List;
/** Syntax node for list and tuple expressions. */
@@ -38,21 +37,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append(isTuple() ? '(' : '[');
- String sep = "";
- for (Expression e : elements) {
- buffer.append(sep);
- e.prettyPrint(buffer);
- sep = ", ";
- }
- if (isTuple() && elements.size() == 1) {
- buffer.append(',');
- }
- buffer.append(isTuple() ? ')' : ']');
- }
-
- @Override
public String toString() {
// Print [a, b, c, ...] up to a maximum of 4 elements or 32 chars.
StringBuilder buf = new StringBuilder();
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
index dac1f2c..f553865 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/LoadStatement.java
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import java.util.List;
/** Syntax node for an import statement. */
@@ -96,29 +95,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- buffer.append("load(");
- imp.prettyPrint(buffer);
- for (Binding binding : bindings) {
- buffer.append(", ");
- Identifier local = binding.getLocalName();
- String origName = binding.getOriginalName().getName();
- if (origName.equals(local.getName())) {
- buffer.append('"');
- local.prettyPrint(buffer);
- buffer.append('"');
- } else {
- local.prettyPrint(buffer);
- buffer.append("=\"");
- buffer.append(origName);
- buffer.append('"');
- }
- }
- buffer.append(")\n");
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Node.java b/src/main/java/com/google/devtools/build/lib/syntax/Node.java
index 63d844a..74e0da0 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Node.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Node.java
@@ -15,10 +15,8 @@
package com.google.devtools.build.lib.syntax;
import com.google.devtools.build.lib.events.Location;
-import java.io.IOException;
-import java.util.List;
-/** An Node is a node in a Starlark syntax tree. */
+/** A Node is a node in a Starlark syntax tree. */
public abstract class Node {
// Use these typical node distributions in Bazel files
@@ -71,70 +69,21 @@
return location;
}
- /** Number of spaces that each indentation level expands to when pretty-printing. */
- public static final int INDENT_WIDTH = 2;
-
- /** Writes out the indentation prefix for a line. */
- protected void printIndent(Appendable buffer, int indentLevel) throws IOException {
- for (int i = 0; i < indentLevel * INDENT_WIDTH; i++) {
- buffer.append(' ');
- }
- }
-
/**
- * Writes out a suite of statements. The statements are indented one more level than given, i.e.,
- * the {@code indentLevel} parameter should be the same as the parent node's.
+ * Returns a pretty-printed representation of this syntax tree.
*
- * <p>This also prints out a {@code pass} line if the suite is empty.
+ * <p>This function returns the canonical source code corresponding to a syntax tree. Generally,
+ * the output can be round-tripped: pretty-printing a syntax tree then parsing the result should
+ * yield an equivalent syntax tree.
+ *
+ * <p>The pretty-printed form of a syntax tree may be used as a proxy for equality in tests.
+ * However, different trees may have the same printed form. In particular, {@link StarlarkFile}
+ * includes comments that are not reflected in the string.
*/
- protected void printSuite(Appendable buffer, List<Statement> statements, int parentIndentLevel)
- throws IOException {
- if (statements.isEmpty()) {
- printIndent(buffer, parentIndentLevel + 1);
- buffer.append("pass\n");
- } else {
- for (Statement stmt : statements) {
- stmt.prettyPrint(buffer, parentIndentLevel + 1);
- }
- }
- }
-
- /**
- * Writes a pretty-printed representation of this node to a buffer, assuming the given starting
- * indentation level.
- *
- * <p>For expressions, the indentation level is ignored. For statements, the indentation is
- * written, then the statement contents (which may include multiple lines with their own
- * indentation), then a newline character.
- *
- * <p>Indentation expands to {@code INDENT_WIDTH} many spaces per indent.
- *
- * <p>Pretty printing returns the canonical source code corresponding to an AST. Generally, the
- * output can be round-tripped: Pretty printing an AST and then parsing the result should give you
- * back an equivalent AST.
- *
- * <p>Pretty printing can also be used as a proxy for comparing for equality between two ASTs.
- * This can be very useful in tests. However, it is still possible for two different trees to have
- * the same pretty printing. In particular, {@link StarlarkFile} includes import metadata and
- * comment information that is not reflected in the string.
- */
- public abstract void prettyPrint(Appendable buffer, int indentLevel) throws IOException;
-
- /** Same as {@link #prettyPrint(Appendable, int)}, except with no indent. */
- void prettyPrint(Appendable buffer) throws IOException {
- prettyPrint(buffer, 0);
- }
-
- /** Returns a pretty-printed representation of this node. */
- public String prettyPrint() {
- StringBuilder builder = new StringBuilder();
- try {
- prettyPrint(builder);
- } catch (IOException e) {
- // Not possible for StringBuilder.
- throw new AssertionError(e);
- }
- return builder.toString();
+ public final String prettyPrint() {
+ StringBuilder buf = new StringBuilder();
+ new NodePrinter(buf).printNode(this);
+ return buf.toString();
}
/**
@@ -146,7 +95,7 @@
*/
@Override
public String toString() {
- return prettyPrint();
+ return prettyPrint(); // default behavior, overridden in several subclasses
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/NodePrinter.java b/src/main/java/com/google/devtools/build/lib/syntax/NodePrinter.java
new file mode 100644
index 0000000..588a9d5
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/syntax/NodePrinter.java
@@ -0,0 +1,473 @@
+// Copyright 2019 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
+//
+// 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.devtools.build.lib.syntax;
+
+import java.util.List;
+
+/** A pretty-printer for Starlark syntax trees. */
+final class NodePrinter {
+
+ private final StringBuilder buf;
+ private int indent;
+
+ NodePrinter(StringBuilder buf) {
+ this.buf = buf;
+ }
+
+ // Constructor exposed to legacy tests.
+ // TODO(adonovan): rewrite the tests not to care about the indent parameter.
+ NodePrinter(StringBuilder buf, int indent) {
+ this.buf = buf;
+ this.indent = indent;
+ }
+
+ // Main entry point for an arbitrary node.
+ // Called by Node.prettyPrint.
+ void printNode(Node n) {
+ if (n instanceof Expression) {
+ printExpr((Expression) n);
+
+ } else if (n instanceof Statement) {
+ printStmt((Statement) n);
+
+ } else if (n instanceof StarlarkFile) {
+ StarlarkFile file = (StarlarkFile) n;
+ // Only statements are printed, not comments.
+ for (Statement stmt : file.getStatements()) {
+ printStmt(stmt);
+ }
+
+ } else if (n instanceof Comment) {
+ Comment comment = (Comment) n;
+ // We can't really print comments in the right place anyway,
+ // due to how their relative order is lost in the representation
+ // of StarlarkFile. So don't bother word-wrapping and just print
+ // it on a single line.
+ printIndent();
+ buf.append("# ");
+ buf.append(comment.getValue());
+
+ } else if (n instanceof Argument) {
+ printArgument((Argument) n);
+
+ } else if (n instanceof Parameter) {
+ printParameter((Parameter) n);
+
+ } else if (n instanceof DictExpression.Entry) {
+ printDictEntry((DictExpression.Entry) n);
+
+ } else {
+ throw new IllegalArgumentException("unexpected: " + n.getClass());
+ }
+ }
+
+ private void printSuite(List<Statement> statements) {
+ // A suite is non-empty; pass statements are explicit.
+ indent++;
+ for (Statement stmt : statements) {
+ printStmt(stmt);
+ }
+ indent--;
+ }
+
+ private void printIndent() {
+ for (int i = 0; i < indent; i++) {
+ buf.append(" ");
+ }
+ }
+
+ private void printArgument(Argument arg) {
+ if (arg instanceof Argument.Positional) {
+ // nop
+ } else if (arg instanceof Argument.Keyword) {
+ buf.append(((Argument.Keyword) arg).getIdentifier().getName());
+ buf.append(" = ");
+ } else if (arg instanceof Argument.Star) {
+ buf.append('*');
+ } else if (arg instanceof Argument.StarStar) {
+ buf.append("**");
+ }
+ printExpr(arg.getValue());
+ }
+
+ private void printParameter(Parameter param) {
+ if (param instanceof Parameter.Mandatory) {
+ buf.append(param.getName());
+ } else if (param instanceof Parameter.Optional) {
+ buf.append(param.getName());
+ buf.append('=');
+ printExpr(param.getDefaultValue());
+ } else if (param instanceof Parameter.Star) {
+ buf.append('*');
+ if (param.getName() != null) {
+ buf.append(param.getName());
+ }
+ } else if (param instanceof Parameter.StarStar) {
+ buf.append("**");
+ buf.append(param.getName());
+ }
+ }
+
+ private void printDictEntry(DictExpression.Entry e) {
+ printExpr(e.getKey());
+ buf.append(": ");
+ printExpr(e.getValue());
+ }
+
+ // Appends "def f(a, ..., z):" to the buf.
+ // Also used by DefStatement.toString.
+ void printDefSignature(DefStatement def) {
+ buf.append("def ");
+ printExpr(def.getIdentifier());
+ buf.append('(');
+ String sep = "";
+ for (Parameter param : def.getParameters()) {
+ buf.append(sep);
+ printParameter(param);
+ sep = ", ";
+ }
+ buf.append("):");
+ }
+
+ private void printStmt(Statement s) {
+ printIndent();
+
+ switch (s.kind()) {
+ case ASSIGNMENT:
+ {
+ AssignmentStatement stmt = (AssignmentStatement) s;
+ printExpr(stmt.getLHS());
+ buf.append(" = ");
+ printExpr(stmt.getRHS());
+ buf.append('\n');
+ break;
+ }
+
+ case AUGMENTED_ASSIGNMENT:
+ {
+ AugmentedAssignmentStatement stmt = (AugmentedAssignmentStatement) s;
+ printExpr(stmt.getLHS());
+ buf.append(' ');
+ buf.append(stmt.getOperator());
+ buf.append("= ");
+ printExpr(stmt.getRHS());
+ buf.append('\n');
+ break;
+ }
+
+ case EXPRESSION:
+ {
+ ExpressionStatement stmt = (ExpressionStatement) s;
+ printExpr(stmt.getExpression());
+ buf.append('\n');
+ break;
+ }
+
+ case FLOW:
+ {
+ FlowStatement stmt = (FlowStatement) s;
+ buf.append(stmt.getKind()).append('\n');
+ break;
+ }
+
+ case FOR:
+ {
+ ForStatement stmt = (ForStatement) s;
+ buf.append("for ");
+ printExpr(stmt.getLHS());
+ buf.append(" in ");
+ printExpr(stmt.getCollection());
+ buf.append(":\n");
+ printSuite(stmt.getBlock());
+ break;
+ }
+
+ case DEF:
+ {
+ DefStatement stmt = (DefStatement) s;
+ printDefSignature(stmt);
+ buf.append('\n');
+ printSuite(stmt.getStatements());
+ break;
+ }
+
+ case IF:
+ {
+ IfStatement stmt = (IfStatement) s;
+ buf.append(stmt.isElif() ? "elif " : "if ");
+ printExpr(stmt.getCondition());
+ buf.append(":\n");
+ printSuite(stmt.getThenBlock());
+ List<Statement> elseBlock = stmt.getElseBlock();
+ if (elseBlock != null) {
+ if (elseBlock.size() == 1
+ && elseBlock.get(0) instanceof IfStatement
+ && ((IfStatement) elseBlock.get(0)).isElif()) {
+ printStmt(elseBlock.get(0));
+ } else {
+ printIndent();
+ buf.append("else:\n");
+ printSuite(elseBlock);
+ }
+ }
+ break;
+ }
+
+ case LOAD:
+ {
+ LoadStatement stmt = (LoadStatement) s;
+ buf.append("load(");
+ printExpr(stmt.getImport());
+ for (LoadStatement.Binding binding : stmt.getBindings()) {
+ buf.append(", ");
+ Identifier local = binding.getLocalName();
+ String origName = binding.getOriginalName().getName();
+ if (origName.equals(local.getName())) {
+ buf.append('"');
+ printExpr(local);
+ buf.append('"');
+ } else {
+ printExpr(local);
+ buf.append("=\"");
+ buf.append(origName);
+ buf.append('"');
+ }
+ }
+ buf.append(")\n");
+ break;
+ }
+
+ case RETURN:
+ {
+ ReturnStatement stmt = (ReturnStatement) s;
+ buf.append("return");
+ if (stmt.getReturnExpression() != null) {
+ buf.append(' ');
+ printExpr(stmt.getReturnExpression());
+ }
+ buf.append('\n');
+ break;
+ }
+ }
+ }
+
+ private void printExpr(Expression expr) {
+ switch (expr.kind()) {
+ case BINARY_OPERATOR:
+ {
+ BinaryOperatorExpression binop = (BinaryOperatorExpression) expr;
+ // TODO(bazel-team): retain parentheses in the syntax tree so we needn't
+ // conservatively emit them here.
+ buf.append('(');
+ printExpr(binop.getX());
+ buf.append(' ');
+ buf.append(binop.getOperator());
+ buf.append(' ');
+ printExpr(binop.getY());
+ buf.append(')');
+ break;
+ }
+
+ case COMPREHENSION:
+ {
+ Comprehension comp = (Comprehension) expr;
+ buf.append(comp.isDict() ? '{' : '[');
+ printNode(comp.getBody()); // Expression or DictExpression.Entry
+ for (Comprehension.Clause clause : comp.getClauses()) {
+ buf.append(' ');
+ if (clause instanceof Comprehension.For) {
+ Comprehension.For forClause = (Comprehension.For) clause;
+ buf.append("for ");
+ printExpr(forClause.getVars());
+ buf.append(" in ");
+ printExpr(forClause.getIterable());
+ } else {
+ Comprehension.If ifClause = (Comprehension.If) clause;
+ buf.append("if ");
+ printExpr(ifClause.getCondition());
+ }
+ }
+ buf.append(comp.isDict() ? '}' : ']');
+ break;
+ }
+
+ case CONDITIONAL:
+ {
+ ConditionalExpression cond = (ConditionalExpression) expr;
+ printExpr(cond.getThenCase());
+ buf.append(" if ");
+ printExpr(cond.getCondition());
+ buf.append(" else ");
+ printExpr(cond.getElseCase());
+ break;
+ }
+
+ case DICT_EXPR:
+ {
+ DictExpression dictexpr = (DictExpression) expr;
+ buf.append("{");
+ String sep = "";
+ for (DictExpression.Entry entry : dictexpr.getEntries()) {
+ buf.append(sep);
+ printDictEntry(entry);
+ sep = ", ";
+ }
+ buf.append("}");
+ break;
+ }
+
+ case DOT:
+ {
+ DotExpression dot = (DotExpression) expr;
+ printExpr(dot.getObject());
+ buf.append('.');
+ printExpr(dot.getField());
+ break;
+ }
+
+ case FUNCALL:
+ {
+ FuncallExpression call = (FuncallExpression) expr;
+ printExpr(call.getFunction());
+ buf.append('(');
+ String sep = "";
+ for (Argument arg : call.getArguments()) {
+ buf.append(sep);
+ printArgument(arg);
+ sep = ", ";
+ }
+ buf.append(')');
+ break;
+ }
+
+ case IDENTIFIER:
+ buf.append(((Identifier) expr).getName());
+ break;
+
+ case INDEX:
+ {
+ IndexExpression index = (IndexExpression) expr;
+ printExpr(index.getObject());
+ buf.append('[');
+ printExpr(index.getKey());
+ buf.append(']');
+ break;
+ }
+
+ case INTEGER_LITERAL:
+ {
+ buf.append(((IntegerLiteral) expr).getValue());
+ break;
+ }
+
+ case LIST_EXPR:
+ {
+ ListExpression list = (ListExpression) expr;
+ buf.append(list.isTuple() ? '(' : '[');
+ String sep = "";
+ for (Expression e : list.getElements()) {
+ buf.append(sep);
+ printExpr(e);
+ sep = ", ";
+ }
+ if (list.isTuple() && list.getElements().size() == 1) {
+ buf.append(',');
+ }
+ buf.append(list.isTuple() ? ')' : ']');
+ break;
+ }
+
+ case SLICE:
+ {
+ SliceExpression slice = (SliceExpression) expr;
+ printExpr(slice.getObject());
+ buf.append('[');
+ // The first separator colon is unconditional.
+ // The second separator appears only if step is printed.
+ if (slice.getStart() != null) {
+ printExpr(slice.getStart());
+ }
+ buf.append(':');
+ if (slice.getEnd() != null) {
+ printExpr(slice.getEnd());
+ }
+ if (slice.getStep() != null) {
+ buf.append(':');
+ printExpr(slice.getStep());
+ }
+ buf.append(']');
+ break;
+ }
+
+ case STRING_LITERAL:
+ {
+ StringLiteral literal = (StringLiteral) expr;
+ String value = literal.getValue();
+
+ // TODO(adonovan): record the raw text of string (and integer) literals
+ // so that we can use the syntax tree for source modification tools.
+ // However, that may come with a memory cost until we start compiling
+ // (at which point the cost is only transient).
+ // For now, just simulate the behavior of repr(str).
+ buf.append('"');
+ for (int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ switch (c) {
+ case '"':
+ buf.append("\\\"");
+ break;
+ case '\\':
+ buf.append("\\\\");
+ break;
+ case '\r':
+ buf.append("\\r");
+ break;
+ case '\n':
+ buf.append("\\n");
+ break;
+ case '\t':
+ buf.append("\\t");
+ break;
+ default:
+ // The Starlark spec (and lexer) are far from complete here,
+ // and it's hard to come up with a clean semantics for
+ // string escapes that serves Java (UTF-16) and Go (UTF-8).
+ // Clearly string literals should not contain non-printable
+ // characters. For now we'll continue to pretend that all
+ // non-printables are < 32, but this obviously false.
+ if (c < 32) {
+ buf.append(String.format("\\x%02x", (int) c));
+ } else {
+ buf.append(c);
+ }
+ }
+ }
+ buf.append('"');
+ break;
+ }
+
+ case UNARY_OPERATOR:
+ {
+ UnaryOperatorExpression unop = (UnaryOperatorExpression) expr;
+ // TODO(bazel-team): retain parentheses in the syntax tree so we needn't
+ // conservatively emit them here.
+ buf.append(unop.getOperator() == TokenKind.NOT ? "not " : unop.getOperator().toString());
+ buf.append('(');
+ printExpr(unop.getX());
+ buf.append(')');
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parameter.java b/src/main/java/com/google/devtools/build/lib/syntax/Parameter.java
index 13d272a..19cf096 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parameter.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parameter.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
import javax.annotation.Nullable;
/**
@@ -51,28 +50,14 @@
return null;
}
- @Override
- public final void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- prettyPrint(buffer);
- }
-
- @Override
- public abstract void prettyPrint(Appendable buffer) throws IOException;
-
/**
* Syntax node for a mandatory parameter, {@code f(id)}. It may be positional or keyword-only
* depending on its position.
*/
public static final class Mandatory extends Parameter {
-
Mandatory(Identifier identifier) {
super(identifier);
}
-
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append(getName());
- }
}
/**
@@ -95,13 +80,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append(getName());
- buffer.append('=');
- defaultValue.prettyPrint(buffer);
- }
-
- @Override
public String toString() {
return getName() + "=" + defaultValue;
}
@@ -109,32 +87,16 @@
/** Syntax node for a star parameter, {@code f(*identifier)} or or {@code f(..., *, ...)}. */
public static final class Star extends Parameter {
-
Star(@Nullable Identifier identifier) {
super(identifier);
}
-
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append('*');
- if (getName() != null) {
- buffer.append(getName());
- }
- }
}
/** Syntax node for a parameter of the form {@code f(**identifier)}. */
public static final class StarStar extends Parameter {
-
StarStar(Identifier identifier) {
super(identifier);
}
-
- @Override
- public void prettyPrint(Appendable buffer) throws IOException {
- buffer.append("**");
- buffer.append(getName());
- }
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Printer.java b/src/main/java/com/google/devtools/build/lib/syntax/Printer.java
index 0bf4d74..bf41cf7 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Printer.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Printer.java
@@ -33,8 +33,6 @@
/** (Pretty) Printing of Skylark values */
public class Printer {
- public static final char SKYLARK_QUOTATION_MARK = '"';
-
/**
* Creates an instance of {@link BasePrinter} that wraps an existing buffer.
*
@@ -328,13 +326,13 @@
* @return this printer.
*/
protected BasePrinter writeString(String s) {
- this.append(SKYLARK_QUOTATION_MARK);
+ this.append('"');
int len = s.length();
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
escapeCharacter(c);
}
- return this.append(SKYLARK_QUOTATION_MARK);
+ return this.append('"');
}
private BasePrinter backslashChar(char c) {
@@ -342,7 +340,7 @@
}
private BasePrinter escapeCharacter(char c) {
- if (c == SKYLARK_QUOTATION_MARK) {
+ if (c == '"') {
return backslashChar(c);
}
switch (c) {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
index 3d20477..0f04b04 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ReturnStatement.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
import javax.annotation.Nullable;
/** A wrapper Statement class for return expressions. */
@@ -31,17 +30,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- printIndent(buffer, indentLevel);
- buffer.append("return");
- if (returnExpression != null) {
- buffer.append(' ');
- returnExpression.prettyPrint(buffer, indentLevel);
- }
- buffer.append('\n');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
index 06184a0..d252299 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SliceExpression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
import javax.annotation.Nullable;
/** Syntax node for a slice expression, e.g. obj[:len(obj):2]. */
@@ -48,26 +47,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- object.prettyPrint(buffer);
- buffer.append('[');
- // The first separator colon is unconditional. The second separator appears only if step is
- // printed.
- if (start != null) {
- start.prettyPrint(buffer);
- }
- buffer.append(':');
- if (end != null) {
- end.prettyPrint(buffer);
- }
- if (step != null) {
- buffer.append(':');
- step.prettyPrint(buffer);
- }
- buffer.append(']');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkFile.java b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkFile.java
index cde6b80..8d285967 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkFile.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkFile.java
@@ -132,14 +132,6 @@
}
@Override
- public void prettyPrint(Appendable buffer, int indentLevel) throws IOException {
- // Only statements are printed, not comments.
- for (Statement stmt : statements) {
- stmt.prettyPrint(buffer, indentLevel);
- }
- }
-
- @Override
public String toString() {
return "<StarlarkFile with " + statements.size() + " statements>";
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Statement.java b/src/main/java/com/google/devtools/build/lib/syntax/Statement.java
index 116243c..493255f 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Statement.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Statement.java
@@ -26,7 +26,7 @@
EXPRESSION,
FLOW,
FOR,
- FUNCTION_DEF,
+ DEF,
IF,
LOAD,
RETURN,
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java b/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
index 3ea5353..48406a6 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StringLiteral.java
@@ -35,49 +35,6 @@
}
@Override
- public void prettyPrint(Appendable buf) throws IOException {
- // TODO(adonovan): record the raw text of string (and integer) literals
- // so that we can use the syntax tree for source modification tools.
- // However, that may come with a memory cost until we start compiling
- // (at which point the cost is only transient).
- // For now, just simulate the behavior of repr(str).
- buf.append('"');
- for (int i = 0; i < value.length(); i++) {
- char c = value.charAt(i);
- switch (c) {
- case '"':
- buf.append("\\\"");
- break;
- case '\\':
- buf.append("\\\\");
- break;
- case '\r':
- buf.append("\\r");
- break;
- case '\n':
- buf.append("\\n");
- break;
- case '\t':
- buf.append("\\t");
- break;
- default:
- // The Starlark spec (and lexer) are far from complete here,
- // and it's hard to come up with a clean semantics for
- // string escapes that serves Java (UTF-16) and Go (UTF-8).
- // Clearly string literals should not contain non-printable
- // characters. For now we'll continue to pretend that all
- // non-printables are < 32, but this obviously false.
- if (c < 32) {
- buf.append(String.format("\\x%02x", (int) c));
- } else {
- buf.append(c);
- }
- }
- }
- buf.append('"');
- }
-
- @Override
public void accept(NodeVisitor visitor) {
visitor.visit(this);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
index eff1163..4a58e94 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/UnaryOperatorExpression.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.syntax;
-import java.io.IOException;
/** A UnaryOperatorExpression represents a unary operator expression, 'op x'. */
public final class UnaryOperatorExpression extends Expression {
@@ -37,16 +36,6 @@
}
@Override
- public void prettyPrint(Appendable buffer) throws IOException {
- // TODO(bazel-team): retain parentheses in the syntax tree so we needn't
- // conservatively emit them here.
- buffer.append(op == TokenKind.NOT ? "not " : op.toString());
- buffer.append('(');
- x.prettyPrint(buffer);
- buffer.append(')');
- }
-
- @Override
public String toString() {
// Note that this omits the parentheses for brevity, but is not correct in general due to
// operator precedence rules. For example, "(not False) in mylist" prints as
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java b/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java
index 0dcff06..d437d22 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/ValidationEnvironment.java
@@ -157,7 +157,7 @@
collectDefinitions(forStmt.getLHS());
collectDefinitions(forStmt.getBlock());
break;
- case FUNCTION_DEF:
+ case DEF:
DefStatement def = (DefStatement) stmt;
declare(def.getIdentifier());
break;
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/PrettyPrintTest.java b/src/test/java/com/google/devtools/build/lib/syntax/PrettyPrintTest.java
index e088d82..e2a9a0f 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/PrettyPrintTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/PrettyPrintTest.java
@@ -18,7 +18,6 @@
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -52,14 +51,9 @@
* Asserts that the given node's pretty print at a given indent level matches the given string.
*/
private void assertPrettyMatches(Node node, int indentLevel, String expected) {
- StringBuilder prettyBuilder = new StringBuilder();
- try {
- node.prettyPrint(prettyBuilder, indentLevel);
- } catch (IOException e) {
- // Impossible for StringBuilder.
- throw new AssertionError(e);
- }
- assertThat(prettyBuilder.toString()).isEqualTo(expected);
+ StringBuilder buf = new StringBuilder();
+ new NodePrinter(buf, indentLevel).printNode(node);
+ assertThat(buf.toString()).isEqualTo(expected);
}
/** Asserts that the given node's pretty print with no indent matches the given string. */