*/
protected void process(CompilationUnitDeclaration unit, int i) {
EclipseFactory world =
- EclipseFactory.forLookupEnvironment(lookupEnvironment);
+ EclipseFactory.fromLookupEnvironment(lookupEnvironment);
world.showMessage(IMessage.INFO, "compiling " + new String(unit.getFileName()), null, null);
super.process(unit, i);
package org.aspectj.ajdt.internal.compiler.ast;
-import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger;
-import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
-import org.aspectj.ajdt.internal.compiler.lookup.InterTypeScope;
-import org.aspectj.weaver.AjAttribute;
-import org.aspectj.weaver.AjcMemberMaker;
-import org.aspectj.weaver.CrosscuttingMembers;
-import org.aspectj.weaver.Member;
-import org.aspectj.weaver.NameMangler;
-import org.aspectj.weaver.NewConstructorTypeMunger;
-import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.Shadow;
-import org.aspectj.weaver.TypeX;
+import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.weaver.*;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
-import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
-import org.eclipse.jdt.internal.compiler.ast.CastExpression;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
-import org.eclipse.jdt.internal.compiler.ast.Expression;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
-import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
-import org.eclipse.jdt.internal.compiler.ast.Statement;
-import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.Parser;
-
+/**
+ * An inter-type constructor declaration.
+ *
+ * This will generate two implementation methods in the aspect, the main one for the body
+ * of the constructor, and an additional <code>preMethod</code> for the code that
+ * runs before the super constructor is called.
+ *
+ * @author Jim Hugunin
+ */
public class InterTypeConstructorDeclaration extends InterTypeDeclaration {
private MethodDeclaration preMethod;
private ExplicitConstructorCall explicitConstructorCall = null;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.util.CharOperation;
+/**
+ * Base type for all inter-type declarations including methods, fields and constructors.
+ *
+ * @author Jim Hugunin
+ */
public abstract class InterTypeDeclaration extends MethodDeclaration {
- //public AstNode myDeclaration;
public TypeReference onType;
protected ReferenceBinding onTypeBinding;
protected int declaredModifiers;
protected char[] declaredSelector;
- //protected Set superMethodsCalled;
-
public InterTypeDeclaration(CompilationResult result, TypeReference onType) {
super(result);
this.onType = onType;
ClassScope newParent = new InterTypeScope(upperScope, onTypeBinding);
- //interBinding.introducedField.declaringClass);
scope.parent = newParent;
this.scope.isStatic = Modifier.isStatic(declaredModifiers);
super.resolve(newParent);
SuperFixerVisitor v = new SuperFixerVisitor(this, onTypeBinding);
this.traverse(v, (ClassScope)null);
munger.setSuperMethodsCalled(v.superMethodsCalled);
-// HashSet set = new HashSet();
-// for (Iterator i = v.superMethodsCalled.iterator(); i.hasNext(); ) {
-// MethodBinding b = (MethodBinding)i.next();
-// set.add(EclipseWorld.makeResolvedMember(b));
-// }
-//
-// munger.setSuperMethodsCalled(set);
}
protected void resolveOnType(ClassScope classScope) {
checkSpec();
onTypeBinding = (ReferenceBinding)onType.getTypeBinding(classScope);
if (!onTypeBinding.isValidBinding()) {
- if (onTypeBinding instanceof ProblemReferenceBinding) {
- classScope.problemReporter().invalidType(onType, onTypeBinding);
- } else {
- //XXX trouble
- }
+ classScope.problemReporter().invalidType(onType, onTypeBinding);
ignoreFurtherInvestigation = true;
}
- //??? this is not a friendly compiler limitation
-// if (!(onTypeBinding instanceof SourceTypeBinding)) {
-// classScope.problemReporter().signalError(onType.sourceStart, onType.sourceEnd,
-// "can only introduce on types available as source code (compiler limitation)");
-// ignoreFurtherInvestigation = true;
-// }
}
}
protected int generateInfoAttributes(ClassFile classFile) {
- //munger.getSignature().setPosition(sourceStart, sourceEnd);
-
- //System.out.println("generating effective for " + this);
List l;;
Shadow.Kind kind = getShadowKindForBody();
if (kind != null) {
l = makeEffectiveSignatureAttribute(munger.getSignature(), kind, true);
} else {
- l = new ArrayList(0); //AstUtil.getAjSyntheticAttribute();
+ l = new ArrayList(0);
}
return classFile.generateMethodInfoAttribute(binding, l);
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.Parser;
+
/**
+ * An inter-type field declaration.
+ *
* returnType encodes the type of the field
* selector encodes the name
+ * statements is null until resolution when it is filled in from the initializer
+ *
+ * @author Jim Hugunin
*/
public class InterTypeFieldDeclaration extends InterTypeDeclaration {
public Expression initialization;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.Parser;
-
+/**
+ * An inter-type method declaration.
+ *
+ * @author Jim Hugunin
+ */
public class InterTypeMethodDeclaration extends InterTypeDeclaration {
public InterTypeMethodDeclaration(CompilationResult result, TypeReference onType) {
super(result, onType);
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-
+/**
+ * Used to represent any method call to a method named <code>proceed</code>. During
+ * <code>resolvedType</code> it will be determined if this is actually in the body
+ * of an <code>around</code> advice and if not this will be treated like any other
+ * MessageSend.
+ *
+ * @author Jim Hugunin
+ */
public class Proceed extends MessageSend {
public boolean inInner = false;
public TypeBinding resolveType(BlockScope scope) {
// find out if I'm really in an around body or not
- //??? there is a small performance issue here
+ //??? this could in theory be done by the parser, but that appears to be hard
AdviceDeclaration aroundDecl = findEnclosingAround(scope);
if (aroundDecl == null) {
return super.resolveType(scope);
}
-
-
constant = NotAConstant;
binding = codegenBinding = aroundDecl.proceedMethodBinding;
return findEnclosingAround(scope.parent);
}
-
-
-
}
package org.aspectj.ajdt.internal.compiler.lookup;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
import org.aspectj.bridge.IMessage;
-import org.aspectj.bridge.MessageUtil;
-import org.aspectj.weaver.ResolvedTypeX;
-import org.aspectj.weaver.TypeX;
-import org.aspectj.weaver.patterns.DeclareParents;
-import org.aspectj.weaver.patterns.TypePattern;
-import org.aspectj.weaver.patterns.TypePatternList;
+import org.aspectj.weaver.*;
+import org.aspectj.weaver.bcel.BcelTypeMunger;
+import org.aspectj.weaver.patterns.*;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
-import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+/**
+ * Overrides the default eclipse LookupEnvironment for two purposes.
+ *
+ * 1. To provide some additional phases to <code>completeTypeBindings</code>
+ * that weave declare parents and inter-type declarations at the correct time.
+ *
+ * 2. To intercept the loading of new binary types to ensure the they will have
+ * declare parents and inter-type declarations woven when appropriate.
+ *
+ * @author Jim Hugunin
+ */
public class AjLookupEnvironment extends LookupEnvironment {
public EclipseFactory factory = null;
- private boolean builtInterTypesAndPerClauses = false;
+// private boolean builtInterTypesAndPerClauses = false;
private List pendingTypesToWeave = new ArrayList();
public AjLookupEnvironment(
//??? duplicates some of super's code
public void completeTypeBindings() {
- builtInterTypesAndPerClauses = false;
+// builtInterTypesAndPerClauses = false;
//pendingTypesToWeave = new ArrayList();
stepCompleted = BUILD_TYPE_HIERARCHY;
}
}
-
-
// need to build inter-type declarations for all AspectDeclarations at this point
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
SourceTypeBinding[] b = units[i].scope.topLevelTypes;
buildInterTypeAndPerClause(b[j].scope);
}
}
- builtInterTypesAndPerClauses = true;
- doPendingWeaves();
+ factory.finishTypeMungers();
// now do weaving
Collection typeMungers = factory.getTypeMungers();
- //System.out.println("typeMungers: " + typeMungers);
Collection declareParents = factory.getDeclareParents();
+
+ doPendingWeaves();
+
for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents);
units[i] = null; // release unnecessary reference to the parsed unit
buildInterTypeAndPerClause(((SourceTypeBinding) memberTypes[i]).scope);
}
}
-
-
-
private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, Collection declareParents) {
- for (int i = 0, length = unit.topLevelTypes.length; i < length; i++)
- weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents);
-
- //System.err.println("done with inter types");
+ for (int i = 0, length = unit.topLevelTypes.length; i < length; i++) {
+ weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents, false);
+ }
}
-
private void weaveInterTypeDeclarations(SourceTypeBinding sourceType) {
- if (!builtInterTypesAndPerClauses) {
- pendingTypesToWeave.add(sourceType);
+ if (!factory.areTypeMungersFinished()) {
+ if (!pendingTypesToWeave.contains(sourceType)) pendingTypesToWeave.add(sourceType);
} else {
- //System.err.println("weaving: " + new String(sourceType.sourceName()) + ", " + world.getTypeMungers());
- weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents());
+ weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents(), true);
}
}
- private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents) {
+
+ private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents, boolean skipInners) {
ResolvedTypeX onType = factory.fromEclipse(sourceType);
onType.clearInterTypeMungers();
}
for (Iterator i = typeMungers.iterator(); i.hasNext();) {
- Object o = i.next();
- if (o instanceof EclipseTypeMunger) {
- EclipseTypeMunger munger = (EclipseTypeMunger) o;
- if (munger.matches(onType)) {
- onType.addInterTypeMunger(munger);
- }
- } else {
- //FIXME this needs to handle some binary form type mungers for aspect libs
- //???System.out.println("skipping: " + o);
+ EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
+ if (munger.matches(onType)) {
+ onType.addInterTypeMunger(munger);
}
}
for (Iterator i = onType.getInterTypeMungers().iterator(); i.hasNext();) {
EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
+ //System.err.println("applying: " + munger + " to " + new String(sourceType.sourceName));
munger.munge(sourceType);
}
-
+ if (skipInners) return;
ReferenceBinding[] memberTypes = sourceType.memberTypes;
for (int i = 0, length = memberTypes.length; i < length; i++) {
if (memberTypes[i] instanceof SourceTypeBinding) {
- weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents);
+ weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents, false);
}
}
}
}
private void addParent(DeclareParents declareParents, SourceTypeBinding sourceType, TypePattern typePattern) {
- //if (!typePattern.assertExactType(world.getMessageHandler())) return;
if (typePattern == TypePattern.NO) return; // already had an error here
TypeX iType = typePattern.getExactType();
-// if (iType == null) {
-// throw new RuntimeException("yikes: " + typePattern);
-// }
- //if (iType == ResolvedTypeX.MISSING || iType == null) return;
ReferenceBinding b = (ReferenceBinding)factory.makeTypeBinding(iType); //"
if (b.isClass()) {
//XXX currently unused
private Map/*TypeBinding, ResolvedTypeX*/ bindingToResolvedTypeX = new HashMap();
- public static EclipseFactory forLookupEnvironment(LookupEnvironment env) {
+ public static EclipseFactory fromLookupEnvironment(LookupEnvironment env) {
AjLookupEnvironment aenv = (AjLookupEnvironment)env;
return aenv.factory;
}
public static EclipseFactory fromScopeLookupEnvironment(Scope scope) {
- return forLookupEnvironment(AstUtil.getCompilationUnitScope(scope).environment);
+ return fromLookupEnvironment(AstUtil.getCompilationUnitScope(scope).environment);
}
getWorld().showMessage(kind, message, loc1, loc2);
}
-
-// public Advice concreteAdvice(
-// AjAttribute.AdviceAttribute attribute,
-// Pointcut pointcut,
-// Member signature)
-// {
-// return new EclipseAdvice(attribute, pointcut, signature);
-// }
-//
-// public ConcreteTypeMunger concreteTypeMunger(
-// ResolvedTypeMunger munger, ResolvedTypeX aspectType)
-// {
-// return null;
-// }
-
-// protected ResolvedTypeX.ConcreteName resolveObjectType(ResolvedTypeX.Name typeX) {
-// TypeBinding binding = makeTypeBinding(typeX);
-//
-//// System.err.println("resolvedObjectType: " + typeX +
-//// " found " +
-//// (binding == null ? "null" : binding.getClass().getName()));
-//
-// if (!(binding instanceof SourceTypeBinding)) {
-// //System.err.println("missing: " + binding);
-// return null;
-// }
-//
-//// if (binding instanceof BinaryTypeBinding) {
-//// //System.err.println("binary: " + typeX);
-//// return new EclipseBinaryType(
-//// buildManager.bcelWorld.resolve(typeX),
-//// this,
-//// (BinaryTypeBinding)binding);
-//// }
-//
-// return new EclipseSourceType(typeX, this,(SourceTypeBinding)binding);
-// }
-//
- public EclipseSourceType lookupConcreteName(SourceTypeBinding b) {
- throw new RuntimeException("unimplemented");
- }
-
-
-
public ResolvedTypeX fromEclipse(ReferenceBinding binding) {
if (binding == null) return ResolvedTypeX.MISSING;
//??? this seems terribly inefficient
public Collection getDeclareParents() {
return getWorld().getDeclareParents();
}
+
+ public Collection finishedTypeMungers = null;
+
+ public boolean areTypeMungersFinished() {
+ return finishedTypeMungers != null;
+ }
+
+ public void finishTypeMungers() {
+ // make sure that type mungers are
+ finishedTypeMungers = new ArrayList();
+ Collection baseTypeMungers =
+ getWorld().getCrosscuttingMembersSet().getTypeMungers();
+ for (Iterator i = baseTypeMungers.iterator(); i.hasNext(); ) {
+ ConcreteTypeMunger munger = (ConcreteTypeMunger) i.next();
+ EclipseTypeMunger etm = makeEclipseTypeMunger(munger);
+ if (etm != null) finishedTypeMungers.add(etm);
+ }
+ }
+
+ public EclipseTypeMunger makeEclipseTypeMunger(ConcreteTypeMunger concrete) {
+ if (concrete instanceof EclipseTypeMunger) return (EclipseTypeMunger)concrete;
+ if (EclipseTypeMunger.supportsKind(concrete.getMunger().getKind())) {
+ return new EclipseTypeMunger(this, concrete.getMunger(), concrete.getAspectType(), null);
+ } else {
+ return null;
+ }
+ }
public Collection getTypeMungers() {
- //XXX almost certainly the wrong types
- return getWorld().getCrosscuttingMembersSet().getTypeMungers();
+ //??? assert finishedTypeMungers != null
+ return finishedTypeMungers;
}
public static ResolvedMember makeResolvedMember(MethodBinding binding) {
+ //System.err.println("member for: " + binding + ", " + new String(binding.declaringClass.sourceName));
ResolvedMember ret = new ResolvedMember(
binding.isConstructor() ? Member.CONSTRUCTOR : Member.METHOD,
fromBinding(binding.declaringClass),
import java.util.*;
-import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
-import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
+import org.aspectj.ajdt.internal.compiler.ast.*;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.*;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.*;
+/**
+ * Supports viewing eclipse TypeDeclarations/SourceTypeBindings as a ResolvedTypeX
+ *
+ * @author Jim Hugunin
+ */
public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
protected ResolvedPointcutDefinition[] declaredPointcuts = null;
protected ResolvedMember[] declaredMethods = null;
List declaredMethods = new ArrayList();
List declaredFields = new ArrayList();
- MethodBinding[] methods = binding.methods();
- for (int i=0, len=methods.length; i < len; i++) {
- MethodBinding m = methods[i];
- AbstractMethodDeclaration amd = m.sourceMethod();
- if (amd == null) continue; //???
- if (amd instanceof PointcutDeclaration) {
- PointcutDeclaration d = (PointcutDeclaration)amd;
- ResolvedPointcutDefinition df = d.makeResolvedPointcutDefinition();
- declaredPointcuts.add(df);
- } else {
- //XXX this doesn't handle advice quite right
- declaredMethods.add(eclipseWorld().makeResolvedMember(m));
+ binding.methods(); // the important side-effect of this call is to make sure bindings are completed
+ AbstractMethodDeclaration[] methods = declaration.methods;
+ if (methods != null) {
+ for (int i=0, len=methods.length; i < len; i++) {
+ AbstractMethodDeclaration amd = methods[i];
+ if (amd == null || amd.ignoreFurtherInvestigation) continue;
+ if (amd instanceof PointcutDeclaration) {
+ PointcutDeclaration d = (PointcutDeclaration)amd;
+ ResolvedPointcutDefinition df = d.makeResolvedPointcutDefinition();
+ declaredPointcuts.add(df);
+ } else if (amd instanceof InterTypeDeclaration) {
+ // these are handled in a separate pass
+ continue;
+ } else if (amd instanceof DeclareDeclaration) {
+ // these are handled in a separate pass
+ continue;
+ } else if (amd instanceof AdviceDeclaration) {
+ // these are ignored during compilation and only used during weaving
+ continue;
+ } else {
+ if (amd.binding == null || !amd.binding.isValidBinding()) continue;
+ declaredMethods.add(eclipseWorld().makeResolvedMember(amd.binding));
+ }
}
}
-
+
FieldBinding[] fields = binding.fields();
for (int i=0, len=fields.length; i < len; i++) {
FieldBinding f = fields[i];
super(munger, aspectType);
this.world = world;
this.sourceMethod = sourceMethod;
+ TypeX targetTypeX = munger.getSignature().getDeclaringType();
+ targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX);
+ }
+
+ public static boolean supportsKind(ResolvedTypeMunger.Kind kind) {
+ return kind == ResolvedTypeMunger.Field
+ || kind == ResolvedTypeMunger.Method
+ || kind == ResolvedTypeMunger.Constructor;
}
public String toString() {
return "(EclipseTypeMunger " + getMunger() + ")";
}
- private boolean match(SourceTypeBinding sourceType) {
- if (targetBinding == null) {
- TypeX targetTypeX = munger.getSignature().getDeclaringType();
- targetBinding = (ReferenceBinding)world.makeTypeBinding(targetTypeX);
- }
- //??? assumes instance uniqueness for ReferenceBindings
- return targetBinding == sourceType;
-
- }
-
/**
* Modifies signatures of a TypeBinding through its ClassScope,
* i.e. adds Method|FieldBindings, plays with inheritance, ...
*/
public boolean munge(SourceTypeBinding sourceType) {
- if (!match(sourceType)) return false;
-
+ if (sourceType != targetBinding) return false; //??? move this test elsewhere
if (munger.getKind() == ResolvedTypeMunger.Field) {
mungeNewField(sourceType, (NewFieldTypeMunger)munger);
} else if (munger.getKind() == ResolvedTypeMunger.Method) {
} else if (munger.getKind() == ResolvedTypeMunger.Constructor) {
mungeNewConstructor(sourceType, (NewConstructorTypeMunger)munger);
} else {
- throw new RuntimeException("unimplemented");
+ throw new RuntimeException("unimplemented: " + munger.getKind());
}
return true;
}
}
public boolean canBeSeenBy(TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
+ //System.err.println("canBeSeenBy: " + this + ", " + isPublic());
if (isPublic()) return true;
SourceTypeBinding invocationType = scope.invocationType();
public void addInterTypeField(FieldBinding binding) {
+ //System.err.println("adding: " + binding + " to " + this);
interTypeFields.add(binding);
}
return;
}
+ if (CharOperation.startsWith(abstractMethod.selector, "ajc$interField".toCharArray())) {
+ //??? think through how this could go wrong
+ return;
+ }
+
// if we implemented this method by an inter-type declaration, then there is no error
//??? be sure this is always right
--- /dev/null
+package client;
+
+import lib.ConcreteA;
+import org.aspectj.lang.*;
+
+public class Client {
+ public static void main(String[] args) {
+ C c = new C();
+ System.out.println(c.value);
+ ConcreteA.Marker m = c;
+ System.out.println(m.value);
+ try {
+ new Client();
+ } catch (SoftException se) {
+ System.out.println("se: " + se);
+ }
+ }
+
+
+ public Client() {
+ foo();
+ }
+
+ private void foo() throws ConcreteA.MyException {
+ throw new ConcreteA.MyException();
+ }
+}
+
+class C implements ConcreteA.Marker { }
\ No newline at end of file
--- /dev/null
+package lib;\r
+\r
+public aspect ConcreteA {\r
+ public interface Marker {}\r
+ \r
+ public String Marker.value = "public";\r
+ //private String Marker.pValue = "private";\r
+\r
+ public static class MyException extends Exception {}\r
+\r
+ declare soft: MyException: withincode(new(..));\r
+}
\ No newline at end of file
package org.aspectj.ajdt.internal.compiler.batch;
import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.testing.util.TestUtil;
public class BinaryFormsTestCase extends CommandTestCase {
super(name);
}
- public void testDummy() {}
+
+ public void testJar1() throws IOException {
+ List args = new ArrayList();
+ args.add("-outjar");
+ args.add("out/lib.jar");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("-d");
+ args.add("out");
+
+ args.add("testdata/src1/binary/lib/ConcreteA.aj");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+ args = new ArrayList();
+ args.add("-aspectpath");
+ args.add("out/lib.jar");
+
+ args.add("-classpath");
+ args.add("../runtime/bin");
+
+ args.add("-d");
+ args.add("out");
+
+ args.add("testdata/src1/binary/client/Client.java");
+
+ CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+ TestUtil.runMain("out;out/lib.jar", "client.Client");
+ }
public void XXXtestJar1() throws IOException {
ret = {}\r
for e in errors:\r
loc = e.getISourceLocation()\r
+ if loc is None: continue #???\r
s = "%s:%i" % (loc.sourceFile.name[:-5], loc.line)\r
ret[s] = s\r
return ret.keys()\r
// start by munging all typeMungers
for (Iterator i = typeMungers.iterator(); i.hasNext(); ) {
- BcelTypeMunger munger = (BcelTypeMunger)i.next();
+ Object o = i.next();
+ if ( !(o instanceof BcelTypeMunger) ) {
+ System.err.println("surprising: " + o);
+ continue;
+ }
+ BcelTypeMunger munger = (BcelTypeMunger)o;
isChanged |= munger.munge(this);
}