Skip to content

Commit

Permalink
Support TASTy 25.1 (Scala 3.0.0 M2)
Browse files Browse the repository at this point in the history
this commit does not implement backwards compatability for
tasty unpickling, perhaps that may be desireable
  • Loading branch information
bishabosha committed Dec 2, 2020
1 parent 2b17fa9 commit fa45a3b
Show file tree
Hide file tree
Showing 33 changed files with 219 additions and 189 deletions.
4 changes: 2 additions & 2 deletions project/DottySupport.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import sbt.librarymanagement.{
* Settings to support validation of TastyUnpickler against the release of dotty with the matching TASTy version
*/
object TastySupport {
val supportedTASTyRelease = "3.0.0-M1-bin-20201026-ac4e29d-NIGHTLY" // TASTy version 24
val scala3Compiler = "org.scala-lang" % "scala3-compiler_3.0.0-M1" % supportedTASTyRelease
val supportedTASTyRelease = "3.0.0-M2" // TASTy version 25.1
val scala3Compiler = "org.scala-lang" % "scala3-compiler_3.0.0-M2" % supportedTASTyRelease
}

/** Settings needed to compile with Dotty,
Expand Down
19 changes: 13 additions & 6 deletions src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object TastyUnpickler {
val unpickler = new TastyUnpickler[tasty.type](new TastyReader(bytes))(tasty)
unpickler.readHeader()
unpickler.readNames()
val Some(astReader) = unpickler.readSection("ASTs"): @unchecked
val Some(astReader) = unpickler.readSection(TastyFormat.ASTsSection): @unchecked
val treeUnpickler = new TreeUnpickler[tasty.type](astReader, unpickler.nameAtRef)(tasty)
treeUnpickler.enterTopLevel(classRoot, objectRoot)
}
Expand Down Expand Up @@ -84,6 +84,12 @@ private class TastyUnpickler[Tasty <: TastyUniverse](reader: TastyReader)(implic
ctx.log(s"${nameTable.size}: ${name.debug}")
name
}
def readSignedRest(original: TastyName, target: TastyName): TastyName = {
val result = ErasedTypeRef(readName())
val paramsSig = until(end)(readParamSig())
val sig = Signature(paramsSig, result)
debugName(SignedName(original, sig, target))
}
val result = tag match {
case UTF8 =>
goto(end)
Expand All @@ -103,12 +109,13 @@ private class TastyUnpickler[Tasty <: TastyUniverse](reader: TastyReader)(implic
debugName(UniqueName(original, separator, num))
case DEFAULTGETTER =>
debugName(DefaultName(readName(), readNat()))
case TARGETSIGNED =>
val original = readName()
val target = readName()
readSignedRest(original, target)
case SIGNED =>
val original = readName()
val result = ErasedTypeRef(readName())
val paramsSig = until(end)(readParamSig())
val sig = Signature(paramsSig, result)
debugName(SignedName(original, sig))
val original = readName()
readSignedRest(original, original)
case OBJECTCLASS =>
debugName(ObjectName(readName()))
case BODYRETAINER =>
Expand Down
11 changes: 6 additions & 5 deletions src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
case ANDtype => defn.IntersectionType(readType(), readType())
case ORtype => unionIsUnsupported
case SUPERtype => defn.SuperType(readType(), readType())
case MATCHtype => matchTypeIsUnsupported
case MATCHtype | MATCHCASEtype => matchTypeIsUnsupported
case POLYtype => readMethodic(Function.const(PolyType), _.toTypeName)
case METHODtype =>
def companion(mods0: TastyFlagSet) = {
Expand Down Expand Up @@ -579,7 +579,8 @@ class TreeUnpickler[Tasty <: TastyUniverse](
case STATIC => addFlag(Static)
case OBJECT => addFlag(Object)
case TRAIT => addFlag(Trait)
case SUPERTRAIT => addFlag(SuperTrait)
case TRANSPARENT => addFlag(Transparent)
case INFIX => addFlag(Infix)
case ENUM => addFlag(Enum)
case LOCAL => addFlag(Local)
case SYNTHETIC => addFlag(Synthetic)
Expand Down Expand Up @@ -720,7 +721,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
tag match {
case DEFDEF =>
val isMacro = repr.originalFlagSet.is(Erased | Macro)
checkUnsupportedFlags(repr.tastyOnlyFlags &~ (Extension | Exported | optFlag(isMacro)(Erased)))
checkUnsupportedFlags(repr.tastyOnlyFlags &~ (Extension | Exported | Infix | optFlag(isMacro)(Erased)))
val isCtor = sym.isConstructor
val typeParams = {
if (isCtor) {
Expand Down Expand Up @@ -767,8 +768,8 @@ class TreeUnpickler[Tasty <: TastyUniverse](
else tpe
)
case TYPEDEF | TYPEPARAM =>
val allowedTypeFlags = Enum | Open | Exported | SuperTrait
val allowedClassFlags = allowedTypeFlags | Opaque
val allowedTypeFlags = Enum | Open | Exported | Infix
val allowedClassFlags = allowedTypeFlags | Opaque | Transparent
if (sym.isClass) {
checkUnsupportedFlags(repr.tastyOnlyFlags &~ allowedClassFlags)
sym.owner.ensureCompleted()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ trait AnnotationOps { self: TastyUniverse =>
ctx.log(s"annotation on $annotee: $atree")
val annot = mkAnnotation(atree)
val annotSym = annot.tpe.typeSymbol
if ((annotSym eq defn.AlphaAnnotationClass) || (annotSym eq defn.StaticMethodAnnotationClass)) {
if ((annotSym eq defn.TargetNameAnnotationClass) || (annotSym eq defn.StaticMethodAnnotationClass)) {
annotee.addAnnotation(
u.definitions.CompileTimeOnlyAttr,
u.Literal(u.Constant(unsupportedMessage(s"annotation on $annotee: @$annot"))))
Expand Down
35 changes: 18 additions & 17 deletions src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ trait FlagOps { self: TastyUniverse =>

object FlagSets {
val TastyOnlyFlags: TastyFlagSet = (
Erased | Internal | Inline | InlineProxy | Opaque | Extension | Given | Exported | SuperTrait | Enum
Erased | Internal | Inline | InlineProxy | Opaque | Extension | Given | Exported | Transparent | Enum | Infix
| Open | ParamAlias
)
val TermParamOrAccessor: TastyFlagSet = Param | ParamSetter
Expand Down Expand Up @@ -75,21 +75,22 @@ trait FlagOps { self: TastyUniverse =>
def showTasty(flags: TastyFlagSet): String = { // keep up to date with with FlagSets.TastyOnlyFlags
val tflags = flags & FlagSets.TastyOnlyFlags
if (!tflags) "EmptyTastyFlags"
else (tflags).toSingletonSets.map { f =>
(f: @unchecked) match {
case Erased => "erased"
case Internal => "<internal>"
case Inline => "inline"
case InlineProxy => "<inlineproxy>"
case Opaque => "opaque"
case Extension => "<extension>"
case Given => "given"
case Exported => "<exported>"
case SuperTrait => "<supertrait>"
case Enum => "enum"
case Open => "open"
case ParamAlias => "<paramalias>"
}
} mkString(" | ")
else {
val sb = collection.mutable.ArrayBuffer.empty[String]
if (flags.is(Erased)) sb += "erased"
if (flags.is(Internal)) sb += "<internal>"
if (flags.is(Inline)) sb += "inline"
if (flags.is(InlineProxy)) sb += "<inlineproxy>"
if (flags.is(Opaque)) sb += "opaque"
if (flags.is(Extension)) sb += "<extension>"
if (flags.is(Given)) sb += "given"
if (flags.is(Exported)) sb += "<exported>"
if (flags.is(Transparent)) sb += "transparent"
if (flags.is(Enum)) sb += "enum"
if (flags.is(Open)) sb += "open"
if (flags.is(ParamAlias)) sb += "<paramalias>"
if (flags.is(Infix)) sb += "infix"
sb.mkString(" | ")
}
}
}
65 changes: 35 additions & 30 deletions src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ trait SymbolOps { self: TastyUniverse =>
termParamss

def namedMemberOfType(space: Type, tname: TastyName)(implicit ctx: Context): Symbol = tname match {
case SignedName(qual, sig) => signedMemberOfSpace(space, qual, sig.map(_.encode))
case _ => memberOfSpace(space, tname)
case SignedName(qual, sig, target) => signedMemberOfSpace(space, qual, sig.map(_.encode), target)
case _ => memberOfSpace(space, tname)
}

private def memberOfSpace(space: Type, tname: TastyName)(implicit ctx: Context): Symbol = {
Expand Down Expand Up @@ -145,37 +145,42 @@ trait SymbolOps { self: TastyUniverse =>
typeError(s"can't find $missing; perhaps it is missing from the classpath.")
}

private def signedMemberOfSpace(space: Type, qual: TastyName, sig: MethodSignature[ErasedTypeRef])(implicit ctx: Context): Symbol = {
ctx.log(s"""<<< looking for overload in symbolOf[$space] @@ $qual: ${showSig(sig)}""")
val member = space.member(encodeTermName(qual))
if (!(isSymbol(member) && hasType(member))) errorMissing(space, qual)
val (tyParamCount, argTpeRefs) = {
val (tyParamCounts, params) = sig.params.partitionMap(identity)
if (tyParamCounts.length > 1) {
unsupportedError(s"multiple type parameter lists on erased method signature ${showSig(sig)}")
}
(tyParamCounts.headOption.getOrElse(0), params)
private def signedMemberOfSpace(space: Type, qual: TastyName, sig: MethodSignature[ErasedTypeRef], target: TastyName)(implicit ctx: Context): Symbol = {
if (target ne qual) {
unsupportedError(s"selection of method $qual with @targetName(" + '"' + target + '"' + ")")
}
def compareSym(sym: Symbol): Boolean = sym match {
case sym: u.MethodSymbol =>
val method = sym.tpe.asSeenFrom(space, sym.owner)
ctx.log(s">>> trying $sym: $method")
val params = method.paramss.flatten
val isJava = sym.isJavaDefined
NameErasure.sigName(method.finalResultType, isJava) === sig.result &&
params.length === argTpeRefs.length &&
(qual === TastyName.Constructor && tyParamCount === member.owner.typeParams.length
|| tyParamCount === sym.typeParams.length) &&
params.zip(argTpeRefs).forall { case (param, tpe) => NameErasure.sigName(param.tpe, isJava) === tpe } && {
ctx.log(s">>> selected ${showSym(sym)}: ${sym.tpe}")
true
else {
ctx.log(s"""<<< looking for overload in symbolOf[$space] @@ $qual: ${showSig(sig)}""")
val member = space.member(encodeTermName(qual))
if (!(isSymbol(member) && hasType(member))) errorMissing(space, qual)
val (tyParamCount, argTpeRefs) = {
val (tyParamCounts, params) = sig.params.partitionMap(identity)
if (tyParamCounts.length > 1) {
unsupportedError(s"multiple type parameter lists on erased method signature ${showSig(sig)}")
}
case _ =>
ctx.log(s"""! member[$space]("$qual") ${showSym(sym)} is not a method""")
false
(tyParamCounts.headOption.getOrElse(0), params)
}
def compareSym(sym: Symbol): Boolean = sym match {
case sym: u.MethodSymbol =>
val method = sym.tpe.asSeenFrom(space, sym.owner)
ctx.log(s">>> trying $sym: $method")
val params = method.paramss.flatten
val isJava = sym.isJavaDefined
NameErasure.sigName(method.finalResultType, isJava) === sig.result &&
params.length === argTpeRefs.length &&
(qual === TastyName.Constructor && tyParamCount === member.owner.typeParams.length
|| tyParamCount === sym.typeParams.length) &&
params.zip(argTpeRefs).forall { case (param, tpe) => NameErasure.sigName(param.tpe, isJava) === tpe } && {
ctx.log(s">>> selected ${showSym(sym)}: ${sym.tpe}")
true
}
case _ =>
ctx.log(s"""! member[$space]("$qual") ${showSym(sym)} is not a method""")
false
}
member.asTerm.alternatives.find(compareSym).getOrElse(
typeError(s"No matching overload of $space.$qual with signature ${showSig(sig)}"))
}
member.asTerm.alternatives.find(compareSym).getOrElse(
typeError(s"No matching overload of $space.$qual with signature ${showSig(sig)}"))
}

def showSig(sig: MethodSignature[ErasedTypeRef]): String = sig.map(_.signature).show
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ trait TypeOps { self: TastyUniverse =>

final val ChildAnnot: Symbol = u.definitions.ChildAnnotationClass
final val RepeatedAnnot: Symbol = u.definitions.RepeatedAnnotationClass
final val AlphaAnnotationClass: Symbol = u.definitions.AlphaAnnotationClass
final val TargetNameAnnotationClass: Symbol = u.definitions.TargetNameAnnotationClass
final val StaticMethodAnnotationClass: Symbol = u.definitions.StaticMethodAnnotationClass

object PolyFunctionType {
Expand Down
93 changes: 46 additions & 47 deletions src/compiler/scala/tools/tasty/TastyFlags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ object TastyFlags {
final val Given = Extension.next
final val Exported = Given.next
final val Macro = Exported.next
final val SuperTrait = Macro.next
final val Enum = SuperTrait.next
final val Transparent = Macro.next
final val Enum = Transparent.next
final val Open = Enum.next
final val ParamAlias = Open.next
final val Infix = ParamAlias.next

private[TastyFlags] final val maxFlag: Long = ParamAlias.shift

Expand All @@ -80,7 +81,6 @@ object TastyFlags {
TastyFlagSet(1L << shift)
}

def toSingletonSets: SingletonSets = SingletonSets(toLong)
def |(other: TastyFlagSet): TastyFlagSet = TastyFlagSet(toLong | other.toLong)
def &(mask: TastyFlagSet): TastyFlagSet = TastyFlagSet(toLong & mask.toLong)
def &~(mask: TastyFlagSet): TastyFlagSet = TastyFlagSet(toLong & ~mask.toLong)
Expand All @@ -96,50 +96,49 @@ object TastyFlags {
"EmptyTastyFlags"
}
else {
toSingletonSets.map { f =>
(f: @unchecked) match {
case Private => "Private"
case Protected => "Protected"
case AbsOverride => "AbsOverride"
case Abstract => "Abstract"
case Final => "Final"
case Sealed => "Sealed"
case Case => "Case"
case Implicit => "Implicit"
case Lazy => "Lazy"
case Override => "Override"
case Static => "Static"
case Object => "Object"
case Trait => "Trait"
case Local => "Local"
case Synthetic => "Synthetic"
case Artifact => "Artifact"
case Mutable => "Mutable"
case FieldAccessor => "FieldAccessor"
case CaseAccessor => "CaseAccessor"
case Covariant => "Covariant"
case Contravariant => "Contravariant"
case HasDefault => "HasDefault"
case Stable => "Stable"
case ParamSetter => "ParamSetter"
case Param => "Param"
case Deferred => "Deferred"
case Method => "Method"
case Erased => "Erased"
case Internal => "Internal"
case Inline => "Inline"
case InlineProxy => "InlineProxy"
case Opaque => "Opaque"
case Extension => "Extension"
case Given => "Given"
case Exported => "Exported"
case Macro => "Macro"
case SuperTrait => "SuperTrait"
case Enum => "Enum"
case Open => "Open"
case ParamAlias => "ParamAlias"
}
} mkString(" | ")
val sb = collection.mutable.ArrayBuffer.empty[String]
if (is(Private)) sb += "Private"
if (is(Protected)) sb += "Protected"
if (is(AbsOverride)) sb += "AbsOverride"
if (is(Abstract)) sb += "Abstract"
if (is(Final)) sb += "Final"
if (is(Sealed)) sb += "Sealed"
if (is(Case)) sb += "Case"
if (is(Implicit)) sb += "Implicit"
if (is(Lazy)) sb += "Lazy"
if (is(Override)) sb += "Override"
if (is(Static)) sb += "Static"
if (is(Object)) sb += "Object"
if (is(Trait)) sb += "Trait"
if (is(Local)) sb += "Local"
if (is(Synthetic)) sb += "Synthetic"
if (is(Artifact)) sb += "Artifact"
if (is(Mutable)) sb += "Mutable"
if (is(FieldAccessor)) sb += "FieldAccessor"
if (is(CaseAccessor)) sb += "CaseAccessor"
if (is(Covariant)) sb += "Covariant"
if (is(Contravariant)) sb += "Contravariant"
if (is(HasDefault)) sb += "HasDefault"
if (is(Stable)) sb += "Stable"
if (is(ParamSetter)) sb += "ParamSetter"
if (is(Param)) sb += "Param"
if (is(Deferred)) sb += "Deferred"
if (is(Method)) sb += "Method"
if (is(Erased)) sb += "Erased"
if (is(Internal)) sb += "Internal"
if (is(Inline)) sb += "Inline"
if (is(InlineProxy)) sb += "InlineProxy"
if (is(Opaque)) sb += "Opaque"
if (is(Extension)) sb += "Extension"
if (is(Given)) sb += "Given"
if (is(Exported)) sb += "Exported"
if (is(Macro)) sb += "Macro"
if (is(Transparent)) sb += "Transparent"
if (is(Enum)) sb += "Enum"
if (is(Open)) sb += "Open"
if (is(ParamAlias)) sb += "ParamAlias"
if (is(Infix)) sb += "Infix"
sb.mkString(" | ")
}
}
}
Expand Down

0 comments on commit fa45a3b

Please sign in to comment.