aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kriegisch <Alexander@Kriegisch.name>2023-01-17 19:23:26 +0100
committerAlexander Kriegisch <Alexander@Kriegisch.name>2024-04-12 15:32:39 +0200
commited0a8ea17b691489057b670f1b6859e025d6c7c8 (patch)
tree9e2026ff21ba0269bcbe830fcde5eda1ef41bfcd
parentcad9346701b4ef3884283886948b0c2504e00e17 (diff)
downloadaspectj-ed0a8ea17b691489057b670f1b6859e025d6c7c8.tar.gz
aspectj-ed0a8ea17b691489057b670f1b6859e025d6c7c8.zip
New Xlint warning 'arrayCannotBeVoid' when resolving 'void[]'
Because void arrays are illegal (and nonsensical), now there is a new Xlint warning whenever World.resolve resolves a new 'void[]'. Because in the World class we do not have any source context, no path + line number are logged. The user only sees something like: [warning] arrays cannot have a void type, but found 'void[]' in pointcut [Xlint:arrayCannotBeVoid] Then later, if due to the returned MissingResolvedTypeWithKnownSignature type a joinpoint does not match, there is an additional my/path/MyAspect.aj:42 [warning] advice defined in MyAspect has not been applied [Xlint:adviceDidNotMatch] log line, but not necessarily anywhere near the former one. On the one hand, this is better than nothing. OTOH, comparing the situation with no logging message other than Xlint:adviceDidNotMatch in case of something equally illegal like 'Foo<int>' (primitive generic type parameter), this is actually more than we have in several other situations and might even be regarded as superfluous. In case of multiple 'void[]' cases within a big number of aspects, the same aspect or even the same pointcut, the user would have no clue where exactly to search for it. He would just see multiple log messages without source context. One option would be to set 'arrayCannotBeVoid=ignore' in XlintDefault.properties, so the user would have to explicitly activate it. But IMO, this message should be visible by default. Another option would be to find out how to defer logging the messages until later similarly to BcelWeaver.warnOnUnmatchedAdvice and then to bulk-print them. But in order to achieve that, the information about the existence of any 'void[]' occurrences would have to be stored in a flag similar to BcelAdvice.hasMatchedAtLeastOnce, bloating BcelAdvice for that rare case. Alternatively, each advice pointcut could be heuristically scanned for the literal substring 'void[]', logging the Xlint message if it is found anywhere. Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
-rw-r--r--org.aspectj.matcher/src/main/java/org/aspectj/weaver/Lint.java2
-rw-r--r--org.aspectj.matcher/src/main/java/org/aspectj/weaver/World.java8
-rw-r--r--org.aspectj.matcher/src/main/resources/org/aspectj/weaver/XlintDefault.properties2
-rw-r--r--org.aspectj.matcher/src/test/java/org/aspectj/weaver/CommonWorldTests.java12
4 files changed, 24 insertions, 0 deletions
diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Lint.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Lint.java
index 3963e09f4..70d6a8b73 100644
--- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Lint.java
+++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/Lint.java
@@ -138,6 +138,8 @@ public class Lint {
public final Kind missingAspectForReweaving = new Kind("missingAspectForReweaving",
"aspect {0} cannot be found when reweaving {1}");
+ public final Kind arrayCannotBeVoid = new Kind("arrayCannotBeVoid", "arrays cannot have a void type, but found ''{0}'' in pointcut");
+
private static final Trace trace = TraceFactory.getTraceFactory().getTrace(Lint.class);
public Lint(World world) {
diff --git a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/World.java b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/World.java
index 6eab96f15..c5f43da8f 100644
--- a/org.aspectj.matcher/src/main/java/org/aspectj/weaver/World.java
+++ b/org.aspectj.matcher/src/main/java/org/aspectj/weaver/World.java
@@ -316,7 +316,15 @@ public abstract class World implements Dump.INode {
synchronized (buildingTypeLock) {
if (ty.isArray()) {
ResolvedType componentType = resolve(ty.getComponentType(), allowMissing);
+ if (componentType.isVoid()) {
+ if (isInJava5Mode() && getLint().adviceDidNotMatch.isEnabled()) {
+ getLint().arrayCannotBeVoid.signal(ty.toString(), null);
+ }
+ ret = new MissingResolvedTypeWithKnownSignature(signature, this);
+ }
+ else {
ret = new ArrayReferenceType(signature, "[" + componentType.getErasureSignature(), this, componentType);
+ }
} else {
ret = resolveToReferenceType(ty, allowMissing);
if (!allowMissing && ret.isMissing()) {
diff --git a/org.aspectj.matcher/src/main/resources/org/aspectj/weaver/XlintDefault.properties b/org.aspectj.matcher/src/main/resources/org/aspectj/weaver/XlintDefault.properties
index f996d040b..b7a982246 100644
--- a/org.aspectj.matcher/src/main/resources/org/aspectj/weaver/XlintDefault.properties
+++ b/org.aspectj.matcher/src/main/resources/org/aspectj/weaver/XlintDefault.properties
@@ -48,3 +48,5 @@ missingAspectForReweaving=error
cannotAdviseJoinpointInInterfaceWithAroundAdvice=warning
nonReweavableTypeEncountered=error
+
+arrayCannotBeVoid=warning
diff --git a/org.aspectj.matcher/src/test/java/org/aspectj/weaver/CommonWorldTests.java b/org.aspectj.matcher/src/test/java/org/aspectj/weaver/CommonWorldTests.java
index cf9a944fb..550476b4d 100644
--- a/org.aspectj.matcher/src/test/java/org/aspectj/weaver/CommonWorldTests.java
+++ b/org.aspectj.matcher/src/test/java/org/aspectj/weaver/CommonWorldTests.java
@@ -110,6 +110,9 @@ public abstract class CommonWorldTests extends TestCase {
ResolvedType[] primitives = world.resolve(primitiveTypes);
for (ResolvedType ty : primitives) {
UnresolvedType tx = UnresolvedType.forSignature("[" + ty.getSignature());
+ // 'void[]' is an illegal type -> skip
+ if (tx.getSignature().equals("[V"))
+ continue;
ResolvedType aty = world.resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty.isMissing());
modifiersTest(aty, Modifier.PUBLIC | Modifier.FINAL);
@@ -128,6 +131,9 @@ public abstract class CommonWorldTests extends TestCase {
for (ResolvedType ty1 : primitives) {
isCoerceableFromTest(aty, ty1, false);
tx = UnresolvedType.forSignature("[" + ty1.getSignature());
+ // 'void[]' is an illegal type -> skip
+ if (tx.getSignature().equals("[V"))
+ continue;
ResolvedType aty1 = getWorld().resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty1.isMissing());
if (ty.equals(ty1)) {
@@ -142,6 +148,9 @@ public abstract class CommonWorldTests extends TestCase {
// double dimension arrays
for (ResolvedType ty : primitives) {
UnresolvedType tx = UnresolvedType.forSignature("[[" + ty.getSignature());
+ // 'void[][]' is an illegal type -> skip
+ if (tx.getSignature().equals("[[V"))
+ continue;
ResolvedType aty = world.resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty.isMissing());
modifiersTest(aty, Modifier.PUBLIC | Modifier.FINAL);
@@ -160,6 +169,9 @@ public abstract class CommonWorldTests extends TestCase {
for (ResolvedType ty1 : primitives) {
isCoerceableFromTest(aty, ty1, false);
tx = UnresolvedType.forSignature("[[" + ty1.getSignature());
+ // 'void[][]' is an illegal type -> skip
+ if (tx.getSignature().equals("[[V"))
+ continue;
ResolvedType aty1 = getWorld().resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty1.isMissing());
if (ty.equals(ty1)) {