From c1260e6b26b78f0f431b778cd8f22d3493e97f3f Mon Sep 17 00:00:00 2001 From: jhugunin Date: Tue, 14 Jan 2003 21:36:18 +0000 Subject: [PATCH] fixed bug #29186, much better handling of structure generation added an Xlint flag for warnings when join points don't have structure nodes --- asm/src/org/aspectj/asm/StructureModel.java | 37 ++++++++++-- .../internal/core/builder/AsmBuilder.java | 60 +++++++++++++++++-- weaver/src/org/aspectj/weaver/AsmAdaptor.java | 15 ++++- weaver/src/org/aspectj/weaver/Lint.java | 3 + .../src/org/aspectj/weaver/ResolvedTypeX.java | 4 ++ weaver/src/org/aspectj/weaver/Shadow.java | 2 +- .../aspectj/weaver/XlintDefault.properties | 4 +- .../org/aspectj/weaver/bcel/BcelWeaver.java | 5 ++ 8 files changed, 116 insertions(+), 14 deletions(-) diff --git a/asm/src/org/aspectj/asm/StructureModel.java b/asm/src/org/aspectj/asm/StructureModel.java index 18f464b4f..831f90f84 100644 --- a/asm/src/org/aspectj/asm/StructureModel.java +++ b/asm/src/org/aspectj/asm/StructureModel.java @@ -70,14 +70,39 @@ public class StructureModel implements Serializable { } if (packageNode == null) return null; } - // !!! this searches each file for a class + + // this searches each file for a class for (Iterator it = packageNode.getChildren().iterator(); it.hasNext(); ) { ProgramElementNode fileNode = (ProgramElementNode)it.next(); - for (Iterator j = fileNode.getChildren().iterator(); j.hasNext(); ) { - ProgramElementNode classNode = (ProgramElementNode)j.next(); - if (classNode instanceof ProgramElementNode && className.equals(classNode.getName())) { - return (ProgramElementNode)classNode; - } + ProgramElementNode ret = findClassInNodes(fileNode.getChildren(), className); + if (ret != null) return ret; + } + + return null; + } + + private ProgramElementNode findClassInNodes(Collection nodes, String name) { + String baseName; + String innerName; + int dollar = name.indexOf('$'); + if (dollar == -1) { + baseName = name; + innerName = null; + } else { + baseName = name.substring(0, dollar); + innerName = name.substring(dollar+1); + } + + + for (Iterator j = nodes.iterator(); j.hasNext(); ) { + ProgramElementNode classNode = (ProgramElementNode)j.next(); +// System.err.println("checking: " + classNode + " for " + baseName); +// System.err.println("children: " + classNode.getChildren()); + if (baseName.equals(classNode.getName())) { + if (innerName == null) return classNode; + else return findClassInNodes(classNode.getChildren(), innerName); + } else if (name.equals(classNode.getName())) { + return classNode; } } return null; diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java index 7a42f7c2a..c894d128b 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AsmBuilder.java @@ -101,6 +101,7 @@ public class AsmBuilder extends AbstractSyntaxTreeVisitorAdapter { public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) { String name = new String(typeDeclaration.name); + //System.err.println("type with name: " + name); ProgramElementNode.Kind kind = ProgramElementNode.Kind.CLASS; if (typeDeclaration instanceof AspectDeclaration) kind = ProgramElementNode.Kind.ASPECT; else if (typeDeclaration.isInterface()) kind = ProgramElementNode.Kind.INTERFACE; @@ -124,6 +125,8 @@ public class AsmBuilder extends AbstractSyntaxTreeVisitorAdapter { // ??? share impl with visit(TypeDeclaration, ..) ? public boolean visit(MemberTypeDeclaration memberTypeDeclaration, ClassScope scope) { String name = new String(memberTypeDeclaration.name); + //System.err.println("member type with name: " + name); + ProgramElementNode.Kind kind = ProgramElementNode.Kind.CLASS; if (memberTypeDeclaration instanceof AspectDeclaration) kind = ProgramElementNode.Kind.ASPECT; else if (memberTypeDeclaration.isInterface()) kind = ProgramElementNode.Kind.INTERFACE; @@ -144,6 +147,54 @@ public class AsmBuilder extends AbstractSyntaxTreeVisitorAdapter { stack.pop(); } + public boolean visit(LocalTypeDeclaration memberTypeDeclaration, BlockScope scope) { + String name = new String(memberTypeDeclaration.name); + String fullName = new String(memberTypeDeclaration.binding.constantPoolName()); + int dollar = fullName.indexOf('$'); + fullName = fullName.substring(dollar+1); +// +// System.err.println("member type with name: " + name + ", " + +// new String(fullName)); + + ProgramElementNode.Kind kind = ProgramElementNode.Kind.CLASS; + if (memberTypeDeclaration.isInterface()) kind = ProgramElementNode.Kind.INTERFACE; + + ProgramElementNode peNode = new ProgramElementNode( + fullName, + kind, + makeLocation(memberTypeDeclaration), + memberTypeDeclaration.modifiers, + "", + new ArrayList()); + + //??? we add this to the compilation unit + findEnclosingClass(stack).addChild(peNode); + stack.push(peNode); + return true; + } + public void endVisit(LocalTypeDeclaration memberTypeDeclaration, BlockScope scope) { + stack.pop(); + } + + public boolean visit(AnonymousLocalTypeDeclaration memberTypeDeclaration, BlockScope scope) { + return visit((LocalTypeDeclaration)memberTypeDeclaration, scope); + } + + public void endVisit(AnonymousLocalTypeDeclaration memberTypeDeclaration, BlockScope scope) { + stack.pop(); + } + + private StructureNode findEnclosingClass(Stack stack) { + for (int i = stack.size()-1; i >= 0; i--) { + ProgramElementNode pe = (ProgramElementNode)stack.get(i); + if (pe.getProgramElementKind() == ProgramElementNode.Kind.CLASS) { + return pe; + } + + } + return (StructureNode)stack.peek(); + } + // !!! improve name and type generation public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { ProgramElementNode.Kind kind = ProgramElementNode.Kind.METHOD; @@ -171,10 +222,11 @@ public class AsmBuilder extends AbstractSyntaxTreeVisitorAdapter { methodDeclaration.modifiers, "", new ArrayList()); - - Member member = EclipseWorld.makeResolvedMember(methodDeclaration.binding); - peNode.setBytecodeName(member.getName()); - peNode.setBytecodeSignature(member.getSignature()); + if (methodDeclaration.binding != null) { + Member member = EclipseWorld.makeResolvedMember(methodDeclaration.binding); + peNode.setBytecodeName(member.getName()); + peNode.setBytecodeSignature(member.getSignature()); + } ((StructureNode)stack.peek()).addChild(peNode); stack.push(peNode); diff --git a/weaver/src/org/aspectj/weaver/AsmAdaptor.java b/weaver/src/org/aspectj/weaver/AsmAdaptor.java index 256f7c470..c9c0e52c0 100644 --- a/weaver/src/org/aspectj/weaver/AsmAdaptor.java +++ b/weaver/src/org/aspectj/weaver/AsmAdaptor.java @@ -77,6 +77,7 @@ public class AsmAdaptor { private static ProgramElementNode getNode(StructureModel model, Advice a) { //ResolvedTypeX inAspect = a.getConcreteAspect(); Member member = a.getSignature(); + if (a.getSignature() == null) return null; return lookupMember(model, member); } @@ -84,6 +85,13 @@ public class AsmAdaptor { Member enclosingMember = shadow.getEnclosingCodeSignature(); ProgramElementNode enclosingNode = lookupMember(model, enclosingMember); + if (enclosingNode == null) { + Lint.Kind err = shadow.getIWorld().getLint().shadowNotInStructure; + if (err.isEnabled()) { + err.signal(shadow.toString(), shadow.getSourceLocation()); + } + return null; + } Member shadowSig = shadow.getSignature(); if (!shadowSig.equals(enclosingMember)) { @@ -117,7 +125,7 @@ public class AsmAdaptor { "", new ArrayList()); - System.err.println(peNode.getSourceLocation()); + //System.err.println(peNode.getSourceLocation()); peNode.setBytecodeName(shadowSig.getName()); peNode.setBytecodeSignature(shadowSig.getSignature()); enclosingNode.addChild(peNode); @@ -142,13 +150,16 @@ public class AsmAdaptor { if (classNode == null) return null; // XXX remove this check for (Iterator it = classNode.getChildren().iterator(); it.hasNext(); ) { ProgramElementNode node = (ProgramElementNode)it.next(); + //System.err.println("checking: " + member.getName() + " with " + node.getBytecodeName() + ", " + node.getBytecodeSignature()); if (member.getName().equals(node.getBytecodeName()) && member.getSignature().equals(node.getBytecodeSignature())) { return node; } } - return null; + // if we can't find the member, we'll just put it in the class + //??? is this what the IDEs want + return classNode; } diff --git a/weaver/src/org/aspectj/weaver/Lint.java b/weaver/src/org/aspectj/weaver/Lint.java index eeef10f10..80163d951 100644 --- a/weaver/src/org/aspectj/weaver/Lint.java +++ b/weaver/src/org/aspectj/weaver/Lint.java @@ -37,6 +37,9 @@ public class Lint { public final Kind typeNotExposedToWeaver = new Kind("typeNotExposedToWeaver", "this affected type is not exposed to the weaver: {0}"); + public final Kind shadowNotInStructure = + new Kind("shadowNotInStructure", "the shadow for this join point is not exposed in the structure model: {0}"); + public Lint(World world) { this.world = world; } diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java index b22087543..b6b0a4fe3 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java @@ -436,6 +436,10 @@ public abstract class ResolvedTypeX extends TypeX { } + public boolean isSynthetic() { + return signature.indexOf("$ajc") != -1; + } + public final boolean isFinal() { return Modifier.isFinal(getModifiers()); } diff --git a/weaver/src/org/aspectj/weaver/Shadow.java b/weaver/src/org/aspectj/weaver/Shadow.java index 505006ccc..fe58a5672 100644 --- a/weaver/src/org/aspectj/weaver/Shadow.java +++ b/weaver/src/org/aspectj/weaver/Shadow.java @@ -305,7 +305,7 @@ public abstract class Shadow { ShadowMunger munger = (ShadowMunger) iter.next(); munger.implementOn(this); if (world.getModel() != null) { - System.err.println("munger: " + munger + " on " + this); + //System.err.println("munger: " + munger + " on " + this); AsmAdaptor.noteMunger(world.getModel(), this, munger); } } diff --git a/weaver/src/org/aspectj/weaver/XlintDefault.properties b/weaver/src/org/aspectj/weaver/XlintDefault.properties index 25e48c76e..59d6d2f28 100644 --- a/weaver/src/org/aspectj/weaver/XlintDefault.properties +++ b/weaver/src/org/aspectj/weaver/XlintDefault.properties @@ -3,4 +3,6 @@ invalidWildcardTypeName = ignore unresolvableMember = warning -typeNotExposedToWeaver = warning \ No newline at end of file +typeNotExposedToWeaver = warning + +shadowNotInStructure = ignore \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 1d62b92cb..53ccfd705 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -294,6 +294,11 @@ public class BcelWeaver implements IWeaver { // non-private for testing LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType) throws IOException { + if (classType.isSynthetic()) { + dumpUnchanged(classFile); + return null; + } + JavaClass javaClass = classType.getJavaClass(); List shadowMungers = fastMatch(shadowMungerList, javaClass); List typeMungers = fastMatch(classType.getInterTypeMungers(), javaClass); -- 2.39.5