Получите квалифицированный тип из DeclaredType / TypeMirror с API Java doc - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть DeclaredType поля, и я хотел бы получить полностью определенный тип (необработанный тип?) Поля.Например, если поле имеет вид:

public static Optional<String> foo;

Я хотел бы получить java.util.Optional.

В настоящее время я могу получить имя пакета с помощью:

env.getElementUtils().getPackageOf(declaredType.asElement());

IЯ могу получить аргументы типа, однако я возвращаюсь к той же проблеме, и в итоге получаю List из TypeMirror, который я не знаю, как получить квалифицированное имя типов.

Я заметил, что я могу позвонить TypeMirror#toString(), и это вернет (для вышеупомянутого) что-то вроде:

java.util.Optional<java.lang.String>

Я думаю, я мог бы тогда вырезать все перед <, но это похоже нахак.

Для справки вот как я получаю поле:

private VariableElement getFieldWithName(DocletEnvironment environment, TypeElement classDoc, String fieldName) {
    for(VariableElement e : ElementFilter.fieldsIn(environment.getElementUtils().getAllMembers(classDoc))) {
        if(e.getSimpleName().toString().equals(fieldName)) {
            return e;
        }
    }
    return null;
}

TypeElement classElement = env.getElementUtils().getTypeElement(MyClass.class.getCanonicalName());
VariableElement fieldDoc = getFieldWithName(env, classElement, "foo");
DeclaredType declaredType = (DeclaredType) fieldDoc.asType();

Ответы [ 2 ]

0 голосов
/ 15 марта 2019

Чтобы преобразовать универсальный тип в исходную базу, разрешите его без аргументов типа.См. Types # getDeclaredType , которая может быть вызвана без указания каких-либо типов:

Если ноль и если элемент type является универсальным, то возвращается необработанный тип элемента type

DeclaredType rawType = env.getTypeUtils().getDeclaredType(typeElement);
0 голосов
/ 05 января 2019

Я протестировал этот код, и он работает на Apache Netbeans 10 и Jdk11.Используйте ((DeclaredType) variableElement.asType()).asElement().toString():

            DeclaredType declaredType = (DeclaredType) e.asType();//e is VariableElement from the loop
            fullyQualifiedName = declaredType.asElement().toString();

Классы тестирования:

class MyClass1 {
public static Optional<String> foo;
public static List<String> newList;
public static MyClass2 obj;
public Media media;
public void calculate(Double dl) {
}}

class MyClass2 extends MyClass1{
public static Color cl;
}

И реализация Doclet :

public class TestVarElement implements Doclet {

 public void testFields(DocletEnvironment env) {
    TypeElement typeElement = env.getElementUtils().getTypeElement(MyClass1.class.getCanonicalName());
    System.out.println("Test for 'foo': "+getFieldWithName(env,typeElement,"foo"));
    System.out.println("Test for 'newList': "+getFieldWithName(env,typeElement,"newList"));
    System.out.println("Test for 'obj': "+getFieldWithName(env,typeElement,"obj"));
    System.out.println("Test for 'media': "+getFieldWithName(env,typeElement,"media"));
}

    private String getFieldWithName(DocletEnvironment env, TypeElement classDoc, String fieldName) {
        String fullyQualifiedName = "";
        for (VariableElement e : ElementFilter.fieldsIn(env.getElementUtils().getAllMembers(classDoc))) {
            if (e.getSimpleName().toString().equals(fieldName)) {
                DeclaredType declaredType = (DeclaredType) e.asType(); //The type of the VariableElement
                fullyQualifiedName = declaredType.asElement().toString(); //Get the fqn 
                break;
            }
        }
        return fullyQualifiedName;
    }
   @Override
    public boolean run(DocletEnvironment docEnv) {
        testFields(docEnv);
        return true;
    }

    ... Other Overrids

    }

Отладка / ВыполнениеПрограмма:

     public class NewClass {
            public static void main(String[] args) {
                ToolProvider javadoc=ToolProvider.findFirst("javadoc").orElseThrow();
                int result=javadoc.run(System.out, System.err, new String[]{"-doclet",TestVarElement.class.getName(),"C:\\Users\\Super3\\Documents\\NetBeansProjects\\Myproject\\src\\pk\\TestVarElement.java"});

//The following is for java 8 or older, the implementation is diferent where `start` method is used instead of `run`.
     //Main.execute (new String[]{"-doclet",TestVarElement.class.getName(),"C:\\Users\\Super3\\Documents\\NetBeansProjects\\Myproject\\src\\pk\\TestVarElement.java"});
          }
        }

Вывод

Тест для 'foo': java.util.Optional

Тест для 'newList':java.util.List

Тест для 'obj': pk.MyClass2

Тест для 'media': javax.print.attribute.standard.Media

...