User: joe Date: 31 Aug 26 11:36 Revision: f88bdf4ac645e67ca78a3c1ef4ef4bbea1a8b2ce Summary: Override LibraryEntity version of AttachSourcesAction.perform. Fixes #2637 TeamCity URL: http://ci.mcdev.io:80/viewModification.html?tab=vcsModificationFiles&modId=10611&personal=false Index: src/main/kotlin/platform/mcp/fabricloom/FabricLoomDecompileSourceProvider.kt =================================================================== --- src/main/kotlin/platform/mcp/fabricloom/FabricLoomDecompileSourceProvider.kt (revision f0da010c1cfa0cadaa88a9da3088809e0eb57007) +++ src/main/kotlin/platform/mcp/fabricloom/FabricLoomDecompileSourceProvider.kt (revision f88bdf4ac645e67ca78a3c1ef4ef4bbea1a8b2ce) @@ -27,11 +27,16 @@ import com.demonwav.mcdev.util.runWriteActionAndWait import com.intellij.codeInsight.AttachSourcesProvider import com.intellij.openapi.externalSystem.task.TaskCallback +import com.intellij.openapi.project.Project import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.util.ActionCallback +import com.intellij.platform.backend.workspace.WorkspaceModel import com.intellij.platform.workspace.jps.entities.LibraryEntity +import com.intellij.platform.workspace.jps.entities.LibraryRoot +import com.intellij.platform.workspace.jps.entities.LibraryRootTypeId +import com.intellij.platform.workspace.jps.entities.modifyLibraryEntity import com.intellij.psi.PsiFile import com.intellij.psi.PsiJavaFile import java.nio.file.Paths @@ -88,17 +93,39 @@ @Suppress("DialogTitleCapitalization") // Minecraft is a proper noun override fun getBusyText(): String = "Decompiling Minecraft..." + @Deprecated("Deprecated in AttachSourcesAction") override fun perform(orderEntriesContainingFile: List): ActionCallback { val project = orderEntriesContainingFile.firstOrNull()?.ownerModule?.project ?: return ActionCallback.REJECTED + return performInternal(project) { + attachSources(orderEntriesContainingFile, decompiler.sourcesPath) + } + } + + override fun perform( + libraryEntities: Collection, + project: Project + ): ActionCallback { + return performInternal(project) { + attachSources(project, libraryEntities, decompiler.sourcesPath) + } + } + + private fun performInternal(project: Project, attachSources: () -> ActionCallback): ActionCallback { val projectPath = project.basePath ?: return ActionCallback.REJECTED val callback = ActionCallback() val taskCallback = object : TaskCallback { override fun onSuccess() { - attachSources(orderEntriesContainingFile, decompiler.sourcesPath) + val innerCallback = attachSources() + innerCallback.doWhenProcessed { + if (innerCallback.isDone) { - callback.setDone() + callback.setDone() + } else { + callback.setRejected() - } + } + } + } override fun onFailure() = callback.setRejected() } @@ -112,7 +139,7 @@ return callback } - private fun attachSources(libraryEntries: List, sourcePath: String): ActionCallback? { + private fun attachSources(libraryEntries: List, sourcePath: String): ActionCallback { // Distinct because for some reason the same library is in there twice for (libraryEntry in libraryEntries.distinctBy { it.libraryName }) { val library = libraryEntry.library @@ -131,5 +158,22 @@ return ActionCallback.DONE } + + private fun attachSources(project: Project, libraryEntities: Collection, sourcePath: String): ActionCallback { + runWriteActionAndWait { + val model = WorkspaceModel.getInstance(project) + model.updateProjectModel("Attaching sources") { storage -> + for (libraryEntity in libraryEntities.distinctBy { it.name }) { + storage.modifyLibraryEntity(libraryEntity) { + roots += LibraryRoot( + model.getVirtualFileUrlManager().getOrCreateFromUrl("jar://$sourcePath!/"), + LibraryRootTypeId.SOURCES + ) - } -} + } + } + } + } + return ActionCallback.DONE + } + } +} Index: src/main/kotlin/platform/mcp/vanillagradle/VanillaGradleDecompileSourceProvider.kt =================================================================== --- src/main/kotlin/platform/mcp/vanillagradle/VanillaGradleDecompileSourceProvider.kt (revision f0da010c1cfa0cadaa88a9da3088809e0eb57007) +++ src/main/kotlin/platform/mcp/vanillagradle/VanillaGradleDecompileSourceProvider.kt (revision f88bdf4ac645e67ca78a3c1ef4ef4bbea1a8b2ce) @@ -29,6 +29,7 @@ import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback import com.intellij.openapi.externalSystem.task.TaskCallback import com.intellij.openapi.externalSystem.util.ExternalSystemUtil +import com.intellij.openapi.project.Project import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.util.ActionCallback import com.intellij.platform.workspace.jps.entities.LibraryEntity @@ -48,9 +49,9 @@ } override fun getLibrariesActions( - orderEntries: Collection, + libraryEntities: Collection, psiFile: PsiFile, - ): Collection { + ): Collection { return getDecompileActions(psiFile) } @@ -72,9 +73,18 @@ override fun getBusyText(): String = @Suppress("DialogTitleCapitalization") "Decompiling Minecraft..." + @Deprecated("Deprecated in AttachSourcesAction") override fun perform(orderEntriesContainingFile: List): ActionCallback { val project = orderEntriesContainingFile.firstOrNull()?.ownerModule?.project ?: return ActionCallback.REJECTED + return performInternal(project) + } + + override fun perform(libraryEntities: Collection, project: Project): ActionCallback { + return performInternal(project) + } + + private fun performInternal(project: Project): ActionCallback { val projectPath = project.basePath ?: return ActionCallback.REJECTED val callback = ActionCallback()