8005842: Loops in ASTWriter. Corrected @Reference and @Ignore node annotation for IR nodes
Reviewed-by: hannesw, sundar
This commit is contained in:
parent
df21b0860f
commit
dd47345d51
@ -44,7 +44,6 @@ import jdk.nashorn.internal.codegen.Frame;
|
|||||||
import jdk.nashorn.internal.codegen.MethodEmitter.Label;
|
import jdk.nashorn.internal.codegen.MethodEmitter.Label;
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.annotations.ParentNode;
|
import jdk.nashorn.internal.ir.annotations.ParentNode;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
@ -55,11 +54,11 @@ import jdk.nashorn.internal.runtime.Source;
|
|||||||
*/
|
*/
|
||||||
public class Block extends Node {
|
public class Block extends Node {
|
||||||
/** Parent context */
|
/** Parent context */
|
||||||
@ParentNode @Reference
|
@ParentNode @Ignore
|
||||||
private Block parent;
|
private Block parent;
|
||||||
|
|
||||||
/** Owning function. */
|
/** Owning function. */
|
||||||
@Ignore @Reference
|
@Ignore //don't print it, it is apparent in the tree
|
||||||
protected FunctionNode function;
|
protected FunctionNode function;
|
||||||
|
|
||||||
/** List of statements */
|
/** List of statements */
|
||||||
|
@ -46,7 +46,6 @@ import jdk.nashorn.internal.codegen.Splitter;
|
|||||||
import jdk.nashorn.internal.codegen.Transform;
|
import jdk.nashorn.internal.codegen.Transform;
|
||||||
import jdk.nashorn.internal.codegen.types.Type;
|
import jdk.nashorn.internal.codegen.types.Type;
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.parser.Parser;
|
import jdk.nashorn.internal.parser.Parser;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
@ -142,11 +141,11 @@ public class FunctionNode extends Block {
|
|||||||
private final List<VarNode> declarations;
|
private final List<VarNode> declarations;
|
||||||
|
|
||||||
/** VarNode for this function statement */
|
/** VarNode for this function statement */
|
||||||
@Reference @Ignore //this is explicit code anyway and should not be traverseda after lower
|
@Ignore //this is explicit code anyway and should not be traversed after lower
|
||||||
private VarNode funcVarNode;
|
private VarNode funcVarNode;
|
||||||
|
|
||||||
/** Line number for function declaration */
|
/** Line number for function declaration */
|
||||||
@Reference @Ignore
|
@Ignore
|
||||||
private LineNumberNode funcVarLineNumberNode;
|
private LineNumberNode funcVarLineNumberNode;
|
||||||
|
|
||||||
/** Function flags. */
|
/** Function flags. */
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
package jdk.nashorn.internal.ir;
|
package jdk.nashorn.internal.ir;
|
||||||
|
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
@ -42,11 +42,11 @@ public class LabelNode extends Node {
|
|||||||
private Block body;
|
private Block body;
|
||||||
|
|
||||||
/** Node to break from. */
|
/** Node to break from. */
|
||||||
@Reference
|
@Ignore
|
||||||
private Node breakNode;
|
private Node breakNode;
|
||||||
|
|
||||||
/** Node to continue. */
|
/** Node to continue. */
|
||||||
@Reference
|
@Ignore
|
||||||
private Node continueNode;
|
private Node continueNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package jdk.nashorn.internal.ir;
|
package jdk.nashorn.internal.ir;
|
||||||
|
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,11 +38,11 @@ public abstract class LabeledNode extends Node {
|
|||||||
protected final LabelNode labelNode;
|
protected final LabelNode labelNode;
|
||||||
|
|
||||||
/** Target control node. */
|
/** Target control node. */
|
||||||
@Reference @Ignore
|
@Ignore
|
||||||
protected final Node targetNode;
|
protected final Node targetNode;
|
||||||
|
|
||||||
/** Try chain. */
|
/** Try chain. */
|
||||||
@Reference
|
@Ignore
|
||||||
protected final TryNode tryChain;
|
protected final TryNode tryChain;
|
||||||
|
|
||||||
/** scope nesting level */
|
/** scope nesting level */
|
||||||
|
@ -29,7 +29,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ import jdk.nashorn.internal.runtime.Source;
|
|||||||
*/
|
*/
|
||||||
public class ObjectNode extends Node {
|
public class ObjectNode extends Node {
|
||||||
/** Literal context. */
|
/** Literal context. */
|
||||||
@Reference @Ignore
|
@Ignore
|
||||||
private Block context;
|
private Block context;
|
||||||
|
|
||||||
/** Literal elements. */
|
/** Literal elements. */
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package jdk.nashorn.internal.ir;
|
package jdk.nashorn.internal.ir;
|
||||||
|
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
import jdk.nashorn.internal.ir.annotations.Reference;
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
@ -35,7 +34,7 @@ import jdk.nashorn.internal.runtime.Source;
|
|||||||
*/
|
*/
|
||||||
public class ReferenceNode extends Node {
|
public class ReferenceNode extends Node {
|
||||||
/** Node referenced. */
|
/** Node referenced. */
|
||||||
@Reference @Ignore
|
@Reference
|
||||||
private final FunctionNode reference;
|
private final FunctionNode reference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +29,6 @@ import static jdk.nashorn.internal.parser.TokenType.RETURN;
|
|||||||
import static jdk.nashorn.internal.parser.TokenType.YIELD;
|
import static jdk.nashorn.internal.parser.TokenType.YIELD;
|
||||||
|
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
@ -42,7 +41,7 @@ public class ReturnNode extends Node {
|
|||||||
private Node expression;
|
private Node expression;
|
||||||
|
|
||||||
/** Try chain. */
|
/** Try chain. */
|
||||||
@Reference @Ignore
|
@Ignore
|
||||||
private final TryNode tryChain;
|
private final TryNode tryChain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,6 +30,8 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jdk.nashorn.internal.codegen.CompileUnit;
|
import jdk.nashorn.internal.codegen.CompileUnit;
|
||||||
import jdk.nashorn.internal.codegen.MethodEmitter;
|
import jdk.nashorn.internal.codegen.MethodEmitter;
|
||||||
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
|
import jdk.nashorn.internal.ir.annotations.Reference;
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
|
|
||||||
|
|
||||||
@ -50,15 +52,18 @@ public class SplitNode extends Node {
|
|||||||
private MethodEmitter caller;
|
private MethodEmitter caller;
|
||||||
|
|
||||||
/** Containing function. */
|
/** Containing function. */
|
||||||
|
@Reference
|
||||||
private final FunctionNode functionNode;
|
private final FunctionNode functionNode;
|
||||||
|
|
||||||
/** A list of target labels in parent methods this split node may encounter. */
|
/** A list of target labels in parent methods this split node may encounter. */
|
||||||
|
@Ignore
|
||||||
private final List<MethodEmitter.Label> externalTargets;
|
private final List<MethodEmitter.Label> externalTargets;
|
||||||
|
|
||||||
/** True if this split node or any of its children contain a return statement. */
|
/** True if this split node or any of its children contain a return statement. */
|
||||||
private boolean hasReturn;
|
private boolean hasReturn;
|
||||||
|
|
||||||
/** Body of split code. */
|
/** Body of split code. */
|
||||||
|
@Ignore
|
||||||
private Node body;
|
private Node body;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,6 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jdk.nashorn.internal.codegen.MethodEmitter.Label;
|
import jdk.nashorn.internal.codegen.MethodEmitter.Label;
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ public class SwitchNode extends BreakableNode {
|
|||||||
private List<CaseNode> cases;
|
private List<CaseNode> cases;
|
||||||
|
|
||||||
/** Switch default. */
|
/** Switch default. */
|
||||||
@Reference @Ignore //points to one of the members in the list above, don't traverse twice
|
@Ignore //points to one of the members in the list above, don't traverse twice
|
||||||
private CaseNode defaultCase;
|
private CaseNode defaultCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package jdk.nashorn.internal.ir;
|
package jdk.nashorn.internal.ir;
|
||||||
|
|
||||||
import jdk.nashorn.internal.ir.annotations.Ignore;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ public class ThrowNode extends Node {
|
|||||||
private Node expression;
|
private Node expression;
|
||||||
|
|
||||||
/** Try chain. */
|
/** Try chain. */
|
||||||
@Reference @Ignore
|
@Ignore
|
||||||
private final TryNode tryChain;
|
private final TryNode tryChain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,7 +29,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jdk.nashorn.internal.codegen.MethodEmitter.Label;
|
import jdk.nashorn.internal.codegen.MethodEmitter.Label;
|
||||||
import jdk.nashorn.internal.ir.annotations.Reference;
|
import jdk.nashorn.internal.ir.annotations.Ignore;
|
||||||
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
import jdk.nashorn.internal.ir.visitor.NodeVisitor;
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ import jdk.nashorn.internal.runtime.Source;
|
|||||||
*/
|
*/
|
||||||
public class TryNode extends Node {
|
public class TryNode extends Node {
|
||||||
/** Try chain. */
|
/** Try chain. */
|
||||||
@Reference
|
@Ignore //don't print, will be apparent from the AST
|
||||||
private TryNode next;
|
private TryNode next;
|
||||||
|
|
||||||
/** Try statements. */
|
/** Try statements. */
|
||||||
|
@ -71,12 +71,12 @@ public final class ASTWriter {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
printAST(sb, "root", root, 0);
|
printAST(sb, null, "root", root, 0);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void printAST(final StringBuilder sb, final String name, final Node node, final int indent) {
|
private void printAST(final StringBuilder sb, final Field field, final String name, final Node node, final int indent) {
|
||||||
ASTWriter.indent(sb, indent);
|
ASTWriter.indent(sb, indent);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
sb.append("[Object ");
|
sb.append("[Object ");
|
||||||
@ -85,59 +85,18 @@ public final class ASTWriter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean isReference = field != null && field.getAnnotation(Reference.class) != null;
|
||||||
|
|
||||||
Class<?> clazz = node.getClass();
|
Class<?> clazz = node.getClass();
|
||||||
String type = clazz.getName();
|
String type = clazz.getName();
|
||||||
|
|
||||||
type = type.substring(type.lastIndexOf('.') + 1, type.length());
|
type = type.substring(type.lastIndexOf('.') + 1, type.length());
|
||||||
// type += "@" + Debug.id(node) + "#" + node.getSymbol();
|
// type += "@" + Debug.id(node) + "#" + node.getSymbol();
|
||||||
|
|
||||||
final List<Field> children = new LinkedList<>();
|
final List<Field> children = new LinkedList<>();
|
||||||
final Deque<Class<?>> stack = new ArrayDeque<>();
|
|
||||||
|
|
||||||
/**
|
if (!isReference) {
|
||||||
* Here is some ugliness that can be overcome by proper ChildNode annotations
|
enqueueChildren(node, clazz, children);
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String status = "";
|
String status = "";
|
||||||
@ -193,52 +152,98 @@ public final class ASTWriter {
|
|||||||
append("]").
|
append("]").
|
||||||
append('\n');
|
append('\n');
|
||||||
|
|
||||||
for (final Field field : children) {
|
for (final Field child : children) {
|
||||||
|
if (child.getAnnotation(ParentNode.class) != null) {
|
||||||
if (field.getAnnotation(ParentNode.class) != null) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (child.getAnnotation(Ignore.class) != null) {
|
||||||
if (field.getAnnotation(Ignore.class) != null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (field.getAnnotation(Reference.class) != null) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object value;
|
Object value;
|
||||||
try {
|
try {
|
||||||
value = field.get(node);
|
value = child.get(node);
|
||||||
} catch (final IllegalArgumentException | IllegalAccessException e) {
|
} catch (final IllegalArgumentException | IllegalAccessException e) {
|
||||||
Context.printStackTrace(e);
|
Context.printStackTrace(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof Node) {
|
if (value instanceof Node) {
|
||||||
printAST(sb, field.getName(), (Node)value, indent + 1);
|
printAST(sb, child, child.getName(), (Node)value, indent + 1);
|
||||||
} else if (value instanceof Collection) {
|
} else if (value instanceof Collection) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
ASTWriter.indent(sb, indent + 1);
|
ASTWriter.indent(sb, indent + 1);
|
||||||
sb.append("[Collection ").
|
sb.append("[Collection ").
|
||||||
append(field.getName()).
|
append(child.getName()).
|
||||||
append("[0..").
|
append("[0..").
|
||||||
append(((Collection<Node>)value).size()).
|
append(((Collection<Node>)value).size()).
|
||||||
append("]]").
|
append("]]").
|
||||||
append('\n');
|
append('\n');
|
||||||
|
|
||||||
for (final Node child : (Collection<Node>)value) {
|
for (final Node member : (Collection<Node>)value) {
|
||||||
printAST(sb, field.getName() + "[" + pos++ + "]", child, indent + 2);
|
printAST(sb, 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) {
|
private static void indent(final StringBuilder sb, final int indent) {
|
||||||
for (int i = 0; i < indent; i++) {
|
for (int i = 0; i < indent; i++) {
|
||||||
for (int j = 0 ; j < TABWIDTH ; j++) {
|
for (int j = 0; j < TABWIDTH; j++) {
|
||||||
sb.append(' ');
|
sb.append(' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user