@@ -22,51 +22,71 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
22
22
/** The type `tp` as seen from prefix `pre` and owner `cls`. See the spec
23
23
* for what this means.
24
24
*/
25
- final def asSeenFrom (tp : Type , pre : Type , cls : Symbol ): Type =
26
- new AsSeenFromMap (pre, cls).apply(tp)
27
-
28
- /** The TypeMap handling the asSeenFrom */
29
- class AsSeenFromMap (pre : Type , cls : Symbol ) extends ApproximatingTypeMap {
25
+ final def asSeenFrom (tp : Type , pre : Type , cls : Symbol ): Type = tp match {
26
+ case tp : NamedType =>
27
+ if (tp.symbol.isStatic) tp
28
+ else
29
+ tp.derivedSelect(asSeenFrom(tp.prefix, pre, cls)) match {
30
+ case tp1 : TypeArgRef => tp1.underlying.hiBound
31
+ case tp1 => tp1
32
+ }
33
+ case tp : ThisType => toPrefix(tp, pre, cls, tp.cls, 1 )
34
+ case _ : BoundType => tp
35
+ case _ => new AsSeenFromMap (pre, cls, 1 ).mapOver2(tp)
36
+ }
30
37
31
- def apply (tp : Type ): Type = {
38
+ /** Map a `C.this` type to the right prefix. If the prefix is unstable, and
39
+ * the current variance is <= 0, return a range.
40
+ */
41
+ def toPrefix (tp : Type , pre : Type , cls : Symbol , thiscls : ClassSymbol , variance : Int ): Type = /* >|>*/ ctx.conditionalTraceIndented(TypeOps .track, s " toPrefix( $pre, $cls, $thiscls) " ) /* <|<*/ {
42
+ if ((pre eq NoType ) || (pre eq NoPrefix ) || (cls is PackageClass ))
43
+ tp
44
+ else pre match {
45
+ case pre : SuperType => toPrefix(tp, pre.thistpe, cls, thiscls, variance)
46
+ case _ =>
47
+ if (thiscls.derivesFrom(cls) && pre.baseType(thiscls).exists)
48
+ if (variance > 0 || isLegalPrefix(pre)) pre
49
+ else new AsSeenFromMap (pre, cls, variance).range(pre.bottomType, pre)
50
+ else if ((pre.termSymbol is Package ) && ! (thiscls is Package ))
51
+ toPrefix(tp, pre.select(nme.PACKAGE ), cls, thiscls, variance)
52
+ else
53
+ toPrefix(tp, pre.baseType(cls).normalizedPrefix, cls.owner, thiscls, variance)
54
+ }
55
+ }
32
56
33
- /** Map a `C.this` type to the right prefix. If the prefix is unstable, and
34
- * the current variance is <= 0, return a range.
35
- */
36
- def toPrefix (pre : Type , cls : Symbol , thiscls : ClassSymbol ): Type = /* >|>*/ ctx.conditionalTraceIndented(TypeOps .track, s " toPrefix( $pre, $cls, $thiscls) " ) /* <|<*/ {
37
- if ((pre eq NoType ) || (pre eq NoPrefix ) || (cls is PackageClass ))
38
- tp
39
- else pre match {
40
- case pre : SuperType => toPrefix(pre.thistpe, cls, thiscls)
41
- case _ =>
42
- if (thiscls.derivesFrom(cls) && pre.baseType(thiscls).exists)
43
- if (variance <= 0 && ! isLegalPrefix(pre)) range(pre.bottomType, pre)
44
- else pre
45
- else if ((pre.termSymbol is Package ) && ! (thiscls is Package ))
46
- toPrefix(pre.select(nme.PACKAGE ), cls, thiscls)
47
- else
48
- toPrefix(pre.baseType(cls).normalizedPrefix, cls.owner, thiscls)
49
- }
50
- }
57
+ /** The TypeMap handling the asSeenFrom */
58
+ class AsSeenFromMap (pre : Type , cls : Symbol , v : Int ) extends ApproximatingTypeMap {
59
+ variance = v
51
60
52
- /* >|>*/ ctx.conditionalTraceIndented(TypeOps .track, s " asSeen ${tp.show} from ( ${pre.show}, ${cls.show}) " , show = true ) /* <|<*/ { // !!! DEBUG
53
- // All cases except for ThisType are the same as in Map. Inlined for performance
54
- // TODO: generalize the inlining trick?
61
+ def apply (tp : Type ): Type =
62
+ /* >|> ctx.conditionalTraceIndented(TypeOps.track, s"asSeen ${tp.show} from (${pre.show}, ${cls.show})", show = true) <|<*/ { // !!! DEBUG
55
63
tp match {
56
64
case tp : NamedType =>
57
- val sym = tp.symbol
58
- if (sym.isStatic) tp
65
+ if (tp.symbol.isStatic) tp
59
66
else derivedSelect(tp, atVariance(variance max 0 )(this (tp.prefix)))
60
- case tp : ThisType =>
61
- toPrefix(pre, cls, tp.cls)
62
- case _ : BoundType | NoPrefix =>
63
- tp
64
- case tp : RefinedType => // @!!!
65
- derivedRefinedType(tp, apply(tp.parent), apply(tp.refinedInfo))
66
- case _ =>
67
- mapOver(tp)
67
+ case tp : ThisType => toPrefix(tp, pre, cls, tp.cls, variance)
68
+ case _ : BoundType => tp
69
+ case _ => mapOver2(tp)
68
70
}
69
71
}
72
+
73
+ override def mapOver2 (tp : Type ) = tp match {
74
+ case tp : AppliedType =>
75
+ def mapArgs (args : List [Type ], tparams : List [ParamInfo ]): List [Type ] = args match {
76
+ case arg :: otherArgs =>
77
+ val arg1 = arg match {
78
+ case arg : TypeBounds => this (arg)
79
+ case arg => atVariance(variance * tparams.head.paramVariance)(this (arg))
80
+ }
81
+ val otherArgs1 = mapArgs(otherArgs, tparams.tail)
82
+ if ((arg1 eq arg) && (otherArgs1 eq otherArgs)) args
83
+ else arg1 :: otherArgs1
84
+ case nil =>
85
+ nil
86
+ }
87
+ derivedAppliedType(tp, this (tp.tycon), mapArgs(tp.args, tp.typeParams))
88
+ case _ =>
89
+ mapOver3(tp)
70
90
}
71
91
72
92
override def reapply (tp : Type ) =
0 commit comments