View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.lang.ecmascript.ast;
    5
    6   import java.io.IOException;
    7   import java.io.PrintWriter;
    8   import java.io.Writer;
    9   import java.util.ArrayList;
    10  import java.util.List;
    11
    12  import net.sourceforge.pmd.util.StringUtil;
    13
    14  public class DumpFacade {
    15
    16  	private PrintWriter writer;
    17  	private boolean recurse;
    18
    19  	public void initializeWith(Writer writer, String prefix, boolean recurse, EcmascriptNode<?> node) {
    20  		this.writer = (writer instanceof PrintWriter) ? (PrintWriter) writer : new PrintWriter(writer);
    21  		this.recurse = recurse;
    22  		this.dump(node, prefix);
    23  		try {
    24  			writer.flush();
    25  		} catch (IOException e) {
    26  			throw new RuntimeException("Problem flushing PrintWriter.", e);
    27  		}
    28  	}
    29
    30  	public Object visit(EcmascriptNode<?> node, Object data) {
    31  		dump(node, (String) data);
    32  		if (recurse) {
    33  			for (int i = 0; i < node.jjtGetNumChildren(); i++) {
    34  				visit((EcmascriptNode<?>) node.jjtGetChild(i), data + " ");
    35  			}
    36  			return data;
    37  		} else {
    38  			return data;
    39  		}
    40  	}
    41
    42  	private void dump(EcmascriptNode<?> node, String prefix) {
    43  		//
    44  		// Dump format is generally composed of the following items...
    45  		//
    46
    47  		// 1) Dump prefix
    48  		writer.print(prefix);
    49
    50  		// 2) JJT Name of the Node
    51  		writer.print(node.toString());
    52
    53  		//
    54  		// If there are any additional details, then:
    55  		// 1) A colon
    56  		// 2) The Node.getImage() if it is non-empty
    57  		// 3) Extras in parentheses
    58  		//
    59
    60  		// Standard image handling
    61  		String image = node.getImage();
    62
    63  		// Special image handling (e.g. Nodes with normally null images)
    64  		image = StringUtil.escapeWhitespace(image);
    65
    66  		// Extras
    67  		List<String> extras = new ArrayList<String>();
    68
    69  		// Standard DestructuringNode extras
    70  		if (node instanceof DestructuringNode) {
    71  			if (((DestructuringNode) node).isDestructuring()) {
    72  				extras.add("destructuring");
    73  			}
    74  		}
    75
    76  		// Other extras
    77  		if (node instanceof ASTArrayComprehension) {
    78  			if (((ASTArrayComprehension) node).hasFilter()) {
    79  				extras.add("has filter");
    80  			}
    81  		} else if (node instanceof ASTBreakStatement) {
    82  			if (((ASTBreakStatement) node).hasLabel()) {
    83  				extras.add("has label");
    84  			}
    85  		} else if (node instanceof ASTCatchClause) {
    86  			if (((ASTCatchClause) node).isIf()) {
    87  				extras.add("if");
    88  			}
    89  		} else if (node instanceof ASTContinueStatement) {
    90  			if (((ASTContinueStatement) node).hasLabel()) {
    91  				extras.add("has label");
    92  			}
    93  		} else if (node instanceof ASTExpressionStatement) {
    94  			if (((ASTExpressionStatement) node).hasResult()) {
    95  				extras.add("has result");
    96  			}
    97  		} else if (node instanceof ASTForInLoop) {
    98  			if (((ASTForInLoop) node).isForEach()) {
    99  				extras.add("for each");
    100 			}
    101 		} else if (node instanceof ASTFunctionCall) {
    102 			if (((ASTFunctionCall) node).hasArguments()) {
    103 				extras.add("has arguments");
    104 			}
    105 		} else if (node instanceof ASTFunctionNode) {
    106 			if (((ASTFunctionNode) node).isClosure()) {
    107 				extras.add("closure");
    108 			}
    109 			if (((ASTFunctionNode) node).isGetter()) {
    110 				extras.add("getter");
    111 			}
    112 			if (((ASTFunctionNode) node).isSetter()) {
    113 				extras.add("setter");
    114 			}
    115 		} else if (node instanceof ASTIfStatement) {
    116 			if (((ASTIfStatement) node).hasElse()) {
    117 				extras.add("has else");
    118 			}
    119 		} else if (node instanceof ASTKeywordLiteral) {
    120 			if (((ASTKeywordLiteral) node).isBoolean()) {
    121 				extras.add("boolean");
    122 			}
    123 		} else if (node instanceof ASTLetNode) {
    124 			if (((ASTLetNode) node).hasBody()) {
    125 				extras.add("has body");
    126 			}
    127 		} else if (node instanceof ASTName) {
    128 			if (((ASTName) node).isLocalName()) {
    129 				extras.add("local");
    130 			}
    131 			if (((ASTName) node).isGlobalName()) {
    132 				extras.add("global");
    133 			}
    134 		} else if (node instanceof ASTNewExpression) {
    135 			if (((ASTNewExpression) node).hasArguments()) {
    136 				extras.add("has arguments");
    137 			}
    138 			if (((ASTNewExpression) node).hasInitializer()) {
    139 				extras.add("has initializer");
    140 			}
    141 		} else if (node instanceof ASTNumberLiteral) {
    142 			extras.add("Number=" + ((ASTNumberLiteral) node).getNumber());
    143 			extras.add("NormalizedImage=" + ((ASTNumberLiteral) node).getNormalizedImage());
    144 		} else if (node instanceof ASTObjectProperty) {
    145 			if (((ASTObjectProperty) node).isGetter()) {
    146 				extras.add("getter");
    147 			}
    148 			if (((ASTObjectProperty) node).isSetter()) {
    149 				extras.add("setter");
    150 			}
    151 		} else if (node instanceof ASTRegExpLiteral) {
    152 			extras.add("Flags=" + ((ASTRegExpLiteral) node).getFlags());
    153 		} else if (node instanceof ASTReturnStatement) {
    154 			if (((ASTReturnStatement) node).hasResult()) {
    155 				extras.add("has result");
    156 			}
    157 		} else if (node instanceof ASTStringLiteral) {
    158 			if (((ASTStringLiteral) node).isSingleQuoted()) {
    159 				extras.add("single quoted");
    160 			}
    161 			if (((ASTStringLiteral) node).isDoubleQuoted()) {
    162 				extras.add("double quoted");
    163 			}
    164 		} else if (node instanceof ASTSwitchCase) {
    165 			if (((ASTSwitchCase) node).isDefault()) {
    166 				extras.add("default");
    167 			}
    168 		} else if (node instanceof ASTTryStatement) {
    169 			if (((ASTTryStatement) node).isCatch()) {
    170 				extras.add("catch");
    171 			}
    172 			if (((ASTTryStatement) node).isFinally()) {
    173 				extras.add("finally");
    174 			}
    175 		} else if (node instanceof ASTUnaryExpression) {
    176 			if (((ASTUnaryExpression) node).isPrefix()) {
    177 				extras.add("prefix");
    178 			}
    179 			if (((ASTUnaryExpression) node).isPostfix()) {
    180 				extras.add("postfix");
    181 			}
    182 		}
    183
    184 		// Standard EcmascriptNode extras
    185 		if (node.hasSideEffects()) {
    186 			extras.add("has side effects");
    187 		}
    188
    189 		// Output image and extras
    190 		if (image != null || !extras.isEmpty()) {
    191 			writer.print(':');
    192 			if (image != null) {
    193 				writer.print(image);
    194 			}
    195 			for (String extra : extras) {
    196 				writer.print('(');
    197 				writer.print(extra);
    198 				writer.print(')');
    199 			}
    200 		}
    201
    202 		writer.println();
    203 	}
    204
    205 }