|
|
@@ -11,149 +11,234 @@ |
|
|
|
* Andy Clement Extensions for better IDE representation |
|
|
|
* ******************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
package org.aspectj.asm.internal; |
|
|
|
|
|
|
|
import java.io.*; |
|
|
|
import java.util.*; |
|
|
|
import java.io.File; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Iterator; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
import org.aspectj.asm.*; |
|
|
|
import org.aspectj.bridge.*; |
|
|
|
import org.aspectj.asm.AsmManager; |
|
|
|
import org.aspectj.asm.IHierarchy; |
|
|
|
import org.aspectj.asm.IProgramElement; |
|
|
|
import org.aspectj.bridge.ISourceLocation; |
|
|
|
import org.aspectj.bridge.SourceLocation; |
|
|
|
|
|
|
|
/** |
|
|
|
* @author Mik Kersten |
|
|
|
*/ |
|
|
|
public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
|
|
|
|
|
|
|
|
private static final long serialVersionUID = 6462734311117048620L; |
|
|
|
|
|
|
|
protected IProgramElement root = null; |
|
|
|
protected String configFile = null; |
|
|
|
|
|
|
|
private Map fileMap = null; |
|
|
|
private Map handleMap = null; |
|
|
|
private Map typeMap = null; |
|
|
|
|
|
|
|
|
|
|
|
protected IProgramElement root = null; |
|
|
|
protected String configFile = null; |
|
|
|
|
|
|
|
private Map fileMap = null; |
|
|
|
private Map handleMap = null; |
|
|
|
private Map typeMap = null; |
|
|
|
|
|
|
|
public IProgramElement getElement(String handle) { |
|
|
|
return findElementForHandleOrCreate(handle, false); |
|
|
|
} |
|
|
|
|
|
|
|
public IProgramElement getRoot() { |
|
|
|
return root; |
|
|
|
} |
|
|
|
public IProgramElement getRoot() { |
|
|
|
return root; |
|
|
|
} |
|
|
|
|
|
|
|
public void setRoot(IProgramElement root) { |
|
|
|
this.root = root; |
|
|
|
handleMap = new HashMap(); |
|
|
|
typeMap = new HashMap(); |
|
|
|
} |
|
|
|
public void setRoot(IProgramElement root) { |
|
|
|
this.root = root; |
|
|
|
handleMap = new HashMap(); |
|
|
|
typeMap = new HashMap(); |
|
|
|
} |
|
|
|
|
|
|
|
public void addToFileMap( Object key, Object value ){ |
|
|
|
fileMap.put( key, value ); |
|
|
|
public void addToFileMap(Object key, Object value) { |
|
|
|
fileMap.put(key, value); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public boolean removeFromFileMap(Object key) { |
|
|
|
if (fileMap.containsKey(key)) { |
|
|
|
return (fileMap.remove(key)!=null); |
|
|
|
return (fileMap.remove(key) != null); |
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
public void setFileMap(HashMap fileMap) { |
|
|
|
this.fileMap = fileMap; |
|
|
|
} |
|
|
|
this.fileMap = fileMap; |
|
|
|
} |
|
|
|
|
|
|
|
public Object findInFileMap( Object key ) { |
|
|
|
public Object findInFileMap(Object key) { |
|
|
|
return fileMap.get(key); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Set getFileMapEntrySet() { |
|
|
|
return fileMap.entrySet(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public boolean isValid() { |
|
|
|
return root != null && fileMap != null; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
return root != null && fileMap != null; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Returns the first match |
|
|
|
* |
|
|
|
* @param parent |
|
|
|
* @param kind not null |
|
|
|
* @param kind not null |
|
|
|
* @return null if not found |
|
|
|
*/ |
|
|
|
public IProgramElement findElementForSignature(IProgramElement parent, IProgramElement.Kind kind, String signature) { |
|
|
|
for (Iterator it = parent.getChildren().iterator(); it.hasNext(); ) { |
|
|
|
IProgramElement node = (IProgramElement)it.next(); |
|
|
|
for (Iterator it = parent.getChildren().iterator(); it.hasNext();) { |
|
|
|
IProgramElement node = (IProgramElement) it.next(); |
|
|
|
if (node.getKind() == kind && signature.equals(node.toSignatureString())) { |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
IProgramElement childSearch = findElementForSignature(node, kind, signature); |
|
|
|
if (childSearch != null) return childSearch; |
|
|
|
if (childSearch != null) |
|
|
|
return childSearch; |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
public IProgramElement findElementForLabel( |
|
|
|
IProgramElement parent, |
|
|
|
IProgramElement.Kind kind, |
|
|
|
String label) { |
|
|
|
|
|
|
|
for (Iterator it = parent.getChildren().iterator(); it.hasNext(); ) { |
|
|
|
IProgramElement node = (IProgramElement)it.next(); |
|
|
|
|
|
|
|
public IProgramElement findElementForLabel(IProgramElement parent, IProgramElement.Kind kind, String label) { |
|
|
|
|
|
|
|
for (Iterator it = parent.getChildren().iterator(); it.hasNext();) { |
|
|
|
IProgramElement node = (IProgramElement) it.next(); |
|
|
|
if (node.getKind() == kind && label.equals(node.toLabelString())) { |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
IProgramElement childSearch = findElementForLabel(node, kind, label); |
|
|
|
if (childSearch != null) return childSearch; |
|
|
|
if (childSearch != null) |
|
|
|
return childSearch; |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @param packageName if null default package is searched |
|
|
|
* @param className can't be null |
|
|
|
*/ |
|
|
|
* Find the entry in the model that represents a particular type. |
|
|
|
* |
|
|
|
* @param packageName the package in which the type is declared or null for the default package |
|
|
|
* @param typeName the name of the type |
|
|
|
* @return the IProgramElement representing the type, or null if not found |
|
|
|
*/ |
|
|
|
public IProgramElement findElementForType(String packageName, String typeName) { |
|
|
|
StringBuffer keyb = (packageName == null) ? new StringBuffer() : |
|
|
|
new StringBuffer(packageName); |
|
|
|
keyb.append("."); |
|
|
|
keyb.append(typeName); |
|
|
|
|
|
|
|
// Build a cache key and check the cache |
|
|
|
StringBuffer keyb = (packageName == null) ? new StringBuffer() : new StringBuffer(packageName); |
|
|
|
keyb.append(".").append(typeName); |
|
|
|
String key = keyb.toString(); |
|
|
|
IProgramElement ret = (IProgramElement) typeMap.get(key); |
|
|
|
if (ret == null) { |
|
|
|
IProgramElement packageNode = null; |
|
|
|
if (packageName == null) { |
|
|
|
packageNode = root; |
|
|
|
} else { |
|
|
|
if (root == null) return null; |
|
|
|
List kids = root.getChildren(); |
|
|
|
if (kids == null) return null; |
|
|
|
for (Iterator it = kids.iterator(); it.hasNext(); ) { |
|
|
|
IProgramElement node = (IProgramElement)it.next(); |
|
|
|
if (packageName.equals(node.getName())) { |
|
|
|
packageNode = node; |
|
|
|
} |
|
|
|
} |
|
|
|
if (packageNode == null) return null; |
|
|
|
} |
|
|
|
|
|
|
|
IProgramElement cachedValue = (IProgramElement) typeMap.get(key); |
|
|
|
if (cachedValue != null) { |
|
|
|
return cachedValue; |
|
|
|
} |
|
|
|
|
|
|
|
List packageNodes = findMatchingPackages(packageName); |
|
|
|
|
|
|
|
for (Iterator iterator = packageNodes.iterator(); iterator.hasNext();) { |
|
|
|
IProgramElement pkg = (IProgramElement) iterator.next(); |
|
|
|
// this searches each file for a class |
|
|
|
for (Iterator it = packageNode.getChildren().iterator(); it.hasNext(); ) { |
|
|
|
IProgramElement fileNode = (IProgramElement)it.next(); |
|
|
|
for (Iterator it = pkg.getChildren().iterator(); it.hasNext();) { |
|
|
|
IProgramElement fileNode = (IProgramElement) it.next(); |
|
|
|
IProgramElement cNode = findClassInNodes(fileNode.getChildren(), typeName, typeName); |
|
|
|
if (cNode != null) { |
|
|
|
ret = cNode; |
|
|
|
typeMap.put(key,ret); |
|
|
|
} |
|
|
|
} |
|
|
|
typeMap.put(key, cNode); |
|
|
|
return cNode; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return ret; |
|
|
|
return null; |
|
|
|
|
|
|
|
// IProgramElement packageNode = null; |
|
|
|
// if (packageName == null) { |
|
|
|
// packageNode = root; |
|
|
|
// } else { |
|
|
|
// if (root == null) |
|
|
|
// return null; |
|
|
|
// List kids = root.getChildren(); |
|
|
|
// if (kids == null) { |
|
|
|
// return null; |
|
|
|
// } |
|
|
|
// for (Iterator it = kids.iterator(); it.hasNext() && packageNode == null;) { |
|
|
|
// IProgramElement node = (IProgramElement) it.next(); |
|
|
|
// if (packageName.equals(node.getName())) { |
|
|
|
// packageNode = node; |
|
|
|
// } |
|
|
|
// } |
|
|
|
// if (packageNode == null) { |
|
|
|
// return null; |
|
|
|
// } |
|
|
|
// } |
|
|
|
|
|
|
|
// // this searches each file for a class |
|
|
|
// for (Iterator it = packageNode.getChildren().iterator(); it.hasNext();) { |
|
|
|
// IProgramElement fileNode = (IProgramElement) it.next(); |
|
|
|
// IProgramElement cNode = findClassInNodes(fileNode.getChildren(), typeName, typeName); |
|
|
|
// if (cNode != null) { |
|
|
|
// typeMap.put(key, cNode); |
|
|
|
// return cNode; |
|
|
|
// } |
|
|
|
// } |
|
|
|
// return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Look for any package nodes matching the specified package name. There may be multiple in the case where the types within a |
|
|
|
* package are split across source folders. |
|
|
|
* |
|
|
|
* @param packagename the packagename being searched for |
|
|
|
* @return a list of package nodes that match that name |
|
|
|
*/ |
|
|
|
public List/* IProgramElement */findMatchingPackages(String packagename) { |
|
|
|
List children = root.getChildren(); |
|
|
|
// The children might be source folders or packages |
|
|
|
if (children.size() == 0) { |
|
|
|
return Collections.EMPTY_LIST; |
|
|
|
} |
|
|
|
if (((IProgramElement) children.get(0)).getKind() == IProgramElement.Kind.SOURCE_FOLDER) { |
|
|
|
// dealing with source folders |
|
|
|
List matchingPackageNodes = new ArrayList(); |
|
|
|
for (Iterator iterator = children.iterator(); iterator.hasNext();) { |
|
|
|
IProgramElement sourceFolder = (IProgramElement) iterator.next(); |
|
|
|
List possiblePackageNodes = sourceFolder.getChildren(); |
|
|
|
for (Iterator iterator2 = possiblePackageNodes.iterator(); iterator2.hasNext();) { |
|
|
|
IProgramElement possiblePackageNode = (IProgramElement) iterator2.next(); |
|
|
|
if (possiblePackageNode.getKind() == IProgramElement.Kind.PACKAGE) { |
|
|
|
if (possiblePackageNode.getName().equals(packagename)) { |
|
|
|
matchingPackageNodes.add(possiblePackageNode); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return matchingPackageNodes; |
|
|
|
} else { |
|
|
|
// dealing directly with packages below the root, no source folders. Therefore at most one |
|
|
|
// thing to return in the list |
|
|
|
if (packagename == null) { |
|
|
|
// default package |
|
|
|
List result = new ArrayList(); |
|
|
|
result.add(root); |
|
|
|
return result; |
|
|
|
} |
|
|
|
for (Iterator iterator = children.iterator(); iterator.hasNext();) { |
|
|
|
IProgramElement possiblePackage = (IProgramElement) iterator.next(); |
|
|
|
if (possiblePackage.getKind() == IProgramElement.Kind.PACKAGE) { |
|
|
|
if (possiblePackage.getName().equals(packagename)) { |
|
|
|
List result = new ArrayList(); |
|
|
|
result.add(possiblePackage); |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return Collections.EMPTY_LIST; |
|
|
|
} |
|
|
|
|
|
|
|
private IProgramElement findClassInNodes(Collection nodes, String name, String typeName) { |
|
|
|
String baseName; |
|
|
|
String innerName; |
|
|
@@ -163,20 +248,22 @@ public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
innerName = null; |
|
|
|
} else { |
|
|
|
baseName = name.substring(0, dollar); |
|
|
|
innerName = name.substring(dollar+1); |
|
|
|
innerName = name.substring(dollar + 1); |
|
|
|
} |
|
|
|
|
|
|
|
for (Iterator j = nodes.iterator(); j.hasNext(); ) { |
|
|
|
IProgramElement classNode = (IProgramElement)j.next(); |
|
|
|
|
|
|
|
for (Iterator j = nodes.iterator(); j.hasNext();) { |
|
|
|
IProgramElement classNode = (IProgramElement) j.next(); |
|
|
|
if (baseName.equals(classNode.getName())) { |
|
|
|
if (innerName == null) return classNode; |
|
|
|
else return findClassInNodes(classNode.getChildren(), innerName, typeName); |
|
|
|
if (innerName == null) |
|
|
|
return classNode; |
|
|
|
else |
|
|
|
return findClassInNodes(classNode.getChildren(), innerName, typeName); |
|
|
|
} else if (name.equals(classNode.getName())) { |
|
|
|
return classNode; |
|
|
|
} else if (typeName.equals(classNode.getBytecodeSignature())) { |
|
|
|
} else if (typeName.equals(classNode.getBytecodeSignature())) { |
|
|
|
return classNode; |
|
|
|
} else if (classNode.getChildren() != null && !classNode.getChildren().isEmpty()){ |
|
|
|
IProgramElement node = findClassInNodes(classNode.getChildren(),name, typeName); |
|
|
|
} else if (classNode.getChildren() != null && !classNode.getChildren().isEmpty()) { |
|
|
|
IProgramElement node = findClassInNodes(classNode.getChildren(), name, typeName); |
|
|
|
if (node != null) { |
|
|
|
return node; |
|
|
|
} |
|
|
@@ -185,69 +272,63 @@ public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @param sourceFilePath modified to '/' delimited path for consistency |
|
|
|
* @return a new structure node for the file if it was not found in the model |
|
|
|
* @param sourceFilePath modified to '/' delimited path for consistency |
|
|
|
* @return a new structure node for the file if it was not found in the model |
|
|
|
*/ |
|
|
|
public IProgramElement findElementForSourceFile(String sourceFile) { |
|
|
|
try { |
|
|
|
if (!isValid() || sourceFile == null) { |
|
|
|
return IHierarchy.NO_STRUCTURE; |
|
|
|
} else { |
|
|
|
String correctedPath = |
|
|
|
AsmManager.getDefault().getCanonicalFilePath(new File(sourceFile)); |
|
|
|
//StructureNode node = (StructureNode)getFileMap().get(correctedPath);//findFileNode(filePath, model); |
|
|
|
IProgramElement node = (IProgramElement)findInFileMap(correctedPath);//findFileNode(filePath, model); |
|
|
|
if (node != null) { |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
return createFileStructureNode(correctedPath); |
|
|
|
} |
|
|
|
} |
|
|
|
try { |
|
|
|
if (!isValid() || sourceFile == null) { |
|
|
|
return IHierarchy.NO_STRUCTURE; |
|
|
|
} else { |
|
|
|
String correctedPath = AsmManager.getDefault().getCanonicalFilePath(new File(sourceFile)); |
|
|
|
// StructureNode node = (StructureNode)getFileMap().get(correctedPath);//findFileNode(filePath, model); |
|
|
|
IProgramElement node = (IProgramElement) findInFileMap(correctedPath);// findFileNode(filePath, model); |
|
|
|
if (node != null) { |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
return createFileStructureNode(correctedPath); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
return IHierarchy.NO_STRUCTURE; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* TODO: discriminate columns |
|
|
|
*/ |
|
|
|
public IProgramElement findElementForSourceLine(ISourceLocation location) { |
|
|
|
try { |
|
|
|
return findElementForSourceLine( |
|
|
|
AsmManager.getDefault().getCanonicalFilePath( |
|
|
|
location.getSourceFile()), |
|
|
|
location.getLine()); |
|
|
|
return findElementForSourceLine(AsmManager.getDefault().getCanonicalFilePath(location.getSourceFile()), location |
|
|
|
.getLine()); |
|
|
|
} catch (Exception e) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Never returns null |
|
|
|
* Never returns null |
|
|
|
* |
|
|
|
* @param sourceFilePath canonicalized path for consistency |
|
|
|
* @param lineNumber if 0 or 1 the corresponding file node will be returned |
|
|
|
* @return a new structure node for the file if it was not found in the model |
|
|
|
* @param sourceFilePath canonicalized path for consistency |
|
|
|
* @param lineNumber if 0 or 1 the corresponding file node will be returned |
|
|
|
* @return a new structure node for the file if it was not found in the model |
|
|
|
*/ |
|
|
|
public IProgramElement findElementForSourceLine(String sourceFilePath, int lineNumber) { |
|
|
|
String canonicalSFP = AsmManager.getDefault().getCanonicalFilePath( |
|
|
|
new File(sourceFilePath)); |
|
|
|
String canonicalSFP = AsmManager.getDefault().getCanonicalFilePath(new File(sourceFilePath)); |
|
|
|
IProgramElement node = findNodeForSourceLineHelper(root, canonicalSFP, lineNumber, -1); |
|
|
|
if (node != null) { |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
return createFileStructureNode(sourceFilePath); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public IProgramElement findElementForOffSet(String sourceFilePath, int lineNumber, int offSet) { |
|
|
|
String canonicalSFP = AsmManager.getDefault().getCanonicalFilePath( |
|
|
|
new File(sourceFilePath)); |
|
|
|
String canonicalSFP = AsmManager.getDefault().getCanonicalFilePath(new File(sourceFilePath)); |
|
|
|
IProgramElement node = findNodeForSourceLineHelper(root, canonicalSFP, lineNumber, offSet); |
|
|
|
if (node != null) { |
|
|
|
return node; |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
return createFileStructureNode(sourceFilePath); |
|
|
|
} |
|
|
@@ -259,68 +340,61 @@ public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
if (lastSlash == -1) { |
|
|
|
lastSlash = sourceFilePath.lastIndexOf('/'); |
|
|
|
} |
|
|
|
// '!' is used like in URLs "c:/blahblah/X.jar!a/b.class" |
|
|
|
// '!' is used like in URLs "c:/blahblah/X.jar!a/b.class" |
|
|
|
int i = sourceFilePath.lastIndexOf('!'); |
|
|
|
int j = sourceFilePath.indexOf(".class"); |
|
|
|
if (i > lastSlash && i != -1 && j != -1) { |
|
|
|
// we are a binary aspect in the default package |
|
|
|
lastSlash = i; |
|
|
|
} |
|
|
|
String fileName = sourceFilePath.substring(lastSlash+1); |
|
|
|
IProgramElement fileNode = new ProgramElement(fileName, IProgramElement.Kind.FILE_JAVA, new SourceLocation(new File(sourceFilePath), 1, 1),0,null,null); |
|
|
|
//fileNode.setSourceLocation(); |
|
|
|
String fileName = sourceFilePath.substring(lastSlash + 1); |
|
|
|
IProgramElement fileNode = new ProgramElement(fileName, IProgramElement.Kind.FILE_JAVA, new SourceLocation(new File( |
|
|
|
sourceFilePath), 1, 1), 0, null, null); |
|
|
|
// fileNode.setSourceLocation(); |
|
|
|
fileNode.addChild(NO_STRUCTURE); |
|
|
|
return fileNode; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private IProgramElement findNodeForSourceLineHelper(IProgramElement node, String sourceFilePath, int lineNumber, int offSet) { |
|
|
|
if (matches(node, sourceFilePath, lineNumber, offSet) |
|
|
|
&& !hasMoreSpecificChild(node, sourceFilePath, lineNumber, offSet)) { |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
if (matches(node, sourceFilePath, lineNumber, offSet) && !hasMoreSpecificChild(node, sourceFilePath, lineNumber, offSet)) { |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
if (node != null && node.getChildren() != null) { |
|
|
|
for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { |
|
|
|
IProgramElement foundNode = findNodeForSourceLineHelper( |
|
|
|
(IProgramElement)it.next(), |
|
|
|
sourceFilePath, |
|
|
|
lineNumber, |
|
|
|
offSet); |
|
|
|
if (foundNode != null) return foundNode; |
|
|
|
for (Iterator it = node.getChildren().iterator(); it.hasNext();) { |
|
|
|
IProgramElement foundNode = findNodeForSourceLineHelper((IProgramElement) it.next(), sourceFilePath, lineNumber, |
|
|
|
offSet); |
|
|
|
if (foundNode != null) |
|
|
|
return foundNode; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private boolean matches(IProgramElement node, String sourceFilePath, int lineNumber, int offSet) { |
|
|
|
// try { |
|
|
|
// if (node != null && node.getSourceLocation() != null) |
|
|
|
// System.err.println("====\n1: " + |
|
|
|
// sourceFilePath + "\n2: " + |
|
|
|
// node.getSourceLocation().getSourceFile().getCanonicalPath().equals(sourceFilePath) |
|
|
|
// ); |
|
|
|
return node != null |
|
|
|
// try { |
|
|
|
// if (node != null && node.getSourceLocation() != null) |
|
|
|
// System.err.println("====\n1: " + |
|
|
|
// sourceFilePath + "\n2: " + |
|
|
|
// node.getSourceLocation().getSourceFile().getCanonicalPath().equals(sourceFilePath) |
|
|
|
// ); |
|
|
|
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) |
|
|
|
|| |
|
|
|
(lineNumber <= 1 |
|
|
|
&& node.getKind().isSourceFile()) |
|
|
|
); |
|
|
|
// } catch (IOException ioe) { |
|
|
|
// return false; |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
&& ((offSet != -1 && node.getSourceLocation().getOffset() == offSet) || offSet == -1) |
|
|
|
&& ((node.getSourceLocation().getLine() <= lineNumber && node.getSourceLocation().getEndLine() >= lineNumber) || (lineNumber <= 1 && node |
|
|
|
.getKind().isSourceFile())); |
|
|
|
// } catch (IOException ioe) { |
|
|
|
// return false; |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
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, offSet)) return true; |
|
|
|
for (Iterator it = node.getChildren().iterator(); it.hasNext();) { |
|
|
|
IProgramElement child = (IProgramElement) it.next(); |
|
|
|
if (matches(child, sourceFilePath, lineNumber, offSet)) |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
@@ -332,11 +406,11 @@ public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
public void setConfigFile(String configFile) { |
|
|
|
this.configFile = configFile; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public IProgramElement findElementForHandle(String handle) { |
|
|
|
return findElementForHandleOrCreate(handle,true); |
|
|
|
return findElementForHandleOrCreate(handle, true); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TODO: optimize this lookup |
|
|
|
// only want to create a file node if can't find the IPE if called through |
|
|
|
// findElementForHandle() to mirror behaviour before pr141730 |
|
|
@@ -346,81 +420,84 @@ public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
if (ipe != null) { |
|
|
|
return ipe; |
|
|
|
} |
|
|
|
|
|
|
|
ipe = findElementForHandle(root,handle); |
|
|
|
|
|
|
|
ipe = findElementForHandle(root, handle); |
|
|
|
if (ipe == null && create) { |
|
|
|
ipe = createFileStructureNode(getFilename(handle)); |
|
|
|
} |
|
|
|
if (ipe != null) { |
|
|
|
cache(handle,ipe); |
|
|
|
cache(handle, ipe); |
|
|
|
} |
|
|
|
return ipe; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private IProgramElement findElementForHandle(IProgramElement parent, String handle) { |
|
|
|
for (Iterator it = parent.getChildren().iterator(); it.hasNext(); ) { |
|
|
|
IProgramElement node = (IProgramElement)it.next(); |
|
|
|
for (Iterator it = parent.getChildren().iterator(); it.hasNext();) { |
|
|
|
IProgramElement node = (IProgramElement) it.next(); |
|
|
|
String nodeHid = node.getHandleIdentifier(); |
|
|
|
if (handle.equals(nodeHid)) { |
|
|
|
return node; |
|
|
|
} else { |
|
|
|
if (handle.startsWith(nodeHid)) { |
|
|
|
// it must be down here if it is anywhere |
|
|
|
IProgramElement childSearch = findElementForHandle(node,handle); |
|
|
|
if (childSearch != null) return childSearch; |
|
|
|
IProgramElement childSearch = findElementForHandle(node, handle); |
|
|
|
if (childSearch != null) |
|
|
|
return childSearch; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
// |
|
|
|
// private IProgramElement findElementForBytecodeInfo( |
|
|
|
// IProgramElement node, |
|
|
|
// String parentName, |
|
|
|
// String name, |
|
|
|
// String signature) { |
|
|
|
// for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { |
|
|
|
// IProgramElement curr = (IProgramElement)it.next(); |
|
|
|
// if (parentName.equals(curr.getParent().getBytecodeName()) |
|
|
|
// && name.equals(curr.getBytecodeName()) |
|
|
|
// && signature.equals(curr.getBytecodeSignature())) { |
|
|
|
// return node; |
|
|
|
// } else { |
|
|
|
// IProgramElement childSearch = findElementForBytecodeInfo(curr, parentName, name, signature); |
|
|
|
// if (childSearch != null) return childSearch; |
|
|
|
// } |
|
|
|
// } |
|
|
|
// return null; |
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
// |
|
|
|
// private IProgramElement findElementForBytecodeInfo( |
|
|
|
// IProgramElement node, |
|
|
|
// String parentName, |
|
|
|
// String name, |
|
|
|
// String signature) { |
|
|
|
// for (Iterator it = node.getChildren().iterator(); it.hasNext(); ) { |
|
|
|
// IProgramElement curr = (IProgramElement)it.next(); |
|
|
|
// if (parentName.equals(curr.getParent().getBytecodeName()) |
|
|
|
// && name.equals(curr.getBytecodeName()) |
|
|
|
// && signature.equals(curr.getBytecodeSignature())) { |
|
|
|
// return node; |
|
|
|
// } else { |
|
|
|
// IProgramElement childSearch = findElementForBytecodeInfo(curr, parentName, name, signature); |
|
|
|
// if (childSearch != null) return childSearch; |
|
|
|
// } |
|
|
|
// } |
|
|
|
// return null; |
|
|
|
// } |
|
|
|
|
|
|
|
protected void cache(String handle, IProgramElement pe) { |
|
|
|
if (!AsmManager.isCompletingTypeBindings()) { |
|
|
|
handleMap.put(handle,pe); |
|
|
|
handleMap.put(handle, pe); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void flushTypeMap() { |
|
|
|
typeMap.clear(); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
public void flushHandleMap() { |
|
|
|
handleMap.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
public void flushFileMap() { |
|
|
|
fileMap.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
// TODO rename this method ... it does more than just the handle map |
|
|
|
// TODO rename this method ... it does more than just the handle map |
|
|
|
public void updateHandleMap(Set deletedFiles) { |
|
|
|
// Only delete the entries we need to from the handle map - for performance reasons |
|
|
|
List forRemoval = new ArrayList(); |
|
|
|
Set k = handleMap.keySet(); |
|
|
|
for (Iterator iter = k.iterator(); iter.hasNext();) { |
|
|
|
String handle = (String) iter.next(); |
|
|
|
IProgramElement ipe = (IProgramElement)handleMap.get(handle); |
|
|
|
if (deletedFiles.contains(getCanonicalFilePath(ipe)))forRemoval.add(handle); |
|
|
|
IProgramElement ipe = (IProgramElement) handleMap.get(handle); |
|
|
|
if (deletedFiles.contains(getCanonicalFilePath(ipe))) |
|
|
|
forRemoval.add(handle); |
|
|
|
} |
|
|
|
for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { |
|
|
|
String handle = (String) iter.next(); |
|
|
@@ -430,8 +507,9 @@ public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
k = typeMap.keySet(); |
|
|
|
for (Iterator iter = k.iterator(); iter.hasNext();) { |
|
|
|
String typeName = (String) iter.next(); |
|
|
|
IProgramElement ipe = (IProgramElement)typeMap.get(typeName); |
|
|
|
if (deletedFiles.contains(getCanonicalFilePath(ipe))) forRemoval.add(typeName); |
|
|
|
IProgramElement ipe = (IProgramElement) typeMap.get(typeName); |
|
|
|
if (deletedFiles.contains(getCanonicalFilePath(ipe))) |
|
|
|
forRemoval.add(typeName); |
|
|
|
} |
|
|
|
for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { |
|
|
|
String typeName = (String) iter.next(); |
|
|
@@ -441,25 +519,25 @@ public class AspectJElementHierarchy implements IHierarchy { |
|
|
|
k = fileMap.keySet(); |
|
|
|
for (Iterator iter = k.iterator(); iter.hasNext();) { |
|
|
|
String filePath = (String) iter.next(); |
|
|
|
IProgramElement ipe = (IProgramElement)fileMap.get(filePath); |
|
|
|
if (deletedFiles.contains(getCanonicalFilePath(ipe))) forRemoval.add(filePath); |
|
|
|
IProgramElement ipe = (IProgramElement) fileMap.get(filePath); |
|
|
|
if (deletedFiles.contains(getCanonicalFilePath(ipe))) |
|
|
|
forRemoval.add(filePath); |
|
|
|
} |
|
|
|
for (Iterator iter = forRemoval.iterator(); iter.hasNext();) { |
|
|
|
String filePath = (String) iter.next(); |
|
|
|
fileMap.remove(filePath); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private String getFilename(String hid) { |
|
|
|
return AsmManager.getDefault().getHandleProvider().getFileForHandle(hid); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private String getCanonicalFilePath(IProgramElement ipe) { |
|
|
|
if (ipe.getSourceLocation() != null) { |
|
|
|
return AsmManager.getDefault().getCanonicalFilePath(ipe.getSourceLocation().getSourceFile()); |
|
|
|
return AsmManager.getDefault().getCanonicalFilePath(ipe.getSourceLocation().getSourceFile()); |
|
|
|
} |
|
|
|
return ""; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|