IntelliJ插件开发从PsiAnnotationMemberValue获取实际对象

时间:2016-08-03 05:21:24

标签: java intellij-idea intellij-plugin

好吧,所以在我正在处理的插件中,我需要获取传递给注释的参数值。我在#idea-users freenode频道上获得了解决方案,因为我应该将PsiAnnotationMemberValue转换为PsiLiteral,并调用getValue()。虽然这适用于原语,以及像Strings这样的东西,但现在我正在尝试获得自定义的枚举值。当我尝试这样做时,我的代码抛出了一个ClassCastException,并显示以下错误消息:

java.lang.ClassCastException: com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl cannot be cast to com.intellij.psi.PsiLiteral

代码:

@Override
public boolean eventIgnoresCancelled(PsiMethod method) {

    PsiLiteral literal = null;

    for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
        if(annotation.getQualifiedName().contains("IsCancelled")) {
            literal = ((PsiLiteral) annotation.findAttributeValue("value"));
        }
    }

    if(literal == null || literal.getValue() == null) {
        return false;
    }
    Object tristateValue = literal.getValue();
    try {
        String name = (String) tristateValue.getClass().getMethod("name").invoke(tristateValue);
        return name.equalsIgnoreCase("TRUE") || name.equalsIgnoreCase("UNDEFINED");
    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
        e.printStackTrace();
    }
    return false;
}

1 个答案:

答案 0 :(得分:1)

您的代码不应该假设所有注释值都是文字,它们也可以是.class表达式,数组,其他注释等。以及引用。 IDEA的PSI对你的枚举一无所知,但是给定一个PsiReferenceExpression注释值,你可以检查它的名字(getReferenceName()),甚至可以解析()并获得同样具有getName()方法的实际枚举常量。并且,从异常中可以看出,您已经拥有PsiReferenceExpression对象,所以除了PsiLiteral之外,请处理这种情况。