Gradle project Boot upgrade support

This commit is contained in:
aboyko
2023-05-26 19:45:37 -04:00
parent 93231e2f59
commit bd37fbcd2b
33 changed files with 1232 additions and 498 deletions

View File

@@ -504,40 +504,59 @@
<iterate>
<or>
<adapt
type="org.eclipse.core.resources.IResource">
type="org.eclipse.core.resources.IFile">
<and>
<test
forcePluginActivation="true"
property="org.springsource.ide.eclipse.boot.isBootResource">
</test>
<or>
<test
property="org.eclipse.core.resources.name"
value="pom.xml">
</test>
<adapt
type="org.eclipse.core.resources.IProject">
<and>
<test
property="org.eclipse.core.resources.path"
value="/*/pom.xml">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.m2e.core.maven2Nature">
</test>
</adapt>
</and>
<and>
<test
property="org.eclipse.core.resources.path"
value="/*/build.gradle">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.buildship.core.gradleprojectnature">
</test>
</and>
</or>
</and>
</adapt>
<adapt
type="org.eclipse.core.resources.IProject">
<and>
<test
forcePluginActivation="true"
property="org.springsource.ide.eclipse.boot.isBootResource">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.jdt.core.javanature">
</test>
<or>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.m2e.core.maven2Nature">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.buildship.core.gradleprojectnature">
</test>
</or>
</and>
</adapt>
<and>
<instanceof
value="org.eclipse.jdt.core.IJavaProject">
</instanceof>
<test
property="org.springsource.ide.eclipse.commons.java.projectNature"
value="org.eclipse.m2e.core.maven2Nature">
</test>
<test
forcePluginActivation="true"
property="org.springsource.ide.eclipse.boot.javaelement.isBootProject">
</test>
</and>
</or>
</iterate>
<test
@@ -560,40 +579,59 @@
<iterate>
<or>
<adapt
type="org.eclipse.core.resources.IResource">
type="org.eclipse.core.resources.IFile">
<and>
<test
forcePluginActivation="true"
property="org.springsource.ide.eclipse.boot.isBootResource">
</test>
<or>
<test
property="org.eclipse.core.resources.name"
value="pom.xml">
</test>
<adapt
type="org.eclipse.core.resources.IProject">
<and>
<test
property="org.eclipse.core.resources.path"
value="/*/pom.xml">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.m2e.core.maven2Nature">
</test>
</adapt>
</and>
<and>
<test
property="org.eclipse.core.resources.path"
value="/*/build.gradle">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.buildship.core.gradleprojectnature">
</test>
</and>
</or>
</and>
</adapt>
<adapt
type="org.eclipse.core.resources.IProject">
<and>
<test
forcePluginActivation="true"
property="org.springsource.ide.eclipse.boot.isBootResource">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.jdt.core.javanature">
</test>
<or>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.m2e.core.maven2Nature">
</test>
<test
property="org.eclipse.core.resources.projectNature"
value="org.eclipse.buildship.core.gradleprojectnature">
</test>
</or>
</and>
</adapt>
<and>
<instanceof
value="org.eclipse.jdt.core.IJavaProject">
</instanceof>
<test
property="org.springsource.ide.eclipse.commons.java.projectNature"
value="org.eclipse.m2e.core.maven2Nature">
</test>
<test
forcePluginActivation="true"
property="org.springsource.ide.eclipse.boot.javaelement.isBootProject">
</test>
</and>
</or>
</iterate>
<test

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017 Pivotal, Inc.
* Copyright (c) 2017, 2023 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -77,7 +77,7 @@ public class GradleCore {
((DefaultGradleConnector) gradleConnector).daemonMaxIdleTime(1, TimeUnit.SECONDS);
configuration.configure(gradleConnector);
// Use patched Gradle 4.4 distribution or higher as a workaround for https://github.com/gradle/gradle/issues/2483
gradleConnector.useGradleVersion("7.3");
gradleConnector.useGradleVersion("7.6");
connection = gradleConnector.connect();
return connection.getModel(modelType);
} catch (GradleConnectionException e) {

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2019 Pivotal, Inc.
* Copyright (c) 2017, 2023 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13,13 +13,13 @@ package org.springframework.ide.vscode.commons.gradle;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
import org.gradle.tooling.model.build.BuildEnvironment;
import org.gradle.tooling.model.eclipse.EclipseExternalDependency;
import org.gradle.tooling.model.eclipse.EclipseProject;
import org.gradle.tooling.model.eclipse.EclipseProjectDependency;
import org.gradle.tooling.model.eclipse.EclipseSourceDirectory;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.JavaUtils;
@@ -98,8 +98,7 @@ public class GradleProjectClasspath implements IClasspath {
for (EclipseSourceDirectory sf : project.getSourceDirectories()) {
CPE cpe = createSourceCPE(project, sf);
cpe.setOwn(true);
// TODO: figure out how to differentiate source java folder from resources
cpe.setJavaContent(true);
cpe.setJavaContent(!Files.walk(sf.getDirectory().toPath()).filter(Files::isRegularFile).anyMatch(p -> !p.startsWith(".") && !p.getFileName().toString().endsWith(".java")));
boolean isTest = false;
try {
isTest = sf.getClasspathAttributes().stream().filter(attr -> "gradle_used_by_scope".equals(attr.getName()) && "test".equals(attr.getValue())).findFirst().isPresent();

View File

@@ -56,6 +56,16 @@
<artifactId>rewrite-maven</artifactId>
<version>${rewrite-version}</version>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
<artifactId>rewrite-groovy</artifactId>
<version>${rewrite-version}</version>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
<artifactId>rewrite-gradle</artifactId>
<version>${rewrite-version}</version>
</dependency>
<dependency>
<groupId>org.openrewrite</groupId>
<artifactId>rewrite-yaml</artifactId>
@@ -88,6 +98,48 @@
<version>${rewrite-spring-version}</version>
</dependency>
<dependency>
<groupId>org.openrewrite.gradle.tooling</groupId>
<artifactId>model</artifactId>
<version>${rewrite-gradle-tooling-api-version}</version>
</dependency>
<dependency>
<groupId>org.gradle</groupId>
<artifactId>gradle-tooling-api</artifactId>
<version>7.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-maven</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-gradle</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-maven</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>gradle-repo</id>
<name>Gradle Tooling Repo</name>
<url>https://repo.gradle.org/gradle/libs-releases</url>
</repository>
</repositories>
</project>

View File

@@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (c) 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.rewrite.gradle;
import static org.openrewrite.Tree.randomId;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Parser.Input;
import org.openrewrite.SourceFile;
import org.openrewrite.gradle.GradleParser;
import org.openrewrite.gradle.marker.GradleProject;
import org.openrewrite.gradle.toolingapi.OpenRewriteModel;
import org.openrewrite.gradle.toolingapi.OpenRewriteModelBuilder;
import org.openrewrite.groovy.GroovyParser;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.JavaParser.Builder;
import org.openrewrite.java.marker.JavaProject;
import org.openrewrite.java.marker.JavaVersion;
import org.openrewrite.marker.BuildTool;
import org.openrewrite.marker.Marker;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.rewrite.java.AbstractJavaProjectParser;
public class GradleIJavaProjectParser extends AbstractJavaProjectParser {
public GradleIJavaProjectParser(IJavaProject jp, Builder<?, ?> javaParserBuilder,
Function<Path, Input> parserInputProvider) {
super(jp, javaParserBuilder, parserInputProvider);
}
@Override
protected List<Marker> getJavaProvenance(SourceFile buildFileAst, Path projectDirectory) {
Optional<GradleProject> gradleProject = buildFileAst.getMarkers().findFirst(GradleProject.class);
String javaRuntimeVersion = System.getProperty("java.runtime.version");
String javaVendor = System.getProperty("java.vm.vendor");
String sourceCompatibility = javaRuntimeVersion;
String targetCompatibility = javaRuntimeVersion;
return Arrays.asList(
new BuildTool(randomId(), BuildTool.Type.Gradle, null),
new JavaVersion(randomId(), javaRuntimeVersion, javaVendor, sourceCompatibility, targetCompatibility),
new JavaProject(randomId(), gradleProject.map(g -> g.getName()).orElse(null), null/*new JavaProject.Publication(
mavenModel.getGroupId(),
mavenModel.getArtifactId(),
mavenModel.getVersion()*/
)
);
}
@Override
protected List<? extends SourceFile> parseBuildFiles(Path projectDir, ExecutionContext ctx) {
OpenRewriteModel openRewriteGradleModel = OpenRewriteModelBuilder.forProjectDirectory(projectDir.toFile(), Paths.get(jp.getProjectBuild().getBuildFile()).toFile());
GradleProject gradleProject = GradleProject.fromToolingModel(openRewriteGradleModel.gradleProject());
GradleParser gradleParser = GradleParser.builder().groovyParser(GroovyParser.builder()).build();
Path buildFilePath = Paths.get(jp.getProjectBuild().getBuildFile());
return ListUtils.map(
gradleParser.parseInputs(() ->
getInputs(Stream.of(buildFilePath)).iterator(), null, ctx), gb -> gb.withMarkers(gb.getMarkers().addIfAbsent(gradleProject))
);
}
}

View File

@@ -0,0 +1,116 @@
/*******************************************************************************
* Copyright (c) 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.rewrite.java;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openrewrite.Parser;
import org.openrewrite.Parser.Input;
import org.openrewrite.SourceFile;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaParser.Builder;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.protocol.java.Classpath;
import org.springframework.ide.vscode.commons.protocol.java.Classpath.CPE;
public abstract class AbstractJavaProjectParser extends ProjectParser {
private static String[] NON_JAVA_FILE_TYPES = new String[] { ".properties", ".xml", ".yml", ".yaml", ".factories" };
private static String JAVA_FILE_TYPE = ".java";
private static Predicate<CPE> MAIN_JAVA_CPE_FILTER = cpe -> Classpath.isSource(cpe) && cpe.isOwn() && cpe.isJavaContent() && !cpe.isTest();
private static Predicate<CPE> TEST_JAVA_CPE_FILTER = cpe -> Classpath.isSource(cpe) && cpe.isOwn() && cpe.isJavaContent() && cpe.isTest();
private static Predicate<CPE> MAIN_NON_JAVA_CPE_FILTER = cpe -> Classpath.isSource(cpe) && cpe.isOwn() && !cpe.isJavaContent() && !cpe.isTest();
private static Predicate<CPE> TEST_NON_JAVA_CPE_FILTER = cpe -> Classpath.isSource(cpe) && cpe.isOwn() && !cpe.isJavaContent() && cpe.isTest();
protected IJavaProject jp;
private Builder<?, ?> javaParserBuilder;
private Function<Path, Input> parserInputProvider;
protected AbstractJavaProjectParser(IJavaProject jp, JavaParser.Builder<?, ?> javaParserBuilder,
Function<Path, Parser.Input> parserInputProvider) {
this.jp = jp;
this.javaParserBuilder = javaParserBuilder;
this.parserInputProvider = parserInputProvider;
}
@Override
protected List<SourceSet> getSourceSets(Path projectDir, SourceFile buildFile) {
return List.of(
new SourceSet(
ProjectParser.MAIN,
getSources(MAIN_JAVA_CPE_FILTER, JAVA_FILE_TYPE),
getSources(MAIN_NON_JAVA_CPE_FILTER, NON_JAVA_FILE_TYPES),
IClasspathUtil.getBinaryRoots(jp.getClasspath(), cpe -> !cpe.isTest()).stream().map(f -> f.toPath()).collect(Collectors.toList())
),
new SourceSet(
ProjectParser.TEST,
getSources(TEST_JAVA_CPE_FILTER, JAVA_FILE_TYPE),
getSources(TEST_NON_JAVA_CPE_FILTER, NON_JAVA_FILE_TYPES),
IClasspathUtil.getBinaryRoots(jp.getClasspath(), cpe -> !cpe.isTest()).stream().map(f -> f.toPath()).collect(Collectors.toList())
)
);
}
private List<Path> getSources(Predicate<CPE> cpeFilter, String... fileTypes) {
BiPredicate<Path, java.nio.file.attribute.BasicFileAttributes> predicate = (p, bfa) -> bfa.isRegularFile()
&& Arrays.stream(fileTypes).anyMatch(type -> p.getFileName().toString().endsWith(type));
try {
return jp.getClasspath().getClasspathEntries().stream().filter(cpeFilter).flatMap(cpe -> {
try {
return Files.find(Paths.get(cpe.getPath()), 999, predicate);
} catch (IOException e) {
return Stream.empty();
}
}).collect(Collectors.toList());
} catch (Exception e) {
return Collections.emptyList();
}
}
@Override
protected Input createParserInput(Path p) {
Parser.Input in = null;
if (parserInputProvider != null) {
in = parserInputProvider.apply(p);
}
if (in == null) {
return super.createParserInput(p);
}
return in;
}
@Override
protected Builder<?, ?> getJavaParserBuilder() {
return javaParserBuilder;
}
}

View File

@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.rewrite.java;
import java.util.List;
import org.openrewrite.ExecutionContext;
import org.openrewrite.SourceFile;
import org.springframework.ide.vscode.commons.java.IJavaProject;
public interface IJavaProjectParser {
List<SourceFile> parse(IJavaProject project, ExecutionContext ctx);
}

View File

@@ -18,6 +18,7 @@ import java.nio.channels.ClosedByInterruptException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@@ -52,7 +53,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
import org.springframework.ide.vscode.commons.rewrite.maven.MavenProjectParser;
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
@@ -462,13 +462,13 @@ public class ORAstUtils {
public static String getSourceSetName(IJavaProject project, Path sourcePath) {
if (IClasspathUtil.getProjectTestJavaSources(project.getClasspath()).anyMatch(f -> sourcePath.startsWith(f.toPath()))) {
return MavenProjectParser.TEST;
return ProjectParser.TEST;
} else {
return MavenProjectParser.MAIN;
return ProjectParser.MAIN;
}
}
public static JavaSourceSet addJavaSourceSet(List<? extends SourceFile> sourceFiles, String sourceSetName, List<Path> classpath) {
public static JavaSourceSet addJavaSourceSet(List<? extends SourceFile> sourceFiles, String sourceSetName, Collection<Path> classpath) {
JavaSourceSet sourceSet = JavaSourceSet.build(sourceSetName, classpath, null, false);
List<JavaType.FullyQualified> types = sourceSet.getClasspath();
for (SourceFile sourceFile : sourceFiles) {

View File

@@ -0,0 +1,173 @@
/*******************************************************************************
* Copyright (c) 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.rewrite.java;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Parser;
import org.openrewrite.Parser.Input;
import org.openrewrite.SourceFile;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.marker.JavaSourceSet;
import org.openrewrite.java.tree.J.CompilationUnit;
import org.openrewrite.marker.Marker;
import org.openrewrite.properties.PropertiesParser;
import org.openrewrite.text.PlainTextParser;
import org.openrewrite.xml.XmlParser;
import org.openrewrite.yaml.YamlParser;
public abstract class ProjectParser {
public static final String MAIN = "main";
public static final String TEST = "test";
protected static record SourceSet(String name, Collection<Path> javaSources, Collection<Path> resources, Collection<Path> classpath) {};
public List<SourceFile> parse(Path projectDir, ExecutionContext ctx) {
List<? extends SourceFile> buildFiles = parseBuildFiles(projectDir, ctx);
List<SourceFile> sources = new ArrayList<>();
for (SourceFile buildFile : buildFiles) {
sources.addAll(parseModule(projectDir, buildFile, ctx));
}
return sources;
}
protected Collection<? extends SourceFile> parseModule(Path projectDir, SourceFile buildFile, ExecutionContext ctx) {
List<SourceFile> sources = new ArrayList<>();
List<Marker> projectProvenance = getJavaProvenance(buildFile, projectDir);
sources.add(addProjectProvenance(buildFile, projectProvenance));
for (SourceSet ss : getSourceSets(projectDir, buildFile)) {
JavaParser javaParser = getJavaParserBuilder().build();
Collection<Path> mainClasspath = ss.classpath();
javaParser.setClasspath(mainClasspath);
List<CompilationUnit> javaSources = ListUtils.map(javaParser.parseInputs(
() -> getInputs(ss.javaSources.stream()).iterator(), projectDir, ctx), addProvenance(projectProvenance));
JavaSourceSet javaSourceSet = ORAstUtils.addJavaSourceSet(javaSources, ss.name(),
mainClasspath);
sources.addAll(javaSources);
List<Input> resources = getInputs(ss.resources().stream()).collect(Collectors.toList());
parseResources(resources, projectDir, sources, projectProvenance, javaSourceSet, ctx);
}
return sources;
}
private void parseResources(List<Parser.Input> resources, Path projectDirectory, List<SourceFile> sourceFiles, List<Marker> projectProvenance, JavaSourceSet sourceSet, ExecutionContext ctx) {
List<Marker> provenance = new ArrayList<>(projectProvenance);
provenance.add(sourceSet);
sourceFiles.addAll(ListUtils.map(new XmlParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".xml") ||
p.getPath().getFileName().toString().endsWith(".wsdl") ||
p.getPath().getFileName().toString().endsWith(".xhtml") ||
p.getPath().getFileName().toString().endsWith(".xsd") ||
p.getPath().getFileName().toString().endsWith(".xsl") ||
p.getPath().getFileName().toString().endsWith(".xslt"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
sourceFiles.addAll(ListUtils.map(new YamlParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".yml") || p.getPath().getFileName().toString().endsWith(".yaml"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
sourceFiles.addAll(ListUtils.map(new PropertiesParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".properties"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
sourceFiles.addAll(ListUtils.map(new PlainTextParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".factories"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
}
private <S extends SourceFile> S addProjectProvenance(S s, List<Marker> projectProvenance) {
for (Marker marker : projectProvenance) {
s = s.withMarkers(s.getMarkers().addIfAbsent(marker));
}
return s;
}
private <S extends SourceFile> UnaryOperator<S> addProvenance(List<Marker> projectProvenance) {
return s -> {
if (projectProvenance != null) {
s = addProjectProvenance(s, projectProvenance);
}
return s;
};
}
protected JavaParser.Builder<?, ?> getJavaParserBuilder() {
return JavaParser.fromJavaVersion();
}
protected final Stream<Parser.Input> getInputs(Stream<Path> files) {
return files.map(p ->
new Parser.Input(p, () -> {
try {
return Files.newInputStream(p);
} catch (IOException e) {
return new ByteArrayInputStream(new byte[0]);
}
})
);
}
protected Parser.Input createParserInput(Path p) {
return new Parser.Input(p, () -> {
try {
return Files.newInputStream(p);
} catch (IOException e) {
return new ByteArrayInputStream(new byte[0]);
}
});
}
abstract protected List<Marker> getJavaProvenance(SourceFile buildFileAst, Path projectDirectory);
abstract protected List<? extends SourceFile> parseBuildFiles(Path projectDir, ExecutionContext ctx);
abstract protected Collection<SourceSet> getSourceSets(Path projectDir, SourceFile buildFile);
}

View File

@@ -0,0 +1,119 @@
/*******************************************************************************
* Copyright (c) 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.rewrite.maven;
import static org.openrewrite.Tree.randomId;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Parser.Input;
import org.openrewrite.SourceFile;
import org.openrewrite.java.JavaParser.Builder;
import org.openrewrite.java.marker.JavaProject;
import org.openrewrite.java.marker.JavaVersion;
import org.openrewrite.marker.BuildTool;
import org.openrewrite.marker.Marker;
import org.openrewrite.maven.MavenParser;
import org.openrewrite.maven.tree.MavenResolutionResult;
import org.openrewrite.maven.tree.ResolvedPom;
import org.openrewrite.xml.tree.Xml;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.rewrite.java.AbstractJavaProjectParser;
public class MavenIJavaProjectParser extends AbstractJavaProjectParser {
private static final Logger logger = LoggerFactory.getLogger(MavenIJavaProjectParser.class);
private static final Pattern mavenWrapperVersionPattern = Pattern.compile(".*apache-maven/(.*?)/.*");
private MavenParser.Builder mavenParserBuilder;
public MavenIJavaProjectParser(IJavaProject jp, Builder<?, ?> javaParserBuilder,
Function<Path, Input> parserInputProvider, MavenParser.Builder mavenParserBuilder) {
super(jp, javaParserBuilder, parserInputProvider);
this.mavenParserBuilder = mavenParserBuilder;
}
protected List<Marker> getJavaProvenance(SourceFile maven, Path projectDirectory) {
ResolvedPom mavenModel = getModel((Xml.Document) maven);
String javaRuntimeVersion = System.getProperty("java.runtime.version");
String javaVendor = System.getProperty("java.vm.vendor");
String sourceCompatibility = javaRuntimeVersion;
String targetCompatibility = javaRuntimeVersion;
String propertiesSourceCompatibility = mavenModel.getValue(mavenModel.getValue("maven.compiler.source"));
if (propertiesSourceCompatibility != null) {
sourceCompatibility = propertiesSourceCompatibility;
}
String propertiesTargetCompatibility = mavenModel.getValue(mavenModel.getValue("maven.compiler.target"));
if (propertiesTargetCompatibility != null) {
targetCompatibility = propertiesTargetCompatibility;
}
Path wrapperPropertiesPath = projectDirectory.resolve(".mvn/wrapper/maven-wrapper.properties");
String mavenVersion = "3.6";
if (Files.exists(wrapperPropertiesPath)) {
try {
Properties wrapperProperties = new Properties();
wrapperProperties.load(new FileReader(wrapperPropertiesPath.toFile()));
String distributionUrl = (String) wrapperProperties.get("distributionUrl");
if (distributionUrl != null) {
Matcher wrapperVersionMatcher = mavenWrapperVersionPattern.matcher(distributionUrl);
if (wrapperVersionMatcher.matches()) {
mavenVersion = wrapperVersionMatcher.group(1);
}
}
} catch (IOException e) {
logger.error("", e);
}
}
return Arrays.asList(
new BuildTool(randomId(), BuildTool.Type.Maven, mavenVersion),
new JavaVersion(randomId(), javaRuntimeVersion, javaVendor, sourceCompatibility, targetCompatibility),
new JavaProject(randomId(), mavenModel.getRequested().getName(), new JavaProject.Publication(
mavenModel.getGroupId(),
mavenModel.getArtifactId(),
mavenModel.getVersion()
))
);
}
@Override
protected List<? extends SourceFile> parseBuildFiles(Path projectDir, ExecutionContext ctx) {
MavenParser mavenParser = mavenParserBuilder.build();
return mavenParser.parseInputs(() -> getInputs(Stream.of(Paths.get(jp.getProjectBuild().getBuildFile()))).iterator(), projectDir, ctx);
}
private static ResolvedPom getModel(Xml.Document maven) {
MavenResolutionResult pom = getResolvedPom(maven);
return pom == null ? null : pom.getPom();
}
private static MavenResolutionResult getResolvedPom(Xml.Document maven) {
return maven.getMarkers().findFirst(MavenResolutionResult.class).orElse(null);
}
}

View File

@@ -1,389 +0,0 @@
/*******************************************************************************
* Copyright (c) 2022 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.rewrite.maven;
import static org.openrewrite.Tree.randomId;
import java.io.ByteArrayInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Parser;
import org.openrewrite.SourceFile;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.marker.JavaProject;
import org.openrewrite.java.marker.JavaSourceSet;
import org.openrewrite.java.marker.JavaVersion;
import org.openrewrite.java.tree.J.CompilationUnit;
import org.openrewrite.marker.BuildTool;
import org.openrewrite.marker.Marker;
import org.openrewrite.maven.MavenParser;
import org.openrewrite.maven.tree.Dependency;
import org.openrewrite.maven.tree.MavenResolutionResult;
import org.openrewrite.maven.tree.Pom;
import org.openrewrite.maven.tree.ResolvedPom;
import org.openrewrite.properties.PropertiesParser;
import org.openrewrite.text.PlainTextParser;
import org.openrewrite.xml.XmlParser;
import org.openrewrite.xml.tree.Xml;
import org.openrewrite.xml.tree.Xml.Document;
import org.openrewrite.yaml.YamlParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
/**
* Parse a Maven project on disk into a list of {@link org.openrewrite.SourceFile} including
* Maven, Java, YAML, properties, and XML AST representations of sources and resources found.
*/
public class MavenProjectParser {
public static final String TEST = "test";
public static final String MAIN = "main";
private static final Pattern mavenWrapperVersionPattern = Pattern.compile(".*apache-maven/(.*?)/.*");
private static final Logger logger = LoggerFactory.getLogger(MavenProjectParser.class);
private final MavenParser mavenParser;
private final JavaParser.Builder<?, ?> javaParserBuilder;
private final ExecutionContext ctx;
private final Function<Path, Parser.Input> parserInputProvider;
public MavenProjectParser(MavenParser.Builder mavenParserBuilder,
JavaParser.Builder<?, ?> javaParserBuilder,
ExecutionContext ctx,
Function<Path, Parser.Input> parserInputProvider) {
this.mavenParser = mavenParserBuilder.build();
this.javaParserBuilder = javaParserBuilder;
this.ctx = ctx;
this.parserInputProvider = parserInputProvider;
}
/**
* Given a root path to a maven project, this parser will parse the maven project (including submodules)
* and return a list of ALL source files for all maven modules under the root path.
* <PRE>
* Notes About Provenance Information:
*
* There are always three markers applied to each source file and there can potentially be up to five provenance
* markers in total:
*
* BuildTool - What build tool was used to compile the source file (This will always be Maven)
* JavaVersion - What Java version/vendor was used when compiling the source file.
* JavaProject - For each maven module/sub-module, the same JavaProject will be associated with ALL source files
* belonging to that module.
*
* Optional:
*
* GitProvenance - If the entire project exists in the context of a git repository, all source files (for all modules) will have the same GitProvenance.
* JavaSourceSet - All Java source files and all resource files that exist in src/main or src/test will have a JavaSourceSet marker assigned to them.
*
* </PRE>
* @param projectDirectory A path to the root folder containing a meven project.
* @return A list of source files that have been parsed from the root folder
*/
public List<SourceFile> parse(Path projectDirectory, List<Path> dependencies) {
List<Xml.Document> mavens = mavenParser.parseInputs(getMavenPoms(projectDirectory, ctx, parserInputProvider), projectDirectory, ctx);
List<Document> sorted = sort(mavens);
// Filter out pom files inside target folders. (Naive implementation.)
mavens = sorted.stream().filter(m -> !isInsideBuildFolderOfOtherMavenProjects(sorted, m)).collect(Collectors.toList());
JavaParser javaParser = javaParserBuilder.build();
logger.info("The order in which projects are being parsed is:");
for (Xml.Document maven : mavens) {
logger.info(" {}:{}", getModel(maven).getGroupId(), getModel(maven).getArtifactId());
}
List<SourceFile> sourceFiles = new ArrayList<>();
for (Xml.Document maven : mavens) {
List<Marker> projectProvenance = getJavaProvenance(maven, projectDirectory);
sourceFiles.add(addProjectProvenance(maven, projectProvenance));
// List<Path> dependencies = downloadArtifacts(getResolvedPom(maven).getDependencies().get(Scope.Compile));
javaParser.setClasspath(dependencies);
List<CompilationUnit> mainJavaSources = ListUtils.map(javaParser.parseInputs(
getJavaSources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, ctx), addProvenance(projectProvenance));
JavaSourceSet mainSourceSet = ORAstUtils.addJavaSourceSet(mainJavaSources, MAIN, dependencies);
sourceFiles.addAll(mainJavaSources);
//Resources in the src/main should also have the main source set attached to them.
parseResources(getResources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, sourceFiles, projectProvenance, mainSourceSet);
// List<Path> testDependencies = downloadArtifacts(maven.getModel().getDependencies(Scope.Test));
// javaParser.setClasspath(testDependencies);
List<CompilationUnit> testJavaSources = ListUtils.map(javaParser.parseInputs(
getTestJavaSources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, ctx), addProvenance(projectProvenance));
JavaSourceSet testSourceSet = ORAstUtils.addJavaSourceSet(testJavaSources, TEST, dependencies);
sourceFiles.addAll(testJavaSources);
//Resources in the src/test should also have the test source set attached to them.
parseResources(getTestResources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, sourceFiles, projectProvenance, testSourceSet);
}
return sourceFiles;
}
private List<Marker> getJavaProvenance(Xml.Document maven, Path projectDirectory) {
ResolvedPom mavenModel = getModel(maven);
String javaRuntimeVersion = System.getProperty("java.runtime.version");
String javaVendor = System.getProperty("java.vm.vendor");
String sourceCompatibility = javaRuntimeVersion;
String targetCompatibility = javaRuntimeVersion;
String propertiesSourceCompatibility = mavenModel.getValue(mavenModel.getValue("maven.compiler.source"));
if (propertiesSourceCompatibility != null) {
sourceCompatibility = propertiesSourceCompatibility;
}
String propertiesTargetCompatibility = mavenModel.getValue(mavenModel.getValue("maven.compiler.target"));
if (propertiesTargetCompatibility != null) {
targetCompatibility = propertiesTargetCompatibility;
}
Path wrapperPropertiesPath = projectDirectory.resolve(".mvn/wrapper/maven-wrapper.properties");
String mavenVersion = "3.6";
if (Files.exists(wrapperPropertiesPath)) {
try {
Properties wrapperProperties = new Properties();
wrapperProperties.load(new FileReader(wrapperPropertiesPath.toFile()));
String distributionUrl = (String) wrapperProperties.get("distributionUrl");
if (distributionUrl != null) {
Matcher wrapperVersionMatcher = mavenWrapperVersionPattern.matcher(distributionUrl);
if (wrapperVersionMatcher.matches()) {
mavenVersion = wrapperVersionMatcher.group(1);
}
}
} catch (IOException e) {
ctx.getOnError().accept(e);
}
}
return Arrays.asList(
new BuildTool(randomId(), BuildTool.Type.Maven, mavenVersion),
new JavaVersion(randomId(), javaRuntimeVersion, javaVendor, sourceCompatibility, targetCompatibility),
new JavaProject(randomId(), mavenModel.getRequested().getName(), new JavaProject.Publication(
mavenModel.getGroupId(),
mavenModel.getArtifactId(),
mavenModel.getVersion()
))
);
}
private void parseResources(List<Parser.Input> resources, Path projectDirectory, List<SourceFile> sourceFiles, List<Marker> projectProvenance, JavaSourceSet sourceSet) {
List<Marker> provenance = new ArrayList<>(projectProvenance);
provenance.add(sourceSet);
sourceFiles.addAll(ListUtils.map(new XmlParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".xml") ||
p.getPath().getFileName().toString().endsWith(".wsdl") ||
p.getPath().getFileName().toString().endsWith(".xhtml") ||
p.getPath().getFileName().toString().endsWith(".xsd") ||
p.getPath().getFileName().toString().endsWith(".xsl") ||
p.getPath().getFileName().toString().endsWith(".xslt"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
sourceFiles.addAll(ListUtils.map(new YamlParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".yml") || p.getPath().getFileName().toString().endsWith(".yaml"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
sourceFiles.addAll(ListUtils.map(new PropertiesParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".properties"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
sourceFiles.addAll(ListUtils.map(new PlainTextParser().parseInputs(
resources.stream()
.filter(p -> p.getPath().getFileName().toString().endsWith(".factories"))
.collect(Collectors.toList()),
projectDirectory,
ctx
), addProvenance(provenance)));
}
private <S extends SourceFile> S addProjectProvenance(S s, List<Marker> projectProvenance) {
for (Marker marker : projectProvenance) {
s = s.withMarkers(s.getMarkers().addIfAbsent(marker));
}
return s;
}
private <S extends SourceFile> UnaryOperator<S> addProvenance(List<Marker> projectProvenance) {
return s -> {
s = addProjectProvenance(s, projectProvenance);
return s;
};
}
// private List<Path> downloadArtifacts(Set<Dependency> dependencies) {
// return dependencies.stream()
// .filter(d -> d.getRepository() != null)
// .map(artifactDownloader::downloadArtifact)
// .filter(Objects::nonNull)
// .collect(Collectors.toList());
// }
public static List<Xml.Document> sort(List<Xml.Document> mavens) {
// the value is the set of maven projects that depend on the key
Map<Xml.Document, Set<Xml.Document>> byDependedOn = new HashMap<>();
for (Xml.Document maven : mavens) {
byDependedOn.computeIfAbsent(maven, m -> new HashSet<>());
for (Dependency dependency : getModel(maven).getRequested().getDependencies()) {
for (Xml.Document test : mavens) {
if (getModel(test).getGroupId().equals(dependency.getGroupId()) &&
getModel(test).getArtifactId().equals(dependency.getArtifactId())) {
byDependedOn.computeIfAbsent(maven, m -> new HashSet<>()).add(test);
}
}
}
}
List<Xml.Document> sorted = new ArrayList<>(mavens.size());
next:
while (!byDependedOn.isEmpty()) {
for (Map.Entry<Xml.Document, Set<Xml.Document>> mavenAndDependencies : byDependedOn.entrySet()) {
if (mavenAndDependencies.getValue().isEmpty()) {
Xml.Document maven = mavenAndDependencies.getKey();
byDependedOn.remove(maven);
sorted.add(maven);
for (Set<Xml.Document> dependencies : byDependedOn.values()) {
dependencies.remove(maven);
}
continue next;
}
}
}
return sorted;
}
private static boolean isInsideBuildFolderOfOtherMavenProjects(List<Xml.Document> all, Xml.Document current) {
return all.stream().filter(m -> {
if (m != current) {
Path pomPath = m.getSourcePath();
return current.getSourcePath().startsWith((pomPath.getParent() == null ? Paths.get("") : pomPath.getParent()) .resolve("target"));
}
return false;
}).findFirst().isPresent();
}
private static List<Parser.Input> getSources(Path srcDir, ExecutionContext ctx, Function<Path, Parser.Input> parserInputProvider, String... fileTypes) {
if (!srcDir.toFile().exists()) {
return List.of();
}
BiPredicate<Path, java.nio.file.attribute.BasicFileAttributes> predicate = (p, bfa) ->
bfa.isRegularFile() && Arrays.stream(fileTypes).anyMatch(type -> p.getFileName().toString().endsWith(type));
try {
return Files.find(srcDir, 999, predicate).map(p -> {
Parser.Input in = null;
if (parserInputProvider != null) {
in = parserInputProvider.apply(p);
}
if (in == null) {
in = new Parser.Input(p, () -> {
try {
return Files.newInputStream(p);
} catch (IOException e) {
return new ByteArrayInputStream(new byte[0]);
}
});
}
return in;
}).collect(Collectors.toList());
} catch (IOException e) {
ctx.getOnError().accept(e);
return List.of();
}
}
public static List<Parser.Input> getMavenPoms(Path projectDir, ExecutionContext ctx,
Function<Path, Parser.Input> parserInputProvider) {
return getSources(projectDir, ctx, parserInputProvider, "pom.xml").stream().filter(p -> {
Path relativeToProject = projectDir.relativize(p.getPath());
String relativePathStr = relativeToProject.toString();
return relativeToProject.getFileName().toString().equals("pom.xml")
&& !relativePathStr.contains("/src/") && !relativePathStr.startsWith("src/")
&& !relativePathStr.contains("/bin/") && !relativePathStr.startsWith("bin/")
&& !relativePathStr.contains("/target/") && !relativePathStr.startsWith("target/");
}).collect(Collectors.toList());
}
private static ResolvedPom getModel(Xml.Document maven) {
MavenResolutionResult pom = getResolvedPom(maven);
return pom == null ? null : pom.getPom();
}
private static MavenResolutionResult getResolvedPom(Xml.Document maven) {
return maven.getMarkers().findFirst(MavenResolutionResult.class).orElse(null);
}
private static List<Parser.Input> getJavaSources(Pom pom, Path projectDir, ExecutionContext ctx, Function<Path, Parser.Input> parserInputProvider) {
if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
return List.of();
}
return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "main", "java")),
ctx, parserInputProvider, ".java");
}
private static List<Parser.Input> getTestJavaSources(Pom pom, Path projectDir, ExecutionContext ctx, Function<Path, Parser.Input> parserInputProvider) {
if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
return List.of();
}
return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "test", "java")),
ctx, parserInputProvider, ".java");
}
private static List<Parser.Input> getResources(Pom pom, Path projectDir, ExecutionContext ctx, Function<Path, Parser.Input> parserInputProvider) {
if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
return List.of();
}
return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "main", "resources")),
ctx, parserInputProvider, ".properties", ".xml", ".yml", ".yaml", ".factories");
}
private static List<Parser.Input> getTestResources(Pom pom, Path projectDir, ExecutionContext ctx, Function<Path, Parser.Input> parserInputProvider) {
if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
return List.of();
}
return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "test", "resources")),
ctx, parserInputProvider, ".properties", ".xml", ".yml", ".yaml");
}
}

