summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraclement <aclement>2009-01-05 21:42:49 +0000
committeraclement <aclement>2009-01-05 21:42:49 +0000
commitd8011d6238c919468419918a902ceb33b8f7cb95 (patch)
tree1aabdb1c2e3c5badd80cd177cd1d3e48a4d2e4fd
parent7972815e3c844e097bf401745ca1d6a4c5672063 (diff)
downloadaspectj-d8011d6238c919468419918a902ceb33b8f7cb95.tar.gz
aspectj-d8011d6238c919468419918a902ceb33b8f7cb95.zip
259649: smarter model lookup
-rw-r--r--asm/src/org/aspectj/asm/IProgramElement.java3
-rw-r--r--asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java96
2 files changed, 86 insertions, 13 deletions
diff --git a/asm/src/org/aspectj/asm/IProgramElement.java b/asm/src/org/aspectj/asm/IProgramElement.java
index b67c84f2d..ede81c720 100644
--- a/asm/src/org/aspectj/asm/IProgramElement.java
+++ b/asm/src/org/aspectj/asm/IProgramElement.java
@@ -366,6 +366,9 @@ public interface IProgramElement extends Serializable {
public boolean isSourceFile() {
return this == FILE_ASPECTJ || this == FILE_JAVA;
}
+ public boolean isFile() {
+ return this == FILE;
+ }
public boolean isDeclare() {
return name.startsWith("declare");
diff --git a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java
index 5443e759f..63066ba38 100644
--- a/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java
+++ b/asm/src/org/aspectj/asm/internal/AspectJElementHierarchy.java
@@ -324,11 +324,49 @@ public class AspectJElementHierarchy implements IHierarchy {
*/
public IProgramElement findElementForSourceLine(String sourceFilePath, int lineNumber) {
String canonicalSFP = asm.getCanonicalFilePath(new File(sourceFilePath));
- IProgramElement node = findNodeForSourceLineHelper(root, canonicalSFP, lineNumber, -1);
- if (node != null) {
+ // Used to do this:
+// IProgramElement node2 = findNodeForSourceLineHelper(root, canonicalSFP, lineNumber, -1);
+
+ // Find the relevant source file node first
+ IProgramElement node = findNodeForSourceFile(root, canonicalSFP);
+ if (node == null) {
+ return createFileStructureNode(sourceFilePath);
+ }
+
+ // Check if there is a more accurate child node of that source file node:
+ IProgramElement closernode = findCloserMatchForLineNumber(node, lineNumber);
+ if (closernode == null) {
return node;
} else {
- return createFileStructureNode(sourceFilePath);
+ return closernode;
+ }
+ }
+
+ /**
+ * Discover the node representing a particular source file.
+ *
+ * @param node where in the model to start looking (usually the root on the initial call)
+ * @param sourcefilePath the source file being searched for
+ * @return the node representing that source file or null if it cannot be found
+ */
+ private IProgramElement findNodeForSourceFile(IProgramElement node, String sourcefilePath) {
+ // 1. why is <root> a sourcefile node?
+ // 2. should isSourceFile() return true for a FILE that is a .class file...?
+ if ((node.getKind().isSourceFile() && !node.getName().equals("<root>")) || node.getKind().isFile()) {
+ ISourceLocation nodeLoc = node.getSourceLocation();
+ if (nodeLoc != null && nodeLoc.getSourceFile().getAbsolutePath().equals(sourcefilePath)) {
+ return node;
+ }
+ return null; // no need to search children of a source file node
+ } else {
+ // check the children
+ for (Iterator iterator = node.getChildren().iterator(); iterator.hasNext();) {
+ IProgramElement foundit = findNodeForSourceFile((IProgramElement) iterator.next(), sourcefilePath);
+ if (foundit != null) {
+ return foundit;
+ }
+ }
+ return null;
}
}
@@ -363,17 +401,48 @@ public class AspectJElementHierarchy implements IHierarchy {
return fileNode;
}
- private IProgramElement findNodeForSourceLineHelper(IProgramElement node, String sourceFilePath, int lineNumber, int offSet) {
- if (matches(node, sourceFilePath, lineNumber, offSet) && !hasMoreSpecificChild(node, sourceFilePath, lineNumber, offSet)) {
+ /**
+ * For a specified node, check if any of the children more accurately represent the specified line.
+ *
+ * @param node where to start looking
+ * @param lineno the line number
+ * @return any closer match below 'node' or null if nothing is a more accurate match
+ */
+ private IProgramElement findCloserMatchForLineNumber(IProgramElement node, int lineno) {
+ for (Iterator childrenIter = node.getChildren().iterator(); childrenIter.hasNext();) {
+ IProgramElement child = (IProgramElement) childrenIter.next();
+ ISourceLocation childLoc = child.getSourceLocation();
+ if (childLoc != null) {
+ if (childLoc.getLine() <= lineno && childLoc.getEndLine() >= lineno) {
+ // This child is a better match for that line number
+ IProgramElement evenCloserMatch = findCloserMatchForLineNumber(child, lineno);
+ if (evenCloserMatch == null) {
+ return child;
+ } else {
+ return evenCloserMatch;
+ }
+ } else if (child.getKind().isType()) { // types are a bit clueless about where they are... do other nodes have similar problems??
+ IProgramElement evenCloserMatch = findCloserMatchForLineNumber(child, lineno);
+ if (evenCloserMatch != null) {
+ return evenCloserMatch;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private IProgramElement findNodeForSourceLineHelper(IProgramElement node, String sourceFilePath, int lineno, int offset) {
+ if (matches(node, sourceFilePath, lineno, offset) && !hasMoreSpecificChild(node, sourceFilePath, lineno, offset)) {
return node;
}
- if (node != null && node.getChildren() != null) {
+ if (node != null) {
for (Iterator it = node.getChildren().iterator(); it.hasNext();) {
- IProgramElement foundNode = findNodeForSourceLineHelper((IProgramElement) it.next(), sourceFilePath, lineNumber,
- offSet);
- if (foundNode != null)
+ IProgramElement foundNode = findNodeForSourceLineHelper((IProgramElement) it.next(), sourceFilePath, lineno, offset);
+ if (foundNode != null) {
return foundNode;
+ }
}
}
@@ -387,11 +456,12 @@ public class AspectJElementHierarchy implements IHierarchy {
// sourceFilePath + "\n2: " +
// node.getSourceLocation().getSourceFile().getCanonicalPath().equals(sourceFilePath)
// );
+ ISourceLocation nodeSourceLocation = (node != null ? node.getSourceLocation() : null);
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
+ && nodeSourceLocation != null
+ && nodeSourceLocation.getSourceFile().getAbsolutePath().equals(sourceFilePath)
+ && ((offSet != -1 && nodeSourceLocation.getOffset() == offSet) || offSet == -1)
+ && ((nodeSourceLocation.getLine() <= lineNumber && nodeSourceLocation.getEndLine() >= lineNumber) || (lineNumber <= 1 && node
.getKind().isSourceFile()));
// } catch (IOException ioe) {
// return false;