Мне нужно создать плагин Eclipse, который отображает всплывающую подсказку, когда я наводил указатель мыши на строковый литерал. Но только если этот строковый литерал является первым параметром специального метода.Как перейти к StringLiterals с Eclipse AST?
Вот файл Test.java я использую, чтобы проверить мой плагин:
package test;
public class Test {
public static void main(String[] args) {
String hello = "Hello";
String world = Translator.get("Test.worldLabel");
System.out.println(hello + " " + world);
}
}
Я создал класс, реализующий IJavaEditorTextHover и мне нужно скомпилировать редактируемый файл Java, чтобы вычислить, если курсор парит строку который должен быть переведен или нет.
- Наведение "Привет" ничего не сделает.
- Наведение «Test.worldLabel» отображает мою подсказку, потому что этот литерал включен внутри вызова метода Translator.get().
Сначала я использовал это (170 внутри "Test.worldLabel"):
ITypeRoot typeRoot = (ITypeRoot)
JavaUI.getEditorInputJavaElement(editorPart.getEditorInput());
JavaElement foundElement = (JavaElement) typeRoot.getElementAt(170);
Но foundElement содержит метод весь основной(): это не достаточно мелкозернистая.
Тогда правильный путь, я думаю:
private static ASTNode parse(ICompilationUnit unit, int position) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(unit);
parser.setResolveBindings(true);
parser.setIgnoreMethodBodies(false);
// TODO Future optimisation: parser.setFocalPosition(position);
return parser.createAST((IProgressMonitor) null); // parse
}
И в моем IJavaEditorTextHover.getHoverInfo реализации (...):
ICompilationUnit compilationUnit = (ICompilationUnit)
JavaUI.getEditorInputJavaElement(editor.getEditorInput())
int position = 170/*hoverRegion.getOffset()*/;
ASTNode ast = parse(compilationUnit, position);
И теперь, вот мой вопрос:
Как, с этого узла, я получаю ASTNode, выдающий StringLiteral в позиции 170 в исходном коде («Test.worldLabel» St кольцо)?
Бонус вопрос: я выбрал правильное решение? На основе результатов.
Edit: Ну, вот решение, которое я нашел:
private StringLiteral findStringLiteralAtPosition(final ASTNode parent, final int position) {
final List<StringLiteral> stringLiterals = new ArrayList<StringLiteral>();
parent.accept(new ASTVisitor() {
@Override
public boolean visit(StringLiteral stringLiteral) {
int start = stringLiteral.getStartPosition();
int end = start + stringLiteral.getLength();
if (start <= position && position <= end) {
stringLiterals.add(stringLiteral);
}
return super.visit(stringLiteral);
}
});
return (stringLiterals.size() > 0 ? stringLiterals.get(0) : null);
}
ли шов ОК? Или это более простой способ или более эффективный?