cleanup SDK related APIs, move classes, add docs

GitOrigin-RevId: f8d2bbf800285d80461a61cbd0bc6f9a0b95a6e5
This commit is contained in:
Eugene Petrenko
2020-01-16 08:11:51 +00:00
committed by intellij-monorepo-bot
parent b0b06a9e32
commit a6ea44ba4d
13 changed files with 193 additions and 162 deletions
@@ -7,9 +7,8 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.*
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.*
import com.intellij.openapi.roots.ui.configuration.SdkDetector
import com.intellij.openapi.roots.ui.configuration.*
import com.intellij.openapi.roots.ui.configuration.UnknownSdkResolver.*
import com.intellij.openapi.roots.ui.configuration.SdkDetector.DetectedSdkListener
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTask
import com.intellij.openapi.util.registry.Registry
@@ -31,7 +30,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
JdkListDownloader.downloadModelForJdkInstaller(indicator)
}
override fun proposeDownload(sdk: UnknownSdk, indicator: ProgressIndicator): DownloadSdkFix? {
override fun proposeDownload(sdk: UnknownSdk, indicator: ProgressIndicator): UnknownSdkDownloadableSdkFix? {
if (sdk.sdkType != sdkType) return null
val req = JdkRequirements.parseRequirement(sdk) ?: return null
@@ -49,7 +48,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
}.maxBy { it.second }
?.first ?: return null
return object: DownloadSdkFix {
return object: UnknownSdkDownloadableSdkFix {
override fun getDownloadDescription() = jdkToDownload.fullPresentationText
override fun createTask(indicator: ProgressIndicator): SdkDownloadTask {
@@ -75,7 +74,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
result
}
override fun proposeLocalFix(sdk: UnknownSdk, indicator: ProgressIndicator): LocalSdkFix? {
override fun proposeLocalFix(sdk: UnknownSdk, indicator: ProgressIndicator): UnknownSdkLocalSdkFix? {
if (sdk.sdkType != sdkType) return null
val req = JdkRequirements.parseRequirement(sdk) ?: return null
@@ -107,7 +106,7 @@ class JdkAuto : UnknownSdkResolver, JdkDownloaderBase {
private class JavaLocalSdkFix(val homeDir: String,
val version: JavaVersion,
val suggestedName: String) : LocalSdkFix {
val suggestedName: String) : UnknownSdkLocalSdkFix {
override fun getExistingSdkHome() = homeDir
override fun getVersionString() = JdkVersionDetector.formatVersionString(version)
override fun getSuggestedSdkName() : String = suggestedName
@@ -3,7 +3,7 @@ package com.intellij.jdkDownloader
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.UnknownSdk
import com.intellij.openapi.roots.ui.configuration.UnknownSdk
import com.intellij.util.lang.JavaVersion
@@ -7,6 +7,8 @@ import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.roots.ui.configuration.SdkListPresenter;
import com.intellij.openapi.roots.ui.configuration.UnknownSdk;
import com.intellij.openapi.roots.ui.configuration.UnknownSdkLocalSdkFix;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
@@ -15,7 +17,6 @@ import java.util.Set;
import java.util.TreeSet;
import static com.intellij.notification.NotificationAction.createSimple;
import static com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.*;
public class UnknownSdkBalloonNotification {
private static final NotificationGroup SDK_CONFIGURED_GROUP
@@ -32,7 +33,7 @@ public class UnknownSdkBalloonNotification {
myProject = project;
}
public void notifyFixedSdks(@NotNull Map<? extends UnknownSdk, LocalSdkFix> localFixes) {
public void notifyFixedSdks(@NotNull Map<? extends UnknownSdk, UnknownSdkLocalSdkFix> localFixes) {
if (localFixes.isEmpty()) return;
final String title;
@@ -40,8 +41,8 @@ public class UnknownSdkBalloonNotification {
final StringBuilder message = new StringBuilder();
Set<String> usages = new TreeSet<>();
for (Map.Entry<? extends UnknownSdk, LocalSdkFix> entry : localFixes.entrySet()) {
LocalSdkFix fix = entry.getValue();
for (Map.Entry<? extends UnknownSdk, UnknownSdkLocalSdkFix> entry : localFixes.entrySet()) {
UnknownSdkLocalSdkFix fix = entry.getValue();
String usage = "\"" + entry.getKey().getSdkName() + "\"" +
" is set to " +
fix.getVersionString() +
@@ -52,7 +53,7 @@ public class UnknownSdkBalloonNotification {
message.append(StringUtil.join(usages, "<br/><br/>"));
if (localFixes.size() == 1) {
Map.Entry<? extends UnknownSdk, LocalSdkFix> entry = localFixes.entrySet().iterator().next();
Map.Entry<? extends UnknownSdk, UnknownSdkLocalSdkFix> entry = localFixes.entrySet().iterator().next();
UnknownSdk info = entry.getKey();
String sdkTypeName = info.getSdkType().getPresentableName();
title = sdkTypeName + " is configured";
@@ -8,7 +8,7 @@ import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.progress.ProgressManager.checkCanceled
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.SdkType
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.UnknownSdk
import com.intellij.openapi.roots.ui.configuration.UnknownSdk
import com.intellij.openapi.roots.ModuleJdkOrderEntry
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ProjectRootManager
@@ -11,8 +11,8 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.DownloadSdkFix;
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.UnknownSdk;
import com.intellij.openapi.roots.ui.configuration.UnknownSdk;
import com.intellij.openapi.roots.ui.configuration.UnknownSdkDownloadableSdkFix;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
@@ -83,7 +83,7 @@ public class UnknownSdkEditorNotification implements Disposable {
public void showNotifications(boolean allowProjectSdkValidation,
@NotNull Map<String, SdkType> unifiableSdkNames,
@NotNull Map<UnknownSdk, DownloadSdkFix> files) {
@NotNull Map<UnknownSdk, UnknownSdkDownloadableSdkFix> files) {
ImmutableSet.Builder<SdkFixInfo> notifications = ImmutableSet.builder();
for (Map.Entry<String, SdkType> e : unifiableSdkNames.entrySet()) {
String name = e.getKey();
@@ -91,7 +91,7 @@ public class UnknownSdkEditorNotification implements Disposable {
notifications.add(new SimpleSdkFixInfo(name, type));
}
for (Map.Entry<UnknownSdk, DownloadSdkFix> e : files.entrySet()) {
for (Map.Entry<UnknownSdk, UnknownSdkDownloadableSdkFix> e : files.entrySet()) {
notifications.add(new SimpleSdkFixInfo(e.getKey(), e.getValue()));
}
@@ -144,7 +144,7 @@ public class UnknownSdkEditorNotification implements Disposable {
private final String mySdkName;
@Nullable private final SdkType mySdkType;
@Nullable private final UnknownSdk mySdk;
@Nullable private final DownloadSdkFix myFix;
@Nullable private final UnknownSdkDownloadableSdkFix myFix;
SimpleSdkFixInfo(String sdkName, @Nullable SdkType sdkType) {
mySdkName = sdkName;
@@ -153,7 +153,7 @@ public class UnknownSdkEditorNotification implements Disposable {
myFix = null;
}
SimpleSdkFixInfo(@NotNull UnknownSdk sdk, @NotNull DownloadSdkFix fix) {
SimpleSdkFixInfo(@NotNull UnknownSdk sdk, @NotNull UnknownSdkDownloadableSdkFix fix) {
mySdkName = sdk.getSdkName();
mySdkType = sdk.getSdkType();
mySdk = sdk;
@@ -1,118 +0,0 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.projectRoots.impl;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTask;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Extension point to resolve missing SDKs in a project,
* it is executed from a background thread on project open
* or after project model changes
*/
public interface UnknownSdkResolver {
@ApiStatus.Internal
ExtensionPointName<UnknownSdkResolver> EP_NAME = ExtensionPointName.create("com.intellij.unknownSdkResolver");
/**
* Creates search context. The same object is used to process all unknown SDKs in the project,
* it a good idea to cache any heavy operations inside that instance.
* That method must be cheap to run.
* <br/>
* Return {@code null} to ignore a given request
*/
@Nullable
UnknownSdkLookup createResolver(@Nullable Project project, @NotNull ProgressIndicator indicator);
interface UnknownSdkLookup {
/**
* The implementation should check on a local machine (both in existing SDKs and on the disk)
* for a possible matching SDK
*
* @return best match or {@code null} if there is no fix found
*/
@Nullable
LocalSdkFix proposeLocalFix(@NotNull UnknownSdk sdk, @NotNull ProgressIndicator indicator);
/**
* Checks the internet for a possible download to fix the SDK.
*
* @return the best possible download for {@link com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTracker},
* or {@code null} if there is no fix found
*/
@Nullable
DownloadSdkFix proposeDownload(@NotNull UnknownSdk sdk, @NotNull ProgressIndicator indicator);
}
/**
* Contains information and requirements for the SDK to resolve
*/
@ApiStatus.NonExtendable
interface UnknownSdk {
/**
* Type of SDK to resolve with {@link UnknownSdkLookup}
*/
@NotNull
SdkType getSdkType();
/**
* A missing SDK name, if known. A detector implementation may rely on the naming
* to use it for a better decision on the SDK to suggest.
*/
@Nullable
default String getSdkName() { return null; }
/**
* A minimum version (inclusive) of a resolved SDK.
* {@link SdkType#versionComparator()} will be used for comparison.
*/
@Nullable
default String getSdkMinVersionRequirement() { return null; }
/**
* A maximum version (exclusive) of a resolved SDK.
* {@link SdkType#versionComparator()} will be used for comparison.
*/
@Nullable
default String getSdkMaxVersionRequirement() { return null; }
}
/**
* Locally detected SDK to fix immediately
*/
interface LocalSdkFix {
/**
* @return the resolved home of the detected SDK to configure
*/
@NotNull String getExistingSdkHome();
/**
* @return the actual version string of the SDK
*/
@NotNull String getVersionString();
/**
* @return suggested name for an SDK to be created, still, the name could
* be altered to avoid conflicts
*/
@NotNull
String getSuggestedSdkName();
}
/**
* A download suggestion to fix a missing SDK by downloading it
* @see com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownload
*/
interface DownloadSdkFix {
@NotNull
String getDownloadDescription();
@NotNull
SdkDownloadTask createTask(@NotNull ProgressIndicator indicator);
}
}
@@ -15,10 +15,9 @@ import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.DownloadSdkFix;
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.LocalSdkFix;
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.UnknownSdkLookup;
import com.intellij.openapi.roots.ui.configuration.SdkPopupFactory;
import com.intellij.openapi.roots.ui.configuration.*;
import com.intellij.openapi.roots.ui.configuration.UnknownSdkDownloadableSdkFix;
import com.intellij.openapi.roots.ui.configuration.UnknownSdkResolver.UnknownSdkLookup;
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTask;
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTracker;
import com.intellij.openapi.ui.Messages;
@@ -37,7 +36,6 @@ import javax.swing.*;
import java.util.*;
import static com.intellij.openapi.progress.PerformInBackgroundOption.ALWAYS_BACKGROUND;
import static com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.UnknownSdk;
public class UnknownSdkTracker implements Disposable {
private static final Logger LOG = Logger.getInstance(UnknownSdkTracker.class);
@@ -99,10 +97,10 @@ public class UnknownSdkTracker implements Disposable {
List<UnknownSdkLookup> lookups = collectSdkLookups(indicator);
indicator.setText("Looking for local SDKs...");
Map<UnknownSdk, LocalSdkFix> localFixes = findFixesAndRemoveFixable(indicator, fixable, lookups, UnknownSdkLookup::proposeLocalFix);
Map<UnknownSdk, UnknownSdkLocalSdkFix> localFixes = findFixesAndRemoveFixable(indicator, fixable, lookups, UnknownSdkLookup::proposeLocalFix);
indicator.setText("Looking for downloadable SDKs...");
Map<UnknownSdk, DownloadSdkFix> downloadFixes = findFixesAndRemoveFixable(indicator, fixable, lookups, UnknownSdkLookup::proposeDownload);
Map<UnknownSdk, UnknownSdkDownloadableSdkFix> downloadFixes = findFixesAndRemoveFixable(indicator, fixable, lookups, UnknownSdkLookup::proposeDownload);
fixable.forEach(it -> missingSdks.put(it.getSdkName(), it.getSdkType()));
if (!localFixes.isEmpty()) {
@@ -117,8 +115,8 @@ public class UnknownSdkTracker implements Disposable {
}
private void showStatus(@NotNull Map<String, SdkType> missingSdks,
@NotNull Map<UnknownSdk, LocalSdkFix> localFixes,
@NotNull Map<UnknownSdk, DownloadSdkFix> downloadFixes) {
@NotNull Map<UnknownSdk, UnknownSdkLocalSdkFix> localFixes,
@NotNull Map<UnknownSdk, UnknownSdkDownloadableSdkFix> downloadFixes) {
UnknownSdkBalloonNotification
.getInstance(myProject)
.notifyFixedSdks(localFixes);
@@ -150,7 +148,7 @@ public class UnknownSdkTracker implements Disposable {
return lookups;
}
public void applyDownloadableFix(@NotNull UnknownSdk info, @NotNull DownloadSdkFix fix) {
public void applyDownloadableFix(@NotNull UnknownSdk info, @NotNull UnknownSdkDownloadableSdkFix fix) {
downloadFix(myProject, info, fix, sdk -> {
if (sdk != null) {
updateUnknownSdks();
@@ -161,7 +159,7 @@ public class UnknownSdkTracker implements Disposable {
@ApiStatus.Internal
public static void downloadFix(@Nullable Project project,
@NotNull UnknownSdk info,
@NotNull DownloadSdkFix fix,
@NotNull UnknownSdkDownloadableSdkFix fix,
@NotNull Consumer<? super Sdk> onCompleted) {
SdkDownloadTask task;
String title = "Configuring SDK";
@@ -229,12 +227,12 @@ public class UnknownSdkTracker implements Disposable {
.showUnderneathToTheRightOf(underneathRightOfComponent);
}
private void configureLocalSdks(@NotNull Map<UnknownSdk, LocalSdkFix> localFixes) {
private void configureLocalSdks(@NotNull Map<UnknownSdk, UnknownSdkLocalSdkFix> localFixes) {
if (localFixes.isEmpty()) return;
for (Map.Entry<UnknownSdk, LocalSdkFix> e : localFixes.entrySet()) {
for (Map.Entry<UnknownSdk, UnknownSdkLocalSdkFix> e : localFixes.entrySet()) {
UnknownSdk info = e.getKey();
LocalSdkFix fix = e.getValue();
UnknownSdkLocalSdkFix fix = e.getValue();
configureLocalSdk(info, fix, sdk -> {});
}
@@ -244,7 +242,7 @@ public class UnknownSdkTracker implements Disposable {
@ApiStatus.Internal
public static void configureLocalSdk(@NotNull UnknownSdk info,
@NotNull LocalSdkFix fix,
@NotNull UnknownSdkLocalSdkFix fix,
@NotNull Consumer<? super Sdk> onCompleted) {
ApplicationManager.getApplication().invokeLater(() -> {
try {
@@ -12,13 +12,12 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.SdkType
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver
import com.intellij.openapi.projectRoots.impl.UnknownSdkResolver.*
import com.intellij.openapi.projectRoots.impl.UnknownSdkTracker
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.util.Consumer
import org.jetbrains.annotations.Contract
import org.jetbrains.annotations.Nls
import java.util.function.Predicate
/**
@@ -52,8 +51,8 @@ data class SdkLookupBuilder private constructor(
val sdkMinVersionInclusive: String? = null,
val sdkMaxVersionExclusive: String? = null,
val onLocalSdkSuggested: ((LocalSdkFix) -> Boolean)? = null,
val onDownloadableSdkSuggested: ((DownloadSdkFix) -> Boolean)? = null,
val onLocalSdkSuggested: ((UnknownSdkLocalSdkFix) -> Boolean)? = null,
val onDownloadableSdkSuggested: ((UnknownSdkDownloadableSdkFix) -> Boolean)? = null,
/**
* The [Sdk#sdkType] may not match the proposed [sdkType] if the
@@ -78,8 +77,8 @@ data class SdkLookupBuilder private constructor(
@Contract(pure = true) fun withMinSdkVersionInclusive(version: String) = copy(sdkMinVersionInclusive = version)
@Contract(pure = true) fun withMaxSdkVersionExclusive(version: String) = copy(sdkMaxVersionExclusive = version)
@Contract(pure = true) fun onLocalSdkSuggested(handler: (LocalSdkFix) -> Boolean) = copy(onLocalSdkSuggested = handler)
@Contract(pure = true) fun onDownloadableSdkSuggested(handler: (DownloadSdkFix) -> Boolean) = copy(onDownloadableSdkSuggested = handler)
@Contract(pure = true) fun onLocalSdkSuggested(handler: (UnknownSdkLocalSdkFix) -> Boolean) = copy(onLocalSdkSuggested = handler)
@Contract(pure = true) fun onDownloadableSdkSuggested(handler: (UnknownSdkDownloadableSdkFix) -> Boolean) = copy(onDownloadableSdkSuggested = handler)
@Contract(pure = true) fun onSdkResolved(handler: (Sdk?) -> Unit) = copy(onSdkResolved = handler)
fun lookup() = service<SdkLookup>().lookup(copy())
@@ -119,10 +118,21 @@ internal class SdkLookupImpl : SdkLookup {
return
}
val versionPredicate = if (sdkMinVersionInclusive != null || sdkMaxVersionExclusive != null) {
val vCmp = sdkType.versionStringComparator()
Predicate<String> { version ->
((sdkMinVersionInclusive == null || vCmp.compare(sdkMinVersionInclusive, version) <= 0))
&&
((sdkMaxVersionExclusive == null || vCmp.compare(version, sdkMaxVersionExclusive) > 0))
}
} else {
Predicate { true }
}
val unknownSdk = object: UnknownSdk {
override fun getSdkMinVersionRequirement() = this@run.sdkMinVersionInclusive
override fun getSdkMaxVersionRequirement() = this@run.sdkMaxVersionExclusive
override fun getSdkType() : SdkType = this@run.sdkType
override fun getSdkVersionStringPredicate() = versionPredicate
override fun toString() = "SdkLookup{${sdkType.presentableName}, version in [$sdkMinVersionInclusive, $sdkMaxVersionExclusive) }"
}
runWithProgress(onCancelled = { onSdkResolved?.invoke(null) }) { indicator ->
@@ -0,0 +1,41 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.roots.ui.configuration;
import com.google.common.base.Predicates;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Contains information and requirements for an SDK to resolve
* with {@link UnknownSdkResolver} extension
*/
public interface UnknownSdk {
/**
* Type of SDK to resolve with {@link UnknownSdkResolver.UnknownSdkLookup}
*/
@NotNull
SdkType getSdkType();
/**
* A missing SDK name, if known. A detector implementation may rely on the naming
* to use it for a better decision on the SDK to suggest.
*/
@Nullable
default String getSdkName() { return null; }
/**
* Condition to test a possible SDK candidates to match version
* predicate. We use {@link SdkType#getVersionString(Sdk)} or
* {@link Sdk#getVersionString()} to get versions in most of the cases.
* <br/>
* Use the {@link SdkType#versionComparator()} to better deal with versions comparison
*/
@NotNull
default Predicate<String> getSdkVersionStringPredicate() {
return Predicates.alwaysTrue();
}
}
@@ -0,0 +1,24 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTask;
import org.jetbrains.annotations.NotNull;
/**
* A download suggestion to fix a missing SDK by downloading it
* @see com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownload
*/
public interface UnknownSdkDownloadableSdkFix {
/** User visible description of the proposed download **/
@NotNull
String getDownloadDescription();
/**
* Creates and SDK download task to apply the fix.
* @see com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownload
* @see com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTracker
*/
@NotNull
SdkDownloadTask createTask(@NotNull ProgressIndicator indicator);
}
@@ -0,0 +1,27 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.roots.ui.configuration;
import org.jetbrains.annotations.NotNull;
/**
* Locally detected SDK to fix immediately
*/
public interface UnknownSdkLocalSdkFix {
/**
* @return the resolved home of the detected SDK to configure
*/
@NotNull
String getExistingSdkHome();
/**
* @return the actual version string of the SDK
*/
@NotNull String getVersionString();
/**
* @return suggested name for an SDK to be created, still, the name could
* be altered to avoid conflicts
*/
@NotNull
String getSuggestedSdkName();
}
@@ -0,0 +1,49 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.roots.ui.configuration;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Extension point to resolve missing SDKs in a project,
* it is executed from a background thread on project open
* or after project model changes
*/
public interface UnknownSdkResolver {
@ApiStatus.Internal
ExtensionPointName<UnknownSdkResolver> EP_NAME = ExtensionPointName.create("com.intellij.unknownSdkResolver");
/**
* Creates search context. The same object is used to process all unknown SDKs in the project,
* it a good idea to cache any heavy operations inside that instance.
* That method must be cheap to run.
* <br/>
* Return {@code null} to ignore a given request
*/
@Nullable
UnknownSdkLookup createResolver(@Nullable Project project, @NotNull ProgressIndicator indicator);
interface UnknownSdkLookup {
/**
* The implementation should check on a local machine (both in existing SDKs and on the disk)
* for a possible matching SDK
*
* @return best match or {@code null} if there is no fix found
*/
@Nullable
UnknownSdkLocalSdkFix proposeLocalFix(@NotNull UnknownSdk sdk, @NotNull ProgressIndicator indicator);
/**
* Checks the internet for a possible download to fix the SDK.
*
* @return the best possible download for {@link com.intellij.openapi.roots.ui.configuration.projectRoot.SdkDownloadTracker},
* or {@code null} if there is no fix found
*/
@Nullable
UnknownSdkDownloadableSdkFix proposeDownload(@NotNull UnknownSdk sdk, @NotNull ProgressIndicator indicator);
}
}
@@ -353,7 +353,7 @@
<extensionPoint name="config.inlaySettingsProvider" interface="com.intellij.codeInsight.hints.settings.InlaySettingsProvider"/>
<extensionPoint name="breadcrumbsPresentationProvider" interface="com.intellij.xml.breadcrumbs.BreadcrumbsPresentationProvider"/>
<extensionPoint name="unknownSdkResolver" interface="com.intellij.openapi.projectRoots.impl.UnknownSdkResolver" dynamic="true"/>
<extensionPoint name="unknownSdkResolver" interface="com.intellij.openapi.roots.ui.configuration.UnknownSdkResolver" dynamic="true"/>
<extensionPoint name="pathMacroContributor" interface="com.intellij.openapi.application.PathMacroContributor" dynamic="true"/>
<extensionPoint name="titleInfoProvider" interface="com.intellij.openapi.wm.impl.TitleInfoProvider" area="IDEA_PROJECT"/>