Как получить полное имя класса Java

У меня есть класс, как показано ниже.

public class Login {
    private Keyword browser;
    private String page;
}

Keyword это класс в другой упаковке. Я хочу получить полное имя класса Keyword при разборе Login класс с использованием javaparser.

6 ответов

Вы можете использовать JavaParser Symbol Solver:

<dependency>
    <groupId>com.github.javaparser</groupId>
    <artifactId>javaparser-symbol-solver-core</artifactId>
    <version>3.14.5</version>
</dependency>

Затем проанализируйте код, используя следующую конфигурацию:

CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), 
                                                     new JavaParserTypeSolver(sourceRoot));
final ParserConfiguration config = new ParserConfiguration()
                .setStoreTokens(true)
                .setSymbolResolver(new JavaSymbolSolver(combinedTypeSolver));
SourceRoot root = new SourceRoot(Paths.get("/path/to/project/"));
root.parse("", config, (Path localPath, Path absolutePath, ParseResult<CompilationUnit> result) -> {
                // Do something with the CompilationUnit
                return Result.DONT_SAVE;
            });

Теперь мы можем получить полный идентификатор любого ReferenceType с помощью:

ResolvedType type = referenceType.resolve();
String qualifiedName = type.getQualifiedName();

Вы не можете сделать это с помощью JavaParser, потому что JavaParser не разрешает символы. Чтобы преобразовать имя Keyword в класс, вам нужно сделать несколько вещей: * реализовать правильные правила области видимости (вам нужно искать внутренние классы, затем другие классы в том же файле, а затем рассматривать импорт...) * это зависит от путь к классу, используемый для компиляции: изменение одного и того же класса может быть разрешено по-разному

Для этого должен быть написан решатель символов: это не тривиально, а выполнимо. Если вас интересует эта тема, вы можете прочитать пост, который я только что написал Как создать решатель символов для Java в Clojure. Пост содержит также ссылку на код, свободно доступный на GitHub.

Источник: я участник JavaParser

Я написал метод, который может получить полное имя на основе ClassOrInterfaceDeclaration объект (последняя версия JavaParser):

    private static String getFullyQualifiedName(ClassOrInterfaceDeclaration c2) {
        String name = "";
        ClassOrInterfaceDeclaration parentClass = c2.getParentNode().isPresent() ? getClass(c2.getParentNode().get()): null;
        if(parentClass!=null) {
            name+=getFullyQualifiedName(parentClass)+".";
        } else {
            CompilationUnit u = getCompilationUnit(c2);
            if(u!=null && u.getPackageDeclaration().isPresent()) {
                name+=u.getPackageDeclaration().get().getNameAsString()+".";
            }
        }
        return name+c2.getNameAsString();
    }

    private static ClassOrInterfaceDeclaration getClass(Node n1) {
        while (!(n1 instanceof ClassOrInterfaceDeclaration)) {
            if(n1.getParentNode().isPresent()) {
                n1 = n1.getParentNode().get();
            } else return null;
        }
        return (ClassOrInterfaceDeclaration)n1;
    }

    private static CompilationUnit getCompilationUnit(Node n1) {
        while (!(n1 instanceof CompilationUnit)) {
            if(n1.getParentNode().isPresent()) {
                n1 = n1.getParentNode().get();
            } else return null;
        }
        return (CompilationUnit)n1;
    }

Гораздо более простая версия может быть использована, если вы получите ClassOrInterfaceType класса:

    private static String getFullyQualifiedName(ClassOrInterfaceType e) {
        String name = "";
        if(e.getScope().isPresent())
            name+=getFullyQualifiedName(e.getScope().get())+".";
        return name+e.getNameAsString();
    }

Я надеюсь, что это поможет всем!

Никто до сих пор, похоже, не читал вопрос, но если вы анализируете исходный код, либо он находится в текущем пакете, либо он импортируется оператором импорта.

Я бы ожидал, что писатель или пользователь синтаксического анализатора Java будет знать это.

JavaParser не разрешает импорт (в любом случае это обычно не считается его работой). Вы должны вручную пройти через операторы импорта и искать, если Keyword принадлежит им. Имейте в виду, что Java неявно делает import java.lang.*в противном случае вы не будете разрешать такие типы, как String,

Spring Roo имеет класс JavaParserUtils, содержащий метод getJavaType(CompilationUnitServices compilationUnitServices, ClassOrInterfaceDeclaration cid), Класс не предназначен для использования вне Roo, но вы можете использовать его как шаблон для решения вашей проблемы.

Если вы используете посетителей, кажется, что вы получаете только начальный и конечный индексы в исходном файле для того, чтобы иметь имя типа. Это не даст вам полное имя.

Таким образом, вы должны реализовать visit(ImportDeclaration, A) Метод также в ваш пользовательский посетитель. Затем этот метод должен хранить объявления импорта, чтобы вы могли позже - когда метод visit(FieldDeclaration, A) вызывается - обратитесь к импортированным пакетам и соберите полное имя.

Это может быть лучшим решением для вашей проблемы,

используя экземпляр.

Использование "Экземпляра" в Java

Используйте Отражение Java (java.lang.reflect)

Другие вопросы по тегам