clinit has runtags/V_1_1_b5
@@ -21,28 +21,49 @@ import org.eclipse.jdt.internal.compiler.codegen.CodeStream; | |||
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) | |||
))); | |||
} | |||
} | |||
} |
@@ -169,13 +169,13 @@ public class AspectDeclaration extends MemberTypeDeclaration { | |||
} 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( | |||
@@ -367,7 +367,7 @@ public class AspectDeclaration extends MemberTypeDeclaration { | |||
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) { | |||
@@ -549,7 +549,7 @@ public class AspectDeclaration extends MemberTypeDeclaration { | |||
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) { |
@@ -40,12 +40,21 @@ public class AjcMemberMaker { | |||
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"); | |||
} | |||
@@ -39,7 +39,9 @@ public class NameMangler { | |||
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"; | |||
@@ -36,7 +36,7 @@ public class BcelCflowStackFieldAdder extends BcelTypeMunger { | |||
gen.getConstantPoolGen()).getField(); | |||
gen.addField(f); | |||
LazyMethodGen clinit = gen.getAjcClinit(); //StaticInitializer(); | |||
LazyMethodGen clinit = gen.getAjcPreClinit(); //StaticInitializer(); | |||
InstructionList setup = new InstructionList(); | |||
InstructionFactory fact = gen.getFactory(); | |||
@@ -309,13 +309,27 @@ public class BcelShadow extends Shadow { | |||
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, | |||
@@ -326,8 +340,8 @@ public class BcelShadow extends Shadow { | |||
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; | |||
} | |||
@@ -319,15 +319,15 @@ public final class LazyClassGen { | |||
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); |