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()))
}
}