From 2d13c962a7c233c8911a3f988fe8098e8841bc5b Mon Sep 17 00:00:00 2001 From: Alexander Lepekhin Date: Sun, 15 Jun 2025 12:33:31 +0300 Subject: [PATCH 1/2] process build.gradle --- src/main/java/org/javacs/InferConfig.java | 104 ++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/main/java/org/javacs/InferConfig.java b/src/main/java/org/javacs/InferConfig.java index 8cc004c55..6bf74a642 100644 --- a/src/main/java/org/javacs/InferConfig.java +++ b/src/main/java/org/javacs/InferConfig.java @@ -13,6 +13,7 @@ import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.stream.Stream; +import java.util.regex.*; class InferConfig { private static final Logger LOG = Logger.getLogger("main"); @@ -72,6 +73,17 @@ Set classPath() { return mvnDependencies(pomXml, "dependency:list"); } + // Gradle + try { + createPomFromBuildGradle(); + var pom = workspaceRoot.resolve("./jls/pom.xml"); + if (Files.exists(pom)) { + return mvnDependencies(pom, "dependency:sources"); + } + } catch (IOException e) { + LOG.warning(e.getMessage()); + } + // Bazel var bazelWorkspaceRoot = bazelWorkspaceRoot(); if (Files.exists(bazelWorkspaceRoot.resolve("WORKSPACE"))) { @@ -113,6 +125,17 @@ Set buildDocPath() { return mvnDependencies(pomXml, "dependency:sources"); } + // Gradle + try { + createPomFromBuildGradle(); + var pom = workspaceRoot.resolve("./jls/pom.xml"); + if (Files.exists(pom)) { + return mvnDependencies(pom, "dependency:sources"); + } + } catch (IOException e) { + LOG.warning(e.getMessage()); + } + // Bazel var bazelWorkspaceRoot = bazelWorkspaceRoot(); if (Files.exists(bazelWorkspaceRoot.resolve("WORKSPACE"))) { @@ -497,5 +520,86 @@ private static Path fork(Path workspaceRoot, String[] command) { } } + private void createPomFromBuildGradle() throws IOException { + Path gradleFilePath = Paths.get("build.gradle"); + Path pomFileName = Paths.get("pom.xml"); + Path pomDirectory = Paths.get(".jls"); + + List dependencies = new ArrayList<>(); + List testDependencies = new ArrayList<>(); + + List lines = Files.readAllLines(gradleFilePath); + + // Pattern for implementation dependencies + Pattern implPattern = Pattern.compile("implementation[\\s*\\(,\\(platform\\(]*['\"](.*?:)(.*?)(:.*?)['\"]"); + // Pattern for testImplementation dependencies + Pattern testImplPattern = Pattern.compile("testImplementation[\\s*,\\(,\\(platform\\(]*['\"](.*?:)(.*?)(:.*?)?['\"]"); + + for (String line : lines) { + System.out.println(line); + Matcher m = implPattern.matcher(line); + if (m.find()) { + dependencies.add(new Dependency(m.group(1), m.group(2), m.group(3))); + } + m = testImplPattern.matcher(line); + if (m.find()) { + testDependencies.add(new Dependency(m.group(1), m.group(2), m.group(3))); + } + } + + // Generate basic pom.xml + StringBuilder pom = new StringBuilder(); + pom.append("\n"); + pom.append("\n"); + pom.append(" 4.0.0\n"); + + // Placeholder project info + pom.append(" com.example\n"); + pom.append(" my-app\n"); + pom.append(" 1.0-SNAPSHOT\n"); + + if (!dependencies.isEmpty() || !testDependencies.isEmpty()) { + pom.append(" \n"); + + for (Dependency dep : dependencies) { + pom.append(" \n"); + pom.append(" ").append(dep.groupId.replace(":", "")).append("\n"); + pom.append(" ").append(dep.artifactId).append("\n"); + if (dep.version != null) { + pom.append(" ").append(dep.version.replace(":", "")).append("\n"); + } + pom.append(" \n"); + } + + for (Dependency dep : testDependencies) { + pom.append(" \n"); + pom.append(" ").append(dep.groupId.replace(":", "")).append("\n"); + pom.append(" ").append(dep.artifactId).append("\n"); + if (dep.version != null) { + pom.append(" ").append(dep.version.replace(":", "")).append("\n"); + } + pom.append(" test\n"); + pom.append(" \n"); + } + + pom.append(" \n"); + } + + pom.append("\n"); + + // Write to pom.xml + if (!Files.exists(pomDirectory)) { + Files.createDirectory(pomDirectory); + } + Files.write(pomDirectory.resolve(pomFileName), pom.toString().getBytes()); + + } + + record Dependency(String groupId, String artifactId, String version){} + + private static final Path NOT_FOUND = Paths.get(""); } From 3d1f5b6bfe30614e5b50ff213959fda62e0f6068 Mon Sep 17 00:00:00 2001 From: Alexander Lepekhin Date: Sun, 15 Jun 2025 17:13:43 +0300 Subject: [PATCH 2/2] type pomm added --- src/main/java/org/javacs/InferConfig.java | 209 +++++++++++++++------- 1 file changed, 142 insertions(+), 67 deletions(-) diff --git a/src/main/java/org/javacs/InferConfig.java b/src/main/java/org/javacs/InferConfig.java index 6bf74a642..046638a56 100644 --- a/src/main/java/org/javacs/InferConfig.java +++ b/src/main/java/org/javacs/InferConfig.java @@ -3,6 +3,7 @@ import com.google.devtools.build.lib.analysis.AnalysisProtos; import com.google.devtools.build.lib.analysis.AnalysisProtosV2; import com.google.devtools.build.lib.analysis.AnalysisProtosV2.PathFragment; + import java.io.File; import java.io.IOException; import java.nio.file.FileSystems; @@ -11,23 +12,30 @@ import java.nio.file.Paths; import java.util.*; import java.util.logging.Logger; +import java.util.regex.*; import java.util.regex.Pattern; import java.util.stream.Stream; -import java.util.regex.*; class InferConfig { private static final Logger LOG = Logger.getLogger("main"); /** Root of the workspace that is currently open in VSCode */ private final Path workspaceRoot; + /** External dependencies specified manually by the user */ private final Collection externalDependencies; + /** Location of the maven repository, usually ~/.m2 */ private final Path mavenHome; + /** Location of the gradle cache, usually ~/.gradle */ private final Path gradleHome; - InferConfig(Path workspaceRoot, Collection externalDependencies, Path mavenHome, Path gradleHome) { + InferConfig( + Path workspaceRoot, + Collection externalDependencies, + Path mavenHome, + Path gradleHome) { this.workspaceRoot = workspaceRoot; this.externalDependencies = externalDependencies; this.mavenHome = mavenHome; @@ -50,36 +58,48 @@ private static Path defaultGradleHome() { return Paths.get(System.getProperty("user.home")).resolve(".gradle"); } - /** Find .jar files for external dependencies, for examples maven dependencies in ~/.m2 or jars in bazel-genfiles */ + /** + * Find .jar files for external dependencies, for examples maven dependencies in ~/.m2 or jars + * in bazel-genfiles + */ Set classPath() { + var result = new HashSet(); // externalDependencies if (!externalDependencies.isEmpty()) { - var result = new HashSet(); for (var id : externalDependencies) { var a = Artifact.parse(id); var found = findAnyJar(a, false); if (found == NOT_FOUND) { - LOG.warning(String.format("Couldn't find jar for %s in %s or %s", a, mavenHome, gradleHome)); + LOG.warning( + String.format( + "Couldn't find jar for %s in %s or %s", + a, mavenHome, gradleHome)); continue; } result.add(found); } - return result; + //return result; } // Maven var pomXml = workspaceRoot.resolve("pom.xml"); if (Files.exists(pomXml)) { - return mvnDependencies(pomXml, "dependency:list"); + var deps = mvnDependencies(pomXml, "dependency:list"); + result.addAll(deps); + LOG.warning("IIIIIIIIIIIIIIIIIIIIIIIIII pom deps size "+deps.size()); } // Gradle try { createPomFromBuildGradle(); - var pom = workspaceRoot.resolve("./jls/pom.xml"); + var pom = workspaceRoot.resolve(".jls/pom.xml"); + LOG.warning("IIIIIIIIIIIIIIIIIIIIIIIIII pom ??? "+pom); if (Files.exists(pom)) { - return mvnDependencies(pom, "dependency:sources"); + var deps = mvnDependencies(pom, "dependency:list"); + LOG.warning("IIIIIIIIIIIIIIIIIIIIIIIIII jls depssize "+deps.size()); + result.addAll(deps); } + LOG.warning("IIIIIIIIIIIIIIIIIIIIIIIIII result "+result.size()); } catch (IOException e) { LOG.warning(e.getMessage()); } @@ -87,10 +107,11 @@ Set classPath() { // Bazel var bazelWorkspaceRoot = bazelWorkspaceRoot(); if (Files.exists(bazelWorkspaceRoot.resolve("WORKSPACE"))) { - return bazelClasspath(bazelWorkspaceRoot); + result.addAll(bazelClasspath(bazelWorkspaceRoot)); } - return Collections.emptySet(); + LOG.warning("total dependencies size: " + result.size()); + return result; } private Path bazelWorkspaceRoot() { @@ -104,33 +125,36 @@ private Path bazelWorkspaceRoot() { /** Find source .jar files in local maven repository. */ Set buildDocPath() { + var result = new HashSet(); // externalDependencies if (!externalDependencies.isEmpty()) { - var result = new HashSet(); for (var id : externalDependencies) { var a = Artifact.parse(id); var found = findAnyJar(a, true); if (found == NOT_FOUND) { - LOG.warning(String.format("Couldn't find doc jar for %s in %s or %s", a, mavenHome, gradleHome)); + LOG.warning( + String.format( + "Couldn't find doc jar for %s in %s or %s", + a, mavenHome, gradleHome)); continue; } result.add(found); } - return result; + //return result; } // Maven var pomXml = workspaceRoot.resolve("pom.xml"); if (Files.exists(pomXml)) { - return mvnDependencies(pomXml, "dependency:sources"); + result.addAll(mvnDependencies(pomXml, "dependency:sources")); } // Gradle try { createPomFromBuildGradle(); - var pom = workspaceRoot.resolve("./jls/pom.xml"); + var pom = workspaceRoot.resolve(".jls/pom.xml"); if (Files.exists(pom)) { - return mvnDependencies(pom, "dependency:sources"); + result.addAll(mvnDependencies(pom, "dependency:sources")); } } catch (IOException e) { LOG.warning(e.getMessage()); @@ -139,10 +163,11 @@ Set buildDocPath() { // Bazel var bazelWorkspaceRoot = bazelWorkspaceRoot(); if (Files.exists(bazelWorkspaceRoot.resolve("WORKSPACE"))) { - return bazelSourcepath(bazelWorkspaceRoot); + result.addAll(bazelSourcepath(bazelWorkspaceRoot)); } - return Collections.emptySet(); + LOG.warning("total doc paths size: " + result.size()); + return result; } private Path findAnyJar(Artifact artifact, boolean source) { @@ -169,7 +194,8 @@ Path findMavenJar(Artifact artifact, boolean source) { } private Path findGradleJar(Artifact artifact, boolean source) { - // Search for caches/modules-*/files-*/groupId/artifactId/version/*/artifactId-version[-sources].jar + // Search for + // caches/modules-*/files-*/groupId/artifactId/version/*/artifactId-version[-sources].jar var base = gradleHome.resolve("caches"); var pattern = "glob:" @@ -199,7 +225,8 @@ private String fileName(Artifact artifact, boolean source) { static Set mvnDependencies(Path pomXml, String goal) { Objects.requireNonNull(pomXml, "pom.xml path is null"); try { - // TODO consider using mvn valide dependency:copy-dependencies -DoutputDirectory=??? instead + // TODO consider using mvn valide dependency:copy-dependencies -DoutputDirectory=??? + // instead // Run maven as a subprocess String[] command = { getMvnCommand(), @@ -288,14 +315,21 @@ private Set bazelClasspath(Path bazelWorkspaceRoot) { // Add protos if (buildProtos(bazelWorkspaceRoot)) { - for (var relative : bazelAQuery(bazelWorkspaceRoot, "Javac", "--output", "proto_library")) { + for (var relative : + bazelAQuery(bazelWorkspaceRoot, "Javac", "--output", "proto_library")) { absolute.add(bazelWorkspaceRoot.resolve(relative)); } } // Add rest of classpath for (var relative : - bazelAQuery(bazelWorkspaceRoot, "Javac", "--classpath", "java_library", "java_test", "java_binary")) { + bazelAQuery( + bazelWorkspaceRoot, + "Javac", + "--classpath", + "java_library", + "java_test", + "java_binary")) { absolute.add(bazelWorkspaceRoot.resolve(relative)); } return absolute; @@ -306,13 +340,19 @@ private Set bazelSourcepath(Path bazelWorkspaceRoot) { var outputBase = bazelOutputBase(bazelWorkspaceRoot); for (var relative : bazelAQuery( - bazelWorkspaceRoot, "JavaSourceJar", "--sources", "java_library", "java_test", "java_binary")) { + bazelWorkspaceRoot, + "JavaSourceJar", + "--sources", + "java_library", + "java_test", + "java_binary")) { absolute.add(outputBase.resolve(relative)); } // Add proto source files if (buildProtos(bazelWorkspaceRoot)) { - for (var relative : bazelAQuery(bazelWorkspaceRoot, "Javac", "--source_jars", "proto_library")) { + for (var relative : + bazelAQuery(bazelWorkspaceRoot, "Javac", "--source_jars", "proto_library")) { absolute.add(bazelWorkspaceRoot.resolve(relative)); } } @@ -378,7 +418,10 @@ private Set readQueryResult(Path output) { } private Set bazelAQuery( - Path bazelWorkspaceRoot, String filterMnemonic, String filterArgument, String... kinds) { + Path bazelWorkspaceRoot, + String filterMnemonic, + String filterArgument, + String... kinds) { String kindUnion = ""; for (var kind : kinds) { if (kindUnion.length() > 0) { @@ -404,18 +447,22 @@ private Set bazelAQuery( private Set readActionGraph(Path output, String filterArgument) { try { - var containerV2 = AnalysisProtosV2.ActionGraphContainer.parseFrom(Files.newInputStream(output)); - if (containerV2.getArtifactsCount() != 0 && containerV2.getArtifactsList().get(0).getId() != 0) { + var containerV2 = + AnalysisProtosV2.ActionGraphContainer.parseFrom(Files.newInputStream(output)); + if (containerV2.getArtifactsCount() != 0 + && containerV2.getArtifactsList().get(0).getId() != 0) { return readActionGraphFromV2(containerV2, filterArgument); } - var containerV1 = AnalysisProtos.ActionGraphContainer.parseFrom(Files.newInputStream(output)); + var containerV1 = + AnalysisProtos.ActionGraphContainer.parseFrom(Files.newInputStream(output)); return readActionGraphFromV1(containerV1, filterArgument); } catch (IOException e) { throw new RuntimeException(e); } } - private Set readActionGraphFromV1(AnalysisProtos.ActionGraphContainer container, String filterArgument) { + private Set readActionGraphFromV1( + AnalysisProtos.ActionGraphContainer container, String filterArgument) { var argumentPaths = new HashSet(); var outputIds = new HashSet(); for (var action : container.getActionsList()) { @@ -450,7 +497,8 @@ private Set readActionGraphFromV1(AnalysisProtos.ActionGraphContainer co return artifactPaths; } - private Set readActionGraphFromV2(AnalysisProtosV2.ActionGraphContainer container, String filterArgument) { + private Set readActionGraphFromV2( + AnalysisProtosV2.ActionGraphContainer container, String filterArgument) { var argumentPaths = new HashSet(); var outputIds = new HashSet(); for (var action : container.getActionsList()) { @@ -474,7 +522,8 @@ private Set readActionGraphFromV2(AnalysisProtosV2.ActionGraphContainer // artifact is the output of another java action continue; } - var relative = buildPath(container.getPathFragmentsList(), artifact.getPathFragmentId()); + var relative = + buildPath(container.getPathFragmentsList(), artifact.getPathFragmentId()); if (!argumentPaths.contains(relative)) { // artifact was not specified by --filterArgument continue; @@ -526,24 +575,37 @@ private void createPomFromBuildGradle() throws IOException { Path pomDirectory = Paths.get(".jls"); List dependencies = new ArrayList<>(); - List testDependencies = new ArrayList<>(); + List platformDependencies = new ArrayList<>(); List lines = Files.readAllLines(gradleFilePath); // Pattern for implementation dependencies - Pattern implPattern = Pattern.compile("implementation[\\s*\\(,\\(platform\\(]*['\"](.*?:)(.*?)(:.*?)['\"]"); + Pattern implPattern = + Pattern.compile( + "implementation[\\s*\\(,\\(platform\\(]*['\"](.*?:)(.*?)(:.*?)['\"]"); // Pattern for testImplementation dependencies - Pattern testImplPattern = Pattern.compile("testImplementation[\\s*,\\(,\\(platform\\(]*['\"](.*?:)(.*?)(:.*?)?['\"]"); + Pattern testImplPattern = + Pattern.compile( + "testImplementation[\\s*,\\(,\\(platform\\(]*['\"](.*?:)(.*?)(:.*?)?['\"]"); for (String line : lines) { - System.out.println(line); Matcher m = implPattern.matcher(line); - if (m.find()) { - dependencies.add(new Dependency(m.group(1), m.group(2), m.group(3))); - } - m = testImplPattern.matcher(line); - if (m.find()) { - testDependencies.add(new Dependency(m.group(1), m.group(2), m.group(3))); + if (line.contains("platform")) { + if (m.find()) { + platformDependencies.add(new Dependency(m.group(1), m.group(2), m.group(3), false)); + } + m = testImplPattern.matcher(line); + if (m.find()) { + platformDependencies.add(new Dependency(m.group(1), m.group(2), m.group(3), true)); + } + } else { + if (m.find()) { + dependencies.add(new Dependency(m.group(1), m.group(2), m.group(3), false)); + } + m = testImplPattern.matcher(line); + if (m.find()) { + dependencies.add(new Dependency(m.group(1), m.group(2), m.group(3), true)); + } } } @@ -561,33 +623,48 @@ private void createPomFromBuildGradle() throws IOException { pom.append(" my-app\n"); pom.append(" 1.0-SNAPSHOT\n"); - if (!dependencies.isEmpty() || !testDependencies.isEmpty()) { - pom.append(" \n"); - - for (Dependency dep : dependencies) { - pom.append(" \n"); - pom.append(" ").append(dep.groupId.replace(":", "")).append("\n"); - pom.append(" ").append(dep.artifactId).append("\n"); - if (dep.version != null) { - pom.append(" ").append(dep.version.replace(":", "")).append("\n"); - } - pom.append(" \n"); + pom.append(" \n"); + pom.append(" \n"); + for (Dependency dep : platformDependencies) { + pom.append(" \n"); + pom.append(" ") + .append(dep.groupId.replace(":", "")) + .append("\n"); + pom.append(" ").append(dep.artifactId).append("\n"); + if (dep.version != null) { + pom.append(" ") + .append(dep.version.replace(":", "")) + .append("\n"); } - - for (Dependency dep : testDependencies) { - pom.append(" \n"); - pom.append(" ").append(dep.groupId.replace(":", "")).append("\n"); - pom.append(" ").append(dep.artifactId).append("\n"); - if (dep.version != null) { - pom.append(" ").append(dep.version.replace(":", "")).append("\n"); - } + pom.append(" pom\n"); + if (dep.isTest) { + pom.append(" test\n"); + } + pom.append(" \n"); + } + pom.append(" \n"); + pom.append(" \n"); + pom.append(" \n"); + + for (Dependency dep : dependencies) { + pom.append(" \n"); + pom.append(" ") + .append(dep.groupId.replace(":", "")) + .append("\n"); + pom.append(" ").append(dep.artifactId).append("\n"); + if (dep.version != null) { + pom.append(" ") + .append(dep.version.replace(":", "")) + .append("\n"); + } + if (dep.isTest) { pom.append(" test\n"); - pom.append(" \n"); } - - pom.append(" \n"); + pom.append(" \n"); } + pom.append(" \n"); + pom.append("\n"); // Write to pom.xml @@ -595,11 +672,9 @@ private void createPomFromBuildGradle() throws IOException { Files.createDirectory(pomDirectory); } Files.write(pomDirectory.resolve(pomFileName), pom.toString().getBytes()); - } - record Dependency(String groupId, String artifactId, String version){} - + record Dependency(String groupId, String artifactId, String version, boolean isTest) {} private static final Path NOT_FOUND = Paths.get(""); }