eclipse - 如何使用 Eclipse AST 深入了解 StringLiterals?

标签 eclipse rcp eclipse-jdt string-literals abstract-syntax-tree

我需要创建一个 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 文件以计算光标是否悬停在需要翻译的字符串上。

  • 将鼠标悬停在“你好”上什么都不做。
  • 将鼠标悬停在“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 节点获取表示源代码中位置 170 处的 StringLiteral 的 ASTNode(“Test.worldLabel”字符串)?

奖励问题:我选择了正确的解决方案吗?基于性能。


编辑: 好吧,这是我找到的解决方案:

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);
}

缝合好吗? 或者它是更简单的方法还是更高效的方法?

最佳答案

一种解决方案是根本不使用偏移逻辑。 您可以通过使用节点父检查来概括解决方案。

这是一个示例代码:

public boolean visit(StringLiteral stringLiteral) {

        // Check if parent is a method inovacation.
        if (stringLiteral.getParent().getNodeType() == ASTNode.METHOD_INVOCATION) {

              // get the parent method inovacation.
              MethodInvocation miNode = (MethodInvocation) stringLiteral.getParent();

              //To do: null and empty check on argument list.

              // Check if is the special method and this is the 1st argument
              if (miNode.getName().toString().equals("SpecialMethod")
                        && miNode.arguments().get(0).toString().equals(stringLiteral.toString())) {

                    System.out.println("Found it : " + stringLiteral.toString());
              }
        }

        return true;
    }

关于eclipse - 如何使用 Eclipse AST 深入了解 StringLiterals?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14955197/

相关文章:

C++ Eclipse CDT 如何添加gcc 4.6.3

java - jmenubar 下方的 Eclipse 图标

android - 我应该使用 "copy project into workspace"外部 Android 库还是使用默认根位置?

eclipse-rcp - 在 config.ini 属性 OSGI.bundles 中使用变量

java - 在 RCP TableViewer 中手动触发 CellEditor

eclipse-plugin - 重写节点后注释行消失

java - 如何使用 JDT 确定类是否具有注释(考虑类型层次结构)

c++ - C++ 中的 NI-VISA 库编程 - 超出范围错误

java - 没有检查规则的 CheckStyle API 使用

java - RCP GUI 使用什么类型的布局