ある程度厳密な調査を行った結果、AST 関連の情報がなければ、メソッド内の変更をキャプチャすることは不可能であるという結論に達しました。したがって、必要最小限の情報を保存する最も効率的な方法と、この情報を比較するための最も適切な方法を探してきました。
これが私が思いついた解決策であり、数日間のテストによると、すべての実行中に実行できるほど効率的であるようElementChangedEvent
です。
// during each user-invoked-compile, these are processed and cleared
private static HashMap<String, IMethod> added = new HashMap<String, IMethod>();
private static HashMap<String, IMethod> changed = new HashMap<String, IMethod>();
private static HashMap<String, IMethod> removed = new HashMap<String, IMethod>();
// this persists through out the entire session
private static HashMap<String, ASTNode> subtrees = new HashMap<String, ASTNode>();
private static void attachModelPart() {
JavaCore.addElementChangedListener(new IElementChangedListener() {
@Override
public void elementChanged(ElementChangedEvent event) {
... // added and removed IMethod handling
IJavaElementDelta delta = event.getDelta();
if (delta.getElement() instanceof CompilationUnit) {
delta.getCompilationUnitAST().accept(new ASTVisitor() {
@Override
public boolean visit(MethodDeclaration node) {
String mName = ((TypeDeclaration) node.getParent()).getName()
.getFullyQualifiedName() + "." + node.getName().getFullyQualifiedName();
// Finding match for this methods name(mName) in saved method subtrees...
boolean methodHasChanged = false;
if (subtrees.containsKey(mName)) {
// Found match
// Comparing new subtree to one saved during an earlier event (using ASTNode.subtreeMatch())
methodHasChanged = !node.subtreeMatch(new ASTMatcher(), subtrees.get(mName));
} else {
// No earlier entry found, definitely changed
methodHasChanged = true;
}
if (methodHasChanged) {
// "changed" is a HashMap of IMethods that have been earlierly identified as changed
// "added" works similarly but for added methods (using IJavaElementDelta.getAddedChildren())
if (!changed.containsKey(mName) && !added.containsKey(mName)) {
// Method has indeed changed and is not yet queued for further actions
changed.put(mName, (IMethod) node.resolveBinding().getJavaElement());
}
}
// "subtrees" must be updated with every method's AST subtree in order for this to work
subtrees.put(mName, node);
// continue visiting after first MethodDeclaration
return true;
}
});
}
}
}
}
コメント大歓迎です!