How to capture changes inside methods in an Eclipse plugin

家住魔仙堡 提交于 2019-12-06 14:01:02

After a somewhat rigorous investigation, I've concluded that it is impossible to capture changes inside methods without AST-related information. Thus, I've looked for the most efficient way to store the bare minimum of information needed as well as for the most suitable approach to comparing this information.

Here is the solution that I've come up and according to a couple of days of testing it seems to be efficient enough to be feasible to execute during every single 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;
                    }
                });
            }
        }
    }
}

Comments are most welcome!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!