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 && ! tpe.symbol.is(JavaStatic ) => fail(t)
40+ case tpe @ TermRef (prefix, _)
41+ if cls.is(Module ) && prefix.termSymbol == cls.sourceModule && ! tpe.symbol.is(JavaStatic ) => fail(t)
42+ case tpe @ TermRef (prefix, _)
43+ if cls.is(Module ) && tpe.symbol == cls.sourceModule => fail(t)
44+ case _ =>
45+ case _ =>
46+ }
47+ case _ =>
48+ case _ =>
49+ mdef
50+
51+ end CheckNoSuperThis
0 commit comments