From 5d63035a273670e75984eb837292bd4a863ecab1 Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Mon, 9 Apr 2018 10:15:32 +0200 Subject: [PATCH 1/8] Fix #4073: support detect dotty plugins --- main/src/main/scala/sbt/Defaults.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 82af2a9e4..6e99870fe 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2887,7 +2887,8 @@ object Classpaths { def autoPlugins(report: UpdateReport, internalPluginClasspath: Seq[File]): Seq[String] = { val pluginClasspath = report.matching(configurationFilter(CompilerPlugin.name)) ++ internalPluginClasspath - val plugins = sbt.internal.inc.classpath.ClasspathUtilities.compilerPlugins(pluginClasspath) + val version = scalaVersion.value + val plugins = sbt.internal.inc.classpath.ClasspathUtilities.compilerPlugins(pluginClasspath, scalaInstance.isDotty(version)) plugins.map("-Xplugin:" + _.getAbsolutePath).toSeq } From 9ad1b120c10471c654d03972e6250a57f6a8aefc Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Mon, 9 Apr 2018 10:51:58 +0200 Subject: [PATCH 2/8] add notes --- notes/1.1.1/dotty-plugin.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 notes/1.1.1/dotty-plugin.md diff --git a/notes/1.1.1/dotty-plugin.md b/notes/1.1.1/dotty-plugin.md new file mode 100644 index 000000000..6250c30dd --- /dev/null +++ b/notes/1.1.1/dotty-plugin.md @@ -0,0 +1,9 @@ +[@liufengyun]: https://github.com/liufengyun + +[4073]: https://github.com/sbt/sbt/issues/4073 +[4084]: https://github.com/sbt/sbt/pull/4084 + + +### Improvements + +- Detect dotty plugins which have descriptor file named `plugin.properties` instead of `scalac-plugin.xml`. [#4073][4073]/[#4084][4084] by [@liufengyun][@liufengyun] From 83212785b02060ee9907e31ee80dc44ce2307dac Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Mon, 9 Apr 2018 10:59:46 +0200 Subject: [PATCH 3/8] add dotty plugin test --- .../dotty-compiler-plugin/build.sbt | 19 +++++++++ .../plugin/DivideZero.scala | 40 +++++++++++++++++++ .../src/main/resources/plugin.properties | 1 + .../dotty-compiler-plugin/project/plugins.sbt | 1 + .../src/main/scala/hello/Hello.scala | 13 ++++++ .../dotty-compiler-plugin/test | 2 + 6 files changed, 76 insertions(+) create mode 100644 sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/build.sbt create mode 100644 sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/DivideZero.scala create mode 100644 sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/src/main/resources/plugin.properties create mode 100644 sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt create mode 100644 sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/src/main/scala/hello/Hello.scala create mode 100644 sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/test diff --git a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/build.sbt b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/build.sbt new file mode 100644 index 000000000..19d921ef1 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/build.sbt @@ -0,0 +1,19 @@ +lazy val dottyVersion = dottyLatestNightlyBuild + +lazy val pluginSetting = Seq( + name := "dividezero", + version := "0.0.1", + organization := "ch.epfl.lamp", + scalaVersion := dottyVersion, + + libraryDependencies ++= Seq( + "ch.epfl.lamp" %% "dotty" % "provided" + ) +) + +lazy val plugin = (project in file("plugin")).settings(pluginSetting: _*) + +lazy val app = (project in file(".")).settings( + scalaVersion := dottyVersion, + libraryDependencies += compilerPlugin("ch.epfl.lamp" %% "dividezero" % "0.0.1") +) diff --git a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/DivideZero.scala b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/DivideZero.scala new file mode 100644 index 000000000..1dfe23cf5 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/DivideZero.scala @@ -0,0 +1,40 @@ +package dividezero + +import dotty.tools.dotc._ +import core._ +import Contexts.Context +import plugins._ +import Phases.Phase +import ast.tpd +import transform.MegaPhase.MiniPhase +import Decorators._ +import Symbols.Symbol +import Constants.Constant +import transform.{LinkAll, Pickler} + +class DivideZero extends PluginPhase with StandardPlugin { + val name: String = "divideZero" + override val description: String = "divide zero check" + + val phaseName = name + + override val runsAfter = Set(Pickler.phaseName) + override val runsBefore = Set(LinkAll.phaseName) + + override def init(options: List[String]): List[PluginPhase] = this :: Nil + + private def isNumericDivide(sym: Symbol)(implicit ctx: Context): Boolean = { + def test(tpe: String): Boolean = + (sym.owner eq ctx.requiredClass(tpe.toTermName)) && sym.name.show == "/" + + test("scala.Int") || test("scala.Long") || test("scala.Short") || test("scala.Float") || test("scala.Double") + } + + override def transformApply(tree: tpd.Apply)(implicit ctx: Context): tpd.Tree = tree match { + case tpd.Apply(fun, tpd.Literal(Constants.Constant(v)) :: Nil) if isNumericDivide(fun.symbol) && v == 0 => + ctx.warning("divide by zero", tree.pos) + tpd.Literal(Constant(0)) + case _ => + tree + } +} diff --git a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/src/main/resources/plugin.properties b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/src/main/resources/plugin.properties new file mode 100644 index 000000000..db215842c --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/plugin/src/main/resources/plugin.properties @@ -0,0 +1 @@ +pluginClass=dividezero.DivideZero \ No newline at end of file diff --git a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt new file mode 100644 index 000000000..57022ad6b --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.1.7") diff --git a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/src/main/scala/hello/Hello.scala b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/src/main/scala/hello/Hello.scala new file mode 100644 index 000000000..99ae2d0d7 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/src/main/scala/hello/Hello.scala @@ -0,0 +1,13 @@ +package hello +object Hello { + def main(args: Array[String]): Unit = { + val dotty: Int | String = "dotty" + + val y = 5 / 0 // error + 100 + 6 / 0 // error + 6L / 0L // error + val z = 7 / 0.0 // error + + println(s"Hello $dotty!") + } +} diff --git a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/test b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/test new file mode 100644 index 000000000..28c06d4d6 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/test @@ -0,0 +1,2 @@ +> plugin/publishLocal +> app/run From 06cf5e56356bcded9f65dd162722a0c813592db1 Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Fri, 13 Apr 2018 14:16:23 +0200 Subject: [PATCH 4/8] update sbt-dotty version --- .../compiler-project/dotty-compiler-plugin/project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt index 57022ad6b..ba89aa2bb 100644 --- a/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt +++ b/sbt/src/sbt-test/compiler-project/dotty-compiler-plugin/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.1.7") +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.2.0") From ecbfdfef25f20ec497448cf6bbbe6aa1fa55d13b Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Thu, 3 May 2018 22:36:17 +0200 Subject: [PATCH 5/8] fix compilation error --- main/src/main/scala/sbt/Defaults.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 6e99870fe..3aaf9858a 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2885,10 +2885,9 @@ object Classpaths { excl: FileFilter): Classpath = (base * (filter -- excl) +++ (base / config.name).descendantsExcept(filter, excl)).classpath - def autoPlugins(report: UpdateReport, internalPluginClasspath: Seq[File]): Seq[String] = { + def autoPlugins(report: UpdateReport, internalPluginClasspath: Seq[File], scalaVersion: String): Seq[String] = { val pluginClasspath = report.matching(configurationFilter(CompilerPlugin.name)) ++ internalPluginClasspath - val version = scalaVersion.value - val plugins = sbt.internal.inc.classpath.ClasspathUtilities.compilerPlugins(pluginClasspath, scalaInstance.isDotty(version)) + val plugins = sbt.internal.inc.classpath.ClasspathUtilities.compilerPlugins(pluginClasspath, ScalaInstance.isDotty(scalaVersion)) plugins.map("-Xplugin:" + _.getAbsolutePath).toSeq } @@ -2908,7 +2907,7 @@ object Classpaths { lazy val compilerPluginConfig = Seq( scalacOptions := { val options = scalacOptions.value - val newPlugins = autoPlugins(update.value, internalCompilerPluginClasspath.value.files) + val newPlugins = autoPlugins(update.value, internalCompilerPluginClasspath.value.files, scalaVersion.value) val existing = options.toSet if (autoCompilerPlugins.value) options ++ newPlugins.filterNot(existing) else options } From adf045d4f86225064215dd9a73abc3897b7ee2e2 Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Fri, 4 May 2018 16:39:05 +0200 Subject: [PATCH 6/8] move notes to 1.1.5 --- notes/{1.1.1 => 1.1.5}/dotty-plugin.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename notes/{1.1.1 => 1.1.5}/dotty-plugin.md (100%) diff --git a/notes/1.1.1/dotty-plugin.md b/notes/1.1.5/dotty-plugin.md similarity index 100% rename from notes/1.1.1/dotty-plugin.md rename to notes/1.1.5/dotty-plugin.md From 50f2ebce8817a28bbba2522ddb7f7639b04a3400 Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Fri, 4 May 2018 17:00:25 +0200 Subject: [PATCH 7/8] overload autoPlugins for binary compatibility --- main/src/main/scala/sbt/Defaults.scala | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 3aaf9858a..fa65596fa 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2885,9 +2885,14 @@ object Classpaths { excl: FileFilter): Classpath = (base * (filter -- excl) +++ (base / config.name).descendantsExcept(filter, excl)).classpath - def autoPlugins(report: UpdateReport, internalPluginClasspath: Seq[File], scalaVersion: String): Seq[String] = { + + @deprecated("The method only works for Scalac, use the overloaded version to support both Scalac and Dotty", "1.1.5") + def autoPlugins(report: UpdateReport, internalPluginClasspath: Seq[File]): Seq[String] = + autoPlugins(report, internalPluginClasspath, isDotty = false) + + def autoPlugins(report: UpdateReport, internalPluginClasspath: Seq[File], isDotty: Boolean): Seq[String] = { val pluginClasspath = report.matching(configurationFilter(CompilerPlugin.name)) ++ internalPluginClasspath - val plugins = sbt.internal.inc.classpath.ClasspathUtilities.compilerPlugins(pluginClasspath, ScalaInstance.isDotty(scalaVersion)) + val plugins = sbt.internal.inc.classpath.ClasspathUtilities.compilerPlugins(pluginClasspath, isDotty) plugins.map("-Xplugin:" + _.getAbsolutePath).toSeq } @@ -2907,7 +2912,7 @@ object Classpaths { lazy val compilerPluginConfig = Seq( scalacOptions := { val options = scalacOptions.value - val newPlugins = autoPlugins(update.value, internalCompilerPluginClasspath.value.files, scalaVersion.value) + val newPlugins = autoPlugins(update.value, internalCompilerPluginClasspath.value.files, ScalaInstance.isDotty(scalaVersion.value)) val existing = options.toSet if (autoCompilerPlugins.value) options ++ newPlugins.filterNot(existing) else options } From 1057dcd2914af02924513661a74f85a4b1915053 Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Fri, 4 May 2018 17:10:50 +0200 Subject: [PATCH 8/8] update deprecated message --- main/src/main/scala/sbt/Defaults.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index fa65596fa..ff93c1097 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2886,7 +2886,7 @@ object Classpaths { (base * (filter -- excl) +++ (base / config.name).descendantsExcept(filter, excl)).classpath - @deprecated("The method only works for Scalac, use the overloaded version to support both Scalac and Dotty", "1.1.5") + @deprecated("The method only works for Scala 2, use the overloaded version to support both Scala 2 and Scala 3", "1.1.5") def autoPlugins(report: UpdateReport, internalPluginClasspath: Seq[File]): Seq[String] = autoPlugins(report, internalPluginClasspath, isDotty = false)