Как получить строку и/или столбец из проанализированного источника Java из Eclipse JDT Parser со всех узлов?

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

Я пошел по документация API класса CompilationUnit, чтобы узнать методы getLineNumber(int position) и getColumnNumber(int position), которые, насколько я понимаю, могут помочь. параметр position — это не что иное, как то, что возвращает метод getStartPosition(), выполняя node.getStartPosition().

Теперь проблема заключается в том, что два метода получения строки и столбца в исходном файле не доступны для всех узлов. Например, узлов объявления методов их нет!

Как я могу получить такую ​​информацию обо всем дереве? Я знаю, что это не невозможно, так как я мог использовать синтаксические анализаторы для других языков, которые для каждого узла ast имели строку и связанный с ним столбец. Фактически, я считаю, что javaparser является одним из них для java, поскольку класс содержит атрибуты для строки и столбец жестко запрограммирован. Увидев Eclipse JDT, он показался мне гораздо более надежным, и, находясь там довольно долгое время, я был бы удивлен, что такую ​​информацию невозможно получить.

Редактировать: Опять же, проблема заключается в получении номера строки из вещей, отличных от единицы компиляции, которая появляется только в корне:

<type 'org.eclipse.jdt.core.dom.CompilationUnit'>
1
<type 'org.eclipse.jdt.core.dom.TypeDeclaration'>
<type 'org.eclipse.jdt.core.dom.Javadoc'>
<type 'org.eclipse.jdt.core.dom.TagElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>

Спасибо.


person Oeufcoque Penteano    schedule 11.08.2012    source источник


Ответы (2)


Для потомков я публикую ответ, который я разместил в списке рассылки jdt-core-dev. (Мой ответ не сильно отличается от предложения Райана выше)

Привет Карлос,

Вы правы в отношении метода CompilationUnit.getLineNumber(int). Вы используете его следующим образом:

int lineNumber = compilationUnit.getLineNumber(node.getStartPosition()) - 1;

Однако я не понимаю, где вы застряли. Зачем вам нужен getLineNumber(..), определенный для MethodDeclaration? Все, что вам нужно сделать, это найти узел объявления метода, затем найти для него соответствующий CompilationUnit, используя приведенный ниже код, а затем использовать приведенную выше строку кода, чтобы найти номер строки. Я что-то упустил здесь?

ASTParser parser = ASTParser.newParser(AST.JLS3); // or JLS_4 for java 7 and above

parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(source); // give your java source here as char array
parser.setResolveBindings(true);

CompilationUnit compilationUnit = parser.createAST(null);

Ваше здоровье! Аюш

person Ayushman    schedule 17.08.2012
comment
Спасибо, я не осознавал, что CU был связан с данным java-файлом, и поэтому было бы разумно иметь информацию о позиции строки для узла ast, относящегося к этому файлу. Я больше привык к мысленной модели, в которой каждый узел будет иметь связанную строку и столбец, которым он принадлежит, потому что это была единственная модель, которую я видел вокруг. Все сводится к способу определения обязанностей класса, и этот новый не имел смысла. Теперь все запускается и работает. Я проголосовал и установил ваш ответ как ответ, так как я понял это из вашего ответа. - person Oeufcoque Penteano; 17.08.2012

У меня нет работающей программы передо мной, но на основе документации, на которую вы ссылались выше, и исходного кода в Eclipse, кажется, что вы можете получить CompilationUnit для ASTNode, вызвав getRoot() и приведя его к CompilationUnit. Кроме того, он появляется из ASTParser javadoc и пример на ibm, ASTParser.createAST(IProgressMonitor) почти всегда возвращает CompilationUnit, представляющий исходный код, который вы анализируете.

После того, как у вас будет CompilationUnit с именем root, вы сможете использовать методы root.getLineNumber(node.getStartPosition()) и root.getColumnNumber(node.getStartPosition()).

final ASTParser p = ASTParser.newParser(AST.JLS3);
p.setSource(source);
final CompilationUnit root = (CompilationUnit) p.createAST(null);
// stuff happens
final ASTNode node = //get a node

final int line = root.getLineNumber(node.getStartPosition());
final int column = root.getColumnNumber(node.getStartPosition());
System.out.println("Node started at (" + line + ", " + column + ")";
person Ryan Ransford    schedule 17.08.2012
comment
Спасибо, я проголосовал за ответ, так как он также последователен. Проголосовал за другой как окончательный ответ, потому что он помог мне осознать разницу в моей ментальной модели того, как подходить к проблеме. Отметил это в комментарии к другому ответу. - person Oeufcoque Penteano; 17.08.2012