Skip to content

Commit 14cd342

Browse files
committed
fix #25 - Handle a signed name in a TERMREF
1 parent f21d101 commit 14cd342

File tree

5 files changed

+79
-45
lines changed

5 files changed

+79
-45
lines changed

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

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
251251
/** The symbol defined by current definition */
252252
def symbolAtCurrent()(implicit ctx: Context): Symbol = symAtAddr.get(currentAddr) match {
253253
case Some(sym) =>
254-
assert(ctx.owner === sym.owner, s"owner discrepancy for $sym, expected: ${showSym(ctx.owner)}, found: ${showSym(sym.owner)}")
254+
assert(ctx.owner === sym.owner, s"owner discrepancy for ${showSym(sym)}, expected: ${showSym(ctx.owner)}, found: ${showSym(sym.owner)}")
255255
sym
256256
case None =>
257257
createSymbol()
@@ -408,7 +408,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
408408
readPackageRef().termRef
409409
case TYPEREF =>
410410
val name = readTastyName()
411-
val pre = readType()
411+
val pre = readType()
412412
if (pre.typeSymbol === defn.ScalaPackage && ( name === nme.And || name === nme.Or) ) {
413413
if (name === nme.And) {
414414
AndType
@@ -419,17 +419,12 @@ class TreeUnpickler[Tasty <: TastyUniverse](
419419
}
420420
}
421421
else {
422-
mkTypeRef(pre, name, isTerm = false)
422+
mkTypeRef(pre, name, selectingTerm = false)
423423
}
424424
case TERMREF =>
425-
val sname = readTastyName()
425+
val sname = readTastyName()
426426
val prefix = readType()
427-
sname match {
428-
case TastyName.SignedName(name, sig) =>
429-
??? // TermRef(prefix, name, prefix.member(name).atSignature(sig))
430-
case name =>
431-
mkTypeRef(prefix, name, isTerm = true)
432-
}
427+
mkTypeRef(prefix, sname, selectingTerm = true)
433428
case THIS =>
434429
val sym = readType() match {
435430
case tpe: TypeRef => tpe.sym
@@ -447,7 +442,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
447442
case RECthis =>
448443
sys.error("RECthis")//readTypeRef().asInstanceOf[RecType].recThis
449444
case TYPEALIAS =>
450-
readType()// TypeAlias(readType())
445+
readType()// TypeAlias(readType())
451446
case SHAREDtype =>
452447
val ref = readAddr()
453448
typeAtAddr.getOrElseUpdate(ref, forkAt(ref).readType())
@@ -858,7 +853,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
858853
val tname = readTastyName()
859854
val name = tname.toEncodedTermName
860855

861-
ctx.log(s"completing member $name at $symAddr. (sym=${showSym(sym)})")
856+
ctx.log(s"completing member $name at $symAddr. ${showSym(sym)}")
862857

863858
val completer = sym.completer
864859

@@ -949,7 +944,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
949944
}
950945
case _ => sys.error(s"Reading new member with tag ${astTagToString(tag)}")
951946
}
952-
ctx.log(s"typed { ($sym # ${sym.hashCode}): ${sym.tpe} } in (owner=${showSym(sym.owner)})")
947+
ctx.log(s"typed ${showSym(sym)} : ${sym.tpe} in owner ${showSym(sym.owner)}")
953948
goto(end)
954949
noCycle
955950
}
@@ -1272,32 +1267,6 @@ class TreeUnpickler[Tasty <: TastyUniverse](
12721267
readIndexedParams(tag)
12731268
}
12741269

