Skip to content

Add dottydoc #1453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 100 commits into from
Aug 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
8d8d87b
Add project and impl for initial barebones dottydoc
felixmulder Apr 11, 2016
1b20568
Port cooking of strings from NSC
felixmulder Apr 13, 2016
9d4df20
Add module member lookup
felixmulder Apr 15, 2016
6bd4969
Fix compilation for multiple sources
felixmulder Apr 15, 2016
36e63e8
Add summary comment, cleanup
felixmulder Apr 15, 2016
fb6c152
Add command alias for dottydoc
felixmulder Apr 15, 2016
980a662
Minify css
felixmulder Apr 15, 2016
02a12f9
Improve layout with search and replace confusing Packages title
felixmulder Apr 25, 2016
2de658d
Add the scaladoc CLI args that make sense for dottydoc
felixmulder Apr 25, 2016
887759e
Add recursive CLI args, move other doc args
felixmulder Apr 26, 2016
46ac1bf
Fix package list links
felixmulder Apr 26, 2016
32b4a9c
Add initial return values to members - to be updated
felixmulder Apr 27, 2016
b480bd1
Fix packages not ending up in `packages` map in Phases.scala
felixmulder Apr 28, 2016
cbc05e0
Move dynamically generated content to JVM side
felixmulder Apr 29, 2016
80a9077
Move member rendering back to client (for event listeners)
felixmulder Apr 29, 2016
db659dc
Split implementation to internal mutable and external interface
felixmulder May 3, 2016
0fb1058
Filter out companion objects from package-view
felixmulder May 3, 2016
86f816d
Add companions to package view w ability to choose between them
felixmulder May 3, 2016
53fc2c0
Adjust font configuration for finalized package view
felixmulder May 3, 2016
cb42a04
Filter out ProductX when X > 3 in package view
felixmulder May 4, 2016
80b027f
Break out commentCache to CommentParser
felixmulder May 4, 2016
60b5dc3
Better prints while documenting packages
felixmulder May 4, 2016
5c5d54a
Parse comments only from root packages (which contain all entities su…
felixmulder May 4, 2016
b4622aa
Fix root-package finding in comment-parser
felixmulder May 5, 2016
29cf43b
Add JUnit test structure for testing the DocPhase
felixmulder May 5, 2016
0020302
Add test for checking if Array has documentation after compiling std lib
felixmulder May 5, 2016
bc594c8
Add test for simple comment
felixmulder May 5, 2016
8e39b71
Fix repeated traversal of packages when generating docs (5x speedup)
felixmulder May 5, 2016
07e4ae2
Replace "$plus" with "+" in webview
felixmulder May 5, 2016
3ecc86c
Fix linking (do not remove parent linking!)
felixmulder May 5, 2016
73bfb73
Cosmetic updates
felixmulder May 5, 2016
cb4d93c
Filter out `AnyValCompanion` trait
felixmulder May 5, 2016
2010a93
Move name filtering to AST build in Phase.scala
felixmulder May 6, 2016
f084357
Add implicit method `flat` to `Entity`
felixmulder May 6, 2016
0bfdc91
Fix #7, "immutable" package mistaken for "Immutable" trait
felixmulder May 10, 2016
bcc7585
Add setting for output dir
felixmulder May 10, 2016
926a81c
Add option `-Ydoc-output` for specifying output dir
felixmulder May 11, 2016
59055f2
Add basic member-lookup for result types
felixmulder May 30, 2016
23465a3
Improve return value filtering
felixmulder May 31, 2016
4b99e29
Change package serialization to go straight to JSON
felixmulder May 31, 2016
79133f9
Add interface for interacting with serialized case classes on frontend
felixmulder May 31, 2016
dccfb5b
Remove parent from fields since it is not serialized
felixmulder May 31, 2016
756861e
Add first steps to implementing search
felixmulder May 31, 2016
a099344
Add basic implementation of toplevel entity search
felixmulder Jun 1, 2016
0912727
Add type parameters to rendered entity
felixmulder Jun 10, 2016
34590e7
Add parameter-lists (text-only)
felixmulder Jun 13, 2016
ffcf17a
Change function definition to be span based for better granularity
felixmulder Jun 13, 2016
8294dd0
Add type parameters to classes
felixmulder Jun 13, 2016
76bbb8d
Add supertypes to class, cc, obj and trait
felixmulder Jun 13, 2016
82752b2
Fix value classes not being documented
felixmulder Jun 13, 2016
fdb82c9
Remove `filteredName` method in favor for `decode`
felixmulder Jun 13, 2016
c6a7446
Implement structure allowing lookup of higher-kinded types
felixmulder Jun 14, 2016
cedbb78
Complete proper structure for return types
felixmulder Jun 22, 2016
a727637
Fix proper structure for paramlist links (clientside)
felixmulder Jun 22, 2016
d451f90
Add implicitly added methods to entity documentation
felixmulder Jun 23, 2016
f1c88d7
Add implicitly added values as well
felixmulder Jun 23, 2016
76413f0
Cleanup return types and type parameters from dollar signs
felixmulder Jun 24, 2016
81a86be
Materialize parameter list references
felixmulder Jun 25, 2016
c80af6a
Introduce DocMiniPhase concept, fused phases
felixmulder Jun 28, 2016
7fbda93
Rename AddImplicitsPhase to DocImplicitsPhase
felixmulder Jun 28, 2016
8615072
Rename `XTypeLinkers` to `LinkXTypes` - because the amount of linker …
felixmulder Jun 28, 2016
8e5159f
Rename `cclassTransformation` to `caseClassTransformation`
felixmulder Jun 28, 2016
d5b0014
Remove dependency on pickling library, make frontend use façade
felixmulder Jun 29, 2016
9bd6101
Remove spray-json dependency
felixmulder Jul 4, 2016
5e88fe3
Move frontend code to JS project - only kicker left in JVM project
felixmulder Jul 4, 2016
7d8dade
Implement by name in parameter lists
felixmulder Jul 11, 2016
61169c0
Add warning message on UnsetLink in doc-ui
felixmulder Jul 11, 2016
00ea4fc
Rebase dottydoc over new HK scheme
felixmulder Jul 16, 2016
a284cad
Change TypeReference#paramLinks' type from `MaterializableLink` to `R…
felixmulder Jul 19, 2016
fe1ff8f
Fix #28: render functions passed as arguments
felixmulder Jul 19, 2016
7d8458f
Add support for repeated parameters in producer
felixmulder Jul 20, 2016
354a67c
Render repeated parameters correctly in client
felixmulder Jul 20, 2016
3efdb93
Add support for rendering tuples idiomatically
felixmulder Jul 20, 2016
58b83ce
Render idiomatic tuples in client
felixmulder Jul 20, 2016
c1b57e9
Correctly parse tuples, functions and applied types like `Map[K,V]` f…
felixmulder Jul 20, 2016
5d6c15f
Handle all types of references when linking
felixmulder Jul 20, 2016
c05d628
Change from absolute name to type name in link names
felixmulder Jul 20, 2016
c53c115
Add indication that paramList takes implicit arguments
felixmulder Jul 20, 2016
a1c73e9
Define special handling of infix types like "<:<" and "=:="
felixmulder Jul 20, 2016
c4ec1b6
Sort members when serializing to JSON
felixmulder Jul 20, 2016
87ecca2
Add a SortMembers phase to sort the members instead of doing it when …
felixmulder Jul 20, 2016
553f9b2
Remove shared directory - nothing shared anymore
felixmulder Jul 20, 2016
98b61dd
Fix #25: move doc related structures to `DocBase`
felixmulder Aug 2, 2016
94dd0bc
Get docstring from overriden symbol if not present on the overriding …
felixmulder Aug 2, 2016
922788a
Add info on where implicitly added members originate from
felixmulder Aug 6, 2016
5fdc353
Fix phase fusion for subpackages, fix links in implicitly added methods
felixmulder Aug 7, 2016
20fda57
Fix type params of classes, traits defs, which broke after new HK scheme
felixmulder Aug 7, 2016
079e3db
Implement annotation parsing like CommentFactoryBase from nsc
felixmulder Aug 8, 2016
5cd1d51
Remove client from dottydoc - no more Scala.JS deps!
felixmulder Aug 9, 2016
0d89be8
Add `currentEntity` to templating API
felixmulder Aug 9, 2016
b1defa0
Add scaladoc interface stub
felixmulder Aug 10, 2016
a252074
Implement bridge that generates json on `doc` command
felixmulder Aug 11, 2016
bd77519
Implement working docs requiring manually specifying resources and te…
felixmulder Aug 11, 2016
d6b5c3e
Implement dotty bridge for doc
felixmulder Aug 15, 2016
abf1632
Add documentation to dottydoc API
felixmulder Aug 15, 2016
0a9003d
Move client test to client repo
felixmulder Aug 15, 2016
9879b90
Add snapshots resolver
felixmulder Aug 15, 2016
59c6c0d
Properly materialize supertype links
felixmulder Aug 17, 2016
d8c02ec
Add `ImplicitlyAddedEntity` as a common trait for implicitly added me…
felixmulder Aug 17, 2016
0b69be6
Add phase to deal with constructors
felixmulder Aug 19, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*.DS_Store
*.class
*.log
*.swp
*~
*.swp

Expand Down Expand Up @@ -37,6 +38,7 @@ scala-scala

# Ignore output files but keep the directory
out/
build/
!out/.keep

# Ignore build-file
Expand Down
72 changes: 72 additions & 0 deletions bridge/src/main/scala/xsbt/ScaladocInterface.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* sbt -- Simple Build Tool
* Copyright 2008, 2009 Mark Harrah
*/
package xsbt

import xsbti.Logger
import dotty.tools.dottydoc.api.scala.Dottydoc
import java.net.URL

class ScaladocInterface {
def run(args: Array[String], log: Logger, delegate: xsbti.Reporter) =
(new DottydocRunner(args, log, delegate)).run()
}

class DottydocRunner(args: Array[String], log: Logger, delegate: xsbti.Reporter) extends Dottydoc {
def run(): Unit = getOutputFolder(args).map { outputFolder =>
val index = createIndex(args)
val resources = getResources(args)
val template = getTemplate(resources)

template.fold(writeJson(index, outputFolder)) { tpl =>
buildDocs(outputFolder, tpl, resources, index)
}
} getOrElse {
delegate.log(
NoPosition,
"No output folder set for API documentation (\"-d\" parameter should be passed to the documentation tool)",
xsbti.Severity.Error
)
}

private[this] val NoPosition = new xsbti.Position {
val line = xsbti.Maybe.nothing[Integer]
val lineContent = ""
val offset = xsbti.Maybe.nothing[Integer]
val sourcePath = xsbti.Maybe.nothing[String]
val sourceFile = xsbti.Maybe.nothing[java.io.File]
val pointer = xsbti.Maybe.nothing[Integer]
val pointerSpace = xsbti.Maybe.nothing[String]
}

private def getStringSetting(name: String): Option[String] =
args find (_.startsWith(name)) map (_.drop(name.length))

private def getOutputFolder(args: Array[String]): Option[String] =
args sliding(2) find { case Array(x, _) => x == "-d" } map (_.tail.head.trim)

private def getTemplate(resources: List[URL]): Option[URL] =
resources.find(_.getFile.endsWith("template.html"))

private def getResources(args: Array[String]): List[URL] = {
val cp = args sliding (2) find { case Array(x, _) => x == "-classpath" } map (_.tail.head.trim) getOrElse ""

cp.split(":").find(_.endsWith("dottydoc-client.jar")).map { resourceJar =>
import java.util.jar.JarFile
val jarEntries = (new JarFile(resourceJar)).entries
var entries: List[URL] = Nil

while (jarEntries.hasMoreElements) {
val entry = jarEntries.nextElement()

if (!entry.isDirectory()) {
val path = s"jar:file:$resourceJar!/${entry.getName}"
val url = new URL(path)
entries = url :: entries
}
}

entries
} getOrElse (Nil)
}
}
79 changes: 79 additions & 0 deletions dottydoc/src/dotty/tools/dottydoc/DottyDoc.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package dotty.tools
package dottydoc

import core._
import core.transform._
import dotc.config.CompilerCommand
import dotc.config.Printers.dottydoc
import dotc.core.Contexts._
import dotc.core.Phases.Phase
import dotc.typer.FrontEnd
import dotc.{ CompilationUnit, Compiler, Driver, Run }
import io.PlainFile
import model.Package
import model.json._

import _root_.java.util.{ Map => JMap }

/** Custom Compiler with phases for the documentation tool
*
* The idea here is to structure `dottydoc` around the new infrastructure. As
* such, dottydoc will itself be a compiler. It will, however, produce a format
* that can be used by other tools or web-browsers.
*
* Example:
* 1. Use the existing FrontEnd to typecheck the code being fed to dottydoc
* 2. Create an AST that is serializable
* 3. Serialize to JS object
*/
class DocCompiler extends Compiler {
override def phases: List[List[Phase]] = List(
List(new DocFrontEnd),
List(new DocImplicitsPhase),
List(new DocASTPhase),
List(DocMiniTransformations(new LinkReturnTypes,
new LinkParamListTypes,
new LinkImplicitlyAddedTypes,
new LinkSuperTypes,
new AlternateConstructors,
new SortMembers))
)
}

class DocFrontEnd extends FrontEnd {
override protected def discardAfterTyper(unit: CompilationUnit)(implicit ctx: Context) =
unit.isJava
}

abstract class DocDriver extends Driver {
import scala.collection.JavaConverters._

override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = {
val ctx = rootCtx.fresh
val summary = CompilerCommand.distill(args)(ctx)

ctx.setSettings(summary.sstate)
ctx.setSetting(ctx.settings.YkeepComments, true)

val fileNames = CompilerCommand.checkUsage(summary, sourcesRequired)(ctx)
(fileNames, ctx)
}

override def newCompiler(implicit ctx: Context): Compiler = new DocCompiler

def compiledDocs(args: Array[String]): collection.Map[String, Package] = {
val (fileNames, ctx) = setup(args, initCtx.fresh)
doCompile(newCompiler(ctx), fileNames)(ctx)

ctx.docbase.packages[Package]
}

def compiledDocsJava(args: Array[String]): JMap[String, Package] =
compiledDocs(args).asJava

def indexToJson(index: collection.Map[String, Package]): String =
index.json

def indexToJsonJava(index: JMap[String, Package]): String =
indexToJson(index.asScala)
}
63 changes: 63 additions & 0 deletions dottydoc/src/dotty/tools/dottydoc/api/java/Dottydoc.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package dotty.tools.dottydoc.api.java;

import dotty.tools.dottydoc.DocDriver;
import dotty.tools.dottydoc.model.Package;
import dotty.tools.dottydoc.util.OutputWriter;
import java.util.Map;
import java.util.List;
import java.net.URL;

/**
* The Dottydoc API is fairly simple. The tool creates an index by calling:
* "createIndex" with the same argument list as you would the compiler - e.g:
*
* {{{
* String[] array = {
* "-language:Scala2"
* };
*
* Map<String, Package> index = createIndex(array);
* }}}
*
* Once the index has been generated, the tool can also build a documentation
* API given a Mustache template and a flat resources structure (i.e. absolute
* paths to each resource, which will be put in the same directory).
*
* {{{
* buildDocs("path/to/output/dir", templateURL, resources, index);
* }}}
*
* The tool can also generate JSON from the created index using "toJson(index)"
* or directly using "createJsonIndex"
*/
public class Dottydoc extends DocDriver {

/** Creates index from compiler arguments */
public Map<String, Package> createIndex(String[] args) {
return compiledDocsJava(args);
}

/** Creates JSON from compiler arguments */
public String createJsonIndex(String[] args) {
return indexToJsonJava(createIndex(args));
}

public String toJson(Map<String, Package> index) {
return indexToJsonJava(index);
}

/** Creates a documentation from the given parameters */
public void buildDocs(
String outputDir,
URL template,
List<URL> resources,
Map<String, Package> index
) {
new OutputWriter().writeJava(index, outputDir, template, resources);
}

/** Writes JSON to an output directory as "index.json" */
public void writeJson(Map<String, Package> index, String outputDir) {
new OutputWriter().writeJsonJava(index, outputDir);
}
}
49 changes: 49 additions & 0 deletions dottydoc/src/dotty/tools/dottydoc/api/scala/Dottydoc.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package dotty.tools.dottydoc.api.scala

import dotty.tools.dottydoc.DocDriver
import dotty.tools.dottydoc.model.Package
import dotty.tools.dottydoc.util.OutputWriter

import scala.collection.Map
import java.net.URL

/**
* The Dottydoc API is fairly simple. The tool creates an index by calling:
* "createIndex" with the same argument list as you would the compiler - e.g:
*
* {{{
* val array: Array[String] = Array(
* "-language:Scala2"
* )
*
* val index: Map[String, Package] = createIndex(array)
* }}}
*
* Once the index has been generated, the tool can also build a documentation
* API given a Mustache template and a flat resources structure (i.e. absolute
* paths to each resource, which will be put in the same directory).
*
* {{{
* buildDocs("path/to/output/dir", templateURL, resources, index)
* }}}
*
* The tool can also generate JSON from the created index using "indexToJson"
* or directly using "createJsonIndex"
*/
trait Dottydoc extends DocDriver {
Copy link
Member

Choose a reason for hiding this comment

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

Why do you have both Dottydoc.java and Dottydoc.scala ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea is to have a Java interface for when the time comes that releases are compiled with dotty. As such, tools compiled with dotty should be able to use the Scala interface, while incompatible projects (such as sbt on 2.10) will still be able to use the Java interface.

Copy link
Member

Choose a reason for hiding this comment

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

OK, should this interface be part of dotty-interfaces ?

Copy link
Contributor Author

@felixmulder felixmulder Aug 22, 2016

Choose a reason for hiding this comment

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

I'm okay with that as long as it's on the same classpath available to the bridge as dotty 😄

Let me know and I'll make it happen.

Copy link
Member

Choose a reason for hiding this comment

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

OK, let's keep it as is for now

/** Creates index from compiler arguments */
def createIndex(args: Array[String]): Map[String, Package] =
compiledDocs(args)

/** Creates JSON from compiler arguments */
def createJsonIndex(args: Array[String]): String =
indexToJson(compiledDocs(args))

/** Creates a documentation from the given parameters */
def buildDocs(outDir: String, template: URL, resources: List[URL], index: Map[String, Package]) =
new OutputWriter().write(index, outDir, template, resources)

/** Writes JSON to an output directory as "index.json" */
def writeJson(index: Map[String, Package], outputDir: String) =
new OutputWriter().writeJson(index, outputDir)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dotty.tools
package dottydoc
package core

import dotc.core.Contexts.Context

import transform.DocMiniPhase
import model._
import model.internal._

/** This DocMiniPhase adds the alternate constructors, currently defined as
* methods with the name `<init>`, to the Entity#constructors list
*/
class AlternateConstructors extends DocMiniPhase {
def partitionMembers(ent: Entity with Constructors with Members): (List[List[ParamList]], List[Entity]) = {
val (constructors, members) = ent.members.partition(x => x.name == "<init>")

val paramLists: List[List[ParamList]] = constructors.collect {
case df: Def => df.paramLists
}

(ent.constructors ++ paramLists, members)
}

override def transformClass(implicit ctx: Context) = { case cls: ClassImpl =>
val (constructors, members) = partitionMembers(cls)
cls.copy(members = members, constructors = constructors)
}

override def transformCaseClass(implicit ctx: Context) = { case cc: CaseClassImpl =>
val (constructors, members) = partitionMembers(cc)
cc.copy(members = members, constructors = constructors)
}
}
Loading