aboutsummaryrefslogblamecommitdiff
path: root/test/test/DottyDocParsingTests.scala
blob: 8522cdae32f9b114920b3575bcbf90037c865ef9 (plain) (tree)
1
2
3
4
5
6
7
8
9







                                             
                                                 
 
                         




                                            
                                                                                                              


     
                                    









                                                                                  
                                                                      


     
                                                    









                                                                                  
                                                                                          

     
                                        













                                                                          

                                                                             




         
                                             






                                   
                                                                                                                          


     
                                        


                                                      
                                                                                                                    


     
                                            










                                                                        

                                                                           



       
                                                


















                                                                                                                   



                                                                                    



       
                           










                                                                               
                                                                             
                        
                                                                                                                   





                                                              
                                    













                                                                                               

                                                                           
                        
                                                                                                                   





                                                              
                       













                                                                                      
                                                                            
                                                 
                                                                            



       
                                  


















                                                                    
                                                                            
                                             
                                                                            

                            
                                                                                                                        





                                                              
                             




















                                                
                                                                                  


                                                                         



                                                                                                                       






                                                                              
                                              










                                            
                                                                      


     
                                                













                                            
                                                                      


     
                                   




















                                                                                


                                                                   






                                                                      
                                 




















                                                                                


                                                                   






                                                                      
                                 




















                                                                                


                                                                   






                                                                      
                                  




















                                                                                


                                                                    





                                                                      
















                                              
                                                        



                                                                      











                                                   
                                                                













                                                
                                                                

     
                 
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.map(_.raw) == 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.map(_.raw), "/** 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.map(_.raw), "/** 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.map(_.raw), "/** Class1 docstring */")
          checkDocString(c2.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Class without package */")
    }
  }

  @Test def SingleTraitWihoutPackage = {
    val source = "/** Trait docstring */\ntrait Trait"

    checkFrontend(source) {
      case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Trait1 docstring */")
        checkDocString(t2.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Trait1 docstring */")
        checkDocString(c2.rawComment.map(_.raw), "/** Class2 docstring */")
        checkDocString(cc3.rawComment.map(_.raw), "/** CaseClass3 docstring */")
        checkDocString(ac4.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Outer docstring */")
        tpl.body match {
          case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Outer1 docstring */")
        checkDocString(o2.rawComment.map(_.raw), "/** Outer2 docstring */")
        tpl.body match {
          case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Object1 docstring */")
        assertEquals(o2.name.toString, "Object2")
        checkDocString(o2.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Object1 docstring */")
        assert(o2.name.toString == "Object2")
        checkDocString(o2.rawComment.map(_.raw), "/** Object2 docstring */")

        o2.impl.body match {
          case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.raw), "/** 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.map(_.raw), "/** Package object docstring */")

        p.impl.body match {
          case (b: TypeDef) :: (t: TypeDef) :: (o: ModuleDef) :: Nil => {
            checkDocString(b.rawComment.map(_.raw), "/** Boo docstring */")
            checkDocString(t.rawComment.map(_.raw), "/** Trait docstring */")
            checkDocString(o.rawComment.map(_.raw), "/** InnerObject docstring */")
            checkDocString(o.impl.body.head.asInstanceOf[TypeDef].rawComment.map(_.raw), "/** 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.map(_.raw), "/** 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.map(_.raw), "/** 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.map(_.raw), "/** val1 */")
            checkDocString(v2.rawComment.map(_.raw), "/** val2 */")
            checkDocString(v3.rawComment.map(_.raw), "/** 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.map(_.raw), "/** var1 */")
            checkDocString(v2.rawComment.map(_.raw), "/** var2 */")
            checkDocString(v3.rawComment.map(_.raw), "/** 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.map(_.raw), "/** def1 */")
            checkDocString(v2.rawComment.map(_.raw), "/** def2 */")
            checkDocString(v3.rawComment.map(_.raw), "/** 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.map(_.raw), "/** type1 */")
            checkDocString(v2.rawComment.map(_.raw), "/** type2 */")
            checkDocString(v3.rawComment.map(_.raw), "/** 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.map(_.raw))
          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.map(_.raw), "/** 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.map(_.raw), "/** Class1 */")
    }
  }
} /* End class */