aboutsummaryrefslogblamecommitdiff
path: root/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala
blob: 5144d81e4c31c235931aae2c1fb966a77beaeb41 (plain) (tree)
1
2
3
4
5
6
7


                   



                         




                         
                      
                 

                             
                                                          















































































                                                                                                  








































                                                                                     
                                         

                                                                


                                                                   
                                                                   















                                                                        
package dotty.tools
package dotc
package parsing

import org.junit.Test
import org.junit.Assert._

import ast.untpd.modsDeco
import ast.untpd._
import ast.{ Trees => d }
import Parsers.Parser
import util.SourceFile
import core.Contexts._
import core.Flags

object ModifiersParsingTest {
  implicit val ctx: Context = (new ContextBase).initialCtx

  implicit def parse(code: String): Tree = {
    val (_, stats) = new Parser(new SourceFile("<meta>", code.toCharArray)).templateStatSeq()
    stats match { case List(stat) => stat; case stats => Thicket(stats) }
  }

  implicit class TreeDeco(val code: Tree) extends AnyVal {
    def firstConstrValDef: ValDef = code match {
      case d.TypeDef(_, d.Template(constr, _, _, _)) =>
        constr.vparamss.head.head
    }

    def firstTypeParam: TypeDef = code match {
      case d.TypeDef(_, d.Template(constr, _, _, _)) =>
        constr.tparams.head
    }

    def defParam(i: Int): ValDef = code match {
      case d.DefDef(_, _, vparamss, _, _) =>
        vparamss.head.toArray.apply(i)
    }

    def defParam(i: Int, j: Int): ValDef = code match {
      case d.DefDef(_, _, vparamss, _, _) =>
        vparamss.toArray.apply(i).toArray.apply(j)
    }

    def funParam(i: Int): Tree = code match {
      case Function(params, _) =>
        params.toArray.apply(i)
    }

    def field(i: Int): Tree = code match {
      case d.TypeDef(_, t: Template) =>
        t.body.toArray.apply(i)
    }

    def field(name: String): Tree = code match {
      case d.TypeDef(_, t: Template) =>
        t.body.find({
          case m: MemberDef => m.name.show == name
          case _ => false
        }).get
    }

    def stat(i: Int): Tree = code match {
      case d.Block(stats, expr) =>
        if (i < stats.length) stats.toArray.apply(i)
        else expr
    }

    def modifiers: List[Mod] = code match {
      case t: MemberDef => t.mods.mods
    }
  }
}


class ModifiersParsingTest {
  import ModifiersParsingTest._


  @Test def valDef = {
    var source: Tree = "class A(var a: Int)"
    assert(source.firstConstrValDef.modifiers == List(Mod.Var()))

    source = "class A(val a: Int)"
    assert(source.firstConstrValDef.modifiers == List(Mod.Val()))

    source = "class A(private val a: Int)"
    assert(source.firstConstrValDef.modifiers == List(Mod.Private(), Mod.Val()))

    source = "class A(protected var a: Int)"
    assert(source.firstConstrValDef.modifiers == List(Mod.Protected(), Mod.Var()))

    source = "class A(protected implicit val a: Int)"
    assert(source.firstConstrValDef.modifiers == List(Mod.Protected(), Mod.Implicit(), Mod.Val()))

    source = "class A[T]"
    assert(source.firstTypeParam.modifiers == List())
  }

  @Test def typeDef = {
    var source: Tree = "class A"
    assert(source.modifiers == List())

    source = "sealed class A"
    assert(source.modifiers == List(Mod.Sealed()))

    source = "implicit class A"
    assert(source.modifiers == List(Mod.Implicit()))

    source = "abstract sealed class A"
    assert(source.modifiers == List(Mod.Abstract(), Mod.Sealed()))
  }

  @Test def fieldDef = {
    val source: Tree =
      """
        | class A {
        |   lazy var a = ???
        |   lazy private val b = ???
        |   final val c = ???
        |
        |   abstract override def f: Boolean
        |   inline def g(n: Int) = ???
        | }
      """.stripMargin

    assert(source.field("a").modifiers == List(Mod.Lazy(), Mod.Var()))
    assert(source.field("b").modifiers == List(Mod.Lazy(), Mod.Private(), Mod.Val()))
    assert(source.field("c").modifiers == List(Mod.Final(), Mod.Val()))
    assert(source.field("f").modifiers == List(Mod.Abstract(), Mod.Override()))
    assert(source.field("g").modifiers == List(Mod.Inline()))
  }

  @Test def paramDef = {
    var source: Tree = "def f(inline a: Int) = ???"
    assert(source.defParam(0).modifiers == List(Mod.Inline()))

    source = "def f(implicit a: Int, b: Int) = ???"
    println(source.defParam(0).modifiers)
    assert(source.defParam(0).modifiers == List(Mod.Implicit()))
    assert(source.defParam(1).modifiers == List(Mod.Implicit()))

    source = "def f(x: Int, y: Int)(implicit a: Int, b: Int) = ???"
    assert(source.defParam(0, 0).modifiers == List())
    assert(source.defParam(1, 0).modifiers == List(Mod.Implicit()))
  }

  @Test def blockDef = {
    var source: Tree = "implicit val x : A = ???"
    assert(source.modifiers == List(Mod.Implicit(), Mod.Val()))

    source = "implicit var x : A = ???"
    assert(source.modifiers == List(Mod.Implicit(), Mod.Var()))

    source = "{ implicit var x : A = ??? }"
    assert(source.stat(0).modifiers == List(Mod.Implicit(), Mod.Var()))

    source = "{ implicit x => x * x }"
    assert(source.stat(0).funParam(0).modifiers == List(Mod.Implicit()))
  }
}