@@ -7,7 +7,7 @@ import util.Spans._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags
7
7
import Symbols ._ , StdNames ._ , Trees ._
8
8
import Decorators ._ , transform .SymUtils ._
9
9
import NameKinds .{UniqueName , EvidenceParamName , DefaultGetterName }
10
- import typer .FrontEnd
10
+ import typer .{ FrontEnd , Namer }
11
11
import util .{Property , SourceFile , SourcePosition }
12
12
import util .NameTransformer .avoidIllegalChars
13
13
import collection .mutable .ListBuffer
@@ -74,46 +74,45 @@ object desugar {
74
74
def derivedTree (sym : Symbol )(implicit ctx : Context ): tpd.Tree = tpd.ref(sym)
75
75
}
76
76
77
- /** A type tree that computes its type from an existing parameter.
78
- * @param suffix String difference between existing parameter (call it `P`) and parameter owning the
79
- * DerivedTypeTree (call it `O`). We have: `O.name == P.name + suffix`.
80
- */
81
- class DerivedFromParamTree (suffix : String )(implicit @ constructorOnly src : SourceFile ) extends DerivedTypeTree {
77
+ /** A type tree that computes its type from an existing parameter. */
78
+ class DerivedFromParamTree ()(implicit @ constructorOnly src : SourceFile ) extends DerivedTypeTree {
82
79
83
- /** Make sure that for all enclosing module classes their companion classes
84
- * are completed. Reason: We need the constructor of such companion classes to
85
- * be completed so that OriginalSymbol attachments are pushed to DerivedTypeTrees
86
- * in apply/unapply methods.
80
+ /** Complete the appropriate constructors so that OriginalSymbol attachments are
81
+ * pushed to DerivedTypeTrees.
87
82
*/
88
- override def ensureCompletions (implicit ctx : Context ): Unit =
83
+ override def ensureCompletions (implicit ctx : Context ): Unit = {
84
+ def completeConstructor (sym : Symbol ) =
85
+ sym.infoOrCompleter match {
86
+ case completer : Namer # ClassCompleter =>
87
+ completer.completeConstructor(sym)
88
+ case _ =>
89
+ }
90
+
89
91
if (! ctx.owner.is(Package ))
90
92
if (ctx.owner.isClass) {
91
- ctx.owner.ensureCompleted( )
93
+ completeConstructor( ctx.owner)
92
94
if (ctx.owner.is(ModuleClass ))
93
- ctx.owner.linkedClass.ensureCompleted( )
95
+ completeConstructor( ctx.owner.linkedClass)
94
96
}
95
97
else ensureCompletions(ctx.outer)
98
+ }
96
99
97
100
/** Return info of original symbol, where all references to siblings of the
98
101
* original symbol (i.e. sibling and original symbol have the same owner)
99
- * are rewired to like -named* parameters or accessors in the scope enclosing
102
+ * are rewired to same -named parameters or accessors in the scope enclosing
100
103
* the current scope. The current scope is the scope owned by the defined symbol
101
104
* itself, that's why we have to look one scope further out. If the resulting
102
105
* type is an alias type, dealias it. This is necessary because the
103
106
* accessor of a type parameter is a private type alias that cannot be accessed
104
107
* from subclasses.
105
- *
106
- * (*) like-named means:
107
- *
108
- * parameter name == reference name ++ suffix
109
108
*/
110
109
def derivedTree (sym : Symbol )(implicit ctx : Context ): tpd.TypeTree = {
111
110
val relocate = new TypeMap {
112
111
val originalOwner = sym.owner
113
112
def apply (tp : Type ) = tp match {
114
113
case tp : NamedType if tp.symbol.exists && (tp.symbol.owner eq originalOwner) =>
115
114
val defctx = ctx.outersIterator.dropWhile(_.scope eq ctx.scope).next()
116
- var local = defctx.denotNamed(tp.name ++ suffix ).suchThat(_.isParamOrAccessor).symbol
115
+ var local = defctx.denotNamed(tp.name).suchThat(_.isParamOrAccessor).symbol
117
116
if (local.exists) (defctx.owner.thisType select local).dealiasKeepAnnots
118
117
else {
119
118
def msg =
@@ -129,20 +128,19 @@ object desugar {
129
128
}
130
129
131
130
/** A type definition copied from `tdef` with a rhs typetree derived from it */
132
- def derivedTypeParam (tdef : TypeDef , suffix : String = " " )(implicit ctx : Context ): TypeDef =
131
+ def derivedTypeParam (tdef : TypeDef )(implicit ctx : Context ): TypeDef =
133
132
cpy.TypeDef (tdef)(
134
- name = tdef.name ++ suffix,
135
- rhs = DerivedFromParamTree (suffix).withSpan(tdef.rhs.span).watching(tdef)
133
+ rhs = DerivedFromParamTree ().withSpan(tdef.rhs.span).watching(tdef)
136
134
)
137
135
138
136
/** A derived type definition watching `sym` */
139
137
def derivedTypeParam (sym : TypeSymbol )(implicit ctx : Context ): TypeDef =
140
- TypeDef (sym.name, DerivedFromParamTree (" " ).watching(sym)).withFlags(TypeParam )
138
+ TypeDef (sym.name, DerivedFromParamTree ().watching(sym)).withFlags(TypeParam )
141
139
142
140
/** A value definition copied from `vdef` with a tpt typetree derived from it */
143
141
def derivedTermParam (vdef : ValDef )(implicit ctx : Context ): ValDef =
144
142
cpy.ValDef (vdef)(
145
- tpt = DerivedFromParamTree (" " ).withSpan(vdef.tpt.span).watching(vdef))
143
+ tpt = DerivedFromParamTree ().withSpan(vdef.tpt.span).watching(vdef))
146
144
147
145
// ----- Desugar methods -------------------------------------------------
148
146
@@ -269,8 +267,8 @@ object desugar {
269
267
def defaultGetter : DefDef =
270
268
DefDef (
271
269
name = DefaultGetterName (methName, n),
272
- tparams = meth.tparams.map(tparam => dropContextBounds(toDefParam(tparam))),
273
- vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam), n),
270
+ tparams = meth.tparams.map(tparam => dropContextBounds(toDefParam(tparam, keepAnnotations = true ))),
271
+ vparamss = takeUpTo(normalizedVparamss.nestedMap(toDefParam(_, keepAnnotations = true ) ), n),
274
272
tpt = TypeTree (),
275
273
rhs = vparam.rhs
276
274
)
@@ -374,10 +372,16 @@ object desugar {
374
372
375
373
@ sharable private val synthetic = Modifiers (Synthetic )
376
374
377
- private def toDefParam (tparam : TypeDef ): TypeDef =
378
- tparam.withMods(tparam.rawMods & EmptyFlags | Param )
379
- private def toDefParam (vparam : ValDef ): ValDef =
380
- vparam.withMods(vparam.rawMods & (GivenOrImplicit | Erased ) | Param )
375
+ private def toDefParam (tparam : TypeDef , keepAnnotations : Boolean ): TypeDef = {
376
+ var mods = tparam.rawMods
377
+ if (! keepAnnotations) mods = mods.withAnnotations(Nil )
378
+ tparam.withMods(mods & EmptyFlags | Param )
379
+ }
380
+ private def toDefParam (vparam : ValDef , keepAnnotations : Boolean ): ValDef = {
381
+ var mods = vparam.rawMods
382
+ if (! keepAnnotations) mods = mods.withAnnotations(Nil )
383
+ vparam.withMods(mods & (GivenOrImplicit | Erased ) | Param )
384
+ }
381
385
382
386
/** The expansion of a class definition. See inline comments for what is involved */
383
387
def classDef (cdef : TypeDef )(implicit ctx : Context ): Tree = {
@@ -439,7 +443,7 @@ object desugar {
439
443
else originalTparams
440
444
}
441
445
else originalTparams
442
- val constrTparams = impliedTparams.map(toDefParam)
446
+ val constrTparams = impliedTparams.map(toDefParam(_, keepAnnotations = false ) )
443
447
val constrVparamss =
444
448
if (originalVparamss.isEmpty) { // ensure parameter list is non-empty
445
449
if (isCaseClass && originalTparams.isEmpty)
@@ -449,7 +453,7 @@ object desugar {
449
453
ctx.error(" Case classes should have a non-implicit parameter list" , namePos)
450
454
ListOfNil
451
455
}
452
- else originalVparamss.nestedMap(toDefParam)
456
+ else originalVparamss.nestedMap(toDefParam(_, keepAnnotations = false ) )
453
457
val constr = cpy.DefDef (constr1)(tparams = constrTparams, vparamss = constrVparamss)
454
458
455
459
val (normalizedBody, enumCases, enumCompanionRef) = {
@@ -461,7 +465,7 @@ object desugar {
461
465
defDef(
462
466
addEvidenceParams(
463
467
cpy.DefDef (ddef)(tparams = constrTparams),
464
- evidenceParams(constr1).map(toDefParam))))
468
+ evidenceParams(constr1).map(toDefParam(_, keepAnnotations = false ) ))))
465
469
case stat =>
466
470
stat
467
471
}
@@ -484,8 +488,19 @@ object desugar {
484
488
485
489
def anyRef = ref(defn.AnyRefAlias .typeRef)
486
490
487
- val derivedTparams = constrTparams.map(derivedTypeParam(_))
488
- val derivedVparamss = constrVparamss.nestedMap(derivedTermParam(_))
491
+ // Annotations are dropped from the constructor parameters but should be
492
+ // preserved in all derived parameters.
493
+ val derivedTparams = {
494
+ val impliedTparamsIt = impliedTparams.toIterator
495
+ constrTparams.map(tparam => derivedTypeParam(tparam)
496
+ .withAnnotations(impliedTparamsIt.next().mods.annotations))
497
+ }
498
+ val derivedVparamss = {
499
+ val constrVparamsIt = constrVparamss.toIterator.flatten
500
+ constrVparamss.nestedMap(vparam => derivedTermParam(vparam)
501
+ .withAnnotations(constrVparamsIt.next().mods.annotations))
502
+ }
503
+
489
504
val arity = constrVparamss.head.length
490
505
491
506
val classTycon : Tree = TypeRefTree () // watching is set at end of method
@@ -774,16 +789,20 @@ object desugar {
774
789
}
775
790
776
791
val cdef1 = addEnumFlags {
777
- val originalTparamsIt = impliedTparams.toIterator
778
- val originalVparamsIt = originalVparamss.toIterator.flatten
779
- val tparamAccessors = derivedTparams.map(_.withMods(originalTparamsIt.next().mods))
792
+ val tparamAccessors = {
793
+ val impliedTparamsIt = impliedTparams.toIterator
794
+ derivedTparams.map(_.withMods(impliedTparamsIt.next().mods))
795
+ }
780
796
val caseAccessor = if (isCaseClass) CaseAccessor else EmptyFlags
781
- val vparamAccessors = derivedVparamss match {
782
- case first :: rest =>
783
- first.map(_.withMods(originalVparamsIt.next().mods | caseAccessor)) ++
784
- rest.flatten.map(_.withMods(originalVparamsIt.next().mods))
785
- case _ =>
786
- Nil
797
+ val vparamAccessors = {
798
+ val originalVparamsIt = originalVparamss.toIterator.flatten
799
+ derivedVparamss match {
800
+ case first :: rest =>
801
+ first.map(_.withMods(originalVparamsIt.next().mods | caseAccessor)) ++
802
+ rest.flatten.map(_.withMods(originalVparamsIt.next().mods))
803
+ case _ =>
804
+ Nil
805
+ }
787
806
}
788
807
cpy.TypeDef (cdef : TypeDef )(
789
808
name = className,
0 commit comments