Skip to content

Commit cdeb00a

Browse files
committed
Add binding between Symbol and Untyped tree in base context
This commit also adds a printer for use by dottydoc.
1 parent 7853ce6 commit cdeb00a

File tree

6 files changed

+97
-41
lines changed

6 files changed

+97
-41
lines changed

src/dotty/tools/dotc/config/Printers.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ object Printers {
1313
}
1414

1515
val default: Printer = new Printer
16+
val dottydoc: Printer = noPrinter
1617
val core: Printer = noPrinter
1718
val typr: Printer = noPrinter
1819
val constr: Printer = noPrinter

src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,14 @@ object Contexts {
550550
def squashed(p: Phase): Phase = {
551551
allPhases.find(_.period.containsPhaseId(p.id)).getOrElse(NoPhase)
552552
}
553+
554+
val _docstrings: mutable.Map[Symbol, String] =
555+
mutable.Map.empty
556+
557+
def docstring(sym: Symbol): Option[String] = _docstrings.get(sym)
558+
559+
def addDocstring(sym: Symbol, doc: Option[String]): Unit =
560+
doc.map(d => _docstrings += (sym -> d))
553561
}
554562

555563
/** The essential mutable state of a context base, collected into a common class */

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,19 +401,29 @@ class Namer { typer: Typer =>
401401
val pkg = createPackageSymbol(pcl.pid)
402402
index(pcl.stats)(ctx.fresh.setOwner(pkg.moduleClass))
403403
invalidateCompanions(pkg, Trees.flatten(pcl.stats map expanded))
404+
setDocstring(pkg, stat)
404405
ctx
405406
case imp: Import =>
406407
importContext(createSymbol(imp), imp.selectors)
407408
case mdef: DefTree =>
408-
enterSymbol(createSymbol(mdef))
409+
val sym = enterSymbol(createSymbol(mdef))
410+
setDocstring(sym, stat)
409411
ctx
410412
case stats: Thicket =>
411-
for (tree <- stats.toList) enterSymbol(createSymbol(tree))
413+
for (tree <- stats.toList) {
414+
val sym = enterSymbol(createSymbol(tree))
415+
setDocstring(sym, stat)
416+
}
412417
ctx
413418
case _ =>
414419
ctx
415420
}
416421

422+
def setDocstring(sym: Symbol, tree: Tree)(implicit ctx: Context) = tree match {
423+
case t: MemberDef => ctx.base.addDocstring(sym, t.rawComment)
424+
case _ => ()
425+
}
426+
417427
/** Create top-level symbols for statements and enter them into symbol table */
418428
def index(stats: List[Tree])(implicit ctx: Context): Context = {
419429

@@ -859,7 +869,7 @@ class Namer { typer: Typer =>
859869
WildcardType
860870
}
861871
paramFn(typedAheadType(mdef.tpt, tptProto).tpe)
862-
}
872+
}
863873

864874
/** The type signature of a DefDef with given symbol */
865875
def defDefSig(ddef: DefDef, sym: Symbol)(implicit ctx: Context) = {

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
586586
case _ => false
587587
}
588588

589-
/** The funcion body to be returned in the closure. Can become a TypedSplice
589+
/** The function body to be returned in the closure. Can become a TypedSplice
590590
* of a typed expression if this is necessary to infer a parameter type.
591591
*/
592592
var fnBody = tree.body

test/test/DottyDocParsingTests.scala

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,9 @@ import dotty.tools.dotc.ast.Trees._
66
import org.junit.Assert._
77
import org.junit.Test
88

