From: aclement Date: Wed, 22 Feb 2006 15:26:26 +0000 (+0000) Subject: optimizationasm: various tweaks!! See optimization #7 in 128650 X-Git-Tag: POST_MEMORY_CHANGES~32 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1cd7b3c6614995f8a38823a63fe4e16fddad86be;p=aspectj.git optimizationasm: various tweaks!! See optimization #7 in 128650 --- diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java index 3a3a24605..3b4197752 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/AjCompilerAdapter.java @@ -176,6 +176,7 @@ public class AjCompilerAdapter implements ICompilerAdapter { notifyRequestor(); } else { weave(); // notification happens as weave progresses... + weaver.getWorld().flush(); } } catch (IOException ex) { AbortCompilation ac = new AbortCompilation(null,ex); @@ -306,6 +307,7 @@ public class AjCompilerAdapter implements ICompilerAdapter { } finally { // ???: is this the right point for this? After weaving has finished clear the caches. CflowPointcut.clearCaches(); + weaver.tidyUp(); } } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java index 93ed90c07..41c4e24fb 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java @@ -81,6 +81,7 @@ public class EclipseFactory { private LookupEnvironment lookupEnvironment; private boolean xSerializableAspects; private World world; + public Collection finishedTypeMungers = null; // We can get clashes if we don't treat raw types differently - we end up looking // up a raw and getting the generic type (pr115788) @@ -397,7 +398,6 @@ public class EclipseFactory { return getWorld().getDeclareAnnotationOnMethods(); } - public Collection finishedTypeMungers = null; public boolean areTypeMungersFinished() { return finishedTypeMungers != null; @@ -987,7 +987,6 @@ public class EclipseFactory { } name.setGenericType(complexName); complexName.setDelegate(t); - complexName.setSourceContext(t.getResolvedTypeX().getSourceContext()); } name.setDelegate(t); @@ -1024,5 +1023,6 @@ public class EclipseFactory { public void cleanup() { this.typexToBinding.clear(); this.rawTypeXToBinding.clear(); + this.finishedTypeMungers = null; } } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java index 81491116d..3f2aab4e9 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java @@ -97,7 +97,7 @@ public class EclipseSourceType extends AbstractReferenceTypeDelegate { this.declaration = declaration; this.unit = unit; - resolvedTypeX.setSourceContext(new EclipseSourceContext(declaration.compilationResult)); + setSourceContext(new EclipseSourceContext(declaration.compilationResult)); resolvedTypeX.setStartPos(declaration.sourceStart); resolvedTypeX.setEndPos(declaration.sourceEnd); } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java index 526086446..1ef198bf2 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildManager.java @@ -108,7 +108,7 @@ public class AjBuildManager implements IOutputClassFileNameProvider,IBinarySourc * that there is only one builder present, so if two extendsion reset it, only * the latter will get used. */ - private static AsmHierarchyBuilder asmHierarchyBuilder = new AsmHierarchyBuilder(); + public static AsmHierarchyBuilder asmHierarchyBuilder = new AsmHierarchyBuilder(); static { CompilationAndWeavingContext.registerFormatter( diff --git a/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java b/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java index 8431da469..56b335cdc 100644 --- a/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java +++ b/weaver/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java @@ -12,9 +12,24 @@ * ******************************************************************/ package org.aspectj.weaver; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.weaver.patterns.Declare; + public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDelegate { + + public final static String UNKNOWN_SOURCE_FILE = ""; // Just randomly picked, happens to match BCEL javaclass default + + private String sourcefilename = UNKNOWN_SOURCE_FILE; // Sourcefilename is stored only here protected boolean exposedToWeaver; protected ReferenceType resolvedTypeX; + private ISourceContext sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT; public AbstractReferenceTypeDelegate(ReferenceType resolvedTypeX, boolean exposedToWeaver) { this.resolvedTypeX = resolvedTypeX; @@ -24,6 +39,8 @@ public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDele public final boolean isClass() { return !isAspect() && !isInterface(); } + + /** * Designed to be overriden by EclipseType to disable collection of shadow mungers @@ -40,5 +57,216 @@ public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDele public ReferenceType getResolvedTypeX() { return resolvedTypeX; } + + /** + * Create the string representation for a delegate, allowing us to + * more easily compare delegate implementations. + */ + public String stringifyDelegate() { + + StringBuffer result = new StringBuffer(); + result.append("=== Delegate for "+getResolvedTypeX().getName()+"\n"); + + result.append("isAspect?"+isAspect()+"\n"); + result.append("isAnnotationStyleAspect?"+isAnnotationStyleAspect()+"\n"); + result.append("isInterface?"+isInterface()+"\n"); + result.append("isEnum?"+isEnum()+"\n"); + result.append("isClass?"+isClass()+"\n"); + result.append("-\n"); + result.append("isAnnotation?"+isAnnotation()+"\n"); + result.append("retentionPolicy="+getRetentionPolicy()+"\n"); + result.append("canAnnotationTargetType?"+canAnnotationTargetType()+"\n"); + AnnotationTargetKind[] kinds = getAnnotationTargetKinds(); + if (kinds!=null && kinds.length>0) { + result.append("annotationTargetKinds:["); + for (int i = 0; i < kinds.length; i++) { + AnnotationTargetKind kind = kinds[i]; + result.append(kind); + if ((i+1)0) { + result.append("getAnnotations() returns: "+axs.length+" annotations\n"); + for (int i = 0; i < axs.length; i++) { + AnnotationX annotationX = axs[i]; + result.append(" #"+i+") "+annotationX+"\n"); + } + } else { + result.append("getAnnotations() returns nothing\n"); + } + ResolvedType[] axtypes = getAnnotationTypes(); + if (axtypes!=null && axtypes.length>0) { + result.append("getAnnotationTypes() returns: "+axtypes.length+" annotations\n"); + for (int i = 0; i < axtypes.length; i++) { + ResolvedType annotation = axtypes[i]; + result.append(" #"+i+") "+annotation+":"+annotation.getClass()+"\n"); + } + } else { + result.append("getAnnotationTypes() returns nothing\n"); + } + + result.append("isExposedToWeaver?"+isExposedToWeaver()+"\n"); + result.append("getSuperclass?"+getSuperclass()+"\n"); + result.append("getResolvedTypeX?"+getResolvedTypeX()+"\n"); + result.append("--\n"); + + ResolvedMember[] fields = getDeclaredFields(); + if (fields!=null && fields.length>0) { + result.append("The fields: "+fields.length+"\n"); + for (int i = 0; i < fields.length; i++) { + ResolvedMember member = fields[i]; + result.append("f"+i+") "+member.toDebugString()+"\n"); + } + } + ResolvedMember[] methods = getDeclaredMethods(); + if (methods!=null && methods.length>0) { + result.append("The methods: "+methods.length+"\n"); + for (int i = 0; i < methods.length; i++) { + ResolvedMember member = methods[i]; + result.append("m"+i+") "+member.toDebugString()+"\n"); + } + } + ResolvedType[] interfaces = getDeclaredInterfaces(); + if (interfaces!=null && interfaces.length>0) { + result.append("The interfaces: "+interfaces.length+"\n"); + for (int i = 0; i < interfaces.length; i++) { + ResolvedType member = interfaces[i]; + result.append("i"+i+") "+member+"\n"); + } + } + + result.append("getModifiers?"+getModifiers()+"\n"); + + result.append("perclause="+getPerClause()+"\n"); + + result.append("aj:weaverstate="+getWeaverState()+"\n"); + + ResolvedMember[] pointcuts = getDeclaredPointcuts(); + if (pointcuts!=null && pointcuts.length>0) { + result.append("The pointcuts: "+pointcuts.length+"\n"); + + // Sort the damn things + List sortedSetOfPointcuts = new ArrayList(); + for (int i = 0; i < pointcuts.length; i++) {sortedSetOfPointcuts.add(pointcuts[i]);} + Collections.sort(sortedSetOfPointcuts); + + int i =0; + for (Iterator iter = sortedSetOfPointcuts.iterator(); iter.hasNext();) { + ResolvedMember member = (ResolvedMember) iter.next(); + result.append("p"+i+") "+member.toDebugString()+"\n"); + i++; + } + } + + Collection declares = getDeclares(); + if (declares.size()>0) { + result.append("The declares: "+declares.size()+"\n"); + +// // Sort the damn things +// List sortedSetOfPointcuts = new ArrayList(); +// for (int i = 0; i < pointcuts.length; i++) {sortedSetOfPointcuts.add(pointcuts[i]);} +// Collections.sort(sortedSetOfPointcuts); + + int i=0; + for (Iterator iter = declares.iterator(); iter.hasNext();) { + Declare dec = (Declare) iter.next(); + result.append("d"+i+") "+dec.toString()+"\n"); + i++; + } + } + + TypeVariable[] tv = getTypeVariables(); + if (tv!=null && tv.length>0) { + result.append("The type variables: "+tv.length+"\n"); + for (int i = 0; i < tv.length; i++) { + result.append("tv"+i+") "+tv[i]+"\n"); + } + } + + Collection tmungers = getTypeMungers(); + if (tmungers.size()>0) { + List sorted = new ArrayList(); + sorted.addAll(tmungers); + Collections.sort(sorted,new Comparator() { + public int compare(Object arg0, Object arg1) { + return arg0.toString().compareTo(arg1.toString()); + } + }); + result.append("The type mungers: "+tmungers.size()+"\n"); + int i=0; + for (Iterator iter = sorted.iterator(); iter.hasNext();) { + ConcreteTypeMunger mun = (ConcreteTypeMunger) iter.next(); + result.append("tm"+i+") "+mun.toString()+"\n"); + i++; + } + } + + result.append("doesNotExposeShadowMungers?"+doesNotExposeShadowMungers()+"\n"); + + Collection pas = getPrivilegedAccesses(); + if (pas!=null && pas.size()>0) { +// List sorted = new ArrayList(); +// sorted.addAll(tmungers); +// Collections.sort(sorted,new Comparator() { +// public int compare(Object arg0, Object arg1) { +// return arg0.toString().compareTo(arg1.toString()); +// } +// }); + result.append("The privileged accesses: "+pas.size()+"\n"); + int i=0; + for (Iterator iter = pas.iterator(); iter.hasNext();) { + ResolvedMember mun = (ResolvedMember) iter.next(); + result.append("tm"+i+") "+mun.toDebugString()+"\n"); + i++; + } + } + +// public Collection getPrivilegedAccesses(); +// public boolean hasAnnotation(UnresolvedType ofType); + result.append("==="); + return result.toString(); + } + + public final String getSourcefilename() { + return sourcefilename; + } + + public final void setSourcefilename(String sourceFileName) { + this.sourcefilename = sourceFileName; + if (sourceFileName!=null && sourceFileName.equals(AbstractReferenceTypeDelegate.UNKNOWN_SOURCE_FILE)) { + this.sourcefilename = "Type '"+ getResolvedTypeX().getName()+"' (no debug info available)"; + } else { + String pname = getResolvedTypeX().getPackageName(); + if (pname != null) { + this.sourcefilename = pname.replace('.', '/') + '/' + sourceFileName; + } + } + } + + public ISourceLocation getSourceLocation() { + return getSourceContext().makeSourceLocation(0, 0); + } + + public ISourceContext getSourceContext() { + return sourceContext; + } + + public void setSourceContext(ISourceContext isc) { + this.sourceContext = isc; + } + } \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/JoinPointSignature.java b/weaver/src/org/aspectj/weaver/JoinPointSignature.java index f39b70fe7..0b10f7541 100644 --- a/weaver/src/org/aspectj/weaver/JoinPointSignature.java +++ b/weaver/src/org/aspectj/weaver/JoinPointSignature.java @@ -122,6 +122,10 @@ public class JoinPointSignature implements ResolvedMember { public String[] getParameterNames() { return realMember.getParameterNames(); } + + public void setParameterNames(String[] names) { + realMember.setParameterNames(names); + } public String[] getParameterNames(World world) { return realMember.getParameterNames(world); diff --git a/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java b/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java index 265f6f4e0..7bc20794f 100644 --- a/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java +++ b/weaver/src/org/aspectj/weaver/JoinPointSignatureIterator.java @@ -13,6 +13,7 @@ package org.aspectj.weaver; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -32,11 +33,11 @@ public class JoinPointSignatureIterator implements Iterator { ResolvedType firstDefiningType; private World world; private List /*JoinPointSignature*/ discoveredSignatures = new ArrayList(); - private List additionalSignatures = new ArrayList(); + private List additionalSignatures = Collections.EMPTY_LIST; private Iterator discoveredSignaturesIterator = null; private Iterator superTypeIterator = null; private Set visitedSuperTypes = new HashSet(); - private List /*SearchPair*/ yetToBeProcessedSuperMembers = new ArrayList(); + private List /*SearchPair*/ yetToBeProcessedSuperMembers = null;//new ArrayList(); private boolean iteratingOverDiscoveredSignatures = true; private boolean couldBeFurtherAsYetUndiscoveredSignatures = true; @@ -184,14 +185,17 @@ public class JoinPointSignatureIterator implements Iterator { ResolvedType declaringType = (ResolvedType) iter.next(); ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType); discoveredSignatures.add(member); // for next time we are reset + if (additionalSignatures==Collections.EMPTY_LIST) additionalSignatures=new ArrayList(); additionalSignatures.add(member); // for this time } // if this was a parameterized type, look in the generic type that backs it too if (superType.isParameterizedType() && (foundMember.backingGenericMember != null)) { ResolvedMember member =new JoinPointSignature(foundMember.backingGenericMember,foundMember.declaringType.resolve(world)); discoveredSignatures.add(member); // for next time we are reset + if (additionalSignatures==Collections.EMPTY_LIST) additionalSignatures=new ArrayList(); additionalSignatures.add(member); // for this time } + if (yetToBeProcessedSuperMembers==null) yetToBeProcessedSuperMembers=new ArrayList(); yetToBeProcessedSuperMembers.add(new SearchPair(foundMember,superType)); return true; } else { @@ -199,7 +203,7 @@ public class JoinPointSignatureIterator implements Iterator { } } } - if (!yetToBeProcessedSuperMembers.isEmpty()) { + if (yetToBeProcessedSuperMembers!=null && !yetToBeProcessedSuperMembers.isEmpty()) { SearchPair nextUp = (SearchPair) yetToBeProcessedSuperMembers.remove(0); firstDefiningType = nextUp.type; firstDefiningMember = nextUp.member; diff --git a/weaver/src/org/aspectj/weaver/ReferenceType.java b/weaver/src/org/aspectj/weaver/ReferenceType.java index 82d640476..aa0c303e6 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceType.java +++ b/weaver/src/org/aspectj/weaver/ReferenceType.java @@ -48,7 +48,6 @@ public class ReferenceType extends ResolvedType { ReferenceType genericType = null; ReferenceTypeDelegate delegate = null; - ISourceContext sourceContext = null; int startPos = 0; int endPos = 0; @@ -347,12 +346,12 @@ public class ReferenceType extends ResolvedType { } public ISourceContext getSourceContext() { - return sourceContext; + return delegate.getSourceContext(); } public ISourceLocation getSourceLocation() { - if (sourceContext == null) return null; - return sourceContext.makeSourceLocation(new Position(startPos, endPos)); + ISourceContext isc = delegate.getSourceContext(); + return isc.makeSourceLocation(new Position(startPos, endPos)); } public boolean isExposedToWeaver() { @@ -601,8 +600,9 @@ public class ReferenceType extends ResolvedType { } public void setDelegate(ReferenceTypeDelegate delegate) { + if (this.delegate!=null && this.delegate.getSourceContext()!=SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) + ((AbstractReferenceTypeDelegate)delegate).setSourceContext(this.delegate.getSourceContext()); this.delegate = delegate; - for(Iterator it = this.derivativeTypes.iterator(); it.hasNext(); ) { ReferenceType dependent = (ReferenceType) it.next(); dependent.setDelegate(delegate); @@ -638,10 +638,6 @@ public class ReferenceType extends ResolvedType { this.endPos = endPos; } - public void setSourceContext(ISourceContext sourceContext) { - this.sourceContext = sourceContext; - } - public void setStartPos(int startPos) { this.startPos = startPos; } diff --git a/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java b/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java index 101c06e66..f93bde6ff 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java +++ b/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java @@ -61,6 +61,10 @@ public interface ReferenceTypeDelegate { public ReferenceType getResolvedTypeX(); public boolean doesNotExposeShadowMungers(); + public ISourceContext getSourceContext(); + + public String getSourcefilename(); + public String getDeclaredGenericSignature(); } \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java index ec9576417..2c70662ef 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMember.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java @@ -57,6 +57,7 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe public ISourceContext getSourceContext(World world); public String[] getParameterNames(); + public void setParameterNames(String[] names); public String[] getParameterNames(World world); diff --git a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java index 5e3846e1a..16a7dc143 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java @@ -47,10 +47,10 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno // the case. It is up to the caller to work out where that is! // Once determined the caller may choose to stash the annotations in this member... private boolean isAnnotatedElsewhere = false; // this field is not serialized. - private boolean isAjSynthetic = true; + private boolean isAjSynthetic = false; // generic methods have type variables - private TypeVariable[] typeVariables; + protected TypeVariable[] typeVariables; // these three fields hold the source location of this member protected int start, end; @@ -276,6 +276,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno public boolean isAjSynthetic() { return isAjSynthetic; } + + protected void setAjSynthetic(boolean b) {isAjSynthetic= b;} public boolean hasAnnotations() { return (annotationTypes!=null); @@ -491,7 +493,6 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } public String[] getParameterNames() { - return parameterNames; } public final void setParameterNames(String[] pnames) { @@ -507,11 +508,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno public ISourceLocation getSourceLocation() { //System.out.println("get context: " + this + " is " + sourceContext); - if (sourceContext == null) { + if (getSourceContext() == null) { //System.err.println("no context: " + this); return null; } - return sourceContext.makeSourceLocation(this); + return getSourceContext().makeSourceLocation(this); } public int getEnd() { @@ -530,6 +531,10 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno this.start = sourceStart; this.end = sourceEnd; } + + public void setDeclaringType(ReferenceType rt) { + declaringType = rt; + } public void setSourceContext(ISourceContext sourceContext) { this.sourceContext = sourceContext; @@ -838,8 +843,12 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno StringBuffer r = new StringBuffer(); // modifiers - String mods = Modifier.toString(modifiers); - if (mods.length()!=0) r.append(mods).append(" "); + int mods = modifiers; + if ((mods & 4096)>0) mods = mods -4096; // remove synthetic (added in the ASM case but not in the BCEL case...) + if ((mods & 512)>0) mods = mods -512; // remove interface (added in the BCEL case but not in the ASM case...) + if ((mods & 131072)>0) mods = mods -131072; // remove deprecated (added in the ASM case but not in the BCEL case...) + String modsStr = Modifier.toString(mods); + if (modsStr.length()!=0) r.append(modsStr).append("("+mods+")").append(" "); // type variables if (typeVariables!=null && typeVariables.length>0) { @@ -853,7 +862,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } // 'declaring' type - r.append(returnType.toDebugString()); + r.append(getGenericReturnType().toDebugString()); r.append(' '); // name @@ -864,8 +873,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno // parameter signature if a method if (kind != FIELD) { r.append("("); - UnresolvedType[] params = parameterTypes; - boolean parameterNamesExist = parameterNames!=null && parameterNames.length==params.length; + UnresolvedType[] params = getGenericParameterTypes(); + boolean parameterNamesExist = showParameterNames && parameterNames!=null && parameterNames.length==params.length; if (params.length != 0) { for (int i=0, len = params.length; i < len; i++) { if (i>0) r.append(", "); @@ -877,6 +886,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } return r.toString(); } + + // SECRETAPI - controlling whether parameter names come out in the debug string (for testing purposes) + public static boolean showParameterNames = true; public String toGenericString() { StringBuffer buf = new StringBuffer(); diff --git a/weaver/src/org/aspectj/weaver/SourceContextImpl.java b/weaver/src/org/aspectj/weaver/SourceContextImpl.java new file mode 100644 index 000000000..b90dae980 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/SourceContextImpl.java @@ -0,0 +1,98 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 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: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +import java.io.File; +import java.util.Arrays; + +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.bridge.SourceLocation; + +public class SourceContextImpl implements ISourceContext { + + private AbstractReferenceTypeDelegate delegate; + private int[] lineBreaks; + + public SourceContextImpl(AbstractReferenceTypeDelegate delegate) { + this.delegate = delegate; + } + + public void configureFromAttribute(String name,int []linebreaks) { + this.delegate.setSourcefilename(name); + this.lineBreaks = linebreaks; + } + + private File getSourceFile() { + return new File(delegate.getSourcefilename()); + } + + public int getOffset() { return 0; } + + /* + // AMC - a temporary "fudge" to give as much information as possible about the identity of the + // source file this source location points to. + String internalClassName = getEnclosingClass().getInternalClassName(); + String fileName = getEnclosingClass().getFileName(); + String extension = fileName.substring( fileName.lastIndexOf("."), fileName.length()); + String filePrefix = fileName.substring( 0, fileName.lastIndexOf(".")); + // internal class name is e.g. figures/Point, we don't know whether the file was + // .aj or .java so we put it together with the file extension of the enclosing class + // BUT... sometimes internalClassName is a different class (an aspect), so we only use it if it + // matches the file name. + String mostAccurateFileNameGuess; + if ( internalClassName.endsWith(filePrefix)) { + mostAccurateFileNameGuess = internalClassName + extension; + } else { + mostAccurateFileNameGuess = fileName; + } + return new SourceLocation(new File(mostAccurateFileNameGuess), getSourceLine()); + */ + + + + public ISourceLocation makeSourceLocation(IHasPosition position) { + if (lineBreaks != null) { + int line = Arrays.binarySearch(lineBreaks, position.getStart()); + if (line < 0) line = -line; + return new SourceLocation(getSourceFile(), line); //??? have more info + } else { + return new SourceLocation(getSourceFile(), 0); + } + } + + public ISourceLocation makeSourceLocation(int line, int offset) { + if (line < 0) line = 0; + SourceLocation sl = new SourceLocation(getSourceFile(), line); + if (offset > 0) { + sl.setOffset(offset); + } else { + if (lineBreaks != null) { + int likelyOffset = 0; + if (line > 0 && line < lineBreaks.length) { + //1st char of given line is next char after previous end of line + likelyOffset = lineBreaks[line-1] + 1; + } + sl.setOffset(likelyOffset); + } + } + return sl; + } + + + public final static ISourceContext UNKNOWN_SOURCE_CONTEXT = new ISourceContext() { + public ISourceLocation makeSourceLocation(IHasPosition position) {return null;} + public ISourceLocation makeSourceLocation(int line, int offset) {return null;} + public int getOffset() {return 0;} + }; +} diff --git a/weaver/src/org/aspectj/weaver/TypeFactory.java b/weaver/src/org/aspectj/weaver/TypeFactory.java index 8ed3df8e6..d750d10ee 100644 --- a/weaver/src/org/aspectj/weaver/TypeFactory.java +++ b/weaver/src/org/aspectj/weaver/TypeFactory.java @@ -46,7 +46,7 @@ public class TypeFactory { } ResolvedType[] resolvedParameters = inAWorld.resolve(someTypeParameters); ReferenceType pType = new ReferenceType(baseType,resolvedParameters,inAWorld); - pType.setSourceContext(aBaseType.getSourceContext()); +// pType.setSourceContext(aBaseType.getSourceContext()); return (ReferenceType) pType.resolve(inAWorld); } @@ -66,7 +66,7 @@ public class TypeFactory { if (!aBaseType.isRawType()) throw new IllegalStateException("Expecting generic type"); } ReferenceType rType = new ReferenceType(aBaseType,inAWorld); - rType.setSourceContext(aBaseType.getSourceContext()); + //rType.setSourceContext(aBaseType.getSourceContext()); return (ReferenceType) rType.resolve(inAWorld); } diff --git a/weaver/src/org/aspectj/weaver/TypeVariable.java b/weaver/src/org/aspectj/weaver/TypeVariable.java index 30ca0f9ac..f66b95661 100644 --- a/weaver/src/org/aspectj/weaver/TypeVariable.java +++ b/weaver/src/org/aspectj/weaver/TypeVariable.java @@ -21,6 +21,7 @@ import java.util.Set; */ public class TypeVariable { + public static final TypeVariable[] NONE = new TypeVariable[0]; /** * whether or not the bounds of this type variable have been * resolved diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 38c808c98..f01b4001c 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -92,6 +92,18 @@ public abstract class World implements Dump.INode { private Properties extraConfiguration = null; + // Records whether ASM is around ... so we might use it for delegates + protected static boolean isASMAround; + + static { + try { + Class c = Class.forName("org.aspectj.org.objectweb.asm.ClassVisitor"); + isASMAround = true; + } catch (ClassNotFoundException cnfe) { + isASMAround = false; + } + } + /** * A list of RuntimeExceptions containing full stack information for every * type we couldn't find. @@ -307,6 +319,7 @@ public abstract class World implements Dump.INode { // ======= simple and raw types =============== String erasedSignature = ty.getErasureSignature(); ReferenceType simpleOrRawType = new ReferenceType(erasedSignature, this); + if (ty.needsModifiableDelegate()) simpleOrRawType.setNeedsModifiableDelegate(true); ReferenceTypeDelegate delegate = resolveDelegate(simpleOrRawType); // 117854 // if (delegate == null) return ResolvedType.MISSING; @@ -683,6 +696,9 @@ public abstract class World implements Dump.INode { } } + /** + * may return null + */ public Properties getExtraConfiguration() { return extraConfiguration; } @@ -1043,6 +1059,16 @@ public abstract class World implements Dump.INode { workInProgress1.remove(baseClass); } + public void flush() { +// System.err.println("BEFORE FLUSHING"); +// System.err.println(typeMap.toString()); + typeMap.expendableMap.clear(); +// System.err.println("AFTER FLUSHING"); +// System.err.println(typeMap.toString()); +// System.gc(); + System.gc(); + } + // --- } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelField.java b/weaver/src/org/aspectj/weaver/bcel/BcelField.java index d512aaca4..94030f692 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelField.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelField.java @@ -113,6 +113,11 @@ final class BcelField extends ResolvedMemberImpl { annotationTypes.toArray(ret); return ret; } + + public AnnotationX[] getAnnotations() { + ensureAnnotationTypesRetrieved(); + return annotations; + } private void ensureAnnotationTypesRetrieved() { if (annotationTypes == null) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index b86d725ef..6d20ad310 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -14,10 +14,12 @@ package org.aspectj.weaver.bcel; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.ExceptionTable; import org.aspectj.apache.bcel.classfile.GenericSignatureParser; import org.aspectj.apache.bcel.classfile.LocalVariable; @@ -36,6 +38,7 @@ import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedType; import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.World; import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException; @@ -143,6 +146,32 @@ final class BcelMethod extends ResolvedMemberImpl { } } } + + // for testing - if we have this attribute, return it - will return null if it doesnt know anything + public AjAttribute[] getAttributes(String name) { + List results = new ArrayList(); + List l = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world.getMessageHandler(),bcelObjectType.getWeaverVersionAttribute()); + for (Iterator iter = l.iterator(); iter.hasNext();) { + AjAttribute element = (AjAttribute) iter.next(); + if (element.getNameString().equals(name)) results.add(element); + } + if (results.size()>0) { + return (AjAttribute[])results.toArray(new AjAttribute[]{}); + } + return null; + } + + // for testing - use with the method above + public String[] getAttributeNames(boolean onlyIncludeAjOnes) { + Attribute[] as = method.getAttributes(); + List names = new ArrayList(); + String[] strs = new String[as.length]; + for (int j = 0; j < as.length; j++) { + if (!onlyIncludeAjOnes || as[j].getName().startsWith(AjAttribute.AttributePrefix)) + names.add(as[j].getName()); + } + return (String[])names.toArray(new String[]{}); + } public boolean isAjSynthetic() { return isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX); @@ -294,6 +323,24 @@ final class BcelMethod extends ResolvedMemberImpl { // generic method declaration canBeParameterized = true; } + + typeVariables = new TypeVariable[mSig.formalTypeParameters.length]; + for (int i = 0; i < typeVariables.length; i++) { + Signature.FormalTypeParameter methodFtp = mSig.formalTypeParameters[i]; + try { + typeVariables[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable( + methodFtp, + mSig.formalTypeParameters, + world); + } catch (GenericSignatureFormatException e) { + // this is a development bug, so fail fast with good info + throw new IllegalStateException( + "While getting the type variables for method " + this.toString() + + " with generic signature " + mSig + + " the following error condition was detected: " + e.getMessage()); + } + } + Signature.FormalTypeParameter[] parentFormals = bcelObjectType.getAllFormals(); Signature.FormalTypeParameter[] formals = new Signature.FormalTypeParameter[parentFormals.length + mSig.formalTypeParameters.length]; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java index f83d96b7f..8bea726dd 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java @@ -27,9 +27,9 @@ 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.annotation.Annotation; +import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue; import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair; import org.aspectj.apache.bcel.classfile.annotation.ElementValue; -import org.aspectj.bridge.ISourceLocation; import org.aspectj.weaver.AbstractReferenceTypeDelegate; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjcMemberMaker; @@ -41,6 +41,7 @@ import org.aspectj.weaver.ReferenceTypeDelegate; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.SourceContextImpl; import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeaverStateInfo; @@ -120,18 +121,21 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { super(resolvedTypeX, exposedToWeaver); this.javaClass = javaClass; - //ATAJ: set the delegate right now for @AJ poincut, else it is done too late to lookup + //ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup // @AJ pc refs annotation in class hierarchy resolvedTypeX.setDelegate(this); - if (resolvedTypeX.getSourceContext() == null) { - resolvedTypeX.setSourceContext(new BcelSourceContext(this)); +// if (resolvedTypeX.getSourceContext() == null) { +// resolvedTypeX. + if (resolvedTypeX.getSourceContext()==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) { + setSourceContext(new SourceContextImpl(this)); } // this should only ever be java.lang.Object which is // the only class in Java-1.4 with no superclasses isObject = (javaClass.getSuperclassNameIndex() == 0); unpackAspectAttributes(); + setSourcefilename(javaClass.getSourceFileName()); } @@ -265,7 +269,6 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { private void unpackAspectAttributes() { isUnpacked = true; - List pointcuts = new ArrayList(); typeMungers = new ArrayList(); declares = new ArrayList(); @@ -309,8 +312,9 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } else if (a instanceof AjAttribute.PrivilegedAttribute) { privilegedAccess = ((AjAttribute.PrivilegedAttribute)a).getAccessedMembers(); } else if (a instanceof AjAttribute.SourceContextAttribute) { - if (getResolvedTypeX().getSourceContext() instanceof BcelSourceContext) { - ((BcelSourceContext)getResolvedTypeX().getSourceContext()).addAttributeInfo((AjAttribute.SourceContextAttribute)a); + if (getResolvedTypeX().getSourceContext() instanceof SourceContextImpl) { + AjAttribute.SourceContextAttribute sca = (AjAttribute.SourceContextAttribute)a; + ((SourceContextImpl)getResolvedTypeX().getSourceContext()).configureFromAttribute(sca.getSourceFileName(),sca.getLineBreaks()); } } else if (a instanceof AjAttribute.WeaverVersionInfo) { wvInfo = (AjAttribute.WeaverVersionInfo)a; // Set the weaver version used to build this type @@ -443,26 +447,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } public boolean isAnnotationWithRuntimeRetention() { - return getRetentionPolicy().equals("RUNTIME"); -// if (!isAnnotation()) { -// return false; -// } else { -// Annotation[] annotationsOnThisType = javaClass.getAnnotations(); -// for (int i = 0; i < annotationsOnThisType.length; i++) { -// Annotation a = annotationsOnThisType[i]; -// if (a.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) { -// List values = a.getValues(); -// boolean isRuntime = false; -// for (Iterator it = values.iterator(); it.hasNext();) { -// ElementNameValuePair element = (ElementNameValuePair) it.next(); -// ElementValue v = element.getValue(); -// isRuntime = v.stringifyValue().equals("RUNTIME"); -// } -// return isRuntime; -// } -// } -// } -// return false; + return (getRetentionPolicy()==null?false:getRetentionPolicy().equals("RUNTIME")); } @@ -510,29 +495,32 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { for (int i = 0; i < annotationsOnThisType.length; i++) { Annotation a = annotationsOnThisType[i]; if (a.getTypeName().equals(UnresolvedType.AT_TARGET.getName())) { - List values = a.getValues(); - for (Iterator it = values.iterator(); it.hasNext();) { - ElementNameValuePair element = (ElementNameValuePair) it.next(); - ElementValue v = element.getValue(); - String targetKind = v.stringifyValue(); - if (targetKind.equals("ANNOTATION_TYPE")) { - targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE); - } else if (targetKind.equals("CONSTRUCTOR")) { - targetKinds.add(AnnotationTargetKind.CONSTRUCTOR); - } else if (targetKind.equals("FIELD")) { - targetKinds.add(AnnotationTargetKind.FIELD); - } else if (targetKind.equals("LOCAL_VARIABLE")) { - targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE); - } else if (targetKind.equals("METHOD")) { - targetKinds.add(AnnotationTargetKind.METHOD); - } else if (targetKind.equals("PACKAGE")) { - targetKinds.add(AnnotationTargetKind.PACKAGE); - } else if (targetKind.equals("PARAMETER")) { - targetKinds.add(AnnotationTargetKind.PARAMETER); - } else if (targetKind.equals("TYPE")) { - targetKinds.add(AnnotationTargetKind.TYPE); - } - } + ArrayElementValue arrayValue = (ArrayElementValue)((ElementNameValuePair)a.getValues().get(0)).getValue(); + ElementValue[] evs = arrayValue.getElementValuesArray(); + if (evs!=null) { + for (int j = 0; j < evs.length; j++) { + + ElementValue v = evs[j]; + String targetKind = v.stringifyValue(); + if (targetKind.equals("ANNOTATION_TYPE")) { + targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE); + } else if (targetKind.equals("CONSTRUCTOR")) { + targetKinds.add(AnnotationTargetKind.CONSTRUCTOR); + } else if (targetKind.equals("FIELD")) { + targetKinds.add(AnnotationTargetKind.FIELD); + } else if (targetKind.equals("LOCAL_VARIABLE")) { + targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE); + } else if (targetKind.equals("METHOD")) { + targetKinds.add(AnnotationTargetKind.METHOD); + } else if (targetKind.equals("PACKAGE")) { + targetKinds.add(AnnotationTargetKind.PACKAGE); + } else if (targetKind.equals("PARAMETER")) { + targetKinds.add(AnnotationTargetKind.PARAMETER); + } else if (targetKind.equals("TYPE")) { + targetKinds.add(AnnotationTargetKind.TYPE); + } + } + } } } if (!targetKinds.isEmpty()) { @@ -547,10 +535,6 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { return getResolvedTypeX().isSynthetic(); } - public ISourceLocation getSourceLocation() { - return getResolvedTypeX().getSourceContext().makeSourceLocation(0, 0); //FIXME ??? we can do better than this - } - public AjAttribute.WeaverVersionInfo getWeaverVersionAttribute() { return wvInfo; } @@ -687,7 +671,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { if (isGeneric()) { // update resolved typex to point at generic type not raw type. ReferenceType genericType = (ReferenceType) this.resolvedTypeX.getGenericType(); - genericType.setSourceContext(this.resolvedTypeX.getSourceContext()); + //genericType.setSourceContext(this.resolvedTypeX.getSourceContext()); genericType.setStartPos(this.resolvedTypeX.getStartPos()); this.resolvedTypeX = genericType; } @@ -751,6 +735,31 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { return (javaClass==null?"BcelObjectType":"BcelObjectTypeFor:"+javaClass.getClassName()); } + // for testing - if we have this attribute, return it - will return null if it doesnt know anything + public AjAttribute[] getAttributes(String name) { + List results = new ArrayList(); + List l = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld().getMessageHandler(),AjAttribute.WeaverVersionInfo.UNKNOWN); + for (Iterator iter = l.iterator(); iter.hasNext();) { + AjAttribute element = (AjAttribute) iter.next(); + if (element.getNameString().equals(name)) results.add(element); + } + if (results.size()>0) { + return (AjAttribute[])results.toArray(new AjAttribute[]{}); + } + return null; + } + + // for testing - use with the method above - this returns *all* including those that are not Aj attributes + public String[] getAttributeNames() { + Attribute[] as = javaClass.getAttributes(); + String[] strs = new String[as.length]; + for (int j = 0; j < as.length; j++) { + strs[j] = as[j].getName(); + } + return strs; + } + + } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 31dbacd0a..a10ad3480 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -148,7 +148,9 @@ public class BcelWeaver implements IWeaver { */ public ResolvedType addLibraryAspect(String aspectName) { // 1 - resolve as is - ResolvedType type = world.resolve(UnresolvedType.forName(aspectName), true); + UnresolvedType unresolvedT = UnresolvedType.forName(aspectName); + unresolvedT.setNeedsModifiableDelegate(true); + ResolvedType type = world.resolve(unresolvedT, true); if (type.isMissing()) { // fallback on inner class lookup mechanism String fixedName = aspectName; @@ -159,7 +161,9 @@ public class BcelWeaver implements IWeaver { fixedNameChars[hasDot] = '$'; fixedName = new String(fixedNameChars); hasDot = fixedName.lastIndexOf('.'); - type = world.resolve(UnresolvedType.forName(fixedName), true); + UnresolvedType ut = UnresolvedType.forName(fixedName); + ut.setNeedsModifiableDelegate(true); + type = world.resolve(ut, true); if (!type.isMissing()) { break; } @@ -1276,8 +1280,8 @@ public class BcelWeaver implements IWeaver { //classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData())); // new: reweavable default with clever diff classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes()))); - } else { - classType.resetState(); +// } else { +// classType.resetState(); } } @@ -1672,4 +1676,11 @@ public class BcelWeaver implements IWeaver { public World getWorld() { return world; } + + public void tidyUp() { + shadowMungerList = null; // setup by prepareForWeave + typeMungerList = null; // setup by prepareForWeave + lateTypeMungerList = null; // setup by prepareForWeave + declareParentsList = null; // setup by prepareForWeave + } } diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java index 739e1bc6f..ba208c751 100644 --- a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java @@ -20,10 +20,12 @@ import java.util.Collections; import org.aspectj.weaver.AnnotationTargetKind; import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ReferenceType; import org.aspectj.weaver.ReferenceTypeDelegate; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.SourceContextImpl; import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.UnresolvedType; import org.aspectj.weaver.WeaverStateInfo; @@ -351,5 +353,14 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega public ReflectionBasedResolvedMemberImpl createResolvedMemberFor(Member aMember) { return null; } + + public String getSourcefilename() { + // crappy guess.. + return resolvedType.getName() + ".class"; + } + + public ISourceContext getSourceContext() { + return SourceContextImpl.UNKNOWN_SOURCE_CONTEXT; + } }