mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 11:50:54 +07:00
[devkit] IDEA-336017 Attach IntelliJ Platform dependency sources
GitOrigin-RevId: 543d07f4d54ad50b9497ca148032ddc526f9292c
This commit is contained in:
committed by
intellij-monorepo-bot
parent
42b017d658
commit
c5a80136b6
@@ -36,14 +36,15 @@ internal class LibraryCoordinatesState : BaseState() {
|
||||
|
||||
private fun getKnownIntellijLibrariesCoordinates(): List<Pair<String, String>> {
|
||||
val result = mutableListOf<Pair<String, String>>()
|
||||
for ((groupId, artifactId) in IntelliJPlatformProduct.values().asSequence().mapNotNull { product ->
|
||||
getMavenCoordinatesOfProduct(product)
|
||||
}) {
|
||||
// original coordinates of the product.
|
||||
result.add(groupId to artifactId)
|
||||
|
||||
// coordinates used in the 'gradle-intellij-plugin' to specify IDE dependency
|
||||
result.add("com.jetbrains" to artifactId)
|
||||
IntelliJPlatformProduct.entries.forEach {
|
||||
it.mavenCoordinates?.split(":")?.let { (groupId,artifactId) ->
|
||||
// original coordinates of the product.
|
||||
result.add(groupId to artifactId)
|
||||
|
||||
// coordinates used in the 'gradle-intellij-plugin' 1.x to specify IDE dependency; obsolete in IntelliJ Platform Gradle Plugin 2.x
|
||||
result.add("com.jetbrains" to artifactId)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -59,29 +60,3 @@ private fun createDefaultState(): LibrariesWithIntellijClassesState {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getMavenCoordinatesOfProduct(product: IntelliJPlatformProduct): Pair<String, String>? {
|
||||
return when (product) {
|
||||
IntelliJPlatformProduct.IDEA -> "com.jetbrains.intellij.idea" to "ideaIU"
|
||||
IntelliJPlatformProduct.IDEA_IC -> "com.jetbrains.intellij.idea" to "ideaIC"
|
||||
IntelliJPlatformProduct.CLION -> "com.jetbrains.intellij.clion" to "clion"
|
||||
IntelliJPlatformProduct.PYCHARM -> "com.jetbrains.intellij.pycharm" to "pycharmPY"
|
||||
IntelliJPlatformProduct.PYCHARM_PC -> "com.jetbrains.intellij.pycharm" to "pycharmPC"
|
||||
IntelliJPlatformProduct.RIDER -> "com.jetbrains.intellij.rider" to "riderRD"
|
||||
IntelliJPlatformProduct.GOIDE -> "com.jetbrains.intellij.goland" to "goland"
|
||||
|
||||
IntelliJPlatformProduct.RUBYMINE,
|
||||
IntelliJPlatformProduct.DATASPELL,
|
||||
IntelliJPlatformProduct.PYCHARM_EDU,
|
||||
IntelliJPlatformProduct.PHPSTORM,
|
||||
IntelliJPlatformProduct.WEBSTORM,
|
||||
IntelliJPlatformProduct.APPCODE,
|
||||
IntelliJPlatformProduct.MOBILE_IDE,
|
||||
IntelliJPlatformProduct.DBE,
|
||||
IntelliJPlatformProduct.ANDROID_STUDIO,
|
||||
IntelliJPlatformProduct.CWM_GUEST,
|
||||
IntelliJPlatformProduct.JETBRAINS_CLIENT,
|
||||
IntelliJPlatformProduct.GATEWAY,
|
||||
IntelliJPlatformProduct.IDEA_IE -> null
|
||||
}
|
||||
}
|
||||
@@ -2,38 +2,45 @@
|
||||
package org.jetbrains.idea.devkit.projectRoots;
|
||||
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public enum IntelliJPlatformProduct {
|
||||
IDEA("IU", "IntelliJ IDEA", null),
|
||||
IDEA_IC("IC", "IntelliJ IDEA Community Edition", PlatformUtils.IDEA_CE_PREFIX),
|
||||
IDEA_IE("IE", "IntelliJ IDEA Educational Edition", PlatformUtils.IDEA_EDU_PREFIX),
|
||||
RUBYMINE("RM", "RubyMine", PlatformUtils.RUBY_PREFIX),
|
||||
PYCHARM("PY", "PyCharm", PlatformUtils.PYCHARM_PREFIX),
|
||||
PYCHARM_PC("PC", "PyCharm Community Edition", PlatformUtils.PYCHARM_CE_PREFIX),
|
||||
DATASPELL("DS", "DataSpell", PlatformUtils.DATASPELL_PREFIX),
|
||||
PYCHARM_EDU("PE", "PyCharm Educational Edition", PlatformUtils.PYCHARM_EDU_PREFIX),
|
||||
PHPSTORM("PS", "PhpStorm", PlatformUtils.PHP_PREFIX),
|
||||
WEBSTORM("WS", "WebStorm", PlatformUtils.WEB_PREFIX),
|
||||
APPCODE("OC", "AppCode", PlatformUtils.APPCODE_PREFIX),
|
||||
CLION("CL", "CLion", PlatformUtils.CLION_PREFIX),
|
||||
MOBILE_IDE("MI", "Mobile IDE", PlatformUtils.MOBILE_IDE_PREFIX),
|
||||
DBE("DB", "DataGrip", PlatformUtils.DBE_PREFIX),
|
||||
RIDER("RD", "Rider", PlatformUtils.RIDER_PREFIX),
|
||||
GOIDE("GO", "GoLand", PlatformUtils.GOIDE_PREFIX),
|
||||
ANDROID_STUDIO("AI", "Android Studio", "AndroidStudio"),
|
||||
IDEA("IU", "IntelliJ IDEA", null, "com.jetbrains.intellij.idea:ideaIU"),
|
||||
IDEA_IC("IC", "IntelliJ IDEA Community Edition", PlatformUtils.IDEA_CE_PREFIX, "com.jetbrains.intellij.idea:ideaIC"),
|
||||
IDEA_IE("IE", "IntelliJ IDEA Educational Edition", PlatformUtils.IDEA_EDU_PREFIX, null),
|
||||
RUBYMINE("RM", "RubyMine", PlatformUtils.RUBY_PREFIX, null),
|
||||
PYCHARM("PY", "PyCharm", PlatformUtils.PYCHARM_PREFIX, "com.jetbrains.intellij.pycharm:pycharmPY"),
|
||||
PYCHARM_PC("PC", "PyCharm Community Edition", PlatformUtils.PYCHARM_CE_PREFIX, "com.jetbrains.intellij.pycharm:pycharmPC"),
|
||||
DATASPELL("DS", "DataSpell", PlatformUtils.DATASPELL_PREFIX, null),
|
||||
PYCHARM_EDU("PE", "PyCharm Educational Edition", PlatformUtils.PYCHARM_EDU_PREFIX, null),
|
||||
PHPSTORM("PS", "PhpStorm", PlatformUtils.PHP_PREFIX, "com.jetbrains.intellij.phpstorm:phpstorm"),
|
||||
WEBSTORM("WS", "WebStorm", PlatformUtils.WEB_PREFIX, null),
|
||||
APPCODE("OC", "AppCode", PlatformUtils.APPCODE_PREFIX, null),
|
||||
CLION("CL", "CLion", PlatformUtils.CLION_PREFIX, "com.jetbrains.intellij.clion:clion"),
|
||||
MOBILE_IDE("MI", "Mobile IDE", PlatformUtils.MOBILE_IDE_PREFIX, null),
|
||||
DBE("DB", "DataGrip", PlatformUtils.DBE_PREFIX, null),
|
||||
RIDER("RD", "Rider", PlatformUtils.RIDER_PREFIX, "com.jetbrains.intellij.rider:riderRD"),
|
||||
GOIDE("GO", "GoLand", PlatformUtils.GOIDE_PREFIX, "com.jetbrains.intellij.goland:goland"),
|
||||
ANDROID_STUDIO("AI", "Android Studio", "AndroidStudio", null),
|
||||
/**
|
||||
* @deprecated Code With Me Guest is an old name for JetBrains Client
|
||||
*/
|
||||
@Deprecated
|
||||
CWM_GUEST("CWMG", "Code With Me Guest", PlatformUtils.CWM_GUEST_PREFIX),
|
||||
JETBRAINS_CLIENT("JBC", "JetBrains Client", PlatformUtils.JETBRAINS_CLIENT_PREFIX),
|
||||
GATEWAY("GW", "Gateway", PlatformUtils.GATEWAY_PREFIX);
|
||||
CWM_GUEST("CWMG", "Code With Me Guest", PlatformUtils.CWM_GUEST_PREFIX, null),
|
||||
JETBRAINS_CLIENT("JBC", "JetBrains Client", PlatformUtils.JETBRAINS_CLIENT_PREFIX, null),
|
||||
GATEWAY("GW", "Gateway", PlatformUtils.GATEWAY_PREFIX, "com.jetbrains.intellij.gateway:gateway"),
|
||||
FLEET_BACKEND("FLIJ", "Fleet Backend", PlatformUtils.FLEET_PREFIX, "com.jetbrains.intellij.fleetBackend:fleetBackend");
|
||||
|
||||
private final String myProductCode;
|
||||
private final String myName;
|
||||
private final String myPlatformPrefix;
|
||||
private final String myMavenCoordinates;
|
||||
|
||||
public @NonNls String getName() {
|
||||
return myName;
|
||||
@@ -43,10 +50,18 @@ public enum IntelliJPlatformProduct {
|
||||
return myPlatformPrefix;
|
||||
}
|
||||
|
||||
IntelliJPlatformProduct(@NonNls String productCode,@NonNls String name, @NonNls String platformPrefix) {
|
||||
/**
|
||||
* Provides Maven coordinates which can be used for resolving artifact from the IntelliJ Repository.
|
||||
*/
|
||||
public @Nullable String getMavenCoordinates() {
|
||||
return myMavenCoordinates;
|
||||
}
|
||||
|
||||
IntelliJPlatformProduct(@NonNls String productCode, @NonNls String name, @NonNls String platformPrefix, @Nullable String mavenCoordinates) {
|
||||
myProductCode = productCode;
|
||||
myName = name;
|
||||
myPlatformPrefix = platformPrefix;
|
||||
myMavenCoordinates = mavenCoordinates;
|
||||
}
|
||||
|
||||
public static IntelliJPlatformProduct fromBuildNumber(String buildNumber) {
|
||||
@@ -57,4 +72,8 @@ public enum IntelliJPlatformProduct {
|
||||
}
|
||||
return IDEA;
|
||||
}
|
||||
|
||||
public static @Nullable IntelliJPlatformProduct fromMavenCoordinates(String groupId, String artifactId) {
|
||||
return ContainerUtil.find(values(), product -> Objects.equals(product.getMavenCoordinates(), groupId + ":" + artifactId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.projectRoots;
|
||||
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
|
||||
import static org.jetbrains.idea.devkit.projectRoots.IntelliJPlatformProduct.fromMavenCoordinates;
|
||||
|
||||
public class IntelliJPlatformProductTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
public void testFromMavenCoordinates() {
|
||||
assertSame(fromMavenCoordinates("com.jetbrains.intellij.idea", "ideaIU"), IntelliJPlatformProduct.IDEA);
|
||||
assertSame(fromMavenCoordinates("com.jetbrains.intellij.idea", "ideaIC"), IntelliJPlatformProduct.IDEA_IC);
|
||||
assertSame(fromMavenCoordinates("com.jetbrains.intellij.phpstorm", "phpstorm"), IntelliJPlatformProduct.PHPSTORM);
|
||||
assertSame(fromMavenCoordinates("foo", "bar"), null);
|
||||
}
|
||||
}
|
||||
@@ -27,5 +27,6 @@
|
||||
<orderEntry type="module" module-name="intellij.platform.core.ui" />
|
||||
<orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.java.testFramework" scope="TEST" />
|
||||
<orderEntry type="module" module-name="intellij.java" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -9,6 +9,7 @@
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<attachSourcesProvider implementation="org.jetbrains.idea.devkit.gradle.IntelliJPlatformAttachSourcesProvider"/>
|
||||
<consoleFilterProvider implementation="org.jetbrains.idea.devkit.gradle.GradlePluginConsoleFilterProvider"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
module.wizard.gradle.presentable.name=IntelliJ Platform Plugin
|
||||
module.wizard.gradle.learn.title=Learn how to <a>build plugins with Gradle</a>
|
||||
attachSources.action.name=Download IntelliJ Platform sources
|
||||
attachSources.action.busyText=Downloading IntelliJ Platform sources\u2026
|
||||
attachLSPSources.action.name=Attach IntelliJ Platform LSP-API sources
|
||||
attachLSPSources.action.busyText=Attaching IntelliJ Platform LSP-API sources\u2026
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.idea.devkit.gradle
|
||||
|
||||
import com.intellij.codeInsight.AttachSourcesProvider
|
||||
import com.intellij.codeInsight.AttachSourcesProvider.AttachSourcesAction
|
||||
import com.intellij.jarFinder.InternetAttachSourceProvider
|
||||
import com.intellij.java.library.MavenCoordinates
|
||||
import com.intellij.java.library.getMavenCoordinates
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.util.ActionCallback
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.findFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.idea.devkit.projectRoots.IntelliJPlatformProduct
|
||||
import org.jetbrains.plugins.gradle.util.GradleDependencySourceDownloader
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Attaches sources to the IntelliJ Platform dependencies in projects using IntelliJ Platform Gradle Plugin 2.x.
|
||||
* Some IDEs, like IntelliJ IDEA Ultimate or PhpStorm, don't provide sources for artifacts published to IntelliJ Repository.
|
||||
* To handle such a case, IntelliJ IDEA Community sources are attached.
|
||||
*/
|
||||
class IntelliJPlatformAttachSourcesProvider : AttachSourcesProvider {
|
||||
|
||||
override fun getActions(orderEntries: MutableList<out LibraryOrderEntry>, psiFile: PsiFile): List<AttachSourcesAction> {
|
||||
// Search for a product that matches any of the entry coordinates. Return both product and coordinates, to refer to the same version.
|
||||
val (product, libraryCoordinates) = orderEntries.mapNotNull {
|
||||
it.library?.getMavenCoordinates()
|
||||
}.firstNotNullOfOrNull { coordinates ->
|
||||
val product = IntelliJPlatformProduct.fromMavenCoordinates(coordinates.groupId, coordinates.artifactId)
|
||||
if (product == null) {
|
||||
return@firstNotNullOfOrNull null
|
||||
}
|
||||
product to coordinates
|
||||
} ?: return emptyList()
|
||||
|
||||
// We're checking if the compiled class belongs to the `/com/intellij/platform/lsp/` package, but not `.../impl` as it's not part of the API
|
||||
val isLspApi = with(psiFile.virtualFile.path.substringAfter('!')) {
|
||||
when {
|
||||
startsWith("/com/intellij/platform/lsp/impl/") -> false
|
||||
startsWith("/com/intellij/platform/lsp/") -> true
|
||||
else -> false
|
||||
} && product == IntelliJPlatformProduct.IDEA // LSP API sources are provided only with IU
|
||||
}
|
||||
|
||||
val action = when {
|
||||
isLspApi -> createAttachLSPSourcesAction(psiFile)
|
||||
else -> createAttachPlatformSourcesAction(psiFile, product, libraryCoordinates)
|
||||
}
|
||||
|
||||
return action?.let { listOf(it) } ?: emptyList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve and attach IntelliJ IDEA Community or PyCharm Community sources to the IntelliJ Platform dependency in requested version.
|
||||
*/
|
||||
private fun createAttachPlatformSourcesAction(
|
||||
psiFile: PsiFile,
|
||||
product: IntelliJPlatformProduct,
|
||||
libraryCoordinates: MavenCoordinates,
|
||||
): AttachSourcesAction? {
|
||||
val productCoordinates =
|
||||
when (product) {
|
||||
IntelliJPlatformProduct.PYCHARM, IntelliJPlatformProduct.PYCHARM_PC -> IntelliJPlatformProduct.PYCHARM_PC
|
||||
else -> IntelliJPlatformProduct.IDEA_IC
|
||||
}.mavenCoordinates ?: return null
|
||||
|
||||
return object : AttachSourcesAction {
|
||||
override fun getName() = DevKitGradleBundle.message("attachSources.action.name")
|
||||
|
||||
override fun getBusyText() = DevKitGradleBundle.message("attachSources.action.busyText")
|
||||
|
||||
override fun perform(orderEntries: MutableList<out LibraryOrderEntry>): ActionCallback {
|
||||
val externalProjectPath = orderEntries.first().ownerModule.let {
|
||||
ExternalSystemApiUtil.getExternalRootProjectPath(it)
|
||||
} ?: return ActionCallback.REJECTED
|
||||
|
||||
val executionResult = ActionCallback()
|
||||
val project = psiFile.project
|
||||
val sourceArtifactNotation = "$productCoordinates:${libraryCoordinates.version}:sources"
|
||||
|
||||
GradleDependencySourceDownloader.downloadSources(project, name, sourceArtifactNotation, externalProjectPath).whenComplete { path, error ->
|
||||
if (error != null) {
|
||||
executionResult.setRejected()
|
||||
}
|
||||
else {
|
||||
attachSources(path, orderEntries) {
|
||||
executionResult.setDone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return executionResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When targeting IntelliJ IDEA Ultimate, it is possible to attach LSP module sources.
|
||||
* If the compiled class belongs to `com/intellij/platform/lsp/`, suggest attaching relevant ZIP archive with LSP sources.
|
||||
*/
|
||||
private fun createAttachLSPSourcesAction(psiFile: PsiFile): AttachSourcesAction? {
|
||||
val jarFile = VfsUtilCore.getVirtualFileForJar(psiFile.virtualFile) ?: return null
|
||||
val sources = jarFile.parent.findFile("src/src_lsp-openapi.zip") ?: return null
|
||||
|
||||
return object : AttachSourcesAction {
|
||||
override fun getName() = DevKitGradleBundle.message("attachLSPSources.action.name")
|
||||
|
||||
override fun getBusyText() = DevKitGradleBundle.message("attachLSPSources.action.busyText")
|
||||
|
||||
override fun perform(orderEntries: MutableList<out LibraryOrderEntry>): ActionCallback {
|
||||
val executionResult = ActionCallback()
|
||||
|
||||
attachSources(sources.toNioPath().toFile(), orderEntries) {
|
||||
executionResult.setDone()
|
||||
}
|
||||
|
||||
return executionResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches sources jar to the specified libraries and executes the provided block of code.
|
||||
*/
|
||||
private fun attachSources(path: File, orderEntries: MutableList<out LibraryOrderEntry>, block: () -> Unit) {
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
InternetAttachSourceProvider.attachSourceJar(path, orderEntries.mapNotNull { it.library })
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user