aboutsummaryrefslogtreecommitdiff
path: root/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala
blob: 5144d81e4c31c235931aae2c1fb966a77beaeb41 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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()))
  }
}