1+ package dotty .tools
2+ package dotc
3+ package transform
4+
5+ import core .DenotTransformers .*
6+ import dotty .tools .dotc .transform .MegaPhase .MiniPhase
7+ import core .Contexts .Context
8+ import core .Types .*
9+ import core .Names .*
10+ import core .Symbols .*
11+ import dotty .tools .dotc .core .Flags
12+ import dotty .tools .dotc .core .Constants .*
13+
14+ class AddReifiedTypes extends MiniPhase with InfoTransformer {
15+ import ast .tpd .*
16+
17+ override def phaseName : String = " addReifiedTypes"
18+ override def description : String = " add reified type values to methods"
19+
20+ override def transformInfo (tp : Type , sym : Symbol )(using Context ): Type = tp match {
21+ case pt : PolyType =>
22+ pt.derivedLambdaType(
23+ pt.paramNames,
24+ pt.paramInfos,
25+ addReifiedParams(pt.resType, pt.paramNames)
26+ )
27+ case _ => tp
28+ }
29+
30+ def addReifiedParams (tp : Type , typeParamNames : List [Name ])(using Context ): Type = tp match {
31+ case mt : MethodType =>
32+ val newParamNames = typeParamNames.map(name => termName(s " reified_ $name" ))
33+ val newParamTypes = newParamNames.map(_ => defn.AnyType )
34+ mt.derivedLambdaType(
35+ mt.paramNames ++ newParamNames,
36+ mt.paramInfos ++ newParamTypes,
37+ mt.resultType
38+ )
39+ case pt : PolyType =>
40+ pt.derivedLambdaType(
41+ pt.paramNames,
42+ pt.paramInfos,
43+ addReifiedParams(pt.resType, typeParamNames)
44+ )
45+ case _ => tp
46+ }
47+
48+ override def transformDefDef (tree : DefDef )(using Context ): Tree = {
49+ val sym = tree.symbol
50+ val typeParams = tree.paramss.collectFirst {
51+ case tparams : List [? ] if tparams.nonEmpty && tparams.head.isInstanceOf [TypeDef ] =>
52+ tparams.asInstanceOf [List [TypeDef ]]
53+ }.getOrElse(Nil )
54+
55+ if (typeParams.nonEmpty) {
56+ val newParamDefs = typeParams.map { tparam =>
57+ val paramName = termName(s " reified_ ${tparam.name}" )
58+ val paramSym = newSymbol(
59+ sym,
60+ paramName,
61+ Flags .Param ,
62+ defn.AnyType
63+ ).asTerm
64+ ValDef (paramSym)
65+ }
66+
67+ var added = false
68+ val newParamss = tree.paramss.map { clause =>
69+ val isTypeClause = clause.nonEmpty && clause.head.isInstanceOf [TypeDef ]
70+ if (! isTypeClause && ! added) {
71+ added = true
72+ val newClause : ParamClause = clause.asInstanceOf [List [ValDef ]] ++ newParamDefs
73+ newClause
74+ } else {
75+ clause
76+ }
77+ }
78+
79+ if (added) cpy.DefDef (tree)(paramss = newParamss)
80+ else tree
81+ } else tree
82+ }
83+
84+ override def transformApply (tree : Apply )(using Context ): Tree = {
85+ val sym = tree.fun.symbol
86+ if (sym.exists && sym.is(Flags .Method ) && sym.info.isInstanceOf [PolyType ]) {
87+ val reifiedArgs = tree.fun match {
88+ case TypeApply (_, targs) =>
89+ targs.map(targ => createReifiedValue(targ.tpe))
90+ case _ =>
91+ val poly = sym.info.asInstanceOf [PolyType ]
92+ poly.paramNames.map(_ => createReifiedValue(defn.AnyType ))
93+ }
94+ cpy.Apply (tree)(tree.fun, tree.args ++ reifiedArgs)
95+ } else {
96+ tree
97+ }
98+ }
99+
100+ def createReifiedValue (tpe : Type )(using Context ): Tree = {
101+ Literal (Constant (()))
102+ }
103+ }
0 commit comments