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

Improved support for multiple scala versions #356

Merged

Conversation

daenenk
Copy link
Contributor

@daenenk daenenk commented Jan 12, 2018

improved-support-for-multiple-scala-versions
for ScalaIDE-4.6 and up
to support also scala-2.11 while preserving functionality for older versions,
i.e. support for scala-2.10 in ScalaIDE-4.0 and up.

This is a patch on top of commit 1bbf64c (Fix #239)
added EclipseKeys.defaultScalaInstallation
usage documentation added in README.md

daenenk and others added 3 commits January 5, 2018 09:40
This is a patch on top of commit 1bbf64c (Fix sbt#239)
added EclipseKeys.defaultScalaInstallation
usage documentation added in README.md
…pport-for-ScalaIDE-4.6

improved-support-for-multiple-scala-versions
…pport-for-multiple-scala-versions into src/main/scala-sbt-1.0/
@daenenk
Copy link
Contributor Author

daenenk commented Jan 12, 2018

#239 provided a initial support for multiple scala versions for Scala-IDE4.0, but is the implementation looked for scala-2.10 specifically. As a consequence the issue raised again when Scala-IDE4.6.0 came out targeting scala-2.12 as default.
Some Issue reports and request have attempted to fix this: see #287 and #340.
With this pull I hope to provide a more generic solution. I refactored the code submitted in #239.

README.md Outdated

Given
```
EclipseKeys.defaultScalaInstallation := "xD.yD" // "2.12" is the default
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand what the D represents here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

D stands for "default". 'xD.yD' represents the scala installation eclipse is using as default.

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 updated the description. I hope it is more clear now.

val ideSettings = fromScalacToSDT(options)
ScalaVersion.parse(version).settingsFrom(ideSettings.toMap).toSeq
ScalaVersion.parse(installation, version).settingsFrom(ideSettings.toMap).toSeq
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be accurate to call these variables installationVersion and projectVersion?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fine for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

update as you suggested has been pushed

@benmccann benmccann merged commit ab608cc into sbt:master Jan 15, 2018
@benmccann
Copy link
Contributor

@daenenk I just merged this, but now am wondering if this is the best approach and am thinking about reverting it. Do we really need to make the user set defaultScalaInstallation themselves or can we extract it from ScalaVersion like in #340

@daenenk
Copy link
Contributor Author

daenenk commented Jan 16, 2018

Both #356 and #340 determine the version value for the properties scala.compiler.additionalParams, scala.compiler.installation and scala.compiler.sourceLevel (in org.scala-ide.sdt.core.prefs) from scalaVersion (in build.sbt). The delta is the criteria when to specify these project specific properties or not. #340 checks whether Xp.Yp (as derived from scalaVersion) is exactly 2.10; if yes, then the project specific parameters are generated. I could have taken the same approach, and check on 2.10 or 2.11 (further referred to a approach A), without introducing the key defaultScalaInstallation. This would have worked for Scala IDE 4.6 - 4.7, but would impact support for older Scala IDE releases, and would fail again when a future Scala IDE comes with scala 2.13 or 3.0 as default scala installation.

The introduction of defaultScalaInstallation, set to 2.12 as default (i.e. the approach of #356, further referred to a B), results in the same behavior as A for Scala IDE 4.6 - 4.7, while people could ignore defaultScalaInstallation. In addition, it gives the flexibility to set defaultScalaInstallation to 2.11 in order to support e.g. Scala IDE 4.5.0, as well as to e.g. 2.13 for futureScala IDE releases.

To be clear, defaultScalaInstallation reflects your Scala IDE, and is not related to the scalaVersion of your project. I don't like eclipse-specifc settings in my build.sbt file. The solution for this is to specify sbtsclipse as global plugin, and (if needed) to overwrite defaultScalaInstallation in a global ad hoc plugin. For sbt 0.13, you could write a file ~/.sbt/0.13/plugins/SbtEclipseSettings.scala:

import sbt._
import Keys._
import com.typesafe.sbteclipse.plugin.EclipsePlugin.EclipseKeys._

object SbtEclipseSettings extends Plugin {
  override def settings = Seq(
    defaultScalaInstallation := "2.11"
  )
}

This may look complex, but most people will not need it, and for those who need it, it is easier than being blocked or having to create a pull request on sbteclipse again.

I don't know exactly what all implications are of the setting scala.compiler.additionalParams=\ -Xsource\:2.11 -Ymacro-expand\:none. That's what Scala IDE itself generate when you select scala installation 2.11. An alternative solution (C) would be to always set scala.compiler.useProjectSettings=true and scala.compiler.additionalParams=\ -Xsource\:Xp.Yp -Ymacro-expand\:none, unless the latter would be overrruled by scalacOptions. Still, silently adding -Ymacro-expand\:none (also for scala 2.12 projects) may not be what people want/expect. In case there would be a need to overrrule scala.compiler.useProjectSettings=true, still a sbteclipse-specific key will be needed.

Up till now, I think approach B had the smallest impact on the sbteclipse code based and it's behaviour, and it is better than before #356, as well as approach A. It will help people out using scala 2.11 on a recent Scala IDE's, and don't break functionality for others.

A better solution may be possible in the future. It would be nice if the engineers of the eclipse Scala IDE would join this discussion.

@benmccann
Copy link
Contributor

@wpopielarski @sschaef do you think that sbteclipse is taking the correct approach to generating eclipse files for use by scala IDE here?

@daenenk
Copy link
Contributor Author

daenenk commented Jan 17, 2018

Defining a project in build.sbt, for me, is the best approach; then using sbt to resolve the dependencies. Finaly we need a way to import the project into an IDE. sbteclipse does a pretty good job: the eclipse task resolves the dependencies and generates a resolved project definition, in terms of producing the eclipse files.

The question is whether generating the latter directly in a (eclipse) Scala IDE format is the best approach. To decouple the dependencies on the IDE, maybe you could agree on an a generic resolved project definition format (something straight and simple, all you need in a single file: property-file or json formatted). The Scala IDE should than support importing the latter. During the import, warnings of incompatibility could be generated. This approach would also require an update-import feature in eclipse.

So far, I've no experience with https://github.com/scala-ide/sbt-integration. At first glance, it looks more complex to setup.

benmccann added a commit that referenced this pull request May 7, 2018
@benmccann
Copy link
Contributor

Thinking about this more, I believe that setting scala.compiler.useProjectSettings=true would have been the better thing to try, so I've reverted this PR. It sounds like we should set -Ymacro-expand:none only if the user is using 2.10

@daenenk
Copy link
Contributor Author

daenenk commented May 7, 2018

I agree with

I believe that setting scala.compiler.useProjectSettings=true would have been the better thing to try

That's exactly what the code does, in case the defaultScalaInstallation > projectScalaVersion

  1. setting scala.compiler.useProjectSettings=true, and
  2. setting scala.compiler.installation

The fact that also scala.compiler.additionalParams=-Xsource\:2.11 -Ymacro-expand\:none must be set is unfortunately. It is also unclear for me why exactly the ScalaIDE requires this, but it get sbteclipse working in all cases.

@benmccann
Copy link
Contributor

Can we do it always so that this plugin does not to have to know about defaultScalaInstallation?

@daenenk
Copy link
Contributor Author

daenenk commented May 7, 2018

Yes, but it has consequences.
The scala.compiler.installation parameter, sets the scala compiler. But that is not enough, since the IDE has a single presentation compiler. With the -Xsource param, the latter is forced in a backward compatibility mode. This mode however has some limitations; that's why the param -Ymacro-expand:none is needed as well. I'm not 100% sure whether this limitation is still there but I've not found evidence of this being solved.

So yes, we can apply these settings in all cases, which means we apply also -Ymacro-expand:none in all cases. Personally, I could live with that.

If some people would need macro-expand support in eclipse, sbt-eclipse could define a setting key useProjectSettings (iso defaultScalaInstallation). Only when this is true the settings as discussed are generated. You may not like again having a setting key, but at least this one does not reflect a version number.

@benmccann
Copy link
Contributor

benmccann commented May 8, 2018

We may only need to do that when setting -Xsource:2.10?

Since whitebox macros have some incompatible improvements between 2.11 and 2.10, the IDE is not able to expand macros for you in compatibility mode. This probably will remain a long-term limitation of this mode. This is why the -Ymacro-expand:none setting works conjointly with the -Xsource:2.10 setting.

I'm not sure though when they say "This probably will remain a long-term limitation of this mode." whether that means we need to do it for newer versions as well. Maybe you're right that it always needs to be done

@benmccann
Copy link
Contributor

Maybe a better option would be to have a boolean flag like setProjectScalaVersion. Then you can still choose to set it or not. The thing that gave me pause about defaultScalaInstallation is that it makes it really hard to work in a team environment where people upgrade their Scala IDE at different times

@daenenk
Copy link
Contributor Author

daenenk commented May 8, 2018

I keep the sbt-eclipse plugin and its settings as global settings on my machine only, as other developers may not use it. I do share the concern that having to maintain a version number in the build config with defaultScalaInstallation may cause extra maintenance and version control issues in a team.

Based on your view I summarize the solution as:

  • definition of a setting key setProjectScalaVersion
  • when setProjectScalaVersion == false, no project specific parameters are configured
  • when setProjectScalaVersion == true, the following settings will be configured:
    • scala.compiler.useProjectSettings=true
    • scala.compiler.installation
    • scala.compiler.additionalParams
      The latter will specify the scala version, and only in case this is 2.10.x, it also adds -Ymacro-expand:none

@benmccann
Copy link
Contributor

Yes, sounds good to me

Sorry for the back-and-forth on this one and my taking so long. I no longer use sbt as we have migrated to Play on Gradle, so I've had a hard time finding time to devote to this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants