From ec0b8cefd1557ad2deee928bd20164d9b38d3a04 Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 29 May 2008 04:49:34 +0000 Subject: [PATCH] 231396: Moved test visitor out to test code --- .../weaver/patterns/PatternNodeVisitor.java | 512 ----------------- .../weaver/patterns/DumpPointcutVisitor.java | 525 ++++++++++++++++++ 2 files changed, 525 insertions(+), 512 deletions(-) create mode 100644 weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java b/weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java index 74105dcb0..3fedd718e 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java @@ -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 Alexandre Vasseur - */ - 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 index 000000000..3c47c2005 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java @@ -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 Alexandre Vasseur + */ +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 -- 2.39.5