@@ -64,6 +64,8 @@ public class AsmManager { | |||
private static String dumpFilename = ""; | |||
private static boolean reporting = false; | |||
private static boolean completingTypeBindings = false; | |||
// static { | |||
// setReporting("c:/model.nfo",true,true,true,true); | |||
// } | |||
@@ -72,7 +74,7 @@ public class AsmManager { | |||
hierarchy = new AspectJElementHierarchy(); | |||
// List relationships = new ArrayList(); | |||
mapper = new RelationshipMap(hierarchy); | |||
handleProvider = new FullPathHandleProvider(); | |||
handleProvider = new OptimizedFullPathHandleProvider(); | |||
} | |||
public void createNewASM() { | |||
@@ -845,5 +847,11 @@ public class AsmManager { | |||
*/ | |||
public static boolean isCreatingModel() { return creatingModel;} | |||
public static void setCompletingTypeBindings(boolean b) { | |||
completingTypeBindings = b; | |||
} | |||
public static boolean isCompletingTypeBindings() { return completingTypeBindings; } | |||
} | |||
@@ -53,4 +53,6 @@ public interface IElementHandleProvider { | |||
*/ | |||
public int getLineNumberForHandle(String handle); | |||
public int getOffSetForHandle(String handle); | |||
} |
@@ -91,6 +91,7 @@ public interface IHierarchy extends Serializable { | |||
* @return a new structure node for the file if it was not found in the model | |||
*/ | |||
public IProgramElement findElementForSourceLine(String sourceFilePath, int lineNumber); | |||
public IProgramElement findElementForOffSet(String sourceFilePath, int lineNumber, int offSet); | |||
public String getConfigFile(); | |||
@@ -43,11 +43,12 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
// int col = new Integer(st.nextToken()).intValue(); TODO: use column number when available | |||
String file = AsmManager.getDefault().getHandleProvider().getFileForHandle(handle); // st.nextToken(); | |||
int line = AsmManager.getDefault().getHandleProvider().getLineNumberForHandle(handle); // st.nextToken(); | |||
int offSet = AsmManager.getDefault().getHandleProvider().getOffSetForHandle(handle); | |||
String canonicalSFP = AsmManager.getDefault().getCanonicalFilePath(new File(file)); | |||
IProgramElement ret = findNodeForSourceLineHelper(root,canonicalSFP, line); | |||
IProgramElement ret = findNodeForSourceLineHelper(root,canonicalSFP, line, offSet); | |||
if (ret!=null) { | |||
handleMap.put(handle,ret); | |||
cache(handle,ret); | |||
} | |||
return ret; | |||
} | |||
@@ -245,7 +246,18 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
public IProgramElement findElementForSourceLine(String sourceFilePath, int lineNumber) { | |||
String canonicalSFP = AsmManager.getDefault().getCanonicalFilePath( | |||
new File(sourceFilePath)); | |||
IProgramElement node = findNodeForSourceLineHelper(root, canonicalSFP, lineNumber); | |||
IProgramElement node = findNodeForSourceLineHelper(root, canonicalSFP, lineNumber, -1); | |||
if (node != null) { | |||
return node; | |||
} else { | |||
return createFileStructureNode(sourceFilePath); | |||
} | |||
} | |||
public IProgramElement findElementForOffSet(String sourceFilePath, int lineNumber, int offSet) { | |||
String canonicalSFP = AsmManager.getDefault().getCanonicalFilePath( | |||
new File(sourceFilePath)); | |||
IProgramElement node = findNodeForSourceLineHelper(root, canonicalSFP, lineNumber, offSet); | |||
if (node != null) { | |||
return node; | |||
} else { | |||
@@ -267,9 +279,9 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
} | |||
private IProgramElement findNodeForSourceLineHelper(IProgramElement node, String sourceFilePath, int lineNumber) { | |||
if (matches(node, sourceFilePath, lineNumber) | |||
&& !hasMoreSpecificChild(node, sourceFilePath, lineNumber)) { | |||
private IProgramElement findNodeForSourceLineHelper(IProgramElement node, String sourceFilePath, int lineNumber, int offSet) { | |||
if (matches(node, sourceFilePath, lineNumber, offSet) | |||
&& !hasMoreSpecificChild(node, sourceFilePath, lineNumber, offSet)) { | |||
return node; | |||
} | |||
@@ -278,15 +290,16 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
IProgramElement foundNode = findNodeForSourceLineHelper( | |||
(IProgramElement)it.next(), | |||
sourceFilePath, | |||
lineNumber); | |||
lineNumber, | |||
offSet); | |||
if (foundNode != null) return foundNode; | |||
} | |||
} | |||
return null; | |||
} | |||
private boolean matches(IProgramElement node, String sourceFilePath, int lineNumber) { | |||
private boolean matches(IProgramElement node, String sourceFilePath, int lineNumber, int offSet) { | |||
// try { | |||
// if (node != null && node.getSourceLocation() != null) | |||
// System.err.println("====\n1: " + | |||
@@ -296,6 +309,8 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
return node != null | |||
&& node.getSourceLocation() != null | |||
&& node.getSourceLocation().getSourceFile().getAbsolutePath().equals(sourceFilePath) | |||
&& ((offSet != -1 && node.getSourceLocation().getOffset() == offSet) | |||
|| offSet == -1 ) | |||
&& ((node.getSourceLocation().getLine() <= lineNumber | |||
&& node.getSourceLocation().getEndLine() >= lineNumber) | |||
|| | |||
@@ -307,10 +322,10 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
// } | |||
} | |||
private boolean hasMoreSpecificChild(IProgramElement node, String sourceFilePath, int lineNumber) { | |||
private boolean hasMoreSpecificChild(IProgramElement node, String sourceFilePath, int lineNumber, int offSet) { | |||
for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { | |||
IProgramElement child = (IProgramElement)it.next(); | |||
if (matches(child, sourceFilePath, lineNumber)) return true; | |||
if (matches(child, sourceFilePath, lineNumber, offSet)) return true; | |||
} | |||
return false; | |||
} | |||
@@ -336,8 +351,9 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
// TODO: use column number when available | |||
String file = AsmManager.getDefault().getHandleProvider().getFileForHandle(handle); // st.nextToken(); | |||
int line = AsmManager.getDefault().getHandleProvider().getLineNumberForHandle(handle); // st.nextToken(); | |||
int offSet = AsmManager.getDefault().getHandleProvider().getOffSetForHandle(handle); | |||
ret = findElementForSourceLine(file, line); | |||
ret = findElementForOffSet(file, line, offSet); | |||
if (ret != null) { | |||
cache(handle,(ProgramElement)ret); | |||
} | |||
@@ -371,9 +387,11 @@ public class AspectJElementHierarchy implements IHierarchy { | |||
// } | |||
// return null; | |||
// } | |||
protected void cache(String handle, ProgramElement pe) { | |||
handleMap.put(handle,pe); | |||
protected void cache(String handle, IProgramElement pe) { | |||
if (!AsmManager.isCompletingTypeBindings()) { | |||
handleMap.put(handle,pe); | |||
} | |||
} | |||
public void flushTypeMap() { |
@@ -62,4 +62,12 @@ public class FullPathHandleProvider implements IElementHandleProvider { | |||
st.nextToken(); // skip over the file | |||
return new Integer(st.nextToken()).intValue(); | |||
} | |||
public int getOffSetForHandle(String handle) { | |||
StringTokenizer st = new StringTokenizer(handle, ID_DELIM); | |||
st.nextToken(); // skip over the file | |||
st.nextToken(); // skip over the line number | |||
st.nextToken(); // skip over the column | |||
return new Integer(st.nextToken()).intValue(); | |||
} | |||
} |
@@ -88,4 +88,12 @@ public class OptimizedFullPathHandleProvider implements IElementHandleProvider { | |||
st.nextToken(); // skip over the file | |||
return new Integer(st.nextToken()).intValue(); | |||
} | |||
public int getOffSetForHandle(String handle) { | |||
StringTokenizer st = new StringTokenizer(handle, ID_DELIM); | |||
st.nextToken(); // skip over the file | |||
st.nextToken(); // skip over the line number | |||
st.nextToken(); // skip over the column | |||
return new Integer(st.nextToken()).intValue(); | |||
} | |||
} |
@@ -78,13 +78,11 @@ public class ProgramElement implements IProgramElement { | |||
public ProgramElement (String name, IProgramElement.Kind kind, ISourceLocation sourceLocation, | |||
int modifiers, String comment, List children) { | |||
this(name, kind, children); | |||
this.sourceLocation = //ISourceLocation.EMPTY; | |||
sourceLocation; | |||
this.sourceLocation = sourceLocation; | |||
setFormalComment(comment); | |||
// if (comment!=null && comment.length()>0) formalComment = comment; | |||
this.modifiers = modifiers; | |||
// this.accessibility = genAccessibility(modifiers); | |||
cacheByHandle(); | |||
} | |||
/** | |||
@@ -104,9 +102,7 @@ public class ProgramElement implements IProgramElement { | |||
boolean member) { | |||
this(name, kind, children); | |||
this.sourceLocation = | |||
//ISourceLocation.EMPTY; | |||
sourceLocation; | |||
this.sourceLocation = sourceLocation; | |||
this.kind = kind; | |||
this.modifiers = modifiers; | |||
// this.accessibility = accessibility; | |||
@@ -116,7 +112,6 @@ public class ProgramElement implements IProgramElement { | |||
// if (comment!=null && comment.length()>0) formalComment = comment; | |||
if (relations!=null && relations.size()!=0) setRelations(relations); | |||
// this.relations = relations; | |||
cacheByHandle(); | |||
} | |||
public List getModifiers() { |
@@ -25,6 +25,7 @@ import java.util.Set; | |||
import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration; | |||
import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration; | |||
import org.aspectj.asm.AsmManager; | |||
import org.aspectj.bridge.IMessage; | |||
import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.bridge.WeaveMessage; | |||
@@ -117,6 +118,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
//??? duplicates some of super's code | |||
public void completeTypeBindings() { | |||
AsmManager.setCompletingTypeBindings(true); | |||
ContextToken completeTypeBindingsToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COMPLETING_TYPE_BINDINGS, ""); | |||
// builtInterTypesAndPerClauses = false; | |||
//pendingTypesToWeave = new ArrayList(); | |||
@@ -251,8 +253,8 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC | |||
stepCompleted = BUILD_FIELDS_AND_METHODS; | |||
lastCompletedUnitIndex = lastUnitIndex; | |||
CompilationAndWeavingContext.leavingPhase(completeTypeBindingsToken); | |||
AsmManager.setCompletingTypeBindings(false); | |||
CompilationAndWeavingContext.leavingPhase(completeTypeBindingsToken); | |||
} | |||
@@ -17,15 +17,17 @@ import java.io.File; | |||
import org.aspectj.ajdt.internal.core.builder.EclipseAdapterUtils; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit; | |||
import org.aspectj.org.eclipse.jdt.core.compiler.IProblem; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit; | |||
import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemHandler; | |||
public class EclipseSourceLocation implements ISourceLocation { | |||
private static String NO_CONTEXT = "USE_NULL--NO_CONTEXT_AVAILABLE"; | |||
CompilationResult result; | |||
// EclipseSourceContext eclipseContext; | |||
int startPos, endPos; | |||
String filename; | |||
// lazy but final | |||
File file; | |||
int startLine = -1; | |||
@@ -36,6 +38,7 @@ public class EclipseSourceLocation implements ISourceLocation { | |||
public EclipseSourceLocation(CompilationResult result, int startPos, int endPos) { | |||
super(); | |||
this.result = result; | |||
if (result!=null && result.fileName!=null) this.filename = new String(result.fileName); | |||
this.startPos = startPos; | |||
this.endPos = endPos; | |||
} | |||
@@ -58,19 +61,20 @@ public class EclipseSourceLocation implements ISourceLocation { | |||
public File getSourceFile() { | |||
if (null == file) { | |||
if ((null == result) | |||
|| (null == result.fileName) | |||
|| (0 == result.fileName.length)) { | |||
if (filename==null) { | |||
// if ((null == result) | |||
// || (null == result.fileName) | |||
// || (0 == result.fileName.length)) { | |||
file = ISourceLocation.NO_FILE; | |||
} else { | |||
file = new File(new String(result.fileName)); | |||
file = new File(filename);//new String(result.fileName)); | |||
} | |||
} | |||
return file; | |||
} | |||
public int getLine() { | |||
if (-1 == startLine) { | |||
if (-1 == startLine && result!=null) { | |||
startLine = ProblemHandler.searchLineNumber(result.lineSeparatorPositions, startPos); | |||
} | |||
return startLine; |
@@ -227,7 +227,7 @@ public class AsmElementFormatter { | |||
//TODO AV - could speed up if we could dig only for @Aspect declaring types (or aspect if mixed style allowed) | |||
//??? how to : node.getParent().getKind().equals(IProgramElement.Kind.ASPECT)) { | |||
if (true && methodDeclaration.annotations != null) { | |||
if (true && methodDeclaration!=null && methodDeclaration.annotations != null) { | |||
for (int i = 0; i < methodDeclaration.annotations.length; i++) { | |||
//Note: AV: implicit single advice type support here (should be enforced somewhere as well (APT etc)) | |||
Annotation annotation = methodDeclaration.annotations[i]; |
@@ -68,5 +68,9 @@ public class EclipseSourceContext implements ISourceContext { | |||
} | |||
return sl; | |||
} | |||
public void tidy() { | |||
result=null; | |||
} | |||
} |
@@ -19,4 +19,5 @@ public interface ISourceContext { | |||
public ISourceLocation makeSourceLocation(IHasPosition position); | |||
public ISourceLocation makeSourceLocation(int line, int offset); | |||
public int getOffset(); | |||
public void tidy(); | |||
} |
@@ -119,6 +119,8 @@ public class MissingResolvedTypeWithKnownSignature extends ResolvedType { | |||
return 0; | |||
} | |||
public void tidy() {} | |||
}; | |||
} | |||
@@ -21,7 +21,9 @@ public class NameMangler { | |||
throw new RuntimeException("static"); | |||
} | |||
public static final char[] AJC_DOLLAR_PREFIX = {'a', 'j', 'c','$'}; | |||
public static final char[] CLINIT={'<','c','l','i','n','i','t','>'}; | |||
public static final String PREFIX = "ajc$"; | |||
public static final char[] INIT = {'<','i','n','i','t','>'}; | |||
public static final String ITD_PREFIX = PREFIX + "interType$"; | |||
public static final char[] METHOD_ASPECTOF = {'a', 's', 'p','e','c','t','O','f'}; | |||
public static final char[] METHOD_HASASPECT = {'h', 'a', 's','A','s','p','e','c','t'}; |
@@ -19,6 +19,7 @@ import java.util.List; | |||
import java.util.Map; | |||
import org.aspectj.bridge.ISourceLocation; | |||
import org.aspectj.weaver.bcel.BcelObjectType; | |||
import org.aspectj.weaver.patterns.Declare; | |||
import org.aspectj.weaver.patterns.PerClause; | |||
@@ -610,7 +611,8 @@ public class ReferenceType extends ResolvedType { | |||
} | |||
public void setDelegate(ReferenceTypeDelegate delegate) { | |||
if (this.delegate!=null && this.delegate.getSourceContext()!=SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) | |||
// Don't copy from BcelObjectType to EclipseSourceType - the context may be tidied (result null'd) after previous weaving | |||
if (this.delegate!=null && !(this.delegate instanceof BcelObjectType) && this.delegate.getSourceContext()!=SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) | |||
((AbstractReferenceTypeDelegate)delegate).setSourceContext(this.delegate.getSourceContext()); | |||
this.delegate = delegate; | |||
for(Iterator it = this.derivativeTypes.iterator(); it.hasNext(); ) { |
@@ -37,6 +37,8 @@ public class SourceContextImpl implements ISourceContext { | |||
return new File(delegate.getSourcefilename()); | |||
} | |||
public void tidy() {} | |||
public int getOffset() { return 0; } | |||
/* | |||
@@ -94,5 +96,6 @@ public class SourceContextImpl implements ISourceContext { | |||
public ISourceLocation makeSourceLocation(IHasPosition position) {return null;} | |||
public ISourceLocation makeSourceLocation(int line, int offset) {return null;} | |||
public int getOffset() {return 0;} | |||
public void tidy() {} | |||
}; | |||
} |
@@ -100,8 +100,8 @@ public abstract class World implements Dump.INode { | |||
private boolean checkedAdvancedConfiguration=false; | |||
// Xset'table options | |||
private boolean fastDelegateSupportEnabled = isASMAround; | |||
private boolean runMinimalMemory = true; | |||
private boolean runMinimalMemory = false; | |||
public boolean forDEBUG_structuralChangesCode = false; | |||
// Records whether ASM is around ... so we might use it for delegates | |||
@@ -717,6 +717,7 @@ public abstract class World implements Dump.INode { | |||
public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default false | |||
public final static String xsetACTIVATE_LIGHTWEIGHT_DELEGATES = "activateLightweightDelegates"; // default true | |||
public final static String xsetRUN_MINIMAL_MEMORY ="runMinimalMemory"; // default true | |||
public final static String xsetDEBUG_STRUCTURAL_CHANGES_CODE = "debugStructuralChangesCode"; // default false | |||
public boolean isInJava5Mode() { | |||
return behaveInJava5Way; | |||
@@ -1086,21 +1087,27 @@ public abstract class World implements Dump.INode { | |||
if (!checkedAdvancedConfiguration) { | |||
Properties p = getExtraConfiguration(); | |||
if (p!=null) { | |||
if (isASMAround) { // dont bother if its not... | |||
String s = p.getProperty(xsetACTIVATE_LIGHTWEIGHT_DELEGATES,"true"); | |||
fastDelegateSupportEnabled = s.equalsIgnoreCase("true"); | |||
if (!fastDelegateSupportEnabled) | |||
getMessageHandler().handleMessage(MessageUtil.info("[activateLightweightDelegates=false] Disabling optimization to use lightweight delegates for non-woven types")); | |||
} | |||
// wonder if this should be based on whether an incremental build can follow? | |||
String s = p.getProperty(xsetRUN_MINIMAL_MEMORY,"false"); | |||
if (isASMAround) { // dont bother if its not... | |||
String s = p.getProperty(xsetACTIVATE_LIGHTWEIGHT_DELEGATES,"true"); | |||
fastDelegateSupportEnabled = s.equalsIgnoreCase("true"); | |||
if (!fastDelegateSupportEnabled) | |||
getMessageHandler().handleMessage(MessageUtil.info("[activateLightweightDelegates=false] Disabling optimization to use lightweight delegates for non-woven types")); | |||
} | |||
String s = p.getProperty(xsetRUN_MINIMAL_MEMORY,"false"); | |||
runMinimalMemory = s.equalsIgnoreCase("true"); | |||
// if (runMinimalMemory) | |||
// getMessageHandler().handleMessage(MessageUtil.info("[runMinimalMemory=true] Optimizing bcel processing (and cost of performance) to use less memory")); | |||
s = p.getProperty(xsetDEBUG_STRUCTURAL_CHANGES_CODE,"false"); | |||
forDEBUG_structuralChangesCode = s.equalsIgnoreCase("true"); | |||
} | |||
checkedAdvancedConfiguration=true; | |||
} | |||
} | |||
} | |||
} | |||
public boolean isRunMinimalMemory() { | |||
ensureAdvancedConfigurationProcessed(); |
@@ -1058,7 +1058,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
for (int i = 0; i < dontAddMeTwice.length; i++){ | |||
Annotation ann = dontAddMeTwice[i]; | |||
if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())){ | |||
dontAddMeTwice[i] = null; // incase it really has been added twice! | |||
//dontAddMeTwice[i] = null; // incase it really has been added twice! | |||
return true; | |||
} | |||
} |
@@ -386,6 +386,7 @@ public class PointcutParser { | |||
public int getOffset() { | |||
return 0; | |||
} | |||
public void tidy() {} | |||
}; | |||
return new AtAjAttributes.BindingScope(inType,sourceContext,formalBindings); | |||
} |