@@ -83,40 +83,16 @@ trait Deriving { this: Typer =>
83
83
else if (cls.is(Sealed )) sealedShape
84
84
else NoType
85
85
86
- /** A completer for the synthesized `Shape` type. */
87
- class ShapeCompleter extends TypeParamsCompleter {
88
-
89
- override def completerTypeParams (sym : Symbol )(implicit ctx : Context ) = cls.typeParams
90
-
91
- def completeInCreationContext (denot : SymDenotation ) = {
92
- val shape0 = shapeWithClassParams
93
- val tparams = cls.typeParams
94
- val abstractedShape =
95
- if (! shape0.exists) {
96
- ctx.error(em " Cannot derive for $cls; it is neither sealed nor a case class or object " , templateStartPos)
97
- UnspecifiedErrorType
98
- }
99
- else if (tparams.isEmpty)
100
- shape0
101
- else
102
- HKTypeLambda (tparams.map(_.name.withVariance(0 )))(
103
- tl => tparams.map(tparam => tl.integrate(tparams, tparam.info).bounds),
104
- tl => tl.integrate(tparams, shape0))
105
- denot.info = TypeAlias (abstractedShape)
106
- }
107
-
108
- def complete (denot : SymDenotation )(implicit ctx : Context ) =
109
- completeInCreationContext(denot)
110
- }
111
-
112
86
private def add (sym : Symbol ): sym.type = {
113
87
ctx.enter(sym)
114
88
synthetics += sym
115
89
sym
116
90
}
117
91
118
92
/** Create a synthetic symbol owned by current owner */
119
- private def newSymbol (name : Name , info : Type , pos : Position , flags : FlagSet = EmptyFlags )(implicit ctx : Context ) =
93
+ private def newSymbol (name : Name , info : Type ,
94
+ pos : Position = ctx.owner.pos,
95
+ flags : FlagSet = EmptyFlags )(implicit ctx : Context ) =
120
96
ctx.newSymbol(ctx.owner, name, flags | Synthetic , info, coord = pos)
121
97
122
98
/** Create a synthetic method owned by current owner */
@@ -186,37 +162,36 @@ trait Deriving { this: Typer =>
186
162
derived.pos)
187
163
}
188
164
189
- /** Add value corresponding to `val reflectedClass = new ReflectedClass (...)`
190
- * to `synthetics`, unless a definition of `reflectedClass ` exists already.
165
+ /** Add value corresponding to `val genericClass = new GenericClass (...)`
166
+ * to `synthetics`, unless a definition of `genericClass ` exists already.
191
167
*/
192
- private def addReflectedClass (): Unit =
193
- if (! ctx.denotNamed(nme.reflectedClass ).exists) {
194
- add(newSymbol(nme.reflectedClass , defn.ReflectedClassType , templateStartPos))
168
+ private def addGenericClass (): Unit =
169
+ if (! ctx.denotNamed(nme.genericClass ).exists) {
170
+ add(newSymbol(nme.genericClass , defn.GenericClassType , templateStartPos))
195
171
}
196
172
197
- /** Add `type Shape = ... ` type to `synthetics`, unless a definition of type `Shape` exists already */
198
- private def addShape (): Unit =
199
- if (! ctx.denotNamed(tpnme.Shape ).exists) {
200
- val shapeSym = add(newSymbol(tpnme.Shape , new ShapeCompleter , templateStartPos))
201
- val lazyShapedInfo = new LazyType {
202
- def complete (denot : SymDenotation )(implicit ctx : Context ) = {
203
- val tparams = cls.typeParams
204
- val appliedShape = shapeSym.typeRef.appliedTo(tparams.map(_.typeRef))
205
- val shapedType = defn.ShapedType .appliedTo(cls.appliedRef, appliedShape)
206
- denot.info = PolyType .fromParams(tparams, shapedType).ensureMethodic
207
- }
173
+ private def addGeneric (): Unit = {
174
+ val genericCompleter = new LazyType {
175
+ def complete (denot : SymDenotation )(implicit ctx : Context ) = {
176
+ val resultType =
177
+ RefinedType (
178
+ defn.GenericType .appliedTo(cls.appliedRef),
179
+ tpnme.Shape ,
180
+ TypeAlias (shapeWithClassParams))
181
+ denot.info = PolyType .fromParams(cls.typeParams, resultType).ensureMethodic
208
182
}
209
- addDerivedInstance(defn.ShapedType .name, lazyShapedInfo, templateStartPos, reportErrors = false )
210
183
}
184
+ addDerivedInstance(defn.GenericType .name, genericCompleter, templateStartPos, reportErrors = false )
185
+ }
211
186
212
187
/** Create symbols for derived instances and infrastructure,
213
188
* append them to `synthetics` buffer,
214
189
* and enter them into class scope.
215
190
*/
216
191
def enterDerived (derived : List [untpd.Tree ]) = {
217
192
derived.foreach(processDerivedInstance(_))
218
- addShape ()
219
- addReflectedClass ()
193
+ addGeneric ()
194
+ addGenericClass ()
220
195
}
221
196
222
197
private def tupleElems (tp : Type ): List [Type ] = tp match {
@@ -250,12 +225,12 @@ trait Deriving { this: Typer =>
250
225
class Finalizer {
251
226
import tpd ._
252
227
253
- /** The previously synthetsized `reflectedClass ` symbol */
254
- private def reflectedClass =
255
- synthetics.find(sym => ! sym.is(Method ) && sym.name == nme.reflectedClass ).get.asTerm
228
+ /** The previously synthetsized `genericClass ` symbol */
229
+ private def genericClass =
230
+ synthetics.find(sym => ! sym.is(Method ) && sym.name == nme.genericClass ).get.asTerm
256
231
257
- /** The string to pass to `ReflectedClass ` for initializing case and element labels.
258
- * See documentation of `ReflectedClass .label` for what needs to be passed.
232
+ /** The string to pass to `GenericClass ` for initializing case and element labels.
233
+ * See documentation of `GenericClass .label` for what needs to be passed.
259
234
*/
260
235
private def labelString (sh : Type ): String = sh match {
261
236
case ShapeCases (cases) =>
@@ -269,53 +244,62 @@ trait Deriving { this: Typer =>
269
244
(patLabel :: elemLabels).mkString(" \u0000 " )
270
245
}
271
246
272
- /** The RHS of the `reflectedClass ` value definition */
273
- private def reflectedClassRHS =
274
- New (defn.ReflectedClassType ,
247
+ /** The RHS of the `genericClass ` value definition */
248
+ private def genericClassRHS =
249
+ New (defn.GenericClassType ,
275
250
List (Literal (Constant (cls.typeRef)),
276
251
Literal (Constant (labelString(shapeWithClassParams)))))
277
252
278
- /** The RHS of the `derived$Shaped ` typeclass instance.
253
+ /** The RHS of the `derived$Generic ` typeclass instance.
279
254
* Example: For the class definition
280
255
*
281
256
* enum Lst[+T] derives ... { case Cons(hd: T, tl: Lst[T]); case Nil }
282
257
*
283
- * the following typeclass instance is generated:
258
+ * the following typeclass instance is generated, where
259
+ * <shape> = Cases[(Case[Cons[T], (T, Lst[T])], Case[Nil.type, Unit])]:
284
260
*
285
- * implicit def derived$Shape[T]: Shaped[Lst[T], Shape[T]] = new {
286
- * def reflect(x$0: Lst[T]): Mirror = x$0 match {
287
- * case x$0: Cons[T] => reflectedClass.mirror(0, x$0)
288
- * case x$0: Nil.type => reflectedClass.mirror(1)
289
- * }
290
- * def reify(c: Mirror): Lst[T] = c.ordinal match {
291
- * case 0 => Cons[T](c(0).asInstanceOf[T], c(1).asInstanceOf[Lst[T]])
292
- * case 1 => Nil
261
+ * implicit def derived$Generic[T]: Generic[Lst[T]] { type Shape = <shape> } =
262
+ * new Generic[Lst[T]] {
263
+ * type Shape = <shape>
264
+ * def reflect(x$0: Lst[T]): Mirror = x$0 match {
265
+ * case x$0: Cons[T] => genericClass.mirror(0, x$0)
266
+ * case x$0: Nil.type => genericClass.mirror(1)
267
+ * }
268
+ * def reify(c: Mirror): Lst[T] = c.ordinal match {
269
+ * case 0 => Cons[T](c(0).asInstanceOf[T], c(1).asInstanceOf[Lst[T]])
270
+ * case 1 => Nil
271
+ * }
272
+ * def common = genericClass
293
273
* }
294
- * def common = reflectedClass
295
- * }
296
274
*/
297
- private def shapedRHS (shapedType : Type )(implicit ctx : Context ) = {
298
- val AppliedType (_, clsArg :: shapeArg :: Nil ) = shapedType
275
+ private def genericRHS (genericType : Type )(implicit ctx : Context ) = {
276
+ val RefinedType (
277
+ genericInstance @ AppliedType (_, clsArg :: Nil ),
278
+ tpnme.Shape ,
279
+ TypeAlias (shapeArg)) = genericType
299
280
val shape = shapeArg.dealias
300
281
301
282
val implClassSym = ctx.newNormalizedClassSymbol(
302
- ctx.owner, tpnme.ANON_CLASS , EmptyFlags , shapedType :: Nil , coord = templateStartPos)
283
+ ctx.owner, tpnme.ANON_CLASS , EmptyFlags , genericInstance :: Nil , coord = templateStartPos)
303
284
val implClassCtx = ctx.withOwner(implClassSym)
304
285
val implClassConstr =
305
286
newMethod(nme.CONSTRUCTOR , MethodType (Nil , implClassSym.typeRef))(implClassCtx).entered
306
287
307
288
def implClassStats (implicit ctx : Context ): List [Tree ] = {
308
-
289
+ val shapeType : TypeDef = {
290
+ val shapeAlias = newSymbol(tpnme.Shape , TypeAlias (shape)).entered.asType
291
+ TypeDef (shapeAlias)
292
+ }
309
293
val reflectMethod : DefDef = {
310
294
val meth = newMethod(nme.reflect, MethodType (clsArg :: Nil , defn.MirrorType )).entered
311
295
def rhs (paramRef : Tree )(implicit ctx : Context ): Tree = {
312
296
def reflectCase (scrut : Tree , idx : Int , elems : List [Type ]): Tree = {
313
297
val ordinal = Literal (Constant (idx))
314
298
val args = if (elems.isEmpty) List (ordinal) else List (ordinal, scrut)
315
- val mirror = defn.ReflectedClassType
299
+ val mirror = defn.GenericClassType
316
300
.member(nme.mirror)
317
301
.suchThat(sym => args.tpes.corresponds(sym.info.firstParamTypes)(_ <:< _))
318
- ref(reflectedClass ).select(mirror.symbol).appliedToArgs(args)
302
+ ref(genericClass ).select(mirror.symbol).appliedToArgs(args)
319
303
}
320
304
shape match {
321
305
case ShapeCases (cases) =>
@@ -362,11 +346,11 @@ trait Deriving { this: Typer =>
362
346
}
363
347
364
348
val commonMethod : DefDef = {
365
- val meth = newMethod(nme.common, ExprType (defn.ReflectedClassType )).entered
366
- tpd.DefDef (meth, ref(reflectedClass ))
349
+ val meth = newMethod(nme.common, ExprType (defn.GenericClassType )).entered
350
+ tpd.DefDef (meth, ref(genericClass ))
367
351
}
368
352
369
- List (reflectMethod, reifyMethod, commonMethod)
353
+ List (shapeType, reflectMethod, reifyMethod, commonMethod)
370
354
}
371
355
372
356
val implClassDef = ClassDef (implClassSym, DefDef (implClassConstr), implClassStats(implClassCtx))
@@ -393,8 +377,8 @@ trait Deriving { this: Typer =>
393
377
}
394
378
val resultType = instantiated(sym.info)
395
379
val (typeCls, companionRef) = classAndCompanionRef(resultType)
396
- if (typeCls == defn.ShapedClass )
397
- shapedRHS (resultType)
380
+ if (typeCls == defn.GenericClass )
381
+ genericRHS (resultType)
398
382
else {
399
383
val module = untpd.ref(companionRef).withPos(sym.pos)
400
384
val rhs = untpd.Select (module, nme.derived)
@@ -408,15 +392,17 @@ trait Deriving { this: Typer =>
408
392
else if (sym.is(Method ))
409
393
tpd.polyDefDef(sym.asTerm, typeclassInstance(sym)(ctx.fresh.setOwner(sym).setNewScope))
410
394
else
411
- tpd.ValDef (sym.asTerm, reflectedClassRHS )
395
+ tpd.ValDef (sym.asTerm, genericClassRHS )
412
396
413
397
def syntheticDefs : List [Tree ] = synthetics.map(syntheticDef).toList
414
398
}
415
399
416
- def finalize (stat : tpd.TypeDef ): tpd.Tree = {
417
- val templ @ Template (_, _, _, _) = stat.rhs
418
- tpd.cpy.TypeDef (stat)(
419
- rhs = tpd.cpy.Template (templ)(body = templ.body ++ new Finalizer ().syntheticDefs))
420
- }
400
+ def finalize (stat : tpd.TypeDef ): tpd.Tree =
401
+ if (ctx.reporter.hasErrors) stat
402
+ else {
403
+ val templ @ Template (_, _, _, _) = stat.rhs
404
+ tpd.cpy.TypeDef (stat)(
405
+ rhs = tpd.cpy.Template (templ)(body = templ.body ++ new Finalizer ().syntheticDefs))
406
+ }
421
407
}
422
408
}
0 commit comments