Skip to content

Commit 98ef469

Browse files
committed
trace logging for as-seen-from
1 parent ad78fd5 commit 98ef469

File tree

2 files changed

+156
-4
lines changed

2 files changed

+156
-4
lines changed

src/reflect/scala/reflect/internal/tpe/TypeMaps.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ private[internal] trait TypeMaps {
502502
* @param lhs its symbol is a type parameter of `clazz`
503503
* @param rhs a type application constructed from `clazz`
504504
*/
505-
private def correspondingTypeArgument(lhs: Type, rhs: Type): Type = {
505+
protected def correspondingTypeArgument(lhs: Type, rhs: Type): Type = {
506506
val TypeRef(_, lhsSym, lhsArgs) = lhs: @unchecked
507507
val TypeRef(_, rhsSym, rhsArgs) = rhs: @unchecked
508508
require(lhsSym.owner == rhsSym, s"$lhsSym is not a type parameter of $rhsSym")
@@ -551,7 +551,7 @@ private[internal] trait TypeMaps {
551551
// are not influenced by the prefix through which they are seen. Note that type params of
552552
// anonymous type functions, which currently can only arise from normalising type aliases, are
553553
// owned by the type alias of which they are the eta-expansion.
554-
private def classParameterAsSeen(classParam: TypeRef): Type = {
554+
protected def classParameterAsSeen(classParam: TypeRef): Type = {
555555
val tparam = classParam.sym
556556

557557
@tailrec
@@ -574,7 +574,7 @@ private[internal] trait TypeMaps {
574574
}
575575

576576
// Does the candidate symbol match the given prefix and class?
577-
private def matchesPrefixAndClass(pre: Type, clazz: Symbol)(candidate: Symbol) = (clazz == candidate) && {
577+
protected def matchesPrefixAndClass(pre: Type, clazz: Symbol)(candidate: Symbol) = (clazz == candidate) && {
578578
val pre1 = pre match {
579579
case tv: TypeVar =>
580580
// Needed with existentials in prefixes, e.g. test/files/pos/typevar-in-prefix.scala
@@ -633,7 +633,7 @@ private[internal] trait TypeMaps {
633633
}
634634
}
635635

636-
private def thisTypeAsSeen(tp: ThisType): Type = {
636+
protected def thisTypeAsSeen(tp: ThisType): Type = {
637637
@tailrec
638638
def loop(pre: Type, clazz: Symbol): Type = {
639639
val pre1 = pre match {
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package scala.reflect.internal
2+
3+
import org.junit.Assert._
4+
import org.junit.runner.RunWith
5+
import org.junit.runners.JUnit4
6+
import org.junit.{After, Assert, Before, Test}
7+
8+
import scala.annotation.StaticAnnotation
9+
import scala.collection.mutable
10+
import scala.language.existentials
11+
import scala.tools.nsc.settings.ScalaVersion
12+
import scala.tools.nsc.symtab.SymbolTableForUnitTesting
13+
14+
@RunWith(classOf[JUnit4])
15+
class AsSeenFromTest {
16+
17+
object symbolTable extends SymbolTableForUnitTesting
18+
19+
import symbolTable._
20+
import definitions._
21+
22+
type EmptyList[A] = Nil.type
23+
24+
class ann[A] extends StaticAnnotation
25+
26+
trait A[B] {
27+
def foo: B
28+
trait A_I {
29+
def foo: B
30+
}
31+
}
32+
33+
trait B extends A[Int] {
34+
trait B_I extends A_I
35+
}
36+
37+
trait C extends A[Int] {
38+
trait B_I extends A[String]
39+
}
40+
@Test
41+
def asSeenFrom(): Unit = {
42+
assertEquals(typeOf[Int], fooResult(typeOf[B]))
43+
assertEquals(typeOf[Int], fooResult(typeOf[B#B_I]))
44+
assertEquals(typeOf[String], fooResult(typeOf[C#B_I]))
45+
}
46+
47+
object asSeenFrom2Types {
48+
49+
trait O1[O1_A] {
50+
type O1_A_Alias = O1_A
51+
trait I1[I1_A] {
52+
type I1_A_Alias = I1_A
53+
def foo: O1_A_Alias
54+
def bar(x: O1_A_Alias): Unit
55+
}
56+
}
57+
58+
trait O2 extends O1[Int] {
59+
trait I2 extends I1[String] with O1[Nothing] {
60+
self: X =>
61+
bar(self.foo)
62+
}
63+
}
64+
trait X
65+
val o2: O2 = ???
66+
val pre: o2.I2 with X = ???
67+
}
68+
69+
@Test def asSeenFrom2(): Unit = {
70+
import asSeenFrom2Types._
71+
val seenFronTyoe = fooResult(ThisType(symbolOf[O2#I2]))
72+
assertEquals(TypeRef(ThisType(symbolOf[O2]), typeOf[O1[_]].member(TypeName("O1_A_Alias")), Nil), seenFronTyoe)
73+
assertTrue(typeOf[Int] =:= seenFronTyoe)
74+
}
75+
76+
@Test def t21585(): Unit = {
77+
import t21585Types._
78+
79+
// apply(O1.this.O1_A_Alias : NullaryMethodType)
80+
// apply(O1.this.O1_A_Alias : AliasNoArgsTypeRef)
81+
// apply(O1.this.type : UniqueThisType)
82+
// thisTypeAsSeen(O1.this.type)
83+
// matchesPrefixAndClass(pre=I2.this.type, class=trait I1)(candidate=trait O1)
84+
// = false
85+
// matchesPrefixAndClass(pre=O2.this.type, class=trait O1)(candidate=trait O1)
86+
// = true
87+
// = O2.this.type
88+
// = O2.this.type
89+
// = O2.this.O1_A_Alias
90+
//= O2.this.O1_A_Alias
91+
val seenFromType = fooResult(ThisType(typeOf[O2].member(TypeName("I2"))))
92+
assertEquals(TypeRef(ThisType(symbolOf[O2]), typeOf[O1[_]].member(TypeName("O1_A_Alias")), Nil), seenFromType)
93+
assertTrue(typeOf[Int] =:= seenFromType)
94+
}
95+
96+
private def fooResult(pre: Type) = {
97+
val member = pre.member(TermName("foo"))
98+
val tpe = member.info
99+
class LoggingAsSeenFromMap(seenFromPrefix: Type, seenFromClass: Symbol, debug: Boolean = false, var indentLevel: Int = 0)
100+
extends AsSeenFromMap(seenFromPrefix, seenFromClass) {
101+
102+
def logged[T](message: String, op: => T): T = if (debug) {
103+
println(s"${" " * indentLevel}${message.replace('\n', ' ')}")
104+
indentLevel += 1
105+
val result = op
106+
indentLevel -= 1
107+
println(s"${" " * indentLevel}= $result")
108+
result
109+
} else op
110+
111+
override def apply(tp: Type): Type = {
112+
logged(s"apply($tp : ${tp.getClass.getSimpleName})", super.apply(tp))
113+
}
114+
115+
override protected def correspondingTypeArgument(lhs: Type, rhs: Type): Type =
116+
logged(s"correspondingTypeArgument($lhs, $rhs)", super.correspondingTypeArgument(lhs, rhs))
117+
override protected def matchesPrefixAndClass(pre: Type, clazz: Symbol)(candidate: Symbol): Boolean =
118+
logged(s"matchesPrefixAndClass(pre=$pre, class=$clazz)(candidate=$candidate)", super.matchesPrefixAndClass(pre, clazz)(candidate))
119+
override protected def classParameterAsSeen(classParam: TypeRef): Type =
120+
logged(s"classParameterAsSeen($classParam)", super.classParameterAsSeen(classParam))
121+
override protected def thisTypeAsSeen(tp: ThisType): Type =
122+
logged(s"thisTypeAsSeen($tp)", super.thisTypeAsSeen(tp))
123+
}
124+
new LoggingAsSeenFromMap(pre, member.owner, debug = true).apply(tpe).resultType
125+
}
126+
}
127+
object t21585Types {
128+
129+
trait O1[O1_A] {
130+
type O1_A_Alias = O1_A
131+
trait I1 {
132+
def foo: O1_A_Alias
133+
def bar(p: O1_A_Alias): Unit = ()
134+
}
135+
}
136+
137+
trait O2 extends O1[Int] {
138+
trait I2 extends I1 with O1[String] {
139+
def goodCodeRed = {
140+
var x = this.foo
141+
x = 1 // good code red
142+
this.bar(1) // good code red
143+
}
144+
145+
// def badCodeGreen = {
146+
// var x = this.foo
147+
// x = "" // bad code green
148+
// this.bar("") // bad code green
149+
// }
150+
}
151+
}
152+
}

0 commit comments

Comments
 (0)