From b4cad723867dfbb046fd3929cc663f70d7f140ba Mon Sep 17 00:00:00 2001 From: Krzysztof Romanowski Date: Wed, 15 Jul 2020 23:06:13 +0200 Subject: [PATCH 001/181] Initial commit with basic setup --- .gitignore | 34 +++++++++++++ .scalafmt.conf | 1 + README.md | 9 ++++ build.sbt | 19 +++++++ project/build.properties | 1 + project/metals.sbt | 4 ++ project/plugins.sbt | 1 + ...rg.jetbrains.dokka.plugability.DokkaPlugin | 1 + .../scala/dotty/dokka/DottyDokkaConfig.scala | 49 +++++++++++++++++++ .../scala/dotty/dokka/DottyDokkaPlugin.scala | 15 ++++++ src/main/scala/dotty/dokka/Main.scala | 13 +++++ src/test/scala/Test1.scala | 9 ++++ 12 files changed, 156 insertions(+) create mode 100644 .gitignore create mode 100644 .scalafmt.conf create mode 100644 README.md create mode 100644 build.sbt create mode 100644 project/build.properties create mode 100644 project/metals.sbt create mode 100644 project/plugins.sbt create mode 100644 src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin create mode 100644 src/main/scala/dotty/dokka/DottyDokkaConfig.scala create mode 100644 src/main/scala/dotty/dokka/DottyDokkaPlugin.scala create mode 100644 src/main/scala/dotty/dokka/Main.scala create mode 100644 src/test/scala/Test1.scala diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..151fd0f10587 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ + +*.class +*.log + +# sbt specific +.cache +.history +.lib/ +dist/* +target/ +lib_managed/ +src_managed/ +project/boot/ +project/plugins/project/ + +# Scala-IDE specific +.scala_dependencies +.worksheet + +# Intellij +.idea + +#integration tests dir +/test-ws + +# to test deploy +private-* +repo + +.metals +.bloop + +# custom things +output \ No newline at end of file diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 000000000000..9df0d88b69ce --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1 @@ +version = "2.6.3" diff --git a/README.md b/README.md new file mode 100644 index 000000000000..db5e3348c87b --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +## sbt project compiled with Dotty + +### Usage + +This is a normal sbt project, you can compile code with `sbt compile` and run it +with `sbt run`, `sbt console` will start a Dotty REPL. + +For more information on the sbt-dotty plugin, see the +[dotty-example-project](https://github.com/lampepfl/dotty-example-project/blob/master/README.md). diff --git a/build.sbt b/build.sbt new file mode 100644 index 000000000000..92d75c685adb --- /dev/null +++ b/build.sbt @@ -0,0 +1,19 @@ +val dottyVersion = "0.25.0-RC2" + +libraryDependencies += "org.jetbrains.dokka" % "dokka-base" % "1.4.0-M3-dev-81" +libraryDependencies += "org.jetbrains.dokka" % "dokka-core" % "1.4.0-M3-dev-81" + +resolvers += Resolver.jcenterRepo + +resolvers += Resolver.bintrayRepo("kotlin", "kotlin-dev") + +lazy val root = project + .in(file(".")) + .settings( + name := "dotty-dokka", + version := "0.1.0", + + scalaVersion := dottyVersion, + + libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" + ) diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 000000000000..0837f7a132de --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.3.13 diff --git a/project/metals.sbt b/project/metals.sbt new file mode 100644 index 000000000000..343a26a63d73 --- /dev/null +++ b/project/metals.sbt @@ -0,0 +1,4 @@ +// DO NOT EDIT! This file is auto-generated. +// This file enables sbt-bloop to create bloop config files. + +addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.3") diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 000000000000..7cffad4e4d9a --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.1") \ No newline at end of file diff --git a/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin b/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin new file mode 100644 index 000000000000..1c1de05b36b3 --- /dev/null +++ b/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin @@ -0,0 +1 @@ +dotty.dokka.DottyDokkaPlugin \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala new file mode 100644 index 000000000000..9b72dd3e414b --- /dev/null +++ b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala @@ -0,0 +1,49 @@ +package dotty.dokka + +import org.jetbrains.dokka._ +import org.jetbrains.dokka.DokkaSourceSetImpl +import java.io.File +import java.util.{ List => JList, Map => JMap} +import collection.JavaConverters._ + +case class DottyDokkaConfig(paths: String*) extends DokkaConfiguration: + override def getOutputDir: String = new File("output").getAbsolutePath + override def getCacheRoot: String = null + override def getOfflineMode: Boolean = false + override def getFailOnWarning: Boolean = false + override def getSourceSets: JList[DokkaConfiguration.DokkaSourceSet] = List(mkSourceSet).asJava + override def getModules: JList[DokkaConfiguration.DokkaModuleDescription] = List(FakeDottyDokkaModule).asJava + override def getPluginsClasspath: JList[File] = Nil.asJava + override def getPluginsConfiguration: JMap[String, String] = Map("dotty.dokka.DottyDokkaPlugin" -> "dottydoc").asJava + + def mkSourceSet: DokkaConfiguration.DokkaSourceSet = new DokkaSourceSetImpl( + "main", + "Main", + new DokkaSourceSetID("main", "main"), + Nil.asJava, + Nil.asJava, + Set().asJava, + Nil.asJava, + Nil.asJava, + true, + true, + true, + true, + true, + 8, + Nil.asJava, + Nil.asJava, + Nil.asJava, + null, + null, + true, + true, + Nil.asJava, + Platform.jvm + ).asInstanceOf[DokkaConfiguration.DokkaSourceSet] // Why I do need to cast here? Kotlin magic? + + +object FakeDottyDokkaModule extends DokkaConfiguration.DokkaModuleDescription: + override def getDocFile(): String = "docs.doc" + override def getName() = "main" + override def getPath() = "." \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala new file mode 100644 index 000000000000..4212a5645309 --- /dev/null +++ b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala @@ -0,0 +1,15 @@ +package dotty.dokka + +import org.jetbrains.dokka.plugability._ +import org.jetbrains.dokka.transformers.sources._ + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.plugability.DokkaContext + +class ProvideModule extends SourceToDocumentableTranslator: + def invoke(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext): DModule = + ??? + +class DottyDokkaPlugin extends DokkaPlugin: + extending \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/Main.scala b/src/main/scala/dotty/dokka/Main.scala new file mode 100644 index 000000000000..67fc4494f611 --- /dev/null +++ b/src/main/scala/dotty/dokka/Main.scala @@ -0,0 +1,13 @@ +package dotty.dokka + +import org.jetbrains.dokka._ +import org.jetbrains.dokka.utilities._ +import org.jetbrains.dokka.plugability._ +import java.util.ServiceLoader +import collection.JavaConverters._ + +object Main: + def main(args: Array[String]): Unit = + val config = DottyDokkaConfig("Ala.scala") + new DokkaGenerator(config, DokkaConsoleLogger.INSTANCE).generate() + println("Done") diff --git a/src/test/scala/Test1.scala b/src/test/scala/Test1.scala new file mode 100644 index 000000000000..b4232a71f62f --- /dev/null +++ b/src/test/scala/Test1.scala @@ -0,0 +1,9 @@ + +import org.junit.Test +import org.junit.Assert._ + +class Test1 { + @Test def t1(): Unit = { + assertEquals("I was compiled by dotty :)", "ala") + } +} \ No newline at end of file From 7f34b54ddaf96668f01cac33bc0265fed10e222d Mon Sep 17 00:00:00 2001 From: Krzysztof Romanowski Date: Sat, 18 Jul 2020 22:08:16 +0200 Subject: [PATCH 002/181] Fake docs works! --- build.sbt | 17 ++ dokkaJavaApi/.gitignore | 4 + dokkaJavaApi/build.gradle.kts | 54 ++++++ dokkaJavaApi/gradle.properties | 8 + dokkaJavaApi/gradlew | 183 ++++++++++++++++++ dokkaJavaApi/gradlew.bat | 100 ++++++++++ dokkaJavaApi/settings.gradle.kts | 19 ++ .../main/kotlin/dokka.java.api.JavaPlugin.kt | 43 ++++ libs/dokkaJavaApi-0.1.0.jar | Bin 0 -> 13083 bytes .../scala/dotty/dokka/DottyDokkaConfig.scala | 4 +- .../scala/dotty/dokka/DottyDokkaPlugin.scala | 46 ++++- src/main/scala/dotty/dokka/DottyReader.scala | 58 ++++++ 12 files changed, 528 insertions(+), 8 deletions(-) create mode 100644 dokkaJavaApi/.gitignore create mode 100644 dokkaJavaApi/build.gradle.kts create mode 100644 dokkaJavaApi/gradle.properties create mode 100755 dokkaJavaApi/gradlew create mode 100644 dokkaJavaApi/gradlew.bat create mode 100644 dokkaJavaApi/settings.gradle.kts create mode 100644 dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt create mode 100644 libs/dokkaJavaApi-0.1.0.jar create mode 100644 src/main/scala/dotty/dokka/DottyReader.scala diff --git a/build.sbt b/build.sbt index 92d75c685adb..7255352e3e3d 100644 --- a/build.sbt +++ b/build.sbt @@ -17,3 +17,20 @@ lazy val root = project libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" ) + +val dokkaJavaApiJar = file("libs") / "dokkaJavaApi-0.1.0.jar" + +val buildDokkaApi = taskKey[Unit]("Compile dokka wrapper and put jar in lib") +buildDokkaApi := { + val gradleRootDir = file("dokkaJavaApi") + sys.process.Process(Seq("./gradlew", "clean", "build"), gradleRootDir).! + + IO.delete(dokkaJavaApiJar) + IO.move(gradleRootDir / "build" / "libs" / "dokkaJavaApi-0.1.0.jar", dokkaJavaApiJar) + streams.value.log.success(s"Dokka api copied to $dokkaJavaApiJar") +} + +unmanagedJars in Compile += dokkaJavaApiJar + +javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=krzysiek-MS-7971:5005,suspend=y" +fork.in(run) := true \ No newline at end of file diff --git a/dokkaJavaApi/.gitignore b/dokkaJavaApi/.gitignore new file mode 100644 index 000000000000..679542abf224 --- /dev/null +++ b/dokkaJavaApi/.gitignore @@ -0,0 +1,4 @@ +.gradle/ +build/ +gradle/ + diff --git a/dokkaJavaApi/build.gradle.kts b/dokkaJavaApi/build.gradle.kts new file mode 100644 index 000000000000..95aeeef6306a --- /dev/null +++ b/dokkaJavaApi/build.gradle.kts @@ -0,0 +1,54 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") apply false + id("java") +} + + +group = "org.jetbrains.dokka" +version = "0.1.0" + +val language_version: String by project + +tasks.withType(KotlinCompile::class).all { + kotlinOptions { + freeCompilerArgs += "-Xjsr305=strict -Xskip-metadata-version-check -Xopt-in=kotlin.RequiresOptIn." + languageVersion = language_version + apiVersion = language_version + jvmTarget = "1.8" + } +} + +repositories { + jcenter() + mavenCentral() + maven(url = "https://dl.bintray.com/kotlin/kotlin-eap") + maven(url = "https://dl.bintray.com/kotlin/kotlin-dev") +} + +dependencies { + implementation("org.jetbrains.dokka:dokka-core:1.4-mc-1") + implementation("org.jetbrains.dokka:dokka-base:1.4-mc-1") +} + +apply { + plugin("org.jetbrains.kotlin.jvm") + plugin("java") +} + +// Gradle metadata +java { + @Suppress("UnstableApiUsage") + withSourcesJar() + targetCompatibility = JavaVersion.VERSION_1_8 +} + + +// Workaround for https://github.com/bintray/gradle-bintray-plugin/issues/267 +// Manually disable bintray tasks added to the root project +tasks.whenTaskAdded { + if ("bintray" in name) { + enabled = false + } +} \ No newline at end of file diff --git a/dokkaJavaApi/gradle.properties b/dokkaJavaApi/gradle.properties new file mode 100644 index 000000000000..5bdc58a7d955 --- /dev/null +++ b/dokkaJavaApi/gradle.properties @@ -0,0 +1,8 @@ +kotlin.code.style=official + +kotlin_version=1.4-M3 +kotlin_plugin_version=1.4-M3-release-207 +coroutines_version=1.3.7-1.4-M3 + +idea_version=193.6494.35 +language_version=1.4 \ No newline at end of file diff --git a/dokkaJavaApi/gradlew b/dokkaJavaApi/gradlew new file mode 100755 index 000000000000..2fe81a7d95e4 --- /dev/null +++ b/dokkaJavaApi/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/dokkaJavaApi/gradlew.bat b/dokkaJavaApi/gradlew.bat new file mode 100644 index 000000000000..9618d8d9607c --- /dev/null +++ b/dokkaJavaApi/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/dokkaJavaApi/settings.gradle.kts b/dokkaJavaApi/settings.gradle.kts new file mode 100644 index 000000000000..969eb5f58ee9 --- /dev/null +++ b/dokkaJavaApi/settings.gradle.kts @@ -0,0 +1,19 @@ +rootProject.name = "dokkaJavaApi" + +pluginManagement { + val kotlin_version: String by settings + plugins { + id("org.jetbrains.kotlin.jvm") version kotlin_version + id("com.github.johnrengelman.shadow") version "5.2.0" + id("com.jfrog.bintray") version "1.8.5" + id("com.gradle.plugin-publish") version "0.12.0" + } + + repositories { + maven("https://dl.bintray.com/kotlin/kotlin-eap/") + maven("https://dl.bintray.com/kotlin/kotlin-dev/") + mavenCentral() + jcenter() + gradlePluginPortal() + } +} \ No newline at end of file diff --git a/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt b/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt new file mode 100644 index 000000000000..0ed488f4cfb1 --- /dev/null +++ b/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt @@ -0,0 +1,43 @@ +package dokka.java.api + +import org.jetbrains.dokka.CoreExtensions +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.DokkaPlugin +import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer +import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator + +data class SourceSetWrapper(val sourceSet: DokkaConfiguration.DokkaSourceSet) { + fun toSet(): Set = setOf(sourceSet) + fun asMap(value: T): Map = mapOf(sourceSet to value) +} + +abstract class JavaDokkaPlugin : DokkaPlugin() { + private val dokkaBase by lazy { plugin() } + + val provideDottyDocs by extending { + CoreExtensions.sourceToDocumentableTranslator providing { ctx -> + object : SourceToDocumentableTranslator { + override fun invoke(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext): DModule = + createSourceToDocumentableTranslator(context, SourceSetWrapper(sourceSet)) + } + } override dokkaBase.descriptorToDocumentableTranslator + } + + val inspectTheThing by extending { + CoreExtensions.preMergeDocumentableTransformer providing { ctx -> + object : PreMergeDocumentableTransformer { + override fun invoke(modules: List): List { + println(modules) + println("@@@@@@@@@") + println(modules.map { it.packages }) + return modules + } + } + } + } + + abstract fun createSourceToDocumentableTranslator(cxt: DokkaContext, sourceSet: SourceSetWrapper): DModule +} diff --git a/libs/dokkaJavaApi-0.1.0.jar b/libs/dokkaJavaApi-0.1.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..ffa9be8b637aeb485dcca7be8c8baa61afba19b5 GIT binary patch literal 13083 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 literal 0 HcmV?d00001 diff --git a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala index 9b72dd3e414b..b7b38bef73a4 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala @@ -12,7 +12,7 @@ case class DottyDokkaConfig(paths: String*) extends DokkaConfiguration: override def getOfflineMode: Boolean = false override def getFailOnWarning: Boolean = false override def getSourceSets: JList[DokkaConfiguration.DokkaSourceSet] = List(mkSourceSet).asJava - override def getModules: JList[DokkaConfiguration.DokkaModuleDescription] = List(FakeDottyDokkaModule).asJava + override def getModules: JList[DokkaConfiguration.DokkaModuleDescription] = List().asJava override def getPluginsClasspath: JList[File] = Nil.asJava override def getPluginsConfiguration: JMap[String, String] = Map("dotty.dokka.DottyDokkaPlugin" -> "dottydoc").asJava @@ -24,7 +24,7 @@ case class DottyDokkaConfig(paths: String*) extends DokkaConfiguration: Nil.asJava, Set().asJava, Nil.asJava, - Nil.asJava, + List("output/BaseDocs.md").asJava, true, true, true, diff --git a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala index 4212a5645309..c8ef9332c019 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala @@ -4,12 +4,46 @@ import org.jetbrains.dokka.plugability._ import org.jetbrains.dokka.transformers.sources._ import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.model._ +import org.jetbrains.dokka.links._ +import org.jetbrains.dokka.model.doc._ +import org.jetbrains.dokka.base.parsers._ import org.jetbrains.dokka.plugability.DokkaContext +import dokka.java.api._ +import collection.JavaConverters._ +import org.jetbrains.dokka.model.properties.PropertyContainer -class ProvideModule extends SourceToDocumentableTranslator: - def invoke(sourceSet: DokkaConfiguration.DokkaSourceSet, context: DokkaContext): DModule = - ??? -class DottyDokkaPlugin extends DokkaPlugin: - extending \ No newline at end of file +class DottyDokkaPlugin extends JavaDokkaPlugin: + override def createSourceToDocumentableTranslator(cxt: DokkaContext, sourceSet: SourceSetWrapper): DModule = cxt.getConfiguration match { + case dottyConfig: DottyDokkaConfig => + val parser = new MarkdownParser(null, null, cxt.getLogger) + + val doc = parser.parse("## THIS IS MY DOC!") + + val pck = new DPackage( + new DRI("foo", null, null, PointingToDeclaration.INSTANCE, null), + Nil.asJava, + Nil.asJava, + List(DottyReader.parseClasslike("foo.bar.Foo", sourceSet, parser)).asJava, + Nil.asJava, + sourceSet.asMap(doc), + null, + sourceSet.toSet, + PropertyContainer.Companion.empty() + ) + + val res = new DModule( + sourceSet.getSourceSet.getSourceSetID.getModuleName, + List(pck).asJava, + Map().asJava, + null, + sourceSet.toSet, + PropertyContainer.Companion.empty() + ) + + println(res) + res + case _ => + ??? + } \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/DottyReader.scala b/src/main/scala/dotty/dokka/DottyReader.scala new file mode 100644 index 000000000000..9de7cfbffcb0 --- /dev/null +++ b/src/main/scala/dotty/dokka/DottyReader.scala @@ -0,0 +1,58 @@ +package dotty.dokka + + +import org.jetbrains.dokka.plugability._ +import org.jetbrains.dokka.transformers.sources._ + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.model._ +import org.jetbrains.dokka.links._ +import org.jetbrains.dokka.model.doc._ +import org.jetbrains.dokka.base.parsers._ +import org.jetbrains.dokka.plugability.DokkaContext +import dokka.java.api._ +import collection.JavaConverters._ +import org.jetbrains.dokka.model.properties.PropertyContainer +import java.util.{List => JList} + +object DottyReader: + def parseClasslike(fqn: String, sourceSet: SourceSetWrapper, parser: Parser): DClass = + val segments = fqn.split('.') + val name = segments.last + val dri = new DRI(segments.drop(1).mkString("."), name, null, PointingToDeclaration.INSTANCE, null) + + val constr: JList[DFunction] = Nil.asJava + val funs: JList[DFunction] = Nil.asJava + val props: JList[DProperty] = Nil.asJava + val nested: JList[DClasslike] = Nil.asJava + + + val source = new DocumentableSource(): + override def getPath: String = segments.mkString("src/","/", ".scala") + + val vis = KotlinVisibility.Public.INSTANCE + val doc = sourceSet.asMap(parser.parse("## Documentation for Foo")) + val companion : DObject = null + + val gens: JList[DTypeParameter] = Nil.asJava + val supers: JList[DriWithKind] = Nil.asJava + val mod = sourceSet.asMap(JavaModifier.Abstract.INSTANCE) + + new DClass( + dri, + "Foo", + Nil.asJava, + Nil.asJava, + Nil.asJava, + Nil.asJava, + sourceSet.asMap(source), + sourceSet.asMap(KotlinVisibility.Public.INSTANCE), + null, + Nil.asJava, + Map().asJava, + sourceSet.asMap(parser.parse("## Documentation for Foo")), + null, + mod, + sourceSet.toSet, + PropertyContainer.Companion.empty() + ) From b9a385472c0a47bef2760c1a4a531b35c8085c40 Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Mon, 20 Jul 2020 12:40:03 +0200 Subject: [PATCH 003/181] Play with dokka --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 151fd0f10587..4cdc65ff1d1b 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,7 @@ repo .bloop # custom things -output \ No newline at end of file +output + +.vscode + From ada35b99fedb16e647bcec426b3f258c1eb7e195 Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Mon, 20 Jul 2020 12:42:00 +0200 Subject: [PATCH 004/181] pg2 --- README.md | 10 +--- build.sbt | 9 +++- .../scala/dotty/dokka/DottyDokkaConfig.scala | 3 +- .../scala/dotty/dokka/DottyDokkaPlugin.scala | 16 ++----- src/main/scala/dotty/dokka/DottyReader.scala | 31 +++++++++---- src/main/scala/dotty/dokka/Main.scala | 46 ++++++++++++++++++- src/main/scala/dotty/dokka/repr.scala | 11 +++++ 7 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 src/main/scala/dotty/dokka/repr.scala diff --git a/README.md b/README.md index db5e3348c87b..ca4e4a2f7228 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,3 @@ -## sbt project compiled with Dotty +## trying to create documentation for dotty with dokka -### Usage - -This is a normal sbt project, you can compile code with `sbt compile` and run it -with `sbt run`, `sbt console` will start a Dotty REPL. - -For more information on the sbt-dotty plugin, see the -[dotty-example-project](https://github.com/lampepfl/dotty-example-project/blob/master/README.md). +This is mostly playground so I may not work outside my machine. \ No newline at end of file diff --git a/build.sbt b/build.sbt index 7255352e3e3d..a0028d221fd6 100644 --- a/build.sbt +++ b/build.sbt @@ -2,6 +2,9 @@ val dottyVersion = "0.25.0-RC2" libraryDependencies += "org.jetbrains.dokka" % "dokka-base" % "1.4.0-M3-dev-81" libraryDependencies += "org.jetbrains.dokka" % "dokka-core" % "1.4.0-M3-dev-81" +libraryDependencies += "ch.epfl.lamp" % "dotty-tastydoc_0.25" % dottyVersion +libraryDependencies += "ch.epfl.lamp" % "dotty-compiler_0.25" % dottyVersion +libraryDependencies += "ch.epfl.lamp" % "dotty-library_0.25" % dottyVersion resolvers += Resolver.jcenterRepo @@ -32,5 +35,7 @@ buildDokkaApi := { unmanagedJars in Compile += dokkaJavaApiJar -javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=krzysiek-MS-7971:5005,suspend=y" -fork.in(run) := true \ No newline at end of file +// javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=krzysiek-MS-7971:5005,suspend=y" +fork.in(run) := true + +scalacOptions in Compile += "-language:implicitConversion" \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala index b7b38bef73a4..6fc935b6441a 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala @@ -5,8 +5,9 @@ import org.jetbrains.dokka.DokkaSourceSetImpl import java.io.File import java.util.{ List => JList, Map => JMap} import collection.JavaConverters._ +import dotty.tastydoc.representations._ -case class DottyDokkaConfig(paths: String*) extends DokkaConfiguration: +case class DottyDokkaConfig(compilationUnit: DDUnit) extends DokkaConfiguration: override def getOutputDir: String = new File("output").getAbsolutePath override def getCacheRoot: String = null override def getOfflineMode: Boolean = false diff --git a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala index c8ef9332c019..6c92c9b596d8 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala @@ -21,21 +21,13 @@ class DottyDokkaPlugin extends JavaDokkaPlugin: val doc = parser.parse("## THIS IS MY DOC!") - val pck = new DPackage( - new DRI("foo", null, null, PointingToDeclaration.INSTANCE, null), - Nil.asJava, - Nil.asJava, - List(DottyReader.parseClasslike("foo.bar.Foo", sourceSet, parser)).asJava, - Nil.asJava, - sourceSet.asMap(doc), - null, - sourceSet.toSet, - PropertyContainer.Companion.empty() - ) + val reader = DottyReader(sourceSet, parser, dottyConfig) + + val packages = dottyConfig.compilationUnit.packages.map(reader.parsePackage).toList val res = new DModule( sourceSet.getSourceSet.getSourceSetID.getModuleName, - List(pck).asJava, + packages.asJava, Map().asJava, null, sourceSet.toSet, diff --git a/src/main/scala/dotty/dokka/DottyReader.scala b/src/main/scala/dotty/dokka/DottyReader.scala index 9de7cfbffcb0..3f6829e82577 100644 --- a/src/main/scala/dotty/dokka/DottyReader.scala +++ b/src/main/scala/dotty/dokka/DottyReader.scala @@ -14,12 +14,27 @@ import dokka.java.api._ import collection.JavaConverters._ import org.jetbrains.dokka.model.properties.PropertyContainer import java.util.{List => JList} +import dotty.tastydoc.representations._ -object DottyReader: - def parseClasslike(fqn: String, sourceSet: SourceSetWrapper, parser: Parser): DClass = - val segments = fqn.split('.') - val name = segments.last - val dri = new DRI(segments.drop(1).mkString("."), name, null, PointingToDeclaration.INSTANCE, null) +case class DottyReader(sourceSet: SourceSetWrapper, parser: Parser, config: DottyDokkaConfig): + def parsePackage(pck: DDPackage): DPackage = + val entries = config.compilationUnit.classesByPackage.get(pck.name).getOrElse(Nil).map(parseClasslike(pck.name)) + + new DPackage( + new DRI(pck.name, null, null, PointingToDeclaration.INSTANCE, null), + Nil.asJava, + Nil.asJava, + entries.toList.asJava, + Nil.asJava, + sourceSet.asMap(parser.parse(pck.comment)), + null, + sourceSet.toSet, + PropertyContainer.Companion.empty() + ) + + + def parseClasslike(packatgeName: String)(clazz: DDClass): DClass = + val dri = new DRI(packatgeName, clazz.name, null, PointingToDeclaration.INSTANCE, null) val constr: JList[DFunction] = Nil.asJava val funs: JList[DFunction] = Nil.asJava @@ -28,7 +43,7 @@ object DottyReader: val source = new DocumentableSource(): - override def getPath: String = segments.mkString("src/","/", ".scala") + override def getPath: String = packatgeName.mkString("src/","/", s"${clazz.name}.scala") val vis = KotlinVisibility.Public.INSTANCE val doc = sourceSet.asMap(parser.parse("## Documentation for Foo")) @@ -40,7 +55,7 @@ object DottyReader: new DClass( dri, - "Foo", + clazz.name, Nil.asJava, Nil.asJava, Nil.asJava, @@ -50,7 +65,7 @@ object DottyReader: null, Nil.asJava, Map().asJava, - sourceSet.asMap(parser.parse("## Documentation for Foo")), + sourceSet.asMap(parser.parse(clazz.comment)), null, mod, sourceSet.toSet, diff --git a/src/main/scala/dotty/dokka/Main.scala b/src/main/scala/dotty/dokka/Main.scala index 67fc4494f611..da79751acd75 100644 --- a/src/main/scala/dotty/dokka/Main.scala +++ b/src/main/scala/dotty/dokka/Main.scala @@ -4,10 +4,54 @@ import org.jetbrains.dokka._ import org.jetbrains.dokka.utilities._ import org.jetbrains.dokka.plugability._ import java.util.ServiceLoader +import java.io.File +import java.util.jar._ import collection.JavaConverters._ +import scala.tasty.Reflection +import scala.tasty.inspector.TastyInspector +import dotty.tastydoc.representations +import dotty.tastydoc.representations._ + +class DokkaTastyInspector extends TastyInspector: + private val packages = Set.newBuilder[DDPackage] + private val classes = Set.newBuilder[DDClass] + + protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = + import reflect.{_, given _} + + object Traverser extends TreeTraverser: + override def traverseTree(tree: Tree)(using ctx: Context): Unit = + tree match { + case pc: PackageClause => + packages += DDPackage(pc.pid.show, pc.symbol.comment.fold("")(_.raw)) + case clazz: ClassDef => + classes += DDClass(clazz.name, "dotty.dokka", clazz.symbol.comment.fold("")(_.raw)) + case _ => + } + super.traverseTree(tree) + + Traverser.traverseTree(root)(using reflect.rootContext) + + def result() = + val res = DDUnit(classes.result.toList, packages.result.toList) + println(res) + res + + object Main: def main(args: Array[String]): Unit = - val config = DottyDokkaConfig("Ala.scala") + val cp = args.headOption.getOrElse("/home/krzysiek/workspace/dotty-dokka/target/scala-0.25/classes") + def listTastyFiles(f: File): Seq[File] = + val (files, dirs) = f.listFiles().partition(_.isFile) + files.filter(_.getName.endsWith(".tasty")) ++ dirs.flatMap(listTastyFiles) + + val tastyFiles = cp.split(File.pathSeparatorChar).toList.flatMap(p => listTastyFiles(new File(p))).map(_.toString) + + val inspector = new DokkaTastyInspector() + inspector.inspect(System.getProperty("java.class.path"), tastyFiles) + + + val config = DottyDokkaConfig(inspector.result()) new DokkaGenerator(config, DokkaConsoleLogger.INSTANCE).generate() println("Done") diff --git a/src/main/scala/dotty/dokka/repr.scala b/src/main/scala/dotty/dokka/repr.scala new file mode 100644 index 000000000000..87fbc86b41bd --- /dev/null +++ b/src/main/scala/dotty/dokka/repr.scala @@ -0,0 +1,11 @@ +package dotty.dokka + +/** Representation of package */ +case class DDPackage(name: String, comment: String) + +/** Representation of class */ +case class DDClass(name: String, pck: String, comment: String) + +/** Represenation of compilation unit */ +case class DDUnit(classes: Seq[DDClass], packages: Seq[DDPackage]): + lazy val classesByPackage = classes.groupBy(_.pck) \ No newline at end of file From cdcbec19890467ac2cc27dfe58ff906dcdd124ef Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Mon, 20 Jul 2020 14:56:25 +0200 Subject: [PATCH 005/181] Add scope of PoC --- README.md | 20 ++++++++++++++++++-- src/main/scala/dotty/dokka/Main.scala | 1 - 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca4e4a2f7228..9809985838dc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,19 @@ -## trying to create documentation for dotty with dokka +# Dotty dokka + +This project is PoC to test if [dokka](https://github.com/Kotlin/dokka) can be used as forntend to generate documentation for Scala 3 based projects using TASTY as a source of information about types etc. + +## Scope of work + +In order to complete this PoC we should have a version that can: + +1) parse scaladoc format and render it properly (for supported entries, see below) +2) render documentation for packages, classes and methods +3) render multiple parameters list correctly +4) render correctly types however we allow to use text for types that cannot be rednered using Kotlin/Java +5) Properly link to classes and methods from signatures and from within scaladocs + +Nice to have: + +1) Render type members +2) ... -This is mostly playground so I may not work outside my machine. \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/Main.scala b/src/main/scala/dotty/dokka/Main.scala index da79751acd75..4f95257ff3f9 100644 --- a/src/main/scala/dotty/dokka/Main.scala +++ b/src/main/scala/dotty/dokka/Main.scala @@ -51,7 +51,6 @@ object Main: val inspector = new DokkaTastyInspector() inspector.inspect(System.getProperty("java.class.path"), tastyFiles) - val config = DottyDokkaConfig(inspector.result()) new DokkaGenerator(config, DokkaConsoleLogger.INSTANCE).generate() println("Done") From 6043b1acaa2244a2a8a3427e720459269980f1ac Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Mon, 20 Jul 2020 17:01:31 +0200 Subject: [PATCH 006/181] wip-split --- src/main/scala/dotty/dokka/DottyReader.scala | 39 +++++++++++++++++++ src/main/scala/dotty/dokka/Main.scala | 25 ------------ .../scala/dotty/dokka/ScalaDocSupport.scala | 9 +++++ src/main/scala/dotty/dokka/repr.scala | 4 +- 4 files changed, 51 insertions(+), 26 deletions(-) create mode 100644 src/main/scala/dotty/dokka/ScalaDocSupport.scala diff --git a/src/main/scala/dotty/dokka/DottyReader.scala b/src/main/scala/dotty/dokka/DottyReader.scala index 3f6829e82577..e73611c5b434 100644 --- a/src/main/scala/dotty/dokka/DottyReader.scala +++ b/src/main/scala/dotty/dokka/DottyReader.scala @@ -16,6 +16,45 @@ import org.jetbrains.dokka.model.properties.PropertyContainer import java.util.{List => JList} import dotty.tastydoc.representations._ + +import scala.tasty.Reflection +import scala.tasty.inspector.TastyInspector +import dotty.tastydoc.representations +import dotty.tastydoc.representations._ + + +case class DottyDokkaParser(reflect: Reflection, sourceSet: SourceSetWrapper, parser: Parser, config: DottyDokkaConfig) extends ScaladocSupport: + def parseTree(reflect: reflect.Tree): Seq[Documentable] = Nil + + +class DokkaTastyInspector extends TastyInspector: + private val packages = Set.newBuilder[DDPackage] + private val classes = Set.newBuilder[DDClass] + + private val topLevels = Seq.newBuilder[Documentable] + + protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = + import reflect.{_, given _} + + object Traverser extends TreeTraverser: + override def traverseTree(tree: Tree)(using ctx: Context): Unit = + tree match + case clazz: ClassDef => + classes += DDClass(clazz.name, "dotty.dokka", clazz.symbol.comment.fold("")(_.raw)) + case _ => + } + super.traverseTree(tree) + + Traverser.traverseTree(root)(using reflect.rootContext) + + def result() = + val res = DDUnit(classes.result.toList, packages.result.toList) + println(res) + res + + def mkClass + + case class DottyReader(sourceSet: SourceSetWrapper, parser: Parser, config: DottyDokkaConfig): def parsePackage(pck: DDPackage): DPackage = val entries = config.compilationUnit.classesByPackage.get(pck.name).getOrElse(Nil).map(parseClasslike(pck.name)) diff --git a/src/main/scala/dotty/dokka/Main.scala b/src/main/scala/dotty/dokka/Main.scala index 4f95257ff3f9..3684176a6fc9 100644 --- a/src/main/scala/dotty/dokka/Main.scala +++ b/src/main/scala/dotty/dokka/Main.scala @@ -13,31 +13,6 @@ import scala.tasty.inspector.TastyInspector import dotty.tastydoc.representations import dotty.tastydoc.representations._ -class DokkaTastyInspector extends TastyInspector: - private val packages = Set.newBuilder[DDPackage] - private val classes = Set.newBuilder[DDClass] - - protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = - import reflect.{_, given _} - - object Traverser extends TreeTraverser: - override def traverseTree(tree: Tree)(using ctx: Context): Unit = - tree match { - case pc: PackageClause => - packages += DDPackage(pc.pid.show, pc.symbol.comment.fold("")(_.raw)) - case clazz: ClassDef => - classes += DDClass(clazz.name, "dotty.dokka", clazz.symbol.comment.fold("")(_.raw)) - case _ => - } - super.traverseTree(tree) - - Traverser.traverseTree(root)(using reflect.rootContext) - - def result() = - val res = DDUnit(classes.result.toList, packages.result.toList) - println(res) - res - object Main: def main(args: Array[String]): Unit = diff --git a/src/main/scala/dotty/dokka/ScalaDocSupport.scala b/src/main/scala/dotty/dokka/ScalaDocSupport.scala new file mode 100644 index 000000000000..9f3b2c119952 --- /dev/null +++ b/src/main/scala/dotty/dokka/ScalaDocSupport.scala @@ -0,0 +1,9 @@ +package dotty.dokka + +import scala.tasty.reflect._ +import org.jetbrains.dokka.model.doc._ + +trait ScaladocSupport { self: DottyDokkaParser => + def parseComment(commment: reflect.Comment, tree: reflect.Tree): DocumentationNode = + parser.parse(comment.raw) // TODO use scaladoc reader to generate proper docs +} \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/repr.scala b/src/main/scala/dotty/dokka/repr.scala index 87fbc86b41bd..8c276f9723f4 100644 --- a/src/main/scala/dotty/dokka/repr.scala +++ b/src/main/scala/dotty/dokka/repr.scala @@ -1,10 +1,12 @@ package dotty.dokka +case class DDNamed(name: String, dri: ) + /** Representation of package */ case class DDPackage(name: String, comment: String) /** Representation of class */ -case class DDClass(name: String, pck: String, comment: String) +case class DDClass(name: String, pck: String, myExtend: Option[] comment: String) /** Represenation of compilation unit */ case class DDUnit(classes: Seq[DDClass], packages: Seq[DDPackage]): From d1c48c9522bd5f80196a2ff1ddd3603df185833e Mon Sep 17 00:00:00 2001 From: Krzysztof Romanowski Date: Tue, 21 Jul 2020 00:14:59 +0200 Subject: [PATCH 007/181] Generate Documentables directly from TASTY Refactor project to allow further work --- build.sbt | 19 +-- .../main/kotlin/dokka.java.api.JavaPlugin.kt | 13 -- libs/dokkaJavaApi-0.1.0.jar | Bin 13083 -> 8867 bytes .../scala/dotty/dokka/DottyDokkaConfig.scala | 2 +- .../scala/dotty/dokka/DottyDokkaPlugin.scala | 20 +--- src/main/scala/dotty/dokka/DottyReader.scala | 112 ------------------ src/main/scala/dotty/dokka/Main.scala | 16 +-- .../scala/dotty/dokka/ScalaDocSupport.scala | 9 -- src/main/scala/dotty/dokka/repr.scala | 13 -- .../dotty/dokka/tasty/BasicSupport.scala | 31 +++++ .../dotty/dokka/tasty/ClassLikeSupport.scala | 44 +++++++ .../dotty/dokka/tasty/ScalaDocSupport.scala | 9 ++ .../scala/dotty/dokka/tasty/TastyParser.scala | 69 +++++++++++ src/main/scala/tests/package.scala | 4 + src/main/scala/tests/tests.scala | 5 + 15 files changed, 189 insertions(+), 177 deletions(-) delete mode 100644 src/main/scala/dotty/dokka/DottyReader.scala delete mode 100644 src/main/scala/dotty/dokka/ScalaDocSupport.scala delete mode 100644 src/main/scala/dotty/dokka/repr.scala create mode 100644 src/main/scala/dotty/dokka/tasty/BasicSupport.scala create mode 100644 src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala create mode 100644 src/main/scala/dotty/dokka/tasty/ScalaDocSupport.scala create mode 100644 src/main/scala/dotty/dokka/tasty/TastyParser.scala create mode 100644 src/main/scala/tests/package.scala create mode 100644 src/main/scala/tests/tests.scala diff --git a/build.sbt b/build.sbt index a0028d221fd6..e2c35dfebe9c 100644 --- a/build.sbt +++ b/build.sbt @@ -2,9 +2,9 @@ val dottyVersion = "0.25.0-RC2" libraryDependencies += "org.jetbrains.dokka" % "dokka-base" % "1.4.0-M3-dev-81" libraryDependencies += "org.jetbrains.dokka" % "dokka-core" % "1.4.0-M3-dev-81" -libraryDependencies += "ch.epfl.lamp" % "dotty-tastydoc_0.25" % dottyVersion -libraryDependencies += "ch.epfl.lamp" % "dotty-compiler_0.25" % dottyVersion -libraryDependencies += "ch.epfl.lamp" % "dotty-library_0.25" % dottyVersion +libraryDependencies += "ch.epfl.lamp" %% "dotty-tastydoc" % dottyVersion +libraryDependencies += "ch.epfl.lamp" %% "dotty-compiler" % dottyVersion +libraryDependencies += "ch.epfl.lamp" %% "dotty-library" % dottyVersion resolvers += Resolver.jcenterRepo @@ -21,21 +21,24 @@ lazy val root = project libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test" ) -val dokkaJavaApiJar = file("libs") / "dokkaJavaApi-0.1.0.jar" -val buildDokkaApi = taskKey[Unit]("Compile dokka wrapper and put jar in lib") +val buildDokkaApi = taskKey[File]("Compile dokka wrapper and put jar in lib") buildDokkaApi := { + val dokkaJavaApiJar = file("libs") / "dokkaJavaApi-0.1.0.jar" val gradleRootDir = file("dokkaJavaApi") - sys.process.Process(Seq("./gradlew", "clean", "build"), gradleRootDir).! + sys.process.Process(Seq("./gradlew", "build"), gradleRootDir).! IO.delete(dokkaJavaApiJar) IO.move(gradleRootDir / "build" / "libs" / "dokkaJavaApi-0.1.0.jar", dokkaJavaApiJar) streams.value.log.success(s"Dokka api copied to $dokkaJavaApiJar") + dokkaJavaApiJar } -unmanagedJars in Compile += dokkaJavaApiJar +unmanagedJars in Compile += buildDokkaApi.value + +// Uncomment to debug dokka processing (require to run debug in listen mode on 5005 port) +//javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5005,suspend=y" -// javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=krzysiek-MS-7971:5005,suspend=y" fork.in(run) := true scalacOptions in Compile += "-language:implicitConversion" \ No newline at end of file diff --git a/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt b/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt index 0ed488f4cfb1..d0f3a6955035 100644 --- a/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt +++ b/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt @@ -26,18 +26,5 @@ abstract class JavaDokkaPlugin : DokkaPlugin() { } override dokkaBase.descriptorToDocumentableTranslator } - val inspectTheThing by extending { - CoreExtensions.preMergeDocumentableTransformer providing { ctx -> - object : PreMergeDocumentableTransformer { - override fun invoke(modules: List): List { - println(modules) - println("@@@@@@@@@") - println(modules.map { it.packages }) - return modules - } - } - } - } - abstract fun createSourceToDocumentableTranslator(cxt: DokkaContext, sourceSet: SourceSetWrapper): DModule } diff --git a/libs/dokkaJavaApi-0.1.0.jar b/libs/dokkaJavaApi-0.1.0.jar index ffa9be8b637aeb485dcca7be8c8baa61afba19b5..d72af8e04e1f5a06fa2e85d1495416b62a2d6622 100644 GIT binary patch delta 3059 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 delta 7101 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 diff --git a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala index 6fc935b6441a..6c4414359d5d 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala @@ -7,7 +7,7 @@ import java.util.{ List => JList, Map => JMap} import collection.JavaConverters._ import dotty.tastydoc.representations._ -case class DottyDokkaConfig(compilationUnit: DDUnit) extends DokkaConfiguration: +case class DottyDokkaConfig(docConfiguration: DocConfiguration) extends DokkaConfiguration: override def getOutputDir: String = new File("output").getAbsolutePath override def getCacheRoot: String = null override def getOfflineMode: Boolean = false diff --git a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala index 6c92c9b596d8..9c291a07339f 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala @@ -12,30 +12,22 @@ import org.jetbrains.dokka.plugability.DokkaContext import dokka.java.api._ import collection.JavaConverters._ import org.jetbrains.dokka.model.properties.PropertyContainer - +import dotty.dokka.tasty.DokkaTastyInspector class DottyDokkaPlugin extends JavaDokkaPlugin: override def createSourceToDocumentableTranslator(cxt: DokkaContext, sourceSet: SourceSetWrapper): DModule = cxt.getConfiguration match { case dottyConfig: DottyDokkaConfig => - val parser = new MarkdownParser(null, null, cxt.getLogger) - - val doc = parser.parse("## THIS IS MY DOC!") - - val reader = DottyReader(sourceSet, parser, dottyConfig) - - val packages = dottyConfig.compilationUnit.packages.map(reader.parsePackage).toList - - val res = new DModule( + val inspector = DokkaTastyInspector(sourceSet, new MarkdownParser(null, null, cxt.getLogger), dottyConfig) + inspector.inspect(dottyConfig.docConfiguration.classpath, dottyConfig.docConfiguration.tastyFiles) + + new DModule( sourceSet.getSourceSet.getSourceSetID.getModuleName, - packages.asJava, + inspector.result().asJava, Map().asJava, null, sourceSet.toSet, PropertyContainer.Companion.empty() ) - - println(res) - res case _ => ??? } \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/DottyReader.scala b/src/main/scala/dotty/dokka/DottyReader.scala deleted file mode 100644 index e73611c5b434..000000000000 --- a/src/main/scala/dotty/dokka/DottyReader.scala +++ /dev/null @@ -1,112 +0,0 @@ -package dotty.dokka - - -import org.jetbrains.dokka.plugability._ -import org.jetbrains.dokka.transformers.sources._ - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.model._ -import org.jetbrains.dokka.links._ -import org.jetbrains.dokka.model.doc._ -import org.jetbrains.dokka.base.parsers._ -import org.jetbrains.dokka.plugability.DokkaContext -import dokka.java.api._ -import collection.JavaConverters._ -import org.jetbrains.dokka.model.properties.PropertyContainer -import java.util.{List => JList} -import dotty.tastydoc.representations._ - - -import scala.tasty.Reflection -import scala.tasty.inspector.TastyInspector -import dotty.tastydoc.representations -import dotty.tastydoc.representations._ - - -case class DottyDokkaParser(reflect: Reflection, sourceSet: SourceSetWrapper, parser: Parser, config: DottyDokkaConfig) extends ScaladocSupport: - def parseTree(reflect: reflect.Tree): Seq[Documentable] = Nil - - -class DokkaTastyInspector extends TastyInspector: - private val packages = Set.newBuilder[DDPackage] - private val classes = Set.newBuilder[DDClass] - - private val topLevels = Seq.newBuilder[Documentable] - - protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = - import reflect.{_, given _} - - object Traverser extends TreeTraverser: - override def traverseTree(tree: Tree)(using ctx: Context): Unit = - tree match - case clazz: ClassDef => - classes += DDClass(clazz.name, "dotty.dokka", clazz.symbol.comment.fold("")(_.raw)) - case _ => - } - super.traverseTree(tree) - - Traverser.traverseTree(root)(using reflect.rootContext) - - def result() = - val res = DDUnit(classes.result.toList, packages.result.toList) - println(res) - res - - def mkClass - - -case class DottyReader(sourceSet: SourceSetWrapper, parser: Parser, config: DottyDokkaConfig): - def parsePackage(pck: DDPackage): DPackage = - val entries = config.compilationUnit.classesByPackage.get(pck.name).getOrElse(Nil).map(parseClasslike(pck.name)) - - new DPackage( - new DRI(pck.name, null, null, PointingToDeclaration.INSTANCE, null), - Nil.asJava, - Nil.asJava, - entries.toList.asJava, - Nil.asJava, - sourceSet.asMap(parser.parse(pck.comment)), - null, - sourceSet.toSet, - PropertyContainer.Companion.empty() - ) - - - def parseClasslike(packatgeName: String)(clazz: DDClass): DClass = - val dri = new DRI(packatgeName, clazz.name, null, PointingToDeclaration.INSTANCE, null) - - val constr: JList[DFunction] = Nil.asJava - val funs: JList[DFunction] = Nil.asJava - val props: JList[DProperty] = Nil.asJava - val nested: JList[DClasslike] = Nil.asJava - - - val source = new DocumentableSource(): - override def getPath: String = packatgeName.mkString("src/","/", s"${clazz.name}.scala") - - val vis = KotlinVisibility.Public.INSTANCE - val doc = sourceSet.asMap(parser.parse("## Documentation for Foo")) - val companion : DObject = null - - val gens: JList[DTypeParameter] = Nil.asJava - val supers: JList[DriWithKind] = Nil.asJava - val mod = sourceSet.asMap(JavaModifier.Abstract.INSTANCE) - - new DClass( - dri, - clazz.name, - Nil.asJava, - Nil.asJava, - Nil.asJava, - Nil.asJava, - sourceSet.asMap(source), - sourceSet.asMap(KotlinVisibility.Public.INSTANCE), - null, - Nil.asJava, - Map().asJava, - sourceSet.asMap(parser.parse(clazz.comment)), - null, - mod, - sourceSet.toSet, - PropertyContainer.Companion.empty() - ) diff --git a/src/main/scala/dotty/dokka/Main.scala b/src/main/scala/dotty/dokka/Main.scala index 3684176a6fc9..ab4444ceb174 100644 --- a/src/main/scala/dotty/dokka/Main.scala +++ b/src/main/scala/dotty/dokka/Main.scala @@ -13,19 +13,21 @@ import scala.tasty.inspector.TastyInspector import dotty.tastydoc.representations import dotty.tastydoc.representations._ +case class DocConfiguration(tastyFiles: List[String], classpath: String) object Main: def main(args: Array[String]): Unit = - val cp = args.headOption.getOrElse("/home/krzysiek/workspace/dotty-dokka/target/scala-0.25/classes") + // TODO change the default to something more reasonable... + val cp = args.headOption.getOrElse("target/scala-0.25/classes") def listTastyFiles(f: File): Seq[File] = val (files, dirs) = f.listFiles().partition(_.isFile) files.filter(_.getName.endsWith(".tasty")) ++ dirs.flatMap(listTastyFiles) - val tastyFiles = cp.split(File.pathSeparatorChar).toList.flatMap(p => listTastyFiles(new File(p))).map(_.toString) + val config = DocConfiguration( + tastyFiles = cp.split(File.pathSeparatorChar).toList.flatMap(p => listTastyFiles(new File(p))).map(_.toString), + classpath = System.getProperty("java.class.path") + ) - val inspector = new DokkaTastyInspector() - inspector.inspect(System.getProperty("java.class.path"), tastyFiles) - - val config = DottyDokkaConfig(inspector.result()) - new DokkaGenerator(config, DokkaConsoleLogger.INSTANCE).generate() + // TODO pass options, classpath etc. + new DokkaGenerator(new DottyDokkaConfig(config), DokkaConsoleLogger.INSTANCE).generate() println("Done") diff --git a/src/main/scala/dotty/dokka/ScalaDocSupport.scala b/src/main/scala/dotty/dokka/ScalaDocSupport.scala deleted file mode 100644 index 9f3b2c119952..000000000000 --- a/src/main/scala/dotty/dokka/ScalaDocSupport.scala +++ /dev/null @@ -1,9 +0,0 @@ -package dotty.dokka - -import scala.tasty.reflect._ -import org.jetbrains.dokka.model.doc._ - -trait ScaladocSupport { self: DottyDokkaParser => - def parseComment(commment: reflect.Comment, tree: reflect.Tree): DocumentationNode = - parser.parse(comment.raw) // TODO use scaladoc reader to generate proper docs -} \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/repr.scala b/src/main/scala/dotty/dokka/repr.scala deleted file mode 100644 index 8c276f9723f4..000000000000 --- a/src/main/scala/dotty/dokka/repr.scala +++ /dev/null @@ -1,13 +0,0 @@ -package dotty.dokka - -case class DDNamed(name: String, dri: ) - -/** Representation of package */ -case class DDPackage(name: String, comment: String) - -/** Representation of class */ -case class DDClass(name: String, pck: String, myExtend: Option[] comment: String) - -/** Represenation of compilation unit */ -case class DDUnit(classes: Seq[DDClass], packages: Seq[DDPackage]): - lazy val classesByPackage = classes.groupBy(_.pck) \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala new file mode 100644 index 000000000000..017d16454762 --- /dev/null +++ b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala @@ -0,0 +1,31 @@ +package dotty.dokka.tasty + +import org.jetbrains.dokka.links._ +import org.jetbrains.dokka.model.DocumentableSource + +trait BasicSupport: + self: TastyParser => + import reflect._ + + extension SymbolOps on (sym: reflect.Symbol): + def packageName(using ctx: Context): String = + if (sym.isPackageDef) sym.fullName + else sym.owner.packageName + + def topLevelEntryName(using ctx: Context): Option[String] = if (sym.isPackageDef) None else + if (sym.owner.isPackageDef) Some(sym.name) else sym.owner.topLevelEntryName + + def dri = asDRI(sym) + + def asDRI(symbol: reflect.Symbol): DRI = new DRI( + symbol.packageName, + symbol.topLevelEntryName.orNull, // TODO do we need any of this fields? + null, // TODO search for callable here? + PointingToDeclaration.INSTANCE, // TODO different targets? + symbol.show + ) + + def getSource(symbol: reflect.Symbol)(using ctx: Context): DocumentableSource = + val path = symbol.pos.sourceFile.jpath.toString + new DocumentableSource: + override def getPath = path \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala new file mode 100644 index 000000000000..ff64daeef35f --- /dev/null +++ b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala @@ -0,0 +1,44 @@ +package dotty.dokka.tasty + +import org.jetbrains.dokka.model._ +import org.jetbrains.dokka.links._ +import org.jetbrains.dokka.model.doc._ +import collection.JavaConverters._ +import org.jetbrains.dokka.model.properties.PropertyContainer + +trait ClassLikeSupport: + self: TastyParser => + import reflect._ + + def parseClass(classDef: reflect.ClassDef)(using ctx: Context): DClasslike = + val mod = sourceSet.asMap(JavaModifier.Abstract.INSTANCE) + val doc = classDef.symbol.comment match + case Some(comment) => + sourceSet.asMap(parseComment(comment, classDef)) + case None => + Map.empty.asJava + + + val parents = classDef.parents.map { parentTree => + val parentSymbol = if(parentTree.symbol.isClassConstructor) parentTree.symbol.owner else parentTree.symbol + new DriWithKind(asDRI(parentSymbol), if(parentSymbol.isClassDef) KotlinClassKindTypes.CLASS else KotlinClassKindTypes.INTERFACE) + } + + new DClass( + asDRI(classDef.symbol), + classDef.name, + Nil.asJava, + Nil.asJava, + Nil.asJava, + Nil.asJava, + sourceSet.asMap(getSource(classDef.symbol)), + sourceSet.asMap(KotlinVisibility.Public.INSTANCE), + null, + Nil.asJava, + sourceSet.asMap(parents.asJava), + doc, + null, + mod, + inspector.sourceSet.toSet, + PropertyContainer.Companion.empty() + ) diff --git a/src/main/scala/dotty/dokka/tasty/ScalaDocSupport.scala b/src/main/scala/dotty/dokka/tasty/ScalaDocSupport.scala new file mode 100644 index 000000000000..16feba187b5a --- /dev/null +++ b/src/main/scala/dotty/dokka/tasty/ScalaDocSupport.scala @@ -0,0 +1,9 @@ +package dotty.dokka.tasty + +import scala.tasty.reflect._ +import org.jetbrains.dokka.model.doc._ + +trait ScaladocSupport { self: TastyParser => + def parseComment(comment: reflect.Comment, tree: reflect.Tree): DocumentationNode = + inspector.parser.parse(comment.raw) // TODO use scaladoc reader to generate proper docs +} \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/tasty/TastyParser.scala b/src/main/scala/dotty/dokka/tasty/TastyParser.scala new file mode 100644 index 000000000000..d8c9268d8edd --- /dev/null +++ b/src/main/scala/dotty/dokka/tasty/TastyParser.scala @@ -0,0 +1,69 @@ +package dotty.dokka +package tasty + + +import org.jetbrains.dokka.plugability._ +import org.jetbrains.dokka.transformers.sources._ + +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.model._ +import org.jetbrains.dokka.links._ +import org.jetbrains.dokka.model.doc._ +import org.jetbrains.dokka.base.parsers._ +import org.jetbrains.dokka.plugability.DokkaContext +import dokka.java.api._ +import collection.JavaConverters._ +import org.jetbrains.dokka.model.properties.PropertyContainer +import java.util.{List => JList} +import dotty.tastydoc.representations._ + + +import scala.tasty.Reflection +import scala.tasty.inspector.TastyInspector +import dotty.tastydoc.representations +import dotty.tastydoc.representations._ + +case class TastyParser(reflect: Reflection, inspector: DokkaTastyInspector) extends ScaladocSupport with BasicSupport with ClassLikeSupport: + import reflect._ + + def sourceSet = inspector.sourceSet + + def parseRootTree(root: Tree): Seq[Documentable] = + val docs = Seq.newBuilder[Documentable] + object Traverser extends TreeTraverser: + override def traverseTree(tree: Tree)(using ctx: Context): Unit = + tree match { + case clazz: ClassDef => + docs += parseClass(clazz) + //classes += DDClass(clazz.name, "dotty.dokka", clazz.symbol.comment.fold("")(_.raw)) + case _ => + } + super.traverseTree(tree) + + Traverser.traverseTree(root)(using reflect.rootContext) + docs.result() + +case class DokkaTastyInspector(sourceSet: SourceSetWrapper, parser: Parser, config: DottyDokkaConfig) extends TastyInspector: + + private val topLevels = Seq.newBuilder[Documentable] + + protected def processCompilationUnit(reflect: Reflection)(root: reflect.Tree): Unit = + val parser = new TastyParser(reflect, this) + topLevels ++= parser.parseRootTree(root.asInstanceOf[parser.reflect.Tree]) + + def result(): List[DPackage] = + val all = topLevels.result() + val byPackage = all.filter(_.getDri != null).groupBy(_.getDri().getPackageName()) + byPackage.map { case (pck, entries) => + new DPackage( + new DRI(pck, null, null, PointingToDeclaration.INSTANCE, null), + Nil.asJava, + Nil.asJava, + entries.collect{ case d: DClasslike => d }.toList.asJava, // TODO add support for other things like type or package object entries + Nil.asJava, + Map.empty.asJava, // TODO find docs for package and search for package object to extract doc + null, + sourceSet.toSet, + PropertyContainer.Companion.empty() + ) + }.toList diff --git a/src/main/scala/tests/package.scala b/src/main/scala/tests/package.scala new file mode 100644 index 000000000000..7fac475792cb --- /dev/null +++ b/src/main/scala/tests/package.scala @@ -0,0 +1,4 @@ +/** This should be moved to its own project */ +package object tests { + +} diff --git a/src/main/scala/tests/tests.scala b/src/main/scala/tests/tests.scala new file mode 100644 index 000000000000..aa628a47f7da --- /dev/null +++ b/src/main/scala/tests/tests.scala @@ -0,0 +1,5 @@ +package tests + +class A + +class B extends A \ No newline at end of file From c3bbbe206aa4b32d1e2e6fce110e3cb772d66c4b Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Tue, 21 Jul 2020 09:42:59 +0200 Subject: [PATCH 008/181] Do not require to run gradle --- build.sbt | 8 +- dokkaJavaApi/gradlew | 2 + dokkaJavaApi/gradlew.bat | 204 ++++++++++++++++++------------------ libs/dokkaJavaApi-0.1.0.jar | Bin 8867 -> 8867 bytes 4 files changed, 111 insertions(+), 103 deletions(-) diff --git a/build.sbt b/build.sbt index e2c35dfebe9c..7dc39bd070e1 100644 --- a/build.sbt +++ b/build.sbt @@ -22,19 +22,21 @@ lazy val root = project ) + val dokkaJavaApiJar = file("libs") / "dokkaJavaApi-0.1.0.jar" + + val buildDokkaApi = taskKey[File]("Compile dokka wrapper and put jar in lib") buildDokkaApi := { - val dokkaJavaApiJar = file("libs") / "dokkaJavaApi-0.1.0.jar" val gradleRootDir = file("dokkaJavaApi") sys.process.Process(Seq("./gradlew", "build"), gradleRootDir).! - IO.delete(dokkaJavaApiJar) + if (dokkaJavaApiJar.exists()) IO.delete(dokkaJavaApiJar) IO.move(gradleRootDir / "build" / "libs" / "dokkaJavaApi-0.1.0.jar", dokkaJavaApiJar) streams.value.log.success(s"Dokka api copied to $dokkaJavaApiJar") dokkaJavaApiJar } -unmanagedJars in Compile += buildDokkaApi.value +unmanagedJars in Compile += dokkaJavaApiJar // Uncomment to debug dokka processing (require to run debug in listen mode on 5005 port) //javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5005,suspend=y" diff --git a/dokkaJavaApi/gradlew b/dokkaJavaApi/gradlew index 2fe81a7d95e4..fbd7c515832d 100755 --- a/dokkaJavaApi/gradlew +++ b/dokkaJavaApi/gradlew @@ -82,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -129,6 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/dokkaJavaApi/gradlew.bat b/dokkaJavaApi/gradlew.bat index 9618d8d9607c..a9f778a7a964 100644 --- a/dokkaJavaApi/gradlew.bat +++ b/dokkaJavaApi/gradlew.bat @@ -1,100 +1,104 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/libs/dokkaJavaApi-0.1.0.jar b/libs/dokkaJavaApi-0.1.0.jar index d72af8e04e1f5a06fa2e85d1495416b62a2d6622..2236b1bf46fb6cf910b9bd78fb4f1e424012ada1 100644 GIT binary patch delta 444 zcmZ4Ny4aN`z?+$ci-CcIgTdW*B9A(=yYJVDW?o?Gx-yvhs{x`WYcT47=*?}c(^$Za z&k`S4xe=PbZuSzm%M6wYXVifx(GocZVaRi7uz{o|Hhc0gGKnz5Y@GaF&J-j*SzX>9 zOz)DHmMmjnU`WZ&&Q8=1@J3erb@DrTX~sE|xfG-vfO-Oe${3hH1Q75;C?F}o@YeA- zkcOC$l~|UjpIDHIVboa#X{K)slN%KjCvz*xg6;NHl4j~>ot&nm$%|@jt)etj7dKF? z>E!c@LJA;f7KQ6Y(d5Sz>;Y@jHre3+pZSv|OtZX2?JV3YxXyZdU5Dx%P C>2Xp3 delta 500 zcmZ4Ny4aN`z?+$ci-CcIgF%IHB9A)ruU%gznt6e!$+P4`DzVbwvk6 zZ7%26VF5Fk8K*%Q`4SpzV3FzEcbUPAWx~fGQgc{8u<|f6i7>-#ocvzS6r^Oby1YG@ z_EwT+EStPSPK`gn8=(-SB2!*k@)QFDLrQ*jcA`GI>|A;2=nrt&ti&=5B>_NL1||>z z1pE*RND45#b(Cg=84K2!SdfWfzP6$?lNaOUhYF^XYZXNlfDQ^UxagVf&BDN-!^yy4 z05^|;VM${pD^Q{0WMf7_3}5^Nnj^#olvbELPl9c-jS>&otWEQT_jfWgFobb1Fj%6P zWh($w><(7sIp64M3DCkeZUzQ(6h*QklQ$~5f&;KnL7M5A#N<8&O%YZ$kRl!+Tmv-v Ip&W<@0IHOcH~;_u From c3596ae7f672bf9062ef0ff7856966de7ad082e6 Mon Sep 17 00:00:00 2001 From: Aleksander Boruch-Gruszecki Date: Tue, 21 Jul 2020 10:18:10 +0200 Subject: [PATCH 009/181] Fix a typo in compiler option name --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7dc39bd070e1..7a4faa6d5a23 100644 --- a/build.sbt +++ b/build.sbt @@ -43,4 +43,4 @@ unmanagedJars in Compile += dokkaJavaApiJar fork.in(run) := true -scalacOptions in Compile += "-language:implicitConversion" \ No newline at end of file +scalacOptions in Compile += "-language:implicitConversions" From 89609350d97853f7842ca5ac8657d4d730dab5f5 Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Tue, 21 Jul 2020 14:12:54 +0200 Subject: [PATCH 010/181] Setup CI and publicaiton --- .github/workflows/CI.yaml | 38 ++++++++++++++++++++++++++++++++++++++ build.sbt | 3 +++ src/test/scala/Test1.scala | 9 --------- 3 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/CI.yaml delete mode 100644 src/test/scala/Test1.scala diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml new file mode 100644 index 000000000000..0224eed32ace --- /dev/null +++ b/.github/workflows/CI.yaml @@ -0,0 +1,38 @@ +name: CI for context buddy + +on: + push: + branches: + - master + pull_request: +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v2 + - run: git fetch --prune --unshallow --tags + + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Compile and test + run: sbt compile test + + - name: Generate test documentation + run: sbt generateExapleDocumentation + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: eu-central-1 + + - name: Publish all + run: | + dest=s3://contextbuddy/dokka-dotty/$([ $GITHUB_REF = "master" ] && echo master || echo pr-$(echo $GITHUB_REF | cut '-d/' -f3)) + aws s3 rm $dest + aws s3 sync output $dest diff --git a/build.sbt b/build.sbt index 7dc39bd070e1..c4f93937ab4f 100644 --- a/build.sbt +++ b/build.sbt @@ -36,6 +36,9 @@ buildDokkaApi := { dokkaJavaApiJar } +val generateExapleDocumentation = taskKey[Unit]("Generate example documentation") +generateExapleDocumentation := run.in(Compile).toTask("").value // TODO + unmanagedJars in Compile += dokkaJavaApiJar // Uncomment to debug dokka processing (require to run debug in listen mode on 5005 port) diff --git a/src/test/scala/Test1.scala b/src/test/scala/Test1.scala deleted file mode 100644 index b4232a71f62f..000000000000 --- a/src/test/scala/Test1.scala +++ /dev/null @@ -1,9 +0,0 @@ - -import org.junit.Test -import org.junit.Assert._ - -class Test1 { - @Test def t1(): Unit = { - assertEquals("I was compiled by dotty :)", "ala") - } -} \ No newline at end of file From ddf60676605229ddcbf73edf4acd629a17d15b38 Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Tue, 21 Jul 2020 15:38:45 +0200 Subject: [PATCH 011/181] Add caching --- .github/workflows/CI.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 0224eed32ace..c9c395e49c5d 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -13,6 +13,17 @@ jobs: - uses: actions/checkout@v2 - run: git fetch --prune --unshallow --tags + - name: Cache Coursier + uses: actions/cache@v1 + with: + path: ~/.cache/coursier + key: sbt-coursier-cache + - name: Cache SBT + uses: actions/cache@v1 + with: + path: ~/.sbt + key: sbt-${{ hashFiles('**/build.sbt') }} + - name: Set up JDK 11 uses: actions/setup-java@v1 with: @@ -36,3 +47,5 @@ jobs: dest=s3://contextbuddy/dokka-dotty/$([ $GITHUB_REF = "master" ] && echo master || echo pr-$(echo $GITHUB_REF | cut '-d/' -f3)) aws s3 rm $dest aws s3 sync output $dest + + From ffaaca11c4c2752393d7925e4c8d438d6601d9d5 Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Tue, 21 Jul 2020 16:49:49 +0200 Subject: [PATCH 012/181] Basic support for methods, generics does not work. --- .../dotty/dokka/tasty/BasicSupport.scala | 47 +++++++++--- .../dotty/dokka/tasty/ClassLikeSupport.scala | 72 ++++++++++++++----- src/main/scala/tests/tests.scala | 23 +++++- 3 files changed, 116 insertions(+), 26 deletions(-) diff --git a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala index 017d16454762..62a5b4edea35 100644 --- a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala @@ -1,7 +1,8 @@ package dotty.dokka.tasty import org.jetbrains.dokka.links._ -import org.jetbrains.dokka.model.DocumentableSource +import org.jetbrains.dokka.model._ +import collection.JavaConverters._ trait BasicSupport: self: TastyParser => @@ -15,15 +16,43 @@ trait BasicSupport: def topLevelEntryName(using ctx: Context): Option[String] = if (sym.isPackageDef) None else if (sym.owner.isPackageDef) Some(sym.name) else sym.owner.topLevelEntryName - def dri = asDRI(sym) + def dri = asDRI(sym) + def declarationDri = asDRI(sym, true) - def asDRI(symbol: reflect.Symbol): DRI = new DRI( - symbol.packageName, - symbol.topLevelEntryName.orNull, // TODO do we need any of this fields? - null, // TODO search for callable here? - PointingToDeclaration.INSTANCE, // TODO different targets? - symbol.show - ) + def documentation(using cxt: reflect.Context) = sym.comment match + case Some(comment) => + sourceSet.asMap(parseComment(comment, sym.tree)) + case None => + Map.empty.asJava + + def source(using ctx: Context) = sourceSet.asMap(getSource(sym)) + + def dokkaType(using cxt: reflect.Context): Bound = // TODO render primitives better? + // TODO support varags + val params = sym.typeMembers.map(_.dokkaType) + println(s"${sym.show} -> ${sym.dri}") + new org.jetbrains.dokka.model.TypeConstructor(sym.dri, params.asJava, FunctionModifiers.NONE) + + + + // TODO add support for type aliases! + def asDRI(symbol: reflect.Symbol, declaration: Boolean = false): DRI = + val pointsTo = + if (!symbol.isTypeDef || declaration) PointingToDeclaration.INSTANCE + else PointingToGenericParameters(symbol.owner.typeMembers.indexOf(symbol)) + + val method = + if (symbol.isDefDef) Some(symbol) + else if (symbol.owner.isDefDef) Some(symbol.owner) + else None + + new DRI( + symbol.packageName, + symbol.topLevelEntryName.orNull, // TODO do we need any of this fields? + method.map(s => new org.jetbrains.dokka.links.Callable(s.name, null, Nil.asJava)).orNull, + pointsTo, // TODO different targets? + symbol.show + ) def getSource(symbol: reflect.Symbol)(using ctx: Context): DocumentableSource = val path = symbol.pos.sourceFile.jpath.toString diff --git a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala index ff64daeef35f..e2896f78c804 100644 --- a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala @@ -11,24 +11,21 @@ trait ClassLikeSupport: import reflect._ def parseClass(classDef: reflect.ClassDef)(using ctx: Context): DClasslike = - val mod = sourceSet.asMap(JavaModifier.Abstract.INSTANCE) - val doc = classDef.symbol.comment match - case Some(comment) => - sourceSet.asMap(parseComment(comment, classDef)) - case None => - Map.empty.asJava - - - val parents = classDef.parents.map { parentTree => - val parentSymbol = if(parentTree.symbol.isClassConstructor) parentTree.symbol.owner else parentTree.symbol - new DriWithKind(asDRI(parentSymbol), if(parentSymbol.isClassDef) KotlinClassKindTypes.CLASS else KotlinClassKindTypes.INTERFACE) - } + + val parents = for + parentTree <- classDef.parents + parentSymbol = if (parentTree.symbol.isClassConstructor) parentTree.symbol.owner else parentTree.symbol + if !parentSymbol.flags.is(Flags.Synthetic) // TODO add beter filtering on parent symbols + yield new DriWithKind(asDRI(parentSymbol), if(parentSymbol.isClassDef) KotlinClassKindTypes.CLASS else KotlinClassKindTypes.INTERFACE) + + val methods = classDef.symbol.classMethods.filterNot(_.flags.is(Flags.Synthetic)) + val constuctors = classDef.symbol.children.filter(_.isClassConstructor) new DClass( asDRI(classDef.symbol), classDef.name, - Nil.asJava, - Nil.asJava, + constuctors.map(parseMethod).asJava, + methods.map(parseMethod).asJava, Nil.asJava, Nil.asJava, sourceSet.asMap(getSource(classDef.symbol)), @@ -36,9 +33,52 @@ trait ClassLikeSupport: null, Nil.asJava, sourceSet.asMap(parents.asJava), - doc, + classDef.symbol.documentation, null, - mod, + sourceSet.asMap(JavaModifier.Abstract.INSTANCE), inspector.sourceSet.toSet, PropertyContainer.Companion.empty() ) + + def parseMethod(methodSymbol: Symbol): DFunction = + val method = methodSymbol.tree.asInstanceOf[DefDef] + val paramLists = method.paramss + + new DFunction( + methodSymbol.dri, + methodSymbol.name, + methodSymbol.isClassConstructor, + paramLists.flatten.map(parseArgument).asJava, // TODO add support for parameters + methodSymbol.documentation, + null, + methodSymbol.source, + sourceSet.asMap(KotlinVisibility.Public.INSTANCE), + method.returnTpt.tpe.typeSymbol.dokkaType, // TODO play with it? + /*generics =*/ method.typeParams.map(parseTypeArgument).asJava, + /*receiver =*/ null, + /*modifier =*/ sourceSet.asMap(JavaModifier.Abstract.INSTANCE), + sourceSet.toSet(), + PropertyContainer.Companion.empty() + ) + + def parseArgument(argument: ValDef): DParameter = + new DParameter( + argument.symbol.dri, + argument.symbol.name, + argument.symbol.documentation, + null, + argument.tpt.tpe.typeSymbol.dokkaType, // Can we get type symbol easier? + sourceSet.toSet(), + PropertyContainer.Companion.empty() + ) + + def parseTypeArgument(argument: TypeDef): DTypeParameter = + new DTypeParameter( + argument.symbol.declarationDri, // TODO do we need that? Maybe we can suppot TypeDef in .dri method? + argument.symbol.name, + argument.symbol.documentation, + null, + Nil.asJava, // TODO add type bounds + sourceSet.toSet(), + PropertyContainer.Companion.empty() + ) \ No newline at end of file diff --git a/src/main/scala/tests/tests.scala b/src/main/scala/tests/tests.scala index aa628a47f7da..d22ce9f89522 100644 --- a/src/main/scala/tests/tests.scala +++ b/src/main/scala/tests/tests.scala @@ -1,5 +1,26 @@ package tests class A +class B extends A +class C +class D[T] +class E[T] extends D[T] -class B extends A \ No newline at end of file + + +class Constructors(a: String): + def this() = this("Ala") + +class Methods: + def simple(): B = ??? + def oneParam(a: A): B = ??? + def multipleParams(a: A, b: B): C = ??? + def vararg(a: A*): C = ??? + def multipleList(a: A)(b: B): C = ??? + + def generic[T](a: D[T]): D[T] = ??? + def generic2[T, V](a: D[T], b: E[V]): D[T] = ??? + + def primitives(a: Int, b: Double, c: Short): Byte = 0 + def strings(a: String): String = "" + def arrays(a: Array[String], b: Array[Int]): Array[Double] = ??? From 7b24b9e786f00c83750600d8c79e81a45ea783b3 Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Wed, 22 Jul 2020 14:27:48 +0200 Subject: [PATCH 013/181] Create Scala signature provider that redeners methods --- .../main/kotlin/dokka.java.api.JavaPlugin.kt | 33 +++++++- libs/dokkaJavaApi-0.1.0.jar | Bin 8867 -> 14381 bytes .../scala/dotty/dokka/DottyDokkaPlugin.scala | 6 +- src/main/scala/dotty/dokka/Main.scala | 5 +- .../dotty/dokka/ScalaSignatureProvider.scala | 71 ++++++++++++++++++ .../dotty/dokka/tasty/BasicSupport.scala | 36 ++++----- .../dotty/dokka/tasty/ClassLikeSupport.scala | 13 +++- src/main/scala/dotty/dokka/utils.scala | 47 ++++++++++++ 8 files changed, 188 insertions(+), 23 deletions(-) create mode 100644 src/main/scala/dotty/dokka/ScalaSignatureProvider.scala create mode 100644 src/main/scala/dotty/dokka/utils.scala diff --git a/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt b/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt index d0f3a6955035..3b069d4b1446 100644 --- a/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt +++ b/dokkaJavaApi/src/main/kotlin/dokka.java.api.JavaPlugin.kt @@ -3,11 +3,21 @@ package dokka.java.api import org.jetbrains.dokka.CoreExtensions import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.signatures.KotlinSignatureProvider +import org.jetbrains.dokka.base.signatures.SignatureProvider +import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter +import org.jetbrains.dokka.base.translators.documentables.PageContentBuilder import org.jetbrains.dokka.model.DModule +import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.pages.ContentGroup +import org.jetbrains.dokka.pages.ContentKind +import org.jetbrains.dokka.pages.Kind +import org.jetbrains.dokka.pages.Style import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.transformers.documentation.PreMergeDocumentableTransformer import org.jetbrains.dokka.transformers.sources.SourceToDocumentableTranslator +import org.jetbrains.dokka.utilities.DokkaLogger +import java.util.function.Consumer data class SourceSetWrapper(val sourceSet: DokkaConfiguration.DokkaSourceSet) { fun toSet(): Set = setOf(sourceSet) @@ -26,5 +36,26 @@ abstract class JavaDokkaPlugin : DokkaPlugin() { } override dokkaBase.descriptorToDocumentableTranslator } + val scalaSignatureProvider by extending { + dokkaBase.signatureProvider providing { ctx -> + createSignatureProvider(ctx.single(dokkaBase.commentsToContentConverter), ctx.logger) + } override dokkaBase.kotlinSignatureProvider + } + abstract fun createSourceToDocumentableTranslator(cxt: DokkaContext, sourceSet: SourceSetWrapper): DModule + abstract fun createSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLogger): SignatureProvider } + +// TODO we probably does not need that +class JPageContentBuilder(cc: CommentsToContentConverter, sp: SignatureProvider, l: DokkaLogger) : + PageContentBuilder(cc, sp, l) { + fun mkContent( + d: Documentable, + kind: Kind = ContentKind.Main, + styles: Set",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[e],starts:{e:"<\/script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},e]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^\\s*([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("properties",function(r){var t="[ \\t\\f]*",e="("+t+"[:=]"+t+"|[ \\t\\f]+)",s="([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",n="([^\\\\:= \\t\\f\\n]|\\\\.)+",a={e:e,r:0,starts:{cN:"string",e:/$/,r:0,c:[{b:"\\\\\\n"}]}};return{cI:!0,i:/\S/,c:[r.C("^\\s*[!#]","$"),{b:s+e,rB:!0,c:[{cN:"attr",b:s,endsParent:!0,r:0}],starts:a},{b:n+e,rB:!0,r:0,c:[{cN:"meta",b:n,endsParent:!0,r:0}],starts:a},{cN:"attr",r:0,b:n+t+"$"}]}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",k:"unless",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d;var l=[{b:/^\s*=>/,starts:{e:"$",c:i.c=d}},{cN:"meta",b:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(l).concat(d)}});hljs.registerLanguage("yaml",function(e){var b="true false yes no null",a="^[ \\-]*",r="[a-zA-Z_][\\w\\-]*",t={cN:"attr",v:[{b:a+r+":"},{b:a+'"'+r+'":'},{b:a+"'"+r+"':"}]},c={cN:"string",r:0,v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/\S+/}],c:[e.BE,{cN:"template-variable",v:[{b:"{{",e:"}}"},{b:"%{",e:"}"}]}]};return{cI:!0,aliases:["yml","YAML","yaml"],c:[t,{cN:"meta",b:"^---s*$",r:10},{cN:"string",b:"[\\|>] *$",rE:!0,c:c.c,e:t.v[0].b},{b:"<%[%=-]?",e:"[%-]?%>",sL:"ruby",eB:!0,eE:!0,r:0},{cN:"type",b:"!"+e.UIR},{cN:"type",b:"!!"+e.UIR},{cN:"meta",b:"&"+e.UIR+"$"},{cN:"meta",b:"\\*"+e.UIR+"$"},{cN:"bullet",b:"^ *-",r:0},e.HCM,{bK:b,k:{literal:b}},e.CNM,c]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,{cN:"",b:/\\"/},{cN:"string",b:/'/,e:/'/},t]}});hljs.registerLanguage("scala",function(e){var t={cN:"subst",v:[{b:"\\$[A-Za-z0-9_]+"},{b:"\\${",e:"}"}]},a={cN:"string",v:[{b:'"',e:'"',i:"\\n",c:[e.BE]},{b:'"""',e:'"""',r:10},{b:'[a-z]+"',e:'"',i:"\\n",c:[e.BE,t]},{cN:"string",b:'[a-z]+"""',e:'"""',c:[t],r:10}]},r={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0},c={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0},i={cN:"class",bK:"class object trait type",e:/[:={\[\n;]/,eE:!0,c:[{bK:"extends with",r:10},{b:/\[/,e:/\]/,eB:!0,eE:!0,r:0,c:[r]},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,r:0,c:[r]},c]},s={cN:"function",bK:"def",e:/[:={\[(\n;]/,eE:!0,c:[c]};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[e.CLCM,e.CBCM,a,{cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"},r,s,i,e.CNM,{cN:"meta",b:"@[A-Za-z]+"}]}}); \ No newline at end of file diff --git a/dotty-docs/docs/js/jquery.min.js b/dotty-docs/docs/js/jquery.min.js new file mode 100644 index 000000000000..a1c07fd803b5 --- /dev/null +++ b/dotty-docs/docs/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0 { + $(".sidebar").toggleClass("toggled"); + }) + $("#search-icon").click(() => { + $("#searchbar").toggleClass("shown"); + $("#search-api-input").focus(); + }) + const searchInput = $("#search-api-input"); + searchInput.keydown(evt => { + if (evt.which == 13) { + const baseUrl = $("#baseurl-input").val(); + window.location = ( + baseUrl + "/api/search.html?" + + "searchTerm=" + searchInput.val() + + "&previousUrl=" + encodeURI(window.location) + ); + } + }) +}) diff --git a/dotty-docs/docs/sidebar.yml b/dotty-docs/docs/sidebar.yml new file mode 100644 index 000000000000..b8f627760c8c --- /dev/null +++ b/dotty-docs/docs/sidebar.yml @@ -0,0 +1,239 @@ +sidebar: + - title: Blog + url: blog/index.html + - title: Usage + subsection: + - title: Getting Started + url: docs/usage/getting-started.html + - title: sbt-projects + url: docs/usage/sbt-projects.html + - title: IDE support for Dotty + url: docs/usage/ide-support.html + - title: Worksheet mode in Dotty IDE + url: docs/usage/worksheet-mode.html + - title: Language Versions + url: docs/usage/language-versions.html + - title: cbt-projects + url: docs/usage/cbt-projects.html + - title: Dottydoc + url: docs/usage/dottydoc.html + - title: Reference + subsection: + - title: Overview + url: docs/reference/overview.html + - title: New Types + subsection: + - title: Intersection types + url: docs/reference/new-types/intersection-types.html + - title: Union types + url: docs/reference/new-types/union-types.html + - title: Type lambdas + url: docs/reference/new-types/type-lambdas.html + - title: Match types + url: docs/reference/new-types/match-types.html + - title: Dependent Function Types + url: docs/reference/new-types/dependent-function-types.html + - title: Enums + subsection: + - title: Enumerations + url: docs/reference/enums/enums.html + - title: Algebraic Data Types + url: docs/reference/enums/adts.html + - title: Translation + url: docs/reference/enums/desugarEnums.html + - title: Contextual Abstractions + subsection: + - title: Overview + url: docs/reference/contextual/motivation.html + - title: Given Instances + url: docs/reference/contextual/givens.html + - title: Using Clauses + url: docs/reference/contextual/using-clauses.html + - title: Context Bounds + url: docs/reference/contextual/context-bounds.html + - title: Given Imports + url: docs/reference/contextual/given-imports.html + - title: Extension Methods + url: docs/reference/contextual/extension-methods.html + - title: Implementing Type classes + url: docs/reference/contextual/type-classes.html + - title: Type class Derivation + url: docs/reference/contextual/derivation.html + - title: Multiversal Equality + url: docs/reference/contextual/multiversal-equality.html + - title: Context Functions + url: docs/reference/contextual/context-functions.html + - title: Implicit Conversions + url: docs/reference/contextual/conversions.html + - title: By-Name Context Parameters + url: docs/reference/contextual/by-name-context-parameters.html + - title: Relationship with Scala 2 Implicits + url: docs/reference/contextual/relationship-implicits.html + - title: Metaprogramming + subsection: + - title: Overview + url: docs/reference/metaprogramming/toc.html + - title: Inline + url: docs/reference/metaprogramming/inline.html + - title: Macros + url: docs/reference/metaprogramming/macros.html + - title: Staging + url: docs/reference/metaprogramming/staging.html + - title: TASTy Reflection + url: docs/reference/metaprogramming/tasty-reflect.html + - title: TASTy Inspection + url: docs/reference/metaprogramming/tasty-inspect.html + - title: Other New Features + subsection: + - title: Trait Parameters + url: docs/reference/other-new-features/trait-parameters.html + - title: Super Traits + url: docs/reference/other-new-features/super-traits.html + - title: Creator Applications + url: docs/reference/other-new-features/creator-applications.html + - title: Export Clauses + url: docs/reference/other-new-features/export.html + - title: Opaque Type Aliases + url: docs/reference/other-new-features/opaques.html + - title: Open Classes + url: docs/reference/other-new-features/open-classes.html + - title: Parameter Untupling + url: docs/reference/other-new-features/parameter-untupling.html + - title: Kind Polymorphism + url: docs/reference/other-new-features/kind-polymorphism.html + - title: Tupled Function + url: docs/reference/other-new-features/tupled-function.html + - title: threadUnsafe Annotation + url: docs/reference/other-new-features/threadUnsafe-annotation.html + - title: New Control Syntax + url: docs/reference/other-new-features/control-syntax.html + - title: Optional Braces + url: docs/reference/other-new-features/indentation.html + - title: Explicit Nulls + url: docs/reference/other-new-features/explicit-nulls.html + - title: Safe Initialization + url: docs/reference/other-new-features/safe-initialization.html + - title: Other Changed Features + subsection: + - title: Numeric Literals + url: docs/reference/changed-features/numeric-literals.html + - title: Structural Types + url: docs/reference/changed-features/structural-types.html + - title: Operators + url: docs/reference/changed-features/operators.html + - title: Wildcard Types + url: docs/reference/changed-features/wildcards.html + - title: Type Checking + url: docs/reference/changed-features/type-checking.html + - title: Type Inference + url: docs/reference/changed-features/type-inference.html + - title: Implicit Resolution + url: docs/reference/changed-features/implicit-resolution.html + - title: Implicit Conversions + url: docs/reference/changed-features/implicit-conversions.html + - title: Overload Resolution + url: docs/reference/changed-features/overload-resolution.html + - title: Match Expressions + url: docs/reference/changed-features/match-syntax.html + - title: Vararg Patterns + url: docs/reference/changed-features/vararg-patterns.html + - title: Pattern Bindings + url: docs/reference/changed-features/pattern-bindings.html + - title: Pattern Matching + url: docs/reference/changed-features/pattern-matching.html + - title: Eta Expansion + url: docs/reference/changed-features/eta-expansion.html + - title: Compiler Plugins + url: docs/reference/changed-features/compiler-plugins.html + - title: Lazy Vals initialization + url: docs/reference/changed-features/lazy-vals-init.html + - title: Main Functions + url: docs/reference/changed-features/main-functions.html + - title: Dropped Features + subsection: + - title: DelayedInit + url: docs/reference/dropped-features/delayed-init.html + - title: Macros + url: docs/reference/dropped-features/macros.html + - title: Existential Types + url: docs/reference/dropped-features/existential-types.html + - title: Type Projection + url: docs/reference/dropped-features/type-projection.html + - title: Do-While + url: docs/reference/dropped-features/do-while.html + - title: Procedure Syntax + url: docs/reference/dropped-features/procedure-syntax.html + - title: Package Objects + url: docs/reference/dropped-features/package-objects.html + - title: Early Initializers + url: docs/reference/dropped-features/early-initializers.html + - title: Class Shadowing + url: docs/reference/dropped-features/class-shadowing.html + - title: Limit 22 + url: docs/reference/dropped-features/limit22.html + - title: XML literals + url: docs/reference/dropped-features/xml.html + - title: Symbol Literals + url: docs/reference/dropped-features/symlits.html + - title: Auto-Application + url: docs/reference/dropped-features/auto-apply.html + - title: Weak Conformance + url: docs/reference/dropped-features/weak-conformance.html + - title: Nonlocal Returns + url: docs/reference/dropped-features/nonlocal-returns.html + - title: "[this] Qualifier" + url: docs/reference/dropped-features/this-qualifier.html + - title: Contributing + subsection: + - title: Contribute Knowledge + url: docs/contributing/contribute-knowledge.html + - title: Getting Started + url: docs/contributing/getting-started.html + - title: Workflow + url: docs/contributing/workflow.html + - title: Testing + url: docs/contributing/testing.html + - title: Debugging + url: docs/contributing/debugging.html + - title: IDEs and Tools + subsection: + - title: Mill + url: docs/contributing/tools/mill.html + - title: Scalafix + url: docs/contributing/tools/scalafix.html + - title: Procedures + subsection: + - title: Release Model + url: docs/contributing/procedures/release.html + - title: Modifying the Test Framework + url: docs/contributing/procedures/vulpix.html + - title: Internals + subsection: + - title: Backend + url: docs/internals/backend.html + - title: Classpaths + url: docs/internals/classpaths.html + - title: Core Data Structrues + url: docs/internals/core-data-structures.html + - title: Contexts + url: docs/internals/contexts.html + - title: Dotc vs Scalac + url: docs/internals/dotc-scalac.html + - title: Higher-Kinded Types + url: docs/internals/higher-kinded-v2.html + - title: Overall Structure + url: docs/internals/overall-structure.html + - title: Periods + url: docs/internals/periods.html + - title: Syntax + url: docs/internals/syntax.html + - title: Type System + url: docs/internals/type-system.html + - title: "Dotty Internals 1: Trees & Symbols (Meeting Notes)" + url: docs/internals/dotty-internals-1-notes.html + - title: Debug Macros + url: docs/internals/debug-macros.html + - title: Resources + subsection: + - title: Talks + url: docs/resources/talks.html From 47b370ce9166db3c600456d7d312f6d99c749c5d Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Thu, 6 Aug 2020 17:26:48 +0200 Subject: [PATCH 050/181] Add command line api --- .github/workflows/CI.yaml | 5 +- .../scala/dotty/dokka/DottyDokkaConfig.scala | 11 +- .../scala/dotty/dokka/DottyDokkaPlugin.scala | 3 +- src/main/scala/dotty/dokka/Main.scala | 93 ++++++-- .../dotty/dokka/tasty/BasicSupport.scala | 2 + .../dotty/dokka/tasty/ClassLikeSupport.scala | 6 +- .../scala/dotty/dokka/tasty/TastyParser.scala | 24 +- .../dotty/dokka/tasty/TypesSupport.scala | 212 +++++++++--------- src/main/scala/tests/nested.scala | 9 + .../scala/dotty/dokka/DottyTestRunner.scala | 18 +- .../scala/dotty/dokka/SignatureTests.scala | 1 + 11 files changed, 241 insertions(+), 143 deletions(-) diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index c9c395e49c5d..a146bef2b9e4 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -33,7 +33,10 @@ jobs: run: sbt compile test - name: Generate test documentation - run: sbt generateExapleDocumentation + run: sbt generateSelfDocumentation + + - name: Generate documentation for dotty library + run: sbt generateDottyLibDocumentation - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 diff --git a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala index 4c9c3cf0f751..e0b59a8dd960 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaConfig.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaConfig.scala @@ -8,15 +8,18 @@ import collection.JavaConverters._ import dotty.tastydoc.representations._ case class DottyDokkaConfig(docConfiguration: DocConfiguration) extends DokkaConfiguration: - var _outputDir: String = new File("output").getAbsolutePath - override def getOutputDir: String = _outputDir + override def getOutputDir: String = docConfiguration.args.output.getAbsolutePath override def getCacheRoot: String = null override def getOfflineMode: Boolean = false override def getFailOnWarning: Boolean = false override def getSourceSets: JList[DokkaConfiguration.DokkaSourceSet] = List(mkSourceSet).asJava override def getModules: JList[DokkaConfiguration.DokkaModuleDescription] = List().asJava override def getPluginsClasspath: JList[File] = Nil.asJava - override def getPluginsConfiguration: JMap[String, String] = Map("dotty.dokka.DottyDokkaPlugin" -> "dottydoc").asJava + + override def getPluginsConfiguration: JMap[String, String] = Map( + "dotty.dokka.DottyDokkaPlugin" -> "dottydoc", + "ExternalDocsTooKey" -> docConfiguration.args.docsRoot.orNull + ).asJava def mkSourceSet: DokkaConfiguration.DokkaSourceSet = new DokkaSourceSetImpl( "main", @@ -26,7 +29,7 @@ case class DottyDokkaConfig(docConfiguration: DocConfiguration) extends DokkaCon Nil.asJava, Set().asJava, Nil.asJava, - List("output/BaseDocs.md").asJava, + Nil.asJava, true, /*includeRootPackage*/ false, false, /* changed because of exception in reportUndocumentedTransformer - there's 'when' which doesnt match because it contains only KotlinVisbility cases */ diff --git a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala index bf393cf5bc63..b5b2fa9a09c3 100644 --- a/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala +++ b/src/main/scala/dotty/dokka/DottyDokkaPlugin.scala @@ -16,13 +16,14 @@ import dotty.dokka.tasty.DokkaTastyInspector import org.jetbrains.dokka.base.transformers.pages.comments.CommentsToContentConverter import org.jetbrains.dokka.utilities.DokkaLogger import org.jetbrains.dokka.base.signatures.SignatureProvider +import org.jetbrains.dokka.pages._ class DottyDokkaPlugin extends JavaDokkaPlugin: override def createSourceToDocumentableTranslator(cxt: DokkaContext, sourceSet: SourceSetWrapper): DModule = cxt.getConfiguration match { case dottyConfig: DottyDokkaConfig => val inspector = DokkaTastyInspector(sourceSet, new MarkdownParser(null, null, cxt.getLogger), dottyConfig) - inspector.inspect(dottyConfig.docConfiguration.classpath, dottyConfig.docConfiguration.tastyFiles) + inspector.inspect(dottyConfig.docConfiguration.args.classpath, dottyConfig.docConfiguration.tastyFiles) new DModule( sourceSet.getSourceSet.getSourceSetID.getModuleName, diff --git a/src/main/scala/dotty/dokka/Main.scala b/src/main/scala/dotty/dokka/Main.scala index 5faf5e2b0c64..20c54453793c 100644 --- a/src/main/scala/dotty/dokka/Main.scala +++ b/src/main/scala/dotty/dokka/Main.scala @@ -12,26 +12,83 @@ import scala.tasty.Reflection import scala.tasty.inspector.TastyInspector import dotty.tastydoc.representations import dotty.tastydoc.representations._ +import sbt.io.IO +import java.nio.file.Files -case class DocConfiguration(tastyFiles: List[String], classpath: String) +import org.kohsuke.args4j.{CmdLineParser, Option => COption} -object Main: - def main(args: Array[String]): Unit = - // TODO #20 change the default to something more reasonable... - val cp = args.headOption.getOrElse("target/scala-0.26/classes") - def listTastyFiles(f: File): Seq[String] = - val (files, dirs) = f.listFiles().partition(_.isFile) - files.filter(_.getName.endsWith(".tasty")).map(_.toString) ++ dirs.flatMap(listTastyFiles) +class RawArgs: + @COption(name="--tastyRoots", required = true, aliases = Array("-t"), usage="Roots where tools should look for tasty files") + private var tastyRoots: String = null + + @COption(name="--output",required = true, aliases = Array("-o"), usage="Output to generate documentation to") + private var output: String = "output" + + @COption(name="--classpath", aliases = Array("--cp", "-c"), usage="Classpath to load depenecies from") + private var classpath: String = System.getProperty("java.class.path") + + + @COption(name="--docs", aliases = Array("-d"), usage="Root of project docs") + private var docsRoot: String = null - val config = DocConfiguration( - tastyFiles = - for - root <- cp.split(File.pathSeparatorChar).toList - tastyFile <- listTastyFiles(new File(root)) if tastyFile.contains("tests") || tastyFile.contains("example") - yield tastyFile, - classpath = System.getProperty("java.class.path") + @COption(name="--projectTitle") + private var projectTitle: String = null + + @COption(name="--projectVersion") + private var projectVersion: String = null + + @COption(name="--projectLogo") + private var projectLogo: String = null + + def toArgs = Args( + tastyRoots.split(File.pathSeparatorChar).toList.map(new File(_)), + classpath, + new File(output), + Option(docsRoot), + projectVersion, + Option(projectTitle), + Option(projectLogo) ) - // TODO #20 pass options, classpath etc. - new DokkaGenerator(new DottyDokkaConfig(config), DokkaConsoleLogger.INSTANCE).generate() - println("Done") +case class Args( + tastyRoots: Seq[File], + classpath: String, + output: File, + docsRoot: Option[String], + projectVersion: String, + projectTitle: Option[String], + projectLogo: Option[String] +) + +case class DocConfiguration(tastyFiles: List[String], args: Args) + +object Main: + def main(args: Array[String]): Unit = + val rawArgs = new RawArgs + new CmdLineParser(rawArgs).parseArgument(args:_*) + val parsedArgs = rawArgs.toArgs + + val (jars, dirs) = parsedArgs.tastyRoots.partition(_.isFile) + val extracted = jars.filter(_.exists()).map { jarFile => + val tempFile = Files.createTempDirectory("jar-unzipped").toFile + IO.unzip(jarFile, tempFile) + tempFile + } + + try + def listTastyFiles(f: File): Seq[String] = + val (files, dirs) = f.listFiles().partition(_.isFile) + files.filter(_.getName.endsWith(".tasty")).map(_.toString) ++ dirs.flatMap(listTastyFiles) + + val tastyFiles = (dirs ++ extracted).flatMap(listTastyFiles).toList + + val config = DocConfiguration(tastyFiles, parsedArgs) + + if (parsedArgs.output.exists()) IO.delete(parsedArgs.output) + + // TODO #20 pass options, classpath etc. + new DokkaGenerator(new DottyDokkaConfig(config), DokkaConsoleLogger.INSTANCE).generate() + + println("Done") + finally + extracted.foreach(IO.delete) diff --git a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala index 25f9123f0387..9f2e94c7119b 100644 --- a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala @@ -38,6 +38,8 @@ trait BasicSupport: Option.when(sym.flags.is(Flags.Override))(ScalaOnlyModifiers.Override), ).flatten + def shouldDocumentClasslike: Boolean = !isCompanionObject() && !sym.flags.is(Flags.Private) + def isCompanionObject(): Boolean = sym.flags.is(Flags.Object) && sym.companionClass.exists // TODO #22 make sure that DRIs are unique plus probably reuse semantic db code? diff --git a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala index 9599f11e45bf..2b1a5fbf603b 100644 --- a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala @@ -25,9 +25,9 @@ trait ClassLikeSupport: } val nested = classDef.body.collect { - case c: ClassDef if !c.symbol.isCompanionObject() => - parseClass(c) - } + case c: ClassDef if c.symbol.shouldDocumentClasslike => + processTree(c)(parseClass(c)) + }.flatten val flags = classDef.symbol.flags val kind = diff --git a/src/main/scala/dotty/dokka/tasty/TastyParser.scala b/src/main/scala/dotty/dokka/tasty/TastyParser.scala index 5876ffefd62e..f5d63a27bd78 100644 --- a/src/main/scala/dotty/dokka/tasty/TastyParser.scala +++ b/src/main/scala/dotty/dokka/tasty/TastyParser.scala @@ -30,23 +30,39 @@ case class TastyParser(reflect: Reflection, inspector: DokkaTastyInspector) def sourceSet = inspector.sourceSet + def processTree[T](tree: Tree)(op: => T): Option[T] = try Option(op) catch case e: Throwable => errorMsg(tree, tree.symbol.show, e) + def processSymbol[T](sym: Symbol)(op: => T): Option[T] = try Option(op) catch case e: Throwable => errorMsg(sym, sym.show, e) + + private def errorMsg[T](a: Any, m: => String, e: Throwable): Option[T] = + val msg = try m catch case e: Throwable => a.toString + println(s"ERROR: tree is faling: msg") + e.printStackTrace() + throw e + def parseRootTree(root: Tree): Seq[Documentable] = val docs = Seq.newBuilder[Documentable] object Traverser extends TreeTraverser: + var seen: List[Tree] = Nil + override def traverseTree(tree: Tree)(using ctx: Context): Unit = + seen = tree :: seen tree match { case pck: PackageClause => docs += parsePackage(pck) super.traverseTree(tree) case packageObject: ClassDef if(packageObject.symbol.name.contains("package$")) => docs += parsePackageObject(packageObject) - case clazz: ClassDef if(!clazz.symbol.isCompanionObject()) => + case clazz: ClassDef if clazz.symbol.shouldDocumentClasslike => docs += parseClass(clazz) - case _ => - super.traverseTree(tree) + case _ => } + seen = seen.tail + + try Traverser.traverseTree(root)(using reflect.rootContext) + catch case e: Throwable => + println(s"Problem parsing ${root.pos}, documentation may not be generated.") + e.printStackTrace() - Traverser.traverseTree(root)(using reflect.rootContext) docs.result() case class DokkaTastyInspector(sourceSet: SourceSetWrapper, parser: Parser, config: DottyDokkaConfig) extends TastyInspector: diff --git a/src/main/scala/dotty/dokka/tasty/TypesSupport.scala b/src/main/scala/dotty/dokka/tasty/TypesSupport.scala index 88dbcb1047c3..b63a790250a9 100644 --- a/src/main/scala/dotty/dokka/tasty/TypesSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/TypesSupport.scala @@ -16,14 +16,11 @@ trait TypesSupport: case term: Term => inner(term.tpe) new TypeConstructor(tpeTree.symbol.dri, data.asJava, FunctionModifiers.NONE) - + private def text(str: String): JProjection = new UnresolvedBound(str) private def texts(str: String): List[JProjection] = List(text(str)) - - private def noSupported(name: String): List[JProjection] = - println(s"WARN: Unsupported type: $name") - List(text(s"Unsupported[$name]")) + private def link(symbol: reflect.Symbol)(using cxt: reflect.Context): JProjection = new OtherParameter(symbol.dri, symbol.name) @@ -37,111 +34,116 @@ trait TypesSupport: tpeAnnotation.tpe.typeSymbol.toString == "class Repeated" // TODO #23 add support for all types signatures that makes sense - private def inner(tp: reflect.TypeOrBounds)(using cxt: reflect.Context): List[JProjection] = tp match - case OrType(left, right) => inner(left) ++ texts(" | ") ++ inner(right) - case AndType(left, right) => inner(left) ++ texts(" & ") ++ inner(right) - case ByNameType(tpe) => text("=> ") :: inner(tpe) - case ConstantType(constant) => - texts(constant.value match - case c: Char => s"'$c'" - case other => other.toString - ) - case ThisType(tpe) => inner(tpe) - case AnnotatedType(AppliedType(_, Seq(tpe)), annotation) if isRepeated(annotation) => - inner(tpe) :+ text("*") - case AnnotatedType(tpe, _) => - inner(tpe) - case tl @ TypeLambda(paramNames, paramTypes, resType) => noSupported(s"TypeLambda: ${paramNames} , ") //TOFIX - case Refinement(parent, name, info) => - // val tuple = convertTypeOrBoundsToReference(reflect)(info) match { - // case r if (info match {case info: TypeBounds => true case _ => false}) => ("type", name, r) - // case r@TypeReference(_, _, _, _) => ("val", name, r) - // case ByNameReference(rChild) => ("def", name, rChild) - // case r => throw new Exception("Match error in info of Refinement. This should not happen, please open an issue. " + r) - // } - // convertTypeToReference(reflect)(parent) match { - // case RefinedReference(p, ls) => - // RefinedReference(p, ls:+tuple) - // case t => RefinedReference(t, List(tuple)) - // } - noSupported("Refinement") - case AppliedType(tpe, typeOrBoundsList) => - if tpe.isFunctionType then - typeOrBoundsList match - case Nil => - Nil - case Seq(rtpe) => - text("() => ") :: inner(rtpe) - case Seq(arg, rtpe) => - inner(arg) ++ texts(" => ") ++ inner(rtpe) - case args => - texts("(") ++ commas(args.drop(1).map(inner)) ++ texts(") =>") ++ inner(args.last) - // else if (tpe.) // TODO support tuples here - else inner(tpe) ++ texts("[") ++ commas(typeOrBoundsList.map(inner)) ++ texts("]") + private def inner(tp: reflect.TypeOrBounds)(using cxt: reflect.Context): List[JProjection] = + def noSupported(name: String): List[JProjection] = + println(s"WARN: Unsupported type: $name: ${tp.show}") + List(text(s"Unsupported[$name]")) + + tp match + case OrType(left, right) => inner(left) ++ texts(" | ") ++ inner(right) + case AndType(left, right) => inner(left) ++ texts(" & ") ++ inner(right) + case ByNameType(tpe) => text("=> ") :: inner(tpe) + case ConstantType(constant) => + texts(constant.value match + case c: Char => s"'$c'" + case other => other.toString + ) + case ThisType(tpe) => inner(tpe) + case AnnotatedType(AppliedType(_, Seq(tpe)), annotation) if isRepeated(annotation) => + inner(tpe) :+ text("*") + case AnnotatedType(tpe, _) => + inner(tpe) + case tl @ TypeLambda(paramNames, paramTypes, resType) => noSupported(s"TypeLambda: ${paramNames} , ") //TOFIX + case Refinement(parent, name, info) => + // val tuple = convertTypeOrBoundsToReference(reflect)(info) match { + // case r if (info match {case info: TypeBounds => true case _ => false}) => ("type", name, r) + // case r@TypeReference(_, _, _, _) => ("val", name, r) + // case ByNameReference(rChild) => ("def", name, rChild) + // case r => throw new Exception("Match error in info of Refinement. This should not happen, please open an issue. " + r) + // } + // convertTypeToReference(reflect)(parent) match { + // case RefinedReference(p, ls) => + // RefinedReference(p, ls:+tuple) + // case t => RefinedReference(t, List(tuple)) + // } + noSupported("Refinement") + case AppliedType(tpe, typeOrBoundsList) => + if tpe.isFunctionType then + typeOrBoundsList match + case Nil => + Nil + case Seq(rtpe) => + text("() => ") :: inner(rtpe) + case Seq(arg, rtpe) => + inner(arg) ++ texts(" => ") ++ inner(rtpe) + case args => + texts("(") ++ commas(args.drop(1).map(inner)) ++ texts(") =>") ++ inner(args.last) + // else if (tpe.) // TODO support tuples here + else inner(tpe) ++ texts("[") ++ commas(typeOrBoundsList.map(inner)) ++ texts("]") - case tp @ TypeRef(qual, typeName) => - qual match { - case _: Type | _: NoPrefix => List(link(tp.typeSymbol)) - case other => noSupported(s"Type.qual: $other") - } - // convertTypeOrBoundsToReference(reflect)(qual) match { - // case TypeReference(label, link, xs, _) => TypeReference(typeName, link + "/" + label, xs, true) - // case EmptyReference => TypeReference(typeName, "", Nil, true) - // case _ if tp.typeSymbol.exists => - // tp.typeSymbol match { - // // NOTE: Only TypeRefs can reference ClassDefSymbols - // case sym if sym.isClassDef => //Need to be split because these types have their own file - // convertTypeOrBoundsToReference(reflect)(qual) match { - // case TypeReference(label, link, xs, _) => TypeReference(sym.name, link + "/" + label, xs, true) - // case EmptyReference if sym.name == "" | sym.name == "_root_" => EmptyReference - // case EmptyReference => TypeReference(sym.name, "", Nil, true) - // case _ => throw Exception("Match error in SymRef/TypeOrBounds/ClassDef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) - // } + case tp @ TypeRef(qual, typeName) => + qual match { + case _: Type | _: NoPrefix => List(link(tp.typeSymbol)) + case other => noSupported(s"Type.qual: $other") + } + // convertTypeOrBoundsToReference(reflect)(qual) match { + // case TypeReference(label, link, xs, _) => TypeReference(typeName, link + "/" + label, xs, true) + // case EmptyReference => TypeReference(typeName, "", Nil, true) + // case _ if tp.typeSymbol.exists => + // tp.typeSymbol match { + // // NOTE: Only TypeRefs can reference ClassDefSymbols + // case sym if sym.isClassDef => //Need to be split because these types have their own file + // convertTypeOrBoundsToReference(reflect)(qual) match { + // case TypeReference(label, link, xs, _) => TypeReference(sym.name, link + "/" + label, xs, true) + // case EmptyReference if sym.name == "" | sym.name == "_root_" => EmptyReference + // case EmptyReference => TypeReference(sym.name, "", Nil, true) + // case _ => throw Exception("Match error in SymRef/TypeOrBounds/ClassDef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) + // } - // // NOTE: This branch handles packages, which are now TypeRefs - // case sym if sym.isTerm || sym.isTypeDef => - // convertTypeOrBoundsToReference(reflect)(qual) match { - // case TypeReference(label, link, xs, _) => TypeReference(sym.name, link + "/" + label, xs) - // case EmptyReference if sym.name == "" | sym.name == "_root_" => EmptyReference - // case EmptyReference => TypeReference(sym.name, "", Nil) - // case _ => throw Exception("Match error in SymRef/TypeOrBounds/Other. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) - // } - // case sym => throw Exception("Match error in SymRef. This should not happen, please open an issue. " + sym) - // } - // case _ => - // throw Exception("Match error in TypeRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) - // } - case TermRef(qual, typeName) => - // convertTypeOrBoundsToReference(reflect)(qual) match { - // case TypeReference(label, link, xs, _) => TypeReference(typeName + "$", link + "/" + label, xs) - // case EmptyReference => TypeReference(typeName, "", Nil) - // case _ => throw Exception("Match error in TermRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) - // } - noSupported("TypeRef") + // // NOTE: This branch handles packages, which are now TypeRefs + // case sym if sym.isTerm || sym.isTypeDef => + // convertTypeOrBoundsToReference(reflect)(qual) match { + // case TypeReference(label, link, xs, _) => TypeReference(sym.name, link + "/" + label, xs) + // case EmptyReference if sym.name == "" | sym.name == "_root_" => EmptyReference + // case EmptyReference => TypeReference(sym.name, "", Nil) + // case _ => throw Exception("Match error in SymRef/TypeOrBounds/Other. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) + // } + // case sym => throw Exception("Match error in SymRef. This should not happen, please open an issue. " + sym) + // } + // case _ => + // throw Exception("Match error in TypeRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) + // } + case TermRef(qual, typeName) => + // convertTypeOrBoundsToReference(reflect)(qual) match { + // case TypeReference(label, link, xs, _) => TypeReference(typeName + "$", link + "/" + label, xs) + // case EmptyReference => TypeReference(typeName, "", Nil) + // case _ => throw Exception("Match error in TermRef. This should not happen, please open an issue. " + convertTypeOrBoundsToReference(reflect)(qual)) + // } + noSupported("TypeRef") - // NOTE: old SymRefs are now either TypeRefs or TermRefs - the logic here needs to be moved into above branches - // NOTE: _.symbol on *Ref returns its symbol - // case SymRef(symbol, typeOrBounds) => symbol match { - // } - // case _ => throw Exception("No match for type in conversion to Reference. This should not happen, please open an issue. " + tp) - case TypeBounds(low, hi) => - typeBound(low, low = true) ++ typeBound(low, low = false) - - case reflect.NoPrefix() => Nil + // NOTE: old SymRefs are now either TypeRefs or TermRefs - the logic here needs to be moved into above branches + // NOTE: _.symbol on *Ref returns its symbol + // case SymRef(symbol, typeOrBounds) => symbol match { + // } + // case _ => throw Exception("No match for type in conversion to Reference. This should not happen, please open an issue. " + tp) + case TypeBounds(low, hi) => + typeBound(low, low = true) ++ typeBound(low, low = false) + + case reflect.NoPrefix() => Nil - case MatchType(bond, sc, cases) => - def asCase(on: List[JProjection], ret: List[JProjection]) = texts(" case ") ++ on ++ texts(" => ") ++ ret ++ texts("\n") - val casesTexts = cases.flatMap { - case AppliedType(t, Seq(from, to)) if t == MatchCaseType => - asCase(inner(from), inner(to)) - case TypeLambda(paramNames, paramTypes, AppliedType(t, Seq(from, to))) if t == MatchCaseType => - asCase(inner(from), inner(to)) - } - inner(sc) ++ texts(" match {\n") ++ casesTexts ++ texts("}") - - case TypeIdent(t) => texts(t) + case MatchType(bond, sc, cases) => + def asCase(on: List[JProjection], ret: List[JProjection]) = texts(" case ") ++ on ++ texts(" => ") ++ ret ++ texts("\n") + val casesTexts = cases.flatMap { + case AppliedType(t, Seq(from, to)) if t == MatchCaseType => + asCase(inner(from), inner(to)) + case TypeLambda(paramNames, paramTypes, AppliedType(t, Seq(from, to))) if t == MatchCaseType => + asCase(inner(from), inner(to)) + } + inner(sc) ++ texts(" match {\n") ++ casesTexts ++ texts("}") + + case TypeIdent(t) => texts(t) - case ParamRef(TypeLambda(names, _, _), i) => texts(names.apply(i)) + case ParamRef(TypeLambda(names, _, _), i) => texts(names.apply(i)) private def typeBound(t: Type, low: Boolean) = val ignore = if(low) t.typeSymbol == defn.NothingClass else t.typeSymbol == defn.AnyClass diff --git a/src/main/scala/tests/nested.scala b/src/main/scala/tests/nested.scala index b82d2bff5d2e..2f5fe3931e95 100644 --- a/src/main/scala/tests/nested.scala +++ b/src/main/scala/tests/nested.scala @@ -47,4 +47,13 @@ object R class X { object Y +} + +// bug found in dotty code, still fails with type +sealed trait ErrorKind +object ErrorKind +{ + // This below produce some strange type + // case object Parser extends ErrorKind + // case object Typer extends ErrorKind } \ No newline at end of file diff --git a/src/test/scala/dotty/dokka/DottyTestRunner.scala b/src/test/scala/dotty/dokka/DottyTestRunner.scala index 0f7a8081d4ad..c28efc5736a6 100644 --- a/src/test/scala/dotty/dokka/DottyTestRunner.scala +++ b/src/test/scala/dotty/dokka/DottyTestRunner.scala @@ -27,6 +27,16 @@ abstract class DottyAbstractCoreTest extends AbstractCoreTest: folder.create() folder + private def args = Args( + tastyRoots = Nil , + classpath = System.getProperty("java.class.path"), + None, + output = getTempDir().getRoot, + projectVersion = "1.0", + projectTitle = None, + projectLogo = None + ) + def listPages(tastyDir: String): Seq[ContentPage] = var signatures: Seq[ContentPage] = Nil val tests = new AbstractCoreTest$TestBuilder() @@ -48,13 +58,7 @@ abstract class DottyAbstractCoreTest extends AbstractCoreTest: val tastyFiles = tastyDir.split(File.pathSeparatorChar).toList.flatMap(p => listTastyFiles(new File(p))).map(_.toString) - val config = new DottyDokkaConfig( - DocConfiguration( - tastyFiles = tastyFiles, - classpath = System.getProperty("java.class.path") - ) - ) - config._outputDir = getTempDir().getRoot.toPath.toAbsolutePath.toString + val config = new DottyDokkaConfig(DocConfiguration(tastyFiles, args)) DokkaTestGenerator( config, new TestLogger(DokkaConsoleLogger.INSTANCE), diff --git a/src/test/scala/dotty/dokka/SignatureTests.scala b/src/test/scala/dotty/dokka/SignatureTests.scala index 067606d4e5cc..1dd4f8dff3c7 100644 --- a/src/test/scala/dotty/dokka/SignatureTests.scala +++ b/src/test/scala/dotty/dokka/SignatureTests.scala @@ -26,6 +26,7 @@ class TypesSignatures extends SingleFileTest("typesSignatures", SingleFileTest.a class FieldsSignatures extends SingleFileTest("fieldsSignatures", SingleFileTest.all.filter(_ != "object")) class NestedSignatures extends SingleFileTest("nested", SingleFileTest.all) + class CompanionObjectSignatures extends SingleFileTest("companionObjectSignatures", SingleFileTest.all) class PackageSymbolSignatures extends SingleFileTest("packageSymbolSignatures", SingleFileTest.all) From 757e8937698a75909244a579c623169029e9d22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Mon, 10 Aug 2020 09:21:52 +0200 Subject: [PATCH 051/181] Fix for bug with non-excluding modifiers --- .../dotty/dokka/ScalaSignatureProvider.scala | 12 ++++++++++-- src/main/scala/dotty/dokka/scalaModel.scala | 16 ++++++++-------- .../scala/dotty/dokka/tasty/BasicSupport.scala | 6 +++--- src/main/scala/tests/classModifiers.scala | 12 ++++++++++++ .../scala/tests/classSignatureTestSource.scala | 3 +-- src/test/scala/dotty/dokka/SignatureTests.scala | 4 +++- 6 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 src/main/scala/tests/classModifiers.scala diff --git a/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala b/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala index c9306aafe031..2108f8290a2a 100644 --- a/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala +++ b/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala @@ -139,9 +139,16 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge val extras = t.getExtra.getMap() val additionalModifiers = Option(extras.get(AdditionalModifiers.Companion).asInstanceOf[AdditionalModifiers]) - val prefixes = additionalModifiers .map(_.getContent) - .map(content => content.defaultValue.asScala.map(_.getName)) + .map(content => content.defaultValue.asScala.collect{case s: ScalaOnlyModifiers => s}) + + val prefixes = additionalModifiers + .map(_.filter(_.prefix).map(_.getName)) + .map(modifiers => modifiers.toSeq.toSignatureString()) + .getOrElse("") + + val suffixes = additionalModifiers + .map(_.filter(!_.prefix).map(_.getName)) .map(modifiers => modifiers.toSeq.toSignatureString()) .getOrElse("") @@ -151,6 +158,7 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge prefixes.trim, t.getVisibility.defaultValue.getName, t.getModifier.defaultValue.getName, + suffixes.trim, kind ).toSignatureString() ) diff --git a/src/main/scala/dotty/dokka/scalaModel.scala b/src/main/scala/dotty/dokka/scalaModel.scala index b921e3ef9836..b21226a7e313 100644 --- a/src/main/scala/dotty/dokka/scalaModel.scala +++ b/src/main/scala/dotty/dokka/scalaModel.scala @@ -33,12 +33,14 @@ class BaseKey[T, V] extends ExtraProperty.Key[T, V]: override def mergeStrategyFor(left: V, right: V): MergeStrategy[T] = MergeStrategy.Remove.INSTANCE.asInstanceOf[MergeStrategy[T]] -enum ScalaOnlyModifiers(val name: String) extends ExtraModifiers(name, null): - case Implicit extends ScalaOnlyModifiers("implicit") - case Inline extends ScalaOnlyModifiers("inline") - case Lazy extends ScalaOnlyModifiers("lazy") - case Override extends ScalaOnlyModifiers("override") - case Erased extends ScalaOnlyModifiers("erased") +enum ScalaOnlyModifiers(val name: String, val prefix: Boolean) extends ExtraModifiers(name, null): + case Sealed extends ScalaOnlyModifiers("sealed", true) + case Case extends ScalaOnlyModifiers("case", false) + case Implicit extends ScalaOnlyModifiers("implicit", true) + case Inline extends ScalaOnlyModifiers("inline", true) + case Lazy extends ScalaOnlyModifiers("lazy", true) + case Override extends ScalaOnlyModifiers("override", true) + case Erased extends ScalaOnlyModifiers("erased", true) enum ScalaVisibility(val name: String) extends org.jetbrains.dokka.model.Visibility(name, null): case NoModifier extends ScalaVisibility("") @@ -46,8 +48,6 @@ enum ScalaVisibility(val name: String) extends org.jetbrains.dokka.model.Visibil case Private extends ScalaVisibility("private") enum ScalaModifier(val name: String) extends org.jetbrains.dokka.model.Modifier(name, null): - case Case extends ScalaModifier("case") case Abstract extends ScalaModifier("abstract") case Final extends ScalaModifier("final") - case Sealed extends ScalaModifier("sealed") case Empty extends ScalaModifier("") \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala index e622cc4e18b4..1b84433cc54b 100644 --- a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala @@ -49,19 +49,19 @@ class SymOps[R <: Reflection](val r: R) { else ScalaVisibility.NoModifier def getModifier(): ScalaModifier = - if (sym.flags.is(Flags.Case)) ScalaModifier.Case - else if (sym.flags.is(Flags.Abstract)) ScalaModifier.Abstract - else if (sym.flags.is(Flags.Sealed)) ScalaModifier.Sealed + if (sym.flags.is(Flags.Abstract)) ScalaModifier.Abstract else if (sym.flags.is(Flags.Final)) ScalaModifier.Final else ScalaModifier.Empty def getExtraModifiers(): Set[ScalaOnlyModifiers] = Set( + Option.when(sym.flags.is(Flags.Sealed))(ScalaOnlyModifiers.Sealed), Option.when(sym.flags.is(Flags.Erased))(ScalaOnlyModifiers.Erased), Option.when(sym.flags.is(Flags.Implicit))(ScalaOnlyModifiers.Implicit), Option.when(sym.flags.is(Flags.Inline))(ScalaOnlyModifiers.Inline), Option.when(sym.flags.is(Flags.Lazy))(ScalaOnlyModifiers.Lazy), Option.when(sym.flags.is(Flags.Override))(ScalaOnlyModifiers.Override), + Option.when(sym.flags.is(Flags.Case))(ScalaOnlyModifiers.Case) ).flatten def shouldDocumentClasslike: Boolean = !isCompanionObject() && !sym.flags.is(Flags.Private) diff --git a/src/main/scala/tests/classModifiers.scala b/src/main/scala/tests/classModifiers.scala new file mode 100644 index 000000000000..db3c15ddc39b --- /dev/null +++ b/src/main/scala/tests/classModifiers.scala @@ -0,0 +1,12 @@ +package tests + +package classModifiers + +sealed abstract class B + +abstract case class C(s: String) + +sealed case class D(c: String) + +final case class E(c: String) + diff --git a/src/main/scala/tests/classSignatureTestSource.scala b/src/main/scala/tests/classSignatureTestSource.scala index 36996c682a79..9ca8aa4e394d 100644 --- a/src/main/scala/tests/classSignatureTestSource.scala +++ b/src/main/scala/tests/classSignatureTestSource.scala @@ -45,8 +45,7 @@ object Documentation // TODO We do not see members from companions val valInsideDocObject = ??? } -sealed // TODO #23 support access and modifiers! -abstract class ClassExtendingDocumentation[T, A <: Int, B >: String, -X, +Y] extends Documentation[T, A, B, X, Y] +sealed abstract class ClassExtendingDocumentation[T, A <: Int, B >: String, -X, +Y] extends Documentation[T, A, B, X, Y] {} trait TraitTest diff --git a/src/test/scala/dotty/dokka/SignatureTests.scala b/src/test/scala/dotty/dokka/SignatureTests.scala index cefefdbab338..1661c7c43b07 100644 --- a/src/test/scala/dotty/dokka/SignatureTests.scala +++ b/src/test/scala/dotty/dokka/SignatureTests.scala @@ -35,4 +35,6 @@ class PackageObjectSymbolSignatures extends SingleFileTest("packageObjectSymbolS class MergedPackageSignatures extends MultipleFileTest(List("mergedPackage1", "mergedPackage2", "mergedPackage3"), List("mergedPackage"), SingleFileTest.all.filter(_ != "object")) -class ExtensionMethodSignature extends SingleFileTest("extensionMethodSignatures", SingleFileTest.all) \ No newline at end of file +class ExtensionMethodSignature extends SingleFileTest("extensionMethodSignatures", SingleFileTest.all) + +class ClassModifiers extends SingleFileTest("classModifiers", SingleFileTest.classlikeKinds) \ No newline at end of file From 0411d3513bf564163552db618164577bcd7b5a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Fri, 7 Aug 2020 15:45:10 +0200 Subject: [PATCH 052/181] Added grouping block. Extension grouping by extended symbol. Content modifying utils. --- .../scala/dotty/dokka/ScalaPageCreator.scala | 197 +++++++++++++++++- .../dotty/dokka/ScalaSignatureProvider.scala | 26 ++- src/main/scala/dotty/dokka/scalaModel.scala | 27 ++- .../dotty/dokka/tasty/ClassLikeSupport.scala | 30 ++- .../dotty/dokka/tasty/SyntheticSupport.scala | 8 +- src/main/scala/dotty/dokka/utils.scala | 51 ++++- .../tests/extensionMethodSignatures.scala | 29 ++- 7 files changed, 331 insertions(+), 37 deletions(-) diff --git a/src/main/scala/dotty/dokka/ScalaPageCreator.scala b/src/main/scala/dotty/dokka/ScalaPageCreator.scala index 716ca6a602e3..2a86731e9cc1 100644 --- a/src/main/scala/dotty/dokka/ScalaPageCreator.scala +++ b/src/main/scala/dotty/dokka/ScalaPageCreator.scala @@ -10,6 +10,10 @@ import org.jetbrains.dokka.pages._ import collection.JavaConverters._ import org.jetbrains.dokka.model.properties._ import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions +import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet +import org.jetbrains.dokka.base.resolvers.anchors._ + + class ScalaPageCreator( commentsToContentConverter: CommentsToContentConverter, @@ -99,14 +103,205 @@ class ScalaPageCreator( }) } + def insertCustomExtensionTab(clazz: DClass, defContent: ContentGroup): ContentGroup = { + val content = getContentGroupWithParents(defContent, p => p.getStyle.asScala.contains(ContentStyle.TabbedContent)) + val addedContent = PageContentBuilder(commentsToContentConverter, signatureProvider, logger).contentFor(clazz)(builder => { + groupingBlock( + builder, + "Extensions", + clazz.get(ClasslikeExtension).extensions.map(e => e.extendedSymbol -> e.extensions).sortBy(_._2.size), + (builder, receiver) => { + group(builder)(builder => { + builder.unaryPlus(builder.buildSignature(receiver)) + kotlin.Unit.INSTANCE + }) + }, + (builder, elem) => { + link(builder, elem.getName, elem.getDri)(kind = ContentKind.Main) + sourceSetDependentHint(builder)( builder => + { + contentForBrief(builder, elem) + builder.unaryPlus(builder.buildSignature(elem)) + kotlin.Unit.INSTANCE + }, + dri = Set(elem.getDri).asJava, + sourceSets = elem.getSourceSets, + kind = ContentKind.SourceSetDependentHint, + styles = Set().asJava + ) + kotlin.Unit.INSTANCE + } + )( + kind = ContentKind.Main, + sourceSets = builder.getMainSourcesetData.asScala.toSet, + styles = Set(), + extra = PropertyContainer.Companion.empty().plus(SimpleAttr.Companion.header("Extensions")), + false, + true, + Nil, + false, + true + ) + kotlin.Unit.INSTANCE + }) + val modifiedContent = content(0).copy( + (content(0).getChildren.asScala ++ List(addedContent)).asJava, + content(0).getDci, + content(0).getSourceSets, + content(0).getStyle, + content(0).getExtra + ) + modifyContentGroup(content, modifiedContent) + } + override def contentForClasslike(c: DClasslike): ContentGroup = { val defaultContent = super.contentForClasslike(c) c match{ case clazz: DClass => - insertCompanionObject(clazz, defaultContent) + val op1 = insertCompanionObject(clazz, defaultContent) + insertCustomExtensionTab(clazz, op1) case _ => defaultContent } } + private def modifyContentGroup(originalContentNodeWithParents: Seq[ContentGroup], modifiedContentNode: ContentGroup): ContentGroup = + originalContentNodeWithParents match { + case (head: ContentGroup) :: (tail: Seq[ContentGroup]) => tail match { + case (tailHead: ContentGroup) :: (tailTail: Seq[ContentGroup]) => + val newChildren = tailHead.getChildren.asScala.map(c => if c != head then c else modifiedContentNode) + modifyContentGroup( + tailTail, + tailHead.copy( + newChildren.asJava, + tailHead.getDci, + tailHead.getSourceSets, + tailHead.getStyle, + tailHead.getExtra + ) + ) + case _ => head + } + case _ => modifiedContentNode + } + + private def getContentGroupWithParents(root: ContentGroup, condition: ContentGroup => Boolean): Seq[ContentGroup] = { + def getFirstMatch(list: List[ContentNode]): Seq[ContentGroup] = list match { + case (head: ContentNode) :: (tail: List[ContentNode]) => head match { + case g: ContentGroup => + val res = getContentGroupWithParents(g, condition) + if(!res.isEmpty) res + else getFirstMatch(tail) + case _ => getFirstMatch(tail) + } + + case _ => Seq() + } + if(condition(root)) Seq(root) + else { + val res = getFirstMatch(root.getChildren.asScala.toList) + if(!res.isEmpty) res ++ Seq(root) + else Seq() + } + } + + private def groupingBlock[G, T <: Documentable]( + builder: PageContentBuilder#DocumentableContentBuilder, + name: String, + elements: List[T], + groupingFunc: T => G, + groupSplitterFunc: (PageContentBuilder#DocumentableContentBuilder, G) => Unit, + elementFunc: (PageContentBuilder#DocumentableContentBuilder, T) => Unit + )( + kind: Kind = ContentKind.Main, + sourceSets: Set[DokkaConfiguration$DokkaSourceSet] = builder.getMainSourcesetData.asScala.toSet, + styles: Set[Style] = builder.getMainStyles.asScala.toSet, + extra: PropertyContainer[ContentNode] = builder.getMainExtra, + renderWhenEmpty: Boolean = false, + needsSorting: Boolean = true, + headers: List[ContentGroup] = Nil, + needsAnchors: Boolean = false, + omitSplitterOnSingletons: Boolean = false + ): Unit = { + val grouped = elements.groupBy(groupingFunc).toList + groupingBlock( + builder, + name, + grouped, + groupSplitterFunc, + elementFunc + )( + kind, + sourceSets, + styles, + extra, + renderWhenEmpty, + needsSorting, + headers, + needsAnchors, + omitSplitterOnSingletons + ) + } + + private def groupingBlock[A, T <: Documentable, G <: List[(A, List[T])]]( + builder: PageContentBuilder#DocumentableContentBuilder, + name: String, + elements: G, + groupSplitterFunc: (PageContentBuilder#DocumentableContentBuilder, A) => Unit, + elementFunc: (PageContentBuilder#DocumentableContentBuilder, T) => Unit + )( + kind: Kind, + sourceSets: Set[DokkaConfiguration$DokkaSourceSet], + styles: Set[Style], + extra: PropertyContainer[ContentNode], + renderWhenEmpty: Boolean, + needsSorting: Boolean, + headers: List[ContentGroup], + needsAnchors: Boolean, + omitSplitterOnSingletons: Boolean + ): Unit = if (renderWhenEmpty || !elements.isEmpty) { + header(builder, 3, name)(kind = kind) + group(builder)(builder => + { + elements.foreach((a, elems) => { + if(elems.size > 1 || !omitSplitterOnSingletons) groupSplitterFunc(builder, a) + builder.unaryPlus( + ContentTable( + headers.asJava, + (if(needsSorting) then elems.sortBy(_.getName) else elems) + .map( elem => { + //TODO: There's problem with using extra property containers from Dokka in Scala + //val newExtra = if(needsAnchors) then extra.plus(SymbolAnchorHint) else extra + val newExtra = extra + builder.buildGroup(Set(elem.getDri).asJava, elem.getSourceSets, kind, styles.asJava, newExtra, bdr => { + elementFunc(bdr, elem) + kotlin.Unit.INSTANCE + }) + }).asJava, + DCI(builder.getMainDRI, kind), + sourceSets.asJava, styles.asJava, extra + ) + ) + }) + kotlin.Unit.INSTANCE + }, + styles = Set(ContentStyle.WithExtraAttributes), + extra = extra + ) + } + + private def contentForBrief(builder: PageContentBuilder#DocumentableContentBuilder, d: Documentable) = d.getSourceSets.asScala.foreach( ss => + d.getDocumentation.asScala.toMap.get(ss).flatMap(_.getChildren.asScala.headOption).map(_.getRoot).map( dt => + group(builder)(builder => + { + builder.comment(dt, ContentKind.Comment, builder.getMainSourcesetData, builder.getMainStyles, builder.getMainExtra) + kotlin.Unit.INSTANCE + }, + sourceSets = Set(ss), + kind = ContentKind.BriefComment + ) + ) + ) + + } \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala b/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala index 2108f8290a2a..2b70a52a5195 100644 --- a/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala +++ b/src/main/scala/dotty/dokka/ScalaSignatureProvider.scala @@ -23,7 +23,7 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge tokens.filter(_.trim.nonEmpty).mkString(""," "," ") override def signature(documentable: Documentable) = documentable match { - case extension: DFunction if extension.get(MethodExtension).isExtension => + case extension: DFunction if extension.get(MethodExtension).extensionInfo.isDefined => List(extensionSignature(extension)).asJava case method: DFunction => List(methodSignature(method)).asJava @@ -61,16 +61,21 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge private def extensionSignature(extension: DFunction): ContentNode = content(extension){ builder => - utils.annotationsBlock(builder, extension) - builder.modifiersAndVisibility(extension, "def") + val grouped = extension.get(MethodExtension).extensionInfo.map(_.isGrouped).getOrElse(false) val extendedSymbol = if (extension.isRightAssociative()) { extension.getParameters.asScala(extension.get(MethodExtension).parametersListSizes(0)) } else { extension.getParameters.asScala(0) } - builder.addText(s"(${extendedSymbol.getName}: ") - builder.typeSignature(extendedSymbol.getType) - builder.addText(").") + + utils.annotationsBlock(builder, extension) + if(!grouped){ + builder.addText("extension ") + builder.addText(s" (${extendedSymbol.getName}: ") + builder.typeSignature(extendedSymbol.getType) + builder.addText(") ") + } + builder.modifiersAndVisibility(extension, "def") builder.addLink(extension.getName, extension.getDri) builder.generics(extension) builder.functionParameters(extension) @@ -122,10 +127,17 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge } private def parameterSignature(parameter: DParameter): ContentNode = + val ext = parameter.get(ParameterExtension) content(parameter){ builder => + if(ext.isGrouped){ + builder.addText("extension (") + } else { + builder.addText("(") + } builder.addText(parameter.getName) builder.addText(": ") builder.typeSignature(parameter.getType) + builder.addText(")") } extension on(f: DFunction): @@ -188,7 +200,7 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge paramLists.foldLeft(0){ (from, size) => val toIndex = from + size if from == toIndex then builder.addText("()") - else if !methodExtension.isExtension || from != receiverPos then + else if !methodExtension.extensionInfo.isDefined || from != receiverPos then builder.addList(method.getParameters.subList(from, toIndex), "(", ")"){ param => utils.annotationsInline(builder, param) // builder.addText("TODO modifiers") diff --git a/src/main/scala/dotty/dokka/scalaModel.scala b/src/main/scala/dotty/dokka/scalaModel.scala index b21226a7e313..a3ec19dedad9 100644 --- a/src/main/scala/dotty/dokka/scalaModel.scala +++ b/src/main/scala/dotty/dokka/scalaModel.scala @@ -6,19 +6,34 @@ import collection.JavaConverters._ import org.jetbrains.dokka.links._ import org.jetbrains.dokka.model.doc._ import org.jetbrains.dokka.model.properties._ + +case class ExtensionInformation(val isGrouped: Boolean) -case class MethodExtension(parametersListSizes: Seq[Int], isExtension: Boolean) extends ExtraProperty[DFunction]: +case class MethodExtension(parametersListSizes: Seq[Int], extensionInfo: Option[ExtensionInformation]) extends ExtraProperty[DFunction]: override def getKey = MethodExtension object MethodExtension extends BaseKey[DFunction, MethodExtension] +case class ParameterExtension(isExtendedSymbol: Boolean, isGrouped: Boolean) extends ExtraProperty[DParameter]: + override def getKey = ParameterExtension + +object ParameterExtension extends BaseKey[DParameter, ParameterExtension] + enum Kind(val name: String){ case Class extends Kind("class") case Object extends Kind("object") case Trait extends Kind("trait") } -case class ClasslikeExtension(parentTypes: List[Bound], constructor: Option[DFunction], kind: Kind, companion: Option[DClasslike]) extends ExtraProperty[DClasslike]: +case class ExtensionGroup(val extendedSymbol: DParameter, val extensions: List[DFunction]) + +case class ClasslikeExtension( + parentTypes: List[Bound], + constructor: Option[DFunction], + kind: Kind, + companion: Option[DClasslike], + extensions: List[ExtensionGroup] +) extends ExtraProperty[DClasslike]: override def getKey = ClasslikeExtension object ClasslikeExtension extends BaseKey[DClasslike, ClasslikeExtension] @@ -50,4 +65,10 @@ enum ScalaVisibility(val name: String) extends org.jetbrains.dokka.model.Visibil enum ScalaModifier(val name: String) extends org.jetbrains.dokka.model.Modifier(name, null): case Abstract extends ScalaModifier("abstract") case Final extends ScalaModifier("final") - case Empty extends ScalaModifier("") \ No newline at end of file + case Empty extends ScalaModifier("") + +extension (f: DFunction): + def isRightAssociative(): Boolean = f.getName.endsWith(":") + def getExtendedSymbol(): Option[DParameter] = Option.when(f.get(MethodExtension).extensionInfo.isDefined)( + f.getParameters.asScala(if f.isRightAssociative() then f.get(MethodExtension).parametersListSizes(0) else 0) + ) diff --git a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala index 790431a43675..e868b768181b 100644 --- a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala @@ -21,12 +21,20 @@ trait ClassLikeSupport: val (extensions, methods) = classDef.symbol.classMethods.filterNot(isSyntheticFunc).partition(isExtensionMethod(_)) - val parsedExtensions = extensions - .map(parseMethod(_, isExtension = true)) + + val parsedExtensions = extensions.map(e => (getExtendedSymbol(e).get, e) ).groupBy{ + case (arg, e) => arg.symbol.pos + }.map{ + case (pos, list) => if(list.size == 1) { + ExtensionGroup(parseArgument(list(0)._1, _ => "", true, false), List(parseMethod(list(0)._2, extInfo = Some(ExtensionInformation(false))))) + } else { + ExtensionGroup(parseArgument(list(0)._1, _ => "", true, true), list.map(f => parseMethod(f._2, extInfo = Some(ExtensionInformation(true))))) + } + }.toList val constuctors = classDef.body.collect { case d: DefDef if d.name == "" && classDef.constructor.symbol != d.symbol => - parseMethod(d.symbol, isExtension = false) + parseMethod(d.symbol) } val nested = classDef.body.collect { @@ -50,7 +58,7 @@ trait ClassLikeSupport: val constructorMethod = if kind == Kind.Object then None - else Some(parseMethod(classDef.constructor.symbol, constructorWithoutParamLists(classDef), paramMod, isExtension = false)) + else Some(parseMethod(classDef.constructor.symbol, constructorWithoutParamLists(classDef), paramMod)) val typeParams = classDef.body.collect { case targ: TypeDef => targ }.filter(_.symbol.isTypeParam) @@ -76,7 +84,7 @@ trait ClassLikeSupport: classDef.symbol.dri, name, /*constuctors =*/ constuctors.asJava, - /*methods =*/ methods.map(parseMethod(_, isExtension = false)).asJava, + /*methods =*/ methods.map(parseMethod(_)).asJava, /*fields =*/ (typeDefs.map(parseTypeDef) ++ valDefs.map(parseValDef)).asJava, /*nested =*/ nested.asJava, /*sources =*/ classDef.symbol.source, @@ -89,16 +97,15 @@ trait ClassLikeSupport: /*modifier =*/ sourceSet.asMap(modifier), inspector.sourceSet.toSet, PropertyContainer.Companion.empty() - .plus(ClasslikeExtension(parents, constructorMethod, kind, companion)) + .plus(ClasslikeExtension(parents, constructorMethod, kind, companion, parsedExtensions)) .plus(AdditionalModifiers(sourceSet.asMap(classDef.symbol.getExtraModifiers().asJava))) - .plus(CallableExtensions(parsedExtensions.toSet.asJava)) ) - def parseMethod(methodSymbol: Symbol, emptyParamsList: Boolean = false, paramPrefix: Symbol => String = _ => "", isExtension: Boolean): DFunction = + def parseMethod(methodSymbol: Symbol, emptyParamsList: Boolean = false, paramPrefix: Symbol => String = _ => "", extInfo: Option[ExtensionInformation] = None): DFunction = val method = methodSymbol.tree.asInstanceOf[DefDef] val paramLists = if emptyParamsList then Nil else method.paramss val genericTypes = if (methodSymbol.isClassConstructor) Nil else method.typeParams - val name = if methodSymbol.isClassConstructor then "this" else if isExtension then methodSymbol.name.stripPrefix("extension_") else methodSymbol.name + val name = if methodSymbol.isClassConstructor then "this" else if extInfo.isDefined then methodSymbol.name.stripPrefix("extension_") else methodSymbol.name new DFunction( methodSymbol.dri, @@ -115,11 +122,11 @@ trait ClassLikeSupport: /*modifier =*/ sourceSet.asMap(methodSymbol.getModifier()), sourceSet.toSet(), PropertyContainer.Companion.empty() - plus MethodExtension(paramLists.map(_.size), isExtension) + plus MethodExtension(paramLists.map(_.size), extInfo) plus AdditionalModifiers(sourceSet.asMap(methodSymbol.getExtraModifiers().asJava)) ) - def parseArgument(argument: ValDef, prefix: Symbol => String): DParameter = + def parseArgument(argument: ValDef, prefix: Symbol => String, isExtendedSymbol: Boolean = false, isGrouped: Boolean = false): DParameter = new DParameter( argument.symbol.dri, prefix(argument.symbol) + argument.symbol.name, @@ -128,6 +135,7 @@ trait ClassLikeSupport: argument.tpt.dokkaType, sourceSet.toSet(), PropertyContainer.Companion.empty() + .plus(ParameterExtension(isExtendedSymbol, isGrouped)) ) def parseTypeArgument(argument: TypeDef): DTypeParameter = diff --git a/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala b/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala index 724b5933d50a..15153529dca7 100644 --- a/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala @@ -33,4 +33,10 @@ trait SyntheticsSupport: given dotc.core.Contexts.Context = r.rootContext.asInstanceOf val sym = rsym.asInstanceOf[dotc.core.Symbols.Symbol] sym.is(dotc.core.Flags.Extension) - } \ No newline at end of file + } + + def getExtendedSymbol(d: Symbol): Option[ValDef] = + Option.when(hackIsExtension(self.reflect)(d))( + if(d.name.endsWith(":")) d.tree.asInstanceOf[DefDef].paramss(1)(0) + else d.tree.asInstanceOf[DefDef].paramss(0)(0) + ) \ No newline at end of file diff --git a/src/main/scala/dotty/dokka/utils.scala b/src/main/scala/dotty/dokka/utils.scala index e29d6af16a26..832d21e3f11e 100644 --- a/src/main/scala/dotty/dokka/utils.scala +++ b/src/main/scala/dotty/dokka/utils.scala @@ -35,12 +35,12 @@ extension on (builder: PageContentBuilder): /* Need to do it this way, because Dotty seems to not support named parameters of extensions and I couldn't change kind */ def group(builder: PageContentBuilder#DocumentableContentBuilder)( func: Function1[PageContentBuilder#DocumentableContentBuilder, kotlin.Unit], - dri: JSet[DRI] = builder.getMainDRI, - sourceSets: JSet[DokkaConfiguration$DokkaSourceSet] = builder.getMainSourcesetData, + dri: Set[DRI] = builder.getMainDRI.asScala.toSet, + sourceSets: Set[DokkaConfiguration$DokkaSourceSet] = builder.getMainSourcesetData.asScala.toSet, kind: Kind = ContentKind.Main, - styles: JSet[Style] = builder.getMainStyles, + styles: Set[Style] = builder.getMainStyles.asScala.toSet, extra: PropertyContainer[ContentNode] = builder.getMainExtra -): Unit = builder.group(dri, sourceSets, kind, styles, extra, a => func(a)) +): Unit = builder.group(dri.asJava, sourceSets.asJava, kind, styles.asJava, extra, a => func(a)) def sourceSetDependentHint(builder: PageContentBuilder#DocumentableContentBuilder)( func: Function1[PageContentBuilder#DocumentableContentBuilder, kotlin.Unit], @@ -51,6 +51,49 @@ def sourceSetDependentHint(builder: PageContentBuilder#DocumentableContentBuilde extra: PropertyContainer[ContentNode] = builder.getMainExtra ): Unit = builder.sourceSetDependentHint(dri, sourceSets, kind, styles, extra, a => func(a)) +def header(builder: PageContentBuilder#DocumentableContentBuilder, level: Int, text: String)( + func: Function1[PageContentBuilder#DocumentableContentBuilder, kotlin.Unit] = builder => kotlin.Unit.INSTANCE, + dri: JSet[DRI] = builder.getMainDRI, + sourceSets: JSet[DokkaConfiguration$DokkaSourceSet] = builder.getMainSourcesetData, + kind: Kind = ContentKind.Main, + styles: JSet[Style] = builder.getMainStyles, + extra: PropertyContainer[ContentNode] = builder.getMainExtra +): Unit = builder.header(level, text, kind, sourceSets, styles, extra, a => func(a)) + +def text(builder: PageContentBuilder#DocumentableContentBuilder, text: String)( + sourceSets: JSet[DokkaConfiguration$DokkaSourceSet] = builder.getMainSourcesetData, + kind: Kind = ContentKind.Main, + styles: JSet[Style] = builder.getMainStyles, + extra: PropertyContainer[ContentNode] = builder.getMainExtra +) = builder.text(text, kind, sourceSets, styles, extra) + +def link(builder: PageContentBuilder#DocumentableContentBuilder, text: String, address: DRI)( + kind: Kind = ContentKind.Main, + sourceSets: Set[DokkaConfiguration$DokkaSourceSet] = builder.getMainSourcesetData.asScala.toSet, + styles: Set[Style] = builder.getMainStyles.asScala.toSet, + extra: PropertyContainer[ContentNode] = builder.getMainExtra +) = { + builder.unaryPlus(linkNode(builder, text, address)(sourceSets = sourceSets, styles = styles, extra = extra)) +} + +def linkNode( + builder: PageContentBuilder#DocumentableContentBuilder, + text: String, + address: DRI +)( + kind: Kind = ContentKind.Main, + sourceSets: Set[DokkaConfiguration$DokkaSourceSet] = builder.getMainSourcesetData.asScala.toSet, + styles: Set[Style] = builder.getMainStyles.asScala.toSet, + extra: PropertyContainer[ContentNode] = builder.getMainExtra +) = ContentDRILink( + List(ContentText(text, DCI(builder.getMainDRI, kind), sourceSets.asJava, styles.asJava, extra)).asJava, + address, + DCI(builder.getMainDRI, kind), + sourceSets.asJava, + styles.asJava, + extra + ) + extension on(builder: PageContentBuilder$DocumentableContentBuilder): def addText(str: String) = builder.text(str, ContentKind.Main, builder.getMainSourcesetData, builder.getMainStyles, builder.getMainExtra) diff --git a/src/main/scala/tests/extensionMethodSignatures.scala b/src/main/scala/tests/extensionMethodSignatures.scala index 427ac68f4ee8..c0a45aa78622 100644 --- a/src/main/scala/tests/extensionMethodSignatures.scala +++ b/src/main/scala/tests/extensionMethodSignatures.scala @@ -6,21 +6,30 @@ class ClassOne // Commented cases won't work for now // extension ClassTwoOps on (c: ClassTwo): // def getA() = c.a - - def (c: ClassTwo).getB(): String - = c.b + extension (c: ClassTwo) def getB(): String + = c.b - def (c: ClassTwo).getGivenParams(a: Int, b: Int, d: Int)(e: String): Int + extension (c: ClassTwo) def getGivenParams(a: Int, b: Int, d: Int)(e: String): Int = 56 - def (c: ClassTwo).|||:(a: Int, b: Int, d: Int)(e: String): Int + extension (c: ClassTwo) def |||:(a: Int, b: Int, d: Int)(e: String): Int = 56 - // extension (c:ClassTwo): - // def getString() - // = c.toString() - // def getInt() - // = 5 + extension (b: Int) def secondGroup(): String + = ??? + extension (c:ClassTwo) + : + def getString(a: String): String + = a + + def getInt(): Int + = 5 + + extension (s: String) + def someMethod(): String + = ??? + def otherMethod(a: Int): Int + = ??? } case class ClassTwo(a: String, b: String) From d64138f0c8054934c5e93aaf67e2c0c825d2bb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Mon, 10 Aug 2020 11:12:59 +0200 Subject: [PATCH 053/181] Companion rendering refactor --- .../scala/dotty/dokka/ScalaPageCreator.scala | 58 +++++++++---------- src/main/scala/dotty/dokka/scalaModel.scala | 2 +- .../dotty/dokka/tasty/BasicSupport.scala | 2 +- .../dotty/dokka/tasty/ClassLikeSupport.scala | 13 ++--- .../dotty/dokka/tasty/SyntheticSupport.scala | 6 +- 5 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/main/scala/dotty/dokka/ScalaPageCreator.scala b/src/main/scala/dotty/dokka/ScalaPageCreator.scala index 2a86731e9cc1..02a16b92b004 100644 --- a/src/main/scala/dotty/dokka/ScalaPageCreator.scala +++ b/src/main/scala/dotty/dokka/ScalaPageCreator.scala @@ -12,6 +12,7 @@ import org.jetbrains.dokka.model.properties._ import org.jetbrains.dokka.base.transformers.documentables.CallableExtensions import org.jetbrains.dokka.DokkaConfiguration$DokkaSourceSet import org.jetbrains.dokka.base.resolvers.anchors._ +import org.jetbrains.dokka.links._ @@ -22,24 +23,15 @@ class ScalaPageCreator( ) extends DefaultPageCreator(commentsToContentConverter, signatureProvider, logger) { override def pageForClasslike(c: DClasslike): ClasslikePageNode = { val res = super.pageForClasslike(c) - def addCompanionObjectPage(co: DClasslike, defContent: ClasslikePageNode): ClasslikePageNode = { - val page = pageForClasslike(co) - defContent.modified( - defContent.getName, - defContent.getContent, - defContent.getDri, - defContent.getEmbeddedResources, - (defContent.getChildren.asScala ++ List( - page.modified( - page.getName + "$", - page.getContent, - page.getDri, - page.getEmbeddedResources, - page.getChildren - ) - )).asJava - ) - } + + def renameCompanionObjectPage(objectPage: ClasslikePageNode): ClasslikePageNode = objectPage + .modified( + objectPage.getName + "$", + objectPage.getContent, + objectPage.getDri, + objectPage.getEmbeddedResources, + objectPage.getChildren + ) def addExtensionMethodPages(clazz: DClass, defContent: ClasslikePageNode): ClasslikePageNode = { val extensionPages = clazz.getExtra.getMap.asScala.values @@ -68,19 +60,27 @@ class ScalaPageCreator( c match { case clazz: DClass => - val op1 = clazz.get(ClasslikeExtension).companion.fold(res)(addCompanionObjectPage(_, res)) - val op2 = addExtensionMethodPages(clazz, op1) - op2 + val op1 = addExtensionMethodPages(clazz, res) + val ext = clazz.get(ClasslikeExtension) + if(ext.kind == dotty.dokka.Kind.Object && ext.companion.isDefined) renameCompanionObjectPage(op1) + else op1 case _ => res } } - def insertCompanionObject(clazz: DClass, defContent: ContentGroup): ContentGroup = { - def companionObjectContent(co: DClasslike): Function1[PageContentBuilder#DocumentableContentBuilder, kotlin.Unit] = builder => { + def insertCompanion(clazz: DClass, defContent: ContentGroup): ContentGroup = { + def companionContent(co: DRI): Function1[PageContentBuilder#DocumentableContentBuilder, kotlin.Unit] = builder => { group(builder)(builder => { sourceSetDependentHint(builder)( builder => { - builder.unaryPlus(builder.buildSignature(co)) + group(builder)(builder => { + text(builder, "Companion ")() + clazz.get(ClasslikeExtension).kind match { + case dotty.dokka.Kind.Object => link(builder, "class", co)() + case _ => link(builder, "object", co)() + } + kotlin.Unit.INSTANCE + }, kind = ContentKind.Symbol) kotlin.Unit.INSTANCE } ) @@ -91,7 +91,7 @@ class ScalaPageCreator( } clazz.get(ClasslikeExtension).companion.fold(defContent)(co => { - val addedContent = PageContentBuilder(commentsToContentConverter, signatureProvider, logger).contentFor(clazz)(companionObjectContent(co)) + val addedContent = PageContentBuilder(commentsToContentConverter, signatureProvider, logger).contentFor(clazz)(companionContent(co)) val newChildren = List(defContent.getChildren.asScala.head) ++ List(addedContent) ++ defContent.getChildren.asScala.tail ContentGroup( newChildren.asJava, @@ -159,7 +159,7 @@ class ScalaPageCreator( c match{ case clazz: DClass => - val op1 = insertCompanionObject(clazz, defaultContent) + val op1 = insertCompanion(clazz, defaultContent) insertCustomExtensionTab(clazz, op1) case _ => defaultContent } @@ -167,8 +167,8 @@ class ScalaPageCreator( private def modifyContentGroup(originalContentNodeWithParents: Seq[ContentGroup], modifiedContentNode: ContentGroup): ContentGroup = originalContentNodeWithParents match { - case (head: ContentGroup) :: (tail: Seq[ContentGroup]) => tail match { - case (tailHead: ContentGroup) :: (tailTail: Seq[ContentGroup]) => + case head :: tail => tail match { + case tailHead :: tailTail => val newChildren = tailHead.getChildren.asScala.map(c => if c != head then c else modifiedContentNode) modifyContentGroup( tailTail, @@ -187,7 +187,7 @@ class ScalaPageCreator( private def getContentGroupWithParents(root: ContentGroup, condition: ContentGroup => Boolean): Seq[ContentGroup] = { def getFirstMatch(list: List[ContentNode]): Seq[ContentGroup] = list match { - case (head: ContentNode) :: (tail: List[ContentNode]) => head match { + case head :: tail => head match { case g: ContentGroup => val res = getContentGroupWithParents(g, condition) if(!res.isEmpty) res diff --git a/src/main/scala/dotty/dokka/scalaModel.scala b/src/main/scala/dotty/dokka/scalaModel.scala index a3ec19dedad9..cb0cc4fa8942 100644 --- a/src/main/scala/dotty/dokka/scalaModel.scala +++ b/src/main/scala/dotty/dokka/scalaModel.scala @@ -31,7 +31,7 @@ case class ClasslikeExtension( parentTypes: List[Bound], constructor: Option[DFunction], kind: Kind, - companion: Option[DClasslike], + companion: Option[DRI], extensions: List[ExtensionGroup] ) extends ExtraProperty[DClasslike]: override def getKey = ClasslikeExtension diff --git a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala index 1b84433cc54b..46d3e824e871 100644 --- a/src/main/scala/dotty/dokka/tasty/BasicSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/BasicSupport.scala @@ -64,7 +64,7 @@ class SymOps[R <: Reflection](val r: R) { Option.when(sym.flags.is(Flags.Case))(ScalaOnlyModifiers.Case) ).flatten - def shouldDocumentClasslike: Boolean = !isCompanionObject() && !sym.flags.is(Flags.Private) + def shouldDocumentClasslike: Boolean = !sym.flags.is(Flags.Private) && !sym.flags.is(Flags.Synthetic) def isCompanionObject(): Boolean = sym.flags.is(Flags.Object) && sym.companionClass.exists diff --git a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala index e868b768181b..d772d4fa944a 100644 --- a/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/ClassLikeSupport.scala @@ -26,9 +26,9 @@ trait ClassLikeSupport: case (arg, e) => arg.symbol.pos }.map{ case (pos, list) => if(list.size == 1) { - ExtensionGroup(parseArgument(list(0)._1, _ => "", true, false), List(parseMethod(list(0)._2, extInfo = Some(ExtensionInformation(false))))) + ExtensionGroup(parseArgument(list(0)(0), _ => "", true, false), List(parseMethod(list(0)(1), extInfo = Some(ExtensionInformation(false))))) } else { - ExtensionGroup(parseArgument(list(0)._1, _ => "", true, true), list.map(f => parseMethod(f._2, extInfo = Some(ExtensionInformation(true))))) + ExtensionGroup(parseArgument(list(0)(0), _ => "", true, true), list.map(f => parseMethod(f(1), extInfo = Some(ExtensionInformation(true))))) } }.toList @@ -70,15 +70,10 @@ trait ClassLikeSupport: val valDefs = classDef.body.collect { case td: ValDef if !isSyntheticField(td.symbol, classDef) => td} - val companion = kind match { - case Kind.Object => None - case _ => - Some(classDef.symbol.companionClass) + val companion = Some(classDef.symbol.companionClass) .filter(_.exists) .filter(!_.flags.is(Flags.Synthetic)) - .map(_.tree.asInstanceOf[ClassDef]) - .map(parseClass(_)) - } + .map(_.dri) new DClass( classDef.symbol.dri, diff --git a/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala b/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala index 15153529dca7..3aee8bff04c7 100644 --- a/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala @@ -35,8 +35,10 @@ trait SyntheticsSupport: sym.is(dotc.core.Flags.Extension) } + def hackIsLeftAssoc(d: Symbol): Boolean = !d.name.endsWith(":") + def getExtendedSymbol(d: Symbol): Option[ValDef] = Option.when(hackIsExtension(self.reflect)(d))( - if(d.name.endsWith(":")) d.tree.asInstanceOf[DefDef].paramss(1)(0) - else d.tree.asInstanceOf[DefDef].paramss(0)(0) + if(hackIsLeftAssoc(d)) d.tree.asInstanceOf[DefDef].paramss(0)(0) + else d.tree.asInstanceOf[DefDef].paramss(1)(0) ) \ No newline at end of file From a9a5750251b542d97dfb63583ca3ca34838c415a Mon Sep 17 00:00:00 2001 From: Krzysztof Romanwoski Date: Fri, 7 Aug 2020 12:01:51 +0200 Subject: [PATCH 054/181] Move match type case to sythetic support --- .../scala/dotty/dokka/tasty/SyntheticSupport.scala | 12 +++++++++++- src/main/scala/dotty/dokka/tasty/TypesSupport.scala | 7 ++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala b/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala index 3aee8bff04c7..cb26ff8b3245 100644 --- a/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/SyntheticSupport.scala @@ -41,4 +41,14 @@ trait SyntheticsSupport: Option.when(hackIsExtension(self.reflect)(d))( if(hackIsLeftAssoc(d)) d.tree.asInstanceOf[DefDef].paramss(0)(0) else d.tree.asInstanceOf[DefDef].paramss(1)(0) - ) \ No newline at end of file + ) + + object MatchTypeCase: + def unapply(tpe: Type): Option[(TypeOrBounds, TypeOrBounds)] = + tpe match + case AppliedType(t, Seq(from, to)) if t == MatchCaseType => + Some((from, to)) + case TypeLambda(paramNames, paramTypes, AppliedType(t, Seq(from, to))) if t == MatchCaseType => + Some((from, to)) + case _ => + None diff --git a/src/main/scala/dotty/dokka/tasty/TypesSupport.scala b/src/main/scala/dotty/dokka/tasty/TypesSupport.scala index b63a790250a9..0c4d67350056 100644 --- a/src/main/scala/dotty/dokka/tasty/TypesSupport.scala +++ b/src/main/scala/dotty/dokka/tasty/TypesSupport.scala @@ -132,12 +132,9 @@ trait TypesSupport: case reflect.NoPrefix() => Nil case MatchType(bond, sc, cases) => - def asCase(on: List[JProjection], ret: List[JProjection]) = texts(" case ") ++ on ++ texts(" => ") ++ ret ++ texts("\n") val casesTexts = cases.flatMap { - case AppliedType(t, Seq(from, to)) if t == MatchCaseType => - asCase(inner(from), inner(to)) - case TypeLambda(paramNames, paramTypes, AppliedType(t, Seq(from, to))) if t == MatchCaseType => - asCase(inner(from), inner(to)) + case MatchTypeCase(from, to) => + texts(" case ") ++ inner(from) ++ texts(" => ") ++ inner(to) ++ texts("\n") } inner(sc) ++ texts(" match {\n") ++ casesTexts ++ texts("}") From 5c89624f44df0b84e9c6afd740f75cacb1bac463 Mon Sep 17 00:00:00 2001 From: Krzysztof Romanowski Date: Sat, 8 Aug 2020 02:37:38 +0200 Subject: [PATCH 055/181] Prepare dotty-dokka to document itelf Add action to publish documentation from each build on master to gh-pages Add support for rendering index documents Add seleton documentation --- .github/workflows/CI.yaml | 16 +- build.sbt | 5 +- documentation/docs/index.md | 3 + documentation/docs/static-page/index.md | 3 + documentation/docs/why-dokka.md | 7 + documentation/index.md | 24 +++ .../virtuslab/dokka/site/StaticSitePlugin.kt | 4 + .../virtuslab/dokka/site/locationProvider.kt | 23 ++ .../com/virtuslab/dokka/site/processors.kt | 112 +++++++--- .../com/virtuslab/dokka/site/renderer.kt | 51 ++++- .../com/virtuslab/dokka/site/templates.kt | 6 +- dotty-docs/docs/_includes/features.html | 123 ----------- .../docs/_includes/getting-started.html | 28 --- dotty-docs/docs/_includes/logo-page.html | 43 ---- .../docs/_includes/table-of-contents.html | 15 -- dotty-docs/docs/_layouts/main.html | 8 - dotty-docs/docs/images/dotty-logo-white.svg | 30 +++ dotty-docs/docs/images/dotty-logo.svg | 30 +++ dotty-docs/docs/images/scala-logo copy.svg | 13 ++ dotty-docs/docs/images/scala-logo-white.svg | 13 ++ dotty-docs/docs/index.html | 204 +++++++++++++++++- libs/dokkaJavaApi-0.1.0.jar | Bin 80812 -> 106390 bytes .../resources/dotty_res/styles/scalastyle.css | 7 + src/main/scala/dotty/dokka/Main.scala | 58 ++--- 24 files changed, 539 insertions(+), 287 deletions(-) create mode 100644 documentation/docs/index.md create mode 100644 documentation/docs/static-page/index.md create mode 100644 documentation/docs/why-dokka.md create mode 100644 documentation/index.md create mode 100644 dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/locationProvider.kt delete mode 100644 dotty-docs/docs/_includes/features.html delete mode 100644 dotty-docs/docs/_includes/getting-started.html delete mode 100644 dotty-docs/docs/_includes/logo-page.html delete mode 100644 dotty-docs/docs/_includes/table-of-contents.html create mode 100644 dotty-docs/docs/images/dotty-logo-white.svg create mode 100644 dotty-docs/docs/images/dotty-logo.svg create mode 100644 dotty-docs/docs/images/scala-logo copy.svg create mode 100644 dotty-docs/docs/images/scala-logo-white.svg diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index a146bef2b9e4..f8d73b731fbd 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -1,4 +1,4 @@ -name: CI for context buddy +name: CI for dotty-dokka on: push: @@ -8,7 +8,7 @@ on: jobs: build: runs-on: ubuntu-latest - timeout-minutes: 10 + timeout-minutes: 20 steps: - uses: actions/checkout@v2 - run: git fetch --prune --unshallow --tags @@ -51,4 +51,16 @@ jobs: aws s3 rm $dest aws s3 sync output $dest + - name: Update gh-pages + run: | + if [ $GITHUB_REF = "refs/heads/master" ]; then + git config --global user.email "$(git log -1 --format=%ae)" + git config --global user.name "$(git log -1 --format=%an)" + git subtree add --prefix=our-site origin gh-pages + rm -r our-site/* + cp -r output/self/* our-site + git add our-site + git commit -m "$(git log -1 --pretty=%B)" + git subtree push --prefix=our-site origin gh-pages + fi diff --git a/build.sbt b/build.sbt index 0ca369de8f3a..bdd227d84e00 100644 --- a/build.sbt +++ b/build.sbt @@ -43,13 +43,13 @@ buildDokkaApi := { val generateSelfDocumentation = inputKey[Unit]("Generate example documentation") generateSelfDocumentation := { - run.in(Compile).fullInput(" -o output/self -t target/scala-0.26/classes").evaluated // TODO #35 proper sbt integration + run.in(Compile).fullInput(" -o output/self -t target/scala-0.26/classes -d documentation").evaluated // TODO #35 proper sbt integration } unmanagedJars in Compile += dokkaJavaApiJar // Uncomment to debug dokka processing (require to run debug in listen mode on 5005 port) -// javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5005,suspend=y" +//javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5005,suspend=y" fork.in(run) := true // There is a bug in dokka that prevents parallel tests withing the same jvm @@ -58,6 +58,7 @@ Test / parallelExecution := false scalacOptions in Compile += "-language:implicitConversions" + // TODO #35 proper sbt integration val generateDottyLibDocumentation = taskKey[Unit]("Generate documentation for dotty lib") generateDottyLibDocumentation := Def.taskDyn { diff --git a/documentation/docs/index.md b/documentation/docs/index.md new file mode 100644 index 000000000000..796998e3fbc6 --- /dev/null +++ b/documentation/docs/index.md @@ -0,0 +1,3 @@ +## Documentation for our docs + +Will create docs here! \ No newline at end of file diff --git a/documentation/docs/static-page/index.md b/documentation/docs/static-page/index.md new file mode 100644 index 000000000000..c17e49e6cdf4 --- /dev/null +++ b/documentation/docs/static-page/index.md @@ -0,0 +1,3 @@ +## Static page + +TBD \ No newline at end of file diff --git a/documentation/docs/why-dokka.md b/documentation/docs/why-dokka.md new file mode 100644 index 000000000000..cf54d07ccdf0 --- /dev/null +++ b/documentation/docs/why-dokka.md @@ -0,0 +1,7 @@ +--- +title: Why dokka? +--- + +# Why dokka? + +It works. \ No newline at end of file diff --git a/documentation/index.md b/documentation/index.md new file mode 100644 index 000000000000..069e017982ac --- /dev/null +++ b/documentation/index.md @@ -0,0 +1,24 @@ +# Dotty-dokka + +**Documentation tool for Scala 3** + +We are using [TASTY](https://github.com/lampepfl/dotty/blob/master/tasty/src/dotty/tools/tasty/TastyFormat.scala) to generate documentation. We aim to has all known and loved feature from scaladoc as well as new feature such as : + +- integrated documentation and API +- has option for basic pluggablity +- and much more + +**Yes, this page was generated using dotty-dokka** + +You can learn more from out [documentation](main/index.html). + +## Getting started + +For now the recommended way to try out our project would be: + - Clone our [repository](https://github.com/Virtuslab/dotty-dokka) + - Run `sbt main -o -t -cp ` where + - ``: location where documentation should be created + - ``: is list of dirs or jars that contains tasty files that should be documented + - ``: classpath that was used to generate tasty files + + We also support `-d ` argument to provide static documentation. You can find more about that feature [here](static-page.html). diff --git a/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/StaticSitePlugin.kt b/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/StaticSitePlugin.kt index a8cf766a7c30..5f7e4d92f9fd 100644 --- a/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/StaticSitePlugin.kt +++ b/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/StaticSitePlugin.kt @@ -30,4 +30,8 @@ class StaticSitePlugin: DokkaPlugin() { providing { ctx -> ExternalDocsToolRenderer(ctx) } override dokkaBase.htmlRenderer) } + + val locationProvider by extending { + dokkaBase.locationProviderFactory providing ::StaticSiteLocationProviderFactory override dokkaBase.locationProvider + } } \ No newline at end of file diff --git a/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/locationProvider.kt b/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/locationProvider.kt new file mode 100644 index 000000000000..c64f74db6323 --- /dev/null +++ b/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/locationProvider.kt @@ -0,0 +1,23 @@ +package dokka.java.api.com.virtuslab.dokka.site + +import org.jetbrains.dokka.base.resolvers.local.DefaultLocationProvider +import org.jetbrains.dokka.base.resolvers.local.LocationProvider +import org.jetbrains.dokka.base.resolvers.local.LocationProviderFactory +import org.jetbrains.dokka.pages.ContentPage +import org.jetbrains.dokka.pages.PageNode +import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.plugability.DokkaContext + +class StaticSiteLocationProviderFactory(val ctx: DokkaContext) : LocationProviderFactory { + override fun getLocationProvider(pageNode: RootPageNode): LocationProvider { + return StaticSiteLocationProvider(ctx, pageNode) + } +} + +class StaticSiteLocationProvider(ctx: DokkaContext, pageNode: RootPageNode): DefaultLocationProvider(pageNode, ctx) { + override fun pathTo(node: PageNode, context: PageNode?): String = + if (node is BaseStaticSiteProcessor.DocPageNode && node.dri.contains(docsRootDRI)) + "index" + else + super.pathTo(node, context) +} \ No newline at end of file diff --git a/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/processors.kt b/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/processors.kt index 68164f186235..570be5a0b42d 100644 --- a/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/processors.kt +++ b/dokkaJavaApi/src/main/kotlin/com/virtuslab/dokka/site/processors.kt @@ -1,9 +1,11 @@ package dokka.java.api.com.virtuslab.dokka.site +import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.base.renderers.html.NavigationNode import org.jetbrains.dokka.base.renderers.html.NavigationPage import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.Documentable +import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.pages.PageTransformer @@ -11,8 +13,18 @@ import java.io.File const val ExternalDocsTooKey = "ExternalDocsTooKey" -interface SelfRendered { - fun htmlText(): String +val docsRootDRI = DRI.topLevel.copy(extra = "_top_level_index") + +data class PreRenderedContent( + val html: String, + override val dci: DCI, + override val sourceSets: Set, + override val style: Set