Skip to content

Commit 0f0137e

Browse files
authored
Merge pull request #10462 from romanowski/scala3doc/use-dotty-argument-parser
Migrate scala3doc to compiler's parser
2 parents 866656c + 2cd20e4 commit 0f0137e

32 files changed

+569
-465
lines changed

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import PathResolver.Defaults
77
import rewrites.Rewrites
88
import Settings.Setting
99

10-
class ScalaSettings extends Settings.SettingGroup {
11-
10+
/** Settings shared by compiler and scala3doc */
11+
trait CommonScalaSettings { self: Settings.SettingGroup =>
1212
protected def defaultClasspath: String = sys.env.getOrElse("CLASSPATH", ".")
1313

1414
/** Path related settings */
@@ -18,33 +18,76 @@ class ScalaSettings extends Settings.SettingGroup {
1818
val javaextdirs: Setting[String] = PathSetting("-javaextdirs", "Override java extdirs classpath.", Defaults.javaExtDirs) withAbbreviation "--java-extension-directories"
1919
val sourcepath: Setting[String] = PathSetting("-sourcepath", "Specify location(s) of source files.", Defaults.scalaSourcePath) withAbbreviation "--source-path"
2020
val sourceroot: Setting[String] = PathSetting("-sourceroot", "Specify workspace root directory.", ".")
21-
val semanticdbTarget: Setting[String] = PathSetting("-semanticdb-target", "Specify an alternative output directory for SemanticDB files.", "")
2221

2322
val classpath: Setting[String] = PathSetting("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp" withAbbreviation "--class-path"
2423
val outputDir: Setting[AbstractFile] = OutputSetting("-d", "directory|jar", "Destination for generated classfiles.",
2524
new PlainDirectory(Directory(".")))
2625
val priorityclasspath: Setting[String] = PathSetting("-priorityclasspath", "Class path that takes precedence over all other paths (or testing only).", "") withAbbreviation "--priority-class-path"
26+
val color: Setting[String] = ChoiceSetting("-color", "mode", "Colored output", List("always", "never"/*, "auto"*/), "always"/* "auto"*/) withAbbreviation "--color"
27+
val verbose: Setting[Boolean] = BooleanSetting("-verbose", "Output messages about what the compiler is doing.") withAbbreviation "--verbose"
28+
val version: Setting[Boolean] = BooleanSetting("-version", "Print product version and exit.") withAbbreviation "--version"
29+
val pageWidth: Setting[Int] = IntSetting("-pagewidth", "Set page width", 80) withAbbreviation "--page-width"
30+
val silentWarnings: Setting[Boolean] = BooleanSetting("-nowarn", "Silence all warnings.") withAbbreviation "--no-warnings"
2731

2832
/** Other settings */
29-
val deprecation: Setting[Boolean] = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.") withAbbreviation "--deprecation"
3033
val encoding: Setting[String] = StringSetting("-encoding", "encoding", "Specify character encoding used by source files.", Properties.sourceEncoding) withAbbreviation "--encoding"
34+
val usejavacp: Setting[Boolean] = BooleanSetting("-usejavacp", "Utilize the java.class.path in classpath resolution.") withAbbreviation "--use-java-class-path"
35+
36+
/** Plugin-related setting */
37+
val plugin: Setting[List[String]] = MultiStringSetting ("-Xplugin", "paths", "Load a plugin from each classpath.")
38+
val disable: Setting[List[String]] = MultiStringSetting ("-Xplugin-disable", "plugin", "Disable plugins by name.")
39+
val require: Setting[List[String]] = MultiStringSetting ("-Xplugin-require", "plugin", "Abort if a named plugin is not loaded.")
40+
val showPlugins: Setting[Boolean] = BooleanSetting ("-Xplugin-list", "Print a synopsis of loaded plugins.")
41+
val pluginsDir: Setting[String] = StringSetting ("-Xpluginsdir", "path", "Path to search for plugin archives.", Defaults.scalaPluginPath)
42+
val pluginOptions: Setting[List[String]] = MultiStringSetting ("-P", "plugin:opt", "Pass an option to a plugin, e.g. -P:<plugin>:<opt>")
43+
44+
/** Doctool specific settings */
45+
val siteRoot: Setting[String] = StringSetting(
46+
"-siteroot",
47+
"site root",
48+
"A directory containing static files from which to generate documentation.",
49+
"./docs"
50+
)
51+
52+
53+
val projectName: Setting[String] = StringSetting (
54+
"-project",
55+
"project title",
56+
"The name of the project.",
57+
""
58+
)
59+
60+
val projectVersion: Setting[String] = StringSetting (
61+
"-project-version",
62+
"project version",
63+
"The current version of your project.",
64+
""
65+
)
66+
67+
val projectLogo: Setting[String] = StringSetting(
68+
"-project-logo",
69+
"project logo filename",
70+
"The file that contains the project's logo (in /images).",
71+
""
72+
)
73+
}
74+
75+
class ScalaSettings extends Settings.SettingGroup with CommonScalaSettings {
76+
/** Path related settings */
77+
val semanticdbTarget: Setting[String] = PathSetting("-semanticdb-target", "Specify an alternative output directory for SemanticDB files.", "")
78+
79+
val deprecation: Setting[Boolean] = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.") withAbbreviation "--deprecation"
3180
val explainTypes: Setting[Boolean] = BooleanSetting("-explain-types", "Explain type errors in more detail.") withAbbreviation "--explain-types"
3281
val explain: Setting[Boolean] = BooleanSetting("-explain", "Explain errors in more detail.") withAbbreviation "--explain"
3382
val feature: Setting[Boolean] = BooleanSetting("-feature", "Emit warning and location for usages of features that should be imported explicitly.") withAbbreviation "--feature"
3483
val help: Setting[Boolean] = BooleanSetting("-help", "Print a synopsis of standard options.") withAbbreviation "--help"
35-
val color: Setting[String] = ChoiceSetting("-color", "mode", "Colored output", List("always", "never"/*, "auto"*/), "always"/* "auto"*/) withAbbreviation "--color"
3684
val source: Setting[String] = ChoiceSetting("-source", "source version", "source version", List("3.0", "3.1", "3.0-migration", "3.1-migration"), "3.0").withAbbreviation("--source")
3785
val target: Setting[String] = ChoiceSetting("-target", "target", "Target platform for object files.", List("jvm-1.8", "jvm-9"), "jvm-1.8") withAbbreviation "--target"
3886
val scalajs: Setting[Boolean] = BooleanSetting("-scalajs", "Compile in Scala.js mode (requires scalajs-library.jar on the classpath).") withAbbreviation "--scalajs"
3987
val unchecked: Setting[Boolean] = BooleanSetting("-unchecked", "Enable additional warnings where generated code depends on assumptions.") withAbbreviation "--unchecked"
4088
val uniqid: Setting[Boolean] = BooleanSetting("-uniqid", "Uniquely tag all identifiers in debugging output.") withAbbreviation "--unique-id"
41-
val usejavacp: Setting[Boolean] = BooleanSetting("-usejavacp", "Utilize the java.class.path in classpath resolution.") withAbbreviation "--use-java-class-path"
42-
val verbose: Setting[Boolean] = BooleanSetting("-verbose", "Output messages about what the compiler is doing.") withAbbreviation "--verbose"
43-
val version: Setting[Boolean] = BooleanSetting("-version", "Print product version and exit.") withAbbreviation "--version"
44-
val pageWidth: Setting[Int] = IntSetting("-pagewidth", "Set page width", 80) withAbbreviation "--page-width"
4589
val language: Setting[List[String]] = MultiStringSetting("-language", "feature", "Enable one or more language features.") withAbbreviation "--language"
4690
val rewrite: Setting[Option[Rewrites]] = OptionSetting[Rewrites]("-rewrite", "When used in conjunction with a `...-migration` source version, rewrites sources to migrate to new version.") withAbbreviation "--rewrite"
47-
val silentWarnings: Setting[Boolean] = BooleanSetting("-nowarn", "Silence all warnings.") withAbbreviation "--no-warnings"
4891
val fromTasty: Setting[Boolean] = BooleanSetting("-from-tasty", "Compile classes from tasty files. The arguments are .tasty or .jar files.") withAbbreviation "--from-tasty"
4992

5093
val newSyntax: Setting[Boolean] = BooleanSetting("-new-syntax", "Require `then` and `do` in control expressions.")
@@ -57,20 +100,11 @@ class ScalaSettings extends Settings.SettingGroup {
57100
val printTasty: Setting[Boolean] = BooleanSetting("-print-tasty", "Prints the raw tasty.") withAbbreviation "--print-tasty"
58101
val printLines: Setting[Boolean] = BooleanSetting("-print-lines", "Show source code line numbers.") withAbbreviation "--print-lines"
59102

60-
/** Plugin-related setting */
61-
val plugin: Setting[List[String]] = MultiStringSetting ("-Xplugin", "paths", "Load a plugin from each classpath.")
62-
val disable: Setting[List[String]] = MultiStringSetting ("-Xplugin-disable", "plugin", "Disable plugins by name.")
63-
val require: Setting[List[String]] = MultiStringSetting ("-Xplugin-require", "plugin", "Abort if a named plugin is not loaded.")
64-
val showPlugins: Setting[Boolean] = BooleanSetting ("-Xplugin-list", "Print a synopsis of loaded plugins.")
65-
val pluginsDir: Setting[String] = StringSetting ("-Xpluginsdir", "path", "Path to search for plugin archives.", Defaults.scalaPluginPath)
66-
val pluginOptions: Setting[List[String]] = MultiStringSetting ("-P", "plugin:opt", "Pass an option to a plugin, e.g. -P:<plugin>:<opt>")
67-
68103
/** Scala.js-related settings */
69104
val scalajsGenStaticForwardersForNonTopLevelObjects: Setting[Boolean] = BooleanSetting("-scalajs-genStaticForwardersForNonTopLevelObjects", "Generate static forwarders even for non-top-level objects (Scala.js only)")
70105
val scalajsMapSourceURI: Setting[List[String]] = MultiStringSetting("-scalajs-mapSourceURI", "uri1[->uri2]", "rebases source URIs from uri1 to uri2 (or to a relative URI) for source maps (Scala.js only)")
71106

72-
/** -X "Advanced" settings
73-
*/
107+
/** -X "Advanced" settings */
74108
val Xhelp: Setting[Boolean] = BooleanSetting("-X", "Print a synopsis of advanced options.")
75109
val XnoForwarders: Setting[Boolean] = BooleanSetting("-Xno-forwarders", "Do not generate static forwarders in mirror classes.")
76110
val XmaxInlines: Setting[Int] = IntSetting("-Xmax-inlines", "Maximal number of successive inlines.", 32)
@@ -186,28 +220,8 @@ class ScalaSettings extends Settings.SettingGroup {
186220
val Yinstrument: Setting[Boolean] = BooleanSetting("-Yinstrument", "Add instrumentation code that counts allocations and closure creations.")
187221
val YinstrumentDefs: Setting[Boolean] = BooleanSetting("-Yinstrument-defs", "Add instrumentation code that counts method calls; needs -Yinstrument to be set, too.")
188222

189-
/** Dottydoc specific settings */
190-
val siteRoot: Setting[String] = StringSetting(
191-
"-siteroot",
192-
"site root",
193-
"A directory containing static files from which to generate documentation.",
194-
"./docs"
195-
)
196-
197-
198-
val projectName: Setting[String] = StringSetting (
199-
"-project",
200-
"project title",
201-
"The name of the project.",
202-
""
203-
)
204-
205-
val projectVersion: Setting[String] = StringSetting (
206-
"-project-version",
207-
"project version",
208-
"The current version of your project.",
209-
""
210-
)
223+
/** Dottydoc specific settings that are not used in scala3doc */
224+
val docSnapshot: Setting[Boolean] = BooleanSetting("-doc-snapshot", "Generate a documentation snapshot for the current Dotty version")
211225

212226
val projectUrl: Setting[String] = StringSetting (
213227
"-project-url",
@@ -216,14 +230,5 @@ class ScalaSettings extends Settings.SettingGroup {
216230
""
217231
)
218232

219-
val projectLogo: Setting[String] = StringSetting(
220-
"-project-logo",
221-
"project logo filename",
222-
"The file that contains the project's logo (in /images).",
223-
""
224-
)
225-
226-
val docSnapshot: Setting[Boolean] = BooleanSetting("-doc-snapshot", "Generate a documentation snapshot for the current Dotty version")
227-
228233
val wikiSyntax: Setting[Boolean] = BooleanSetting("-Xwiki-syntax", "Retains the Scala2 behavior of using Wiki Syntax in Scaladoc.")
229234
}

compiler/src/dotty/tools/dotc/config/Settings.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ object Settings {
234234
*
235235
* to get their arguments.
236236
*/
237-
protected[config] def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
237+
def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
238238
def stateWithArgs(args: List[String]) = ArgsSummary(state.sstate, args, state.errors, state.warnings)
239239
state.arguments match {
240240
case Nil =>
@@ -269,8 +269,8 @@ object Settings {
269269
def BooleanSetting(name: String, descr: String, initialValue: Boolean = false): Setting[Boolean] =
270270
publish(Setting(name, descr, initialValue))
271271

272-
def StringSetting(name: String, helpArg: String, descr: String, default: String): Setting[String] =
273-
publish(Setting(name, descr, default, helpArg))
272+
def StringSetting(name: String, helpArg: String, descr: String, default: String, aliases: List[String] = Nil): Setting[String] =
273+
publish(Setting(name, descr, default, helpArg, aliases = aliases))
274274

275275
def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): Setting[String] =
276276
publish(Setting(name, descr, default, helpArg, choices))

project/Build.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,8 +1484,9 @@ object Build {
14841484
def asScala3doc: Project = {
14851485
def generateDocumentation(targets: String, name: String, outDir: String, ref: String, params: String = "") = Def.taskDyn {
14861486
val projectVersion = version.value
1487-
val sourcesAndRevision = s"-s github://lampepfl/dotty --revision $ref --projectVersion $projectVersion"
1488-
val cmd = s""" -d $outDir -t $targets -n "$name" $sourcesAndRevision $params"""
1487+
IO.createDirectory(file(outDir))
1488+
val sourcesAndRevision = s"-source-links github://lampepfl/dotty -revision $ref -project-version $projectVersion"
1489+
val cmd = s""" -d $outDir -project "$name" $sourcesAndRevision $params $targets"""
14891490
run.in(Compile).toTask(cmd)
14901491
}
14911492

@@ -1524,7 +1525,7 @@ object Build {
15241525
generateDocumentation(
15251526
classDirectory.in(Compile).value.getAbsolutePath,
15261527
"scala3doc", "scala3doc/output/self", VersionUtil.gitHash,
1527-
"-p scala3doc/documentation --projectLogo scala3doc/documentation/logo.svg")
1528+
"-siteroot scala3doc/documentation -project-logo scala3doc/documentation/logo.svg")
15281529
}.value,
15291530

15301531
generateScala3Documentation := Def.inputTaskDyn {
@@ -1538,7 +1539,7 @@ object Build {
15381539
(`scala3-library-bootstrapped`/Compile/products).value,
15391540
).flatten
15401541

1541-
val roots = joinProducts(dottyJars)
1542+
val roots = dottyJars.mkString(" ")
15421543

15431544
if (dottyJars.isEmpty) Def.task { streams.value.log.error("Dotty lib wasn't found") }
15441545
else Def.task{
@@ -1548,7 +1549,7 @@ object Build {
15481549
IO.write(dest / "CNAME", "dotty.epfl.ch")
15491550
}.dependsOn(generateDocumentation(
15501551
roots, "Scala 3", dest.getAbsolutePath, "master",
1551-
"-p scala3doc/scala3-docs --projectLogo scala3doc/scala3-docs/logo.svg"))
1552+
"-siteroot scala3doc/scala3-docs -project-logo scala3doc/scala3-docs/logo.svg"))
15521553
}.evaluated,
15531554

15541555

@@ -1562,7 +1563,7 @@ object Build {
15621563
if (dottyJars.isEmpty) Def.task { streams.value.log.error("Dotty lib wasn't found") }
15631564
else generateDocumentation(
15641565
roots, "Scala 3", "scala3doc/output/scala3-stdlib", "maser",
1565-
"-p scala3doc/scala3-docs --syntax wiki --projectLogo scala3doc/scala3-docs/logo.svg "
1566+
"-siteroot scala3doc/scala3-docs -comment-syntax wiki -project-logo scala3doc/scala3-docs/logo.svg "
15661567
)
15671568
}.value,
15681569

sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object DottyPlugin extends AutoPlugin {
1919
val isDottyJS = settingKey[Boolean]("Is this project compiled with Dotty and Scala.js?")
2020

2121
val useScala3doc = settingKey[Boolean]("Use Scala3doc as the documentation tool")
22-
val scala3docOptions = settingKey[Seq[String]]("Options for Scala3doc")
22+
val tastyFiles = taskKey[Seq[File]]("List all testy files")
2323

2424
// NOTE:
2525
// - this is a def to support `scalaVersion := dottyLatestNightlyBuild`
@@ -360,17 +360,6 @@ object DottyPlugin extends AutoPlugin {
360360
// Configuration for the doctool
361361
resolvers ++= (if(!useScala3doc.value) Nil else Seq(Resolver.jcenterRepo)),
362362
useScala3doc := false,
363-
scala3docOptions := Nil,
364-
Compile / doc / scalacOptions := {
365-
// We are passing scala3doc argument list as single argument to scala instance starting with magic prefix "--+DOC+"
366-
val s3dOpts = scala3docOptions.value.map("--+DOC+" + _)
367-
val s3cOpts = (Compile / doc / scalacOptions).value
368-
if (isDotty.value && useScala3doc.value) {
369-
s3dOpts ++ s3cOpts
370-
} else {
371-
s3cOpts
372-
}
373-
},
374363
// We need to add doctool classes to the classpath so they can be called
375364
scalaInstance in doc := Def.taskDyn {
376365
if (isDotty.value)
@@ -443,18 +432,14 @@ object DottyPlugin extends AutoPlugin {
443432
}
444433

445434
private val docSettings = inTask(doc)(Seq(
446-
sources := Def.taskDyn {
447-
val old = sources.value
448-
449-
if (isDotty.value) Def.task {
450-
val _ = compile.value // Ensure that everything is compiled, so TASTy is available.
451-
val tastyFiles = (classDirectory.value ** "*.tasty").get.map(_.getAbsoluteFile)
452-
old ++ tastyFiles
453-
} else Def.task {
454-
old
455-
}
435+
tastyFiles := {
436+
val _ = compile.value // Ensure that everything is compiled, so TASTy is available.
437+
(classDirectory.value ** "*.tasty").get.map(_.getAbsoluteFile)
438+
},
439+
sources := Def.taskDyn[Seq[File]] {
440+
if (isDotty.value) Def.task { tastyFiles.value }
441+
else Def.task { sources.value }
456442
}.value,
457-
458443
scalacOptions ++= {
459444
if (isDotty.value) {
460445
val projectName =
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package example.typeAndObjects
2+
3+
4+
sealed trait Expr
5+
6+
object Expr{
7+
case class BinaryOp(offset: Int, lhs: Expr, op: BinaryOp.Op, rhs: Expr) extends Expr
8+
9+
object BinaryOp{
10+
sealed trait Op
11+
case object `<<` extends Op
12+
case object `>>` extends Op
13+
}
14+
}

scala3doc-testcases/src/tests/typeLambdas.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ type Id[T <: AnyKind]
1010

1111
type TL1 = Id[[X, Y] =>> Map[X,Y]]
1212

13-
type TL2 = Id[[X >: Int] =>> [Y <: String] =>> Map[X, Y]]
13+
type TL2 = Id[[X >: Int] =>> [Y <: String] =>> Map[X, Y]]
14+
15+
type LabdaA = List[(x: String) => List[x.type]]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package dotty.dokka
2+
3+
import dotty.tools.dotc.core.Contexts._
4+
5+
type DocContext = Context

scala3doc/src/dotty/dokka/DottyDokkaConfig.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import java.io.File
66
import collection.JavaConverters._
77
import dotty.dokka.site.StaticSiteContext
88

9-
case class DottyDokkaConfig(docConfiguration: DocConfiguration) extends DokkaConfiguration:
10-
override def getOutputDir: File = docConfiguration.args.output
9+
case class DottyDokkaConfig(args: Scala3doc.Args, docContext: DocContext) extends DokkaConfiguration:
10+
override def getOutputDir: File = args.output
1111
override def getCacheRoot: File = null
1212
override def getOfflineMode: Boolean = false
1313
override def getFailOnWarning: Boolean = false
@@ -17,21 +17,21 @@ case class DottyDokkaConfig(docConfiguration: DocConfiguration) extends DokkaCon
1717
override def getModuleName(): String = "ModuleName"
1818
override def getModuleVersion(): String = ""
1919

20-
lazy val sourceLinks: SourceLinks = SourceLinks.load(docConfiguration)
20+
lazy val sourceLinks: SourceLinks = SourceLinks.load(args)
2121

22-
lazy val staticSiteContext = docConfiguration.args.docsRoot.map(path => StaticSiteContext(
22+
lazy val staticSiteContext = args.docsRoot.map(path => StaticSiteContext(
2323
File(path).getAbsoluteFile(),
2424
Set(mkSourceSet.asInstanceOf[SourceSetWrapper]),
25-
docConfiguration.args,
25+
args,
2626
sourceLinks
2727
))
2828

2929
override def getPluginsConfiguration: JList[DokkaConfiguration.PluginConfiguration] = JList()
3030

3131
lazy val mkSourceSet: DokkaSourceSet =
3232
new DokkaSourceSetImpl(
33-
/*displayName=*/ docConfiguration.args.name,
34-
/*sourceSetID=*/ new DokkaSourceSetID(docConfiguration.args.name, "main"),
33+
/*displayName=*/ args.name,
34+
/*sourceSetID=*/ new DokkaSourceSetID(args.name, "main"),
3535
/*classpath=*/ JList(),
3636
/*sourceRoots=*/ JSet(),
3737
/*dependentSourceSets=*/ JSet(),

0 commit comments

Comments
 (0)