diff --git a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java index 9ae0e9bee..80d6f4622 100644 --- a/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java +++ b/idea-plugin/src/main/java/com/palantir/javaformat/intellij/FormatterProvider.java @@ -20,6 +20,8 @@ import com.github.benmanes.caffeine.cache.LoadingCache; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.intellij.execution.wsl.WSLDistribution; +import com.intellij.execution.wsl.WslPath; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManager; import com.intellij.openapi.application.ApplicationInfo; @@ -95,6 +97,29 @@ private static Optional createFormatter(FormatterCacheKey cach if (useBootstrappingFormatter( jdkMajorVersion, ApplicationInfo.getInstance().getBuild())) { Path jdkPath = getJdkPath(cacheKey.project); + if (SystemInfo.isWindows) { + WslPath jdkUncPath = + WslPath.parseWindowsUncPath(jdkPath.toAbsolutePath().toString()); + if (jdkUncPath != null) { + // Project JDK is inside WSL2. We have to run the formatter inside WSL2 as well + Path jdkLinuxPath = Path.of(jdkUncPath.getLinuxPath()); + String wslId = jdkUncPath.getDistributionId(); + WSLDistribution distro = jdkUncPath.getDistribution(); + List linuxImplementationClassPath = implementationClasspath.stream() + .map(Path::toAbsolutePath) + .map(distro::getWslPath) + .map(Path::of) + .toList(); + + log.info( + "Using bootstrapping formatter with WSL distribution {}, jdk version {} and path: {}", + wslId, + jdkMajorVersion, + jdkLinuxPath); + return Optional.of(new BootstrappingFormatterService( + wslId, jdkLinuxPath, jdkMajorVersion, linuxImplementationClassPath)); + } + } log.info("Using bootstrapping formatter with jdk version {} and path: {}", jdkMajorVersion, jdkPath); return Optional.of(new BootstrappingFormatterService(jdkPath, jdkMajorVersion, implementationClasspath)); } @@ -153,7 +178,9 @@ private static Path getJdkPath(Project project) { return getProjectJdk(project) .map(Sdk::getHomePath) .map(Path::of) - .map(sdkHome -> sdkHome.resolve("bin").resolve("java" + (SystemInfo.isWindows ? ".exe" : ""))) + .map(sdkHome -> sdkHome.resolve("bin") + .resolve("java" + + (SystemInfo.isWindows && !WslPath.isWslUncPath(sdkHome.toString()) ? ".exe" : ""))) .filter(Files::exists) .orElseThrow(() -> new IllegalStateException("Could not determine JDK path for project: " + project.getName())); diff --git a/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java b/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java index 92d734449..4aacbab4e 100644 --- a/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java +++ b/palantir-java-format-jdk-bootstrap/src/main/java/com/palantir/javaformat/bootstrap/BootstrappingFormatterService.java @@ -32,6 +32,7 @@ import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; import org.immutables.value.Value; @@ -44,11 +45,21 @@ public final class BootstrappingFormatterService implements FormatterService { private final Path jdkPath; private final Integer jdkMajorVersion; private final List implementationClassPath; + private final Optional wslDistributionId; public BootstrappingFormatterService(Path jdkPath, Integer jdkMajorVersion, List implementationClassPath) { this.jdkPath = jdkPath; this.jdkMajorVersion = jdkMajorVersion; this.implementationClassPath = implementationClassPath; + this.wslDistributionId = Optional.empty(); + } + + public BootstrappingFormatterService( + String wslDistributionId, Path jdkPath, Integer jdkMajorVersion, List implementationClassPath) { + this.jdkPath = jdkPath; + this.jdkMajorVersion = jdkMajorVersion; + this.implementationClassPath = implementationClassPath; + this.wslDistributionId = Optional.of(wslDistributionId); } @Override @@ -84,13 +95,16 @@ private ImmutableList getFormatReplacementsInternal(String input, C .jdkPath(jdkPath) .withJvmArgsForVersion(jdkMajorVersion) .implementationClasspath(implementationClassPath) + .wslDistributionId(wslDistributionId) .outputReplacements(true) .characterRanges(ranges.stream().map(RangeUtils::toStringRange).collect(Collectors.toList())) .build(); @SuppressWarnings("for-rollout:NullAway") - Optional output = - FormatterCommandRunner.runWithStdin(command.toArgs(), input, Optional.of(jdkPath.getParent())); + Optional output = FormatterCommandRunner.runWithStdin( + command.toArgs(), + input, + wslDistributionId.isPresent() ? Optional.empty() : Optional.of(jdkPath.getParent())); if (output.isEmpty() || output.get().isEmpty()) { return ImmutableList.of(); } @@ -102,9 +116,13 @@ private String runFormatterCommand(String input) throws IOException { .jdkPath(jdkPath) .withJvmArgsForVersion(jdkMajorVersion) .implementationClasspath(implementationClassPath) + .wslDistributionId(wslDistributionId) .outputReplacements(false) .build(); - return FormatterCommandRunner.runWithStdin(command.toArgs(), input, Optional.ofNullable(jdkPath.getParent())) + return FormatterCommandRunner.runWithStdin( + command.toArgs(), + input, + wslDistributionId.isPresent() ? Optional.empty() : Optional.ofNullable(jdkPath.getParent())) .orElse(input); } @@ -114,6 +132,8 @@ interface FormatterCliArgs { boolean outputReplacements(); + Optional wslDistributionId(); + Path jdkPath(); List implementationClasspath(); @@ -121,14 +141,29 @@ interface FormatterCliArgs { List jvmArgs(); default List toArgs() { - ImmutableList.Builder args = ImmutableList.builder() - .add(jdkPath().toAbsolutePath().toString()) + ImmutableList.Builder args = ImmutableList.builder(); + + String pathSeparator; + Function pathToString; + if (wslDistributionId().isPresent()) { + pathSeparator = ":"; + pathToString = path -> path.toString().replace('\\', '/'); + + args.add("wsl", "-d", wslDistributionId().get()); + args.add("--cd", pathToString.apply(jdkPath().getParent())); + } else { + pathSeparator = System.getProperty("path.separator"); + pathToString = path -> path.toAbsolutePath().toString(); + } + + args.add() + .add(pathToString.apply(jdkPath())) .addAll(jvmArgs()) .add( "-cp", implementationClasspath().stream() - .map(path -> path.toAbsolutePath().toString()) - .collect(Collectors.joining(System.getProperty("path.separator")))) + .map(pathToString) + .collect(Collectors.joining(pathSeparator))) .add(FORMATTER_MAIN_CLASS); if (!characterRanges().isEmpty()) {