]> source.dussan.org Git - aspectj.git/commitdiff
can't do around x initialization,
authorjhugunin <jhugunin>
Tue, 31 Dec 2002 00:55:19 +0000 (00:55 +0000)
committerjhugunin <jhugunin>
Tue, 31 Dec 2002 00:55:19 +0000 (00:55 +0000)
refactored hasThis kinda thing

weaver/src/org/aspectj/weaver/Advice.java
weaver/src/org/aspectj/weaver/Shadow.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/bcel/ExceptionRange.java
weaver/src/org/aspectj/weaver/bcel/Range.java

index 361c4a93f76411166dbdd785c0eca419ef662bdb..e903b6c420844c32acc22358be8b83c825a2b961 100644 (file)
@@ -104,10 +104,15 @@ public abstract class Advice extends ShadowMunger {
                        return shadow.hasThis();
                } else if (kind == AdviceKind.Around) {
                        if (shadow.getKind() == Shadow.PreInitialization) {
-                               world.showMessage(IMessage.WARNING,
+                               world.showMessage(IMessage.ERROR,
                                        "around on pre-initialization not supported (compiler limitation)", 
                                        getSourceLocation(), shadow.getSourceLocation());
                                        return false;
+                       } else if (shadow.getKind() == Shadow.Initialization) {
+                               world.showMessage(IMessage.ERROR,
+                                       "around on initialization not supported (compiler limitation)", 
+                                       getSourceLocation(), shadow.getSourceLocation());
+                                       return false;
                        } else {
                                if (!getSignature().getReturnType().isConvertableFrom(shadow.getReturnType(), world)) {
                                        //System.err.println(this + ", " + sourceContext + ", " + start);
index 1051194203061562f1cb89207bae69e172c8e5f5..6e37e89f32f6278a2889ec95caa4761fc09ad528 100644 (file)
@@ -35,29 +35,88 @@ import org.aspectj.util.*;
 public abstract class Shadow {
        private final Kind kind; 
     private final Member signature;
+       protected final Shadow enclosingShadow;
     protected List mungers = new ArrayList(1);
 
        // ----
-
-    protected Shadow(Kind kind, Member signature) {
+    protected Shadow(Kind kind, Member signature, Shadow enclosingShadow) {
         this.kind = kind;
         this.signature = signature;
+        this.enclosingShadow = enclosingShadow;
     }
 
        // ----
 
     public abstract World getIWorld();
     
+    /**
+     * could this(*) pcd ever match
+     */
+    public final boolean hasThis() {
+       if (getKind().neverHasThis()) {
+               return false;
+       } else if (getKind().isEnclosingKind()) {
+               return !getSignature().isStatic();
+       } else if (enclosingShadow == null) {
+               return false;
+       } else {
+               return enclosingShadow.hasThis();
+       }
+    }
+
+    /**
+     * the type of the this object here
+     * 
+     * @throws IllegalStateException if there is no this here
+     */
+    public final TypeX getThisType() {
+        if (!hasThis()) throw new IllegalStateException("no this");
+        if (getKind().isEnclosingKind()) {
+               return getSignature().getDeclaringType();
+       } else {
+               return enclosingShadow.getThisType();
+       }
+    }
+    
+    /**
+     * a var referencing this
+     * 
+     * @throws IllegalStateException if there is no target here
+     */
+    public abstract Var getThisVar();
+    
+    
+    
+    /**
+     * could target(*) pcd ever match
+     */
     public final boolean hasTarget() {
-        return !(getSignature().isStatic() || (getKind() == ConstructorCall)
-                         || (getKind() == PreInitialization));
+       if (getKind().neverHasTarget()) {
+               return false;
+       } else if (getKind().isTargetSameAsThis()) {
+               return hasThis();
+       } else {
+               return !getSignature().isStatic();
+       }
     }
 
+    /**
+     * the type of the target object here
+     * 
+     * @throws IllegalStateException if there is no target here
+     */
     public final TypeX getTargetType() {
-        if (!hasTarget()) return ResolvedTypeX.MISSING;
+        if (!hasTarget()) throw new IllegalStateException("no target");
         return getSignature().getDeclaringType();
     }
     
+    /**
+     * a var referencing the target
+     * 
+     * @throws IllegalStateException if there is no target here
+     */
+    public abstract Var getTargetVar();
+    
     public TypeX[] getArgTypes() {
        if (getKind() == FieldSet) return new TypeX[] { getSignature().getReturnType() };
         return getSignature().getParameterTypes();
@@ -73,12 +132,9 @@ public abstract class Shadow {
         return getSignature()
             .getParameterTypes().length;
     }
-    
-    public abstract boolean hasThis();
-       public abstract TypeX getThisType();    
+       
        public abstract TypeX getEnclosingType();       
-       public abstract Var getThisVar();
-       public abstract Var getTargetVar();
+
        public abstract Var getArgVar(int i);
        
        public abstract Var getThisJoinPointVar();
@@ -128,7 +184,7 @@ public abstract class Shadow {
     /** A type-safe enum representing the kind of shadows
      */
        public static final class Kind extends TypeSafeEnum {
-               private boolean argsOnStack;
+               private boolean argsOnStack;  //XXX unused
 
                public Kind(String name, int key, boolean argsOnStack) {
                        super(name, key);
@@ -140,7 +196,7 @@ public abstract class Shadow {
                }
 
                public boolean argsOnStack() {
-                       return argsOnStack;
+                       return !isTargetSameAsThis();
                }
 
                // !!! this is false for handlers!
@@ -148,6 +204,44 @@ public abstract class Shadow {
                        return true;
                }
                
+               // XXX revisit along with removal of priorities
+               public boolean hasHighPriorityExceptions() {
+                       return !isTargetSameAsThis();
+               }
+               
+               
+               /**
+                * These are all the shadows that contains other shadows within them and
+                * are often directly associated with methods.
+                */
+               public boolean isEnclosingKind() {
+                       return this == MethodExecution || this == ConstructorExecution ||
+                                       this == AdviceExecution || this == StaticInitialization
+                                       || this == Initialization;
+               }
+               
+               public boolean isTargetSameAsThis() {
+                       return this == MethodExecution 
+                               || this == ConstructorExecution 
+                               || this == StaticInitialization
+                               || this == PreInitialization
+                               || this == AdviceExecution
+                               || this == Initialization;
+               }
+               
+               public boolean neverHasTarget() {
+                       return this == ConstructorCall
+                               || this == ExceptionHandler
+                               || this == PreInitialization
+                               || this == StaticInitialization;
+               }
+               
+               public boolean neverHasThis() {
+                       return this == PreInitialization
+                               || this == StaticInitialization;
+               }
+               
+               
                public String getSimpleName() {
                        int dash = getName().lastIndexOf('-');
                        if (dash == -1) return getName();
@@ -233,6 +327,9 @@ public abstract class Shadow {
 
 
 
+
+
+
        // ---- type access methods
   
       
index a56b7d139967476010cd06194c362ff905e80723..8ceda85e38e15a6bf2b2668e0c849e4f615184cb 100644 (file)
@@ -495,6 +495,10 @@ class BcelClassWeaver implements IClassWeaver {
                                                                (InstructionHandle) srcToDest.get(oldRange.getEnd()));
                                                        shadowMap.put(oldRange, freshRange);
                                                        //recipient.matchedShadows.add(freshShadow);
+                                                       // XXX should go through the NEW copied shadow and update
+                                                       // the thisVar, targetVar, and argsVar
+                                                       // ??? Might want to also go through at this time and add
+                                                       // "extra" vars to the shadow. 
                                                }
                                        }
                    }
@@ -634,13 +638,16 @@ class BcelClassWeaver implements IClassWeaver {
                        enclosingShadow = BcelShadow.makeConstructorExecution(world, mg, superOrThisCall);
                        
                        // walk the body
+                       boolean beforeSuperOrThisCall = true;
                        if (shouldWeaveBody(mg)) { //!mg.isAjSynthetic()) {
                                for (InstructionHandle h = mg.getBody().getStart();
                                        h != null;
                                        h = h.getNext()) {
-                                       if (h == superOrThisCall)
+                                       if (h == superOrThisCall) {
+                                               beforeSuperOrThisCall = false;
                                                continue;
-                                       match(mg, h, enclosingShadow, shadowAccumulator);
+                                       }
+                                       match(mg, h, beforeSuperOrThisCall ? null : enclosingShadow, shadowAccumulator);
                                }
                                match(enclosingShadow, shadowAccumulator);
                        }
index 8fad558e1d1c17fa4a7a475ff733c2c60f5333ba..4f80060e1b74019dd5ef2c3f5f69bc6da598b902 100644 (file)
@@ -78,9 +78,7 @@ public class BcelShadow extends Shadow {
     private ShadowRange range;    
     private final BcelWorld world;  
     private final LazyMethodGen enclosingMethod;
-    private final BcelShadow enclosingShadow;
-
-       private boolean fallsThrough;
+       private boolean fallsThrough;  //XXX not used anymore
 
        // ---- initialization
        
@@ -96,10 +94,9 @@ public class BcelShadow extends Shadow {
                LazyMethodGen enclosingMethod,
                BcelShadow enclosingShadow) 
        {
-               super(kind, signature);
+               super(kind, signature, enclosingShadow);
                this.world = world;
                this.enclosingMethod = enclosingMethod;
-               this.enclosingShadow = enclosingShadow;
                fallsThrough = kind.argsOnStack();
        }
 
@@ -273,7 +270,7 @@ public class BcelShadow extends Shadow {
     
     // overrides
     public TypeX getEnclosingType() {
-       return world.resolve(getEnclosingClass().getClassName());
+       return getEnclosingClass().getType();
     }
 
     public LazyClassGen getEnclosingClass() {
@@ -652,23 +649,6 @@ public class BcelShadow extends Shadow {
        }
 
     // ---- type access methods
-  
-    public boolean hasThis() {
-       if (getKind() == PreInitialization) return false;
-       return !getEnclosingCodeSignature().isStatic();
-        //???return !enclosingMethod.isStatic();
-    }        
-    public TypeX getThisType() {
-        if (!hasThis()) return ResolvedTypeX.MISSING;
-        return getEnclosingCodeSignature().getDeclaringType();
-        //???return TypeX.forName(getEnclosingClass().getClassName());      
-    }
-
-    public boolean isTargetDifferentFromThis() {
-        return hasTarget() && isExpressionKind();
-    }
-
-
     private ObjectType getTargetBcelType() {
         return (ObjectType) world.makeBcelType(getTargetType());
     }
@@ -677,10 +657,28 @@ public class BcelShadow extends Shadow {
     }
 
     // ---- kinding
+
+       /**
+        * If the end of my range has no real instructions following then
+        * my context needs a return at the end.
+        */
+    public boolean terminatesWithReturn() {
+       return getRange().getRealNext() == null;
+    }
     
-    public boolean isExpressionKind() {
-               if (getKind() == PreInitialization) return true;
-        return getKind().argsOnStack();
+    /**
+        * Is arg0 occupied with the value of this
+        */
+    public boolean arg0HoldsThis() {
+       if (getKind().isEnclosingKind()) {
+               return !getSignature().isStatic();
+       } else if (enclosingShadow == null) {
+               //XXX this is mostly right
+               // this doesn't do the right thing for calls in the pre part of introduced constructors.
+               return !enclosingMethod.isStatic();
+       } else {
+               return ((BcelShadow)enclosingShadow).arg0HoldsThis();
+       }
     }
 
     // ---- argument getting methods
@@ -770,7 +768,7 @@ public class BcelShadow extends Shadow {
                // the enclosing of an execution is itself
                return getThisJoinPointStaticPartBcelVar();
        } else {
-               return enclosingShadow.getThisJoinPointStaticPartBcelVar();
+               return ((BcelShadow)enclosingShadow).getThisJoinPointStaticPartBcelVar();
        }
     }
     
@@ -815,8 +813,8 @@ public class BcelShadow extends Shadow {
     public void initializeTargetVar() {
        InstructionFactory fact = getFactory();         
         if (targetVar != null) return;
-        if (! isExpressionKind()) {
-            initializeThisVar();
+        if (getKind().isTargetSameAsThis()) {
+            if (hasThis()) initializeThisVar();
             targetVar = thisVar;
         } else {
             initializeArgVars(); // gotta pop off the args before we find the target
@@ -846,7 +844,7 @@ public class BcelShadow extends Shadow {
             }
         } else {
             int index = 0;
-            if (hasThis()) index++;
+            if (arg0HoldsThis()) index++;
             
             for (int i = 0; i < len; i++) {
                 TypeX type = getArgType(i); 
@@ -966,7 +964,7 @@ public class BcelShadow extends Shadow {
         enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(),
                                  handlerStart, (ObjectType)BcelWorld.makeBcelType(catchType), //???Type.THROWABLE, 
                                  // high priority if our args are on the stack
-                                 isExpressionKind());    
+                                 getKind().hasHighPriorityExceptions());
     }      
 
 
@@ -994,7 +992,7 @@ public class BcelShadow extends Shadow {
         enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(),
                                  handlerStart, (ObjectType)BcelWorld.makeBcelType(catchType), 
                                  // high priority if our args are on the stack
-                                 isExpressionKind());    
+                                 getKind().hasHighPriorityExceptions());    
     }      
 
 
@@ -1173,7 +1171,7 @@ public class BcelShadow extends Shadow {
             range.append(advice);
         } else {
             InstructionList callback = makeCallToCallback(extractedMethod);
-            if (! isExpressionKind()) {
+            if (terminatesWithReturn()) {
                 callback.append(fact.createReturn(extractedMethod.getReturnType()));
             } else {
                 advice.append(fact.createBranchInstruction(Constants.GOTO, range.getEnd()));
@@ -1358,7 +1356,7 @@ public class BcelShadow extends Shadow {
         } else {
             InstructionList callback = makeCallToCallback(callbackMethod);
             InstructionList postCallback = new InstructionList();
-            if (! isExpressionKind()) {
+            if (terminatesWithReturn()) {
                 callback.append(fact.createReturn(callbackMethod.getReturnType()));
             } else {
                 advice.append(fact.createBranchInstruction(Constants.GOTO, postCallback.append(fact.NOP)));
@@ -1652,7 +1650,7 @@ public class BcelShadow extends Shadow {
                int newi = 0;
                // if we're passing in a this and we're not argsOnStack we're always 
                // passing in a target too
-               if (hasThis()) { ret.put(0, 0); oldi++; newi+=1; }
+               if (arg0HoldsThis()) { ret.put(0, 0); oldi++; newi+=1; }
                //assert targetVar == thisVar
                for (int i = 0; i < getArgCount(); i++) {
                    TypeX type = getArgType(i); 
@@ -1661,6 +1659,12 @@ public class BcelShadow extends Shadow {
                    newi += type.getSize();
                }   
         }      
+        
+//        System.err.println("making remap for : " + this);
+//        if (targetVar != null) System.err.println("target slot : " + targetVar.getSlot());
+//        if (thisVar != null) System.err.println("  this slot : " + thisVar.getSlot());
+//        System.err.println(ret);
+        
         return ret;
     }
 
@@ -1684,7 +1688,7 @@ public class BcelShadow extends Shadow {
             TypeX targetType = getTargetType();
             ResolvedMember resolvedMember = getSignature().resolve(world);
             if (resolvedMember != null && Modifier.isProtected(resolvedMember.getModifiers()) && 
-               !samePackage(targetType.getPackageName(), getThisType().getPackageName()))
+               !samePackage(targetType.getPackageName(), getEnclosingType().getPackageName()))
             {
                if (!targetType.isAssignableFrom(getThisType(), world)) {
                        throw new BCException("bad bytecode");
@@ -1777,7 +1781,7 @@ public class BcelShadow extends Shadow {
                return new SourceLocation(new File(getEnclosingClass().getFileName()), getSourceLine());
        }
 
-       public BcelShadow getEnclosingShadow() {
+       public Shadow getEnclosingShadow() {
                return enclosingShadow;
        }
 
@@ -1786,6 +1790,6 @@ public class BcelShadow extends Shadow {
        }
 
        public boolean isFallsThrough() {
-               return fallsThrough;
+               return !terminatesWithReturn(); //fallsThrough;
        }
 }
index 2e65203613202c0699960614bc85983b6689e899..a18bf8f454d46365a76ac1f28780fe4d55f2fce4 100644 (file)
@@ -42,14 +42,20 @@ public final class ExceptionRange extends Range {
        /**
         * After this constructor is called, this range is not well situated unless 
         * {@link #associateWithTargets} is called
+        * 
+        * XXX priority should be fixed
         */
        public ExceptionRange(InstructionList body, TypeX exceptionType, int priority) {
                super(body);
                this.exceptionType = exceptionType;
                this.priority = priority;
        }
-       public ExceptionRange(InstructionList body, TypeX exceptionType, boolean highPriority) {
-               this(body, exceptionType, highPriority ? Integer.MAX_VALUE : -1);
+       
+       /**
+        * @param insideExisting 
+        */
+       public ExceptionRange(InstructionList body, TypeX exceptionType, boolean insideExisting) {
+               this(body, exceptionType, insideExisting ? Integer.MAX_VALUE : -1);
        }
        public void associateWithTargets(
                InstructionHandle start,
index 49df80897fb141fb38c7687950251f7347e1b7e7..416c02a77f87194bb041b80a734f0a801765ea5f 100644 (file)
@@ -80,6 +80,10 @@ abstract class Range implements InstructionTargeter {
         return getRealEnd(end);
     }
        
+    InstructionHandle getRealNext() {
+        return getRealStart(end);
+    }
+       
        static InstructionHandle getRealPrev(InstructionHandle ih) {
                InstructionHandle ret = ih.getPrev();
                while (isRangeHandle(ret)) {