Skip to content

Commit b91b61b

Browse files
authored
Add support for compiler plugins (#140)
* Add support for compiler plugins
1 parent f6735d9 commit b91b61b

File tree

8 files changed

+75
-17
lines changed

8 files changed

+75
-17
lines changed

modules/build/src/main/scala/scala/build/options/BuildOptions.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ final case class BuildOptions(
7575
def compilerPlugins: Seq[AnyDependency] =
7676
scalaJsOptions.compilerPlugins(scalaParams.scalaVersion) ++
7777
scalaNativeOptions.compilerPlugins ++
78-
semanticDbPlugins
78+
semanticDbPlugins ++
79+
scalaOptions.compilerPlugins
7980

8081
def allExtraJars: Seq[Path] =
8182
classPathOptions.extraJars.map(_.toNIO)

modules/build/src/main/scala/scala/build/options/ScalaOptions.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package scala.build.options
22

3+
import dependency.AnyDependency
4+
35
final case class ScalaOptions(
46
scalaVersion: Option[String] = None,
57
scalaBinaryVersion: Option[String] = None,
68
addScalaLibrary: Option[Boolean] = None,
79
generateSemanticDbs: Option[Boolean] = None,
810
scalacOptions: Seq[String] = Nil,
9-
extraScalaVersions: Set[String] = Set.empty
11+
extraScalaVersions: Set[String] = Set.empty,
12+
compilerPlugins: Seq[AnyDependency] = Nil
1013
)
1114

1215
object ScalaOptions {

modules/cli/src/main/scala/scala/cli/commands/SharedDependencyOptions.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ final case class SharedDependencyOptions(
1515
@HelpMessage("")
1616
@Name("repo")
1717
@Name("r")
18-
repository: List[String] = Nil
18+
repository: List[String] = Nil,
19+
@Group("Scala")
20+
@Name("P")
21+
@Name("plugin")
22+
@HelpMessage("Add compiler plugins dependencies")
23+
compilerPlugin: List[String] = Nil
1924
)
2025
// format: on
2126

modules/cli/src/main/scala/scala/cli/commands/SharedOptions.scala

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package scala.cli.commands
22

33
import java.io.{ByteArrayOutputStream, File, InputStream}
4-
54
import caseapp._
65
import caseapp.core.help.Help
76
import coursier.cache.FileCache
87
import coursier.util.Artifact
8+
import dependency.AnyDependency
99
import dependency.parser.DependencyParser
1010

1111
import scala.build.blooprifle.BloopRifleConfig
@@ -115,6 +115,17 @@ final case class SharedOptions(
115115
if (classWrap) Some(CustomCodeClassWrapper)
116116
else None
117117

118+
private def parseDependencies(deps: List[String], ignoreErrors: Boolean): Seq[AnyDependency] =
119+
deps.map(_.trim).filter(_.nonEmpty)
120+
.flatMap { depStr =>
121+
DependencyParser.parse(depStr) match {
122+
case Left(err) =>
123+
if (ignoreErrors) Nil
124+
else sys.error(s"Error parsing dependency '$depStr': $err")
125+
case Right(dep) => Seq(dep)
126+
}
127+
}
128+
118129
def buildOptions(
119130
enableJmh: Boolean,
120131
jmhVersion: Option[String],
@@ -126,7 +137,8 @@ final case class SharedOptions(
126137
scalaBinaryVersion = scalaBinaryVersion.map(_.trim).filter(_.nonEmpty),
127138
addScalaLibrary = scalaLibrary.orElse(java.map(!_)),
128139
generateSemanticDbs = semanticDb,
129-
scalacOptions = scalac.scalacOption.filter(_.nonEmpty)
140+
scalacOptions = scalac.scalacOption.filter(_.nonEmpty),
141+
compilerPlugins = parseDependencies(dependencies.compilerPlugin, ignoreErrors)
130142
),
131143
scriptOptions = ScriptOptions(
132144
codeWrapper = codeWrapper
@@ -154,15 +166,7 @@ final case class SharedOptions(
154166
.filter(_.nonEmpty)
155167
.map(os.Path(_, os.pwd)),
156168
extraRepositories = dependencies.repository.map(_.trim).filter(_.nonEmpty),
157-
extraDependencies = dependencies.dependency.map(_.trim).filter(_.nonEmpty)
158-
.flatMap { depStr =>
159-
DependencyParser.parse(depStr) match {
160-
case Left(err) =>
161-
if (ignoreErrors) Nil
162-
else sys.error(s"Error parsing dependency '$depStr': $err")
163-
case Right(dep) => Seq(dep)
164-
}
165-
}
169+
extraDependencies = parseDependencies(dependencies.dependency, ignoreErrors)
166170
),
167171
internal = InternalOptions(
168172
cache = Some(coursierCache),

modules/integration/src/test/scala/scala/cli/integration/CompileTestDefinitions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.eed3si9n.expecty.Expecty.expect
55
abstract class CompileTestDefinitions(val scalaVersionOpt: Option[String])
66
extends munit.FunSuite with TestScalaVersionArgs {
77

8-
private lazy val extraOptions = scalaVersionArgs ++ TestUtil.extraOptions
8+
protected lazy val extraOptions = scalaVersionArgs ++ TestUtil.extraOptions
99

1010
val simpleInputs = TestInputs(
1111
Seq(

modules/integration/src/test/scala/scala/cli/integration/CompileTests212.scala

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,37 @@ package scala.cli.integration
33
// format: off
44
class CompileTests212 extends CompileTestDefinitions(
55
scalaVersionOpt = Some(Constants.scala212)
6-
)
7-
// format: on
6+
) {
7+
// format: on
8+
9+
val pluginInputs = TestInputs(
10+
Seq(
11+
os.rel / "Plugin.scala" ->
12+
// Copied from (https://github.com/typelevel/kind-projector/blob/00bf25cef1b7d01d61a3555cccb6cf38fe30e117/src/test/scala/polylambda.scala)
13+
"""object Plugin {
14+
| trait ~>[-F[_], +G[_]] {
15+
| def apply[A](x: F[A]): G[A]
16+
| }
17+
| type ToSelf[F[_]] = F ~> F
18+
| val kf5 = λ[Map[*, Int] ~> Map[*, Long]](_.map { case (k, v) => (k, v.toLong) }.toMap)
19+
| val kf6 = λ[ToSelf[Map[*, Int]]](_.map { case (k, v) => (k, v * 2) }.toMap)
20+
|}
21+
|""".stripMargin,
22+
os.rel / "scala.conf" -> ""
23+
)
24+
)
25+
26+
val kindProjectPlugin = "org.typelevel:::kind-projector:0.13.2"
27+
28+
test("should compile with compiler plugin") {
29+
pluginInputs.fromRoot { root =>
30+
os.proc(
31+
TestUtil.cli,
32+
"compile",
33+
extraOptions,
34+
"--compiler-plugin",
35+
kindProjectPlugin
36+
).call(cwd = root).out.text
37+
}
38+
}
39+
}

website/docs/compile.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ scala-cli compile Hello.scala -O -deprecation -O -Xlint:infer-any
7070

7171
`-O` accepts both options with the prefixes above and those without such a prefix.
7272

73+
## Scala compiler plugins
74+
Use `--compiler-plugin` to add compiler plugin dependencies:
75+
76+
```bash
77+
scala-cli compile Main.scala --compiler-plugin org.typelevel:::kind-projector:0.13.2 --scala 2.12.14
78+
```
79+
7380
## Scala version
7481

7582
Specify the Scala version you'd like to use with `--scala`:

website/docs/reference/cli-options.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ Aliases: `--repo`, `-r`
181181

182182
Add repositories
183183

184+
#### `--compiler-plugin`
185+
186+
Aliases: `-P`, `--plugin`
187+
188+
Add compiler plugins dependencies
189+
184190
## Export options
185191

186192
Available in commands:

0 commit comments

Comments
 (0)