Skip to content

Scala3doc/doc context #10568

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 6 commits into from
Dec 2, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import core.Decorators._
import printing.Highlighting.{Blue, Red, Yellow}
import printing.SyntaxHighlighting
import Diagnostic._
import util.SourcePosition
import util.{ SourcePosition, NoSourcePosition }
import util.Chars.{ LF, CR, FF, SU }
import scala.annotation.switch

Expand Down Expand Up @@ -112,9 +112,9 @@ trait MessageRendering {
* @return separator containing error location and kind
*/
def posStr(pos: SourcePosition, diagnosticLevel: String, message: Message)(using Context): String =
if (pos.exists) hl(diagnosticLevel)({
if (pos.source != NoSourcePosition.source) hl(diagnosticLevel)({
val pos1 = pos.nonInlined
val file =
val file = if !pos.exists then pos1.source.file.toString else
s"${pos1.source.file.toString}:${pos1.line + 1}:${pos1.column}"
val errId =
if (message.errorId ne ErrorMessageID.NoExplanationID) {
Expand Down
124 changes: 123 additions & 1 deletion scala3doc/src/dotty/dokka/DocContext.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,127 @@
package dotty.dokka

import org.jetbrains.dokka._
import org.jetbrains.dokka.DokkaSourceSetImpl
import org.jetbrains.dokka.plugability.DokkaContext
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths

import collection.JavaConverters._
import dotty.dokka.site.StaticSiteContext
import dotty.tools.dotc.core.Contexts._
import dotty.tools.io.VirtualFile
import dotty.tools.dotc.util.SourceFile
import dotty.tools.dotc.util.SourcePosition
import dotty.tools.dotc.util.Spans
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import scala.io.Codec

type CompilerContext = dotty.tools.dotc.core.Contexts.Context

given compilerContext(using docContext: DocContext) as CompilerContext =
docContext.compilerContext

given docContextFromDokka(using dokkaContext: DokkaContext) as DocContext =
dokkaContext.getConfiguration.asInstanceOf[DocContext]

val report = dotty.tools.dotc.report

def relativePath(p: Path)(using Context): Path =
val root = Paths.get("").toAbsolutePath()
val absPath = p.toAbsolutePath
println(Seq(p, absPath, absPath.startsWith(root), root.relativize(absPath)))
if absPath.startsWith(root) then root.relativize(p.toAbsolutePath()) else p


def throwableToString(t: Throwable)(using CompilerContext): String =
val os = new ByteArrayOutputStream
t.printStackTrace(new PrintStream(os))
val stLinkes = os.toString().linesIterator
if ctx.settings.verbose.value then stLinkes.mkString("\n")
else stLinkes.take(5).mkString("\n")

private def sourcePostionFor(f: File)(using CompilerContext) =
val relPath = relativePath(f.toPath)
val virtualFile = new VirtualFile(relPath.toString, relPath.toString)
val sourceFile = new SourceFile(virtualFile, Codec.UTF8)
SourcePosition(sourceFile, Spans.NoSpan)

// TODO (https://github.com/lampepfl/scala3doc/issues/238): provide proper error handling
private def createMessage(
msg: String, file: File, e: Throwable | Null)(using CompilerContext): String =
val localizedMessage = s"$file: $msg"
e match
case null => localizedMessage
case throwable: Throwable =>
s"$localizedMessage \ncaused by: ${throwableToString(throwable)}"

extension (r: report.type):
def error(m: String, f: File, e: Throwable | Null = null)(using CompilerContext): Unit =
r.error(createMessage(m, f, e), sourcePostionFor(f))

def warn(m: String, f: File, e: Throwable)(using CompilerContext): Unit =
r.warning(createMessage(m, f, e), sourcePostionFor(f))

def warn(m: String, f: File)(using CompilerContext): Unit =
r.warning(createMessage(m, f, null), sourcePostionFor(f))


case class DocContext(args: Scala3doc.Args, compilerContext: CompilerContext)
extends DokkaConfiguration:
override def getOutputDir: File = args.output
override def getCacheRoot: File = null
override def getOfflineMode: Boolean = false
override def getFailOnWarning: Boolean = false
override def getSourceSets: JList[DokkaSourceSet] = JList(mkSourceSet)
override def getModules: JList[DokkaConfiguration.DokkaModuleDescription] = JList()
override def getPluginsClasspath: JList[File] = JList()
override def getModuleName(): String = "ModuleName"
override def getModuleVersion(): String = ""

lazy val sourceLinks: SourceLinks = SourceLinks.load(using this)

lazy val displaySourceSets = getSourceSets.toDisplaySourceSet

val logger = new Scala3DocDokkaLogger(using compilerContext)

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

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

val mkSourceSet: DokkaSourceSet =
new DokkaSourceSetImpl(
/*displayName=*/ args.name,
/*sourceSetID=*/ new DokkaSourceSetID(args.name, "main"),
/*classpath=*/ JList(),
/*sourceRoots=*/ JSet(),
/*dependentSourceSets=*/ JSet(),
/*samples=*/ JSet(),
/*includes=*/ JSet(),
/*includeNonPublic=*/ true,
/* changed because of exception in reportUndocumentedTransformer - there's 'when' which doesnt match because it contains only KotlinVisbility cases */
/*reportUndocumented=*/ false,
// Now all our packages are empty from dokka perspective
/*skipEmptyPackages=*/ false,
/*skipDeprecated=*/ true,
/*jdkVersion=*/ 8,
/*sourceLinks=*/ JSet(),
/*perPackageOptions=*/ JList(),
/*externalDocumentationLinks=*/ JSet(),
/*languageVersion=*/ null,
/*apiVersion=*/ null,
/*noStdlibLink=*/ true,
/*noJdkLink=*/ true,
/*suppressedFiles=*/ JSet(),
/*suppressedFiles=*/ Platform.jvm
).asInstanceOf[DokkaSourceSet] // Why I do need to cast here? Kotlin magic?

type DocContext = Context
val sourceSet = mkSourceSet.asInstanceOf[SourceSetWrapper]
55 changes: 0 additions & 55 deletions scala3doc/src/dotty/dokka/DottyDokkaConfig.scala

This file was deleted.

46 changes: 20 additions & 26 deletions scala3doc/src/dotty/dokka/DottyDokkaPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import dotty.dokka.model.api._
import org.jetbrains.dokka.CoreExtensions
import org.jetbrains.dokka.base.DokkaBase

import dotty.dokka.site.NavigationCreator
import dotty.dokka.site.SitePagesCreator
import dotty.dokka.site.StaticSiteContext
import dotty.dokka.site.RootIndexPageCreator
import dotty.dokka.site.SiteResourceManager
import dotty.dokka.site.StaticSiteLocationProviderFactory

Expand All @@ -49,7 +49,7 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:
// Just turn off another translator since multiple overrides does not work
val disableDescriptorTranslator = extend(
_.extensionPoint(CoreExtensions.INSTANCE.getSourceToDocumentableTranslator)
.fromRecipe(ctx => new ScalaModuleProvider(using ctx.docContext))
.fromRecipe { case ctx @ given DokkaContext => new ScalaModuleProvider }
.overrideExtension(dokkaBase.getDescriptorToDocumentableTranslator)
.name("disableDescriptorTranslator")
)
Expand All @@ -63,14 +63,14 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:

val ourSignatureProvider = extend(
_.extensionPoint(dokkaBase.getSignatureProvider)
.fromRecipe(ctx =>
new ScalaSignatureProvider(ctx.single(dokkaBase.getCommentsToContentConverter), ctx.getLogger)
).overrideExtension(dokkaBase.getKotlinSignatureProvider)
.fromRecipe{ case ctx @ given DokkaContext =>
new ScalaSignatureProvider(ctx.single(dokkaBase.getCommentsToContentConverter))
}.overrideExtension(dokkaBase.getKotlinSignatureProvider)
)

val scalaResourceInstaller = extend(
_.extensionPoint(dokkaBase.getHtmlPreprocessors)
.fromRecipe(ctx => new ScalaResourceInstaller(ctx.args))
.fromRecipe{ case ctx @ given DokkaContext => new ScalaResourceInstaller }
.after(dokkaBase.getCustomResourceInstaller)
)

Expand All @@ -83,17 +83,14 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:

val scalaDocumentableToPageTranslator = extend(
_.extensionPoint(CoreExtensions.INSTANCE.getDocumentableToPageTranslator)
.fromRecipe(ctx =>
.fromRecipe { case ctx @ given DokkaContext =>
new DocumentableToPageTranslator {
override def invoke(module: DModule): ModulePageNode = ScalaPageCreator(
ctx.single(dokkaBase.getCommentsToContentConverter),
ctx.single(dokkaBase.getSignatureProvider),
ctx.getConfiguration.asInstanceOf[DottyDokkaConfig].sourceLinks,
ctx.getLogger
ctx.single(dokkaBase.getSignatureProvider)
).pageForModule(module)
}
)
.overrideExtension(dokkaBase.getDocumentableToPageTranslator)
}.overrideExtension(dokkaBase.getDocumentableToPageTranslator)
)

val packageHierarchyTransformer = extend(
Expand All @@ -111,7 +108,7 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:

val ourRenderer = extend(
_.extensionPoint(CoreExtensions.INSTANCE.getRenderer)
.fromRecipe(ctx => ScalaHtmlRenderer(ctx, ctx.args))
.fromRecipe { case ctx @ given DokkaContext => new ScalaHtmlRenderer }
.overrideExtension(dokkaBase.getHtmlRenderer)
)

Expand All @@ -129,7 +126,7 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:

val customDocumentationProvider = extend(
_.extensionPoint(dokkaBase.getHtmlPreprocessors)
.fromRecipe(c => SitePagesCreator(c.siteContext))
.fromRecipe{ case c @ given DokkaContext => new SitePagesCreator }
.name("customDocumentationProvider")
.ordered(
before = Seq(
Expand All @@ -142,39 +139,36 @@ class DottyDokkaPlugin extends DokkaJavaPlugin:
)
)

val customIndexRootProvider = extend(
val customNavigation = extend(
_.extensionPoint(dokkaBase.getHtmlPreprocessors)
.fromRecipe(c => RootIndexPageCreator(c.siteContext))
.name("customIndexRootProvider")
.fromRecipe{ case c @ given DokkaContext => new NavigationCreator }
.name("customNavigation")
.ordered(
before = Seq(
dokkaBase.getScriptsInstaller,
dokkaBase.getStylesInstaller,
),
after = Seq(dokkaBase.getNavigationPageInstaller)
after = Seq(customDocumentationProvider.getValue)
)
.overrideExtension(dokkaBase.getNavigationPageInstaller)
)

val customDocumentationResources = extend(
_.extensionPoint(dokkaBase.getHtmlPreprocessors)
.fromRecipe(c => SiteResourceManager(c.siteContext))
.fromRecipe{ case c @ given DokkaContext => new SiteResourceManager }
.name("customDocumentationResources")
.after(
scalaEmbeddedResourceAppender.getValue
scalaEmbeddedResourceAppender.getValue,
customDocumentationProvider.getValue
)
)

val locationProvider = extend(
_.extensionPoint(dokkaBase.getLocationProviderFactory)
.fromRecipe(StaticSiteLocationProviderFactory(_))
.fromRecipe { case c @ given DokkaContext => new StaticSiteLocationProviderFactory }
.overrideExtension(dokkaBase.getLocationProvider)
)

extension (ctx: DokkaContext):
def siteContext: Option[StaticSiteContext] = ctx.getConfiguration.asInstanceOf[DottyDokkaConfig].staticSiteContext
def args: Scala3doc.Args = ctx.getConfiguration.asInstanceOf[DottyDokkaConfig].args
def docContext = ctx.getConfiguration.asInstanceOf[DottyDokkaConfig].docContext

// TODO (https://github.com/lampepfl/scala3doc/issues/232): remove once problem is fixed in Dokka
extension [T] (builder: ExtensionBuilder[T]):
def ordered(before: Seq[Extension[_, _, _]], after: Seq[Extension[_, _, _]]): ExtensionBuilder[T] =
Expand Down
5 changes: 2 additions & 3 deletions scala3doc/src/dotty/dokka/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import java.nio.file.Files

import dotty.tools.dotc.config.Settings._
import dotty.tools.dotc.config.CommonScalaSettings
import dotty.tools.dotc.report
import dotty.tools.dotc.core.Contexts._

/** Main class for the doctool.
Expand All @@ -25,13 +24,13 @@ import dotty.tools.dotc.core.Contexts._
*
* - [](package.DottyDokkaPlugin) is our class that Dokka calls back and which
* actually generates the documentation.
* - [](package.DottyDokkaConfig) is our config for Dokka.
* - [](package.DocContext) is our config for Dokka
*/
object Main:
def main(args: Array[String]): Unit =
try
// We should create our own context here...
val reporter = Scala3doc.run(args)(using (new ContextBase).initialCtx)
val reporter = Scala3doc.run(args, (new ContextBase).initialCtx)
// Sometimes jvm is hanging, so we want to be sure that we force shout down the jvm
sys.exit(if reporter.hasErrors then 1 else 0)
catch
Expand Down
Loading