Поля IF для всех переменных из CompilationUnit

#java #abstract-syntax-tree #eclipse-jdt

#java #абстрактное синтаксическое дерево #eclipse-jdt

Вопрос:

Мне нужно получить ссылки на IField или IJavaElement для всех переменных в моем исходном коде. Я использую плагин, получаю ICompilationUnit, из которого я могу читать все объекты верхнего уровня, используя:

для(IJavaElement i:unit.getTypes ()[0].getChildren() )

или

для(IJavaElement i:unit.getAllTypes () )

Как я могу получить доступ к локальным переменным? Я пытался разобрать ICompilationUnit в CompilationUnit, где я могу получить ASTNode каждого поля, но затем я не могу преобразовать его в IField. Есть идеи?

//редактировать: Например: для класса:

тест публичного класса {

int global1; int global2; void a() { global1 = 4; int local1; int local2 = 5; }

}

Я вызываю

для (тип IType: unit.GetTypes()) { System.out.println(«itype » type); для (IField IField : type.GetFields()) { System.out.println(«IField» IField); }}

И результат таков:

введите тест класса [в [рабочей копии] Test.java [в [в src [в testowy]]]] int global1 int global2 аннулирует a() IField int global1 [в тесте [в [Рабочей копии] Test.java [в [в src [в testowy]]]]] IField int global2 [в тесте [в [Рабочей копии] Test.java [в [в src [в testowy]]]]]

Таким образом, локальные переменные не были найдены…

// добавлено — все еще испытываю трудности: на самом деле это не то поведение, которого я ожидал.

 for( IMethod i:unit.getAllTypes()[0].getMethods() )
        {
        System.out.println("index to h:" h " type " i.getSource() " name: " i.getElementName());
        h  ;
        int o =0;
        for( IJavaElement j: i.getChildren() )
            {
                System.out.println("index to o: " o j " type " j.getElementType() " name: " j.getElementName());
                o  ;
            }

        }
  

Я ожидал, что этот код найдет все методы (которые работают) и получит все локальные переменные из методов (которые не работают). Он никогда не входит в цикл с полями. Он печатает объявление функции правильно, поэтому я уверен, что он видит все переменные…

А что касается использования индексов, я могу посещать все узлы, но как я могу изменить тип с Node на IField / IJavaElement, который мне нужен?

Спасибо 🙂

Ответ №1:

Если вы просто хотите получить поля определенного типа, вы можете сделать это следующим образом:

 for (IType type : iCompilationUnit.getTypes()) {
    for (IField iField : type.getFields()) {
        ....
    }
}
  

Однако, если вы хотите найти все объявления переменных (как полей, так и локальных переменных), вам лучше использовать ASTVisitor. Это приведет к посещению всего вашего AST, и вам просто нужно будет реализовать методы visit для желаемых элементов AST, в вашем случае, я думаю, это будет переменная declarationfragment ‘s.

Комментарии:

1. Спасибо за советы :). К сожалению, это не работает. Он по-прежнему обращается только к глобальным переменным. Я добавил больше деталей к своему вопросу.

2. Это ожидаемое поведение, это не IField ‘s. Также добавлена дополнительная информация к ответу.