Skip to content

Commit 1f433d5

Browse files
authored
Merge pull request #10092 from romanowski/scala3doc/migration
Migrate Scala3doc repo to Dotty
2 parents 9a13214 + a1d4814 commit 1f433d5

File tree

378 files changed

+36638
-9
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

378 files changed

+36638
-9
lines changed

.github/workflows/ci.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@ name: Dotty CI
22

33
on:
44
push:
5+
paths-ignore:
6+
# Do not run everything on changes only in docs
7+
- 'scala3doc/**'
8+
- 'scala3doc-testcases/**'
59
pull_request:
10+
paths-ignore:
11+
# Do not run everything on changes only in docs
12+
- 'scala3doc/**'
13+
- 'scala3doc-testcases/**'
614
schedule:
715
- cron: '0 3 * * *' # Every day at 3 AM
816

.github/workflows/scala3doc.yaml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: CI for Scala3doc
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
container: lampepfl/dotty:2020-04-24
12+
13+
steps:
14+
- name: Git Checkout
15+
uses: actions/checkout@v2
16+
17+
- name: Cache Coursier
18+
uses: actions/cache@v1
19+
with:
20+
path: ~/.cache/coursier
21+
key: sbt-coursier-cache
22+
- name: Cache SBT
23+
uses: actions/cache@v1
24+
with:
25+
path: ~/.sbt
26+
key: sbt-${{ hashFiles('**/build.sbt') }}
27+
28+
- name: Set up JDK 11
29+
uses: actions/setup-java@v1
30+
with:
31+
java-version: 11
32+
33+
- name: Compile and test
34+
run: ./project/scripts/sbt scala3doc/test
35+
36+
- name: Locally publish self
37+
run: ./project/scripts/sbt scala3doc/publishLocal
38+
39+
- name: Generate test documentation
40+
run: ./project/scripts/sbt scala3doc/generateSelfDocumentation
41+
42+
- name: Generate Scala 3 documentation
43+
run: ./project/scripts/sbt scala3doc/generateScala3Documentation
44+
45+
- name: Generate documentation for example project using dotty-sbt
46+
run: ./project/scripts/sbt "sbt-dotty/scripted sbt-dotty/scala3doc"

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ val `stdlib-bootstrapped-tasty-tests` = Build.`stdlib-bootstrapped-tasty-tests`
2020
val `tasty-core` = Build.`tasty-core`
2121
val `tasty-core-bootstrapped` = Build.`tasty-core-bootstrapped`
2222
val `tasty-core-scala2` = Build.`tasty-core-scala2`
23+
val scala3doc = Build.scala3doc
24+
val `scala3doc-testcases` = Build.`scala3doc-testcases`
2325
val `scala3-bench-run` = Build.`scala3-bench-run`
2426
val dist = Build.dist
2527
val `community-build` = Build.`community-build`

project/Build.scala

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ object Build {
213213
}
214214
)
215215

216+
lazy val disableDocSetting =
217+
// Disable scaladoc generation, it's way too slow and we'll replace it
218+
// by dottydoc anyway. We still publish an empty -javadoc.jar to make
219+
// sonatype happy.
220+
sources in (Compile, doc) := Seq()
221+
216222
lazy val commonSettings = publishSettings ++ Seq(
217223
scalaSource in Compile := baseDirectory.value / "src",
218224
scalaSource in Test := baseDirectory.value / "test",
@@ -221,11 +227,6 @@ object Build {
221227
resourceDirectory in Compile := baseDirectory.value / "resources",
222228
resourceDirectory in Test := baseDirectory.value / "test-resources",
223229

224-
// Disable scaladoc generation, it's way too slow and we'll replace it
225-
// by dottydoc anyway. We still publish an empty -javadoc.jar to make
226-
// sonatype happy.
227-
sources in (Compile, doc) := Seq(),
228-
229230
// Prevent sbt from rewriting our dependencies
230231
scalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(false))),
231232

