aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/test/DottyDocParsingTests.scala489
-rw-r--r--test/test/DottyDocTest.scala32
-rw-r--r--test/test/DottyTest.scala3
3 files changed, 522 insertions, 2 deletions
diff --git a/test/test/DottyDocParsingTests.scala b/test/test/DottyDocParsingTests.scala
new file mode 100644
index 000000000..b09d048da
--- /dev/null
+++ b/test/test/DottyDocParsingTests.scala
@@ -0,0 +1,489 @@
+package test
+
+import dotty.tools.dotc.core.Contexts.Context
+import dotty.tools.dotc.ast.Trees._
+
+import org.junit.Assert._
+import org.junit.Test
+
+class DottyDocParsingTests extends DottyDocTest {
+
+ @Test def noComment = {
+ import dotty.tools.dotc.ast.untpd._
+ val source = "class Class"
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(c: TypeDef)) =>
+ assert(c.rawComment == None, "Should not have a comment, mainly used for exhaustive tests")
+ }
+ }
+
+ @Test def singleClassInPackage = {
+ val source =
+ """
+ |package a
+ |
+ |/** Hello world! */
+ |class Class(val x: String)
+ """.stripMargin
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" =>
+ checkDocString(t.rawComment, "/** Hello world! */")
+ }
+ }
+
+ @Test def multipleOpenedOnSingleClassInPackage = {
+ val source =
+ """
+ |package a
+ |
+ |/** Hello /* multiple open */ world! */
+ |class Class(val x: String)
+ """.stripMargin
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" =>
+ checkDocString(t.rawComment, "/** Hello /* multiple open */ world! */")
+ }
+ }
+ @Test def multipleClassesInPackage = {
+ val source =
+ """
+ |package a
+ |
+ |/** Class1 docstring */
+ |class Class1(val x: String)
+ |
+ |/** Class2 docstring */
+ |class Class2(val x: String)
+ """.stripMargin
+
+ checkCompile("frontend", source) { (_, ctx) =>
+ ctx.compilationUnit.untpdTree match {
+ case PackageDef(_, Seq(c1 @ TypeDef(_,_), c2 @ TypeDef(_,_))) => {
+ checkDocString(c1.rawComment, "/** Class1 docstring */")
+ checkDocString(c2.rawComment, "/** Class2 docstring */")
+ }
+ }
+ }
+ }
+
+ @Test def singleCaseClassWithoutPackage = {
+ val source =
+ """
+ |/** Class without package */
+ |case class Class(val x: Int)
+ """.stripMargin
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment, "/** Class without package */")
+ }
+ }
+
+ @Test def SingleTraitWihoutPackage = {
+ val source = "/** Trait docstring */\ntrait Trait"
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment, "/** Trait docstring */")
+ }
+ }
+
+ @Test def multipleTraitsWithoutPackage = {
+ val source =
+ """
+ |/** Trait1 docstring */
+ |trait Trait1
+ |
+ |/** Trait2 docstring */
+ |trait Trait2
+ """.stripMargin
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(t1 @ TypeDef(_,_), t2 @ TypeDef(_,_))) => {
+ checkDocString(t1.rawComment, "/** Trait1 docstring */")
+ checkDocString(t2.rawComment, "/** Trait2 docstring */")
+ }
+ }
+ }
+
+ @Test def multipleMixedEntitiesWithPackage = {
+ val source =
+ """
+ |/** Trait1 docstring */
+ |trait Trait1
+ |
+ |/** Class2 docstring */
+ |class Class2(val x: Int)
+ |
+ |/** CaseClass3 docstring */
+ |case class CaseClass3()
+ |
+ |case class NoComment()
+ |
+ |/** AbstractClass4 docstring */
+ |abstract class AbstractClass4(val x: Int)
+ """.stripMargin
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(t1 @ TypeDef(_,_), c2 @ TypeDef(_,_), cc3 @ TypeDef(_,_), _, ac4 @ TypeDef(_,_))) => {
+ checkDocString(t1.rawComment, "/** Trait1 docstring */")
+ checkDocString(c2.rawComment, "/** Class2 docstring */")
+ checkDocString(cc3.rawComment, "/** CaseClass3 docstring */")
+ checkDocString(ac4.rawComment, "/** AbstractClass4 docstring */")
+ }
+ }
+ }
+
+ @Test def nestedClass = {
+ val source =
+ """
+ |/** Outer docstring */
+ |class Outer {
+ | /** Inner docstring */
+ | class Inner(val x: Int)
+ |}
+ """.stripMargin
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(outer @ TypeDef(_, tpl @ Template(_,_,_,_)))) => {
+ checkDocString(outer.rawComment, "/** Outer docstring */")
+ tpl.body match {
+ case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */")
+ case _ => assert(false, "Couldn't find inner class")
+ }
+ }
+ }
+ }
+
+ @Test def nestedClassThenOuter = {
+ val source =
+ """
+ |/** Outer1 docstring */
+ |class Outer1 {
+ | /** Inner docstring */
+ | class Inner(val x: Int)
+ |}
+ |
+ |/** Outer2 docstring */
+ |class Outer2
+ """.stripMargin
+
+ checkFrontend(source) {
+ case PackageDef(_, Seq(o1 @ TypeDef(_, tpl @ Template(_,_,_,_)), o2 @ TypeDef(_,_))) => {
+ checkDocString(o1.rawComment, "/** Outer1 docstring */")
+ checkDocString(o2.rawComment, "/** Outer2 docstring */")
+ tpl.body match {
+ case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */")
+ case _ => assert(false, "Couldn't find inner class")
+ }
+ }
+ }
+ }
+
+ @Test def objects = {
+ val source =
+ """
+ |package p
+ |
+ |/** Object1 docstring */
+ |object Object1
+ |
+ |/** Object2 docstring */
+ |object Object2
+ """.stripMargin
+
+ checkFrontend(source) {
+ case p @ PackageDef(_, Seq(o1: MemberDef[Untyped], o2: MemberDef[Untyped])) => {
+ assertEquals(o1.name.toString, "Object1")
+ checkDocString(o1.rawComment, "/** Object1 docstring */")
+ assertEquals(o2.name.toString, "Object2")
+ checkDocString(o2.rawComment, "/** Object2 docstring */")
+ }
+ }
+ }
+
+ @Test def objectsNestedClass = {
+ val source =
+ """
+ |package p
+ |
+ |/** Object1 docstring */
+ |object Object1
+ |
+ |/** Object2 docstring */
+ |object Object2 {
+ | class A1
+ | /** Inner docstring */
+ | class Inner
+ |}
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case p @ PackageDef(_, Seq(o1: ModuleDef, o2: ModuleDef)) => {
+ assert(o1.name.toString == "Object1")
+ checkDocString(o1.rawComment, "/** Object1 docstring */")
+ assert(o2.name.toString == "Object2")
+ checkDocString(o2.rawComment, "/** Object2 docstring */")
+
+ o2.impl.body match {
+ case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment, "/** Inner docstring */")
+ case _ => assert(false, "Couldn't find inner class")
+ }
+ }
+ }
+ }
+
+ @Test def packageObject = {
+ val source =
+ """
+ |/** Package object docstring */
+ |package object foo {
+ | /** Boo docstring */
+ | case class Boo()
+ |
+ | /** Trait docstring */
+ | trait Trait
+ |
+ | /** InnerObject docstring */
+ | object InnerObject {
+ | /** InnerClass docstring */
+ | class InnerClass
+ | }
+ |}
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(p: ModuleDef)) => {
+ checkDocString(p.rawComment, "/** Package object docstring */")
+
+ p.impl.body match {
+ case (b: TypeDef) :: (t: TypeDef) :: (o: ModuleDef) :: Nil => {
+ checkDocString(b.rawComment, "/** Boo docstring */")
+ checkDocString(t.rawComment, "/** Trait docstring */")
+ checkDocString(o.rawComment, "/** InnerObject docstring */")
+ checkDocString(o.impl.body.head.asInstanceOf[TypeDef].rawComment, "/** InnerClass docstring */")
+ }
+ case _ => assert(false, "Incorrect structure inside package object")
+ }
+ }
+ }
+ }
+
+ @Test def multipleDocStringsBeforeEntity = {
+ val source =
+ """
+ |/** First comment */
+ |/** Second comment */
+ |/** Real comment */
+ |class Class
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(c: TypeDef)) =>
+ checkDocString(c.rawComment, "/** Real comment */")
+ }
+ }
+
+ @Test def multipleDocStringsBeforeAndAfter = {
+ val source =
+ """
+ |/** First comment */
+ |/** Second comment */
+ |/** Real comment */
+ |class Class
+ |/** Following comment 1 */
+ |/** Following comment 2 */
+ |/** Following comment 3 */
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(c: TypeDef)) =>
+ checkDocString(c.rawComment, "/** Real comment */")
+ }
+ }
+
+ @Test def valuesWithDocString = {
+ val source =
+ """
+ |object Object {
+ | /** val1 */
+ | val val1 = 1
+ |
+ | /** val2 */
+ | val val2: Int = 2
+ | /** bogus docstring */
+ |
+ | /** bogus docstring */
+ | /** val3 */
+ | val val3: List[Int] = 1 :: 2 :: 3 :: Nil
+ |}
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(o: ModuleDef)) => {
+ o.impl.body match {
+ case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
+ checkDocString(v1.rawComment, "/** val1 */")
+ checkDocString(v2.rawComment, "/** val2 */")
+ checkDocString(v3.rawComment, "/** val3 */")
+ }
+ case _ => assert(false, "Incorrect structure inside object")
+ }
+ }
+ }
+ }
+
+ @Test def varsWithDocString = {
+ val source =
+ """
+ |object Object {
+ | /** var1 */
+ | var var1 = 1
+ |
+ | /** var2 */
+ | var var2: Int = 2
+ | /** bogus docstring */
+ |
+ | /** bogus docstring */
+ | /** var3 */
+ | var var3: List[Int] = 1 :: 2 :: 3 :: Nil
+ |}
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(o: ModuleDef)) => {
+ o.impl.body match {
+ case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
+ checkDocString(v1.rawComment, "/** var1 */")
+ checkDocString(v2.rawComment, "/** var2 */")
+ checkDocString(v3.rawComment, "/** var3 */")
+ }
+ case _ => assert(false, "Incorrect structure inside object")
+ }
+ }
+ }
+ }
+
+ @Test def defsWithDocString = {
+ val source =
+ """
+ |object Object {
+ | /** def1 */
+ | def def1 = 1
+ |
+ | /** def2 */
+ | def def2: Int = 2
+ | /** bogus docstring */
+ |
+ | /** bogus docstring */
+ | /** def3 */
+ | def def3: List[Int] = 1 :: 2 :: 3 :: Nil
+ |}
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(o: ModuleDef)) => {
+ o.impl.body match {
+ case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
+ checkDocString(v1.rawComment, "/** def1 */")
+ checkDocString(v2.rawComment, "/** def2 */")
+ checkDocString(v3.rawComment, "/** def3 */")
+ }
+ case _ => assert(false, "Incorrect structure inside object")
+ }
+ }
+ }
+ }
+
+ @Test def typesWithDocString = {
+ val source =
+ """
+ |object Object {
+ | /** type1 */
+ | type T1 = Int
+ |
+ | /** type2 */
+ | type T2 = String
+ | /** bogus docstring */
+ |
+ | /** bogus docstring */
+ | /** type3 */
+ | type T3 = T2
+ |}
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(o: ModuleDef)) => {
+ o.impl.body match {
+ case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => {
+ checkDocString(v1.rawComment, "/** type1 */")
+ checkDocString(v2.rawComment, "/** type2 */")
+ checkDocString(v3.rawComment, "/** type3 */")
+ }
+ case _ => assert(false, "Incorrect structure inside object")
+ }
+ }
+ }
+ }
+
+ @Test def defInnerClass = {
+ val source =
+ """
+ |object Foo {
+ | def foo() = {
+ | /** Innermost */
+ | class Innermost
+ | }
+ |}
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case PackageDef(_, Seq(o: ModuleDef)) =>
+ o.impl.body match {
+ case (foo: MemberDef) :: Nil =>
+ expectNoDocString(foo.rawComment)
+ case _ => assert(false, "Incorrect structure inside object")
+ }
+ }
+ }
+
+ @Test def withExtends = {
+ val source =
+ """
+ |trait Trait1
+ |/** Class1 */
+ |class Class1 extends Trait1
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case p @ PackageDef(_, Seq(_, c: TypeDef)) =>
+ checkDocString(c.rawComment, "/** Class1 */")
+ }
+ }
+
+ @Test def withAnnotation = {
+ val source =
+ """
+ |/** Class1 */
+ |@SerialVersionUID(1)
+ |class Class1
+ """.stripMargin
+
+ import dotty.tools.dotc.ast.untpd._
+ checkFrontend(source) {
+ case p @ PackageDef(_, Seq(c: TypeDef)) =>
+ checkDocString(c.rawComment, "/** Class1 */")
+ }
+ }
+} /* End class */
diff --git a/test/test/DottyDocTest.scala b/test/test/DottyDocTest.scala
new file mode 100644
index 000000000..34269ec64
--- /dev/null
+++ b/test/test/DottyDocTest.scala
@@ -0,0 +1,32 @@
+package test
+
+import dotty.tools.dotc.ast.Trees._
+import dotty.tools.dotc.core.Contexts.Context
+
+trait DottyDocTest extends DottyTest {
+ ctx = ctx.fresh.setSetting(ctx.settings.YkeepComments, true)
+
+ def checkDocString(actual: Option[String], expected: String): Unit = actual match {
+ case Some(str) =>
+ assert(str == expected, s"""Docstring: "$str" didn't match expected "$expected"""")
+ case None =>
+ assert(false, s"""No docstring found, expected: "$expected"""")
+ }
+
+ def expectNoDocString(doc: Option[String]): Unit =
+ doc.fold(()) { d => assert(false, s"""Expected not to find a docstring, but found: "$d"""") }
+
+ def defaultAssertion: PartialFunction[Any, Unit] = {
+ case t: Tree[Untyped] =>
+ assert(false, s"Couldn't match resulting AST to expected AST in: ${t.show}")
+ case x =>
+ assert(false, s"Couldn't match resulting AST to expected AST in: $x")
+ }
+
+ def checkFrontend(source: String)(docAssert: PartialFunction[Tree[Untyped], Unit]) = {
+ checkCompile("frontend", source) { (_, ctx) =>
+ implicit val c = ctx
+ (docAssert orElse defaultAssertion)(ctx.compilationUnit.untpdTree)
+ }
+ }
+}
diff --git a/test/test/DottyTest.scala b/test/test/DottyTest.scala
index 77642561a..15d82c208 100644
--- a/test/test/DottyTest.scala
+++ b/test/test/DottyTest.scala
@@ -32,7 +32,6 @@ class DottyTest /*extends ContextEscapeDetection*/ {
}
*/
private def compilerWithChecker(phase: String)(assertion:(tpd.Tree, Context) => Unit) = new Compiler {
- self =>
override def phases = {
val allPhases = super.phases
val targetPhase = allPhases.flatten.find(p => p.phaseName == phase).get
@@ -48,7 +47,7 @@ class DottyTest /*extends ContextEscapeDetection*/ {
}
}
- def checkCompile(checkAfterPhase: String, source:String)(assertion:(tpd.Tree, Context) => Unit): Unit = {
+ def checkCompile(checkAfterPhase: String, source: String)(assertion: (tpd.Tree, Context) => Unit): Unit = {
val c = compilerWithChecker(checkAfterPhase)(assertion)
c.rootContext(ctx)
val run = c.newRun