import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
public class AspectClinit extends Clinit {
- public AspectClinit(Clinit old, CompilationResult compilationResult) {
+ private boolean hasPre, hasPost;
+
+ public AspectClinit(Clinit old, CompilationResult compilationResult, boolean hasPre, boolean hasPost) {
super(compilationResult);
this.needFreeReturn = old.needFreeReturn;
this.sourceEnd = old.sourceEnd;
this.sourceStart = old.sourceStart;
this.declarationSourceEnd = old.declarationSourceEnd;
this.declarationSourceStart = old.declarationSourceStart;
+
+ this.hasPre = hasPre;
+ this.hasPost = hasPost;
}
protected void generateSyntheticCode(
ClassScope classScope,
CodeStream codeStream)
{
- if (!classScope.referenceContext.binding.isAbstract()) {
+ if (hasPre) {
final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
codeStream.invokestatic(world.makeMethodBindingForCall(
- AjcMemberMaker.ajcClinitMethod(
+ AjcMemberMaker.ajcPreClinitMethod(
world.fromBinding(classScope.referenceContext.binding)
)));
}
super.generateSyntheticCode(classScope, codeStream);
}
+
+ protected void generatePostSyntheticCode(
+ ClassScope classScope,
+ CodeStream codeStream)
+ {
+ super.generatePostSyntheticCode(classScope, codeStream);
+ if (hasPost) {
+ final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(classScope);
+
+ codeStream.invokestatic(world.makeMethodBindingForCall(
+ AjcMemberMaker.ajcPostClinitMethod(
+ world.fromBinding(classScope.referenceContext.binding)
+ )));
+ }
+
+ }
}
} else if (perClause.getKind() == PerClause.SINGLETON) {
binding.addField(world.makeFieldBinding(AjcMemberMaker.perSingletonField(
typeX)));
- methods[0] = new AspectClinit((Clinit)methods[0], compilationResult);
+ methods[0] = new AspectClinit((Clinit)methods[0], compilationResult, false, true);
} else if (perClause.getKind() == PerClause.PERCFLOW) {
binding.addField(
world.makeFieldBinding(
AjcMemberMaker.perCflowField(
typeX)));
- methods[0] = new AspectClinit((Clinit)methods[0], compilationResult);
+ methods[0] = new AspectClinit((Clinit)methods[0], compilationResult, true, false);
} else if (perClause.getKind() == PerClause.PEROBJECT) {
// binding.addField(
// world.makeFieldBinding(
ClassFile classFile)
{
final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
- generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcClinitMethod(
+ generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcPreClinitMethod(
world.fromBinding(binding))),
new BodyGenerator() {
public void generate(CodeStream codeStream) {
ClassFile classFile)
{
final EclipseWorld world = EclipseWorld.fromScopeLookupEnvironment(this.scope);
- generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcClinitMethod(
+ generateMethod(classFile, world.makeMethodBinding(AjcMemberMaker.ajcPostClinitMethod(
world.fromBinding(binding))),
new BodyGenerator() {
public void generate(CodeStream codeStream) {
public static final TypeX NO_ASPECT_BOUND_EXCEPTION =
TypeX.forName("org.aspectj.lang.NoAspectBoundException");
- public static ResolvedMember ajcClinitMethod(TypeX declaringType) {
+ public static ResolvedMember ajcPreClinitMethod(TypeX declaringType) {
return new ResolvedMember(
Member.METHOD,
declaringType,
PRIVATE_STATIC,
- NameMangler.AJC_CLINIT_NAME,
+ NameMangler.AJC_PRE_CLINIT_NAME,
+ "()V");
+ }
+
+ public static ResolvedMember ajcPostClinitMethod(TypeX declaringType) {
+ return new ResolvedMember(
+ Member.METHOD,
+ declaringType,
+ PRIVATE_STATIC,
+ NameMangler.AJC_POST_CLINIT_NAME,
"()V");
}
public static final String PEROBJECT_BIND_METHOD = PREFIX + "perObjectBind";
- public static final String AJC_CLINIT_NAME = PREFIX + "clinit";
+ public static final String AJC_PRE_CLINIT_NAME = PREFIX + "preClinit";
+
+ public static final String AJC_POST_CLINIT_NAME = PREFIX + "postClinit";
gen.getConstantPoolGen()).getField();
gen.addField(f);
- LazyMethodGen clinit = gen.getAjcClinit(); //StaticInitializer();
+ LazyMethodGen clinit = gen.getAjcPreClinit(); //StaticInitializer();
InstructionList setup = new InstructionList();
InstructionFactory fact = gen.getFactory();
LazyMethodGen enclosingMethod)
{
InstructionList body = enclosingMethod.getBody();
- InstructionHandle ih = body.getStart();
- if (ih.getInstruction() instanceof InvokeInstruction) {
- InvokeInstruction ii = (InvokeInstruction)ih.getInstruction();
- if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPoolGen()).equals(NameMangler.AJC_CLINIT_NAME)) {
- ih = ih.getNext();
+ // move the start past ajc$preClinit
+ InstructionHandle clinitStart = body.getStart();
+ if (clinitStart.getInstruction() instanceof InvokeInstruction) {
+ InvokeInstruction ii = (InvokeInstruction)clinitStart.getInstruction();
+ if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPoolGen()).equals(NameMangler.AJC_PRE_CLINIT_NAME)) {
+ clinitStart = clinitStart.getNext();
}
}
+
+ InstructionHandle clinitEnd = body.getEnd();
+
+ //XXX should move the end before the postClinit, but the return is then tricky...
+// if (clinitEnd.getInstruction() instanceof InvokeInstruction) {
+// InvokeInstruction ii = (InvokeInstruction)clinitEnd.getInstruction();
+// if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPoolGen()).equals(NameMangler.AJC_POST_CLINIT_NAME)) {
+// clinitEnd = clinitEnd.getPrev();
+// }
+// }
+
+
+
BcelShadow s =
new BcelShadow(
world,
ShadowRange r = new ShadowRange(body);
r.associateWithShadow(s);
r.associateWithTargets(
- Range.genStart(body, ih),
- Range.genEnd(body));
+ Range.genStart(body, clinitStart),
+ Range.genEnd(body, clinitEnd));
return s;
}
return clinit;
}
- public LazyMethodGen getAjcClinit() {
+ public LazyMethodGen getAjcPreClinit() {
for (Iterator i = methodGens.iterator(); i.hasNext();) {
LazyMethodGen gen = (LazyMethodGen) i.next();
- if (gen.getName().equals(NameMangler.AJC_CLINIT_NAME)) return gen;
+ if (gen.getName().equals(NameMangler.AJC_PRE_CLINIT_NAME)) return gen;
}
LazyMethodGen ajcClinit = new LazyMethodGen(
Modifier.STATIC,
Type.VOID,
- NameMangler.AJC_CLINIT_NAME,
+ NameMangler.AJC_PRE_CLINIT_NAME,
new Type[0],
CollectionUtil.NO_STRINGS,
this);