@@ -244,7 +245,8 @@ object Build {
244245
crossPaths := false,
245246
// Do not depend on the Scala library
246247
autoScalaLibrary := false,
247-
excludeFromIDE := true
248+
excludeFromIDE := true,
249+
disableDocSetting
248250
)
249251

250252
// Settings used when compiling dotty (both non-bootstrapped and bootstrapped)
@@ -258,6 +260,8 @@ object Build {
258260
moduleName ~= { _.stripSuffix("-scala2") },
259261
version := dottyVersion,
260262
target := baseDirectory.value / ".." / "out" / "scala-2" / name.value,
263+
264+
disableDocSetting
261265
)
262266

263267
// Settings used when compiling dotty with the reference compiler
@@ -267,6 +271,8 @@ object Build {
267271
version := dottyNonBootstrappedVersion,
268272
scalaVersion := referenceVersion,
269273
excludeFromIDE := true,
274+
275+
disableDocSetting
270276
)
271277

272278
// Settings used when compiling dotty with a non-bootstrapped dotty
@@ -328,6 +334,8 @@ object Build {
328334
},
329335
// sbt-dotty defines `scalaInstance in doc` so we need to override it manually
330336
scalaInstance in doc := scalaInstance.value,
337+
338+
disableDocSetting,
331339
)
332340