9-
class DottyDocParsingTests extends DottyTest {
10-
def checkDocString(actual: Option[String], expected: String): Unit = actual match {
11-
case Some(str) =>
12-
assert(str == expected, s"""Docstring: "$str" didn't match expected "$expected"""")
13-
case None =>
14-
assert(false, s"""No docstring found, expected: "$expected"""")
15-
}
16-
17-
private def defaultAssertion: PartialFunction[Tree[Untyped], Unit] = {
18-
case x => assert(false, "Couldn't match resulting AST to expected AST in: " + x.show)
19-
}
9+
class DottyDocParsingTests extends DottyDocTest {
2010

21-
private def checkFrontend(source: String)(docAssert: PartialFunction[Tree[Untyped], Unit]) = {
22-
checkCompile("frontend", source) { (_, ctx) =>
23-
implicit val c = ctx
24-
(docAssert orElse defaultAssertion)(ctx.compilationUnit.untpdTree)
25-
}
26-
}
27-
28-
@Test def noComment() = {
11+
@Test def noComment = {
2912
import dotty.tools.dotc.ast.untpd._
3013
val source = "class Class"
3114

@@ -35,7 +18,7 @@ class DottyDocParsingTests extends DottyTest {
3518
}
3619
}
3720

38-
@Test def singleClassInPackage() = {
21+
@Test def singleClassInPackage = {
3922
val source =
4023
"""
4124
|package a
@@ -50,7 +33,7 @@ class DottyDocParsingTests extends DottyTest {
5033
}
5134
}
5235

53-
@Test def multipleOpenedOnSingleClassInPackage() = {
36+
@Test def multipleOpenedOnSingleClassInPackage = {
5437
val source =
5538
"""
5639
|package a
@@ -64,7 +47,7 @@ class DottyDocParsingTests extends DottyTest {
6447
checkDocString(t.rawComment, "/** Hello /* multiple open */ world! */")
6548
}
6649
}
67-
@Test def multipleClassesInPackage() = {
50+
@Test def multipleClassesInPackage = {
6851
val source =
6952
"""
7053
|package a
@@ -86,7 +69,7 @@ class DottyDocParsingTests extends DottyTest {
8669
}
8770
}
8871

89-
@Test def singleCaseClassWithoutPackage() = {
72+
@Test def singleCaseClassWithoutPackage = {
9073
val source =
9174
"""
9275
|/** Class without package */
@@ -98,15 +81,15 @@ class DottyDocParsingTests extends DottyTest {
9881
}
9982
}
10083

101-
@Test def SingleTraitWihoutPackage() = {
84+
@Test def SingleTraitWihoutPackage = {
10285
val source = "/** Trait docstring */\ntrait Trait"
10386

10487
checkFrontend(source) {
10588
case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment, "/** Trait docstring */")
10689
}
10790
}
10891

109-
@Test def multipleTraitsWithoutPackage() = {
92+
@Test def multipleTraitsWithoutPackage = {
11093
val source =
11194
"""
11295
|/** Trait1 docstring */
@@ -124,7 +107,7 @@ class DottyDocParsingTests extends DottyTest {
124107
}
125108
}
126109

127-
@Test def multipleMixedEntitiesWithPackage() = {
110+
@Test def multipleMixedEntitiesWithPackage = {
128111
val source =
129112
"""
130113
|/** Trait1 docstring */
@@ -152,7 +135,7 @@ class DottyDocParsingTests extends DottyTest {
152135
}
153136
}
154137

155-
@Test def nestedClass() = {
138+
@Test def nestedClass = {
156139
val source =
157140
"""
158141
|/** Outer docstring */
@@ -173,7 +156,7 @@ class DottyDocParsingTests extends DottyTest {
173156
}
174157
}
175158

176-
@Test def nestedClassThenOuter() = {
159+
@Test def nestedClassThenOuter = {
177160
val source =
178161
"""
179162
|/** Outer1 docstring */
@@ -198,7 +181,7 @@ class DottyDocParsingTests extends DottyTest {
198181
}
199182
}
200183

201-
@Test def objects() = {
184+
@Test def objects = {
202185
val source =
203186
"""
204187
|package p
@@ -220,7 +203,7 @@ class DottyDocParsingTests extends DottyTest {
220203
}
221204
}
222205

223-
@Test def objectsNestedClass() = {
206+
@Test def objectsNestedClass = {
224207
val source =
225208
"""
226209
|package p
@@ -252,7 +235,7 @@ class DottyDocParsingTests extends DottyTest {
252235
}
253236
}
254237

255-
@Test def packageObject() = {
238+
@Test def packageObject = {
256239
val source =
257240
"""
258241
|/** Package object docstring */
@@ -289,7 +272,7 @@ class DottyDocParsingTests extends DottyTest {
289272
}
290273
}
291274

292-
@Test def multipleDocStringsBeforeEntity() = {
275+
@Test def multipleDocStringsBeforeEntity = {
293276
val source =
294277
"""
295278
|/** First comment */
@@ -305,7 +288,7 @@ class DottyDocParsingTests extends DottyTest {
305288
}
306289
}
307290

308-
@Test def multipleDocStringsBeforeAndAfter() = {
291+
@Test def multipleDocStringsBeforeAndAfter = {
309292
val source =
310293
"""
311294
|/** First comment */
@@ -324,7 +307,7 @@ class DottyDocParsingTests extends DottyTest {
324307
}
325308
}
326309

327-
@Test def valuesWithDocString() = {
310+
@Test def valuesWithDocString = {
328311
val source =
329312
"""
330313
|object Object {
@@ -356,7 +339,7 @@ class DottyDocParsingTests extends DottyTest {
356339
}
357340
}
358341

359-
@Test def varsWithDocString() = {
342+
@Test def varsWithDocString = {
360343
val source =
361344
"""
362345
|object Object {
@@ -388,7 +371,7 @@ class DottyDocParsingTests extends DottyTest {
388371
}
389372
}
390373

391-
@Test def defsWithDocString() = {
374+
@Test def defsWithDocString = {
392375
val source =
393376
"""
394377
|object Object {
@@ -420,7 +403,7 @@ class DottyDocParsingTests extends DottyTest {
420403
}
421404
}
422405

423-
@Test def typesWithDocString() = {
406+
@Test def typesWithDocString = {
424407
val source =
425408
"""
426409
|object Object {
@@ -451,4 +434,26 @@ class DottyDocParsingTests extends DottyTest {
451434
}
452435
}
453436
}
437+
438+
@Test def defInnerClass = {
439+
val source =
440+
"""
441+
|object Foo {
442+
| def foo() = {
443+
| /** Innermost */
444+
| class Innermost
445+
| }
446+
|}
447+
""".stripMargin
448+
449+
import dotty.tools.dotc.ast.untpd._
450+
checkFrontend(source) {
451+
case PackageDef(_, Seq(o: ModuleDef)) =>
452+
o.impl.body match {
453+
case (foo: MemberDef) :: Nil =>
454+
expectNoDocString(foo.rawComment)
455+
case _ => assert(false, "Incorrect structure inside object")
456+
}
457+
}
458+
}
454459
} /* End class */

test/test/DottyDocTest.scala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package test
2+
3+
import dotty.tools.dotc.ast.Trees._
4+
import dotty.tools.dotc.core.Contexts.Context
5+
import dotty.tools.dottydoc.core.Phases.DocPhase
6+
import dotty.tools.dottydoc.model.Entities.Entity
7+
8+
trait DottyDocTest extends DottyTest {
9+
def checkDocString(actual: Option[String], expected: String): Unit = actual match {
10+
case Some(str) =>
11+
assert(str == expected, s"""Docstring: "$str" didn't match expected "$expected"""")
12+
case None =>
13+
assert(false, s"""No docstring found, expected: "$expected"""")
14+
}
15+
16+
def expectNoDocString(doc: Option[String]): Unit =
17+
doc.fold(()) { d => assert(false, s"""Expected not to find a docstring, but found: "$d"""") }
18+
19+
def defaultAssertion: PartialFunction[Any, Unit] = {
20+
case t: Tree[Untyped] =>
21+
assert(false, s"Couldn't match resulting AST to expected AST in: ${t.show}")
22+
case x =>
23+
assert(false, s"Couldn't match resulting AST to expected AST in: $x")
24+
}
25+
26+
def checkFrontend(source: String)(docAssert: PartialFunction[Tree[Untyped], Unit]) = {
27+
checkCompile("frontend", source) { (_, ctx) =>
28+
implicit val c = ctx
29+
(docAssert orElse defaultAssertion)(ctx.compilationUnit.untpdTree)
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)