Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement forcing Scala 3 for crossbuilding projects #661

Open
wants to merge 1 commit into
base: idea241.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion project/dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ object Versions {
val junitInterfaceVersion: String = "0.13.3"

val bspVersion = "2.1.0-M3"
val sbtStructureVersion: String = "2024.1.2"
val sbtStructureVersion: String = "2024.1.2+0-38de1c9e+20240519-1859-SNAPSHOT"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's invalid, but sbt structure release will be required before merge anyway

val sbtIdeaShellVersion: String = "2021.1.0"
val compilerIndicesVersion = "1.0.14"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class SbtProjectSettings extends ExternalProjectSettings {
//Settings used during SBT project import/reload
@BeanProperty var resolveClassifiers: Boolean = true
@BeanProperty var resolveSbtClassifiers: Boolean = false
@BeanProperty var preferScala2 = true
@BeanProperty var preferedScala: Int = 0
//See SCL-21158 for details
//This should be in sync with what is used as a default value in
// org.jetbrains.jps.incremental.scala.model.impl.JpsSbtDependenciesEnumerationHandler.shouldProcessDependenciesRecursively
Expand Down Expand Up @@ -103,7 +103,7 @@ class SbtProjectSettings extends ExternalProjectSettings {
result.useSbtShellForImport = useSbtShellForImport
result.useSbtShellForBuild = useSbtShellForBuild
result.enableDebugSbtShell = enableDebugSbtShell
result.preferScala2 = preferScala2
result.preferedScala = preferedScala
result.insertProjectTransitiveDependencies = insertProjectTransitiveDependencies
result.useSeparateCompilerOutputPaths = useSeparateCompilerOutputPaths
result
Expand All @@ -112,7 +112,7 @@ class SbtProjectSettings extends ExternalProjectSettings {

object SbtProjectSettings {
// Increment if the converter algorithm is updated to trigger a reloading of previously opened projects.
val ConverterVersion = 2
val ConverterVersion = 3

def default: SbtProjectSettings = {
val settings = new SbtProjectSettings()
Expand Down
3 changes: 2 additions & 1 deletion sbt/sbt-impl/resources/messages/SbtBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ sbt.settings.resolvers=Resolvers
sbt.settings.noImplicitImportsFound=No implicit imports found

### org/jetbrains/sbt/project/settings/SbtExtraControls.scala
sbt.settings.scalaVersionPreference=Open cross-compiled Scala 3 / Scala 2 projects as Scala 2
sbt.settings.scalaVersionPreference=Open cross-compiled Scala 3 / Scala 2 projects as:
sbt.settings.scalaVersionPreference.tooltip=Projects that are cross-compiled against both Scala 2 and Scala 3 don't actually use Scala 3 features and can be opened as Scala 2 (which is more reliable)
sbt.settings.useShell=use for:
sbt.settings.default=Default
sbt.settings.download=Download:
sbt.settings.shell.title=sbt shell
sbt.settings.useShellForImport=project reload
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ object SbtExternalSystemManager {
val vmOptions = getVmOptions(settingsState, jreHome)
val environment = Map.empty ++ getAndroidEnvironmentVariables(projectJdkName)
val sbtOptions = SbtOpts.combineOptionsWithArgs(settings.sbtOptions)
val preferedScala = projectSettings.preferedScala match {
case 0 => PreferedScala.Default
case 1 => PreferedScala.Scala2
case 2 => PreferedScala.Scala3
}

new SbtExecutionSettings(
realProjectPath = realProjectPath,
Expand All @@ -103,7 +108,7 @@ object SbtExternalSystemManager {
resolveSbtClassifiers = projectSettings.resolveSbtClassifiers,
useShellForImport = projectSettings.useSbtShellForImport,
shellDebugMode = projectSettings.enableDebugSbtShell,
preferScala2 = projectSettings.preferScala2,
preferedScala = preferedScala ,
userSetEnvironment = settingsState.sbtEnvironment.asScala.toMap,
passParentEnvironment = settingsState.sbtPassParentEnvironment,
insertProjectTransitiveDependencies = projectSettings.insertProjectTransitiveDependencies,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ private final class SbtProjectManagerListener extends ProjectManagerListener {
override def projectOpened(project: Project): Unit = {
SbtProjectSettings.forProject(project).foreach { settings =>
if (settings.converterVersion < SbtProjectSettings.ConverterVersion) {
if (project.hasScala3 && settings.preferScala2) { // TODO Remove (don't trigger the refresh unnecessarily)
if ((project.hasScala3 && settings.preferedScala == 1) || (project.hasScala2 && settings.preferedScala == 2)) { // TODO Remove (don't trigger the refresh unnecessarily)
// TODO Only do this if auto-import is enabled? (more predictable, on the other hand, it's not about "build scripts", as the setting claims)
ExternalSystemUtil.refreshProjects(new ImportSpecBuilder(project, SbtProjectSystem.Id).use(ProgressExecutionMode.IN_BACKGROUND_ASYNC))
// The converterVersion will be updated by SbtProjectDataService on a successful refresh.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class SbtProjectResolver extends ExternalSystemProjectResolver[SbtExecutionSetti

val messageResult: Try[BuildMessages] = {
if (useShellImport) {
val messagesF = dumper.dumpFromShell(project, structureFilePath, options, reporter, settings.preferScala2)
val messagesF = dumper.dumpFromShell(project, structureFilePath, options, reporter, settings.preferedScala)
Try(Await.result(messagesF, Duration.Inf)) // TODO some kind of timeout / cancel mechanism
}
else {
Expand All @@ -175,7 +175,7 @@ class SbtProjectResolver extends ExternalSystemProjectResolver[SbtExecutionSetti
dumper.dumpFromProcess(
projectRoot, structureFilePath, options,
settings.vmExecutable, settings.vmOptions, settings.sbtOptions, environment,
sbtLauncher, sbtStructureJar, settings.preferScala2, settings.passParentEnvironment)
sbtLauncher, sbtStructureJar, settings.preferedScala, settings.passParentEnvironment)
}
}
activeProcessDumper = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ class SbtExecutionSettings(val realProjectPath: String,
val resolveSbtClassifiers: Boolean,
val useShellForImport: Boolean,
val shellDebugMode: Boolean,
val preferScala2: Boolean,
val preferedScala: PreferedScala,
val userSetEnvironment: Map[String, String],
val passParentEnvironment: Boolean,
val insertProjectTransitiveDependencies: Boolean,
val useSeparateCompilerOutputPaths: Boolean
) extends ExternalSystemExecutionSettings

sealed trait PreferedScala
object PreferedScala {
object Default extends PreferedScala
object Scala2 extends PreferedScala
object Scala3 extends PreferedScala
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class SbtExtraControls {
val useSbtShellForImportCheckBox: JCheckBoxWithTooltip = ct(SbtBundle.message("sbt.settings.useShellForImport"), SbtBundle.message("sbt.settings.useShellForImport.tooltip"))
val useSbtShellForBuildCheckBox: JCheckBoxWithTooltip = ct(SbtBundle.message("sbt.settings.useShellForBuild"), SbtBundle.message("sbt.settings.useShellForBuild.tooltip"))
val remoteDebugSbtShellCheckBox: JCheckBoxWithTooltip = ct(SbtBundle.message("sbt.settings.remoteDebug"), SbtBundle.message("sbt.settings.remoteDebug.tooltip"))
val scalaVersionPreferenceCheckBox: JCheckBoxWithTooltip = ct(SbtBundle.message("sbt.settings.scalaVersionPreference"), SbtBundle.message("sbt.settings.scalaVersionPreference.tooltip"))
val scalaVersionPreferenceComboBox = new com.intellij.openapi.ui.ComboBox(Array(SbtBundle.message("sbt.settings.default"), "Scala 2", "Scala 3"))
val insertProjectTransitiveDependencies: JCheckBoxWithTooltip = ct(SbtBundle.message("insert.project.transitive.dependencies"), SbtBundle.message("insert.project.transitive.dependencies.tooltip"))
val useSeparateCompilerOutputPaths: JCheckBoxWithTooltip = ct(SbtBundle.message("use.separate.compiler.output.paths"), SbtBundle.message("use.separate.compiler.output.paths.tooltip"))
private val useSeparateCompilerOutputPathsWarning: JBLabel = new JBLabel(SbtBundle.message("use.separate.compiler.output.paths.warning"))
Expand All @@ -48,10 +48,19 @@ final class SbtExtraControls {
false
)

val scalaVersionPreferencePanel = {
val panel = new JPanel()
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS))
panel.add(new JBLabel(SbtBundle.message("sbt.settings.scalaVersionPreference")))
panel.add(Box.createRigidArea(new Dimension(10, 0)))
panel.add(withTooltip(scalaVersionPreferenceComboBox, SbtBundle.message("sbt.settings.scalaVersionPreference.tooltip")))
panel
}

content.add(new JBLabel(SbtBundle.message("sbt.settings.download")), new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(80, 16), null, 0, false))
content.add(resolveClassifiersCheckBox.panelWithTooltip, gc(0, 1, 1, 1))
content.add(resolveSbtClassifiersCheckBox.panelWithTooltip, gc(1, 1, 1, 1))
content.add(scalaVersionPreferenceCheckBox.panelWithTooltip, gc(2, 0, 1, 2))
content.add(scalaVersionPreferencePanel, new GridConstraints(2, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false))
content.add(insertProjectTransitiveDependencies.panelWithTooltip, gc(3, 0, 1, 2))
content.add(useSeparateCompilerOutputPaths.panelWithTooltip, gc(4, 0, 1, 2))
content.add(useSeparateCompilerOutputPathsWarning, warningConstraints)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class SbtProjectSettingsControl(context: Context, initialSettings: SbtProjectSet
extraControls.useSbtShellForImportCheckBox.isSelected != settings.useSbtShellForImport ||
extraControls.useSbtShellForBuildCheckBox.isSelected != settings.useSbtShellForBuild ||
extraControls.remoteDebugSbtShellCheckBox.isSelected != settings.enableDebugSbtShell ||
extraControls.scalaVersionPreferenceCheckBox.isSelected != settings.preferScala2 ||
extraControls.scalaVersionPreferenceComboBox.getSelectedIndex != settings.preferedScala ||
extraControls.insertProjectTransitiveDependencies.isSelected != settings.insertProjectTransitiveDependencies ||
extraControls.useSeparateCompilerOutputPaths.isSelected != settings.useSeparateCompilerOutputPaths
}
Expand All @@ -97,7 +97,7 @@ class SbtProjectSettingsControl(context: Context, initialSettings: SbtProjectSet
extraControls.useSbtShellForImportCheckBox.setSelected(settings.importWithShell)
extraControls.useSbtShellForBuildCheckBox.setSelected(settings.buildWithShell)
extraControls.remoteDebugSbtShellCheckBox.setSelected(settings.enableDebugSbtShell)
extraControls.scalaVersionPreferenceCheckBox.setSelected(settings.preferScala2)
extraControls.scalaVersionPreferenceComboBox.setSelectedIndex(settings.preferedScala)
extraControls.insertProjectTransitiveDependencies.setSelected(settings.insertProjectTransitiveDependencies)
extraControls.useSeparateCompilerOutputPaths.setSelected(settings.useSeparateCompilerOutputPaths)
extraControls.refreshOutputPathsWarning()
Expand All @@ -122,7 +122,7 @@ class SbtProjectSettingsControl(context: Context, initialSettings: SbtProjectSet
settings.resolveSbtClassifiers = extraControls.resolveSbtClassifiersCheckBox.isSelected
settings.useSbtShellForImport = extraControls.useSbtShellForImportCheckBox.isSelected
settings.enableDebugSbtShell = extraControls.remoteDebugSbtShellCheckBox.isSelected
settings.preferScala2 = extraControls.scalaVersionPreferenceCheckBox.isSelected
settings.preferedScala = extraControls.scalaVersionPreferenceComboBox.getSelectedIndex
settings.insertProjectTransitiveDependencies = extraControls.insertProjectTransitiveDependencies.isSelected
settings.useSeparateCompilerOutputPaths = extraControls.useSeparateCompilerOutputPaths.isSelected

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.jetbrains.plugins.scala.extensions.LoggerExt
import org.jetbrains.plugins.scala.settings.CompilerIndicesSettings
import org.jetbrains.sbt.SbtUtil._
import org.jetbrains.sbt.project.SbtProjectResolver.ImportCancelledException
import org.jetbrains.sbt.project.settings.PreferedScala
import org.jetbrains.sbt.project.structure.SbtOption._
import org.jetbrains.sbt.project.structure.SbtStructureDump._
import org.jetbrains.sbt.shell.SbtShellCommunication
Expand Down Expand Up @@ -51,7 +52,7 @@ class SbtStructureDump {
structureFilePath: String,
options: Seq[String],
reporter: BuildReporter,
preferScala2: Boolean,
preferedScala: PreferedScala,
): Future[BuildMessages] = {

reporter.start()
Expand All @@ -66,8 +67,13 @@ class SbtStructureDump {
val ideaPort = SbtCompilationSupervisorPort.port
if (ideaPort == -1) "" else s"; set ideaPort in Global := $ideaPort"
} else ""
val scalaSelection = preferedScala match {
case PreferedScala.Default => ""
case PreferedScala.Scala2 => "preferScala2;"
case PreferedScala.Scala3 => "preferScala3;"
}

val cmd = s";reload; $setCmd ;${if (preferScala2) "preferScala2;" else ""}*/*:dumpStructureTo $structureFilePath; session clear-all $ideaPortSetting"
val cmd = s";reload; $setCmd ;$scalaSelection*/*:dumpStructureTo $structureFilePath; session clear-all $ideaPortSetting"

val aggregator = shellMessageAggregator(EventId(s"dump:${UUID.randomUUID()}"), shell, reporter)

Expand All @@ -83,7 +89,7 @@ class SbtStructureDump {
environment: Map[String, String],
sbtLauncher: File,
sbtStructureJar: File,
preferScala2: Boolean,
preferedScala: PreferedScala,
passParentEnvironment: Boolean
)
(implicit reporter: BuildReporter)
Expand All @@ -96,13 +102,18 @@ class SbtStructureDump {
s"""SettingKey[_root_.scala.Option[_root_.sbt.File]]("sbtStructureOutputFile") in _root_.sbt.Global := _root_.scala.Some(_root_.sbt.file("$structureFilePath"))""",
s"""SettingKey[_root_.java.lang.String]("sbtStructureOptions") in _root_.sbt.Global := $optString"""
).mkString("set _root_.scala.collection.Seq(", ",", ")")
val scalaSelection = preferedScala match {
case PreferedScala.Default => Seq.empty
case PreferedScala.Scala2 => Seq("preferScala2")
case PreferedScala.Scala3 => Seq("preferScala3")
}

val sbtCommands = (
Seq(
setCommands,
s"""apply -cp "${normalizePath(sbtStructureJar)}" "org.jetbrains.sbt.CreateTasks" "sbt.jetbrains.LogDownloadArtifacts""""
) :++
(if (preferScala2) Seq("preferScala2") else Seq.empty) :+
scalaSelection :+
s"*/*:dumpStructure"
).mkString(";", ";", "")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.jetbrains.sbt.shell
import com.intellij.openapi.util.io.FileUtil
import junit.framework.TestCase
import org.jetbrains.sbt.JvmMemorySize
import org.jetbrains.sbt.project.settings.SbtExecutionSettings
import org.jetbrains.sbt.project.settings.{PreferedScala, SbtExecutionSettings}

import java.io.File

Expand Down Expand Up @@ -36,7 +36,7 @@ class MaxJvmHeapParameterTest extends TestCase {
resolveSbtClassifiers = false,
useShellForImport = false ,
shellDebugMode = false,
preferScala2 = true,
preferedScala = PreferedScala.Default,
userSetEnvironment = Map.empty,
passParentEnvironment = true,
insertProjectTransitiveDependencies = true,
Expand Down