Разрешить тип в контексте

#java #eclipse-jdt #spoon #javaparser #javasymbolsolver

#java #eclipse-jdt #ложка #javaparser #javasymbolsolver

Вопрос:

У меня есть проект Spring boot, и я хочу проанализировать его и записать зависимости между классами. Я использую JavaSymbolSolver, чтобы узнать имя класса

  public static void main(String[] args) throws Exception {

        Set<Map<String, Set<String>>> entries = new HashSet<>();
        String jdkPath = "/usr/lib/jvm/java-11-openjdk-amd64/";
        List<File> projectFiles = FileHandler.readJavaFiles(new File("/home/dell/MySpace/Tekit/soon-back/src/main"));
        CombinedTypeSolver combinedSolver = new CombinedTypeSolver
                (
                        new JavaParserTypeSolver(new File("/home/dell/MySpace/Tekit/soon-back/src/main/java/")),
                        new JavaParserTypeSolver(new File(jdkPath)),
                        new ReflectionTypeSolver()
                );

        JavaSymbolSolver symbolSolver = new JavaSymbolSolver(combinedSolver);
        StaticJavaParser.getConfiguration().setSymbolResolver(symbolSolver);
        CompilationUnit cu = null;

        try {
            cu = StaticJavaParser.parse(projectFiles.get(7));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        List<ClassOrInterfaceDeclaration> classes = new ArrayList<>();
        TypeDeclarationImp typeDeclarationImp = new TypeDeclarationImp();
        typeDeclarationImp.visit(cu, classes);
        Set<String> collect = classes.stream()
                .map(classOrInterfaceDeclaration -> {
                    List<MethodCallExpr> collection = new ArrayList<>();
                    MethodInvocationImp methodInvocationImp = new MethodInvocationImp();
                    classOrInterfaceDeclaration.accept(methodInvocationImp, collection);
                    return collection;
                })
                .flatMap(Collection::stream)
                .map(methodCallExpr -> {
                    return methodCallExpr
                            .getScope()
                            .stream()
                            .filter(Expression::isNameExpr)
                            .map(Expression::calculateResolvedType)
                            .map(ResolvedType::asReferenceType)
                            .map(ResolvedReferenceType::getQualifiedName)
                            .map(s -> s.split("\."))
                            .map(strings -> strings[strings.length - 1])
                            .collect(Collectors.toSet());
                })
                .filter(expressions -> expressions.size() != 0)
                .flatMap(Collection::stream)
                .collect(Collectors.toSet());
        collect.forEach(System.out::println);
    }

  

Я сталкиваюсь с этой проблемой

 Exception in thread "main" UnsolvedSymbolException{context='SecurityContextHolder', name='Solving SecurityContextHolder', cause='null'}
  
  • не могли бы вы сказать мне, необходимо ли указывать все библиотеки, используемые проектом для его анализа, или для этого есть другой способ

Комментарии:

1. Я решил проблему, предоставив все зависимости проекта, когда кто-либо хочет использовать JavaParser, обязательно необходимо предоставить все библиотеки, от которых зависит проект (подготовка контекста для выполнения символов решения) еще один намек, что вам нужен скомпилированный проект без каких-либо ошибок, иначе проект не будет проанализирован

Ответ №1:

Это не совсем правильно. Если вы хотите только пройти AST, вам не нужно предоставлять зависимости проекта, но если вы хотите, например, узнать тип переменной, вы должны использовать решатель символов и объявить все зависимости проекта от него. Кроме того, Javaparser может восстанавливаться после ошибки синтаксического анализа (см. https://matozoid.github.io/2017/06/11/parse-error-recovery.html )