Skip to content

Commit b29bbd7

Browse files
authored
Merge pull request #69 from scalacenter/tasty/typeref-in
Support TERMREFin and TYPEREFin
2 parents 4813edf + de30b8c commit b29bbd7

File tree

8 files changed

+100
-48
lines changed

8 files changed

+100
-48
lines changed

src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -346,24 +346,16 @@ class TreeUnpickler[Tasty <: TastyUniverse](
346346

347347
val result =
348348
(tag: @switch) match {
349-
// case TERMREFin =>
350-
// var sname = readName()
351-
// val prefix = readType()
352-
// val space = readType()
353-
// sname match {
354-
// case SignedName(name, sig) =>
355-
// TermRef(prefix, name, space.decl(name).asSeenFrom(prefix).atSignature(sig))
356-
// case name =>
357-
// TermRef(prefix, name, space.decl(name).asSeenFrom(prefix))
358-
// }
359-
// case TYPEREFin =>
360-
// val name = readName().toTypeName
361-
// val prefix = readType()
362-
// val space = readType()
363-
// space.decl(name) match {
364-
// case symd: SymDenotation if prefix.isArgPrefixOf(symd.symbol) => TypeRef(prefix, symd.symbol)
365-
// case _ => TypeRef(prefix, name, space.decl(name).asSeenFrom(prefix))
366-
// }
349+
case TERMREFin =>
350+
var name = readTastyName()
351+
val prefix = readType()
352+
val space = readType()
353+
selectTerm(prefix, space, name)
354+
case TYPEREFin =>
355+
val name = readTastyName()
356+
val prefix = readType()
357+
val space = readType()
358+
selectType(prefix, space, name)
367359
case REFINEDtype =>
368360
val selected = readEncodedName()
369361
val parent = readType()
@@ -463,13 +455,13 @@ class TreeUnpickler[Tasty <: TastyUniverse](
463455
case TERMREFpkg =>
464456
readPackageRef().termRef
465457
case TYPEREF =>
466-
val name = readTastyName()
467-
val pre = readType()
468-
selectType(pre, name)
458+
val name = readTastyName()
459+
val prefix = readType()
460+
selectType(prefix, prefix, name)
469461
case TERMREF =>
470-
val name = readTastyName()
462+
val name = readTastyName()
471463
val prefix = readType()
472-
selectTerm(prefix, name)
464+
selectTerm(prefix, prefix, name)
473465
case THIS =>
474466
val sym = readType() match {
475467
case tpe: TypeRef => tpe.sym
@@ -1692,7 +1684,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
16921684
// def readLater[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Trees.Lazy[T] =
16931685
// readLaterWithOwner(end, op)(ctx)(ctx.owner)
16941686

1695-
def readLaterWithOwner[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Symbol => Trees.Lazy[T] = {
1687+
def readLaterWithOwner[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Symbol => Trees.Lazy[Option[T]] = {
16961688
val localReader = fork
16971689
goto(end)
16981690
owner => new LazyReader(localReader, owner/*, ctx.mode*/, ctx.source, op)
@@ -1782,14 +1774,23 @@ class TreeUnpickler[Tasty <: TastyUniverse](
17821774

17831775
class LazyReader[T <: AnyRef](
17841776
reader: TreeReader, owner: Symbol/*, mode: Mode*/, source: AbstractFile,
1785-
op: TreeReader => Context => T) extends Trees.Lazy[T] {
1786-
def complete(implicit ctx: Context): T = {
1787-
ctx.log(s"starting to read at ${reader.reader.currentAddr} with owner $owner")
1788-
withPhaseNoLater(ctx.picklerPhase) {
1789-
op(reader)(ctx
1790-
.withOwner(owner))
1791-
// .withModeBits(mode)
1792-
// .withSource(source))
1777+
op: TreeReader => Context => T) extends Trees.Lazy[Option[T]] {
1778+
def complete(implicit ctx: Context): Option[T] = {
1779+
try {
1780+
ctx.log(s"starting to read at ${reader.reader.currentAddr} with owner $owner")
1781+
withPhaseNoLater(ctx.picklerPhase) {
1782+
Some(
1783+
op(reader)(ctx
1784+
.withOwner(owner)
1785+
// .withModeBits(mode)
1786+
// .withSource(source)
1787+
)
1788+
)
1789+
}
1790+
} catch {
1791+
case err: TASTyException =>
1792+
errorTasty(s"${err.getMessage} on ${err.sym}")
1793+
None
17931794
}
17941795
}
17951796
}

src/compiler/scala/tools/nsc/tasty/bridge/AnnotationOps.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import scala.tools.nsc.tasty.{SafeEq, TastyUniverse}
55
trait AnnotationOps extends TastyKernel { self: TastyUniverse =>
66

77
object Annotation {
8-
def deferredSymAndTree(annotee: Symbol)(symf: => Symbol)(tree: => Tree)(implicit ctx: Contexts.Context): Annotation =
8+
def deferredSymAndTree(annotee: Symbol)(symf: => Symbol)(tree: => Option[Tree])(implicit ctx: Contexts.Context): Annotation =
99
new symbolTable.LazyAnnotationInfo({
1010
val annotSym = symf
11-
val annotTree = tree
11+
val annotTree = tree.getOrElse(emptyTree)
1212
val isChild = defn.childAnnotationClass.exists(annotSym === _)
1313
ctx.log(s"annotation of $annotee = $annotTree")
1414
if (isChild) symbolTable.AnnotationInfo(annotTree.tpe, Nil, Nil)

src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ trait SymbolOps extends TastyKernel { self: TastyUniverse =>
3333
}
3434
}
3535

36-
def selectSymFromSig(qualType: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Option[(Int, Symbol)] = {
37-
ctx.log(s"""looking for overload member[$qualType]("$name") @@ ${sig.show}""")
36+
def selectSymFromSig(space: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Option[(Int, Symbol)] = {
37+
ctx.log(s"""looking for overload member[$space]("$name") @@ ${sig.show}""")
3838
val MethodSignature(args, ret) = sig
3939
var seenTypeParams = false
40-
val member = qualType.member(name)
40+
val member = space.member(name)
4141
val (tyParamCount, argsSyms) = {
4242
val (tyParamCounts, params) = args.partitionMap(identity)
4343
if (tyParamCounts.length > 1) {
@@ -54,7 +54,7 @@ trait SymbolOps extends TastyKernel { self: TastyUniverse =>
5454
|| tyParamCount === sym.typeParams.length) &&
5555
params.zip(argsSyms).forall { case (param, tpe) => param.tpe.erasure =:= tpe }
5656
case _ =>
57-
ctx.log(s"""member[$qualType]("$name") ${showSym(sym)} is not a method""")
57+
ctx.log(s"""member[$space]("$name") ${showSym(sym)} is not a method""")
5858
false
5959
}
6060
member.asTerm.alternatives.find(compareSym).map(tyParamCount -> _)

src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
124124
*/
125125
case object AndType extends Type
126126

127-
def selectType(pre: Type, name: TastyName)(implicit ctx: Context): Type = {
127+
def selectType(pre: Type, space: Type, name: TastyName)(implicit ctx: Context): Type = {
128128
if (pre.typeSymbol === defn.ScalaPackage && ( name === nme.And || name === nme.Or ) ) {
129129
if (name === nme.And) {
130130
AndType
@@ -135,12 +135,12 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
135135
}
136136
}
137137
else {
138-
selectFromPrefix(pre, name, selectingTerm = false)
138+
selectFromSpaceWithPrefix(pre, space, name, selectingTerm = false)
139139
}
140140
}
141141

142-
def selectTerm(pre: Type, name: TastyName)(implicit ctx: Context): Type =
143-
selectFromPrefix(pre, name, selectingTerm = true)
142+
def selectTerm(pre: Type, space: Type, name: TastyName)(implicit ctx: Context): Type =
143+
selectFromSpaceWithPrefix(pre, space, name, selectingTerm = true)
144144

145145
/**
146146
* Ported from dotc
@@ -190,32 +190,41 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
190190
}
191191
}
192192

193-
private def selectSymFromSig0(qualType: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Either[String,(Int, Symbol)] =
194-
selectSymFromSig(qualType, name, sig).toRight(s"No matching overload of $qualType.$name with signature ${sig.show}")
193+
private def selectSymFromSig0(space: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Either[String,(Int, Symbol)] =
194+
selectSymFromSig(space, name, sig).toRight(s"No matching overload of $space.$name with signature ${sig.show}")
195195

196196
private def reportThenErrorTpe(msg: String): Type = {
197197
reporter.error(noPosition, msg)
198198
errorType
199199
}
200200

201201
def selectFromPrefix(pre: Type, name: TastyName, selectingTerm: Boolean)(implicit ctx: Context): Type = {
202+
selectFromSpaceWithPrefix(pre, pre, name, selectingTerm)
203+
}
204+
205+
def selectFromSpaceWithPrefix(pre: Type, space: Type, name: TastyName, selectingTerm: Boolean)(implicit ctx: Context): Type = {
202206
val encoded = name.toEncodedTermName
203207
val selector = if (selectingTerm) encoded else encoded.toTypeName
204208
def debugSelectedSym(sym: Symbol): Symbol = {
205209
ctx.log(s"selected ${showSym(sym)} : ${sym.tpe}")
206210
sym
207211
}
212+
def memberOfSpace(space: Type, name: Name): Symbol = {
213+
def lookInTypeCtor = space.typeConstructor.typeParams.filter(_.name == name).headOption.getOrElse(noSymbol)
214+
val fetched = space.member(name)
215+
if (name.isTypeName) fetched.orElse(lookInTypeCtor) else fetched
216+
}
208217
val resolved = name match {
209218
case SignedName(_, sig) =>
210-
selectSymFromSig0(pre, selector, sig.map(erasedNameToErasedType)).map(pair => debugSelectedSym(pair._2))
211-
case _ => Right(pre.member(selector))
219+
selectSymFromSig0(space, selector, sig.map(erasedNameToErasedType)).map(pair => debugSelectedSym(pair._2))
220+
case _ => Right(memberOfSpace(space, selector))
212221
}
213222
val tpeOrErr = resolved.map(sym => NamedType(pre, if (name.isModuleName) sym.linkedClassOfClass else sym))
214223
tpeOrErr.fold(reportThenErrorTpe, identity)
215224
}
216225

217-
def selectFromSig(qualType: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Type = {
218-
val tpeOrErr = selectSymFromSig0(qualType, name, sig).map {
226+
def selectFromSig(space: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Type = {
227+
val tpeOrErr = selectSymFromSig0(space, name, sig).map {
219228
case (tyParamCount, sym) =>
220229
var tpe = sym.tpe
221230
if (name === nme.CONSTRUCTOR && tyParamCount > 0) tpe = mkPolyType(sym.owner.typeParams, tpe)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package tastytest
2+
3+
object TestTermRefIns extends Suite("TestTermRefIns") {
4+
5+
def extractConfig(config: GenericConfig): String = config match {
6+
case embedded: EmbeddedConfig => embedded.config
7+
}
8+
9+
test(assert(extractConfig(Configurations.defaultConfig) === "config"))
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package tastytest
2+
3+
object TestTypeRefIns extends Suite("TestTypeRefIns") {
4+
5+
test(assert(TypeRefIns.b == 1))
6+
7+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package tastytest
2+
3+
trait GenericConfig
4+
5+
sealed trait EmbeddedConfig extends GenericConfig { // scala.annotation.internal.Child annotation with TERMREFin argument
6+
val config: String
7+
}
8+
9+
trait DefaultConfigs {
10+
11+
val defaultConfig: EmbeddedConfig = PrivateConfig
12+
13+
private case object PrivateConfig extends EmbeddedConfig {
14+
val config: String = "config"
15+
}
16+
17+
}
18+
object Configurations extends DefaultConfigs
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package tastytest
2+
3+
object TypeRefIns {
4+
type Id[A] >: A
5+
val a: Array[_ >: Id[Int]] = Array(1, 2)
6+
val b = a(0) // inferred TYPEREFin
7+
}

0 commit comments

Comments
 (0)