]> source.dussan.org Git - aspectj.git/commitdiff
231396: Moved test visitor out to test code
authoraclement <aclement>
Thu, 29 May 2008 04:49:34 +0000 (04:49 +0000)
committeraclement <aclement>
Thu, 29 May 2008 04:49:34 +0000 (04:49 +0000)
weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java
weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java [new file with mode: 0644]

index 74105dcb022370cb50ed65297abdef9c9494dc7e..3fedd718ead39a01fa8c89a7e5884130288e0a66 100644 (file)
@@ -12,7 +12,6 @@
  *******************************************************************************/
 package org.aspectj.weaver.patterns;
 
-import org.aspectj.weaver.Member;
 
 /**
  * A Pointcut or TypePattern visitor
@@ -93,515 +92,4 @@ public interface PatternNodeVisitor {
        // Catch-all
     Object visit(PatternNode node, Object data);
 
-    /**
-     * A sample toString like visitor that helps understanding the AST tree structure organization
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    static class DumpPointcutVisitor implements PatternNodeVisitor {
-
-        private StringBuffer sb = new StringBuffer();
-        public String get() {
-            return sb.toString();
-        }
-
-        private void append(Object o) {
-            sb.append(o.toString());
-        }
-               
-               private void append(char c) {
-                       sb.append(c);
-               }
-
-        /**
-         * This method helps maintaining the API and raises warning when PatternNode subclasses do not
-         * implement the visitor pattern
-         *
-         * @param node
-         * @param data
-         * @return
-         */
-        public Object visit(PatternNode node, Object data) {
-            System.err.println("Should implement: "  + node.getClass());
-            return null;
-        }
-
-        public Object visit(AnyTypePattern node, Object data) {
-            append('*');
-            return null;
-        }
-
-        public Object visit(NoTypePattern node, Object data) {
-            append(node.toString());//TODO no idea when this one is used
-            return null;
-        }
-
-        public Object visit(EllipsisTypePattern node, Object data) {
-            append(node.toString());
-            return null;
-        }
-
-        public Object visit(AnyWithAnnotationTypePattern node, Object data) {
-            node.annotationPattern.accept(this, data);
-            append(" *");
-            return null;
-        }
-
-        public Object visit(AnyAnnotationTypePattern node, Object data) {
-            //@ANY : ignore
-            append('*');
-            return null;
-        }
-
-        public Object visit(EllipsisAnnotationTypePattern node, Object data) {
-            append("..");
-            return null;
-        }
-
-        public Object visit(AndAnnotationTypePattern node, Object data) {
-            node.getLeft().accept(this, data);
-            append(' ');
-            node.getRight().accept(this, data);
-            return null;
-        }
-
-        public Object visit(AndPointcut node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" && ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(AndTypePattern node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" && ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(AnnotationPatternList node, Object data) {
-            AnnotationTypePattern[] annotations = node.getAnnotationPatterns();
-            for (int i = 0; i < annotations.length; i++) {
-                if (i>0) append(", ");//Note: list is ",", and is " " separated for annotations
-                annotations[i].accept(this, data);
-            }
-            return null;
-        }
-
-        public Object visit(AnnotationPointcut node, Object data) {
-            append("@annotation(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ArgsAnnotationPointcut node, Object data) {
-            append("@args(");
-            node.getArguments().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ArgsPointcut node, Object data) {
-            append("args(");
-            node.getArguments().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(BindingAnnotationTypePattern node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(BindingTypePattern node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(CflowPointcut node, Object data) {
-            append(node.isCflowBelow()?"cflowbelow(":"cflow(");
-            node.getEntry().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ExactAnnotationTypePattern node, Object data) {
-            //append('@'); // since @annotation(@someAnno) cannot be parsed anymore
-            append(node.getAnnotationType().getName());
-            return null;
-        }
-
-        public Object visit(ExactTypePattern node, Object data) {
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append('(');
-                node.getAnnotationPattern().accept(this, data);
-                append(' ');
-            }
-
-            String typeString = node.getType().toString();
-            if (node.isVarArgs()) typeString = typeString.substring(0, typeString.lastIndexOf('['));//TODO AV - ugly
-            append(typeString);
-            if (node.isIncludeSubtypes()) append('+');
-            if (node.isVarArgs()) append("...");
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append(')');
-            }
-            return null;
-        }
-
-        public Object visit(KindedPointcut node, Object data) {
-            append(node.getKind().getSimpleName());
-            append('(');
-            node.getSignature().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ModifiersPattern node, Object data) {
-            append(node.toString());//note: node takes care of forbidden mods
-            return null;
-        }
-
-        public Object visit(NamePattern node, Object data) {
-            append(node.toString());
-            return null;
-        }
-
-        public Object visit(NotAnnotationTypePattern node, Object data) {
-            append("!");
-            node.getNegatedPattern().accept(this, data);
-            return null;
-        }
-
-        public Object visit(NotPointcut node, Object data) {
-            append("!(");
-            node.getNegatedPointcut().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(NotTypePattern node, Object data) {
-            append("!(");
-            node.getNegatedPattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(OrAnnotationTypePattern node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" || ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(OrPointcut node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" || ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(OrTypePattern node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" || ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ReferencePointcut node, Object data) {
-            append(node.toString());
-            return null;
-        }
-
-        public Object visit(SignaturePattern node, Object data) {
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                node.getAnnotationPattern().accept(this, data);
-                append(' ');
-            }
-
-            if (node.getModifiers() != ModifiersPattern.ANY) {
-                node.getModifiers().accept(this, data);
-                append(' ');
-            }
-
-            if (node.getKind() == Member.STATIC_INITIALIZATION) {
-                node.getDeclaringType().accept(this, data);
-            } else if (node.getKind() == Member.HANDLER) {
-                append("handler(");
-                node.getParameterTypes().get(0).accept(this, data);//Note: we know we have 1 child
-                append(')');
-            } else {
-                if (!(node.getKind() == Member.CONSTRUCTOR)) {
-                    node.getReturnType().accept(this, data);
-                    append(' ');
-                }
-                if (node.getDeclaringType() != TypePattern.ANY) {
-                    node.getDeclaringType().accept(this, data);
-                    append('.');
-                }
-                if (node.getKind() == Member.CONSTRUCTOR) {
-                    append("new");
-                } else {
-                    node.getName().accept(this, data);
-                }
-                if (node.getKind() == Member.METHOD || node.getKind() == Member.CONSTRUCTOR) {
-                    append('(');
-                    node.getParameterTypes().accept(this, data);
-                    append(')');
-                }
-                if (node.getThrowsPattern() != null) {
-                    append(' ');
-                    node.getThrowsPattern().accept(this, data);
-                }
-            }
-            return null;
-        }
-
-        public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
-            append(node.isThis() ? "@this(" : "@target(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ThisOrTargetPointcut node, Object data) {
-            append(node.isThis() ? "this(" : "target(");
-            node.getType().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        // Note: a visitor instance is not thread safe so should not be shared
-        private boolean inThrowsForbidden = false;
-
-        public Object visit(ThrowsPattern node, Object data) {
-            if (node == ThrowsPattern.ANY) return null;
-
-            append("throws ");
-            node.getRequired().accept(this, data);
-            if (node.getForbidden().size() > 0) {
-                // a hack since throws !(A, B) cannot be parsed
-                try {
-                    inThrowsForbidden = true;
-                    node.getForbidden().accept(this, data);
-                } finally {
-                    inThrowsForbidden = false;
-                }
-            }
-            return null;
-        }
-
-        public Object visit(TypePatternList node, Object data) {
-            if (node.getTypePatterns().length == 0) return null;
-
-            TypePattern[] typePatterns = node.getTypePatterns();
-            for (int i = 0; i < typePatterns.length; i++) {
-                TypePattern typePattern = typePatterns[i];
-                if (i > 0) append(", ");
-                if (inThrowsForbidden) append('!');
-                typePattern.accept(this, data);
-            }
-            return null;
-        }
-
-        public Object visit(WildAnnotationTypePattern node, Object data) {
-            append("@(");
-            node.getTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WildTypePattern node, Object data) {
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append('(');
-                node.getAnnotationPattern().accept(this, data);
-                append(' ');
-            }
-            NamePattern[] namePatterns = node.getNamePatterns();
-            for (int i=0; i < namePatterns.length; i++) {
-                if (namePatterns[i] == null) {
-                    append('.');//FIXME mh, error prone, can't we have a nullNamePattern ?
-                } else {
-                    if (i > 0) append('.');
-                    namePatterns[i].accept(this, data);
-                }
-            }
-            if (node.isIncludeSubtypes()) append('+');
-            if (node.isVarArgs()) append("...");
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append(')');
-            }
-            return null;
-        }
-
-        public Object visit(WithinAnnotationPointcut node, Object data) {
-            append("@within(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WithinCodeAnnotationPointcut node, Object data) {
-            append("@withincode(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WithinPointcut node, Object data) {
-            append("within(");
-            node.getTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WithincodePointcut node, Object data) {
-            append("withincode(");
-            node.getSignature().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
-            append("");//TODO shouldn't that be a "false" ?
-            return null;
-        }
-
-
-        //-------------- perX
-
-        public Object visit(PerCflow node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerFromSuper node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerObject node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerSingleton node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerTypeWithin node, Object data) {
-            append(node);
-            return null;
-        }
-
-        // ------------- declare X
-
-        public Object visit(DeclareAnnotation node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclareErrorOrWarning node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclareParents node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclarePrecedence node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclareSoft node, Object data) {
-            append(node);
-            return null;
-        }
-
-        // ----------- misc
-
-        public Object visit(ConcreteCflowPointcut node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(HandlerPointcut node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(IfPointcut node, Object data) {
-            append(node);
-            return null;
-        }
-               
-               public Object visit(TypeVariablePattern node, Object data) {
-                       append(node);
-                       return null;
-               }
-               
-               public Object visit(TypeVariablePatternList node, Object data) {
-                       append(node);
-                       return null;
-               }
-
-               public Object visit(HasMemberTypePattern node, Object data) {
-                       append(node);
-                       return null;
-               }
-
-        public static void check(String s) {
-            check(Pointcut.fromString(s), false);
-        }
-
-        public static void check(PatternNode pc, boolean isTypePattern) {
-            DumpPointcutVisitor v1 = new DumpPointcutVisitor();
-            pc.accept(v1, null);
-
-            DumpPointcutVisitor v2 = new DumpPointcutVisitor();
-            final PatternNode pc2;
-            if (isTypePattern) {
-                pc2 = new PatternParser(v1.get()).parseTypePattern();
-            } else {
-                pc2 = Pointcut.fromString(v1.get());
-            }
-            pc2.accept(v2, null);
-
-            // at second parsing, the String form stay stable when parsed and parsed again
-            if (! v1.get().equals(v2.get())) {
-                throw new ParserException("Unstable back parsing for '"+pc+"', got '" + v1.get() + "' and '" + v2.get() + "'", null);
-            }
-        }
-
-        public static void main(String args[]) throws Throwable {
-            String[] s = new String[]{
-                //"@args(Foo, Goo, *, .., Moo)",
-                //"execution(* *())",
-                //"call(* *(int, Integer...))",
-                //"staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
-                   "(if(true) && set(int BaseApp.i))"
-
-            };
-            for (int i = 0; i < s.length; i++) {
-                check(s[i]);
-            }
-        }
-
-    }
-
 }
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java b/weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java
new file mode 100644 (file)
index 0000000..3c47c20
--- /dev/null
@@ -0,0 +1,525 @@
+/* *******************************************************************
+ * Copyright (c) 2007-2008 Contributors
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Alexandre Vasseur    
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.weaver.Member;
+
+/**
+ * A sample toString like visitor that helps understanding the AST tree structure organization
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class DumpPointcutVisitor implements PatternNodeVisitor {
+
+    private StringBuffer sb = new StringBuffer();
+    public String get() {
+        return sb.toString();
+    }
+
+    private void append(Object o) {
+        sb.append(o.toString());
+    }
+       
+       private void append(char c) {
+               sb.append(c);
+       }
+
+    /**
+     * This method helps maintaining the API and raises warning when PatternNode subclasses do not
+     * implement the visitor pattern
+     *
+     * @param node
+     * @param data
+     * @return
+     */
+    public Object visit(PatternNode node, Object data) {
+        System.err.println("Should implement: "  + node.getClass());
+        return null;
+    }
+
+    public Object visit(AnyTypePattern node, Object data) {
+        append('*');
+        return null;
+    }
+
+    public Object visit(NoTypePattern node, Object data) {
+        append(node.toString());//TODO no idea when this one is used
+        return null;
+    }
+
+    public Object visit(EllipsisTypePattern node, Object data) {
+        append(node.toString());
+        return null;
+    }
+
+    public Object visit(AnyWithAnnotationTypePattern node, Object data) {
+        node.annotationPattern.accept(this, data);
+        append(" *");
+        return null;
+    }
+
+    public Object visit(AnyAnnotationTypePattern node, Object data) {
+        //@ANY : ignore
+        append('*');
+        return null;
+    }
+
+    public Object visit(EllipsisAnnotationTypePattern node, Object data) {
+        append("..");
+        return null;
+    }
+
+    public Object visit(AndAnnotationTypePattern node, Object data) {
+        node.getLeft().accept(this, data);
+        append(' ');
+        node.getRight().accept(this, data);
+        return null;
+    }
+
+    public Object visit(AndPointcut node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" && ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(AndTypePattern node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" && ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(AnnotationPatternList node, Object data) {
+        AnnotationTypePattern[] annotations = node.getAnnotationPatterns();
+        for (int i = 0; i < annotations.length; i++) {
+            if (i>0) append(", ");//Note: list is ",", and is " " separated for annotations
+            annotations[i].accept(this, data);
+        }
+        return null;
+    }
+
+    public Object visit(AnnotationPointcut node, Object data) {
+        append("@annotation(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ArgsAnnotationPointcut node, Object data) {
+        append("@args(");
+        node.getArguments().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ArgsPointcut node, Object data) {
+        append("args(");
+        node.getArguments().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(BindingAnnotationTypePattern node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(BindingTypePattern node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(CflowPointcut node, Object data) {
+        append(node.isCflowBelow()?"cflowbelow(":"cflow(");
+        node.getEntry().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ExactAnnotationTypePattern node, Object data) {
+        //append('@'); // since @annotation(@someAnno) cannot be parsed anymore
+        append(node.getAnnotationType().getName());
+        return null;
+    }
+
+    public Object visit(ExactTypePattern node, Object data) {
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append('(');
+            node.getAnnotationPattern().accept(this, data);
+            append(' ');
+        }
+
+        String typeString = node.getType().toString();
+        if (node.isVarArgs()) typeString = typeString.substring(0, typeString.lastIndexOf('['));//TODO AV - ugly
+        append(typeString);
+        if (node.isIncludeSubtypes()) append('+');
+        if (node.isVarArgs()) append("...");
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append(')');
+        }
+        return null;
+    }
+
+    public Object visit(KindedPointcut node, Object data) {
+        append(node.getKind().getSimpleName());
+        append('(');
+        node.getSignature().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ModifiersPattern node, Object data) {
+        append(node.toString());//note: node takes care of forbidden mods
+        return null;
+    }
+
+    public Object visit(NamePattern node, Object data) {
+        append(node.toString());
+        return null;
+    }
+
+    public Object visit(NotAnnotationTypePattern node, Object data) {
+        append("!");
+        node.getNegatedPattern().accept(this, data);
+        return null;
+    }
+
+    public Object visit(NotPointcut node, Object data) {
+        append("!(");
+        node.getNegatedPointcut().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(NotTypePattern node, Object data) {
+        append("!(");
+        node.getNegatedPattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(OrAnnotationTypePattern node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" || ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(OrPointcut node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" || ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(OrTypePattern node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" || ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ReferencePointcut node, Object data) {
+        append(node.toString());
+        return null;
+    }
+
+    public Object visit(SignaturePattern node, Object data) {
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            node.getAnnotationPattern().accept(this, data);
+            append(' ');
+        }
+
+        if (node.getModifiers() != ModifiersPattern.ANY) {
+            node.getModifiers().accept(this, data);
+            append(' ');
+        }
+
+        if (node.getKind() == Member.STATIC_INITIALIZATION) {
+            node.getDeclaringType().accept(this, data);
+        } else if (node.getKind() == Member.HANDLER) {
+            append("handler(");
+            node.getParameterTypes().get(0).accept(this, data);//Note: we know we have 1 child
+            append(')');
+        } else {
+            if (!(node.getKind() == Member.CONSTRUCTOR)) {
+                node.getReturnType().accept(this, data);
+                append(' ');
+            }
+            if (node.getDeclaringType() != TypePattern.ANY) {
+                node.getDeclaringType().accept(this, data);
+                append('.');
+            }
+            if (node.getKind() == Member.CONSTRUCTOR) {
+                append("new");
+            } else {
+                node.getName().accept(this, data);
+            }
+            if (node.getKind() == Member.METHOD || node.getKind() == Member.CONSTRUCTOR) {
+                append('(');
+                node.getParameterTypes().accept(this, data);
+                append(')');
+            }
+            if (node.getThrowsPattern() != null) {
+                append(' ');
+                node.getThrowsPattern().accept(this, data);
+            }
+        }
+        return null;
+    }
+
+    public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
+        append(node.isThis() ? "@this(" : "@target(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ThisOrTargetPointcut node, Object data) {
+        append(node.isThis() ? "this(" : "target(");
+        node.getType().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    // Note: a visitor instance is not thread safe so should not be shared
+    private boolean inThrowsForbidden = false;
+
+    public Object visit(ThrowsPattern node, Object data) {
+        if (node == ThrowsPattern.ANY) return null;
+
+        append("throws ");
+        node.getRequired().accept(this, data);
+        if (node.getForbidden().size() > 0) {
+            // a hack since throws !(A, B) cannot be parsed
+            try {
+                inThrowsForbidden = true;
+                node.getForbidden().accept(this, data);
+            } finally {
+                inThrowsForbidden = false;
+            }
+        }
+        return null;
+    }
+
+    public Object visit(TypePatternList node, Object data) {
+        if (node.getTypePatterns().length == 0) return null;
+
+        TypePattern[] typePatterns = node.getTypePatterns();
+        for (int i = 0; i < typePatterns.length; i++) {
+            TypePattern typePattern = typePatterns[i];
+            if (i > 0) append(", ");
+            if (inThrowsForbidden) append('!');
+            typePattern.accept(this, data);
+        }
+        return null;
+    }
+
+    public Object visit(WildAnnotationTypePattern node, Object data) {
+        append("@(");
+        node.getTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WildTypePattern node, Object data) {
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append('(');
+            node.getAnnotationPattern().accept(this, data);
+            append(' ');
+        }
+        NamePattern[] namePatterns = node.getNamePatterns();
+        for (int i=0; i < namePatterns.length; i++) {
+            if (namePatterns[i] == null) {
+                append('.');//FIXME mh, error prone, can't we have a nullNamePattern ?
+            } else {
+                if (i > 0) append('.');
+                namePatterns[i].accept(this, data);
+            }
+        }
+        if (node.isIncludeSubtypes()) append('+');
+        if (node.isVarArgs()) append("...");
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append(')');
+        }
+        return null;
+    }
+
+    public Object visit(WithinAnnotationPointcut node, Object data) {
+        append("@within(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WithinCodeAnnotationPointcut node, Object data) {
+        append("@withincode(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WithinPointcut node, Object data) {
+        append("within(");
+        node.getTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WithincodePointcut node, Object data) {
+        append("withincode(");
+        node.getSignature().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
+        append("");//TODO shouldn't that be a "false" ?
+        return null;
+    }
+
+
+    //-------------- perX
+
+    public Object visit(PerCflow node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerFromSuper node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerObject node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerSingleton node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerTypeWithin node, Object data) {
+        append(node);
+        return null;
+    }
+
+    // ------------- declare X
+
+    public Object visit(DeclareAnnotation node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclareErrorOrWarning node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclareParents node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclarePrecedence node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclareSoft node, Object data) {
+        append(node);
+        return null;
+    }
+
+    // ----------- misc
+
+    public Object visit(ConcreteCflowPointcut node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(HandlerPointcut node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(IfPointcut node, Object data) {
+        append(node);
+        return null;
+    }
+       
+       public Object visit(TypeVariablePattern node, Object data) {
+               append(node);
+               return null;
+       }
+       
+       public Object visit(TypeVariablePatternList node, Object data) {
+               append(node);
+               return null;
+       }
+
+       public Object visit(HasMemberTypePattern node, Object data) {
+               append(node);
+               return null;
+       }
+
+    public static void check(String s) {
+        check(Pointcut.fromString(s), false);
+    }
+
+    public static void check(PatternNode pc, boolean isTypePattern) {
+        DumpPointcutVisitor v1 = new DumpPointcutVisitor();
+        pc.accept(v1, null);
+
+        DumpPointcutVisitor v2 = new DumpPointcutVisitor();
+        final PatternNode pc2;
+        if (isTypePattern) {
+            pc2 = new PatternParser(v1.get()).parseTypePattern();
+        } else {
+            pc2 = Pointcut.fromString(v1.get());
+        }
+        pc2.accept(v2, null);
+
+        // at second parsing, the String form stay stable when parsed and parsed again
+        if (! v1.get().equals(v2.get())) {
+            throw new ParserException("Unstable back parsing for '"+pc+"', got '" + v1.get() + "' and '" + v2.get() + "'", null);
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        String[] s = new String[]{
+            //"@args(Foo, Goo, *, .., Moo)",
+            //"execution(* *())",
+            //"call(* *(int, Integer...))",
+            //"staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
+               "(if(true) && set(int BaseApp.i))"
+
+        };
+        for (int i = 0; i < s.length; i++) {
+            check(s[i]);
+        }
+    }
+
+}
\ No newline at end of file