|
| 1 | +package org.jetbrains.plugins.scala.uiTests.backend |
| 2 | + |
| 3 | +import com.intellij.configurationStore.StoreUtil |
| 4 | +import com.intellij.openapi.application.WriteAction |
| 5 | +import com.intellij.openapi.module.ModuleManager |
| 6 | +import com.intellij.openapi.progress.ProgressIndicator |
| 7 | +import com.intellij.openapi.project.ProjectManager |
| 8 | +import com.intellij.openapi.roots.impl.libraries.LibraryEx |
| 9 | +import com.intellij.openapi.roots.libraries.{Library, LibraryProperties, LibraryTable, LibraryTablesRegistrar, LibraryType, NewLibraryConfiguration} |
| 10 | +import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil |
| 11 | +import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor |
| 12 | +import com.intellij.openapi.roots.{ModifiableRootModel, ModuleRootModificationUtil} |
| 13 | +import org.apache.ivy.util.MessageLogger |
| 14 | +import org.jetbrains.annotations.NotNull |
| 15 | +import org.jetbrains.plugins.scala.{DependencyManagerBase, ScalaBundle, ScalaVersion} |
| 16 | +import org.jetbrains.plugins.scala.components.libextensions.ProgressIndicatorLogger |
| 17 | +import org.jetbrains.plugins.scala.extensions.withProgressSynchronouslyTry |
| 18 | +import org.jetbrains.plugins.scala.project.ScalaLibraryType |
| 19 | +import org.jetbrains.plugins.scala.project.template.ScalaVersionDownloadingDialog.{ScalaVersionResolveResult, createScalaVersionResolveResult} |
| 20 | +import org.jetbrains.plugins.scala.project.template.{Artifact, ScalaSdkDescriptor, ScalaVersionDownloadingDialog} |
| 21 | + |
| 22 | +import scala.util.Try |
| 23 | + |
| 24 | +private[backend] object ScalaSdkUtilImpl { |
| 25 | + def setupScalaSdk(@NotNull scalaVersionString: String): Unit = { |
| 26 | + val project = ProjectManager.getInstance.getOpenProjects()(0) |
| 27 | + val module = ModuleManager.getInstance(project).getModules()(0) |
| 28 | + |
| 29 | + val newLibraryConfiguration = createNewScalaLibraryConfiguration(scalaVersionString) |
| 30 | + ModuleRootModificationUtil.updateModel(module, (model: ModifiableRootModel) => { |
| 31 | + addProjectLibrary(model, newLibraryConfiguration) |
| 32 | + }) |
| 33 | + |
| 34 | + StoreUtil.saveSettings(project, true) |
| 35 | + } |
| 36 | + |
| 37 | + private def createNewScalaLibraryConfiguration(scalaVersionString: String): NewLibraryConfiguration = { |
| 38 | + val scalaVersion = ScalaVersion.fromString(scalaVersionString).getOrElse { |
| 39 | + throw new IllegalArgumentException(s"Invalid scala version: $scalaVersionString") |
| 40 | + } |
| 41 | + val resolvedScalaVersion = tryDownloadScalaWithProgress(scalaVersion).get |
| 42 | + val scalaSdkDescriptor = convertScalaResolveResultToScalaSdkDescriptor(resolvedScalaVersion) |
| 43 | + |
| 44 | + ScalaLibraryType.Description.createNewScalaLibrary(scalaSdkDescriptor) |
| 45 | + } |
| 46 | + |
| 47 | + //Copied from: |
| 48 | + // com.intellij.testFramework.PsiTestUtil.addProjectLibrary(com.intellij.openapi.roots.ModifiableRootModel, java.lang.String, java.util.List<? extends com.intellij.openapi.vfs.VirtualFile>, java.util.List<? extends com.intellij.openapi.vfs.VirtualFile>, java.util.List<? extends com.intellij.openapi.vfs.VirtualFile>, java.util.List<? extends com.intellij.openapi.vfs.VirtualFile>) |
| 49 | + private def addProjectLibrary( |
| 50 | + model: ModifiableRootModel, |
| 51 | + libraryConfiguration: NewLibraryConfiguration, |
| 52 | + ): Library = { |
| 53 | + WriteAction.computeAndWait(() => { |
| 54 | + val libraryTableModel: LibraryTable.ModifiableModel = model.getModuleLibraryTable.getModifiableModel |
| 55 | + |
| 56 | + val projectLibraryTable: LibraryTable = LibraryTablesRegistrar.getInstance.getLibraryTable(model.getProject) |
| 57 | + |
| 58 | + val libraryName = LibraryEditingUtil.suggestNewLibraryName(libraryTableModel, libraryConfiguration.getDefaultLibraryName) |
| 59 | + val library: Library = projectLibraryTable.createLibrary(libraryName) |
| 60 | + val libraryModel = library.getModifiableModel.asInstanceOf[LibraryEx.ModifiableModelEx] |
| 61 | + |
| 62 | + try { |
| 63 | + //NOTE: the red code comes from SCL-23078 |
| 64 | + val libraryType: LibraryType[_ <: LibraryProperties[_]] = libraryConfiguration.getLibraryType |
| 65 | + val libraryKind = if (libraryType != null) libraryType.getKind else null |
| 66 | + libraryModel.setKind(libraryKind) |
| 67 | + |
| 68 | + val editor = new NewLibraryEditor(libraryType, libraryConfiguration.getProperties) |
| 69 | + libraryConfiguration.addRoots(editor) |
| 70 | + editor.applyTo(libraryModel) |
| 71 | + } catch { |
| 72 | + case t: Throwable => |
| 73 | + //noinspection SSBasedInspection |
| 74 | + libraryTableModel.dispose() |
| 75 | + throw t |
| 76 | + } |
| 77 | + |
| 78 | + libraryModel.commit() |
| 79 | + libraryTableModel.commit() |
| 80 | + |
| 81 | + model.addLibraryEntry(library) |
| 82 | + |
| 83 | + library |
| 84 | + }) |
| 85 | + } |
| 86 | + |
| 87 | + private def tryDownloadScalaWithProgress(scalaVersion: ScalaVersion): Try[ScalaVersionResolveResult] = { |
| 88 | + withProgressSynchronouslyTry(ScalaBundle.message("downloading.scala.version", scalaVersion.minor), canBeCanceled = true) { manager => |
| 89 | + val indicator = manager.getProgressIndicator |
| 90 | + val dependencyManager = new DependencyManagerBase { |
| 91 | + override protected def progressIndicator: Option[ProgressIndicator] = Some(indicator) |
| 92 | + override def createLogger: MessageLogger = new ProgressIndicatorLogger(indicator) |
| 93 | + } |
| 94 | + createScalaVersionResolveResult(scalaVersion, dependencyManager) |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + private val ScalaLibraryFileNames = Artifact.ScalaLibraryAndModulesArtifacts.map(_.prefix) |
| 99 | + |
| 100 | + private def convertScalaResolveResultToScalaSdkDescriptor(scalaVersionResolveResult: ScalaVersionResolveResult): ScalaSdkDescriptor = { |
| 101 | + val compilerJars = scalaVersionResolveResult.compilerClassPathJars |
| 102 | + val libraryJars = compilerJars.filter(f => ScalaLibraryFileNames.exists(f.getFileName.toString.startsWith(_))) |
| 103 | + val scaladocExtraClasspath = Nil // TODO SCL-17219 |
| 104 | + ScalaSdkDescriptor( |
| 105 | + version = Some(scalaVersionResolveResult.scalaVersion), |
| 106 | + label = None, |
| 107 | + compilerClasspath = compilerJars, |
| 108 | + scaladocExtraClasspath = scaladocExtraClasspath, |
| 109 | + libraryFiles = libraryJars, |
| 110 | + sourceFiles = scalaVersionResolveResult.librarySourcesJars, |
| 111 | + docFiles = Nil, // docs are not downloaded |
| 112 | + compilerBridgeJar = scalaVersionResolveResult.compilerBridgeJar, |
| 113 | + replClasspath = None |
| 114 | + ) |
| 115 | + } |
| 116 | +} |
0 commit comments