8005842: Loops in ASTWriter. Corrected @Reference and @Ignore node annotation for IR nodes

Tue, 08 Jan 2013 15:20:40 +0100

author
lagergren
date
Tue, 08 Jan 2013 15:20:40 +0100
changeset 16
69a4f0363d0f
parent 15
4620ac94e7dc
child 17
548587cfb065

8005842: Loops in ASTWriter. Corrected @Reference and @Ignore node annotation for IR nodes
Reviewed-by: hannesw, sundar

src/jdk/nashorn/internal/ir/Block.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/FunctionNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LabelNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/LabeledNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ObjectNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ReferenceNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ReturnNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/SplitNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/SwitchNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/ThrowNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/TryNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/debug/ASTWriter.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/internal/ir/Block.java	Tue Jan 08 14:14:17 2013 +0100
     1.2 +++ b/src/jdk/nashorn/internal/ir/Block.java	Tue Jan 08 15:20:40 2013 +0100
     1.3 @@ -44,7 +44,6 @@
     1.4  import jdk.nashorn.internal.codegen.MethodEmitter.Label;
     1.5  import jdk.nashorn.internal.ir.annotations.Ignore;
     1.6  import jdk.nashorn.internal.ir.annotations.ParentNode;
     1.7 -import jdk.nashorn.internal.ir.annotations.Reference;
     1.8  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
     1.9  import jdk.nashorn.internal.runtime.Source;
    1.10  
    1.11 @@ -55,11 +54,11 @@
    1.12   */
    1.13  public class Block extends Node {
    1.14      /** Parent context */
    1.15 -    @ParentNode @Reference
    1.16 +    @ParentNode @Ignore
    1.17      private Block parent;
    1.18  
    1.19      /** Owning function. */
    1.20 -    @Ignore @Reference
    1.21 +    @Ignore //don't print it, it is apparent in the tree
    1.22      protected FunctionNode function;
    1.23  
    1.24      /** List of statements */
     2.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Tue Jan 08 14:14:17 2013 +0100
     2.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Tue Jan 08 15:20:40 2013 +0100
     2.3 @@ -46,7 +46,6 @@
     2.4  import jdk.nashorn.internal.codegen.Transform;
     2.5  import jdk.nashorn.internal.codegen.types.Type;
     2.6  import jdk.nashorn.internal.ir.annotations.Ignore;
     2.7 -import jdk.nashorn.internal.ir.annotations.Reference;
     2.8  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
     2.9  import jdk.nashorn.internal.parser.Parser;
    2.10  import jdk.nashorn.internal.runtime.Source;
    2.11 @@ -142,11 +141,11 @@
    2.12      private final List<VarNode> declarations;
    2.13  
    2.14      /** VarNode for this function statement */
    2.15 -    @Reference @Ignore //this is explicit code anyway and should not be traverseda after lower
    2.16 +    @Ignore //this is explicit code anyway and should not be traversed after lower
    2.17      private VarNode funcVarNode;
    2.18  
    2.19      /** Line number for function declaration */
    2.20 -    @Reference @Ignore
    2.21 +    @Ignore
    2.22      private LineNumberNode funcVarLineNumberNode;
    2.23  
    2.24      /** Function flags. */
     3.1 --- a/src/jdk/nashorn/internal/ir/LabelNode.java	Tue Jan 08 14:14:17 2013 +0100
     3.2 +++ b/src/jdk/nashorn/internal/ir/LabelNode.java	Tue Jan 08 15:20:40 2013 +0100
     3.3 @@ -25,7 +25,7 @@
     3.4  
     3.5  package jdk.nashorn.internal.ir;
     3.6  
     3.7 -import jdk.nashorn.internal.ir.annotations.Reference;
     3.8 +import jdk.nashorn.internal.ir.annotations.Ignore;
     3.9  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    3.10  import jdk.nashorn.internal.runtime.Source;
    3.11  
    3.12 @@ -42,11 +42,11 @@
    3.13      private Block body;
    3.14  
    3.15      /** Node to break from. */
    3.16 -    @Reference
    3.17 +    @Ignore
    3.18      private Node breakNode;
    3.19  
    3.20      /** Node to continue. */
    3.21 -    @Reference
    3.22 +    @Ignore
    3.23      private Node continueNode;
    3.24  
    3.25      /**
     4.1 --- a/src/jdk/nashorn/internal/ir/LabeledNode.java	Tue Jan 08 14:14:17 2013 +0100
     4.2 +++ b/src/jdk/nashorn/internal/ir/LabeledNode.java	Tue Jan 08 15:20:40 2013 +0100
     4.3 @@ -26,7 +26,6 @@
     4.4  package jdk.nashorn.internal.ir;
     4.5  
     4.6  import jdk.nashorn.internal.ir.annotations.Ignore;
     4.7 -import jdk.nashorn.internal.ir.annotations.Reference;
     4.8  import jdk.nashorn.internal.runtime.Source;
     4.9  
    4.10  /**
    4.11 @@ -39,11 +38,11 @@
    4.12      protected final LabelNode labelNode;
    4.13  
    4.14      /** Target control node. */
    4.15 -    @Reference @Ignore
    4.16 +    @Ignore
    4.17      protected final Node targetNode;
    4.18  
    4.19      /** Try chain. */
    4.20 -    @Reference
    4.21 +    @Ignore
    4.22      protected final TryNode tryChain;
    4.23  
    4.24      /** scope nesting level */
     5.1 --- a/src/jdk/nashorn/internal/ir/ObjectNode.java	Tue Jan 08 14:14:17 2013 +0100
     5.2 +++ b/src/jdk/nashorn/internal/ir/ObjectNode.java	Tue Jan 08 15:20:40 2013 +0100
     5.3 @@ -29,7 +29,6 @@
     5.4  import java.util.Collections;
     5.5  import java.util.List;
     5.6  import jdk.nashorn.internal.ir.annotations.Ignore;
     5.7 -import jdk.nashorn.internal.ir.annotations.Reference;
     5.8  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
     5.9  import jdk.nashorn.internal.runtime.Source;
    5.10  
    5.11 @@ -38,7 +37,7 @@
    5.12   */
    5.13  public class ObjectNode extends Node {
    5.14      /** Literal context. */
    5.15 -    @Reference @Ignore
    5.16 +    @Ignore
    5.17      private Block context;
    5.18  
    5.19      /** Literal elements. */
     6.1 --- a/src/jdk/nashorn/internal/ir/ReferenceNode.java	Tue Jan 08 14:14:17 2013 +0100
     6.2 +++ b/src/jdk/nashorn/internal/ir/ReferenceNode.java	Tue Jan 08 15:20:40 2013 +0100
     6.3 @@ -25,7 +25,6 @@
     6.4  
     6.5  package jdk.nashorn.internal.ir;
     6.6  
     6.7 -import jdk.nashorn.internal.ir.annotations.Ignore;
     6.8  import jdk.nashorn.internal.ir.annotations.Reference;
     6.9  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    6.10  import jdk.nashorn.internal.runtime.Source;
    6.11 @@ -35,7 +34,7 @@
    6.12   */
    6.13  public class ReferenceNode extends Node {
    6.14      /** Node referenced. */
    6.15 -    @Reference @Ignore
    6.16 +    @Reference
    6.17      private final FunctionNode reference;
    6.18  
    6.19      /**
     7.1 --- a/src/jdk/nashorn/internal/ir/ReturnNode.java	Tue Jan 08 14:14:17 2013 +0100
     7.2 +++ b/src/jdk/nashorn/internal/ir/ReturnNode.java	Tue Jan 08 15:20:40 2013 +0100
     7.3 @@ -29,7 +29,6 @@
     7.4  import static jdk.nashorn.internal.parser.TokenType.YIELD;
     7.5  
     7.6  import jdk.nashorn.internal.ir.annotations.Ignore;
     7.7 -import jdk.nashorn.internal.ir.annotations.Reference;
     7.8  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
     7.9  import jdk.nashorn.internal.runtime.Source;
    7.10  
    7.11 @@ -42,7 +41,7 @@
    7.12      private Node expression;
    7.13  
    7.14      /** Try chain. */
    7.15 -    @Reference @Ignore
    7.16 +    @Ignore
    7.17      private final TryNode tryChain;
    7.18  
    7.19      /**
     8.1 --- a/src/jdk/nashorn/internal/ir/SplitNode.java	Tue Jan 08 14:14:17 2013 +0100
     8.2 +++ b/src/jdk/nashorn/internal/ir/SplitNode.java	Tue Jan 08 15:20:40 2013 +0100
     8.3 @@ -30,6 +30,8 @@
     8.4  import java.util.List;
     8.5  import jdk.nashorn.internal.codegen.CompileUnit;
     8.6  import jdk.nashorn.internal.codegen.MethodEmitter;
     8.7 +import jdk.nashorn.internal.ir.annotations.Ignore;
     8.8 +import jdk.nashorn.internal.ir.annotations.Reference;
     8.9  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    8.10  
    8.11  
    8.12 @@ -50,15 +52,18 @@
    8.13      private MethodEmitter caller;
    8.14  
    8.15      /** Containing function. */
    8.16 +    @Reference
    8.17      private final FunctionNode functionNode;
    8.18  
    8.19      /** A list of target labels in parent methods this split node may encounter. */
    8.20 +    @Ignore
    8.21      private final List<MethodEmitter.Label> externalTargets;
    8.22  
    8.23      /** True if this split node or any of its children contain a return statement. */
    8.24      private boolean hasReturn;
    8.25  
    8.26      /** Body of split code. */
    8.27 +    @Ignore
    8.28      private Node body;
    8.29  
    8.30      /**
     9.1 --- a/src/jdk/nashorn/internal/ir/SwitchNode.java	Tue Jan 08 14:14:17 2013 +0100
     9.2 +++ b/src/jdk/nashorn/internal/ir/SwitchNode.java	Tue Jan 08 15:20:40 2013 +0100
     9.3 @@ -30,7 +30,6 @@
     9.4  import java.util.List;
     9.5  import jdk.nashorn.internal.codegen.MethodEmitter.Label;
     9.6  import jdk.nashorn.internal.ir.annotations.Ignore;
     9.7 -import jdk.nashorn.internal.ir.annotations.Reference;
     9.8  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
     9.9  import jdk.nashorn.internal.runtime.Source;
    9.10  
    9.11 @@ -48,7 +47,7 @@
    9.12      private List<CaseNode> cases;
    9.13  
    9.14      /** Switch default. */
    9.15 -    @Reference @Ignore //points to one of the members in the list above, don't traverse twice
    9.16 +    @Ignore //points to one of the members in the list above, don't traverse twice
    9.17      private CaseNode defaultCase;
    9.18  
    9.19      /**
    10.1 --- a/src/jdk/nashorn/internal/ir/ThrowNode.java	Tue Jan 08 14:14:17 2013 +0100
    10.2 +++ b/src/jdk/nashorn/internal/ir/ThrowNode.java	Tue Jan 08 15:20:40 2013 +0100
    10.3 @@ -26,7 +26,6 @@
    10.4  package jdk.nashorn.internal.ir;
    10.5  
    10.6  import jdk.nashorn.internal.ir.annotations.Ignore;
    10.7 -import jdk.nashorn.internal.ir.annotations.Reference;
    10.8  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    10.9  import jdk.nashorn.internal.runtime.Source;
   10.10  
   10.11 @@ -38,7 +37,7 @@
   10.12      private Node expression;
   10.13  
   10.14      /** Try chain. */
   10.15 -    @Reference @Ignore
   10.16 +    @Ignore
   10.17      private final TryNode tryChain;
   10.18  
   10.19      /**
    11.1 --- a/src/jdk/nashorn/internal/ir/TryNode.java	Tue Jan 08 14:14:17 2013 +0100
    11.2 +++ b/src/jdk/nashorn/internal/ir/TryNode.java	Tue Jan 08 15:20:40 2013 +0100
    11.3 @@ -29,7 +29,7 @@
    11.4  import java.util.Collections;
    11.5  import java.util.List;
    11.6  import jdk.nashorn.internal.codegen.MethodEmitter.Label;
    11.7 -import jdk.nashorn.internal.ir.annotations.Reference;
    11.8 +import jdk.nashorn.internal.ir.annotations.Ignore;
    11.9  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   11.10  import jdk.nashorn.internal.runtime.Source;
   11.11  
   11.12 @@ -38,7 +38,7 @@
   11.13   */
   11.14  public class TryNode extends Node {
   11.15      /** Try chain. */
   11.16 -    @Reference
   11.17 +    @Ignore //don't print, will be apparent from the AST
   11.18      private TryNode next;
   11.19  
   11.20      /** Try statements. */
    12.1 --- a/src/jdk/nashorn/internal/ir/debug/ASTWriter.java	Tue Jan 08 14:14:17 2013 +0100
    12.2 +++ b/src/jdk/nashorn/internal/ir/debug/ASTWriter.java	Tue Jan 08 15:20:40 2013 +0100
    12.3 @@ -71,12 +71,12 @@
    12.4      @Override
    12.5      public String toString() {
    12.6          final StringBuilder sb = new StringBuilder();
    12.7 -        printAST(sb, "root", root, 0);
    12.8 +        printAST(sb, null, "root", root, 0);
    12.9          return sb.toString();
   12.10      }
   12.11  
   12.12      @SuppressWarnings("unchecked")
   12.13 -    private void printAST(final StringBuilder sb, final String name, final Node node, final int indent) {
   12.14 +    private void printAST(final StringBuilder sb, final Field field, final String name, final Node node, final int indent) {
   12.15          ASTWriter.indent(sb, indent);
   12.16          if (node == null) {
   12.17              sb.append("[Object ");
   12.18 @@ -85,59 +85,18 @@
   12.19              return;
   12.20          }
   12.21  
   12.22 +        final boolean isReference = field != null && field.getAnnotation(Reference.class) != null;
   12.23 +
   12.24          Class<?> clazz = node.getClass();
   12.25 -        String type    = clazz.getName();
   12.26 +        String   type  = clazz.getName();
   12.27 +
   12.28          type = type.substring(type.lastIndexOf('.') + 1, type.length());
   12.29 - //       type += "@" + Debug.id(node) + "#" + node.getSymbol();
   12.30 +//        type += "@" + Debug.id(node) + "#" + node.getSymbol();
   12.31  
   12.32          final List<Field> children = new LinkedList<>();
   12.33 -        final Deque<Class<?>> stack = new ArrayDeque<>();
   12.34  
   12.35 -        /**
   12.36 -         * Here is some ugliness that can be overcome by proper ChildNode annotations
   12.37 -         * with proper orders. Right now we basically sort all classes up to Node
   12.38 -         * with super class first, as this often is the natural order, e.g. base
   12.39 -         * before index for an IndexNode.
   12.40 -         *
   12.41 -         * Also there are special cases as this is not true for UnaryNodes(lhs) and
   12.42 -         * BinaryNodes extends UnaryNode (with lhs), and TernaryNodes.
   12.43 -         *
   12.44 -         * TODO - generalize traversal with an order built on annotations and this
   12.45 -         * will go away.
   12.46 -         */
   12.47 -        do {
   12.48 -            stack.push(clazz);
   12.49 -            clazz = clazz.getSuperclass();
   12.50 -        } while (clazz != null);
   12.51 -
   12.52 -        if (node instanceof TernaryNode) {
   12.53 -            // HACK juggle "third"
   12.54 -            stack.push(stack.removeLast());
   12.55 -        }
   12.56 -        // HACK change operator order for BinaryNodes to get lhs first.
   12.57 -        final Iterator<Class<?>> iter = node instanceof BinaryNode ? stack.descendingIterator() : stack.iterator();
   12.58 -
   12.59 -        while (iter.hasNext()) {
   12.60 -            final Class<?> c = iter.next();
   12.61 -            for (final Field f : c.getDeclaredFields()) {
   12.62 -                try {
   12.63 -                    f.setAccessible(true);
   12.64 -                    final Object child = f.get(node);
   12.65 -                    if (child == null) {
   12.66 -                        continue;
   12.67 -                    }
   12.68 -
   12.69 -                    if (child instanceof Node) {
   12.70 -                        children.add(f);
   12.71 -                    } else if (child instanceof Collection) {
   12.72 -                        if (!((Collection<?>)child).isEmpty()) {
   12.73 -                            children.add(f);
   12.74 -                        }
   12.75 -                    }
   12.76 -                } catch (final IllegalArgumentException | IllegalAccessException e) {
   12.77 -                    return;
   12.78 -                }
   12.79 -            }
   12.80 +        if (!isReference) {
   12.81 +            enqueueChildren(node, clazz, children);
   12.82          }
   12.83  
   12.84          String status = "";
   12.85 @@ -193,52 +152,98 @@
   12.86                  append("]").
   12.87                  append('\n');
   12.88  
   12.89 -            for (final Field field : children) {
   12.90 -
   12.91 -                if (field.getAnnotation(ParentNode.class) != null) {
   12.92 +            for (final Field child : children) {
   12.93 +                if (child.getAnnotation(ParentNode.class) != null) {
   12.94                      continue;
   12.95 -                }
   12.96 -                if (field.getAnnotation(Ignore.class) != null) {
   12.97 -                    continue;
   12.98 -                }
   12.99 -                if (field.getAnnotation(Reference.class) != null) {
  12.100 +                } else if (child.getAnnotation(Ignore.class) != null) {
  12.101                      continue;
  12.102                  }
  12.103  
  12.104                  Object value;
  12.105                  try {
  12.106 -                    value = field.get(node);
  12.107 +                    value = child.get(node);
  12.108                  } catch (final IllegalArgumentException | IllegalAccessException e) {
  12.109                      Context.printStackTrace(e);
  12.110                      return;
  12.111                  }
  12.112  
  12.113                  if (value instanceof Node) {
  12.114 -                    printAST(sb, field.getName(), (Node)value, indent + 1);
  12.115 +                    printAST(sb, child, child.getName(), (Node)value, indent + 1);
  12.116                  } else if (value instanceof Collection) {
  12.117                      int pos = 0;
  12.118                      ASTWriter.indent(sb, indent + 1);
  12.119                      sb.append("[Collection ").
  12.120 -                        append(field.getName()).
  12.121 +                        append(child.getName()).
  12.122                          append("[0..").
  12.123                          append(((Collection<Node>)value).size()).
  12.124                          append("]]").
  12.125                          append('\n');
  12.126  
  12.127 -                    for (final Node child : (Collection<Node>)value) {
  12.128 -                        printAST(sb, field.getName() + "[" + pos++ + "]", child, indent + 2);
  12.129 +                    for (final Node member : (Collection<Node>)value) {
  12.130 +                        printAST(sb, child, child.getName() + "[" + pos++ + "]", member, indent + 2);
  12.131                      }
  12.132                  }
  12.133              }
  12.134          }
  12.135      }
  12.136  
  12.137 +    private static void enqueueChildren(final Node node, final Class<?> nodeClass, final List<Field> children) {
  12.138 +        final Deque<Class<?>> stack = new ArrayDeque<>();
  12.139 +
  12.140 +        /**
  12.141 +         * Here is some ugliness that can be overcome by proper ChildNode annotations
  12.142 +         * with proper orders. Right now we basically sort all classes up to Node
  12.143 +         * with super class first, as this often is the natural order, e.g. base
  12.144 +         * before index for an IndexNode.
  12.145 +         *
  12.146 +         * Also there are special cases as this is not true for UnaryNodes(lhs) and
  12.147 +         * BinaryNodes extends UnaryNode (with lhs), and TernaryNodes.
  12.148 +         *
  12.149 +         * TODO - generalize traversal with an order built on annotations and this
  12.150 +         * will go away.
  12.151 +         */
  12.152 +        Class<?> clazz = nodeClass;
  12.153 +        do {
  12.154 +            stack.push(clazz);
  12.155 +            clazz = clazz.getSuperclass();
  12.156 +        } while (clazz != null);
  12.157 +
  12.158 +        if (node instanceof TernaryNode) {
  12.159 +            // HACK juggle "third"
  12.160 +            stack.push(stack.removeLast());
  12.161 +        }
  12.162 +        // HACK change operator order for BinaryNodes to get lhs first.
  12.163 +        final Iterator<Class<?>> iter = node instanceof BinaryNode ? stack.descendingIterator() : stack.iterator();
  12.164 +
  12.165 +        while (iter.hasNext()) {
  12.166 +            final Class<?> c = iter.next();
  12.167 +            for (final Field f : c.getDeclaredFields()) {
  12.168 +                try {
  12.169 +                    f.setAccessible(true);
  12.170 +                    final Object child = f.get(node);
  12.171 +                    if (child == null) {
  12.172 +                        continue;
  12.173 +                    }
  12.174 +
  12.175 +                    if (child instanceof Node) {
  12.176 +                        children.add(f);
  12.177 +                    } else if (child instanceof Collection) {
  12.178 +                        if (!((Collection<?>)child).isEmpty()) {
  12.179 +                            children.add(f);
  12.180 +                        }
  12.181 +                    }
  12.182 +                } catch (final IllegalArgumentException | IllegalAccessException e) {
  12.183 +                    return;
  12.184 +                }
  12.185 +            }
  12.186 +        }
  12.187 +    }
  12.188 +
  12.189      private static void indent(final StringBuilder sb, final int indent) {
  12.190          for (int i = 0; i < indent; i++) {
  12.191 -            for (int j = 0 ; j < TABWIDTH ; j++) {
  12.192 +            for (int j = 0; j < TABWIDTH; j++) {
  12.193                  sb.append(' ');
  12.194              }
  12.195          }
  12.196      }
  12.197 -
  12.198  }

mercurial