diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-03-10 15:03:48 +0100 |
---|---|---|
committer | Felix Mulder <felix.mulder@gmail.com> | 2016-04-07 08:40:27 +0200 |
commit | 6c8265c6cc3555e00f82cf4909fea5e95d1a2f94 (patch) | |
tree | e7a3ca8df25cb84181fff6c53c212eee43093153 | |
parent | c66998bc56ba73b5b2cbbf6b10f4d5b83017db13 (diff) | |
download | dotty-6c8265c6cc3555e00f82cf4909fea5e95d1a2f94.tar.gz dotty-6c8265c6cc3555e00f82cf4909fea5e95d1a2f94.tar.bz2 dotty-6c8265c6cc3555e00f82cf4909fea5e95d1a2f94.zip |
Add docstring support for types, vals, vars and defs
-rw-r--r-- | src/dotty/tools/dotc/parsing/Parsers.scala | 24 | ||||
-rw-r--r-- | test/test/DottyDocTests.scala | 141 |
2 files changed, 150 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index 053b28a64..dad618381 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -1752,13 +1752,13 @@ object Parsers { */ def defOrDcl(start: Int, mods: Modifiers): Tree = in.token match { case VAL => - patDefOrDcl(posMods(start, mods)) + patDefOrDcl(posMods(start, mods), in.getDocString(start)) case VAR => - patDefOrDcl(posMods(start, addFlag(mods, Mutable))) + patDefOrDcl(posMods(start, addFlag(mods, Mutable)), in.getDocString(start)) case DEF => - defDefOrDcl(posMods(start, mods)) + defDefOrDcl(posMods(start, mods), in.getDocString(start)) case TYPE => - typeDefOrDcl(posMods(start, mods)) + typeDefOrDcl(posMods(start, mods), in.getDocString(start)) case _ => tmplDef(start, mods) } @@ -1768,7 +1768,7 @@ object Parsers { * ValDcl ::= Id {`,' Id} `:' Type * VarDcl ::= Id {`,' Id} `:' Type */ - def patDefOrDcl(mods: Modifiers): Tree = { + def patDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = { val lhs = commaSeparated(pattern2) val tpt = typedOpt() val rhs = @@ -1782,8 +1782,10 @@ object Parsers { } } else EmptyTree lhs match { - case (id @ Ident(name: TermName)) :: Nil => cpy.ValDef(id)(name, tpt, rhs).withMods(mods) - case _ => PatDef(mods, lhs, tpt, rhs) + case (id @ Ident(name: TermName)) :: Nil => + cpy.ValDef(id)(name, tpt, rhs).withMods(mods).withComment(docstring) + case _ => + PatDef(mods, lhs, tpt, rhs) } } @@ -1792,7 +1794,7 @@ object Parsers { * DefDcl ::= DefSig `:' Type * DefSig ::= id [DefTypeParamClause] ParamClauses */ - def defDefOrDcl(mods: Modifiers): Tree = atPos(tokenRange) { + def defDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = atPos(tokenRange) { def scala2ProcedureSyntax(resultTypeStr: String) = { val toInsert = if (in.token == LBRACE) s"$resultTypeStr =" @@ -1833,7 +1835,7 @@ object Parsers { accept(EQUALS) expr() } - DefDef(name, tparams, vparamss, tpt, rhs).withMods(mods1) + DefDef(name, tparams, vparamss, tpt, rhs).withMods(mods1).withComment(docstring) } } @@ -1867,7 +1869,7 @@ object Parsers { /** TypeDef ::= type Id [TypeParamClause] `=' Type * TypeDcl ::= type Id [TypeParamClause] TypeBounds */ - def typeDefOrDcl(mods: Modifiers): Tree = { + def typeDefOrDcl(mods: Modifiers, docstring: Option[String] = None): Tree = { newLinesOpt() atPos(tokenRange) { val name = ident().toTypeName @@ -1875,7 +1877,7 @@ object Parsers { in.token match { case EQUALS => in.nextToken() - TypeDef(name, tparams, typ()).withMods(mods) + TypeDef(name, tparams, typ()).withMods(mods).withComment(docstring) case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF => TypeDef(name, tparams, typeBounds()).withMods(mods) case _ => diff --git a/test/test/DottyDocTests.scala b/test/test/DottyDocTests.scala index 5161f98b8..a950095bc 100644 --- a/test/test/DottyDocTests.scala +++ b/test/test/DottyDocTests.scala @@ -42,11 +42,14 @@ trait DottyDocTest extends DottyTest { self => assert(false, s"""No docstring found, expected: "$expected"""") } - def run(): Unit = { + def run(): Unit = try { val c = compiler(assertion) c.rootContext(ctx) c.newRun.compile(source) println(s"${self.getClass.getSimpleName.split("\\$").last} passed") + } catch { case e: Throwable => + Console.err.println(s"${self.getClass.getSimpleName.split("\\$").last} failed") + throw e } } @@ -54,6 +57,7 @@ trait DottyDocTest extends DottyTest { self => object DottyDocTests extends DottyTest { private[this] val tests = Seq( NoComment, + SingleClassInPackage, MultipleOpenedOnSingleClassInPackage, MultipleClassesInPackage, @@ -67,13 +71,18 @@ object DottyDocTests extends DottyTest { ObjectsNestedClass, PackageObject, MultipleDocStringsBeforeEntity, - MultipleDocStringsBeforeAndAfter + MultipleDocStringsBeforeAndAfter, + + ValuesWithDocString, + VarsWithDocString, + DefsWithDocString, + TypesWithDocString ) def main(args: Array[String]): Unit = { - println("------------ Testing DottyDoc ------------") + println(s"-------------- Testing DottyDoc (${tests.length} tests) --------------") tests.foreach(_.run) - println("--------- DottyDoc tests passed! ----------") + println("--------------- DottyDoc tests passed! -------------------") } } @@ -371,3 +380,127 @@ case object MultipleDocStringsBeforeAndAfter extends DottyDocTest { } } + +case object ValuesWithDocString extends DottyDocTest { + override 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._ + override def assertion = { + 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") + } + } +} + +case object VarsWithDocString extends DottyDocTest { + override 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._ + override def assertion = { + 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") + } + } +} + +case object DefsWithDocString extends DottyDocTest { + override 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._ + override def assertion = { + 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") + } + } +} + +case object TypesWithDocString extends DottyDocTest { + override 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._ + override def assertion = { + 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") + } + } +} |