--- /dev/null
+call ajc -outjar fullBase.jar sample\Base.java sample\Derived.java sample\Iface.java\r
+jar xf fullBase.jar\r
+jar cf base.jar sample\Derived.class sample\Iface.class\r
+set XCLASSPATH=%CLASSPATH%\r
+set CLASSPATH=fullBase.jar;%CLASSPATH%\r
+call ajc -injars base.jar -outjar woven.jar sample\Trace.aj\r
+java -classpath woven.jar;%CLASSPATH% sample.Derived\r
+set CLASSPATH=%XCLASSPATH%\r
--- /dev/null
+package sample;
+
+public abstract class Base implements Iface {
+ int x;
+ Base() {
+ x=1;
+ }
+ abstract void foo();
+}
--- /dev/null
+package sample;
+
+public class Derived extends Base {
+ int y;
+ public Derived() {
+ super();
+ y = 2;
+ }
+
+ public void foo() {}
+
+ public static void main(String args[]) {
+ new Derived();
+ }
+}
--- /dev/null
+package sample;
+
+public interface Iface {
+}
--- /dev/null
+package sample;\r
+\r
+import java.util.logging.Logger;\r
+\r
+public aspect Trace {\r
+ public interface Traced {}\r
+ declare parents: (sample.* && !Trace) extends Traced;\r
+\r
+// private Logger Traced.logger;\r
+ before(Traced current) : \r
+ execution(Traced+.new(..)) && !execution(Traced.new()) && this(current) {\r
+ current.getLogger().severe("entering ctor for "+thisJoinPoint);\r
+ }\r
+\r
+ public Logger Traced.getLogger() {\r
+ // if (logger == null) {\r
+// logger = Logger.getLogger(getClass().toString());\r
+ // }\r
+// return logger;\r
+return null;\r
+ }\r
+}\r
suite.addTestSuite(ImageTestCase.class);
suite.addTestSuite(MultipleCompileTestCase.class);
suite.addTestSuite(JavadocTest.class);
+ suite.addTestSuite(PartiallyExposedHierarchyTestCase.class);
// XXX suite.addTestSuite(VerifyWeaveTestCase.class);
//suite.addTestSuite(WorkingCommandTestCase.class);
//$JUnit-END$
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Matthew Webster - initial implementation
+ *******************************************************************************/
+package org.aspectj.ajdt.internal.compiler.batch;
+
+import java.io.File;
+
+import org.aspectj.tools.ajc.AjcTestCase;
+import org.aspectj.tools.ajc.CompilationResult;
+
+/**
+ * If you need to rebuild the components for this test, I'm afraid you will have
+ * to run build.cmd in the testdata/partialHierarchy directory which calls ajc and
+ * does some jar manipulation.
+ */
+public class PartiallyExposedHierarchyTestCase extends AjcTestCase {
+
+ public static final String PROJECT_DIR = "partialHierarchy";
+
+ private File baseDir;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ baseDir = new File("../org.aspectj.ajdt.core/testdata",PROJECT_DIR);
+ }
+
+ /**
+ * This test verifies that AspectJ behaves correctly when parts of an object
+ * hierarchy are exposed to it for weaving. See pr49657 for all the details.
+ */
+ public void testPartiallyExposedHierarchy () {
+ Message warning = new Message(11,"no interface constructor-execution join point");
+ //TODO This line number will change to 15 (from 5) when type mungers remember where they came from!
+ Message error = new Message(5, "type sample.Base must be accessible for weaving interface inter type declaration from aspect sample.Trace");
+ CompilationResult result = ajc(baseDir,
+ new String[]{"-classpath","fullBase.jar",
+ "-injars","base.jar",
+ "sample"+File.separator+"Trace.aj"});
+// System.err.println(result.getWarningMessages());
+// System.err.println(result.getErrorMessages());
+// System.err.println(result.getStandardOutput());
+ MessageSpec spec = new MessageSpec(null,newMessageList(warning),newMessageList(error));
+ assertMessages(result,spec);
+ }
+
+
+}
return true;
}
+ public ResolvedTypeX getTopmostImplementor(ResolvedTypeX interfaceType) {
+ if (isInterface()) return null;
+ if (!interfaceType.isAssignableFrom(this)) return null;
+ // Check if my super class is an implementor?
+ ResolvedTypeX higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
+ if (higherType!=null) return higherType;
+ return this;
+ }
+
+ private ResolvedTypeX findHigher(ResolvedTypeX other) {
+ if (this == other) return this;
+ for(Iterator i = other.getDirectSupertypes(); i.hasNext(); ) {
+ ResolvedTypeX rtx = (ResolvedTypeX)i.next();
+ boolean b = this.isAssignableFrom(rtx);
+ if (b) return rtx;
+ }
+ return null;
+ }
+
public List getExposedPointcuts() {
List ret = new ArrayList();
if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
public static final String ITD_OVERIDDING_STATIC = "overridingStatic";
public static final String ITD_CONFLICT = "itdConflict";
public static final String ITD_MEMBER_CONFLICT = "itdMemberConflict";
+ public static final String ITD_NON_EXPOSED_IMPLEMENTOR = "itdNonExposedImplementor";
public static final String NON_VOID_RETURN = "nonVoidReturn";
import org.aspectj.apache.bcel.generic.InstructionList;
import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.MessageUtil;
import org.aspectj.bridge.WeaveMessage;
import org.aspectj.weaver.AjcMemberMaker;
import org.aspectj.weaver.AsmRelationshipProvider;
import org.aspectj.weaver.ResolvedTypeMunger;
import org.aspectj.weaver.ResolvedTypeX;
import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.patterns.Pointcut;
addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
return true;
- } else if (onInterface && gen.getType().isTopmostImplementor(onType) &&
- !Modifier.isAbstract(signature.getModifiers()))
- {
- ResolvedMember introMethod =
+
+ } else if (onInterface && !Modifier.isAbstract(signature.getModifiers())) {
+
+ // This means the 'gen' should be the top most implementor
+ // - if it is *not* then something went wrong after we worked
+ // out that it was the top most implementor (see pr49657)
+ if (!gen.getType().isTopmostImplementor(onType)) {
+ ResolvedTypeX rtx = gen.getType().getTopmostImplementor(onType);
+ if (!rtx.isExposedToWeaver()) {
+ ISourceLocation sLoc = munger.getSourceLocation();
+ weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error(
+ WeaverMessages.format(WeaverMessages.ITD_NON_EXPOSED_IMPLEMENTOR,rtx,getAspectType().getName()),
+ (sLoc==null?getAspectType().getSourceLocation():sLoc)));
+ } else {
+ // XXX what does this state mean?
+ // We have incorrectly identified what is the top most implementor and its not because
+ // a type wasn't exposed to the weaver
+ }
+ return false;
+ } else {
+
+ ResolvedMember introMethod =
AjcMemberMaker.interMethod(signature, aspectType, false);
- LazyMethodGen mg = makeMethodGen(gen, introMethod);
+ LazyMethodGen mg = makeMethodGen(gen, introMethod);
- Type[] paramTypes = BcelWorld.makeBcelTypes(introMethod.getParameterTypes());
- Type returnType = BcelWorld.makeBcelType(introMethod.getReturnType());
+ Type[] paramTypes = BcelWorld.makeBcelTypes(introMethod.getParameterTypes());
+ Type returnType = BcelWorld.makeBcelType(introMethod.getReturnType());
- InstructionList body = mg.getBody();
- InstructionFactory fact = gen.getFactory();
- int pos = 0;
+ InstructionList body = mg.getBody();
+ InstructionFactory fact = gen.getFactory();
+ int pos = 0;
- if (!introMethod.isStatic()) {
+ if (!introMethod.isStatic()) {
body.append(InstructionFactory.createThis());
pos++;
- }
- for (int i = 0, len = paramTypes.length; i < len; i++) {
+ }
+ for (int i = 0, len = paramTypes.length; i < len; i++) {
Type paramType = paramTypes[i];
body.append(InstructionFactory.createLoad(paramType, pos));
pos+=paramType.getSize();
- }
- body.append(Utility.createInvoke(fact, weaver.getWorld(), dispatchMethod));
- body.append(InstructionFactory.createReturn(returnType));
- mg.definingType = onType;
+ }
+ body.append(Utility.createInvoke(fact, weaver.getWorld(), dispatchMethod));
+ body.append(InstructionFactory.createReturn(returnType));
+ mg.definingType = onType;
- weaver.addOrReplaceLazyMethodGen(mg);
+ weaver.addOrReplaceLazyMethodGen(mg);
- addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
+ addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled());
- return true;
+ return true;
+ }
} else {
return false;
}
overridingStatic={0} cannot override {1}; overriding method is static
itdConflict=intertype declaration from {0} conflicts with intertype declaration: {1} from {2}
itdMemberConflict=inter-type declaration from {0} conflicts with existing member: {1}
+itdNonExposedImplementor=type {0} must be accessible for weaving interface inter type declaration from aspect {1}
# advice messages...
nonVoidReturn=applying to join point that doesn't return void: {0}