文字列リテラルの上にマウスを置くとツールチップを表示するEclipseプラグインを作成する必要があります。ただし、その文字列リテラルが特別なメソッドの最初のパラメーターである場合に限ります。
プラグインのテストに使用する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ファイルをコンパイルして、カーソルが翻訳する必要のある文字列にカーソルを合わせているかどうかを計算する必要があります。
- 「Hello」にカーソルを合わせると何も起こりません。
- 「Test.worldLabel」にカーソルを合わせると、そのリテラルがTranslator.get()メソッド呼び出しに含まれているため、ツールチップが表示されます。
最初はこれを使用しました(170は「Test.worldLabel」内にあります):
ITypeRoot typeRoot = (ITypeRoot)
JavaUI.getEditorInputJavaElement(editorPart.getEditorInput());
JavaElement foundElement = (JavaElement) typeRoot.getElementAt(170);
ただし、foundElementにはmain()メソッド全体が含まれています。十分にきめ細かいものではありません。
次に、正しい方法は、私が思うに:
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);
そして今、ここに私の質問があります:
このastノードから、ソースコード(「Test.worldLabel」文字列)の位置170にあるStringLiteralを表すASTNodeを取得するにはどうすればよいですか?
ボーナスの質問:私は正しい解決策を選びましたか?パフォーマンスベース。
編集: まあ、ここに私が見つけた解決策があります:
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);
}
縫い目は大丈夫ですか?それとも、より簡単な方法ですか、それともよりパフォーマンスの高い方法ですか?