@@ -5,6 +5,7 @@ package init
5
5
6
6
import dotty .tools .dotc ._
7
7
import ast .tpd
8
+ import tpd ._
8
9
9
10
import dotty .tools .dotc .core ._
10
11
import Contexts ._
@@ -15,51 +16,54 @@ import StdNames._
15
16
import dotty .tools .dotc .transform ._
16
17
import Phases ._
17
18
18
-
19
19
import scala .collection .mutable
20
20
21
+ import Semantic ._
21
22
22
23
class Checker extends Phase {
23
- import tpd ._
24
24
25
25
val phaseName = " initChecker"
26
26
27
- private val semantic = new Semantic
28
-
29
27
override val runsAfter = Set (Pickler .name)
30
28
31
29
override def isEnabled (using Context ): Boolean =
32
30
super .isEnabled && ctx.settings.YcheckInit .value
33
31
34
32
override def runOn (units : List [CompilationUnit ])(using Context ): List [CompilationUnit ] =
35
- units.foreach { unit => traverser.traverse(unit.tpdTree) }
36
- super .runOn(units)
33
+ val checkCtx = ctx.fresh.setPhase(this .start)
34
+ Semantic .withInitialState {
35
+ val traverser = new InitTreeTraverser ()
36
+ units.foreach { unit => traverser.traverse(unit.tpdTree) }
37
+ given Context = checkCtx
38
+ Semantic .check()
39
+ super .runOn(units)
40
+ }
41
+
42
+ def run (using Context ): Unit = {
43
+ // ignore, we already called `Semantic.check()` in `runOn`
44
+ }
37
45
38
- val traverser = new TreeTraverser {
46
+ class InitTreeTraverser ( using WorkList ) extends TreeTraverser {
39
47
override def traverse (tree : Tree )(using Context ): Unit =
40
48
traverseChildren(tree)
41
49
tree match {
42
- case tdef : MemberDef =>
50
+ case mdef : MemberDef =>
43
51
// self-type annotation ValDef has no symbol
44
- if tdef.name != nme.WILDCARD then
45
- tdef.symbol.defTree = tree
46
- case _ =>
47
- }
48
- }
52
+ if mdef.name != nme.WILDCARD then
53
+ mdef.symbol.defTree = tree
49
54
50
- override def run (using Context ): Unit = {
51
- val unit = ctx.compilationUnit
52
- unit.tpdTree.foreachSubTree {
53
- case tdef : TypeDef if tdef.isClassDef =>
54
- transformTypeDef(tdef)
55
+ mdef match
56
+ case tdef : TypeDef if tdef.isClassDef =>
57
+ val cls = tdef.symbol.asClass
58
+ val thisRef = ThisRef (cls)
59
+ if shouldCheckClass(cls) then Semantic .addTask(thisRef)
60
+ case _ =>
55
61
56
- case _ =>
57
- }
62
+ case _ =>
63
+ }
58
64
}
59
65
60
-
61
- private def transformTypeDef (tree : TypeDef )(using Context ): tpd.Tree = {
62
- val cls = tree.symbol.asClass
66
+ private def shouldCheckClass (cls : ClassSymbol )(using Context ) = {
63
67
val instantiable : Boolean =
64
68
cls.is(Flags .Module ) ||
65
69
! cls.isOneOf(Flags .AbstractOrTrait ) && {
@@ -71,21 +75,6 @@ class Checker extends Phase {
71
75
}
72
76
73
77
// A concrete class may not be instantiated if the self type is not satisfied
74
- if (instantiable && cls.enclosingPackageClass != defn.StdLibPatchesPackage .moduleClass) {
75
- import semantic ._
76
- val tpl = tree.rhs.asInstanceOf [Template ]
77
- val thisRef = ThisRef (cls).ensureExists
78
-
79
- val paramValues = tpl.constr.termParamss.flatten.map(param => param.symbol -> Hot ).toMap
80
-
81
- given Promoted = Promoted .empty
82
- given Trace = Trace .empty
83
- given Env = Env (paramValues)
84
-
85
- val res = eval(tpl, thisRef, cls)
86
- res.errors.foreach(_.issue)
87
- }
88
-
89
- tree
78
+ instantiable && cls.enclosingPackageClass != defn.StdLibPatchesPackage .moduleClass
90
79
}
91
80
}
0 commit comments