Skip to content

Migrate scala3doc to compiler's parser #10462

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 56 additions & 51 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import PathResolver.Defaults
import rewrites.Rewrites
import Settings.Setting

class ScalaSettings extends Settings.SettingGroup {

/** Settings shared by compiler and scala3doc */
trait CommonScalaSettings { self: Settings.SettingGroup =>
protected def defaultClasspath: String = sys.env.getOrElse("CLASSPATH", ".")

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

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

/** Other settings */
val deprecation: Setting[Boolean] = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.") withAbbreviation "--deprecation"
val encoding: Setting[String] = StringSetting("-encoding", "encoding", "Specify character encoding used by source files.", Properties.sourceEncoding) withAbbreviation "--encoding"
val usejavacp: Setting[Boolean] = BooleanSetting("-usejavacp", "Utilize the java.class.path in classpath resolution.") withAbbreviation "--use-java-class-path"

/** Plugin-related setting */
val plugin: Setting[List[String]] = MultiStringSetting ("-Xplugin", "paths", "Load a plugin from each classpath.")
val disable: Setting[List[String]] = MultiStringSetting ("-Xplugin-disable", "plugin", "Disable plugins by name.")
val require: Setting[List[String]] = MultiStringSetting ("-Xplugin-require", "plugin", "Abort if a named plugin is not loaded.")
val showPlugins: Setting[Boolean] = BooleanSetting ("-Xplugin-list", "Print a synopsis of loaded plugins.")
val pluginsDir: Setting[String] = StringSetting ("-Xpluginsdir", "path", "Path to search for plugin archives.", Defaults.scalaPluginPath)
val pluginOptions: Setting[List[String]] = MultiStringSetting ("-P", "plugin:opt", "Pass an option to a plugin, e.g. -P:<plugin>:<opt>")

/** Doctool specific settings */
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we move these to Scala3doc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is used by tastdoc so as long as it exisits we can't

Copy link
Contributor

Choose a reason for hiding this comment

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

Dottydoc, you mean? I guess then we should move it in a PR that deletes Dottydoc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

val siteRoot: Setting[String] = StringSetting(
"-siteroot",
"site root",
"A directory containing static files from which to generate documentation.",
"./docs"
)


val projectName: Setting[String] = StringSetting (
"-project",
"project title",
"The name of the project.",
""
)

val projectVersion: Setting[String] = StringSetting (
"-project-version",
"project version",
"The current version of your project.",
""
)

val projectLogo: Setting[String] = StringSetting(
"-project-logo",
"project logo filename",
"The file that contains the project's logo (in /images).",
""
)
}

class ScalaSettings extends Settings.SettingGroup with CommonScalaSettings {
/** Path related settings */
val semanticdbTarget: Setting[String] = PathSetting("-semanticdb-target", "Specify an alternative output directory for SemanticDB files.", "")

val deprecation: Setting[Boolean] = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.") withAbbreviation "--deprecation"
val explainTypes: Setting[Boolean] = BooleanSetting("-explain-types", "Explain type errors in more detail.") withAbbreviation "--explain-types"
val explain: Setting[Boolean] = BooleanSetting("-explain", "Explain errors in more detail.") withAbbreviation "--explain"
val feature: Setting[Boolean] = BooleanSetting("-feature", "Emit warning and location for usages of features that should be imported explicitly.") withAbbreviation "--feature"
val help: Setting[Boolean] = BooleanSetting("-help", "Print a synopsis of standard options.") withAbbreviation "--help"
val color: Setting[String] = ChoiceSetting("-color", "mode", "Colored output", List("always", "never"/*, "auto"*/), "always"/* "auto"*/) withAbbreviation "--color"
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")
val target: Setting[String] = ChoiceSetting("-target", "target", "Target platform for object files.", List("jvm-1.8", "jvm-9"), "jvm-1.8") withAbbreviation "--target"
val scalajs: Setting[Boolean] = BooleanSetting("-scalajs", "Compile in Scala.js mode (requires scalajs-library.jar on the classpath).") withAbbreviation "--scalajs"
val unchecked: Setting[Boolean] = BooleanSetting("-unchecked", "Enable additional warnings where generated code depends on assumptions.") withAbbreviation "--unchecked"
val uniqid: Setting[Boolean] = BooleanSetting("-uniqid", "Uniquely tag all identifiers in debugging output.") withAbbreviation "--unique-id"
val usejavacp: Setting[Boolean] = BooleanSetting("-usejavacp", "Utilize the java.class.path in classpath resolution.") withAbbreviation "--use-java-class-path"
val verbose: Setting[Boolean] = BooleanSetting("-verbose", "Output messages about what the compiler is doing.") withAbbreviation "--verbose"
val version: Setting[Boolean] = BooleanSetting("-version", "Print product version and exit.") withAbbreviation "--version"
val pageWidth: Setting[Int] = IntSetting("-pagewidth", "Set page width", 80) withAbbreviation "--page-width"
val language: Setting[List[String]] = MultiStringSetting("-language", "feature", "Enable one or more language features.") withAbbreviation "--language"
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"
val silentWarnings: Setting[Boolean] = BooleanSetting("-nowarn", "Silence all warnings.") withAbbreviation "--no-warnings"
val fromTasty: Setting[Boolean] = BooleanSetting("-from-tasty", "Compile classes from tasty files. The arguments are .tasty or .jar files.") withAbbreviation "--from-tasty"

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

/** Plugin-related setting */
val plugin: Setting[List[String]] = MultiStringSetting ("-Xplugin", "paths", "Load a plugin from each classpath.")
val disable: Setting[List[String]] = MultiStringSetting ("-Xplugin-disable", "plugin", "Disable plugins by name.")
val require: Setting[List[String]] = MultiStringSetting ("-Xplugin-require", "plugin", "Abort if a named plugin is not loaded.")
val showPlugins: Setting[Boolean] = BooleanSetting ("-Xplugin-list", "Print a synopsis of loaded plugins.")
val pluginsDir: Setting[String] = StringSetting ("-Xpluginsdir", "path", "Path to search for plugin archives.", Defaults.scalaPluginPath)
val pluginOptions: Setting[List[String]] = MultiStringSetting ("-P", "plugin:opt", "Pass an option to a plugin, e.g. -P:<plugin>:<opt>")

/** Scala.js-related settings */
val scalajsGenStaticForwardersForNonTopLevelObjects: Setting[Boolean] = BooleanSetting("-scalajs-genStaticForwardersForNonTopLevelObjects", "Generate static forwarders even for non-top-level objects (Scala.js only)")
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)")

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

/** Dottydoc specific settings */
val siteRoot: Setting[String] = StringSetting(
"-siteroot",
"site root",
"A directory containing static files from which to generate documentation.",
"./docs"
)


val projectName: Setting[String] = StringSetting (
"-project",
"project title",
"The name of the project.",
""
)

val projectVersion: Setting[String] = StringSetting (
"-project-version",
"project version",
"The current version of your project.",
""
)
/** Dottydoc specific settings that are not used in scala3doc */
val docSnapshot: Setting[Boolean] = BooleanSetting("-doc-snapshot", "Generate a documentation snapshot for the current Dotty version")

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

val projectLogo: Setting[String] = StringSetting(
"-project-logo",
"project logo filename",
"The file that contains the project's logo (in /images).",
""
)

val docSnapshot: Setting[Boolean] = BooleanSetting("-doc-snapshot", "Generate a documentation snapshot for the current Dotty version")

val wikiSyntax: Setting[Boolean] = BooleanSetting("-Xwiki-syntax", "Retains the Scala2 behavior of using Wiki Syntax in Scaladoc.")
}
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/config/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ object Settings {
*
* to get their arguments.
*/
protected[config] def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
def stateWithArgs(args: List[String]) = ArgsSummary(state.sstate, args, state.errors, state.warnings)
state.arguments match {
case Nil =>
Expand Down Expand Up @@ -269,8 +269,8 @@ object Settings {
def BooleanSetting(name: String, descr: String, initialValue: Boolean = false): Setting[Boolean] =
publish(Setting(name, descr, initialValue))

def StringSetting(name: String, helpArg: String, descr: String, default: String): Setting[String] =
publish(Setting(name, descr, default, helpArg))
def StringSetting(name: String, helpArg: String, descr: String, default: String, aliases: List[String] = Nil): Setting[String] =
publish(Setting(name, descr, default, helpArg, aliases = aliases))

def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): Setting[String] =
publish(Setting(name, descr, default, helpArg, choices))
Expand Down
13 changes: 7 additions & 6 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1484,8 +1484,9 @@ object Build {
def asScala3doc: Project = {
def generateDocumentation(targets: String, name: String, outDir: String, ref: String, params: String = "") = Def.taskDyn {
val projectVersion = version.value
val sourcesAndRevision = s"-s github://lampepfl/dotty --revision $ref --projectVersion $projectVersion"
val cmd = s""" -d $outDir -t $targets -n "$name" $sourcesAndRevision $params"""
IO.createDirectory(file(outDir))
val sourcesAndRevision = s"-source-links github://lampepfl/dotty -revision $ref -project-version $projectVersion"
val cmd = s""" -d $outDir -project "$name" $sourcesAndRevision $params $targets"""
run.in(Compile).toTask(cmd)
}

Expand Down Expand Up @@ -1524,7 +1525,7 @@ object Build {
generateDocumentation(
classDirectory.in(Compile).value.getAbsolutePath,
"scala3doc", "scala3doc/output/self", VersionUtil.gitHash,
"-p scala3doc/documentation --projectLogo scala3doc/documentation/logo.svg")
"-siteroot scala3doc/documentation -project-logo scala3doc/documentation/logo.svg")
}.value,

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

val roots = joinProducts(dottyJars)
val roots = dottyJars.mkString(" ")

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


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

Expand Down
31 changes: 8 additions & 23 deletions sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object DottyPlugin extends AutoPlugin {
val isDottyJS = settingKey[Boolean]("Is this project compiled with Dotty and Scala.js?")

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

// NOTE:
// - this is a def to support `scalaVersion := dottyLatestNightlyBuild`
Expand Down Expand Up @@ -360,17 +360,6 @@ object DottyPlugin extends AutoPlugin {
// Configuration for the doctool
resolvers ++= (if(!useScala3doc.value) Nil else Seq(Resolver.jcenterRepo)),
useScala3doc := false,
scala3docOptions := Nil,
Compile / doc / scalacOptions := {
// We are passing scala3doc argument list as single argument to scala instance starting with magic prefix "--+DOC+"
val s3dOpts = scala3docOptions.value.map("--+DOC+" + _)
val s3cOpts = (Compile / doc / scalacOptions).value
if (isDotty.value && useScala3doc.value) {
s3dOpts ++ s3cOpts
} else {
s3cOpts
}
},
// We need to add doctool classes to the classpath so they can be called
scalaInstance in doc := Def.taskDyn {
if (isDotty.value)
Expand Down Expand Up @@ -443,18 +432,14 @@ object DottyPlugin extends AutoPlugin {
}

private val docSettings = inTask(doc)(Seq(
sources := Def.taskDyn {
val old = sources.value

if (isDotty.value) Def.task {
val _ = compile.value // Ensure that everything is compiled, so TASTy is available.
val tastyFiles = (classDirectory.value ** "*.tasty").get.map(_.getAbsoluteFile)
old ++ tastyFiles
} else Def.task {
old
}
tastyFiles := {
val _ = compile.value // Ensure that everything is compiled, so TASTy is available.
(classDirectory.value ** "*.tasty").get.map(_.getAbsoluteFile)
},
sources := Def.taskDyn[Seq[File]] {
if (isDotty.value) Def.task { tastyFiles.value }
else Def.task { sources.value }
}.value,

scalacOptions ++= {
if (isDotty.value) {
val projectName =
Expand Down
14 changes: 14 additions & 0 deletions scala3doc-testcases/src/example/typeAndObjects/binaryops.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package example.typeAndObjects


sealed trait Expr

object Expr{
case class BinaryOp(offset: Int, lhs: Expr, op: BinaryOp.Op, rhs: Expr) extends Expr

object BinaryOp{
sealed trait Op
case object `<<` extends Op
case object `>>` extends Op
}
}
4 changes: 3 additions & 1 deletion scala3doc-testcases/src/tests/typeLambdas.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ type Id[T <: AnyKind]

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

type TL2 = Id[[X >: Int] =>> [Y <: String] =>> Map[X, Y]]
type TL2 = Id[[X >: Int] =>> [Y <: String] =>> Map[X, Y]]

type LabdaA = List[(x: String) => List[x.type]]
5 changes: 5 additions & 0 deletions scala3doc/src/dotty/dokka/DocContext.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dotty.dokka

import dotty.tools.dotc.core.Contexts._

type DocContext = Context
14 changes: 7 additions & 7 deletions scala3doc/src/dotty/dokka/DottyDokkaConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import java.io.File
import collection.JavaConverters._
import dotty.dokka.site.StaticSiteContext

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

lazy val sourceLinks: SourceLinks = SourceLinks.load(docConfiguration)
lazy val sourceLinks: SourceLinks = SourceLinks.load(args)

lazy val staticSiteContext = docConfiguration.args.docsRoot.map(path => StaticSiteContext(
lazy val staticSiteContext = args.docsRoot.map(path => StaticSiteContext(
File(path).getAbsoluteFile(),
Set(mkSourceSet.asInstanceOf[SourceSetWrapper]),
docConfiguration.args,
args,
sourceLinks
))

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

lazy val mkSourceSet: DokkaSourceSet =
new DokkaSourceSetImpl(
/*displayName=*/ docConfiguration.args.name,
/*sourceSetID=*/ new DokkaSourceSetID(docConfiguration.args.name, "main"),
/*displayName=*/ args.name,
/*sourceSetID=*/ new DokkaSourceSetID(args.name, "main"),
/*classpath=*/ JList(),
/*sourceRoots=*/ JSet(),
/*dependentSourceSets=*/ JSet(),
Expand Down
Loading