From 97d8f7339e18af21927065509e549cb2e3cad393 Mon Sep 17 00:00:00 2001 From: Alexander Kriegisch Date: Mon, 30 Jan 2023 12:41:47 +0100 Subject: [PATCH] Enable type parameter traversal in exact type patterns Closes #221 Signed-off-by: Alexander Kriegisch --- .../weaver/patterns/BindingTypePattern.java | 4 ++-- .../weaver/patterns/ExactTypePattern.java | 18 ++++++++++------- .../weaver/patterns/HasMemberTypePattern.java | 2 ++ .../aspectj/weaver/patterns/TypePattern.java | 9 +++++++++ .../weaver/patterns/TypeVariablePattern.java | 20 ++++++++++++++++--- .../patterns/TypeVariablePatternList.java | 1 + .../patterns/WildAnnotationTypePattern.java | 2 +- .../weaver/patterns/WildTypePattern.java | 10 +++++----- .../weaver/patterns/ParserTestCase.java | 2 +- 9 files changed, 49 insertions(+), 19 deletions(-) diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/BindingTypePattern.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/BindingTypePattern.java index d7921d589..4175d436e 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/BindingTypePattern.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/BindingTypePattern.java @@ -29,7 +29,7 @@ public class BindingTypePattern extends ExactTypePattern implements BindingPatte private String bindingName; public BindingTypePattern(UnresolvedType type, int index, boolean isVarArgs) { - super(type, false, isVarArgs); + super(type, false, isVarArgs, null); this.formalIndex = index; } @@ -89,7 +89,7 @@ public class BindingTypePattern extends ExactTypePattern implements BindingPatte public TypePattern remapAdviceFormals(IntMap bindings) { if (!bindings.hasKey(formalIndex)) { - return new ExactTypePattern(type, false, isVarArgs); + return new ExactTypePattern(type, false, isVarArgs, null); } else { int newFormalIndex = bindings.get(formalIndex); return new BindingTypePattern(type, newFormalIndex, isVarArgs); diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/ExactTypePattern.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/ExactTypePattern.java index 6a747a3ec..7c48a97c5 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/ExactTypePattern.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/ExactTypePattern.java @@ -79,14 +79,14 @@ public class ExactTypePattern extends TypePattern { if (type.isArray() && this.type.isArray()) { ResolvedType componentType = type.getComponentType().resolve(type.getWorld()); UnresolvedType newPatternType = this.type.getComponentType(); - ExactTypePattern etp = new ExactTypePattern(newPatternType, includeSubtypes, false); + ExactTypePattern etp = new ExactTypePattern(newPatternType, includeSubtypes, false, typeParameters); return etp.matchesSubtypes(componentType, type); } return match; } - public ExactTypePattern(UnresolvedType type, boolean includeSubtypes, boolean isVarArgs) { - super(includeSubtypes, isVarArgs); + public ExactTypePattern(UnresolvedType type, boolean includeSubtypes, boolean isVarArgs, TypePatternList typeParams) { + super(includeSubtypes, isVarArgs, typeParams); this.type = type; } @@ -283,8 +283,12 @@ public class ExactTypePattern extends TypePattern { if (version > EXACT_VERSION) { throw new BCException("ExactTypePattern was written by a more recent version of AspectJ"); } - TypePattern ret = new ExactTypePattern(s.isAtLeast169() ? s.readSignatureAsUnresolvedType() : UnresolvedType.read(s), s - .readBoolean(), s.readBoolean()); + TypePattern ret = new ExactTypePattern( + s.isAtLeast169() ? s.readSignatureAsUnresolvedType() : UnresolvedType.read(s), + s.readBoolean(), + s.readBoolean(), + null // set null first, use 'setTypeParameters' below + ); ret.setAnnotationTypePattern(AnnotationTypePattern.read(s, context)); ret.setTypeParameters(TypePatternList.read(s, context)); ret.readLocation(context, s); @@ -292,7 +296,7 @@ public class ExactTypePattern extends TypePattern { } public static TypePattern readTypePatternOldStyle(DataInputStream s, ISourceContext context) throws IOException { - TypePattern ret = new ExactTypePattern(UnresolvedType.read(s), s.readBoolean(), false); + TypePattern ret = new ExactTypePattern(UnresolvedType.read(s), s.readBoolean(), false, null); ret.readLocation(context, s); return ret; } @@ -342,7 +346,7 @@ public class ExactTypePattern extends TypePattern { } else if (type.isParameterizedType()) { newType = w.resolve(type).parameterize(typeVariableMap); } - ExactTypePattern ret = new ExactTypePattern(newType, includeSubtypes, isVarArgs); + ExactTypePattern ret = new ExactTypePattern(newType, includeSubtypes, isVarArgs, typeParameters); ret.annotationPattern = annotationPattern.parameterizeWith(typeVariableMap, w); ret.copyLocationFrom(this); return ret; diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/HasMemberTypePattern.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/HasMemberTypePattern.java index ea1e15d15..0cd87001c 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/HasMemberTypePattern.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/HasMemberTypePattern.java @@ -198,8 +198,10 @@ public class HasMemberTypePattern extends TypePattern { return visitor.visit(this, data); } + @Override public Object traverse(PatternNodeVisitor visitor, Object data) { Object ret = accept(visitor, data); + super.traverse(visitor, ret); if (this.signaturePattern != null) this.signaturePattern.traverse(visitor, ret); return ret; diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypePattern.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypePattern.java index b0e058d45..36e8f2641 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypePattern.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypePattern.java @@ -360,4 +360,13 @@ public abstract class TypePattern extends PatternNode { return false; } + @Override + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor, data); + if (annotationPattern != null) + annotationPattern.traverse(visitor, ret); + if (typeParameters != null) + typeParameters.traverse(visitor, ret); + return ret; + } } diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePattern.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePattern.java index f887a4077..26eac039a 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePattern.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePattern.java @@ -45,7 +45,7 @@ public class TypeVariablePattern extends PatternNode { */ public TypeVariablePattern(String variableName) { this.name = variableName; - this.upperBound = new ExactTypePattern(UnresolvedType.OBJECT, false, false); + this.upperBound = new ExactTypePattern(UnresolvedType.OBJECT, false, false, null); this.lowerBound = null; this.interfaceBounds = null; } @@ -67,7 +67,7 @@ public class TypeVariablePattern extends PatternNode { this.name = variableName; this.upperBound = upperLimit; if (upperBound == null) { - upperBound = new ExactTypePattern(UnresolvedType.OBJECT, false, false); + upperBound = new ExactTypePattern(UnresolvedType.OBJECT, false, false, null); } this.interfaceBounds = interfaceBounds; this.lowerBound = lowerBound; @@ -77,7 +77,21 @@ public class TypeVariablePattern extends PatternNode { return visitor.visit(this, data); } - public String getName() { + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor, data); + if (lowerBound != null) + lowerBound.traverse(visitor, ret); + if (upperBound != null) + upperBound.traverse(visitor, ret); + if (interfaceBounds != null) { + for (TypePattern pattern : interfaceBounds) { + pattern.traverse(visitor, ret); + } + } + return ret; + } + + public String getName() { return name; } diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePatternList.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePatternList.java index babf57ee4..153b7f4aa 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePatternList.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/TypeVariablePatternList.java @@ -73,6 +73,7 @@ public class TypeVariablePatternList extends PatternNode { return visitor.visit(this, data); } + @Override public Object traverse(PatternNodeVisitor visitor, Object data) { Object ret = accept(visitor, data); if (patterns != null) { diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java index eaec45aa0..4e75a25bc 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java @@ -299,7 +299,7 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern { if (fullyQualifiedName != null && fullyQualifiedName.contains(".")) { ResolvedType resolvedType = world.resolve(UnresolvedType.forName(fullyQualifiedName)); if (resolvedType != null && !resolvedType.isMissing()) { - typePattern = new ExactTypePattern(resolvedType, false, false); + typePattern = new ExactTypePattern(resolvedType, false, false, null); } } } diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildTypePattern.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildTypePattern.java index 212378bf7..407b2f8d1 100644 --- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/WildTypePattern.java @@ -804,7 +804,7 @@ public class WildTypePattern extends TypePattern { if (dim != 0) { aType = UnresolvedType.makeArray(aType, dim); } - ret = new ExactTypePattern(aType, includeSubtypes, isVarArgs); + ret = new ExactTypePattern(aType, includeSubtypes, isVarArgs, typeParameters); } ret.setAnnotationTypePattern(annotationPattern); ret.copyLocationFrom(this); @@ -841,7 +841,7 @@ public class WildTypePattern extends TypePattern { } if (canBeExact) { // might have changed if we find out include subtypes is set on one of the bounds... - return new ExactTypePattern(type, includeSubtypes, isVarArgs); + return new ExactTypePattern(type, includeSubtypes, isVarArgs, typeParameters); } } @@ -878,7 +878,7 @@ public class WildTypePattern extends TypePattern { if (dim != 0) { type = ResolvedType.makeArray(type, dim); } - return new ExactTypePattern(type, includeSubtypes, isVarArgs); + return new ExactTypePattern(type, includeSubtypes, isVarArgs, typeParameters); } else { // AMC... just leave it as a wild type pattern then? importedPrefixes = scope.getImportedPrefixes(); @@ -940,7 +940,7 @@ public class WildTypePattern extends TypePattern { if (dim != 0) { rType = ResolvedType.makeArray(rType, dim); } - return new ExactTypePattern(rType, includeSubtypes, isVarArgs); + return new ExactTypePattern(rType, includeSubtypes, isVarArgs, typeParameters); } else { // we have to set bounds on the TypeVariable held by tvrType before resolving it boolean canCreateExactTypePattern = true; @@ -973,7 +973,7 @@ public class WildTypePattern extends TypePattern { if (dim != 0) { rType = ResolvedType.makeArray(rType, dim); } - return new ExactTypePattern(rType, includeSubtypes, isVarArgs); + return new ExactTypePattern(rType, includeSubtypes, isVarArgs, typeParameters); } return this; // leave as wild type pattern then } diff --git a/org.aspectj.matcher/src/test/java/org/aspectj/weaver/patterns/ParserTestCase.java b/org.aspectj.matcher/src/test/java/org/aspectj/weaver/patterns/ParserTestCase.java index 8c7258d59..7378b6661 100644 --- a/org.aspectj.matcher/src/test/java/org/aspectj/weaver/patterns/ParserTestCase.java +++ b/org.aspectj.matcher/src/test/java/org/aspectj/weaver/patterns/ParserTestCase.java @@ -290,7 +290,7 @@ public class ParserTestCase extends PatternsTestCase { public void testParseAllowedSuperInTypeVariable() { PatternParser parser = new PatternParser("T super Number+"); TypeVariablePattern tv = parser.parseTypeVariable(); - TypeVariablePattern expected = new TypeVariablePattern("T", new ExactTypePattern(UnresolvedType.OBJECT, false, false), + TypeVariablePattern expected = new TypeVariablePattern("T", new ExactTypePattern(UnresolvedType.OBJECT, false, false, null), null, new PatternParser("Number+").parseTypePattern()); assertEquals("Expected type variable T super Number+", expected, tv); } -- 2.39.5