1275-
def selectFromSig(qualType: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Type = {
1276-
ctx.log(s"looking for overloaded method on $qualType.$name of signature ${sig.show}")
1277-
val MethodSignature(args, ret) = sig
1278-
var seenTypeParams = false
1279-
val (tyParamCount, argsSyms) = {
1280-
val (tyParamCounts, params) = args.partitionMap(identity)
1281-
assertTasty(tyParamCounts.length <= 1, s"Multiple type parameter lists on signature ${sig.show} for member $name.")
1282-
(tyParamCounts.headOption.getOrElse(0), params)
1283-
}
1284-
val member = qualType.member(name)
1285-
val alts = member.asTerm.alternatives
1286-
val tpeOpt = alts.find { sym =>
1287-
val method = sym.asMethod
1288-
val params = method.paramss.flatten
1289-
method.returnType.erasure =:= ret &&
1290-
params.length === argsSyms.length &&
1291-
((name === nme.CONSTRUCTOR && tyParamCount === member.owner.typeParams.length)
1292-
|| tyParamCount === method.typeParams.length) &&
1293-
params.zip(argsSyms).forall { case (param, tpe) => param.tpe.erasure =:= tpe }
1294-
}.map(_.tpe).ensuring(_.isDefined, s"No matching overload of $name with signature ${sig.show}")
1295-
var Some(tpe) = tpeOpt
1296-
if (name === nme.CONSTRUCTOR && tyParamCount > 0) tpe = mkPolyType(member.owner.typeParams, tpe)
1297-
ctx.log(s"selected $tpe")
1298-
tpe
1299-
}
1300-
13011270
def completeSelection[T](name: TastyName, sig: Signature[Type], isTerm: Boolean)(f: (Context, Name, (Context, Name, Type) => Type) => T)(implicit ctx: Context): T = {
13021271
val encoded = name.toEncodedTermName
13031272
val selector = if (isTerm) encoded else encoded.toTypeName

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package scala.tools.nsc.tasty.bridge
22

3+
import scala.tools.nsc.tasty.SafeEq
4+
35
import scala.tools.nsc.tasty.TastyUniverse
6+
import scala.tools.nsc.tasty.Signature
7+
import scala.tools.nsc.tasty.Signature.MethodSignature
48

59
trait SymbolOps extends TastyKernel { self: TastyUniverse =>
10+
import Contexts.Context
611

712
object SymbolOps {
813
implicit class SymbolDecorator(sym: Symbol) {
@@ -26,5 +31,29 @@ trait SymbolOps extends TastyKernel { self: TastyUniverse =>
2631
}
2732
}
2833

29-
def showSym(sym: Symbol): String = s"$sym # ${sym.hashCode}"
34+
def selectSymFromSig(qualType: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Option[(Int, Symbol)] = {
35+
ctx.log(s"""looking for overloaded method [$qualType]("$name") @@ ${sig.show}""")
36+
val MethodSignature(args, ret) = sig
37+
var seenTypeParams = false
38+
val member = qualType.member(name)
39+
val (tyParamCount, argsSyms) = {
40+
val (tyParamCounts, params) = args.partitionMap(identity)
41+
if (tyParamCounts.length > 1) {
42+
reporter.error(noPosition, s"Multiple type parameter lists on signature ${sig.show} for $member.")
43+
}
44+
(tyParamCounts.headOption.getOrElse(0), params)
45+
}
46+
val alts = member.asTerm.alternatives
47+
alts.find { sym =>
48+
val method = sym.asMethod
49+
val params = method.paramss.flatten
50+
method.returnType.erasure =:= ret &&
51+
params.length === argsSyms.length &&
52+
((name === nme.CONSTRUCTOR && tyParamCount === member.owner.typeParams.length)
53+
|| tyParamCount === method.typeParams.length) &&
54+
params.zip(argsSyms).forall { case (param, tpe) => param.tpe.erasure =:= tpe }
55+
}.map(tyParamCount -> _)
56+
}
57+
58+
def showSym(sym: Symbol): String = s"Symbol($sym, #${sym.hashCode})"
3059
}

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

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import scala.tools.nsc.tasty.Names.TastyName.SimpleName
88

99
import scala.tools.nsc.tasty._
1010
import scala.tools.nsc.tasty.Names.TastyName.ModuleName
11+
import scala.tools.nsc.tasty.Names.TastyName.SignedName
1112

1213
trait TypeOps extends TastyKernel { self: TastyUniverse =>
1314
import Contexts._
@@ -97,12 +98,40 @@ trait TypeOps extends TastyKernel { self: TastyUniverse =>
9798
}
9899
}
99100

100-
def mkTypeRef(tpe: Type, name: TastyName, isTerm: Boolean): Type = {
101+
private def selectSymFromSig0(qualType: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Either[String,(Int, Symbol)] =
102+
selectSymFromSig(qualType, name, sig).toRight(s"No matching overload of $qualType.$name with signature ${sig.show}")
103+
104+
private def reportThenErrorTpe(msg: String): Type = {
105+
reporter.error(noPosition, msg)
106+
errorType
107+
}
108+
109+
def mkTypeRef(tpe: Type, name: TastyName, selectingTerm: Boolean)(implicit ctx: Context): Type = {
101110
import NameOps._
102-
val encoded = name.toEncodedTermName
103-
val member = tpe.member(if (isTerm) encoded else encoded.toTypeName)
104-
val sym = if (name.isModuleName) member.linkedClassOfClass else member
105-
NamedType(tpe, sym)
111+
val encoded = name.toEncodedTermName
112+
val selector = if (selectingTerm) encoded else encoded.toTypeName
113+
def debugSelectedSym(sym: Symbol): Symbol = {
114+
ctx.log(s"selected ${showSym(sym)} : ${sym.tpe}")
115+
sym
116+
}
117+
val resolved = name match {
118+
case SignedName(qual, sig) =>
119+
selectSymFromSig0(tpe, selector, sig.map(erasedNameToErasedType)).map(pair => debugSelectedSym(pair._2))
120+
case _ => Right(tpe.member(selector))
121+
}
122+
val tpeOrErr = resolved.map(sym => NamedType(tpe, if (name.isModuleName) sym.linkedClassOfClass else sym))
123+
tpeOrErr.fold(reportThenErrorTpe, identity)
124+
}
125+
126+
def selectFromSig(qualType: Type, name: Name, sig: Signature[Type])(implicit ctx: Context): Type = {
127+
val tpeOrErr = selectSymFromSig0(qualType, name, sig).map {
128+
case (tyParamCount, sym) =>
129+
var tpe = sym.tpe
130+
if (name === nme.CONSTRUCTOR && tyParamCount > 0) tpe = mkPolyType(sym.owner.typeParams, tpe)
131+
ctx.log(s"selected ${showSym(sym)} : $tpe")
132+
tpe
133+
}
134+
tpeOrErr.fold(reportThenErrorTpe, identity)
106135
}
107136

108137
abstract class LambdaTypeCompanion[N <: Name, PInfo <: Type, LT <: LambdaType] {

test/tasty/run/src-2/tastytest/TestHello.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ object TestHello extends Suite("TestHello") {
1616
test(assert(HelloWorld.func1(33) === 33))
1717
test(assert((HelloWorld.lzy: "lazy") === "lazy"))
1818
test(assert(HelloWorld.acceptsOnlyMsg3(HelloWorld.msg3) === "Hello, World!Hello, World!"))
19+
test(assert(HelloWorld.withArgAnnot("arg") === ("arg" : Any)))
1920
// test(assert(HelloWorld.`<init>` === 157)) // wait until https://github.com/lampepfl/dotty/issues/7799
2021

2122
}

test/tasty/run/src-3/tastytest/HelloWorld.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package tastytest
22

3+
import scala.annotation.StaticAnnotation
4+
35
object HelloWorld {
6+
7+
class argAnnot(arg: Any) extends StaticAnnotation
8+
49
val msg1: String = "Hello, World!"
510
def msg2: String = "Hello, World!"
611
final val msg3 = "Hello, World!"
@@ -16,5 +21,6 @@ object HelloWorld {
1621
def func1[A]: A => A = x => x
1722
def acceptsOnlyMsg3(m: msg3.type): String = m + m
1823
final lazy val lzy = "lazy"
24+
def withArgAnnot(arg: Any @argAnnot(??? : Int)): Any = arg
1925
// def `<init>`: Int = 157 // broken in https://github.com/lampepfl/dotty/issues/7799
2026
}

0 commit comments

Comments
 (0)