From 923a4f85fd45998d7adca9d2ff2759cd0f8e3b83 Mon Sep 17 00:00:00 2001 From: heowc Date: Sun, 17 Nov 2024 11:37:17 +0900 Subject: [PATCH] fix: java class parsing failed --- .../java/dev/heowc/heo/cli/HeoCliService.java | 10 ++-- .../java/dev/heowc/heo/core/ParserConfig.java | 30 ++++++++++++ .../analysis/domain/DependencyMapper.java | 49 ++++++++++--------- .../heo/core/loader/ModuleLoaderConfig.java | 4 ++ .../application/ModuleLoaderService.java | 17 +++++-- .../heo/core/loader/domain/ModuleLoader.java | 23 ++++++--- 6 files changed, 97 insertions(+), 36 deletions(-) create mode 100644 heo-core/src/main/java/dev/heowc/heo/core/ParserConfig.java create mode 100644 heo-core/src/main/java/dev/heowc/heo/core/loader/ModuleLoaderConfig.java diff --git a/heo-cli/src/main/java/dev/heowc/heo/cli/HeoCliService.java b/heo-cli/src/main/java/dev/heowc/heo/cli/HeoCliService.java index 757823c..452fc7f 100644 --- a/heo-cli/src/main/java/dev/heowc/heo/cli/HeoCliService.java +++ b/heo-cli/src/main/java/dev/heowc/heo/cli/HeoCliService.java @@ -2,13 +2,13 @@ import java.util.List; -import dev.heowc.heo.core.HeoException; - import org.springframework.stereotype.Service; +import dev.heowc.heo.core.HeoException; import dev.heowc.heo.core.Module; import dev.heowc.heo.core.analysis.application.DependencyAnalysisService; import dev.heowc.heo.core.analysis.domain.DependencyAnalysisResult; +import dev.heowc.heo.core.loader.ModuleLoaderConfig; import dev.heowc.heo.core.loader.application.ModuleLoaderService; import dev.heowc.heo.core.reporting.AnalysisReportService; import dev.heowc.heo.core.visualization.ReportVisualizationService; @@ -32,7 +32,7 @@ public HeoCliService(ModuleLoaderService moduleLoaderService, } public void command(String directory, String rootPackage, String destination, HeoConfig heoConfig) { - final List modules = moduleLoaderService.loads(directory, rootPackage); + final List modules = moduleLoaderService.loads(createConfig(directory, rootPackage)); final DependencyAnalysisResult result = dependencyAnalysisService.analyzeProjectDependencies(modules, rootPackage); final String report = analysisReportService.createReport(result); @@ -41,4 +41,8 @@ public void command(String directory, String rootPackage, String destination, He throw new HeoException("Cycles occurred"); } } + + private static ModuleLoaderConfig createConfig(String directory, String rootPackage) { + return new ModuleLoaderConfig(directory, rootPackage); + } } diff --git a/heo-core/src/main/java/dev/heowc/heo/core/ParserConfig.java b/heo-core/src/main/java/dev/heowc/heo/core/ParserConfig.java new file mode 100644 index 0000000..6e3a524 --- /dev/null +++ b/heo-core/src/main/java/dev/heowc/heo/core/ParserConfig.java @@ -0,0 +1,30 @@ +package dev.heowc.heo.core; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParserConfiguration; +import com.github.javaparser.ParserConfiguration.LanguageLevel; +import com.github.javaparser.utils.ParserCollectionStrategy; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +class ParserConfig { + + @Bean + ParserConfiguration parserConfiguration() { + final ParserConfiguration configuration = new ParserConfiguration(); + configuration.setLanguageLevel(LanguageLevel.JAVA_17); + return configuration; + } + + @Bean + ParserCollectionStrategy parserCollectionStrategy(ParserConfiguration parserConfiguration) { + return new ParserCollectionStrategy(parserConfiguration); + } + + @Bean + JavaParser javaParser(ParserConfiguration parserConfiguration) { + return new JavaParser(parserConfiguration); + } +} diff --git a/heo-core/src/main/java/dev/heowc/heo/core/analysis/domain/DependencyMapper.java b/heo-core/src/main/java/dev/heowc/heo/core/analysis/domain/DependencyMapper.java index 9953ea7..b1ce114 100644 --- a/heo-core/src/main/java/dev/heowc/heo/core/analysis/domain/DependencyMapper.java +++ b/heo-core/src/main/java/dev/heowc/heo/core/analysis/domain/DependencyMapper.java @@ -13,12 +13,13 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.github.javaparser.JavaParser; import com.github.javaparser.ParseResult; import com.github.javaparser.ParseStart; import com.github.javaparser.Providers; -import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.ImportDeclaration; import com.github.javaparser.ast.nodeTypes.NodeWithName; @@ -28,18 +29,11 @@ @DomainService public class DependencyMapper { - private final JavaParser javaParser = new JavaParser(); + private final Logger logger = LoggerFactory.getLogger(DependencyMapper.class); + private final JavaParser javaParser; - private static String toGroupId(GroupIdProvider groupIdProvider, String rootPackage, Module module) { - return groupIdProvider.groupId(rootPackage, module); - } - - private static BinaryOperator> merge() { - return (deps, deps2) -> { - final Set merged = new HashSet<>(deps); - merged.addAll(deps2); - return merged; - }; + public DependencyMapper(JavaParser javaParser) { + this.javaParser = javaParser; } public DomainGraph mapDependencies(List modules, String rootPackage) { @@ -48,16 +42,29 @@ public DomainGraph mapDependencies(List modules, String rootPackage) { final Map moduleGroup = modules.stream() .collect(Collectors.toUnmodifiableMap(Module::getIdentity, Function.identity())); - final Map> result = modules.stream() - .map(it -> toDependentModule(rootPackage, it, moduleGroup, - groupIdProvider)) - .collect(Collectors.toUnmodifiableMap(Pair::getKey, - Pair::getValue, merge())); + final Map> result = + modules.stream() + .map(it -> toDependentModule(rootPackage, it, moduleGroup, groupIdProvider)) + .peek(it -> logger.debug("module={}, dependent={}", + it.getKey(), it.getValue())) + .collect(Collectors.toUnmodifiableMap(Pair::getKey, Pair::getValue, merge())); graph.addVertex(result); graph.addEdge(result); return graph; } + private static String toGroupId(GroupIdProvider groupIdProvider, String rootPackage, Module module) { + return groupIdProvider.groupId(rootPackage, module); + } + + private static BinaryOperator> merge() { + return (deps, deps2) -> { + final Set merged = new HashSet<>(deps); + merged.addAll(deps2); + return merged; + }; + } + private Pair> toDependentModule(String rootPackage, Module module, Map moduleGroup, @@ -83,17 +90,15 @@ private DependentModule createDependentModule(Module module, Map private Stream parseImports(Module module) { try { - final ParseResult parsed = - javaParser.parse(ParseStart.COMPILATION_UNIT, + final ParseResult parsed = + javaParser.parse(ParseStart.IMPORT_DECLARATION, Providers.provider(module.getPath(), javaParser.getParserConfiguration().getCharacterEncoding())); if (!parsed.isSuccessful()) { return Stream.empty(); } - return parsed.getResult().orElseThrow() - .getImports() - .stream(); + return parsed.getResult().stream(); } catch (IOException e) { return Stream.empty(); } diff --git a/heo-core/src/main/java/dev/heowc/heo/core/loader/ModuleLoaderConfig.java b/heo-core/src/main/java/dev/heowc/heo/core/loader/ModuleLoaderConfig.java new file mode 100644 index 0000000..6170714 --- /dev/null +++ b/heo-core/src/main/java/dev/heowc/heo/core/loader/ModuleLoaderConfig.java @@ -0,0 +1,4 @@ +package dev.heowc.heo.core.loader; + +public record ModuleLoaderConfig(String projectDirectory, String rootPackage) { +} diff --git a/heo-core/src/main/java/dev/heowc/heo/core/loader/application/ModuleLoaderService.java b/heo-core/src/main/java/dev/heowc/heo/core/loader/application/ModuleLoaderService.java index b1dddb5..f11474e 100644 --- a/heo-core/src/main/java/dev/heowc/heo/core/loader/application/ModuleLoaderService.java +++ b/heo-core/src/main/java/dev/heowc/heo/core/loader/application/ModuleLoaderService.java @@ -1,5 +1,9 @@ package dev.heowc.heo.core.loader.application; +import com.github.javaparser.utils.ParserCollectionStrategy; + +import dev.heowc.heo.core.loader.ModuleLoaderConfig; + import java.io.IOException; import java.io.UncheckedIOException; import java.util.List; @@ -15,13 +19,18 @@ public class ModuleLoaderService { private final Logger logger = LoggerFactory.getLogger(ModuleLoaderService.class); + private final ParserCollectionStrategy parserCollectionStrategy; + + public ModuleLoaderService(ParserCollectionStrategy parserCollectionStrategy) { + this.parserCollectionStrategy = parserCollectionStrategy; + } - public List loads(String projectDirectory, String rootPackage) { + public List loads(ModuleLoaderConfig config) { try { - logger.info("Loading " + rootPackage + " from " + projectDirectory); - return new ModuleLoader(projectDirectory, rootPackage).loadModules(); + logger.info("Loading " + config.rootPackage() + " from " + config.projectDirectory()); + return new ModuleLoader(config, parserCollectionStrategy).loadModules(); } catch (IOException e) { - logger.error("Error while loading " + rootPackage + " from " + projectDirectory, e); + logger.error("Error while loading " + config.rootPackage() + " from " + config.projectDirectory(), e); throw new UncheckedIOException(e); } } diff --git a/heo-core/src/main/java/dev/heowc/heo/core/loader/domain/ModuleLoader.java b/heo-core/src/main/java/dev/heowc/heo/core/loader/domain/ModuleLoader.java index 1b9b2e2..199da82 100644 --- a/heo-core/src/main/java/dev/heowc/heo/core/loader/domain/ModuleLoader.java +++ b/heo-core/src/main/java/dev/heowc/heo/core/loader/domain/ModuleLoader.java @@ -5,6 +5,9 @@ import java.util.List; import java.util.stream.Stream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.github.javaparser.ParseResult; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.utils.ParserCollectionStrategy; @@ -12,9 +15,7 @@ import com.github.javaparser.utils.SourceRoot; import dev.heowc.heo.core.Module; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import dev.heowc.heo.core.loader.ModuleLoaderConfig; public class ModuleLoader { @@ -22,21 +23,29 @@ public class ModuleLoader { private final Path projectPath; private final String rootPackage; + private final ParserCollectionStrategy parserCollectionStrategy; + + public ModuleLoader(ModuleLoaderConfig config, ParserCollectionStrategy parserCollectionStrategy) { + this.projectPath = Path.of(config.projectDirectory()).toAbsolutePath(); + this.rootPackage = config.rootPackage(); + this.parserCollectionStrategy = parserCollectionStrategy; + } public ModuleLoader(String projectDirectory, String rootPackage) { - this.projectPath = Path.of(projectDirectory).toAbsolutePath(); - this.rootPackage = rootPackage; + this(new ModuleLoaderConfig(projectDirectory, rootPackage), + new ParserCollectionStrategy()); } public List loadModules() throws IOException { - final ProjectRoot projectRoot = new ParserCollectionStrategy().collect(projectPath); + final ProjectRoot projectRoot = parserCollectionStrategy.collect(projectPath); return projectRoot.getSourceRoots() .stream() .filter(ModuleLoader::ignoreNonMainSourceRoot) - .peek(it -> logger.info("Detected module (file://{})", it.getRoot())) + .peek(it -> logger.info("Detected source (file://{})", it.getRoot())) .flatMap(this::tryParseSources) .filter(it -> ignoreFile(it.getStorage().orElseThrow().getPath())) .map(ModuleLoader::extractModule) + .peek(it -> logger.debug("Extract module ({})", it)) .toList(); }