#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. Также добавлена дополнительная информация к ответу.