From 5761d472b3942023749d98a1743864a18958cd29 Mon Sep 17 00:00:00 2001 From: Shi Chen Date: Thu, 20 Oct 2022 14:31:05 +0800 Subject: [PATCH] support quickfix for gradle jpms projects Signed-off-by: Shi Chen --- .../internal/JDTDelegateCommandHandler.java | 4 +- .../corrections/CorrectionMessages.java | 2 + .../corrections/CorrectionMessages.properties | 2 + .../corrections/QuickFixProcessor.java | 14 ++++- .../GradleCompatibilityProcessor.java | 60 +++++++++++++++++++ .../internal/handlers/CodeActionHandler.java | 2 +- .../managers/GradleProjectImporter.java | 37 +++++++++--- .../core/internal/managers/GradleUtils.java | 2 +- 8 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/GradleCompatibilityProcessor.java diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTDelegateCommandHandler.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTDelegateCommandHandler.java index 0fb9f4620a..26beef403a 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTDelegateCommandHandler.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/JDTDelegateCommandHandler.java @@ -17,6 +17,7 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; +import org.eclipse.buildship.core.internal.util.gradle.GradleVersion; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.ls.core.internal.commands.BuildPathCommand; @@ -32,7 +33,6 @@ import org.eclipse.jdt.ls.core.internal.handlers.FormatterHandler; import org.eclipse.jdt.ls.core.internal.handlers.ResolveSourceMappingHandler; import org.eclipse.jdt.ls.core.internal.managers.GradleProjectImporter; -import org.eclipse.jdt.ls.core.internal.managers.GradleUtils; import org.eclipse.lsp4j.ResolveTypeHierarchyItemParams; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.TextDocumentPositionParams; @@ -125,7 +125,7 @@ public Object executeCommand(String commandId, List arguments, IProgress String projectUri = (String) arguments.get(0); String gradleVersion = arguments.size() > 1 ? (String) arguments.get(1) : null; if (gradleVersion == null) { - gradleVersion = GradleUtils.CURRENT_GRADLE; + gradleVersion = GradleVersion.current().getVersion(); } return GradleProjectImporter.upgradeGradleVersion(projectUri, gradleVersion, monitor); case "java.project.resolveWorkspaceSymbol": diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.java index 6ffcb59f54..499d1e3405 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.java @@ -313,6 +313,8 @@ private CorrectionMessages() { public static String NewCUCompletionUsingWizardProposal_tooltip_enclosingtype; public static String NewCUCompletionUsingWizardProposal_tooltip_package; + public static String NotAccessibleType_upgrade_Gradle_label; + public static String JavaCorrectionProcessor_addquote_description; public static String JavaCorrectionProcessor_error_quickfix_message; public static String JavaCorrectionProcessor_error_status; diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.properties b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.properties index 680127057d..a8256419e7 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.properties +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/CorrectionMessages.properties @@ -396,6 +396,8 @@ NewCUCompletionUsingWizardProposal_dialogtitle=New NewCUCompletionUsingWizardProposal_tooltip_enclosingtype=Enclosing Type: NewCUCompletionUsingWizardProposal_tooltip_package=Package: +NotAccessibleType_upgrade_Gradle_label=Upgrade Gradle version to 7.0 + JavaCorrectionProcessor_addquote_description=Insert missing quote JavaCorrectionProcessor_error_quickfix_message=An error occurred while computing quick fixes. Check log for details. JavaCorrectionProcessor_error_status=Exception while processing quick fixes or quick assists diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java index a3d15aaa93..55ddb2f8e0 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java @@ -33,11 +33,14 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; +import org.eclipse.jdt.ls.core.internal.ProjectUtils; import org.eclipse.jdt.ls.core.internal.corrections.proposals.ChangeCorrectionProposal; import org.eclipse.jdt.ls.core.internal.corrections.proposals.GetterSetterCorrectionSubProcessor; +import org.eclipse.jdt.ls.core.internal.corrections.proposals.GradleCompatibilityProcessor; import org.eclipse.jdt.ls.core.internal.corrections.proposals.IProposalRelevance; import org.eclipse.jdt.ls.core.internal.corrections.proposals.JavadocTagsSubProcessor; import org.eclipse.jdt.ls.core.internal.corrections.proposals.LocalCorrectionsSubProcessor; @@ -45,8 +48,10 @@ import org.eclipse.jdt.ls.core.internal.corrections.proposals.ReplaceCorrectionProposal; import org.eclipse.jdt.ls.core.internal.corrections.proposals.TypeMismatchSubProcessor; import org.eclipse.jdt.ls.core.internal.corrections.proposals.UnresolvedElementsSubProcessor; +import org.eclipse.jdt.ls.core.internal.text.correction.CUCorrectionCommandProposal; import org.eclipse.jdt.ls.core.internal.text.correction.ModifierCorrectionSubProcessor; import org.eclipse.lsp4j.CodeActionKind; +import org.eclipse.lsp4j.CodeActionParams; /** */ @@ -67,7 +72,7 @@ private static int moveBack(int offset, int start, String ignoreCharacters, ICom return start; } - public List getCorrections(IInvocationContext context, IProblemLocationCore[] locations) throws CoreException { + public List getCorrections(CodeActionParams params, IInvocationContext context, IProblemLocationCore[] locations) throws CoreException { if (locations == null || locations.length == 0) { return Collections.emptyList(); } @@ -76,7 +81,7 @@ public List getCorrections(IInvocationContext context, for (int i = 0; i < locations.length; i++) { IProblemLocationCore curr = locations[i]; if (handledProblems(curr, locations, handledProblems)) { - process(context, curr, resultingCollections); + process(params, context, curr, resultingCollections); } } return resultingCollections; @@ -99,7 +104,7 @@ private static boolean handledProblems(IProblemLocationCore location, IProblemLo return handledProblems.add(problemId); } - private void process(IInvocationContext context, IProblemLocationCore problem, Collection proposals) throws CoreException { + private void process(CodeActionParams params, IInvocationContext context, IProblemLocationCore problem, Collection proposals) throws CoreException { int id = problem.getProblemId(); if (id == 0) { // no proposals for none-problem locations return; @@ -546,6 +551,9 @@ private void process(IInvocationContext context, IProblemLocationCore problem, C case IProblem.PotentiallyUnclosedCloseable: LocalCorrectionsSubProcessor.getTryWithResourceProposals(context, problem, proposals); break; + case IProblem.NotAccessibleType: + GradleCompatibilityProcessor.getGradleCompatibilityProposals(context, problem, proposals); + break; // case IProblem.MissingSynchronizedModifierInInheritedMethod: // ModifierCorrectionSubProcessor.addSynchronizedMethodProposal(context, // problem, proposals); diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/GradleCompatibilityProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/GradleCompatibilityProcessor.java new file mode 100644 index 0000000000..a77be474fd --- /dev/null +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/GradleCompatibilityProcessor.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2022 Microsoft Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Microsoft Corporation - initial API and implementation +*******************************************************************************/ +package org.eclipse.jdt.ls.core.internal.corrections.proposals; + +import java.net.URI; +import java.util.Arrays; +import java.util.Collection; + +import org.eclipse.buildship.core.internal.CorePlugin; +import org.eclipse.buildship.core.internal.preferences.PersistentModel; +import org.eclipse.buildship.core.internal.util.gradle.GradleVersion; +import org.eclipse.core.internal.resources.Workspace; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; +import org.eclipse.jdt.ls.core.internal.ProjectUtils; +import org.eclipse.jdt.ls.core.internal.corrections.CorrectionMessages; +import org.eclipse.jdt.ls.core.internal.corrections.IInvocationContext; +import org.eclipse.jdt.ls.core.internal.managers.GradleUtils; +import org.eclipse.jdt.ls.core.internal.text.correction.CUCorrectionCommandProposal; +import org.eclipse.lsp4j.CodeActionKind; + +public class GradleCompatibilityProcessor { + public static void getGradleCompatibilityProposals(IInvocationContext context, IProblemLocationCore problem, Collection proposals) { + IJavaProject javaProject = context.getCompilationUnit().getJavaProject(); + IProject project = javaProject.getProject(); + if (!ProjectUtils.isGradleProject(project)) { + return; + } + PersistentModel model = CorePlugin.modelPersistence().loadModel(project); + if (!model.isPresent()) { + return; + } + GradleVersion gradleVersion = model.getGradleVersion(); + if (gradleVersion != null && gradleVersion.compareTo(GradleVersion.version(GradleUtils.JPMS_SUPPORTED_VERSION)) < 0) { + IResource resource = javaProject.getResource(); + if (resource == null) { + return; + } + URI uri = resource.getLocationURI(); + if (uri == null) { + return; + } + proposals.add(new CUCorrectionCommandProposal(CorrectionMessages.NotAccessibleType_upgrade_Gradle_label, CodeActionKind.QuickFix, context.getCompilationUnit(), IProposalRelevance.CONFIGURE_BUILD_PATH, "java.project.upgradeGradle", Arrays.asList(uri.toString(), GradleUtils.JPMS_SUPPORTED_VERSION))); + } + + } +} diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeActionHandler.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeActionHandler.java index 2164579e5c..e6c1dec99c 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeActionHandler.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/CodeActionHandler.java @@ -159,7 +159,7 @@ public List> getCodeActionCommands(CodeActionParams if (containsKind(codeActionKinds, CodeActionKind.QuickFix)) { try { codeActions.addAll(nonProjectFixProcessor.getCorrections(params, context, locations)); - List quickfixProposals = this.quickFixProcessor.getCorrections(context, locations); + List quickfixProposals = this.quickFixProcessor.getCorrections(params, context, locations); Set quickSet = new TreeSet<>(comparator); quickSet.addAll(quickfixProposals); proposals.addAll(quickSet); diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleProjectImporter.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleProjectImporter.java index f96a0441c8..7e731aa83c 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleProjectImporter.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleProjectImporter.java @@ -37,10 +37,12 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.stream.Collectors; + import org.apache.commons.lang3.StringUtils; import org.eclipse.buildship.core.BuildConfiguration; import org.eclipse.buildship.core.GradleBuild; @@ -49,8 +51,10 @@ import org.eclipse.buildship.core.SynchronizationResult; import org.eclipse.buildship.core.WrapperGradleDistribution; import org.eclipse.buildship.core.internal.CorePlugin; +import org.eclipse.buildship.core.internal.DefaultGradleBuild; import org.eclipse.buildship.core.internal.preferences.PersistentModel; import org.eclipse.buildship.core.internal.util.gradle.GradleVersion; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; @@ -254,7 +258,7 @@ public void importToWorkspace(IProgressMonitor monitor) throws CoreException { } } if (JavaLanguageServerPlugin.getProjectsManager() != null && JavaLanguageServerPlugin.getProjectsManager().getConnection() != null) { - GradleCompatibilityInfo info = new GradleCompatibilityInfo(gradleStatus.getProjectUri(), gradleStatus.getMessage(), gradleStatus.getHighestJavaVersion(), GradleUtils.CURRENT_GRADLE); + GradleCompatibilityInfo info = new GradleCompatibilityInfo(gradleStatus.getProjectUri(), gradleStatus.getMessage(), gradleStatus.getHighestJavaVersion(), GradleVersion.current().getVersion()); EventNotification notification = new EventNotification().withType(EventType.IncompatibleGradleJdkIssue).withData(info); JavaLanguageServerPlugin.getProjectsManager().getConnection().sendEventNotification(notification); } @@ -278,7 +282,7 @@ public void importToWorkspace(IProgressMonitor monitor) throws CoreException { IMarker marker = ResourceUtils.createWarningMarker(GRADLE_UPGRADE_WRAPPER_MARKER_ID, wrapperProperties, GRADLE_INVALID_TYPE_CODE_MESSAGE, INVALID_TYPE_CODE_ID, reader.getLineNumber()); marker.setAttribute(GRADLE_MARKER_COLUMN_START, 0); marker.setAttribute(GRADLE_MARKER_COLUMN_END, line.length()); - UpgradeGradleWrapperInfo info = new UpgradeGradleWrapperInfo(gradleStatus.getProjectUri(), GRADLE_INVALID_TYPE_CODE_MESSAGE, GradleUtils.CURRENT_GRADLE); + UpgradeGradleWrapperInfo info = new UpgradeGradleWrapperInfo(gradleStatus.getProjectUri(), GRADLE_INVALID_TYPE_CODE_MESSAGE, GradleVersion.current().getVersion()); EventNotification notification = new EventNotification().withType(EventType.UpgradeGradleWrapper).withData(info); JavaLanguageServerPlugin.getProjectsManager().getConnection().sendEventNotification(notification); break; @@ -535,9 +539,26 @@ public boolean accept(File dir, String name) { return shouldSynchronize; } - public static boolean upgradeGradleVersion(String projectUri, String gradleVersion, IProgressMonitor monitor) { + /** + * update the gradle wrapper to the given version + * @param projectUri uri of the project + * @param gradleVersion the target gradle version + * @param monitor the progress monitor + * @return the path to the new gradle-wrapper.properties file + */ + public static String upgradeGradleVersion(String projectUri, String gradleVersion, IProgressMonitor monitor) { String newDistributionUrl = String.format("https://services.gradle.org/distributions/gradle-%s-bin.zip", gradleVersion); Path projectFolder = Paths.get(URI.create(projectUri)); + // try to get root project directory + IProject project = ProjectUtils.getProjectFromUri(projectUri); + Optional build = GradleCore.getWorkspace().getBuild(project); + if (!build.isPresent()) { + return null; + } + GradleBuild gradleBuild = build.get(); + if (gradleBuild instanceof DefaultGradleBuild) { + projectFolder = ((DefaultGradleBuild) gradleBuild).getBuildConfig().getRootProjectDirectory().toPath(); + } File propertiesFile = projectFolder.resolve("gradle").resolve("wrapper").resolve("gradle-wrapper.properties").toFile(); Properties properties = new Properties(); if (propertiesFile.exists()) { @@ -545,7 +566,7 @@ public static boolean upgradeGradleVersion(String projectUri, String gradleVersi properties.load(stream); properties.setProperty("distributionUrl", newDistributionUrl); } catch (IOException e) { - return false; + return null; } } else { properties.setProperty("distributionBase", "GRADLE_USER_HOME"); @@ -557,10 +578,8 @@ public static boolean upgradeGradleVersion(String projectUri, String gradleVersi try { properties.store(new FileOutputStream(propertiesFile), null); } catch (Exception e) { - return false; + return null; } - BuildConfiguration build = getBuildConfiguration(projectFolder); - GradleBuild gradleBuild = GradleCore.getWorkspace().createBuild(build); try { gradleBuild.withConnection(connection -> { connection.newBuild().forTasks("wrapper").run(); @@ -569,7 +588,7 @@ public static boolean upgradeGradleVersion(String projectUri, String gradleVersi } catch (Exception e) { // Do nothing } - return true; + return propertiesFile.getAbsolutePath(); } /** @@ -677,7 +696,7 @@ private static File getGradleInitScriptTempFile(String scriptPath) { *
    * @param initScript the init script file. * @param checksum the expected checksum of the file. - * + * * @throws IOException * @throws NoSuchAlgorithmException */ diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleUtils.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleUtils.java index 99c976a9cc..300c6af443 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleUtils.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/managers/GradleUtils.java @@ -28,9 +28,9 @@ public class GradleUtils { public static String MAX_SUPPORTED_JAVA = JavaCore.VERSION_17; - public static String CURRENT_GRADLE = "7.3.1"; // see https://github.com/gradle/gradle/pull/17397 public static String INVALID_TYPE_FIXED_VERSION = "7.2"; + public static String JPMS_SUPPORTED_VERSION = "7.0"; public static boolean isIncompatible(GradleVersion gradleVersion, String javaVersion) { if (gradleVersion == null || javaVersion == null || javaVersion.isEmpty()) {