333341
lazy val commonBenchmarkSettings = Seq(
@@ -1153,6 +1161,14 @@ object Build {
11531161
lazy val `scala3-bench-bootstrapped` = project.in(file("bench")).asDottyBench(Bootstrapped)
11541162
lazy val `scala3-bench-run` = project.in(file("bench-run")).asDottyBench(Bootstrapped)
11551163

1164+
val testcasesOutputDir = taskKey[String]("Root directory where tests classses are generated")
1165+
val testcasesSourceRoot = taskKey[String]("Root directory where tests sources are generated")
1166+
val generateSelfDocumentation = taskKey[Unit]("Generate example documentation")
1167+
val generateScala3Documentation = taskKey[Unit]("Generate documentation for dotty lib")
1168+
val generateTestcasesDocumentation = taskKey[Unit]("Generate documentation for testcases, usefull for debugging tests")
1169+
lazy val `scala3doc` = project.in(file("scala3doc")).asScala3doc
1170+
lazy val `scala3doc-testcases` = project.in(file("scala3doc-testcases")).asScala3docTestcases
1171+
11561172
// sbt plugin to use Dotty in your own build, see
11571173
// https://github.com/lampepfl/scala3-example-project for usage.
11581174
lazy val `sbt-dotty` = project.in(file("sbt-dotty")).
@@ -1192,6 +1208,7 @@ object Build {
11921208
publishLocal in `scala3-staging`,
11931209
publishLocal in `scala3-tasty-inspector`,
11941210
publishLocal in `scala3-doc-bootstrapped`,
1211+
publishLocal in `scala3doc`,
11951212
publishLocal in `scala3-bootstrapped` // Needed because sbt currently hardcodes the dotty artifact
11961213
).evaluated
11971214
)
@@ -1393,7 +1410,7 @@ object Build {
13931410
def asDottyRoot(implicit mode: Mode): Project = project.withCommonSettings.
13941411
aggregate(`scala3-interfaces`, dottyLibrary, dottyCompiler, tastyCore, dottyDoc, `scala3-sbt-bridge`).
13951412
bootstrappedAggregate(`scala3-language-server`, `scala3-staging`, `scala3-tasty-inspector`,
1396-
`scala3-library-bootstrappedJS`).
1413+
`scala3-library-bootstrappedJS`, scala3doc).
13971414
dependsOn(tastyCore).
13981415
dependsOn(dottyCompiler).
13991416
dependsOn(dottyLibrary).
@@ -1440,6 +1457,70 @@ object Build {
14401457
settings(commonBenchmarkSettings).
14411458
enablePlugins(JmhPlugin)
14421459

1460+
def asScala3doc: Project = {
1461+
def generateDocumentation(targets: String, name: String, outDir: String, params: String = "") = Def.taskDyn {
1462+
val sourceMapping = "=https://github.com/lampepfl/dotty/tree/master#L"
1463+
run.in(Compile).toTask(s""" -d output/$outDir -t $targets -n "$name" -s $sourceMapping $params""")
1464+
}
1465+
1466+
project.settings(commonBootstrappedSettings).
1467+
dependsOn(`scala3-compiler-bootstrapped`).
1468+
dependsOn(`scala3-tasty-inspector`).
1469+
settings(
1470+
// Needed to download dokka and its dependencies
1471+
resolvers += Resolver.jcenterRepo,
1472+
// Needed to download dokka-site
1473+
resolvers += Resolver.bintrayRepo("virtuslab", "dokka"),
1474+
libraryDependencies ++= Seq(
1475+
"com.virtuslab.dokka" % "dokka-site" % "0.1.9",
1476+
"com.vladsch.flexmark" % "flexmark-all" % "0.42.12",
1477+
"nl.big-o" % "liqp" % "0.6.7",
1478+
"args4j" % "args4j" % "2.33",
1479+
1480+
"org.jetbrains.dokka" % "dokka-test-api" % "1.4.10.2" % "test",
1481+
"com.novocode" % "junit-interface" % "0.11" % "test",
1482+
),
1483+
Test / test := (Test / test).dependsOn(compile.in(Compile).in(`scala3doc-testcases`)).value,
1484+
testcasesOutputDir.in(Test) := classDirectory.in(Compile).in(`scala3doc-testcases`).value.getAbsolutePath.toString,
1485+
testcasesSourceRoot.in(Test) := (baseDirectory.in(`scala3doc-testcases`).value / "src").getAbsolutePath.toString,
1486+
Compile / mainClass := Some("dotty.dokka.Main"),
1487+
// There is a bug in dokka that prevents parallel tests withing the same jvm
1488+
fork.in(test) := true,
1489+
generateSelfDocumentation := Def.taskDyn {
1490+
generateDocumentation(classDirectory.in(Compile).value.getAbsolutePath, "scala3doc", "self", "-p documentation")
1491+
}.value,
1492+
generateScala3Documentation := Def.taskDyn {
1493+
val dottyJars = Seq(
1494+
// All projects below will be used to generated documentation for Scala 3
1495+
classDirectory.in(`scala3-interfaces`).in(Compile).value,
1496+
classDirectory.in(`tasty-core`).in(Compile).value,
1497+
classDirectory.in(`scala3-library`).in(Compile).value,
1498+
// TODO this one fails to load using TASTY
1499+
// classDirectory.in(`stdlib-bootstrapped`).in(Compile).value,
1500+
)
1501+
val roots = dottyJars.map(_.toString).mkString(java.io.File.pathSeparator)
1502+
1503+
if (dottyJars.isEmpty) Def.task { streams.value.log.error("Dotty lib wasn't found") }
1504+
else generateDocumentation(roots, "Scala 3", "stdLib", "-p dotty-docs/docs")
1505+
}.value,
1506+
generateTestcasesDocumentation := Def.taskDyn {
1507+
generateDocumentation(Build.testcasesOutputDir.in(Test).value, "Scala3doc testcases", "testcases")
1508+
}.value,
1509+
buildInfoKeys in Test := Seq[BuildInfoKey](
1510+
Build.testcasesOutputDir.in(Test),
1511+
Build.testcasesSourceRoot.in(Test),
1512+
),
1513+
buildInfoPackage in Test := "dotty.dokka",
1514+
BuildInfoPlugin.buildInfoScopedSettings(Test),
1515+
BuildInfoPlugin.buildInfoDefaultSettings,
1516+
// Uncomment to debug dokka processing (require to run debug in listen mode on 5005 port)
1517+
// javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5005,suspend=y"
1518+
)
1519+
}
1520+
1521+
def asScala3docTestcases: Project =
1522+
project.dependsOn(`scala3-compiler-bootstrapped`).settings(commonBootstrappedSettings)
1523+
14431524
def asDist(implicit mode: Mode): Project = project.
14441525
enablePlugins(PackPlugin).
14451526
withCommonSettings.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
scalaVersion := sys.props("plugin.scalaVersion")
2+
3+
useScala3doc := true
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version"))
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package example
2+
3+
/**
4+
* Automatic Tupling of Function Params: https://dotty.epfl.ch/docs/reference/other-new-features/auto-parameter-tupling.html
5+
*/
6+
object AutoParamTupling {
7+
8+
def test: Unit = {
9+
10+
/**
11+
* In order to get thread safety, you need to put @volatile before lazy vals.
12+
* https://dotty.epfl.ch/docs/reference/changed-features/lazy-vals.html
13+
*/
14+
@volatile lazy val xs: List[String] = List("d", "o", "t", "t", "y")
15+
16+
/**
17+
* Current behaviour in Scala 2.12.2 :
18+
* error: missing parameter type
19+
* Note: The expected type requires a one-argument function accepting a 2-Tuple.
20+
* Consider a pattern matching anonymous function, `{ case (s, i) => ... }`
21+
*/
22+
xs.zipWithIndex.map((s, i) => println(s"$i: $s"))
23+
24+
}
25+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package example
2+
3+
import scala.concurrent.{ExecutionContext, Future}
4+
import scala.util.Try
5+
6+
/**
7+
* Context Queries:
8+
* - http://dotty.epfl.ch/docs/reference/contextual/query-types.html,
9+
* - https://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html
10+
*/
11+
object ContextQueries /* Formerly known as Implicit Function Types */ {
12+
13+
object context {
14+
// type alias Contextual
15+
type Contextual[T] = ExecutionContext ?=> T
16+
17+
// sum is expanded to sum(x, y)(ctx)
18+
def asyncSum(x: Int, y: Int): Contextual[Future[Int]] = Future(x + y)
19+
20+
def asyncMult(x: Int, y: Int)(using ctx: ExecutionContext) = Future(x * y)
21+
}
22+
23+
object parse {
24+
25+
type Parseable[T] = ImpliedInstances.StringParser[T] ?=> Try[T]
26+
27+
def sumStrings(x: String, y: String): Parseable[Int] = {
28+
val parser = implicitly[ImpliedInstances.StringParser[Int]]
29+
val tryA = parser.parse(x)
30+
val tryB = parser.parse(y)
31+
32+
for {
33+
a <- tryA
34+
b <- tryB
35+
} yield a + b
36+
}
37+
}
38+
39+
def test: Unit = {
40+
import ExecutionContext.Implicits.global
41+
context.asyncSum(3, 4).foreach(println)
42+
context.asyncMult(3, 4).foreach(println)
43+
44+
println(parse.sumStrings("3", "4"))
45+
println(parse.sumStrings("3", "a"))
46+
}
47+
48+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package example
2+
3+
import scala.language.implicitConversions
4+
5+
/**
6+
* Conversions: http://dotty.epfl.ch/docs/reference/contextual/conversions.html
7+
*/
8+
object Conversion {
9+
10+
case class IntWrapper(a: Int) extends AnyVal
11+
case class DoubleWrapper(b: Double) extends AnyVal
12+
13+
def convert[T, U](x: T)(using converter: Conversion[T, U]): U = converter(x)
14+
15+
given IntWrapperToDoubleWrapper as Conversion[IntWrapper, DoubleWrapper] = new Conversion[IntWrapper, DoubleWrapper] {
16+
override def apply(i: IntWrapper): DoubleWrapper = new DoubleWrapper(i.a.toDouble)
17+
}
18+
19+
def useConversion(using f: Conversion[IntWrapper, DoubleWrapper]) = {
20+
val y: IntWrapper = new IntWrapper(4)
21+
val x: DoubleWrapper = y
22+
x
23+
}
24+
25+
/* Not working anymore.
26+
def useConversion(implicit f: A => B) = {
27+
val y: A = ...
28+
val x: B = a // error under Dotty
29+
}
30+
*/
31+
32+
def test: Unit = {
33+
println(useConversion)
34+
println(convert(new IntWrapper(42)))
35+
}
36+
37+
38+
39+
}

0 commit comments

Comments
 (0)