View File

@@ -0,0 +1,89 @@
/*******************************************************************************
* Copyright (c) 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.rewrite.gradle;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Test;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.SourceFile;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.marker.JavaSourceSet;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaSourceFile;
import org.openrewrite.properties.tree.Properties;
import org.openrewrite.text.PlainText;
import org.openrewrite.yaml.tree.Yaml;
import org.springframework.ide.vscode.commons.gradle.GradleCore;
import org.springframework.ide.vscode.commons.gradle.GradleJavaProject;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
public class GradleIJavaProjectParserTest {
@Test
void testSingleGroovy() throws Exception {
URL resource = getClass().getResource("/test-projects/example-gradle-groovy");
Path testProjectPath = Paths.get(resource.toURI());
IJavaProject jp = GradleJavaProject.create(null, GradleCore.getDefault(), testProjectPath.resolve("build.gradle").toFile(), null);
GradleIJavaProjectParser parser = new GradleIJavaProjectParser(jp, JavaParser.fromJavaVersion(), null);
List<SourceFile> sources = parser.parse(Paths.get(jp.getLocationUri()), new InMemoryExecutionContext(t -> {
throw new RuntimeException(t);
}));
assertEquals(9, sources.size());
// java sources
assertEquals(2, sources.stream().filter(J.CompilationUnit.class::isInstance).collect(Collectors.toList()).size());
// java sources from main
assertEquals(1, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
return ProjectParser.MAIN.equals(sourceSetName);
}).collect(Collectors.toList()).size());
// java sources from test
assertEquals(1, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
return ProjectParser.TEST.equals(sourceSetName);
}).collect(Collectors.toList()).size());
// properties files
assertEquals(1, sources.stream().filter(Properties.File.class::isInstance).collect(Collectors.toList()).size());
// application properties
assertEquals(1, sources.stream().filter(Properties.File.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().equals("application.properties")).collect(Collectors.toList()).size());
// yaml files
assertEquals(2, sources.stream().filter(Yaml.Documents.class::isInstance).collect(Collectors.toList()).size());
// application yaml
assertEquals(2, sources.stream().filter(Yaml.Documents.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().equals("application.yml")).collect(Collectors.toList()).size());
// plain text files
assertEquals(3, sources.stream().filter(PlainText.class::isInstance).collect(Collectors.toList()).size());
// .factories files
assertEquals(3, sources.stream().filter(PlainText.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().endsWith(".factories")).collect(Collectors.toList()).size());
}
}

View File

@@ -12,10 +12,8 @@ package org.springframework.ide.vscode.commons.rewrite.maven;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -29,25 +27,41 @@ import org.openrewrite.maven.MavenParser;
import org.openrewrite.properties.tree.Properties;
import org.openrewrite.text.PlainText;
import org.openrewrite.yaml.tree.Yaml;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.javadoc.JavaDocProviders;
import org.springframework.ide.vscode.commons.maven.MavenBuilder;
import org.springframework.ide.vscode.commons.maven.MavenCore;
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
public class MavenIJavaProjectParserTest {
private static IJavaProject createProject(String name) throws Exception {
Path projectPath = Paths.get(MavenIJavaProjectParserTest.class.getResource("/test-projects/" + name).toURI());
MavenBuilder.newBuilder(projectPath).clean().pack().skipTests().execute();
return MavenJavaProject.create(null, MavenCore.getDefault(),
projectPath.resolve(MavenCore.POM_XML).toFile(), (uri, cpe) -> JavaDocProviders.createFor(cpe));
}
public class MavenProjectParserTest {
@Test
void parseResources() throws Exception {
URL resource = getClass().getResource("/test-projects/test-maven-project-parser");
Path testProjectPath = Paths.get(resource.toURI());
IJavaProject jp = createProject("test-maven-project-parser");
Path testProjectPath = Paths.get(jp.getLocationUri());
MavenParser.Builder mavenParserBuilder = MavenParser.builder()
.mavenConfig(testProjectPath.resolve(".mvn/maven.config"));
MavenProjectParser parser = new MavenProjectParser(mavenParserBuilder, JavaParser.fromJavaVersion(), new InMemoryExecutionContext(t -> {
MavenIJavaProjectParser parser = new MavenIJavaProjectParser(jp, JavaParser.fromJavaVersion(), null, mavenParserBuilder);
List<SourceFile> sources = parser.parse(testProjectPath, new InMemoryExecutionContext(t -> {
if (t instanceof Error) {
throw new RuntimeException(t);
};
}), null);
}));
List<SourceFile> sources = parser.parse(testProjectPath, Collections.emptyList());
assertEquals(12, sources.size());
assertEquals(13, sources.size());
// java sources
assertEquals(6, sources.stream().filter(JavaSourceFile.class::isInstance).collect(Collectors.toList()).size());
@@ -55,13 +69,13 @@ public class MavenProjectParserTest {
// java sources from main
assertEquals(5, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
return MavenProjectParser.MAIN.equals(sourceSetName);
return ProjectParser.MAIN.equals(sourceSetName);
}).collect(Collectors.toList()).size());
// java sources from test
assertEquals(1, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
return MavenProjectParser.TEST.equals(sourceSetName);
return ProjectParser.TEST.equals(sourceSetName);
}).collect(Collectors.toList()).size());
// properties files
@@ -77,10 +91,10 @@ public class MavenProjectParserTest {
assertEquals(2, sources.stream().filter(Yaml.Documents.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().equals("application.yml")).collect(Collectors.toList()).size());
// plain text files
assertEquals(2, sources.stream().filter(PlainText.class::isInstance).collect(Collectors.toList()).size());
assertEquals(3, sources.stream().filter(PlainText.class::isInstance).collect(Collectors.toList()).size());
// .factories files
assertEquals(2, sources.stream().filter(PlainText.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().endsWith(".factories")).collect(Collectors.toList()).size());
assertEquals(3, sources.stream().filter(PlainText.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().endsWith(".factories")).collect(Collectors.toList()).size());
}

View File

@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/

View File

@@ -0,0 +1,23 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.7'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -0,0 +1,240 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@@ -0,0 +1,91 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -0,0 +1 @@
rootProject.name = 'example-gradle-groovy'

View File

@@ -0,0 +1,13 @@
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ExampleGradleGroovyApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleGradleGroovyApplication.class, args);
}
}

View File

@@ -0,0 +1,4 @@
test-map.test-list-object.string-list[0]=not-a-color
test-map.test-list-object.string-list[1]=RED
test-map.test-list-object.string-list[2]=GREEN
test-map.some-key.list[0]=something

View File

@@ -0,0 +1,13 @@
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ExampleGradleGroovyApplicationTests {
@Test
void contextLoads() {
}
}

View File

@@ -115,6 +115,7 @@
<!-- Rewrite specific properties -->
<rewrite-version>7.41.0-SNAPSHOT</rewrite-version>
<rewrite-spring-version>4.37.0-SNAPSHOT</rewrite-spring-version>
<rewrite-gradle-tooling-api-version>0.9.0-SNAPSHOT</rewrite-gradle-tooling-api-version>
<signing.skip>true</signing.skip>
<signing.alias>vmware</signing.alias>

View File

@@ -11,7 +11,6 @@
package org.springframework.ide.vscode.boot.java.rewrite;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.net.URLClassLoader;
@@ -33,7 +32,6 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
import org.eclipse.lsp4j.TextDocumentIdentifier;
@@ -59,19 +57,20 @@ import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.ide.vscode.boot.app.BootJavaConfig;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.IndefiniteProgressTask;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.ListenerList;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.protocol.java.ProjectBuild;
import org.springframework.ide.vscode.commons.rewrite.LoadUtils;
import org.springframework.ide.vscode.commons.rewrite.LoadUtils.DurationTypeConverter;
import org.springframework.ide.vscode.commons.rewrite.ORDocUtils;
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
import org.springframework.ide.vscode.commons.rewrite.config.StsEnvironment;
import org.springframework.ide.vscode.commons.rewrite.maven.MavenProjectParser;
import org.springframework.ide.vscode.commons.rewrite.gradle.GradleIJavaProjectParser;
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
import org.springframework.ide.vscode.commons.rewrite.maven.MavenIJavaProjectParser;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.gson.Gson;
@@ -417,15 +416,15 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
private Optional<WorkspaceEdit> computeWorkspaceEdit(Recipe r, IJavaProject project, IndefiniteProgressTask progressTask) {
Path absoluteProjectDir = Paths.get(project.getLocationUri());
progressTask.progressEvent("Parsing files...");
MavenProjectParser projectParser = createRewriteMavenParser(absoluteProjectDir,
new InMemoryExecutionContext(), p -> {
ProjectParser projectParser = createRewriteProjectParser(project,
p -> {
TextDocument doc = server.getTextDocumentService().getLatestSnapshot(p.toUri().toASCIIString());
if (doc != null) {
return new Parser.Input(p, () -> new ByteArrayInputStream(doc.get().getBytes()));
}
return null;
});
List<SourceFile> sources = projectParser.parse(absoluteProjectDir, getClasspathEntries(project));
List<SourceFile> sources = projectParser.parse(absoluteProjectDir, new InMemoryExecutionContext());
progressTask.progressEvent("Computing changes...");
RecipeRun reciperun = r.run(sources, new InMemoryExecutionContext(e -> log.error("Recipe execution failed", e)));
List<Result> results = reciperun.getResults();
@@ -447,32 +446,20 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
return Collections.emptyList();
}
private static MavenProjectParser createRewriteMavenParser(Path absoluteProjectDir, ExecutionContext context, Function<Path, Parser.Input> inputProvider) {
MavenParser.Builder mavenParserBuilder = MavenParser.builder()
.mavenConfig(absoluteProjectDir.resolve(".mvn/maven.config"));
MavenProjectParser mavenProjectParser = new MavenProjectParser(
mavenParserBuilder,
JavaParser.fromJavaVersion(),
context,
inputProvider
);
return mavenProjectParser;
private static ProjectParser createRewriteProjectParser(IJavaProject jp, Function<Path, Parser.Input> inputProvider) {
switch (jp.getProjectBuild().getType()) {
case ProjectBuild.MAVEN_PROJECT_TYPE:
Path absoluteProjectDir = Paths.get(jp.getLocationUri()).toAbsolutePath();
MavenParser.Builder mavenParserBuilder = MavenParser.builder()
.mavenConfig(absoluteProjectDir.resolve(".mvn/maven.config"));
return new MavenIJavaProjectParser(jp, JavaParser.fromJavaVersion(), inputProvider, mavenParserBuilder);
case ProjectBuild.GRADLE_PROJECT_TYPE:
return new GradleIJavaProjectParser(jp, JavaParser.fromJavaVersion(), inputProvider);
default:
throw new IllegalStateException("The project is neither Maven nor Gradle!");
}
}
private static List<Path> getClasspathEntries(IJavaProject project) {
if (project == null) {
return List.of();
} else {
IClasspath classpath = project.getClasspath();
Stream<File> classpathEntries = IClasspathUtil.getAllBinaryRoots(classpath).stream();
return classpathEntries
.filter(file -> file.exists())
.filter(file -> file.getName().endsWith(".jar"))
.map(file -> file.getAbsoluteFile().toPath()).collect(Collectors.toList());
}
}
public void onRecipesLoaded(Consumer<Void> l) {
loadListeners.add(l);
}

View File

@@ -54,7 +54,7 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
import org.springframework.ide.vscode.commons.rewrite.maven.MavenProjectParser;
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
@@ -165,8 +165,8 @@ public class RewriteReconciler implements JavaReconciler {
// Pass in source sets created from classpath. (Perhaps it is a good idea to have separate classpath and parsers for test and main, TBD)
// Perhaps it is even better to create empty classpath java source sets as reconcile step seem to only need name of the java source set
// Usually java source set classpath is required to figure out how to organize imports for sources
JavaSourceSet mainJavaSourceSet = JavaSourceSet.build(MavenProjectParser.MAIN, classpath, null, false);
JavaSourceSet testJavaSourceSet = new JavaSourceSet(Tree.randomId(), MavenProjectParser.TEST, mainJavaSourceSet.getClasspath());
JavaSourceSet mainJavaSourceSet = JavaSourceSet.build(ProjectParser.MAIN, classpath, null, false);
JavaSourceSet testJavaSourceSet = new JavaSourceSet(Tree.randomId(), ProjectParser.TEST, mainJavaSourceSet.getClasspath());
allProblems.putAll(doReconcile(project, mainSources, javaParser, mainJavaSourceSet, incrementProgress));
allProblems.putAll(doReconcile(project, testSources, javaParser, testJavaSourceSet, incrementProgress));

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022 VMware, Inc.
* Copyright (c) 2022, 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -43,7 +43,7 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
import org.springframework.ide.vscode.commons.rewrite.maven.MavenProjectParser;
import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
public class AutowiredFieldIntoConstructorParameterCodeAction implements RecipeCodeActionDescriptor {
@@ -58,7 +58,7 @@ public class AutowiredFieldIntoConstructorParameterCodeAction implements RecipeC
@Override
public CompilationUnit visitCompilationUnit(CompilationUnit cu, ExecutionContext p) {
JavaSourceSet sourceSet = cu.getMarkers().findFirst(JavaSourceSet.class).orElse(null);
if (sourceSet != null && MavenProjectParser.TEST.equals(sourceSet.getName())) {
if (sourceSet != null && ProjectParser.TEST.equals(sourceSet.getName())) {
return cu;
}
return super.visitCompilationUnit(cu, p);

View File

@@ -76,24 +76,24 @@
"menus": {
"editor/context": [
{
"when": "resourceFilename == pom.xml",
"when": "resourceFilename == pom.xml || resourceFilename == build.gradle",
"command": "vscode-spring-boot.rewrite.list.refactorings",
"group": "SpringBoot"
},
{
"when": "resourceFilename == pom.xml",
"when": "resourceFilename == pom.xml || resourceFilename == build.gradle",
"command": "vscode-spring-boot.rewrite.list.boot-upgrades",
"group": "SpringBoot"
}
],
"explorer/context": [
{
"when": "resourceFilename == pom.xml && config.boot-java.rewrite.refactorings.on == true",
"when": "(resourceFilename == pom.xml || resourceFilename == build.gradle) && config.boot-java.rewrite.refactorings.on == true",
"command": "vscode-spring-boot.rewrite.list.refactorings",
"group": "SpringBoot"
},
{
"when": "resourceFilename == pom.xml && config.boot-java.rewrite.refactorings.on == true",
"when": "(resourceFilename == pom.xml || resourceFilename == build.gradle) && config.boot-java.rewrite.refactorings.on == true",
"command": "vscode-spring-boot.rewrite.list.boot-upgrades",
"group": "SpringBoot"
}