aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/ir/debug/ASTWriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/ir/debug/ASTWriter.java')
-rw-r--r--src/jdk/nashorn/internal/ir/debug/ASTWriter.java290
1 files changed, 0 insertions, 290 deletions
diff --git a/src/jdk/nashorn/internal/ir/debug/ASTWriter.java b/src/jdk/nashorn/internal/ir/debug/ASTWriter.java
deleted file mode 100644
index 52e3c0e0..00000000
--- a/src/jdk/nashorn/internal/ir/debug/ASTWriter.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.ir.debug;
-
-import java.lang.reflect.Field;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Deque;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import jdk.nashorn.internal.ir.BinaryNode;
-import jdk.nashorn.internal.ir.Block;
-import jdk.nashorn.internal.ir.Expression;
-import jdk.nashorn.internal.ir.IdentNode;
-import jdk.nashorn.internal.ir.Node;
-import jdk.nashorn.internal.ir.Statement;
-import jdk.nashorn.internal.ir.Symbol;
-import jdk.nashorn.internal.ir.Terminal;
-import jdk.nashorn.internal.ir.TernaryNode;
-import jdk.nashorn.internal.ir.annotations.Ignore;
-import jdk.nashorn.internal.ir.annotations.Reference;
-import jdk.nashorn.internal.parser.Token;
-import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.Debug;
-
-/**
- * AST-as-text visualizer. Sometimes you want tree form and not source
- * code. This works for both lowered and unlowered IR
- *
- * see the flags --print-ast and --print-ast-lower
- */
-public final class ASTWriter {
- /** Root node from which to start the traversal */
- private final Node root;
-
- private static final int TABWIDTH = 4;
-
- /**
- * Constructor
- * @param root root of the AST to visualize
- */
- public ASTWriter(final Node root) {
- this.root = root;
- }
-
- /**
- * Use the ASTWriter by instantiating it and retrieving its String
- * representation
- *
- * @return the string representation of the AST
- */
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- printAST(sb, null, null, "root", root, 0);
- return sb.toString();
- }
-
- /**
- * Return the visited nodes in an ordered list
- * @return the list of nodes in order
- */
- public Node[] toArray() {
- final List<Node> preorder = new ArrayList<>();
- printAST(new StringBuilder(), preorder, null, "root", root, 0);
- return preorder.toArray(new Node[preorder.size()]);
- }
-
- @SuppressWarnings("unchecked")
- private void printAST(final StringBuilder sb, final List<Node> preorder, final Field field, final String name, final Node node, final int indent) {
- ASTWriter.indent(sb, indent);
- if (node == null) {
- sb.append("[Object ");
- sb.append(name);
- sb.append(" null]\n");
- return;
- }
-
- if (preorder != null) {
- preorder.add(node);
- }
-
- final boolean isReference = field != null && field.isAnnotationPresent(Reference.class);
-
- final Class<?> clazz = node.getClass();
- String type = clazz.getName();
-
- type = type.substring(type.lastIndexOf('.') + 1, type.length());
- int truncate = type.indexOf("Node");
- if (truncate == -1) {
- truncate = type.indexOf("Statement");
- }
- if (truncate != -1) {
- type = type.substring(0, truncate);
- }
- type = type.toLowerCase();
-
- if (isReference) {
- type = "ref: " + type;
- }
- final Symbol symbol;
- if (node instanceof IdentNode) {
- symbol = ((IdentNode)node).getSymbol();
- } else {
- symbol = null;
- }
-
- if (symbol != null) {
- type += ">" + symbol;
- }
-
- if (node instanceof Block && ((Block)node).needsScope()) {
- type += " <scope>";
- }
-
- final List<Field> children = new LinkedList<>();
-
- if (!isReference) {
- enqueueChildren(node, clazz, children);
- }
-
- String status = "";
-
- if (node instanceof Terminal && ((Terminal)node).isTerminal()) {
- status += " Terminal";
- }
-
- if (node instanceof Statement && ((Statement)node).hasGoto()) {
- status += " Goto ";
- }
-
- if (symbol != null) {
- status += symbol;
- }
-
- status = status.trim();
- if (!"".equals(status)) {
- status = " [" + status + "]";
- }
-
- if (symbol != null) {
- String tname = ((Expression)node).getType().toString();
- if (tname.indexOf('.') != -1) {
- tname = tname.substring(tname.lastIndexOf('.') + 1, tname.length());
- }
- status += " (" + tname + ")";
- }
-
- status += " @" + Debug.id(node);
-
- if (children.isEmpty()) {
- sb.append("[").
- append(type).
- append(' ').
- append(name).
- append(" = '").
- append(node).
- append("'").
- append(status).
- append("] ").
- append('\n');
- } else {
- sb.append("[").
- append(type).
- append(' ').
- append(name).
- append(' ').
- append(Token.toString(node.getToken())).
- append(status).
- append("]").
- append('\n');
-
- for (final Field child : children) {
- if (child.isAnnotationPresent(Ignore.class)) {
- continue;
- }
-
- Object value;
- try {
- value = child.get(node);
- } catch (final IllegalArgumentException | IllegalAccessException e) {
- Context.printStackTrace(e);
- return;
- }
-
- if (value instanceof Node) {
- printAST(sb, preorder, child, child.getName(), (Node)value, indent + 1);
- } else if (value instanceof Collection) {
- int pos = 0;
- ASTWriter.indent(sb, indent + 1);
- sb.append('[').
- append(child.getName()).
- append("[0..").
- append(((Collection<Node>)value).size()).
- append("]]").
- append('\n');
-
- for (final Node member : (Collection<Node>)value) {
- printAST(sb, preorder, child, child.getName() + "[" + pos++ + "]", member, indent + 2);
- }
- }
- }
- }
- }
-
- private static void enqueueChildren(final Node node, final Class<?> nodeClass, final List<Field> children) {
- final Deque<Class<?>> stack = new ArrayDeque<>();
-
- /**
- * Here is some ugliness that can be overcome by proper ChildNode annotations
- * with proper orders. Right now we basically sort all classes up to Node
- * with super class first, as this often is the natural order, e.g. base
- * before index for an IndexNode.
- *
- * Also there are special cases as this is not true for UnaryNodes(lhs) and
- * BinaryNodes extends UnaryNode (with lhs), and TernaryNodes.
- *
- * TODO - generalize traversal with an order built on annotations and this
- * will go away.
- */
- Class<?> clazz = nodeClass;
- do {
- stack.push(clazz);
- clazz = clazz.getSuperclass();
- } while (clazz != null);
-
- if (node instanceof TernaryNode) {
- // HACK juggle "third"
- stack.push(stack.removeLast());
- }
- // HACK change operator order for BinaryNodes to get lhs first.
- final Iterator<Class<?>> iter = node instanceof BinaryNode ? stack.descendingIterator() : stack.iterator();
-
- while (iter.hasNext()) {
- final Class<?> c = iter.next();
- for (final Field f : c.getDeclaredFields()) {
- try {
- f.setAccessible(true);
- final Object child = f.get(node);
- if (child == null) {
- continue;
- }
-
- if (child instanceof Node) {
- children.add(f);
- } else if (child instanceof Collection) {
- if (!((Collection<?>)child).isEmpty()) {
- children.add(f);
- }
- }
- } catch (final IllegalArgumentException | IllegalAccessException e) {
- return;
- }
- }
- }
- }
-
- private static void indent(final StringBuilder sb, final int indent) {
- for (int i = 0; i < indent; i++) {
- for (int j = 0; j < TABWIDTH; j++) {
- sb.append(' ');
- }
- }
- }
-}