/* ******************************************************************* * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). * 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: * PARC initial implementation * ******************************************************************/ package org.aspectj.weaver; import java.io.DataInputStream; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.aspectj.asm.IRelationship; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.MessageUtil; import org.aspectj.bridge.WeaveMessage; import org.aspectj.lang.JoinPoint; import org.aspectj.util.PartialOrder; import org.aspectj.util.TypeSafeEnum; import org.aspectj.weaver.ast.Var; import org.aspectj.weaver.bcel.BcelAdvice; /* * The superclass of anything representing a the shadow of a join point. A shadow represents * some bit of code, and encompasses both entry and exit from that code. All shadows have a kind * and a signature. */ public abstract class Shadow { // every Shadow has a unique id, doesn't matter if it wraps... private static int nextShadowID = 100; // easier to spot than zero. private final Kind kind; private final Member signature; private Member matchingSignature; private ResolvedMember resolvedSignature; protected final Shadow enclosingShadow; protected List mungers = Collections.EMPTY_LIST; public int shadowId = nextShadowID++; // every time we build a shadow, it gets a new id // ---- protected Shadow(Kind kind, Member signature, Shadow enclosingShadow) { this.kind = kind; this.signature = signature; this.enclosingShadow = enclosingShadow; } // ---- public abstract World getIWorld(); public List /*ShadowMunger*/ getMungers() { return mungers; } /** * 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 UnresolvedType 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() { 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 UnresolvedType getTargetType() { 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 UnresolvedType[] getArgTypes() { if (getKind() == FieldSet) return new UnresolvedType[] { getSignature().getReturnType() }; return getSignature().getParameterTypes(); } public boolean isShadowForArrayConstructionJoinpoint() { return (getKind()==ConstructorCall && signature.getDeclaringType().isArray()); } public boolean isShadowForMonitor() { return (getKind()==SynchronizationLock || getKind()==SynchronizationUnlock); } // will return the right length array of ints depending on how many dimensions the array has public ResolvedType[] getArgumentTypesForArrayConstructionShadow() { String s = signature.getDeclaringType().getSignature(); int pos = s.indexOf("["); int dims = 1; while (pos1) { // Stores a set of strings of the form 'aspect1:aspect2' which indicates there is no // precedence specified between the two aspects at this shadow. Set clashingAspects = new HashSet(); int max = mungers.size(); // Compare every pair of advice mungers for (int i = max-1; i >=0; i--) { for (int j=0; j