diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java index fb3aede5..1f371b13 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java @@ -14,6 +14,7 @@ package com.microsoft.java.debug.plugin.internal; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.logging.Logger; @@ -28,14 +29,16 @@ import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.ls.core.internal.BuildWorkspaceStatus; import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; import org.eclipse.jdt.ls.core.internal.ProjectUtils; import org.eclipse.jdt.ls.core.internal.ResourceUtils; +import org.eclipse.jdt.ls.core.internal.handlers.BuildWorkspaceHandler; import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager; +import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.eclipse.lsp4j.extended.ProjectBuildParams; import com.microsoft.java.debug.core.Configuration; @@ -45,10 +48,15 @@ public class Compile { private static final int GRADLE_BS_COMPILATION_ERROR = 100; public static Object compile(CompileParams params, IProgressMonitor monitor) { - IProject mainProject = params == null ? null : ProjectUtils.getProject(params.getProjectName()); - if (mainProject == null) { + if (params == null) { + throw new IllegalArgumentException("The compile parameters should not be null."); + } + + IProject mainProject = null; + if (StringUtils.isNotBlank(params.getProjectName())) { + mainProject = ProjectUtils.getProject(params.getProjectName()); + } else if (mainProject == null && StringUtils.isNotBlank(params.getMainClass())) { try { - // Q: is infer project by main class name necessary? perf impact? List javaProjects = ResolveClasspathsHandler.getJavaProjectFromType(params.getMainClass()); if (javaProjects.size() == 1) { mainProject = javaProjects.get(0).getProject(); @@ -78,20 +86,37 @@ public static Object compile(CompileParams params, IProgressMonitor monitor) { return BuildWorkspaceStatus.SUCCEED; } - try { - if (monitor.isCanceled()) { - return BuildWorkspaceStatus.CANCELLED; - } + if (monitor.isCanceled()) { + return BuildWorkspaceStatus.CANCELLED; + } - long compileAt = System.currentTimeMillis(); - if (params != null && params.isFullBuild()) { - ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, monitor); - ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, monitor); - } else { - ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor); + ProjectBuildParams buildParams = new ProjectBuildParams(); + List identifiers = new LinkedList<>(); + buildParams.setFullBuild(params.isFullBuild); + for (IJavaProject javaProject : ProjectUtils.getJavaProjects()) { + if (ProjectsManager.getDefaultProject().equals(javaProject.getProject())) { + continue; } - logger.info("Time cost for ECJ: " + (System.currentTimeMillis() - compileAt) + "ms"); + // we only build project which is not a BSP project, in case that the compile request is triggered by + // HCR with auto-build disabled, the build for BSP projects will be triggered by JavaHotCodeReplaceProvider. + if (!JdtUtils.isBspProject(javaProject.getProject())) { + identifiers.add(new TextDocumentIdentifier(javaProject.getProject().getLocationURI().toString())); + } + } + if (identifiers.size() == 0) { + return BuildWorkspaceStatus.SUCCEED; + } + + buildParams.setIdentifiers(identifiers); + long compileAt = System.currentTimeMillis(); + BuildWorkspaceHandler buildWorkspaceHandler = new BuildWorkspaceHandler(JavaLanguageServerPlugin.getProjectsManager()); + BuildWorkspaceStatus status = buildWorkspaceHandler.buildProjects(buildParams, monitor); + logger.info("Time cost for ECJ: " + (System.currentTimeMillis() - compileAt) + "ms"); + if (status == BuildWorkspaceStatus.FAILED || status == BuildWorkspaceStatus.CANCELLED) { + return status; + } + try { IResource currentResource = mainProject; if (isUnmanagedFolder(mainProject) && StringUtils.isNotBlank(params.getMainClass())) { IType mainType = ProjectUtils.getJavaProject(mainProject).findType(params.getMainClass()); @@ -135,17 +160,14 @@ public static Object compile(CompileParams params, IProgressMonitor monitor) { } } - if (problemMarkers.isEmpty()) { - return BuildWorkspaceStatus.SUCCEED; + if (!problemMarkers.isEmpty()) { + return BuildWorkspaceStatus.WITH_ERROR; } - - return BuildWorkspaceStatus.WITH_ERROR; } catch (CoreException e) { - JavaLanguageServerPlugin.logException("Failed to build workspace.", e); - return BuildWorkspaceStatus.FAILED; - } catch (OperationCanceledException e) { - return BuildWorkspaceStatus.CANCELLED; + JavaLanguageServerPlugin.log(e); } + + return BuildWorkspaceStatus.SUCCEED; } private static boolean isUnmanagedFolder(IProject project) {