Author: ihab.awad
Date: Wed Jul 15 11:24:34 2009
New Revision: 3574
Modified:
trunk/src/com/google/caja/parser/ParseTreeNode.java
trunk/src/com/google/caja/parser/ParseTreeNodeContainer.java
trunk/src/com/google/caja/parser/ParseTreeNodes.java
trunk/src/com/google/caja/parser/css/CssTree.java
trunk/src/com/google/caja/parser/js/AbstractExpression.java
trunk/src/com/google/caja/parser/js/AbstractStatement.java
trunk/src/com/google/caja/parser/js/ArrayConstructor.java
trunk/src/com/google/caja/parser/js/AssignOperation.java
trunk/src/com/google/caja/parser/js/Block.java
trunk/src/com/google/caja/parser/js/BooleanLiteral.java
trunk/src/com/google/caja/parser/js/BreakStmt.java
trunk/src/com/google/caja/parser/js/CajoledModule.java
trunk/src/com/google/caja/parser/js/CaseStmt.java
trunk/src/com/google/caja/parser/js/CatchStmt.java
trunk/src/com/google/caja/parser/js/Conditional.java
trunk/src/com/google/caja/parser/js/ContinueStmt.java
trunk/src/com/google/caja/parser/js/ControlOperation.java
trunk/src/com/google/caja/parser/js/DebuggerStmt.java
trunk/src/com/google/caja/parser/js/Declaration.java
trunk/src/com/google/caja/parser/js/DefaultCaseStmt.java
trunk/src/com/google/caja/parser/js/DoWhileLoop.java
trunk/src/com/google/caja/parser/js/ExpressionStmt.java
trunk/src/com/google/caja/parser/js/FinallyStmt.java
trunk/src/com/google/caja/parser/js/ForEachLoop.java
trunk/src/com/google/caja/parser/js/ForLoop.java
trunk/src/com/google/caja/parser/js/FormalParam.java
trunk/src/com/google/caja/parser/js/FunctionConstructor.java
trunk/src/com/google/caja/parser/js/FunctionDeclaration.java
trunk/src/com/google/caja/parser/js/Identifier.java
trunk/src/com/google/caja/parser/js/IntegerLiteral.java
trunk/src/com/google/caja/parser/js/LabeledStmtWrapper.java
trunk/src/com/google/caja/parser/js/Loop.java
trunk/src/com/google/caja/parser/js/MultiDeclaration.java
trunk/src/com/google/caja/parser/js/Noop.java
trunk/src/com/google/caja/parser/js/NullLiteral.java
trunk/src/com/google/caja/parser/js/ObjectConstructor.java
trunk/src/com/google/caja/parser/js/QuotedExpression.java
trunk/src/com/google/caja/parser/js/RealLiteral.java
trunk/src/com/google/caja/parser/js/Reference.java
trunk/src/com/google/caja/parser/js/RegexpLiteral.java
trunk/src/com/google/caja/parser/js/ReturnStmt.java
trunk/src/com/google/caja/parser/js/SimpleOperation.java
trunk/src/com/google/caja/parser/js/SpecialOperation.java
trunk/src/com/google/caja/parser/js/StringLiteral.java
trunk/src/com/google/caja/parser/js/SwitchStmt.java
trunk/src/com/google/caja/parser/js/ThrowStmt.java
trunk/src/com/google/caja/parser/js/TranslatedCode.java
trunk/src/com/google/caja/parser/js/TryStmt.java
trunk/src/com/google/caja/parser/js/UncajoledModule.java
trunk/src/com/google/caja/parser/js/UseSubset.java
trunk/src/com/google/caja/parser/js/UseSubsetDirective.java
trunk/src/com/google/caja/parser/js/WhileLoop.java
trunk/src/com/google/caja/parser/js/WithStmt.java
trunk/tests/com/google/caja/parser/css/CssParserTest.java
trunk/tests/com/google/caja/parser/js/ParserTest.java
trunk/tests/com/google/caja/util/CajaTestCase.java
Log:
Fix http://code.google.com/p/google-caja/issues/detail?id=985.
Adds more predictability to our reflective ParseTreeNode constructors,
and adds tests of node cloning.
Modified: trunk/src/com/google/caja/parser/ParseTreeNode.java
==============================================================================
--- trunk/src/com/google/caja/parser/ParseTreeNode.java (original)
+++ trunk/src/com/google/caja/parser/ParseTreeNode.java Wed Jul 15 11:24:34
2009
@@ -24,6 +24,11 @@
import java.io.IOException;
import java.util.List;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
/**
* A node in a parse tree.
@@ -90,4 +95,14 @@
* @return a deep clone of the node tree rooted at this {...@code
ParseTreeNode}.
*/
ParseTreeNode clone();
+
+ /**
+ * Indicates that the annotated constructor of a {...@code ParseTreeNode}
is to
+ * be used for reflectively constructing a new node or cloning an
existing
+ * node.
+ */
+ @Documented
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.CONSTRUCTOR)
+ public @interface ReflectiveCtor { }
}
Modified: trunk/src/com/google/caja/parser/ParseTreeNodeContainer.java
==============================================================================
--- trunk/src/com/google/caja/parser/ParseTreeNodeContainer.java
(original)
+++ trunk/src/com/google/caja/parser/ParseTreeNodeContainer.java Wed Jul 15
11:24:34 2009
@@ -33,6 +33,7 @@
*/
public class ParseTreeNodeContainer extends AbstractParseTreeNode {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public ParseTreeNodeContainer(
FilePosition pos, Void value, List<? extends ParseTreeNode>
children) {
super(pos);
Modified: trunk/src/com/google/caja/parser/ParseTreeNodes.java
==============================================================================
--- trunk/src/com/google/caja/parser/ParseTreeNodes.java (original)
+++ trunk/src/com/google/caja/parser/ParseTreeNodes.java Wed Jul 15
11:24:34 2009
@@ -96,12 +96,23 @@
Class<?>[] parameterTypes = ctor.getParameterTypes();
if (parameterTypes.length == 3
&& FilePosition.class.equals(parameterTypes[0])
- && ctor.getParameterTypes()[2].isAssignableFrom(List.class)) {
+ && ctor.getParameterTypes()[2].isAssignableFrom(List.class)
+ && isReflectiveCtorAnnotated(ctor)) {
cloneCtorCache.put(clazz, ctor);
return ctor;
}
}
throw new RuntimeException("Cannot find clone ctor for node " + clazz);
+ }
+
+ private static final boolean isReflectiveCtorAnnotated(Constructor<?>
ctor) {
+ for (int i = 0; i < ctor.getDeclaredAnnotations().length; ++i) {
+ if (ctor.getDeclaredAnnotations()[i]
+ instanceof ParseTreeNode.ReflectiveCtor) {
+ return true;
+ }
+ }
+ return false;
}
@SuppressWarnings("unchecked")
Modified: trunk/src/com/google/caja/parser/css/CssTree.java
==============================================================================
--- trunk/src/com/google/caja/parser/css/CssTree.java (original)
+++ trunk/src/com/google/caja/parser/css/CssTree.java Wed Jul 15 11:24:34
2009
@@ -91,6 +91,7 @@
*/
public static final class StyleSheet extends CssTree {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public StyleSheet(
FilePosition pos, Void novalue, List<? extends CssStatement>
rulesets) {
this(pos, rulesets);
@@ -114,6 +115,7 @@
*/
public static final class DeclarationGroup extends CssTree {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public DeclarationGroup(
FilePosition pos, Void novalue, List<? extends Declaration> decls)
{
this(pos, decls);
@@ -174,6 +176,13 @@
return l;
}
+ /** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
+ public Import(
+ FilePosition pos, Void novalue, List<? extends Medium> media) {
+ super(pos, media);
+ }
+
public Import(
FilePosition pos, UriLiteral uri, List<? extends Medium> media) {
super(pos, join(Collections.singletonList(uri), media));
@@ -214,6 +223,7 @@
*/
public static final class Media extends CssStatement {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public Media(
FilePosition pos, Void novalue,
List<? extends CssTree> mediaAndRuleset) {
@@ -261,6 +271,7 @@
final Name ident;
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public Medium(FilePosition pos, Name ident, List<? extends CssTree>
none) {
this(pos, ident);
}
@@ -288,6 +299,7 @@
public static final class Page extends CssStatement {
final Name ident;
+ @ReflectiveCtor
public Page(
FilePosition pos, Name ident, List<? extends PageElement> decls) {
super(pos, decls);
@@ -338,6 +350,7 @@
final Name ident;
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public PseudoPage(
FilePosition pos, Name ident, List<? extends CssTree> none) {
this(pos, ident);
@@ -366,6 +379,7 @@
*/
public static final class FontFace extends CssStatement {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public FontFace(
FilePosition pos, Void novalue, List<? extends Declaration> decls)
{
this(pos, decls);
@@ -403,6 +417,7 @@
public static final class Property extends CssTree {
private final Name ident;
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public Property(
FilePosition pos, Name ident, List<? extends CssTree> none) {
this(pos, ident);
@@ -435,6 +450,7 @@
*/
public static final class RuleSet extends CssStatement {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public RuleSet(
FilePosition pos, Void novalue,
List<? extends CssTree> selectorsAndDecls) {
@@ -469,6 +485,7 @@
*/
public static final class Selector extends CssTree {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public Selector(
FilePosition pos, Void novalue, List<? extends CssTree> children) {
this(pos, children);
@@ -508,6 +525,7 @@
*/
public static final class SimpleSelector extends CssTree {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public SimpleSelector(
FilePosition pos, Void novalue, List<? extends CssTree> children) {
this(pos, children);
@@ -542,6 +560,7 @@
* @param novalue ignored but required for reflection.
* @param none ignored but required for reflection.
*/
+ @ReflectiveCtor
public WildcardElement(
FilePosition pos, Void novalue, List<? extends CssTree> none) {
this(pos);
@@ -572,6 +591,7 @@
public static final class Attrib extends CssTree {
final String ident;
+ @ReflectiveCtor
public Attrib(
FilePosition pos, String ident,
List<? extends CssTree> operatorAndValue) {
@@ -630,6 +650,7 @@
public static final class AttribOperation extends CssTree {
final AttribOperator op;
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public AttribOperation(
FilePosition pos, AttribOperator op, List<? extends CssTree> none)
{
this(pos, op);
@@ -657,6 +678,7 @@
*/
public static final class Pseudo extends CssTree {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public Pseudo(
FilePosition pos, Void novalue, List<? extends CssExprAtom>
oneAtom) {
this(pos, oneAtom.get(0));
@@ -708,6 +730,7 @@
* @param novalue ignored but required for reflection.
* @param none ignored but required for reflection.
*/
+ @ReflectiveCtor
public EmptyDeclaration(
FilePosition pos, Void novalue, List<? extends CssTree> none) {
this(pos);
@@ -735,6 +758,7 @@
private Prio prio;
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public PropertyDeclaration(
FilePosition pos, Void novalue, List<? extends CssTree> children) {
this(pos, children);
@@ -782,6 +806,7 @@
final String value;
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public Prio(FilePosition pos, String value, List<? extends CssTree>
none) {
this(pos, value);
}
@@ -809,6 +834,7 @@
*/
public static final class Expr extends CssTree {
/** @param novalue ignored but required for reflection. */
+ @ReflectiveCtor
public Expr(
FilePosition pos, Void novalue, List<? extends CssTree> children) {
this(pos, children);
@@ -849,6 +875,7 @@
*/
public static final class Term extends CssTree {
private final UnaryOperator op;
+ @ReflectiveCtor
public Term(FilePosition pos, UnaryOperator op,
List<? extends CssExprAtom> oneatom) {
this(pos, op, oneatom.get(0));
@@ -939,6 +966,7 @@
*/
public static final class IdLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public IdLiteral(
FilePosition pos, String inputValue, List<? extends CssTree> none)
{
this(pos, inputValue);
@@ -960,6 +988,7 @@
*/
public static final class ClassLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public ClassLiteral(
FilePosition pos, String inputValue, List<? extends CssTree> none)
{
this(pos, inputValue);
@@ -981,6 +1010,7 @@
*/
public static final class StringLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public StringLiteral(
FilePosition pos, String inputValue, List<? extends CssTree> none)
{
this(pos, inputValue);
@@ -1001,6 +1031,7 @@
*/
public static final class HashLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public HashLiteral(
FilePosition pos, String inputValue, List<? extends CssTree> none)
{
this(pos, inputValue);
@@ -1021,6 +1052,7 @@
*/
public static final class QuantityLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public QuantityLiteral(
FilePosition pos, String inputValue, List<? extends CssTree> none)
{
this(pos, inputValue);
@@ -1043,6 +1075,7 @@
*/
public static final class UnicodeRangeLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public UnicodeRangeLiteral(
FilePosition pos, String inputValue, List<? extends CssTree> none)
{
this(pos, inputValue);
@@ -1065,9 +1098,10 @@
*/
public static final class UriLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public UriLiteral(
- FilePosition pos, URI value, List<? extends CssTree> none) {
- this(pos, value);
+ FilePosition pos, String value, List<? extends CssTree> none) {
+ this(pos, URI.create(value));
}
public UriLiteral(FilePosition pos, URI value) {
super(pos, value.toString());
@@ -1098,6 +1132,7 @@
*/
public static final class IdentLiteral extends CssLiteral {
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public IdentLiteral(
FilePosition pos, String value, List<? extends CssTree> none) {
this(pos, value);
@@ -1123,6 +1158,7 @@
*/
public static final class FunctionCall extends CssExprAtom {
private final Name name;
+ @ReflectiveCtor
public FunctionCall(
FilePosition pos, Name name, List<? extends Expr> expr) {
this(pos, name, expr.get(0));
@@ -1159,6 +1195,7 @@
public static final class ProgId extends CssExprAtom {
private final Name name;
+ @ReflectiveCtor
public ProgId(
FilePosition pos, Name name, List<? extends ProgIdAttribute>
attrs) {
super(pos, ProgIdAttribute.class, attrs);
@@ -1193,6 +1230,7 @@
public static final class ProgIdAttribute extends CssTree {
private final Name name;
+ @ReflectiveCtor
public ProgIdAttribute(
FilePosition pos, Name name, List<? extends Term> value) {
super(pos, Term.class, value);
@@ -1271,6 +1309,7 @@
final Combinator comb;
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public Combination(
FilePosition pos, Combinator comb, List<? extends CssTree> none) {
this(pos, comb);
@@ -1296,6 +1335,7 @@
final Operator op;
/** @param none ignored but required for reflection. */
+ @ReflectiveCtor
public Operation(
FilePosition pos, Operator op, List<? extends CssTree> none) {
this(pos, op);
@@ -1377,6 +1417,7 @@
public static final class UserAgentHack extends Declaration {
private final EnumSet<UserAgent> enabledOn;
+ @ReflectiveCtor
public UserAgentHack(
FilePosition pos, Set<UserAgent> enabledOn,
List<? extends PropertyDeclaration> decl) {
Modified: trunk/src/com/google/caja/parser/js/AbstractExpression.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/AbstractExpression.java (original)
+++ trunk/src/com/google/caja/parser/js/AbstractExpression.java Wed Jul 15
11:24:34 2009
@@ -30,6 +30,7 @@
*/
public abstract class AbstractExpression
extends AbstractParseTreeNode implements Expression {
+ @ReflectiveCtor
public AbstractExpression(
FilePosition pos, Class<? extends ParseTreeNode> childClass) {
super(pos, childClass);
Modified: trunk/src/com/google/caja/parser/js/AbstractStatement.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/AbstractStatement.java (original)
+++ trunk/src/com/google/caja/parser/js/AbstractStatement.java Wed Jul 15
11:24:34 2009
@@ -34,6 +34,7 @@
*/
public abstract class AbstractStatement
extends AbstractParseTreeNode implements Statement {
+ @ReflectiveCtor
public AbstractStatement(
FilePosition pos, Class<? extends ParseTreeNode> childClass) {
super(pos, childClass);
Modified: trunk/src/com/google/caja/parser/js/ArrayConstructor.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ArrayConstructor.java (original)
+++ trunk/src/com/google/caja/parser/js/ArrayConstructor.java Wed Jul 15
11:24:34 2009
@@ -27,6 +27,7 @@
*/
public final class ArrayConstructor extends AbstractExpression {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public ArrayConstructor(
FilePosition pos, Void value, List<? extends Expression> children) {
this(pos, children);
Modified: trunk/src/com/google/caja/parser/js/AssignOperation.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/AssignOperation.java (original)
+++ trunk/src/com/google/caja/parser/js/AssignOperation.java Wed Jul 15
11:24:34 2009
@@ -27,6 +27,7 @@
* @author [email protected]
*/
public final class AssignOperation extends Operation {
+ @ReflectiveCtor
public AssignOperation(
FilePosition pos, Operator value, List<? extends Expression>
children) {
super(pos, value, children);
Modified: trunk/src/com/google/caja/parser/js/Block.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/Block.java (original)
+++ trunk/src/com/google/caja/parser/js/Block.java Wed Jul 15 11:24:34 2009
@@ -30,6 +30,7 @@
public final class Block
extends AbstractStatement implements NestedScope {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public Block(
FilePosition pos, Void value, List<? extends Statement> children) {
this(pos, children);
Modified: trunk/src/com/google/caja/parser/js/BooleanLiteral.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/BooleanLiteral.java (original)
+++ trunk/src/com/google/caja/parser/js/BooleanLiteral.java Wed Jul 15
11:24:34 2009
@@ -28,6 +28,7 @@
public final boolean value;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public BooleanLiteral(
FilePosition pos, Boolean value, List<? extends ParseTreeNode>
children) {
this(pos, value);
Modified: trunk/src/com/google/caja/parser/js/BreakStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/BreakStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/BreakStmt.java Wed Jul 15 11:24:34
2009
@@ -31,6 +31,7 @@
private final String label;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public BreakStmt(
FilePosition pos, String value, List<? extends ParseTreeNode>
children) {
this(pos, value);
Modified: trunk/src/com/google/caja/parser/js/CajoledModule.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/CajoledModule.java (original)
+++ trunk/src/com/google/caja/parser/js/CajoledModule.java Wed Jul 15
11:24:34 2009
@@ -46,6 +46,7 @@
new InputSource(URI.create("file:///CAJOLED-OUTPUT"));
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public CajoledModule(FilePosition pos,
Void value,
List<? extends ObjectConstructor> children) {
Modified: trunk/src/com/google/caja/parser/js/CaseStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/CaseStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/CaseStmt.java Wed Jul 15 11:24:34
2009
@@ -39,6 +39,7 @@
private Statement body;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public CaseStmt(
FilePosition pos, Void value, List<? extends ParseTreeNode>
children) {
this(pos, (Expression) children.get(0), (Statement) children.get(1));
Modified: trunk/src/com/google/caja/parser/js/CatchStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/CatchStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/CatchStmt.java Wed Jul 15 11:24:34
2009
@@ -31,6 +31,7 @@
private Statement body;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public CatchStmt(
FilePosition pos, Void value, List<? extends ParseTreeNode>
children) {
this(pos, (Declaration) children.get(0), (Statement) children.get(1));
Modified: trunk/src/com/google/caja/parser/js/Conditional.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/Conditional.java (original)
+++ trunk/src/com/google/caja/parser/js/Conditional.java Wed Jul 15
11:24:34 2009
@@ -29,6 +29,7 @@
*/
public final class Conditional extends AbstractStatement {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public Conditional(
FilePosition pos, Void value, List<? extends ParseTreeNode>
children) {
super(pos, ParseTreeNode.class);
Modified: trunk/src/com/google/caja/parser/js/ContinueStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ContinueStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/ContinueStmt.java Wed Jul 15
11:24:34 2009
@@ -30,6 +30,7 @@
private String label;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public ContinueStmt(
FilePosition pos, String value, List<? extends Statement> children) {
this(pos, value);
Modified: trunk/src/com/google/caja/parser/js/ControlOperation.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ControlOperation.java (original)
+++ trunk/src/com/google/caja/parser/js/ControlOperation.java Wed Jul 15
11:24:34 2009
@@ -25,6 +25,7 @@
* @author [email protected]
*/
public final class ControlOperation extends Operation {
+ @ReflectiveCtor
public ControlOperation(
FilePosition pos, Operator value, List<? extends Expression>
children) {
super(pos, value, children);
Modified: trunk/src/com/google/caja/parser/js/DebuggerStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/DebuggerStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/DebuggerStmt.java Wed Jul 15
11:24:34 2009
@@ -33,6 +33,7 @@
* @param value unused.
* @param children unused.
*/
+ @ReflectiveCtor
public DebuggerStmt(
FilePosition pos, Void value, List<? extends ParseTreeNode>
children) {
super(pos, NoChildren.class);
Modified: trunk/src/com/google/caja/parser/js/Declaration.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/Declaration.java (original)
+++ trunk/src/com/google/caja/parser/js/Declaration.java Wed Jul 15
11:24:34 2009
@@ -31,6 +31,7 @@
private Expression initializer;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public Declaration(
FilePosition pos, Void value, List<? extends ParseTreeNode>
children) {
super(pos, ParseTreeNode.class);
Modified: trunk/src/com/google/caja/parser/js/DefaultCaseStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/DefaultCaseStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/DefaultCaseStmt.java Wed Jul 15
11:24:34 2009
@@ -28,6 +28,7 @@
private Statement body;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public DefaultCaseStmt(
FilePosition pos, Void value, List<? extends Statement> children) {
this(pos, children.get(0));
Modified: trunk/src/com/google/caja/parser/js/DoWhileLoop.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/DoWhileLoop.java (original)
+++ trunk/src/com/google/caja/parser/js/DoWhileLoop.java Wed Jul 15
11:24:34 2009
@@ -29,6 +29,7 @@
private Statement body;
private Expression condition;
+ @ReflectiveCtor
public DoWhileLoop(
FilePosition pos, String label, List<? extends ParseTreeNode>
children) {
this(pos, label, (Statement) children.get(0), (Expression)
children.get(1));
Modified: trunk/src/com/google/caja/parser/js/ExpressionStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ExpressionStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/ExpressionStmt.java Wed Jul 15
11:24:34 2009
@@ -31,6 +31,7 @@
private Expression expr;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public ExpressionStmt(
FilePosition pos, Void value, List<? extends Expression> children) {
this(pos, children.get(0));
Modified: trunk/src/com/google/caja/parser/js/FinallyStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/FinallyStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/FinallyStmt.java Wed Jul 15
11:24:34 2009
@@ -27,6 +27,7 @@
private Statement body;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public FinallyStmt(
FilePosition pos, Void value, List<? extends Statement> children) {
this(pos, children.get(0));
Modified: trunk/src/com/google/caja/parser/js/ForEachLoop.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ForEachLoop.java (original)
+++ trunk/src/com/google/caja/parser/js/ForEachLoop.java Wed Jul 15
11:24:34 2009
@@ -31,6 +31,7 @@
private Expression container;
private Statement body;
+ @ReflectiveCtor
public ForEachLoop(
FilePosition pos, String value, List<? extends ParseTreeNode>
children) {
super(pos, value, ParseTreeNode.class);
Modified: trunk/src/com/google/caja/parser/js/ForLoop.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ForLoop.java (original)
+++ trunk/src/com/google/caja/parser/js/ForLoop.java Wed Jul 15 11:24:34
2009
@@ -31,6 +31,7 @@
private Statement increment;
private Statement body;
+ @ReflectiveCtor
public ForLoop(
FilePosition pos, String value, List<? extends ParseTreeNode>
children) {
this(pos, value,
Modified: trunk/src/com/google/caja/parser/js/FormalParam.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/FormalParam.java (original)
+++ trunk/src/com/google/caja/parser/js/FormalParam.java Wed Jul 15
11:24:34 2009
@@ -25,6 +25,7 @@
* @author [email protected]
*/
public final class FormalParam extends Declaration {
+ @ReflectiveCtor
public FormalParam(
FilePosition pos, Void value, List<? extends Expression> children) {
super(pos, value, children);
Modified: trunk/src/com/google/caja/parser/js/FunctionConstructor.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/FunctionConstructor.java
(original)
+++ trunk/src/com/google/caja/parser/js/FunctionConstructor.java Wed Jul 15
11:24:34 2009
@@ -38,6 +38,7 @@
private Block body;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public FunctionConstructor(
FilePosition pos, Void value, List<? extends ParseTreeNode>
children) {
super(pos, ParseTreeNode.class);
Modified: trunk/src/com/google/caja/parser/js/FunctionDeclaration.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/FunctionDeclaration.java
(original)
+++ trunk/src/com/google/caja/parser/js/FunctionDeclaration.java Wed Jul 15
11:24:34 2009
@@ -26,6 +26,7 @@
* @author [email protected]
*/
public final class FunctionDeclaration extends Declaration {
+ @ReflectiveCtor
public FunctionDeclaration(
FilePosition pos, Void value, List<? extends Expression> children) {
super(pos, value, children);
Modified: trunk/src/com/google/caja/parser/js/Identifier.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/Identifier.java (original)
+++ trunk/src/com/google/caja/parser/js/Identifier.java Wed Jul 15 11:24:34
2009
@@ -37,6 +37,7 @@
public final class Identifier extends AbstractParseTreeNode {
private final String name;
+ @ReflectiveCtor
public Identifier(
FilePosition pos, String name, List<? extends ParseTreeNode>
children) {
this(pos, name);
Modified: trunk/src/com/google/caja/parser/js/IntegerLiteral.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/IntegerLiteral.java (original)
+++ trunk/src/com/google/caja/parser/js/IntegerLiteral.java Wed Jul 15
11:24:34 2009
@@ -49,6 +49,7 @@
private final long value;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public IntegerLiteral(
FilePosition pos, Number value, List<? extends ParseTreeNode>
children) {
this(pos, value.longValue());
Modified: trunk/src/com/google/caja/parser/js/LabeledStmtWrapper.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/LabeledStmtWrapper.java (original)
+++ trunk/src/com/google/caja/parser/js/LabeledStmtWrapper.java Wed Jul 15
11:24:34 2009
@@ -36,6 +36,7 @@
// LabeledStatement.
private Statement body;
+ @ReflectiveCtor
public LabeledStmtWrapper(
FilePosition pos, String value, List<? extends ParseTreeNode>
children) {
this(pos, value, (Statement)children.get(0));
Modified: trunk/src/com/google/caja/parser/js/Loop.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/Loop.java (original)
+++ trunk/src/com/google/caja/parser/js/Loop.java Wed Jul 15 11:24:34 2009
@@ -23,6 +23,7 @@
* @author [email protected]
*/
public abstract class Loop extends LabeledStatement {
+ @ReflectiveCtor
public Loop(
FilePosition pos, String label,
Class<? extends ParseTreeNode> childClass) {
Modified: trunk/src/com/google/caja/parser/js/MultiDeclaration.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/MultiDeclaration.java (original)
+++ trunk/src/com/google/caja/parser/js/MultiDeclaration.java Wed Jul 15
11:24:34 2009
@@ -31,6 +31,7 @@
*/
public final class MultiDeclaration extends AbstractStatement {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public MultiDeclaration(
FilePosition pos, Void value, List<? extends Declaration> children) {
this(pos, children);
Modified: trunk/src/com/google/caja/parser/js/Noop.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/Noop.java (original)
+++ trunk/src/com/google/caja/parser/js/Noop.java Wed Jul 15 11:24:34 2009
@@ -25,6 +25,7 @@
*/
public final class Noop extends AbstractStatement {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public Noop(FilePosition p, Void value, List<? extends Statement>
children) {
super(p, NoChildren.class);
assert children.isEmpty();
Modified: trunk/src/com/google/caja/parser/js/NullLiteral.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/NullLiteral.java (original)
+++ trunk/src/com/google/caja/parser/js/NullLiteral.java Wed Jul 15
11:24:34 2009
@@ -29,6 +29,7 @@
* @param value unused.
* @param children unused.
*/
+ @ReflectiveCtor
public NullLiteral(FilePosition pos, NullPlaceholder value,
List<? extends ParseTreeNode> children) {
this(pos);
Modified: trunk/src/com/google/caja/parser/js/ObjectConstructor.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ObjectConstructor.java (original)
+++ trunk/src/com/google/caja/parser/js/ObjectConstructor.java Wed Jul 15
11:24:34 2009
@@ -35,6 +35,7 @@
*/
public final class ObjectConstructor extends AbstractExpression {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public ObjectConstructor(
FilePosition pos, Void value, List<? extends Expression> children) {
super(pos, Expression.class);
Modified: trunk/src/com/google/caja/parser/js/QuotedExpression.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/QuotedExpression.java (original)
+++ trunk/src/com/google/caja/parser/js/QuotedExpression.java Wed Jul 15
11:24:34 2009
@@ -27,6 +27,7 @@
*/
public final class QuotedExpression extends AbstractExpression {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public QuotedExpression(
FilePosition pos, Void value, List<? extends Expression> children) {
super(pos, Expression.class);
Modified: trunk/src/com/google/caja/parser/js/RealLiteral.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/RealLiteral.java (original)
+++ trunk/src/com/google/caja/parser/js/RealLiteral.java Wed Jul 15
11:24:34 2009
@@ -30,6 +30,7 @@
private final double value;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public RealLiteral(
FilePosition pos, Number value, List<? extends ParseTreeNode>
children) {
this(pos, value.doubleValue());
Modified: trunk/src/com/google/caja/parser/js/Reference.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/Reference.java (original)
+++ trunk/src/com/google/caja/parser/js/Reference.java Wed Jul 15 11:24:34
2009
@@ -31,6 +31,7 @@
private Identifier identifier;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public Reference(FilePosition pos, Void value, List<ParseTreeNode>
children) {
super(pos, Identifier.class);
appendChild(children.get(0));
Modified: trunk/src/com/google/caja/parser/js/RegexpLiteral.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/RegexpLiteral.java (original)
+++ trunk/src/com/google/caja/parser/js/RegexpLiteral.java Wed Jul 15
11:24:34 2009
@@ -30,6 +30,7 @@
private final RegexpWrapper value;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public RegexpLiteral(
FilePosition pos, RegexpWrapper value,
List<? extends ParseTreeNode> children) {
Modified: trunk/src/com/google/caja/parser/js/ReturnStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ReturnStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/ReturnStmt.java Wed Jul 15 11:24:34
2009
@@ -27,6 +27,7 @@
private Expression returnValue;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public ReturnStmt(
FilePosition pos, Void value, List<? extends Expression> children) {
super(pos, Expression.class);
Modified: trunk/src/com/google/caja/parser/js/SimpleOperation.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/SimpleOperation.java (original)
+++ trunk/src/com/google/caja/parser/js/SimpleOperation.java Wed Jul 15
11:24:34 2009
@@ -24,6 +24,7 @@
* @author [email protected]
*/
public final class SimpleOperation extends Operation {
+ @ReflectiveCtor
public SimpleOperation(
FilePosition pos, Operator value, List<? extends Expression>
children) {
super(pos, value, children);
Modified: trunk/src/com/google/caja/parser/js/SpecialOperation.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/SpecialOperation.java (original)
+++ trunk/src/com/google/caja/parser/js/SpecialOperation.java Wed Jul 15
11:24:34 2009
@@ -23,6 +23,7 @@
* @author [email protected]
*/
public class SpecialOperation extends Operation {
+ @ReflectiveCtor
public SpecialOperation(
FilePosition pos, Operator op, List<? extends Expression> operands) {
super(pos, op, operands);
Modified: trunk/src/com/google/caja/parser/js/StringLiteral.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/StringLiteral.java (original)
+++ trunk/src/com/google/caja/parser/js/StringLiteral.java Wed Jul 15
11:24:34 2009
@@ -32,6 +32,7 @@
private final String value;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public StringLiteral(
FilePosition pos, String value, List<? extends ParseTreeNode>
children) {
this(pos, value);
Modified: trunk/src/com/google/caja/parser/js/SwitchStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/SwitchStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/SwitchStmt.java Wed Jul 15 11:24:34
2009
@@ -28,6 +28,7 @@
* @author [email protected]
*/
public final class SwitchStmt extends LabeledStatement {
+ @ReflectiveCtor
public SwitchStmt(
FilePosition pos, String label, List<? extends ParseTreeNode>
children) {
super(pos, label, ParseTreeNode.class);
Modified: trunk/src/com/google/caja/parser/js/ThrowStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/ThrowStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/ThrowStmt.java Wed Jul 15 11:24:34
2009
@@ -27,6 +27,7 @@
private Expression exception;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public ThrowStmt(
FilePosition pos, Void value, List<? extends Expression> children) {
this(pos, children.get(0));
Modified: trunk/src/com/google/caja/parser/js/TranslatedCode.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/TranslatedCode.java (original)
+++ trunk/src/com/google/caja/parser/js/TranslatedCode.java Wed Jul 15
11:24:34 2009
@@ -29,6 +29,7 @@
*/
public final class TranslatedCode extends AbstractStatement {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public TranslatedCode(
FilePosition pos, Void value, List<? extends Statement> children) {
super(pos, Statement.class);
Modified: trunk/src/com/google/caja/parser/js/TryStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/TryStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/TryStmt.java Wed Jul 15 11:24:34
2009
@@ -30,6 +30,7 @@
private FinallyStmt fin;
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public TryStmt(
FilePosition pos, Void value, List<? extends Statement> children) {
super(pos, Statement.class);
Modified: trunk/src/com/google/caja/parser/js/UncajoledModule.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/UncajoledModule.java (original)
+++ trunk/src/com/google/caja/parser/js/UncajoledModule.java Wed Jul 15
11:24:34 2009
@@ -36,6 +36,7 @@
*/
public final class UncajoledModule extends AbstractParseTreeNode {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public UncajoledModule(FilePosition pos,
Void value,
List<? extends Block> children) {
Modified: trunk/src/com/google/caja/parser/js/UseSubset.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/UseSubset.java (original)
+++ trunk/src/com/google/caja/parser/js/UseSubset.java Wed Jul 15 11:24:34
2009
@@ -36,6 +36,7 @@
private final String subsetName;
/** @param children unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public UseSubset(
FilePosition pos, String subsetName, List<NoChildren> children) {
this(pos, subsetName);
Modified: trunk/src/com/google/caja/parser/js/UseSubsetDirective.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/UseSubsetDirective.java (original)
+++ trunk/src/com/google/caja/parser/js/UseSubsetDirective.java Wed Jul 15
11:24:34 2009
@@ -77,6 +77,7 @@
*/
public final class UseSubsetDirective extends AbstractStatement {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public UseSubsetDirective(
FilePosition pos, Void value, List<? extends UseSubset> children) {
this(pos, children);
Modified: trunk/src/com/google/caja/parser/js/WhileLoop.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/WhileLoop.java (original)
+++ trunk/src/com/google/caja/parser/js/WhileLoop.java Wed Jul 15 11:24:34
2009
@@ -29,6 +29,7 @@
private Expression condition;
private Statement body;
+ @ReflectiveCtor
public WhileLoop(
FilePosition pos, String label, List<? extends ParseTreeNode>
children) {
this(pos, label, (Expression) children.get(0), (Statement)
children.get(1));
Modified: trunk/src/com/google/caja/parser/js/WithStmt.java
==============================================================================
--- trunk/src/com/google/caja/parser/js/WithStmt.java (original)
+++ trunk/src/com/google/caja/parser/js/WithStmt.java Wed Jul 15 11:24:34
2009
@@ -33,6 +33,7 @@
implements NestedScope {
/** @param value unused. This ctor is provided for reflection. */
+ @ReflectiveCtor
public WithStmt(
FilePosition pos, Void value, List<? extends Statement> children) {
super(pos, ParseTreeNode.class);
Modified: trunk/tests/com/google/caja/parser/css/CssParserTest.java
==============================================================================
--- trunk/tests/com/google/caja/parser/css/CssParserTest.java (original)
+++ trunk/tests/com/google/caja/parser/css/CssParserTest.java Wed Jul 15
11:24:34 2009
@@ -174,6 +174,7 @@
? MessageLevel.WARNING : MessageLevel.FATAL_ERROR;
CssTree.StyleSheet stylesheet = new CssParser(
CssParser.makeTokenQueue(cp, mq, false), mq,
lvl).parseStyleSheet();
+ assertCloneable(stylesheet);
StringBuilder sb = new StringBuilder();
stylesheet.format(new MessageContext(), sb);
assertEquals(golden.trim(), sb.toString().trim());
Modified: trunk/tests/com/google/caja/parser/js/ParserTest.java
==============================================================================
--- trunk/tests/com/google/caja/parser/js/ParserTest.java (original)
+++ trunk/tests/com/google/caja/parser/js/ParserTest.java Wed Jul 15
11:24:34 2009
@@ -526,6 +526,7 @@
String testFile, String goldenFile, String ... errors)
throws Exception {
Statement parseTree = js(fromResource(testFile));
+ assertCloneable(parseTree);
checkFilePositionInvariants(parseTree);
StringBuilder output = new StringBuilder();
Modified: trunk/tests/com/google/caja/util/CajaTestCase.java
==============================================================================
--- trunk/tests/com/google/caja/util/CajaTestCase.java (original)
+++ trunk/tests/com/google/caja/util/CajaTestCase.java Wed Jul 15 11:24:34
2009
@@ -240,6 +240,36 @@
return sb.toString();
}
+ /**
+ * Ensures that a given node is cloneable by calling {...@code clone()} on
it and
+ * checking sanity of the result. Tests for specific {...@code
ParseTreeNode}
+ * subsystems should invoke this on a substantial set of example trees to
+ * guard against problems creeping into the {...@code clone()}
implementations.
+ *
+ * @param node a {...@code ParseTreeNode}.
+ */
+ protected void assertCloneable(ParseTreeNode node) {
+ assertDeepEquals(node, node.clone());
+ }
+
+ /**
+ * Ensures that two {...@code ParseTreeNode} trees are deeply equal in the
+ * topology and types of nodes in each tree, and in the {...@code
getValue()} and
+ * {...@code getFilePosition()} of each respective node.
+ *
+ * @param a a {...@code ParseTreeNode}.
+ * @param b a {...@code ParseTreeNode}.
+ */
+ protected void assertDeepEquals(ParseTreeNode a, ParseTreeNode b) {
+ assertEquals(a.getValue(), b.getValue());
+ assertEquals(a.getFilePosition(), b.getFilePosition());
+ assertEquals(a.children().size(), b.children().size());
+
+ for (int i = 0; i < a.children().size(); ++i) {
+ assertDeepEquals(a.children().get(i), b.children().get(i));
+ }
+ }
+
protected void assertMessagesLessSevereThan(MessageLevel level) {
for (Message msg : mq.getMessages()) {
if (level.compareTo(msg.getMessageLevel()) <= 0) {