1+ package dotty .tools .dotc
2+ package transform
3+
4+ import core .*
5+ import MegaPhase .MiniPhase
6+ import Contexts .* , Types .* , Symbols .* , SymDenotations .* , Flags .*
7+ import ast .*
8+ import Trees .*
9+ import Decorators .*
10+
11+ import annotation .threadUnsafe
12+
13+ object CheckNoSuperThis :
14+ val name : String = " checkNoSuperThis"
15+
16+ /** Checks that super and this calls do not pass `this` as (part of) an argument. */
17+ class CheckNoSuperThis extends MiniPhase :
18+ thisPhase =>
19+ import tpd ._
20+
21+ override def phaseName : String = CheckNoSuperThis .name
22+
23+ override def runsAfterGroupsOf : Set [String ] = Set (Constructors .name)
24+
25+ override def transformDefDef (mdef : DefDef )(using Context ): DefDef =
26+ if mdef.symbol.isClassConstructor then
27+ mdef.rhs match
28+ case Block (stats, _) => splitAtSuper(stats) match
29+ case (Apply (_, superArgs) :: _, _) =>
30+ val cls = mdef.symbol.owner
31+ def fail (t : Tree ) =
32+ report.error(em " super constructor cannot be passed a self reference $t unless parameter is declared by-name " , t.srcPos)
33+ for arg <- superArgs do
34+ arg.foreachSubTree {
35+ case t : This if t.symbol == cls =>
36+ fail(t)
37+ case t : RefTree => t.tpe match
38+ case tpe @ TermRef (prefix, _)
39+ if (prefix == cls.thisType
40+ || cls.is(Module )
41+ && (prefix.termSymbol == cls.sourceModule || tpe.symbol == cls.sourceModule)
42+ ) && ! tpe.symbol.is(JavaStatic ) => fail(t)
43+ case _ =>
44+ case _ =>
45+ }
46+ case _ =>
47+ case _ =>
48+ mdef
49+
50+ end CheckNoSuperThis
0 commit comments