package org.aspectj.weaver.bcel;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.LocalVariable;
import org.aspectj.apache.bcel.classfile.LocalVariableTable;
import org.aspectj.apache.bcel.generic.InstructionConstants;
import org.aspectj.apache.bcel.generic.InstructionFactory;
import org.aspectj.apache.bcel.generic.InstructionHandle;
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.LineNumberTag;
import org.aspectj.apache.bcel.generic.LocalVariableTag;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.Message;
import org.aspectj.weaver.Advice;
import org.aspectj.weaver.AdviceKind;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.IEclipseSourceContext;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.Lint;
import org.aspectj.weaver.Member;
import org.aspectj.weaver.ReferenceType;
import org.aspectj.weaver.ReferenceTypeDelegate;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedMemberImpl;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ShadowMunger;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.patterns.ExactTypePattern;
import org.aspectj.weaver.patterns.ExposedState;
import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.weaver.patterns.Pointcut;
class BcelAdvice extends Advice {
private Test runtimeTest;
private ExposedState exposedState;
private int containsInvokedynamic = 0;
public BcelAdvice(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member adviceSignature, ResolvedType concreteAspect) {
super(attribute, pointcut, simplify(attribute.getKind(), adviceSignature));
this.concreteAspect = concreteAspect;
}
public boolean bindsProceedingJoinPoint() {
UnresolvedType[] parameterTypes = signature.getParameterTypes();
for (int i=0;i<parameterTypes.length;i++) {
if (parameterTypes[i].equals(UnresolvedType.PROCEEDING_JOINPOINT)) {
return true;
}
}
return false;
}
private static Member simplify(AdviceKind kind, Member adviceSignature) {
if (adviceSignature != null) {
UnresolvedType adviceDeclaringType = adviceSignature.getDeclaringType();
if (kind != AdviceKind.Around
|| ((adviceDeclaringType instanceof ResolvedType) && ((ResolvedType) adviceDeclaringType).getWorld()
.isXnoInline())) {
if (adviceSignature instanceof BcelMethod) {
BcelMethod bm = (BcelMethod) adviceSignature;
if (bm.getMethod() != null && bm.getMethod().getAnnotations() != null) {
return adviceSignature;
}
ResolvedMemberImpl simplermember = new ResolvedMemberImpl(bm.getKind(), bm.getDeclaringType(),
bm.getModifiers(), bm.getReturnType(), bm.getName(), bm.getParameterTypes());
simplermember.setParameterNames(bm.getParameterNames());
return simplermember;
}
}
}
return adviceSignature;
}
@Override
public ShadowMunger concretize(ResolvedType fromType, World world, PerClause clause) {
if (!world.areAllLintIgnored()) {
suppressLintWarnings(world);
}
ShadowMunger ret = super.concretize(fromType, world, clause);
if (!world.areAllLintIgnored()) {
clearLintSuppressions(world, this.suppressedLintKinds);
}
IfFinder ifinder = new IfFinder();
ret.getPointcut().accept(ifinder, null);
boolean hasGuardTest = ifinder.hasIf && getKind() != AdviceKind.Around;
boolean isAround = getKind() == AdviceKind.Around;
if ((getExtraParameterFlags() & ThisJoinPoint) != 0) {
if (!isAround && !hasGuardTest && world.getLint().noGuardForLazyTjp.isEnabled()) {
world.getLint().noGuardForLazyTjp.signal("", getSourceLocation());
}
}
return ret;
}
@Override
public ShadowMunger parameterizeWith(ResolvedType declaringType, Map<String, UnresolvedType> typeVariableMap) {
Pointcut pc = getPointcut().parameterizeWith(typeVariableMap, declaringType.getWorld());
BcelAdvice ret = null;
Member adviceSignature = signature;
if (signature instanceof ResolvedMember && signature.getDeclaringType().isGenericType()) {
adviceSignature = ((ResolvedMember) signature).parameterizedWith(declaringType.getTypeParameters(), declaringType,
declaringType.isParameterizedType());
}
ret = new BcelAdvice(this.attribute, pc, adviceSignature, this.concreteAspect);
return ret;
}
@Override
public boolean match(Shadow shadow, World world) {
if (world.areAllLintIgnored()) {
return super.match(shadow, world);
} else {
suppressLintWarnings(world);
boolean ret = super.match(shadow, world);
clearLintSuppressions(world, this.suppressedLintKinds);
return ret;
}
}
@Override
public void specializeOn(Shadow shadow) {
if (getKind() == AdviceKind.Around) {
((BcelShadow) shadow).initializeForAroundClosure();
}
if (getKind() == null) {
exposedState = new ExposedState(0);
return;
}
if (getKind().isPerEntry()) {
exposedState = new ExposedState(0);
} else if (getKind().isCflow()) {
exposedState = new ExposedState(nFreeVars);
} else if (getSignature() != null) {
exposedState = new ExposedState(getSignature());
} else {
exposedState = new ExposedState(0);
return;
}
World world = shadow.getIWorld();
if (!world.areAllLintIgnored()) {
suppressLintWarnings(world);
}
exposedState.setConcreteAspect(concreteAspect);
runtimeTest = getPointcut().findResidue(shadow, exposedState);
if (!world.areAllLintIgnored()) {
clearLintSuppressions(world, this.suppressedLintKinds);
}
if (getKind() == AdviceKind.PerThisEntry) {
shadow.getThisVar();
} else if (getKind() == AdviceKind.PerTargetEntry) {
shadow.getTargetVar();
}
if ((getExtraParameterFlags() & ThisJoinPointStaticPart) != 0) {
((BcelShadow) shadow).getThisJoinPointStaticPartVar();
((BcelShadow) shadow).getEnclosingClass().warnOnAddedStaticInitializer(shadow, getSourceLocation());
}
if ((getExtraParameterFlags() & ThisJoinPoint) != 0) {
boolean hasGuardTest = runtimeTest != Literal.TRUE && getKind() != AdviceKind.Around;
boolean isAround = getKind() == AdviceKind.Around;
((BcelShadow) shadow).requireThisJoinPoint(hasGuardTest, isAround);
((BcelShadow) shadow).getEnclosingClass().warnOnAddedStaticInitializer(shadow, getSourceLocation());
if (!hasGuardTest && world.getLint().multipleAdviceStoppingLazyTjp.isEnabled()) {
((BcelShadow) shadow).addAdvicePreventingLazyTjp(this);
}
}
if ((getExtraParameterFlags() & ThisEnclosingJoinPointStaticPart) != 0) {
((BcelShadow) shadow).getThisEnclosingJoinPointStaticPartVar();
((BcelShadow) shadow).getEnclosingClass().warnOnAddedStaticInitializer(shadow, getSourceLocation());
}
}
private boolean canInline(Shadow s) {
if (attribute.isProceedInInners()) {
return false;
}
if (concreteAspect == null || concreteAspect.isMissing()) {
return false;
}
if (concreteAspect.getWorld().isXnoInline()) {
return false;
}
BcelObjectType boType = BcelWorld.getBcelObjectType(concreteAspect);
if (boType == null) {
return false;
}
if (boType.javaClass.getMajor() >= Constants.MAJOR_1_8) {
if (containsInvokedynamic == 0) {
containsInvokedynamic = 1;
LazyMethodGen lmg = boType.getLazyClassGen().getLazyMethodGen(this.signature.getName(), this.signature.getSignature(), true);
ResolvedType searchType = concreteAspect;
while (lmg == null) {
searchType = searchType.getSuperclass();
if (searchType == null) break;
ReferenceTypeDelegate rtd = ((ReferenceType)searchType).getDelegate();
if (rtd instanceof BcelObjectType) {
BcelObjectType bot = (BcelObjectType)rtd;
if (bot.javaClass.getMajor() < Constants.MAJOR_1_8) {
break;
}
lmg = bot.getLazyClassGen().getLazyMethodGen(this.signature.getName(), this.signature.getSignature(), true);
}
}
if (lmg != null) {
InstructionList ilist = lmg.getBody();
for (InstructionHandle src = ilist.getStart(); src != null; src = src.getNext()) {
if (src.getInstruction().opcode == Constants.INVOKEDYNAMIC) {
containsInvokedynamic = 2;
break;
}
}
}
}
}
if (containsInvokedynamic == 2) {
return false;
}
return boType.getLazyClassGen().isWoven();
}
private boolean aspectIsBroken() {
if (concreteAspect instanceof ReferenceType) {
ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect).getDelegate();
if (!(rtDelegate instanceof BcelObjectType)) {
return true;
}
}
return false;
}
@Override
public boolean implementOn(Shadow s) {
hasMatchedAtLeastOnce = true;
if (aspectIsBroken()) {
return false;
}
BcelShadow shadow = (BcelShadow) s;
if (!shadow.getWorld().isIgnoringUnusedDeclaredThrownException() && !getThrownExceptions().isEmpty()) {
Member member = shadow.getSignature();
if (member instanceof BcelMethod) {
removeUnnecessaryProblems((BcelMethod) member, ((BcelMethod) member).getDeclarationLineNumber());
} else {
ResolvedMember resolvedMember = shadow.getSignature().resolve(shadow.getWorld());
if (resolvedMember instanceof BcelMethod && shadow.getEnclosingShadow() instanceof BcelShadow) {
Member enclosingMember = shadow.getEnclosingShadow().getSignature();
if (enclosingMember instanceof BcelMethod) {
removeUnnecessaryProblems((BcelMethod) enclosingMember,
((BcelMethod) resolvedMember).getDeclarationLineNumber());
}
}
}
}
if (shadow.getIWorld().isJoinpointSynchronizationEnabled() && shadow.getKind() == Shadow.MethodExecution
&& (s.getSignature().getModifiers() & Modifier.SYNCHRONIZED) != 0) {
shadow.getIWorld().getLint().advisingSynchronizedMethods.signal(new String[] { shadow.toString() },
shadow.getSourceLocation(), new ISourceLocation[] { getSourceLocation() });
}
if (runtimeTest == Literal.FALSE) {
Member sig = shadow.getSignature();
if (sig.getArity() == 0 && shadow.getKind() == Shadow.MethodCall && sig.getName().charAt(0) == 'c'
&& sig.getReturnType().equals(ResolvedType.OBJECT) && sig.getName().equals("clone")) {
return false;
}
}
if (getKind() == AdviceKind.Before) {
shadow.weaveBefore(this);
} else if (getKind() == AdviceKind.AfterReturning) {
shadow.weaveAfterReturning(this);
} else if (getKind() == AdviceKind.AfterThrowing) {
UnresolvedType catchType = hasExtraParameter() ? getExtraParameterType() : UnresolvedType.THROWABLE;
shadow.weaveAfterThrowing(this, catchType);
} else if (getKind() == AdviceKind.After) {
shadow.weaveAfter(this);
} else if (getKind() == AdviceKind.Around) {
LazyClassGen enclosingClass = shadow.getEnclosingClass();
if (enclosingClass != null && enclosingClass.isInterface() && shadow.getEnclosingMethod().getName().charAt(0) == '<') {
shadow.getWorld().getLint().cannotAdviseJoinpointInInterfaceWithAroundAdvice.signal(shadow.toString(),
shadow.getSourceLocation());
return false;
}
if (!canInline(s)) {
shadow.weaveAroundClosure(this, hasDynamicTests());
} else {
shadow.weaveAroundInline(this, hasDynamicTests());
}
} else if (getKind() == AdviceKind.InterInitializer) {
shadow.weaveAfterReturning(this);
} else if (getKind().isCflow()) {
shadow.weaveCflowEntry(this, getSignature());
} else if (getKind() == AdviceKind.PerThisEntry) {
shadow.weavePerObjectEntry(this, (BcelVar) shadow.getThisVar());
} else if (getKind() == AdviceKind.PerTargetEntry) {
shadow.weavePerObjectEntry(this, (BcelVar) shadow.getTargetVar());
} else if (getKind() == AdviceKind.Softener) {
shadow.weaveSoftener(this, ((ExactTypePattern) exceptionType).getType());
} else if (getKind() == AdviceKind.PerTypeWithinEntry) {
shadow.weavePerTypeWithinAspectInitialization(this, shadow.getEnclosingType());
} else {
throw new BCException("unimplemented kind: " + getKind());
}
return true;
}
private void removeUnnecessaryProblems(BcelMethod method, int problemLineNumber) {
ISourceContext sourceContext = method.getSourceContext();
if (sourceContext instanceof IEclipseSourceContext) {
((IEclipseSourceContext) sourceContext).removeUnnecessaryProblems(method, problemLineNumber);
}
}
private Collection<ResolvedType> collectCheckedExceptions(UnresolvedType[] excs) {
if (excs == null || excs.length == 0) {
return Collections.emptyList();
}
Collection<ResolvedType> ret = new ArrayList<ResolvedType>();
World world = concreteAspect.getWorld();
ResolvedType runtimeException = world.getCoreType(UnresolvedType.RUNTIME_EXCEPTION);
ResolvedType error = world.getCoreType(UnresolvedType.ERROR);
for (int i = 0, len = excs.length; i < len; i++) {
ResolvedType t = world.resolve(excs[i], true);
if (t.isMissing()) {
world.getLint().cantFindType
.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_EXCEPTION_TYPE, excs[i].getName()),
getSourceLocation());
}
if (!(runtimeException.isAssignableFrom(t) || error.isAssignableFrom(t))) {
ret.add(t);
}
}
return ret;
}
private Collection<ResolvedType> thrownExceptions = null;
@Override
public Collection<ResolvedType> getThrownExceptions() {
if (thrownExceptions == null) {
if (concreteAspect != null && concreteAspect.getWorld() != null &&
(getKind().isAfter() || getKind() == AdviceKind.Before || getKind() == AdviceKind.Around)) {
World world = concreteAspect.getWorld();
ResolvedMember m = world.resolve(signature);
if (m == null) {
thrownExceptions = Collections.emptyList();
} else {
thrownExceptions = collectCheckedExceptions(m.getExceptions());
}
} else {
thrownExceptions = Collections.emptyList();
}
}
return thrownExceptions;
}
@Override
public boolean mustCheckExceptions() {
if (getConcreteAspect() == null) {
return true;
}
return !getConcreteAspect().isAnnotationStyleAspect();
}
@Override
public boolean hasDynamicTests() {
return runtimeTest != null && !(runtimeTest == Literal.TRUE);
}
InstructionList getAdviceInstructions(BcelShadow s, BcelVar extraArgVar, InstructionHandle ifNoAdvice) {
BcelShadow shadow = s;
InstructionFactory fact = shadow.getFactory();
BcelWorld world = shadow.getWorld();
InstructionList il = new InstructionList();
if (hasExtraParameter() && getKind() == AdviceKind.AfterReturning) {
UnresolvedType extraParameterType = getExtraParameterType();
if (!extraParameterType.equals(UnresolvedType.OBJECT) && !extraParameterType.isPrimitiveType()) {
il.append(BcelRenderer.renderTest(fact, world,
Test.makeInstanceof(extraArgVar, getExtraParameterType().resolve(world)), null, ifNoAdvice, null));
}
}
il.append(getAdviceArgSetup(shadow, extraArgVar, null));
il.append(getNonTestAdviceInstructions(shadow));
InstructionHandle ifYesAdvice = il.getStart();
il.insert(getTestInstructions(shadow, ifYesAdvice, ifNoAdvice, ifYesAdvice));
if (shadow.getKind() == Shadow.MethodExecution && getKind() == AdviceKind.Before) {
int lineNumber = 0;
lineNumber = shadow.getEnclosingMethod().getMemberView().getLineNumberOfFirstInstruction();
InstructionHandle start = il.getStart();
if (lineNumber > 0) {
start.addTargeter(new LineNumberTag(lineNumber));
}
LocalVariableTable lvt = shadow.getEnclosingMethod().getMemberView().getMethod().getLocalVariableTable();
if (lvt != null) {
LocalVariable[] lvTable = lvt.getLocalVariableTable();
for (int i = 0; i < lvTable.length; i++) {
LocalVariable lv = lvTable[i];
if (lv.getStartPC() == 0) {
start.addTargeter(new LocalVariableTag(lv.getSignature(), lv.getName(), lv.getIndex(), 0));
}
}
}
}
return il;
}
public InstructionList getAdviceArgSetup(BcelShadow shadow, BcelVar extraVar, InstructionList closureInstantiation) {
InstructionFactory fact = shadow.getFactory();
BcelWorld world = shadow.getWorld();
InstructionList il = new InstructionList();
if (exposedState.getAspectInstance() != null) {
il.append(BcelRenderer.renderExpr(fact, world, exposedState.getAspectInstance()));
}
boolean x = this.getDeclaringAspect().resolve(world).isAnnotationStyleAspect();
final boolean isAnnotationStyleAspect = getConcreteAspect() != null && getConcreteAspect().isAnnotationStyleAspect() && x;
boolean previousIsClosure = false;
for (int i = 0, len = exposedState.size(); i < len; i++) {
if (exposedState.isErroneousVar(i)) {
continue;
}
BcelVar v = (BcelVar) exposedState.get(i);
if (v == null) {
if (!isAnnotationStyleAspect) {
} else {
if ("Lorg/aspectj/lang/ProceedingJoinPoint;".equals(getSignature().getParameterTypes()[i].getSignature())) {
if (getKind() != AdviceKind.Around) {
previousIsClosure = false;
getConcreteAspect()
.getWorld()
.getMessageHandler()
.handleMessage(
new Message("use of ProceedingJoinPoint is allowed only on around advice (" + "arg "
+ i + " in " + toString() + ")", this.getSourceLocation(), true));
il.append(InstructionConstants.ACONST_NULL);
} else {
if (previousIsClosure) {
il.append(InstructionConstants.DUP);
} else {
previousIsClosure = true;
il.append(closureInstantiation.copy());
shadow.closureVarInitialized = true;
}
}
} else if ("Lorg/aspectj/lang/JoinPoint$StaticPart;".equals(getSignature().getParameterTypes()[i]
.getSignature())) {
previousIsClosure = false;
if ((getExtraParameterFlags() & ThisJoinPointStaticPart) != 0) {
shadow.getThisJoinPointStaticPartBcelVar().appendLoad(il, fact);
}
} else if ("Lorg/aspectj/lang/JoinPoint;".equals(getSignature().getParameterTypes()[i].getSignature())) {
previousIsClosure = false;
if ((getExtraParameterFlags() & ThisJoinPoint) != 0) {
il.append(shadow.loadThisJoinPoint());
}
} else if ("Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;".equals(getSignature().getParameterTypes()[i]
.getSignature())) {
previousIsClosure = false;
if ((getExtraParameterFlags() & ThisEnclosingJoinPointStaticPart) != 0) {
shadow.getThisEnclosingJoinPointStaticPartBcelVar().appendLoad(il, fact);
}
} else if (hasExtraParameter()) {
previousIsClosure = false;
extraVar.appendLoadAndConvert(il, fact, getExtraParameterType().resolve(world));
} else {
previousIsClosure = false;
getConcreteAspect()
.getWorld()
.getMessageHandler()
.handleMessage(
new Message("use of ProceedingJoinPoint is allowed only on around advice (" + "arg " + i
+ " in " + toString() + ")", this.getSourceLocation(), true));
il.append(InstructionConstants.ACONST_NULL);
}
}
} else {
UnresolvedType desiredTy = getBindingParameterTypes()[i];
v.appendLoadAndConvert(il, fact, desiredTy.resolve(world));
}
}
if (!isAnnotationStyleAspect) {
if (getKind() == AdviceKind.Around) {
il.append(closureInstantiation);
} else if (hasExtraParameter()) {
extraVar.appendLoadAndConvert(il, fact, getExtraParameterType().resolve(world));
}
if ((getExtraParameterFlags() & ThisJoinPointStaticPart) != 0) {
shadow.getThisJoinPointStaticPartBcelVar().appendLoad(il, fact);
}
if ((getExtraParameterFlags() & ThisJoinPoint) != 0) {
il.append(shadow.loadThisJoinPoint());
}
if ((getExtraParameterFlags() & ThisEnclosingJoinPointStaticPart) != 0) {
shadow.getThisEnclosingJoinPointStaticPartBcelVar().appendLoad(il, fact);
}
}
return il;
}
public InstructionList getNonTestAdviceInstructions(BcelShadow shadow) {
return new InstructionList(Utility.createInvoke(shadow.getFactory(), shadow.getWorld(), getOriginalSignature()));
}
@Override
public Member getOriginalSignature() {
Member sig = getSignature();
if (sig instanceof ResolvedMember) {
ResolvedMember rsig = (ResolvedMember) sig;
if (rsig.hasBackingGenericMember()) {
return rsig.getBackingGenericMember();
}
}
return sig;
}
public InstructionList getTestInstructions(BcelShadow shadow, InstructionHandle sk, InstructionHandle fk, InstructionHandle next) {
return BcelRenderer.renderTest(shadow.getFactory(), shadow.getWorld(), runtimeTest, sk, fk, next);
}
public int compareTo(Object other) {
if (!(other instanceof BcelAdvice)) {
return 0;
}
BcelAdvice o = (BcelAdvice) other;
if (kind.getPrecedence() != o.kind.getPrecedence()) {
if (kind.getPrecedence() > o.kind.getPrecedence()) {
return +1;
} else {
return -1;
}
}
if (kind.isCflow()) {
boolean isBelow = (kind == AdviceKind.CflowBelowEntry);
if (this.innerCflowEntries.contains(o)) {
return isBelow ? +1 : -1;
} else if (o.innerCflowEntries.contains(this)) {
return isBelow ? -1 : +1;
} else {
return 0;
}
}
if (kind.isPerEntry() || kind == AdviceKind.Softener) {
return 0;
}
World world = concreteAspect.getWorld();
int ret = concreteAspect.getWorld().compareByPrecedence(concreteAspect, o.concreteAspect);
if (ret != 0) {
return ret;
}
ResolvedType declaringAspect = getDeclaringAspect().resolve(world);
ResolvedType o_declaringAspect = o.getDeclaringAspect().resolve(world);
if (declaringAspect == o_declaringAspect) {
if (kind.isAfter() || o.kind.isAfter()) {
return this.getStart() < o.getStart() ? -1 : +1;
} else {
return this.getStart() < o.getStart() ? +1 : -1;
}
} else if (declaringAspect.isAssignableFrom(o_declaringAspect)) {
return -1;
} else if (o_declaringAspect.isAssignableFrom(declaringAspect)) {
return +1;
} else {
return 0;
}
}
public BcelVar[] getExposedStateAsBcelVars(boolean isAround) {
if (isAround) {
if (getConcreteAspect() != null && getConcreteAspect().isAnnotationStyleAspect()) {
return BcelVar.NONE;
}
}
if (exposedState == null) {
return BcelVar.NONE;
}
int len = exposedState.vars.length;
BcelVar[] ret = new BcelVar[len];
for (int i = 0; i < len; i++) {
ret[i] = (BcelVar) exposedState.vars[i];
}
return ret;
}
protected void suppressLintWarnings(World inWorld) {
if (suppressedLintKinds == null) {
if (signature instanceof BcelMethod) {
this.suppressedLintKinds = Utility.getSuppressedWarnings(signature.getAnnotations(), inWorld.getLint());
} else {
this.suppressedLintKinds = Collections.emptyList();
return;
}
}
inWorld.getLint().suppressKinds(suppressedLintKinds);
}
protected void clearLintSuppressions(World inWorld, Collection<Lint.Kind> toClear) {
inWorld.getLint().clearSuppressions(toClear);
}
public BcelAdvice(AdviceKind kind, Pointcut pointcut, Member signature, int extraArgumentFlags, int start, int end,
ISourceContext sourceContext, ResolvedType concreteAspect) {
this(new AjAttribute.AdviceAttribute(kind, pointcut, extraArgumentFlags, start, end, sourceContext), pointcut, signature,
concreteAspect);
thrownExceptions = Collections.emptyList();
}
}