Skip to content

Commit

Permalink
Merge pull request #9791 from scalacenter/tasty/upgrade-Scala-3.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
SethTisue committed Oct 27, 2021
2 parents 0eb3d7c + 7833232 commit 8ee33bb
Show file tree
Hide file tree
Showing 28 changed files with 191 additions and 72 deletions.
2 changes: 1 addition & 1 deletion project/DottySupport.scala
Expand Up @@ -12,7 +12,7 @@ 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" // TASTy version 28.0-0
val supportedTASTyRelease = "3.1.0" // TASTy version 28.1-0
val scala3Compiler = "org.scala-lang" % "scala3-compiler_3" % supportedTASTyRelease
val scala3Library = "org.scala-lang" % "scala3-library_3" % supportedTASTyRelease

Expand Down
3 changes: 0 additions & 3 deletions src/compiler/scala/tools/nsc/tasty/ForceKinds.scala
Expand Up @@ -18,8 +18,6 @@ import ForceKinds._

object ForceKinds {

/** When forcing the constructor of an annotation */
final val AnnotCtor: ForceKinds.Single = of(1 << 0)
/** When forcing the companion of a module */
final val DeepForce: ForceKinds.Single = of(1 << 1)
/** When forcing the owner of a symbol */
Expand Down Expand Up @@ -51,7 +49,6 @@ class ForceKinds(val toInt: Int) extends AnyVal {

def describe: List[String] = {
var xs = List.empty[String]
if (is(AnnotCtor)) xs ::= "reading annotation constructor"
if (is(DeepForce)) xs ::= "deep"
if (is(CompleteOwner)) xs ::= "class owner is required"
if (is(OverloadedSym)) xs ::= "overload resolution"
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/scala/tools/nsc/tasty/TastyModes.scala
Expand Up @@ -34,10 +34,14 @@ object TastyModes {
final val InnerScope: TastyMode = TastyMode(1 << 5)
/** When reading the tree of an Opaque type */
final val OpaqueTypeDef: TastyMode = TastyMode(1 << 6)
/** When reading trees of an annotation */
final val ReadAnnotationCtor: TastyMode = TastyMode(1 << 7)

/** The union of `IndexStats` and `InnerScope` */
final val IndexScopedStats: TastyMode = IndexStats | InnerScope

final val ReadAnnotTopLevel: TastyMode = ReadAnnotation | ReadAnnotationCtor

case class TastyMode(val toInt: Int) extends AnyVal { mode =>

def |(other: TastyMode): TastyMode = TastyMode(toInt | other.toInt)
Expand All @@ -58,6 +62,7 @@ object TastyModes {
if (mode.is(ReadMacro)) sb += "ReadMacro"
if (mode.is(InnerScope)) sb += "InnerScope"
if (mode.is(OpaqueTypeDef)) sb += "OpaqueTypeDef"
if (mode.is(ReadAnnotationCtor)) sb += "ReadAnnotationCtor"
sb.mkString(" | ")
}
}
Expand Down
24 changes: 14 additions & 10 deletions src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala
Expand Up @@ -396,7 +396,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
val lo = readType()
if (nothingButMods(end)) readVariances(lo)
else defn.TypeBounds(lo, readVariances(readType()))
case ANNOTATEDtype => defn.AnnotatedType(readType(), readTerm()(ctx.addMode(ReadAnnotation)))
case ANNOTATEDtype => defn.AnnotatedType(readType(), readTerm()(ctx.addMode(ReadAnnotTopLevel)))
case ANDtype => defn.IntersectionType(readType(), readType())
case ORtype => unionIsUnsupported
case SUPERtype => defn.SuperType(readType(), readType())
Expand Down Expand Up @@ -461,6 +461,8 @@ class TreeUnpickler[Tasty <: TastyUniverse](

private def addInferredFlags(tag: Int, tastyFlags: TastyFlagSet, name: TastyName, isAbsType: Boolean, isClass: Boolean, rhsIsEmpty: Boolean)(implicit ctx: Context): TastyFlagSet = {
var flags = tastyFlags
if (flags.is(Given))
flags |= Implicit
val lacksDefinition =
rhsIsEmpty &&
name.isTermName && !name.isConstructorName && !flags.isOneOf(FlagSets.TermParamOrAccessor) ||
Expand All @@ -474,7 +476,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
flags |= FieldAccessor
if (flags.not(Mutable))
flags |= Stable
if (flags.is(Case | Static | Enum)) // singleton enum case
if (flags.is(Case | Enum)) // singleton enum case
flags |= Object | Stable // encode as a module (this needs to be corrected in bytecode)
}
if (ctx.owner.isClass) {
Expand Down Expand Up @@ -668,7 +670,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
case HASDEFAULT => addFlag(HasDefault)
case STABLE => addFlag(Stable)
case EXTENSION => addFlag(Extension)
case GIVEN => addFlag(Implicit)
case GIVEN => addFlag(Given)
case PARAMsetter => addFlag(ParamSetter)
case PARAMalias => addFlag(ParamAlias)
case EXPORTED => addFlag(Exported)
Expand All @@ -692,7 +694,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
private val readTypedWithin: Context => Symbol = implicit ctx => readType().typeSymbolDirect

private val readTypedAnnot: Context => DeferredAnnotation = { implicit ctx =>
val annotCtx = ctx.addMode(ReadAnnotation)
val annotCtx = ctx.addMode(ReadAnnotTopLevel)
val start = currentAddr
readByte() // tag
val end = readEnd()
Expand Down Expand Up @@ -803,7 +805,8 @@ class TreeUnpickler[Tasty <: TastyUniverse](

def DefDef(repr: TastyRepr, localCtx: Context)(implicit ctx: Context): Unit = {
val isMacro = repr.tflags.is(Erased | Macro)
checkUnsupportedFlags(repr.unsupportedFlags &~ (Extension | Exported | Infix | optFlag(isMacro)(Erased)))
val supportedFlags = Extension | Exported | Infix | Given | optFlag(isMacro)(Erased)
checkUnsupportedFlags(repr.unsupportedFlags &~ supportedFlags)
val isCtor = sym.isConstructor
val paramDefss = readParamss()(localCtx).map(_.map(symFromNoCycle))
val typeParams = {
Expand Down Expand Up @@ -842,7 +845,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](

def ValDef(repr: TastyRepr, localCtx: Context)(implicit ctx: Context): Unit = {
// valdef in TASTy is either a singleton object or a method forwarder to a local value.
checkUnsupportedFlags(repr.unsupportedFlags &~ (Enum | Extension | Exported))
checkUnsupportedFlags(repr.unsupportedFlags &~ (Enum | Extension | Exported | Given))
val tpe = readTpt()(localCtx).tpe
ctx.setInfo(sym,
if (repr.tflags.is(FlagSets.SingletonEnum)) {
Expand All @@ -856,7 +859,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
}

def TypeDef(repr: TastyRepr, localCtx: Context)(implicit ctx: Context): Unit = {
val allowedShared = Enum | Opaque | Infix
val allowedShared = Enum | Opaque | Infix | Given
val allowedTypeFlags = allowedShared | Exported
val allowedClassFlags = allowedShared | Open | Transparent
if (sym.isClass) {
Expand All @@ -881,7 +884,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
}

def TermParam(repr: TastyRepr, localCtx: Context)(implicit ctx: Context): Unit = {
checkUnsupportedFlags(repr.unsupportedFlags &~ (ParamAlias | Exported))
checkUnsupportedFlags(repr.unsupportedFlags &~ (ParamAlias | Exported | Given))
val tpt = readTpt()(localCtx)
ctx.setInfo(sym,
if (nothingButMods(end) && sym.not(ParamSetter)) tpt.tpe
Expand Down Expand Up @@ -1131,7 +1134,8 @@ class TreeUnpickler[Tasty <: TastyUniverse](
until(end)(skipTree())
tpd.TypeTree(fnResult(fn.tpe))
} else {
tpd.Apply(fn, until(end)(readTerm()))
val argsCtx = ctx.argumentCtx(fn)
tpd.Apply(fn, until(end)(readTerm()(argsCtx)))
}
case TYPEAPPLY => tpd.TypeApply(readTerm(), until(end)(readTpt()))
case TYPED => tpd.Typed(readTerm(), readTpt())
Expand All @@ -1155,7 +1159,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
// wrong number of arguments in some scenarios reading F-bounded
// types. This came up in #137 of collection strawman.
tpd.AppliedTypeTree(readTpt(), until(end)(readTpt()))
case ANNOTATEDtpt => tpd.Annotated(readTpt(), readTerm()(ctx.addMode(ReadAnnotation)))
case ANNOTATEDtpt => tpd.Annotated(readTpt(), readTerm()(ctx.addMode(ReadAnnotTopLevel)))
case LAMBDAtpt => tpd.LambdaTypeTree(readParams[NoCycle](TYPEPARAM).map(symFromNoCycle), readTpt())
case MATCHtpt => matchTypeIsUnsupported
case TYPEBOUNDStpt =>
Expand Down
5 changes: 4 additions & 1 deletion src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala
Expand Up @@ -269,7 +269,7 @@ trait ContextOps { self: TastyUniverse =>
owner.newTypeParameter(
name = u.freshTypeName("_$")(u.currentFreshNameCreator),
pos = u.NoPosition,
newFlags = FlagSets.Creation.Default
newFlags = FlagSets.Creation.Wildcard
).setInfo(info)

final def newConstructor(owner: Symbol, info: Type): Symbol = unsafeNewSymbol(
Expand Down Expand Up @@ -557,6 +557,9 @@ trait ContextOps { self: TastyUniverse =>

final def newRefinementClassSymbol: Symbol = owner.newRefinementClass(u.NoPosition)

final def argumentCtx(fn: Tree): Context =
if (fn.symbol.isPrimaryConstructor) retractMode(ReadAnnotationCtor) else thisCtx

final def setInfo(sym: Symbol, info: Type): Unit = sym.info = info

final def markAsEnumSingleton(sym: Symbol): Unit =
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala
Expand Up @@ -42,6 +42,7 @@ trait FlagOps { self: TastyUniverse =>
object Creation {
val ObjectDef: TastyFlagSet = Object | Lazy | Final | Stable
val ObjectClassDef: TastyFlagSet = Object | Final
val Wildcard: u.FlagSet = newSymbolFlagSetFromEncoded(Flags.EXISTENTIAL)
val Default: u.FlagSet = newSymbolFlagSet(EmptyTastyFlags)
}
def withAccess(flags: TastyFlagSet, inheritedAccess: TastyFlagSet): TastyFlagSet =
Expand All @@ -56,7 +57,10 @@ trait FlagOps { self: TastyUniverse =>

/** For purpose of symbol initialisation, encode a `TastyFlagSet` as a `symbolTable.FlagSet`. */
private[bridge] def newSymbolFlagSet(tflags: TastyFlagSet): u.FlagSet =
unsafeEncodeTastyFlagSet(tflags) | ModifierFlags.SCALA3X
newSymbolFlagSetFromEncoded(unsafeEncodeTastyFlagSet(tflags))

private[bridge] def newSymbolFlagSetFromEncoded(flags: u.FlagSet): u.FlagSet =
flags | ModifierFlags.SCALA3X

implicit final class SymbolFlagOps(val sym: Symbol) {
def reset(tflags: TastyFlagSet)(implicit ctx: Context): sym.type =
Expand Down
15 changes: 4 additions & 11 deletions src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala
Expand Up @@ -12,7 +12,7 @@

package scala.tools.nsc.tasty.bridge

import scala.tools.nsc.tasty.{TastyUniverse, TastyModes, ForceKinds}, TastyModes._, ForceKinds._
import scala.tools.nsc.tasty.{TastyUniverse, TastyModes}, TastyModes._

import scala.tools.tasty.TastyName
import scala.reflect.internal.Flags
Expand Down Expand Up @@ -70,17 +70,10 @@ trait TreeOps { self: TastyUniverse =>
def selectCtor(qual: Tree) =
u.Select(qual, u.nme.CONSTRUCTOR).setType(qual.tpe.typeSymbol.primaryConstructor.tpe)

if (ctx.mode.is(ReadAnnotation) && name.isSignedConstructor) {
val cls = qual.tpe.typeSymbol
cls.ensureCompleted(AnnotCtor)
if (cls.isJavaAnnotation)
selectCtor(qual)
else
selectName(qual, name)(lookup)
}
else {
if (ctx.mode.is(ReadAnnotationCtor) && name.isSignedConstructor)
selectCtor(qual)
else
selectName(qual, name)(lookup)
}

}

Expand Down
1 change: 0 additions & 1 deletion src/compiler/scala/tools/nsc/transform/Erasure.scala
Expand Up @@ -1297,7 +1297,6 @@ abstract class Erasure extends InfoTransform
if (ct.tag == ClazzTag && ct.typeValue.typeSymbol != definitions.UnitClass) {
val typeValue = ct.typeValue.dealiasWiden
val erased = erasure(typeValue.typeSymbol) applyInArray typeValue

treeCopy.Literal(cleanLiteral, Constant(erased))
} else cleanLiteral

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/tasty/TastyFormat.scala
Expand Up @@ -35,7 +35,7 @@ object TastyFormat {
* compatibility, but remains backwards compatible, with all
* preceding `MinorVersion`.
*/
final val MinorVersion: Int = 0
final val MinorVersion: Int = 1

/**Natural Number. The `ExperimentalVersion` allows for
* experimentation with changes to TASTy without committing
Expand Down
11 changes: 0 additions & 11 deletions src/tastytest/dotty/tools/vulpix/ParallelTesting.scala

This file was deleted.

45 changes: 31 additions & 14 deletions src/tastytest/scala/tools/tastytest/Dotc.scala
Expand Up @@ -16,6 +16,15 @@ object Dotc extends Script.Command {
def initClassloader(): Try[Dotc.ClassLoader] =
Try(Dotc.ClassLoader(ScalaClassLoader.fromURLs(Classpaths.dottyCompiler.asURLs)))

def processIn(op: Dotc.ClassLoader => Int): Int = {
Dotc.initClassloader() match {
case Success(cl) => op(cl)
case Failure(err) =>
println(red(s"could not initialise Scala 3 classpath: $err"))
1
}
}

def loadClass(name: String)(implicit cl: Dotc.ClassLoader) =
Class.forName(name, true, cl.parent)

Expand All @@ -24,6 +33,18 @@ object Dotc extends Script.Command {
invoke(method, null, args)
}

def invokeStatic(
className: String,
methodName: String,
args: Seq[String]
)(implicit cl: Dotc.ClassLoader): Try[Object] = {
val cls = loadClass(className)
val method = cls.getMethod(methodName, classOf[Array[String]])
Try {
invokeStatic(method, Seq(args.toArray))
}
}

def invoke(method: Method, obj: AnyRef, args: Seq[Any])(implicit cl: Dotc.ClassLoader) = {
try cl.parent.asContext[AnyRef] {
method.invoke(obj, args.toArray:_*)
Expand All @@ -35,18 +56,18 @@ object Dotc extends Script.Command {

private def dotcProcess(args: Seq[String])(implicit cl: Dotc.ClassLoader) = processMethod("dotty.tools.dotc.Main")(args)

def processMethod(mainClassName: String)(args: Seq[String])(implicit cl: Dotc.ClassLoader): Try[Boolean] = {
val mainClass = loadClass(mainClassName)
val reporterClass = loadClass("dotty.tools.dotc.reporting.Reporter")
val Main_process = mainClass.getMethod("process", classOf[Array[String]])
val Reporter_hasErrors = reporterClass.getMethod("hasErrors")
Try {
val reporter = unlockExperimentalFeatures(invokeStatic(Main_process, Seq(args.toArray)))
def processMethod(className: String)(args: Seq[String])(implicit cl: Dotc.ClassLoader): Try[Boolean] = {
val reporterCls = loadClass("dotty.tools.dotc.reporting.Reporter")
val Reporter_hasErrors = reporterCls.getMethod("hasErrors")
for (reporter <- invokeStatic(className, "process", args)) yield {
val hasErrors = invoke(Reporter_hasErrors, reporter, Seq.empty).asInstanceOf[Boolean]
!hasErrors
}
}

def mainMethod(className: String)(args: Seq[String])(implicit cl: Dotc.ClassLoader): Try[Unit] =
for (_ <- invokeStatic(className, "main", args)) yield ()

def dotcVersion(implicit cl: Dotc.ClassLoader): String = {
val compilerPropertiesClass = loadClass("dotty.tools.dotc.config.Properties")
val Properties_simpleVersionString = compilerPropertiesClass.getMethod("simpleVersionString")
Expand Down Expand Up @@ -81,14 +102,10 @@ object Dotc extends Script.Command {
return 1
}
val Seq(out, src, additional @ _*) = args: @unchecked
implicit val scala3classloader: Dotc.ClassLoader = initClassloader() match {
case Success(cl) => cl
case Failure(err) =>
println(red(s"could not initialise Scala 3 classpath: $err"))
return 1
Dotc.processIn { implicit scala3classloader =>
val success = dotc(out, out, additional, src).get
if (success) 0 else 1
}
val success = dotc(out, out, additional, src).get
if (success) 0 else 1
}

}
12 changes: 4 additions & 8 deletions src/tastytest/scala/tools/tastytest/DotcDecompiler.scala
@@ -1,6 +1,6 @@
package scala.tools.tastytest

import scala.util.{Try, Success, Failure}
import scala.util.Try

object DotcDecompiler extends Script.Command {

Expand All @@ -19,14 +19,10 @@ object DotcDecompiler extends Script.Command {
return 1
}
val Seq(tasty, additionalSettings @ _*) = args: @unchecked
implicit val scala3classloader: Dotc.ClassLoader = Dotc.initClassloader() match {
case Success(cl) => cl
case Failure(err) =>
println(red(s"could not initialise Scala 3 classpath: $err"))
return 1
Dotc.processIn { implicit scala3classloader =>
val success = decompile(tasty, additionalSettings).get
if (success) 0 else 1
}
val success = decompile(tasty, additionalSettings).get
if (success) 0 else 1
}

}
24 changes: 24 additions & 0 deletions src/tastytest/scala/tools/tastytest/PrintTasty.scala
@@ -0,0 +1,24 @@
package scala.tools.tastytest

import scala.util.Try

object PrintTasty extends Script.Command {

def printTasty(tasty: String)(implicit cl: Dotc.ClassLoader): Try[Unit] =
Dotc.mainMethod("dotty.tools.dotc.core.tasty.TastyPrinter")(Seq(tasty))

val commandName: String = "printTasty"
val describe: String = s"$commandName <tasty: File>"

def process(args: String*): Int = {
if (args.length != 1) {
println(red(s"please provide 1 argument in sub-command: $describe"))
return 1
}
Dotc.processIn { implicit scala3classloader =>
val success = printTasty(tasty = args.head).isSuccess
if (success) 0 else 1
}
}

}
5 changes: 0 additions & 5 deletions src/tastytest/scala/tools/tastytest/package.scala
@@ -1,16 +1,11 @@
package scala.tools

import dotty.tools.vulpix.ParallelTesting

package object tastytest {

import scala.util.Try

import Files.{pathSep, classpathSep}

def unlockExperimentalFeatures[T](op: => T): T =
new ParallelTesting().unlockExperimentalFeatures(op)

def printerrln(str: String): Unit = System.err.println(red(str))
def printwarnln(str: String): Unit = System.err.println(yellow(str))
def printsuccessln(str: String): Unit = System.err.println(green(str))
Expand Down

0 comments on commit 8ee33bb

Please sign in to comment.