@@ -8,6 +8,7 @@ import ValueClasses._
8
8
import scala .annotation .tailrec
9
9
import core ._
10
10
import typer .ErrorReporting ._
11
+ import typer .Checking
11
12
import Types ._ , Contexts ._ , Constants ._ , Names ._ , NameOps ._ , Flags ._ , DenotTransformers ._
12
13
import SymDenotations ._ , Symbols ._ , StdNames ._ , Annotations ._ , Trees ._ , Scopes ._ , Denotations ._
13
14
import util .Positions ._
@@ -27,6 +28,14 @@ import Symbols._, TypeUtils._
27
28
*
28
29
* (4) Check that `New` nodes can be instantiated, and that annotations are valid
29
30
*
31
+ * (5) Convert all trees representing types to TypeTrees.
32
+ *
33
+ * (6) Check the bounds of AppliedTypeTrees
34
+ *
35
+ * (7) Insert `.package` for selections of package object members
36
+ *
37
+ * (8) Replaces self references by name with `this`
38
+ *
30
39
* The reason for making this a macro transform is that some functions (in particular
31
40
* super and protected accessors and instantiation checks) are naturally top-down and
32
41
* don't lend themselves to the bottom-up approach of a mini phase. The other two functions
@@ -49,24 +58,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
49
58
val superAcc = new SuperAccessors (thisTransformer)
50
59
val paramFwd = new ParamForwarding (thisTransformer)
51
60
val synthMth = new SyntheticMethods (thisTransformer)
52
-
53
- /** Check that `tp` refers to a nonAbstract class
54
- * and that the instance conforms to the self type of the created class.
55
- */
56
- private def checkInstantiable (tp : Type , pos : Position )(implicit ctx : Context ): Unit =
57
- tp.underlyingClassRef(refinementOK = false ) match {
58
- case tref : TypeRef =>
59
- val cls = tref.symbol
60
- if (cls.is(AbstractOrTrait ))
61
- ctx.error(d " $cls is abstract; cannot be instantiated " , pos)
62
- if (! cls.is(Module )) {
63
- val selfType = tp.givenSelfType.asSeenFrom(tref.prefix, cls.owner)
64
- if (selfType.exists && ! (tp <:< selfType))
65
- ctx.error(d " $tp does not conform to its self type $selfType; cannot be instantiated " )
66
- }
67
- case _ =>
68
- }
69
-
61
+
70
62
private def newPart (tree : Tree ): Option [New ] = methPart(tree) match {
71
63
case Select (nu : New , _) => Some (nu)
72
64
case _ => None
@@ -76,6 +68,22 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
76
68
// TODO fill in
77
69
}
78
70
71
+ private def normalizeTypeTree (tree : Tree )(implicit ctx : Context ) = {
72
+ def norm (tree : Tree ) = if (tree.isType) TypeTree (tree.tpe).withPos(tree.pos) else tree
73
+ tree match {
74
+ case tree : TypeTree =>
75
+ tree
76
+ case AppliedTypeTree (tycon, args) =>
77
+ val tparams = tycon.tpe.typeSymbol.typeParams
78
+ val bounds = tparams.map(tparam =>
79
+ tparam.info.asSeenFrom(tycon.tpe.normalizedPrefix, tparam.owner.owner).bounds)
80
+ Checking .checkBounds(args, bounds, _.substDealias(tparams, _))
81
+ norm(tree)
82
+ case _ =>
83
+ norm(tree)
84
+ }
85
+ }
86
+
79
87
class PostTyperTransformer extends Transformer {
80
88
81
89
private var inJavaAnnot : Boolean = false
@@ -96,35 +104,51 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
96
104
private def transformAnnots (tree : MemberDef )(implicit ctx : Context ): Unit =
97
105
tree.symbol.transformAnnotations(transformAnnot)
98
106
107
+ private def transformSelect (tree : Select , targs : List [Tree ])(implicit ctx : Context ) = {
108
+ val qual = tree.qualifier
109
+ qual.symbol.moduleClass.denot match {
110
+ case pkg : PackageClassDenotation if ! tree.symbol.maybeOwner.is(Package ) =>
111
+ assert(targs.isEmpty)
112
+ cpy.Select (tree)(qual select pkg.packageObj.symbol, tree.name)
113
+ case _ =>
114
+ superAcc.transformSelect(super .transform(tree), targs)
115
+ }
116
+ }
117
+
99
118
override def transform (tree : Tree )(implicit ctx : Context ): Tree =
100
- try tree match {
101
- case impl : Template =>
119
+ try normalizeTypeTree(tree) match {
120
+ case tree : Ident =>
121
+ tree.tpe match {
122
+ case tpe : ThisType => This (tpe.cls).withPos(tree.pos)
123
+ case _ => tree
124
+ }
125
+ case tree : Select =>
126
+ transformSelect(tree, Nil )
127
+ case tree @ TypeApply (sel : Select , args) =>
128
+ val args1 = transform(args)
129
+ val sel1 = transformSelect(sel, args1)
130
+ if (superAcc.isProtectedAccessor(sel1)) sel1 else cpy.TypeApply (tree)(sel1, args1)
131
+ case tree @ Assign (sel : Select , _) =>
132
+ superAcc.transformAssign(super .transform(tree))
133
+ case tree : Template =>
102
134
val saved = parentNews
103
- parentNews ++= impl .parents.flatMap(newPart)
135
+ parentNews ++= tree .parents.flatMap(newPart)
104
136
try
105
137
synthMth.addSyntheticMethods(
106
138
paramFwd.forwardParamAccessors(
107
- superAcc.wrapTemplate(impl )(
139
+ superAcc.wrapTemplate(tree )(
108
140
super .transform(_).asInstanceOf [Template ])))
109
141
finally parentNews = saved
110
- case tree @ TypeApply (sel : Select , args) =>
111
- val args1 = transform(args)
112
- val sel1 = superAcc.transformSelect(super .transform(sel), args1)
113
- if (superAcc.isProtectedAccessor(sel1)) sel1 else cpy.TypeApply (tree)(sel1, args1)
114
- case sel : Select =>
115
- superAcc.transformSelect(super .transform(sel), Nil )
116
- case tree @ Assign (sel : Select , _) =>
117
- superAcc.transformAssign(super .transform(tree))
118
142
case tree : DefDef =>
119
143
transformAnnots(tree)
120
144
superAcc.wrapDefDef(tree)(super .transform(tree).asInstanceOf [DefDef ])
121
145
case tree : MemberDef =>
122
146
transformAnnots(tree)
123
147
super .transform(tree)
124
148
case tree : New if ! inJavaAnnot && ! parentNews.contains(tree) =>
125
- checkInstantiable(tree.tpe, tree.pos)
149
+ Checking . checkInstantiable(tree.tpe, tree.pos)
126
150
super .transform(tree)
127
- case Annotated (annot, annotated) =>
151
+ case tree @ Annotated (annot, annotated) =>
128
152
cpy.Annotated (tree)(transformAnnot(annot), transform(annotated))
129
153
case tree : TypeTree =>
130
154
tree.withType(
@@ -133,7 +157,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
133
157
case tpe => tpe
134
158
}
135
159
)
136
- case _ =>
160
+ case tree =>
137
161
super .transform(tree)
138
162
}
139
163
catch {
0 commit comments