import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler;
import org.aspectj.bridge.context.CompilationAndWeavingContext;
import org.aspectj.bridge.context.ContextToken;
+import org.aspectj.org.eclipse.jdt.core.Flags;
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
if (kind == AdviceKind.Around) {
ReferenceBinding[] exceptions =
new ReferenceBinding[] { upperScope.getJavaLangThrowable() };
- proceedMethodBinding = new MethodBinding(Modifier.STATIC,
+ proceedMethodBinding = new MethodBinding(Modifier.STATIC | Flags.AccSynthetic,
"proceed".toCharArray(), binding.returnType,
resize(baseArgumentCount+1, binding.parameters),
exceptions, binding.declaringClass);
import java.util.Iterator;
import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope;
+import org.aspectj.org.eclipse.jdt.core.Flags;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
* corresponding method as the anchor for the declared annotation
*/
public void generateCode(ClassScope classScope, ClassFile classFile) {
+ this.binding.modifiers |= Flags.AccSynthetic;
classFile.extraAttributes.add(new EclipseAttributeAdapter(new AjAttribute.DeclareAttribute(declareDecl)));
if (shouldDelegateCodeGeneration()) {
super.generateCode(classScope,classFile);
addVersionAttributeIfNecessary(classFile);
if (generateSyntheticPointcutMethod) {
+ this.binding.modifiers |= AccSynthetic;
super.generateCode(classScope,classFile);
}
return;
import org.aspectj.ajdt.internal.core.builder.AjBuildManager;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.bridge.IMessage.Kind;
+import org.aspectj.org.eclipse.jdt.core.Flags;
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
import org.aspectj.weaver.BoundedReferenceType;
import org.aspectj.weaver.ConcreteTypeMunger;
import org.aspectj.weaver.IHasPosition;
import org.aspectj.weaver.Member;
+import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.NewFieldTypeMunger;
import org.aspectj.weaver.NewMethodTypeMunger;
import org.aspectj.weaver.ReferenceType;
Constant.NotAConstant);
typeVariableToTypeBinding.clear();
currentType = null;
+
+ if (member.getName().startsWith(NameMangler.PREFIX)) {
+ fb.modifiers |= Flags.AccSynthetic;
+ }
return fb;
}
if (tvbs!=null) mb.typeVariables = tvbs;
typeVariableToTypeBinding.clear();
currentType = null;
+
+ if (NameMangler.isSyntheticMethod(member.getName(), true)) {
+ mb.modifiers |= Flags.AccSynthetic;
+ }
+
return mb;
}
--- /dev/null
+import java.lang.reflect.*;
+
+public class TheWholeShow {
+
+ private int f;
+
+ public void foo() {}
+
+ private void bar() {}
+
+ public static void main(String[] args) {
+ Field[] twsFields = TheWholeShow.class.getDeclaredFields();
+ for (Field f : twsFields) {
+ if (!f.getName().equals("f") && !f.getName().equals("x")) {
+ if (!f.isSynthetic()) {
+ System.err.println("Found non-synthetic field: " + f.getName());
+ throw new IllegalStateException("Found non-synthetic field: " + f.getName());
+ }
+ if (!Modifier.isStatic(f.getModifiers()) && !Modifier.isTransient(f.getModifiers())) {
+ System.err.println("Found non-transient field: " + f.getName());
+ throw new IllegalStateException("Found non-transient field: " + f.getName());
+ }
+ }
+ }
+
+ Method[] twsMethods = TheWholeShow.class.getDeclaredMethods();
+ for (Method m: twsMethods) {
+ if (! (m.getName().equals("foo") || m.getName().equals("bar") || m.getName().equals("<init>") ||
+ m.getName().equals("main") || m.getName().equals("checkOnlyHasAdviceMembers") || m.getName().equals("getX")) ) {
+ if (!m.isSynthetic()) {
+ System.err.println("Found non-synthetic method: " + m.getName());
+ throw new IllegalStateException("Found non-synthetic method: " + m.getName());
+ }
+ }
+ }
+
+ checkOnlyHasAdviceMembers(MakeITDs.class);
+ checkOnlyHasAdviceMembers(Declares.class);
+ checkOnlyHasAdviceMembers(Advises.class);
+ checkOnlyHasAdviceMembers(PerObject.class);
+ checkOnlyHasAdviceMembers(PTW.class);
+ checkOnlyHasAdviceMembers(Priv.class);
+
+ }
+
+
+ private static void checkOnlyHasAdviceMembers(Class c) {
+ Method[] ms = c.getDeclaredMethods();
+ Field[] fs = c.getDeclaredFields();
+
+ for (Field f : fs) {
+ if (!f.isSynthetic()) {
+ System.err.println("Found non-synthetic field: " + f.getName() + " in " + c.getName());
+ throw new IllegalStateException("Found non-synthetic field: " + f.getName());
+ }
+ }
+
+ for (Method m : ms) {
+ if (!m.isSynthetic()) {
+ String name = m.getName();
+ if ( ! (name.startsWith("ajc$before") || name.startsWith("ajc$after") || name.startsWith("ajc$around") ||
+ name.startsWith("ajc$interMethod$"))) {
+ System.err.println("Found non-synthetic method: " + m.getName() + " in " + c.getName());
+ throw new IllegalStateException("Found non-synthetic method: " + m.getName());
+ } else if (name.startsWith("ajc$around") && name.endsWith("proceed")) {
+ System.err.println("Found non-synthetic method: " + m.getName() + " in " + c.getName());
+ throw new IllegalStateException("Found non-synthetic method: " + m.getName());
+ }
+ }
+ }
+ }
+}
+
+
+aspect MakeITDs {
+
+ public int TheWholeShow.x = 5;
+ private int TheWholeShow.y = 6;
+ int TheWholeShow.z = 7;
+
+ public int TheWholeShow.getX() { return x; }
+
+ private int TheWholeShow.getY() { return y; }
+
+ int TheWholeShow.getZ() { return z; }
+
+}
+
+aspect Declares {
+
+ interface Foo {}
+
+ declare parents : TheWholeShow implements Foo;
+
+ declare warning : execution(* TheWholeShow.notThere(..)) : "foo";
+
+ declare soft : Exception : execution(* TheWholeShow.foo(..));
+
+}
+
+aspect Advises {
+
+ pointcut pc() : execution(* TheWholeShow.*(..));
+
+ before() : pc() {}
+
+ Object around(Object tws) : pc() && this(tws) {
+ return proceed(new TheWholeShow());
+ }
+
+ after() : pc() {}
+
+ after() returning : pc() {}
+
+ after() throwing : pc() {}
+
+
+}
+
+aspect PerObject perthis(execution(* TheWholeShow.*(..))) {
+
+}
+
+aspect PTW pertypewithin(TheWholeShow) {}
+
+aspect Cflow {
+
+ before() : set(* x) && cflow(execution(* TheWholeShow.*(..))) {}
+
+}
+
+privileged aspect Priv {
+
+ before(TheWholeShow tws) : execution(* TheWholeShow.foo()) && this(tws) {
+ tws.bar();
+ tws.f = 12;
+ }
+
+}
\ No newline at end of file
ajc$interFieldGet$... method on target of ITD-field yes
ajc$interFieldSet$... method on target of ITD-field yes
ajc$interMethodDispatch2$... method on target of ITD-method yes
+
+** note - also make sure that every ajc$ field we introduce in a woven type is marked as transient.
<run class="Declaration1">
<stdout>
<line text="public java.lang.String Test.firstProperty has annotation:true"/>
- <line text="public java.lang.String Test.ajc$interField$Declaration1$TestInterface$secondProperty has annotation:true"/>
+ <line text="public transient java.lang.String Test.ajc$interField$Declaration1$TestInterface$secondProperty has annotation:true"/>
</stdout>
</run>
</ajc-test>
<run class="Declaration2">
<stdout>
<line text="public java.lang.String Test.firstProperty has annotation:true"/>
- <line text="public java.lang.String Test.ajc$interField$Declaration2$TestInterface$secondProperty has annotation:true"/>
+ <line text="public transient java.lang.String Test.ajc$interField$Declaration2$TestInterface$secondProperty has annotation:true"/>
</stdout>
</run>
</ajc-test>
public void testGenericAspectHierarchyWithBounds_pr147845() { runTest("Generic abstract aspect hierarchy with bounds"); }
public void testJRockitBooleanReturn_pr148007() { runTest("jrockit boolean fun");}
public void testJRockitBooleanReturn2_pr148007() { runTest("jrockit boolean fun (no aspects)");}
+ public void testSyntheticAjcMembers_pr147711() { runTest("synthetic ajc$ members"); }
public void testDeclareAtMethodRelationship_pr143924() {
//AsmManager.setReporting("c:/debug.txt",true,true,true,true);
<ajc-test dir="bugs152/pr148007/purejava" title="jrockit boolean fun (no aspects)">
<compile files="test/BooleanUnitTest.java, test/LoggingAspect.java" options="-inlineJSR"/>
<run class="test.BooleanUnitTest"/>
+ </ajc-test>
+
+ <ajc-test dir="features152/synthetic" title="synthetic ajc$ members">
+ <compile files="TheWholeShow.aj" options="-1.5"/>
+ <run class="TheWholeShow"/>
</ajc-test>
</suite>
\ No newline at end of file
public static final String INITFAILURECAUSE_FIELD_NAME = PREFIX + "initFailureCause";
+ public static boolean isSyntheticMethod(String methodName, boolean declaredInAspect) {
+ if (methodName.startsWith(PREFIX)) {
+ // it's synthetic unless it is an advice method
+ if (methodName.startsWith("ajc$before") ||
+ methodName.startsWith("ajc$after")) {
+ return false;
+ } else if (methodName.startsWith("ajc$around")) {
+ // around advice method is not synthetic, but generated proceed is...
+ return (methodName.endsWith("proceed"));
+ } else if (methodName.startsWith("ajc$interMethod$")) {
+ return false; // body of an itd-m
+ }
+ return true;
+ }
+ else if (methodName.indexOf("_aroundBody") != -1) {
+ return true;
+ }
+ else if (declaredInAspect) {
+ if (methodName.equals("aspectOf") || methodName.equals("hasAspect")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static String perObjectInterfaceGet(UnresolvedType aspectType) {
return makeName(aspectType.getNameAsIdentifier(), "perObjectGet");
}
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Signature;
+import org.aspectj.apache.bcel.classfile.Synthetic;
import org.aspectj.apache.bcel.classfile.Unknown;
import org.aspectj.apache.bcel.classfile.annotation.Annotation;
import org.aspectj.apache.bcel.generic.BasicType;
*/
public final class LazyClassGen {
+ private static final int ACC_SYNTHETIC = 0x1000;
+
int highestLineNumber = 0; // ---- JSR 45 info
private SortedMap /* <String, InlinedSourceFileInfo> */ inlinedFiles = new TreeMap();
private void addField(Field field) {
myGen.addField(field);
+ makeSyntheticAndTransientIfNeeded(field);
+ }
+
+ private void makeSyntheticAndTransientIfNeeded(Field field) {
+ if (field.getName().startsWith(NameMangler.PREFIX)) {
+ // it's an aj added field
+ // first do transient
+ if (!field.isStatic()) {
+ field.setModifiers(field.getModifiers() | Constants.ACC_TRANSIENT);
+ }
+ // then do synthetic
+ if (getWorld().isInJava5Mode()) {
+ // add the synthetic modifier flag
+ field.setModifiers(field.getModifiers() | ACC_SYNTHETIC);
+ }
+ if (!hasSyntheticAttribute(field.getAttributes())) {
+ // belt and braces, do the attribute even on Java 5 in addition to the modifier flag
+ Attribute[] oldAttrs = field.getAttributes();
+ Attribute[] newAttrs = new Attribute[oldAttrs.length + 1];
+ System.arraycopy(oldAttrs, 0, newAttrs, 0, oldAttrs.length);
+ ConstantPoolGen cpg = myGen.getConstantPool();
+ int index = cpg.addUtf8("Synthetic");
+ Attribute synthetic = new Synthetic(index, 0, new byte[0], cpg.getConstantPool());
+ newAttrs[newAttrs.length - 1] = synthetic;
+ field.setAttributes(newAttrs);
+ }
+ }
}
+ private boolean hasSyntheticAttribute(Attribute[] attributes) {
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].getName().equals("Synthetic")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public void replaceField(Field oldF, Field newF){
myGen.removeField(oldF);
myGen.addField(newF);
import org.aspectj.weaver.BCException;
import org.aspectj.weaver.ISourceContext;
import org.aspectj.weaver.MemberImpl;
+import org.aspectj.weaver.NameMangler;
import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.Shadow;
*/
public final class LazyMethodGen {
+ private static final int ACC_SYNTHETIC = 0x1000;
+
private int accessFlags;
private Type returnType;
private final String name;
// ---- packing!
public MethodGen pack() {
+ forceSyntheticForAjcMagicMembers();
+
//killNops();
int flags = getAccessFlags();
if (enclosingClass.getWorld().isJoinpointSynchronizationEnabled()) {
}
if (isSynthetic) {
- ConstantPoolGen cpg = gen.getConstantPool();
- int index = cpg.addUtf8("Synthetic");
- gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg.getConstantPool()));
+ if (enclosingClass.getWorld().isInJava5Mode()) {
+ gen.setModifiers(gen.getModifiers() | ACC_SYNTHETIC);
+ }
+ // belt and braces, do the attribute even on Java 5 in addition to the modifier flag
+ ConstantPoolGen cpg = gen.getConstantPool();
+ int index = cpg.addUtf8("Synthetic");
+ gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg.getConstantPool()));
}
if (hasBody()) {
return gen;
}
- public void makeSynthetic() {
+ private void forceSyntheticForAjcMagicMembers() {
+ if (NameMangler.isSyntheticMethod(getName(), inAspect())) {
+ makeSynthetic();
+ }
+ }
+
+ private boolean inAspect() {
+ BcelObjectType objectType = enclosingClass.getBcelObjectType();
+ return (objectType == null ? false : objectType.isAspect());
+ }
+
+ public void makeSynthetic() {
isSynthetic = true;
}
public class HelloWorld extends java.lang.Object:
- private static final org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_0
- private static final org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_1
+ private static final org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_0 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$EnclosingStaticPart ajc$tjp_1 [Synthetic]
public void <init>():
- ALOAD_0 // HelloWorld this (line 5)
+ ALOAD_0 // LHelloWorld; this (line 5)
INVOKESPECIAL java.lang.Object.<init> ()V
constructor-execution(void HelloWorld.<init>())
| GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;
public class HelloWorld extends java.lang.Object:
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic]
public void <init>():
- ALOAD_0 // HelloWorld this (line 5)
+ ALOAD_0 // LHelloWorld; this (line 5)
INVOKESPECIAL java.lang.Object.<init> ()V
constructor-execution(void HelloWorld.<init>())
| GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart;
public class HelloWorld extends java.lang.Object:
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic]
public void <init>():
- ALOAD_0 // HelloWorld this (line 5)
+ ALOAD_0 // LHelloWorld; this (line 5)
INVOKESPECIAL java.lang.Object.<init> ()V
GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart;
ALOAD_0
public class HelloWorld extends java.lang.Object:
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic]
public void <init>():
- ALOAD_0 // HelloWorld this (line 5)
+ ALOAD_0 // LHelloWorld; this (line 5)
INVOKESPECIAL java.lang.Object.<init> ()V
GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart;
ALOAD_0
public class HelloWorld extends java.lang.Object:
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2
- private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_0 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_1 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_2 [Synthetic]
+ private static final org.aspectj.lang.JoinPoint$StaticPart ajc$tjp_3 [Synthetic]
public void <init>():
- ALOAD_0 // HelloWorld this (line 5)
+ ALOAD_0 // LHelloWorld; this (line 5)
INVOKESPECIAL java.lang.Object.<init> ()V
GETSTATIC HelloWorld.ajc$tjp_0 Lorg/aspectj/lang/JoinPoint$StaticPart;
ALOAD_0