Как узнать, используется ли переменная-член в методе с использованием кода в eclipse jdt?

Мне нужно найти все методы в классе, которые используют определенную переменную-член. (например, «Ссылки» в eclipse, но я хочу реализовать с помощью кода...) Я использую шаблон посетителя AST, который посещает FieldDeclaration, чтобы получить имя и тип всех переменных-членов. Я также использую шаблон посетителя, который посещает узлы MethodDeclaration, чтобы получить содержимое каждого метода с помощью getBody(). Теперь у меня есть имя переменной поля, тип и сведения о методе-члене. Я думал, что могу использовать строковый поиск по содержимому каждого метода-члена, но для имени переменной «a» поиск может возвращать true для таких ключевых слов, как «класс» и других!!! Есть ли способ найти использование конкретной переменной, соответствующей fieldDeclaration?? (например, привязка или что-то в этом роде??) Если да, то что такое узел или класс AST?

Вот код, который я использовал...

 SimpleNameVisitor simpleNameVisitor=new SimpleNameVisitor();
 //SimpleNameVisitor is the visitor pattern for SimpleName
 simpleNameVisitor.process(mthd.getMethodBlock());
 //mthd is the object that stores method details
 for(SimpleName simpName:simpleNameVisitor.getIdentifiers()){
    if(varName.contentEquals(simpName.getFullyQualifiedName())){
        //varName is the field variable name
        System.out.println("MethodName: "+mthd.getName());
        return;
    }
  }

Вот код, который решил проблему (предложено wjans; изменено равно на contentEquals)

VariableDeclarationFragment fragment = ... ;
IBinding binding = fragment.getName().resolveBinding();


public boolean visitNode(SimpleName simpleName) throws Exception {
if (binding.toString().contentEquals(simpleName.resolveBinding().toString()) {
    ....
}

}


person Niranjani S    schedule 16.05.2011    source источник
comment
Итак, вы используете Eclipse в качестве плагина? Казалось бы, самое простое решение — посмотреть на существующий код Eclipse и сымитировать его. Если это не то, что вы делаете, возможно, вам следует вставить какой-нибудь код, чтобы люди поняли ваш вопрос.   -  person Anon    schedule 16.05.2011


Ответы (3)


Вы можете сделать что-то вроде этого:

Сохраните ссылку на привязку вашего FieldDeclaration,

VariableDeclarationFragment fragment = ... ;
IBinding binding = fragment.getName().resolveBinding();

и используйте это, чтобы сравнить его с привязками при посещении SimpleName внутри вашего MethodDeclaration

public boolean visitNode(SimpleName simpleName) throws Exception {
    if (binding.equals(simpleName.resolveBinding()) {
        ....
    }
}   
person wjans    schedule 16.05.2011
comment
Спасибо за ссылку на SimpleName. Поскольку привязка находится в классе, я не могу найти метод, использующий SimpleName. Поэтому я использовал getFullyQualifiedName() для SimpleName, чтобы сравнить его с полем Variable Name из FieldDeclaration. - person Niranjani S; 16.05.2011
comment
Однако я обнаружил, что если есть два SimpleName с одинаковым именем, одно из которых отображается как переменная, а другое — как метод, оба учитываются как встречающиеся в методе. Я думаю, что связывание решит конфликт, но как найти метод, содержащий ссылку? - person Niranjani S; 16.05.2011
comment
Вы можете просто сравнить привязки SimpleName, они не будут совпадать, если это метод с тем же именем, что и ваше поле. Чтобы узнать, в каком методе вы находитесь, вы должны воспользоваться посещением АСТ. Просто оставьте/удалите ссылку на метод в visitNode/endVisitNode вашего MethodDeclaration. - person wjans; 17.05.2011

Чтобы реализовать что-то вроде Find References в коде, используйте JDT SearchEngine.

        SearchRequestor findMethod = new SearchRequestor() {
            @Override
            public void acceptSearchMatch(SearchMatch match) throws CoreException {
                // analyze search match.
            }
        };
        SearchEngine engine = new SearchEngine();
        IJavaSearchScope workspaceScope = SearchEngine
                .createWorkspaceScope();
        SearchPattern pattern = SearchPattern
                .createPattern(
                        "org.eclipse.e4.core.internal.contexts.EclipseContext.strategy",
                        IJavaSearchConstants.FIELD,
                        IJavaSearchConstants.REFERENCES,
                        SearchPattern.R_EXACT_MATCH);
        SearchParticipant[] participant = new SearchParticipant[] { SearchEngine
                .getDefaultSearchParticipant() };
        engine.search(pattern, participant, workspaceScope, findMethod,
                new NullProgressMonitor());

См. http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_int_core.htm для получения дополнительных сведений о поиске Java, модели Java и AST.

См. https://bugs.eclipse.org/bugs/attachment.cgi?id=192205 для примера, который использует поиск, а затем просматривает результаты, создавая AST.

person Paul Webster    schedule 16.05.2011
comment
Спасибо за ваш код... Однако я хотел бы реализовать его с помощью AST. - person Niranjani S; 16.05.2011

Посетите все SimpleNames в теле каждого метода в вашем классе:

public boolean visit(SimpleName node) {

    IBinding binding = node.resolveBinding();

    if (binding instanceof IVariableBinding) {

        IVariableBinding variable = (IVariableBinding) binding;

        if (variable.isField())

            //do whatever you wanna do with the field
            System.out.println("field: " + node.toString());

    }

    return super.visit(node);
}
person EmGi    schedule 07.05.2014