From bfed4df048eadd7dd15a2121ddafaccafe47b6b3 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Thu, 8 Feb 2024 18:14:18 +0100 Subject: [PATCH] move isJava to Context --- .../scala/tools/nsc/tasty/TastyModes.scala | 3 + .../tools/nsc/tasty/TastyUnpickler.scala | 11 +- .../scala/tools/nsc/tasty/TreeUnpickler.scala | 110 ++++++++---------- .../tools/nsc/tasty/bridge/ContextOps.scala | 51 ++++---- .../tools/nsc/tasty/bridge/FlagOps.scala | 22 ++-- .../tools/nsc/tasty/bridge/SymbolOps.scala | 12 +- .../tools/nsc/tasty/bridge/TreeOps.scala | 20 ++-- .../tools/nsc/tasty/bridge/TypeOps.scala | 43 ++++--- 8 files changed, 138 insertions(+), 134 deletions(-) diff --git a/src/compiler/scala/tools/nsc/tasty/TastyModes.scala b/src/compiler/scala/tools/nsc/tasty/TastyModes.scala index a8e5e8454599..6352b0fc6ef6 100644 --- a/src/compiler/scala/tools/nsc/tasty/TastyModes.scala +++ b/src/compiler/scala/tools/nsc/tasty/TastyModes.scala @@ -36,6 +36,8 @@ object TastyModes { final val OpaqueTypeDef: TastyMode = TastyMode(1 << 6) /** When reading trees of an annotation */ final val ReadAnnotationCtor: TastyMode = TastyMode(1 << 7) + /** When reading a TASTy file produced from a Java source file (file has JAVAattr attribute) */ + final val ReadJava: TastyMode = TastyMode(1 << 8) /** The union of `IndexStats` and `InnerScope` */ final val IndexScopedStats: TastyMode = IndexStats | InnerScope @@ -63,6 +65,7 @@ object TastyModes { if (mode.is(InnerScope)) sb += "InnerScope" if (mode.is(OpaqueTypeDef)) sb += "OpaqueTypeDef" if (mode.is(ReadAnnotationCtor)) sb += "ReadAnnotationCtor" + if (mode.is(ReadJava)) sb += "ReadJava" sb.mkString(" | ") } } diff --git a/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala b/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala index 6cbfbb4bfc0a..13471520703c 100644 --- a/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala +++ b/src/compiler/scala/tools/nsc/tasty/TastyUnpickler.scala @@ -40,16 +40,23 @@ object TastyUnpickler { ctx.log(s"Unpickling $filename") + def enter(treeUnpickler: TreeUnpickler[tasty.type])(implicit ctx: Context): Unit = { + treeUnpickler.enterTopLevel(classRoot, objectRoot) + } + val unpickler = new TastyUnpickler[tasty.type](new TastyReader(bytes))(tasty) unpickler.readHeader() unpickler.readNames() val Some(astReader) = unpickler.readSection(TastyFormat.ASTsSection): @unchecked + val attributes = unpickler .readSection(TastyFormat.AttributesSection) .map(AttributeUnpickler.attributes) .getOrElse(Attributes.empty) - val treeUnpickler = new TreeUnpickler[tasty.type](astReader, unpickler.nameAtRef, attributes)(tasty) - treeUnpickler.enterTopLevel(classRoot, objectRoot) + + val treeUnpickler = new TreeUnpickler[tasty.type](astReader, unpickler.nameAtRef)(tasty) + val ctx0 = if (attributes.isJava) ctx.addMode(TastyModes.ReadJava) else ctx + enter(treeUnpickler)(ctx0) } private final class Table[T] extends (NameRef => T) { diff --git a/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala b/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala index 915aa67ed444..7a8a1f3189cf 100644 --- a/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala +++ b/src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala @@ -12,7 +12,7 @@ package scala.tools.nsc.tasty -import scala.tools.tasty.{Attributes, TastyRefs, TastyReader, TastyName, TastyFormat, TastyFlags} +import scala.tools.tasty.{TastyRefs, TastyReader, TastyName, TastyFormat, TastyFlags} import TastyRefs._, TastyFlags._, TastyFormat._ import ForceKinds._ @@ -36,8 +36,7 @@ import scala.collection.immutable.ArraySeq */ class TreeUnpickler[Tasty <: TastyUniverse]( reader: TastyReader, - nameAtRef: NameRef => TastyName, - attributes: Attributes)(implicit + nameAtRef: NameRef => TastyName)(implicit val tasty: Tasty) { self => import tasty._ import TreeUnpickler._ @@ -71,12 +70,6 @@ class TreeUnpickler[Tasty <: TastyUniverse]( /** The root owner tree. See `OwnerTree` class definition. Set by `enterTopLevel`. */ private[this] var ownerTree: OwnerTree = _ - /** JAVAattr is necessary to support pipelining in Zinc, we have to set Java erasure semantics if found. - * To support this we also need to support TASTy-only classpaths, see https://github.com/lampepfl/dotty/pull/17594 - * For a test case, see test/tasty/run-pipelined - */ - private[this] val isJava = attributes.isJava - //---------------- unpickling trees ---------------------------------------------------------------------------------- private def registerSym(addr: Addr, sym: Symbol, rejected: Boolean)(implicit ctx: Context) = { @@ -118,7 +111,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( reader: TastyReader, tflags: TastyFlagSet )(implicit ctx: Context) - extends TastyCompleter(isClass, tflags, isJava) { + extends TastyCompleter(isClass, tflags) { private val symAddr = reader.currentAddr @@ -391,10 +384,10 @@ class TreeUnpickler[Tasty <: TastyUniverse]( val result = (tag: @switch) match { case TERMREFin => - defn.TermRefIn(name = readTastyName(), prefix = readType(), space = readType(), isJava = isJava) + defn.TermRefIn(name = readTastyName(), prefix = readType(), space = readType()) case TYPEREFin => defn.TypeRefIn( - name = readTastyName().toTypeName, prefix = readType(), space = readType(), isJava = isJava) + name = readTastyName().toTypeName, prefix = readType(), space = readType()) case REFINEDtype => var name = readTastyName() val parent = readType() @@ -402,7 +395,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( ctx.enterRefinement(parent)(refinedCtx => defn.RefinedType(parent, name, refinedCtx.owner, readType()) ) - case APPLIEDtype => defn.AppliedType(readType(), until(end)(readType()), isJava) + case APPLIEDtype => defn.AppliedType(readType(), until(end)(readType())) case TYPEBOUNDS => val lo = readType() if (nothingButMods(end)) readVariances(lo) @@ -423,13 +416,13 @@ class TreeUnpickler[Tasty <: TastyUniverse]( def readSimpleType(): Type = { (tag: @switch) match { - case TYPEREFdirect => defn.NamedType(defn.NoPrefix, readSymRef(), isJava) - case TERMREFdirect => defn.NamedType(defn.NoPrefix, readSymRef(), isJava) - case TYPEREFsymbol | TERMREFsymbol => defn.NamedType(sym = readSymRef(), prefix = readType(), isJava = isJava) - case TYPEREFpkg => defn.NamedType(defn.NoPrefix, sym = readPackageRef().objectImplementation, isJava = isJava) - case TERMREFpkg => defn.NamedType(defn.NoPrefix, sym = readPackageRef(), isJava = isJava) - case TYPEREF => defn.TypeRef(name = readTastyName().toTypeName, prefix = readType(), isJava = isJava) - case TERMREF => defn.TermRef(name = readTastyName(), prefix = readType(), isJava = isJava) + case TYPEREFdirect => defn.NamedType(defn.NoPrefix, readSymRef()) + case TERMREFdirect => defn.NamedType(defn.NoPrefix, readSymRef()) + case TYPEREFsymbol | TERMREFsymbol => defn.NamedType(sym = readSymRef(), prefix = readType()) + case TYPEREFpkg => defn.NamedType(defn.NoPrefix, sym = readPackageRef().objectImplementation) + case TERMREFpkg => defn.NamedType(defn.NoPrefix, sym = readPackageRef()) + case TYPEREF => defn.TypeRef(name = readTastyName().toTypeName, prefix = readType()) + case TERMREF => defn.TermRef(name = readTastyName(), prefix = readType()) case THIS => defn.ThisType(readType()) case RECtype => typeAtAddr.get(start) match { @@ -493,11 +486,11 @@ class TreeUnpickler[Tasty <: TastyUniverse]( flags |= Method if (name.isDefaultName) flags |= HasDefault // this corresponds to DEFAULTPARAM - if (isJava && !lacksDefinition && ctx.owner.is(Trait, isJava) && !name.isConstructorName) + if (ctx.isJava && !lacksDefinition && ctx.owner.is(Trait) && !name.isConstructorName) flags |= HasDefault // will be replaced by JAVA_DEFAULTMETHOD } if (tag === VALDEF) { - if (flags.is(Inline) || ctx.owner.is(Trait, isJava)) + if (flags.is(Inline) || ctx.owner.is(Trait)) flags |= FieldAccessor if (flags.not(Mutable)) flags |= Stable @@ -727,14 +720,14 @@ class TreeUnpickler[Tasty <: TastyUniverse]( val annotStart = currentAddr ctx.log(s"$annotStart collected annotation ${showSym(annotSym)}, starting at $start, ending at $end") val mkTree = readLaterWithOwner(end, rdr => ctx => - ctx.trace(traceAnnotation(annotStart, annotSym, ctx.owner)) { + ctx.trace(traceAnnotation(annotStart, annotSym, ctx.owner)(ctx)) { rdr.readTerm()(ctx) } )(annotCtx.retractMode(IndexScopedStats)) DeferredAnnotation.fromTree(annotSym)(mkTree) } - private def traceAnnotation(annotStart: Addr, annotSym: Symbol, annotee: Symbol) = TraceInfo[Tree]( + private def traceAnnotation(annotStart: Addr, annotSym: Symbol, annotee: Symbol)(implicit ctx: Context) = TraceInfo[Tree]( query = s"reading annotation tree", qual = s"${showSym(annotSym)} at $annotStart", res = atree => s"annotation of ${showSym(annotee)} = ${showTree(atree)}" @@ -877,10 +870,10 @@ class TreeUnpickler[Tasty <: TastyUniverse]( ctx.setInfo(sym, if (repr.tflags.is(FlagSets.SingletonEnum)) { ctx.completeEnumSingleton(sym, tpe) - defn.NamedType(sym.owner.thisPrefix, sym.objectImplementation, isJava) + defn.NamedType(sym.owner.thisPrefix, sym.objectImplementation) } - else if (isJava && repr.tflags.is(FlagSets.JavaEnumCase)) defn.ConstantType(tpd.Constant(sym)) - else if (!isJava && sym.isFinal && isConstantType(tpe)) defn.InlineExprType(tpe) + else if (ctx.isJava && repr.tflags.is(FlagSets.JavaEnumCase)) defn.ConstantType(tpd.Constant(sym)) + else if (!ctx.isJava && sym.isFinal && isConstantType(tpe)) defn.InlineExprType(tpe) else if (sym.isMethod) defn.ExprType(tpe) else tpe ) @@ -907,7 +900,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( } else rhs.tpe ctx.setInfo(sym, defn.NormalisedBounds(info, sym)) - if (sym.is(Param, isJava)) sym.reset(Private | Protected, isJava) + if (sym.is(Param)) sym.reset(Private | Protected) } } @@ -915,7 +908,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( checkUnsupportedFlags(repr.unsupportedFlags &~ (ParamAlias | Exported | Given)) val tpt = readTpt()(localCtx) ctx.setInfo(sym, - if (nothingButMods(end) && sym.not(ParamSetter, isJava)) tpt.tpe + if (nothingButMods(end) && sym.not(ParamSetter)) tpt.tpe else defn.ExprType(tpt.tpe)) } @@ -1015,8 +1008,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( nextUnsharedTag match { case APPLY | TYPEAPPLY | BLOCK => readTerm()(parentWithOuter).tpe case _ => readTpt()(parentCtx).tpe - }, - isJava + } ) } } @@ -1048,9 +1040,9 @@ class TreeUnpickler[Tasty <: TastyUniverse]( addSelfDef() } if (nextByte === SPLITCLAUSE) { - assert(isJava, s"unexpected SPLITCLAUSE at $start") + assert(ctx.isJava, s"unexpected SPLITCLAUSE at $start") } - setInfoWithParents(tparams, ctx.processParents(cls, parents, isJava)) + setInfoWithParents(tparams, ctx.processParents(cls, parents)) } traverseTemplate() @@ -1119,11 +1111,11 @@ class TreeUnpickler[Tasty <: TastyUniverse]( (qual.typeIdent, defn.ThisType(qual.tpe)) } - def completeSelectType(name: TastyName.TypeName, isJava: Boolean)(implicit ctx: Context): Tree = - completeSelect(name, isJava) + def completeSelectType(name: TastyName.TypeName)(implicit ctx: Context): Tree = + completeSelect(name) - def completeSelect(name: TastyName, isJava: Boolean)(implicit ctx: Context): Tree = - tpd.Select(readTerm(), name, isJava) + def completeSelect(name: TastyName)(implicit ctx: Context): Tree = + tpd.Select(readTerm(), name) def completeSelectionParent(name: TastyName)(implicit ctx: Context): Tree = { assert(name.isSignedConstructor, s"Parent of ${ctx.owner} is not a constructor.") @@ -1136,8 +1128,8 @@ class TreeUnpickler[Tasty <: TastyUniverse]( case IDENTtpt => tpd.Ident(readTastyName().toTypeName)(readType()) case SELECT => if (inParentCtor) completeSelectionParent(readTastyName()) - else completeSelect(readTastyName(), isJava) - case SELECTtpt => completeSelectType(readTastyName().toTypeName, isJava) + else completeSelect(readTastyName()) + case SELECTtpt => completeSelectType(readTastyName().toTypeName) case QUALTHIS => val (qual, tref) = readQualId() tpd.This(qual)(tref) @@ -1162,7 +1154,7 @@ class TreeUnpickler[Tasty <: TastyUniverse]( qual } else { - tpd.Select(readType())(qual, name, isJava) + tpd.Select(readType())(qual, name) } case SUPER => val qual = readTerm() @@ -1201,8 +1193,8 @@ class TreeUnpickler[Tasty <: TastyUniverse]( // If we do directly a tpd.AppliedType tree we might get a // 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()), isJava) - case ANNOTATEDtpt => tpd.Annotated(readTpt(), readTerm()(ctx.addMode(ReadAnnotTopLevel)), isJava) + tpd.AppliedTypeTree(readTpt(), until(end)(readTpt())) + case ANNOTATEDtpt => tpd.Annotated(readTpt(), readTerm()(ctx.addMode(ReadAnnotTopLevel))) case LAMBDAtpt => tpd.LambdaTypeTree(readParams[NoCycle](TYPEPARAM).map(symFromNoCycle), readTpt()) case MATCHtpt => matchTypeIsUnsupported case TYPEBOUNDStpt => @@ -1341,23 +1333,23 @@ class TreeUnpickler[Tasty <: TastyUniverse]( def findOwner(addr: Addr)(implicit ctx: Context): Symbol = { def search(cs: List[OwnerTree], current: Symbol): Symbol = try cs match { - case ot :: cs1 => - if (ot.addr.index === addr.index) { - assert(isSymbol(current), s"no symbol at $addr") - current - } - else if (ot.addr.index < addr.index && addr.index < ot.end.index) - search(ot.children, reader.symbolAt(ot.addr)) - else - search(cs1, current) - case Nil => - throw new TreeWithoutOwner - } - catch { - case ex: TreeWithoutOwner => - ctx.log(s"no owner for $addr among $cs%, %") // pickling.println - throw ex - } + case ot :: cs1 => + if (ot.addr.index === addr.index) { + assert(isSymbol(current), s"no symbol at $addr") + current + } + else if (ot.addr.index < addr.index && addr.index < ot.end.index) + search(ot.children, reader.symbolAt(ot.addr)) + else + search(cs1, current) + case Nil => + throw new TreeWithoutOwner + } + catch { + case ex: TreeWithoutOwner => + ctx.log(s"no owner for $addr among $cs%, %") // pickling.println + throw ex + } try search(children, noSymbol).tap(owner => ctx.log(s"$addr within owner ${showSym(owner)} do:")) catch { case ex: TreeWithoutOwner => diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala index d0d749d0202c..afad1a1f95fa 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala @@ -31,9 +31,9 @@ import scala.util.chaining._ trait ContextOps { self: TastyUniverse => import self.{symbolTable => u} - private def describeOwner(owner: Symbol): String = { + private def describeOwner(owner: Symbol)(implicit ctx: Context): String = { val kind = - if (owner.isOneOf(Param | ParamSetter, isJava = false)) { + if (owner.isOneOf(Param | ParamSetter)) { if (owner.isType) "type parameter" else "parameter" } @@ -43,9 +43,9 @@ trait ContextOps { self: TastyUniverse => s"$kind ${owner.nameString}" } - def boundsString(owner: Symbol): String = { + def boundsString(owner: Symbol)(implicit ctx: Context): String = { if (owner.isType) s"bounds of $owner" - else if (owner.isOneOf(Param | ParamSetter, isJava = false)) s"parameter $owner" + else if (owner.isOneOf(Param | ParamSetter)) s"parameter $owner" else "result" } @@ -63,7 +63,7 @@ trait ContextOps { self: TastyUniverse => s"Unsupported Scala 3 $noun; found in ${location(ctx.globallyVisibleOwner)}." } - final def location(owner: Symbol): String = { + final def location(owner: Symbol)(implicit ctx: Context): String = { if (!isSymbol(owner)) "" else if (owner.isClass || owner.isPackageClass || owner.isPackageObjectOrClass) @@ -193,6 +193,12 @@ trait ContextOps { self: TastyUniverse => protected implicit final def implyThisCtx: thisCtx.type = thisCtx + /** JAVAattr is necessary to support pipelining in Zinc, we have to set Java erasure semantics if found. + * To support this we also need to support TASTy-only classpaths, see https://github.com/lampepfl/dotty/pull/17594 + * For a test case, see test/tasty/run-pipelined + */ + def isJava: Boolean = mode.is(ReadJava) + /**Associates the annotations with the symbol, and will force their evaluation if not reading statements.*/ def adjustAnnotations(sym: Symbol, annots: List[DeferredAnnotation]): Unit = { if (annots.nonEmpty) { @@ -285,18 +291,17 @@ trait ContextOps { self: TastyUniverse => final def newLocalDummy: Symbol = owner.newLocalDummy(u.NoPosition) - final def newWildcard(info: Type, isJava: Boolean): Symbol = + final def newWildcard(info: Type): Symbol = owner.newTypeParameter( name = u.freshTypeName("_$")(u.currentFreshNameCreator), pos = u.NoPosition, newFlags = FlagSets.Creation.wildcard(isJava) ).setInfo(info) - final def newConstructor(owner: Symbol, isJava: Boolean, info: Type): Symbol = unsafeNewSymbol( + final def newConstructor(owner: Symbol, info: Type): Symbol = unsafeNewSymbol( owner = owner, name = TastyName.Constructor, flags = Method, - isJava = isJava, info = info ) @@ -306,7 +311,6 @@ trait ContextOps { self: TastyUniverse => owner = cls, typeName = TastyName.SimpleName(cls.fullName('$') + "$$localSealedChildProxy").toTypeName, flags = tflags, - isJava = false, info = defn.LocalSealedChildProxyInfo(cls, tflags), privateWithin = u.NoSymbol ) @@ -318,7 +322,6 @@ trait ContextOps { self: TastyUniverse => owner = owner, name = tname, flags = flags1, - isJava = false, info = defn.LambdaParamInfo(flags1, idx, infoDb) ) } @@ -359,7 +362,7 @@ trait ContextOps { self: TastyUniverse => case u.PolyType(tparams, res) if res.paramss.isEmpty => u.PolyType(tparams, u.NullaryMethodType(res)) case _:u.MethodType | _:u.PolyType => tpe case _ => // val, which is not stable if structural. Dotty does not support vars - if (isOverride && overridden.is(Stable, isJava = false)) flags |= Stable + if (isOverride && overridden.is(Stable)) flags |= Stable u.NullaryMethodType(tpe) } } @@ -368,13 +371,13 @@ trait ContextOps { self: TastyUniverse => tpe } } - unsafeNewSymbol(owner, name, flags, isJava = false, info) + unsafeNewSymbol(owner, name, flags, info) } /** Guards the creation of an object val by checking for an existing definition in the owner's scope */ final def delayCompletion(owner: Symbol, name: TastyName, completer: TastyCompleter, privateWithin: Symbol = noSymbol): Symbol = { - def default() = unsafeNewSymbol(owner, name, completer.tflags, completer.isJava, completer, privateWithin) + def default() = unsafeNewSymbol(owner, name, completer.tflags, completer, privateWithin) if (completer.tflags.is(Object)) { val sourceObject = findObject(owner, encodeTermName(name)) if (isSymbol(sourceObject)) @@ -390,7 +393,7 @@ trait ContextOps { self: TastyUniverse => /** Guards the creation of an object class by checking for an existing definition in the owner's scope */ final def delayClassCompletion(owner: Symbol, typeName: TastyName.TypeName, completer: TastyCompleter, privateWithin: Symbol): Symbol = { - def default() = unsafeNewClassSymbol(owner, typeName, completer.tflags, completer.isJava, completer, privateWithin) + def default() = unsafeNewClassSymbol(owner, typeName, completer.tflags, completer, privateWithin) if (completer.tflags.is(Object)) { val sourceObject = findObject(owner, encodeTermName(typeName.toTermName)) if (isSymbol(sourceObject)) @@ -431,15 +434,15 @@ trait ContextOps { self: TastyUniverse => /** Unsafe to call for creation of a object val, prefer `delayCompletion` if info is a LazyType */ - private def unsafeNewSymbol(owner: Symbol, name: TastyName, flags: TastyFlagSet, isJava: Boolean, info: Type, privateWithin: Symbol = noSymbol): Symbol = - unsafeSetInfoAndPrivate(unsafeNewUntypedSymbol(owner, name, flags, isJava), info, privateWithin) + private def unsafeNewSymbol(owner: Symbol, name: TastyName, flags: TastyFlagSet, info: Type, privateWithin: Symbol = noSymbol): Symbol = + unsafeSetInfoAndPrivate(unsafeNewUntypedSymbol(owner, name, flags), info, privateWithin) /** Unsafe to call for creation of a object class, prefer `delayClassCompletion` if info is a LazyType */ - private def unsafeNewClassSymbol(owner: Symbol, typeName: TastyName.TypeName, flags: TastyFlagSet, isJava: Boolean, info: Type, privateWithin: Symbol): Symbol = - unsafeSetInfoAndPrivate(unsafeNewUntypedClassSymbol(owner, typeName, flags, isJava), info, privateWithin) + private def unsafeNewClassSymbol(owner: Symbol, typeName: TastyName.TypeName, flags: TastyFlagSet, info: Type, privateWithin: Symbol): Symbol = + unsafeSetInfoAndPrivate(unsafeNewUntypedClassSymbol(owner, typeName, flags), info, privateWithin) - private final def unsafeNewUntypedSymbol(owner: Symbol, name: TastyName, flags: TastyFlagSet, isJava: Boolean): Symbol = { + private final def unsafeNewUntypedSymbol(owner: Symbol, name: TastyName, flags: TastyFlagSet): Symbol = { if (flags.isOneOf(Param | ParamSetter)) { if (name.isTypeName) { owner.newTypeParameter(encodeTypeName(name.toTypeName), u.NoPosition, newSymbolFlagSet(flags, isJava)) @@ -487,7 +490,7 @@ trait ContextOps { self: TastyUniverse => } } - private final def unsafeNewUntypedClassSymbol(owner: Symbol, typeName: TastyName.TypeName, flags: TastyFlagSet, isJava: Boolean): Symbol = { + private final def unsafeNewUntypedClassSymbol(owner: Symbol, typeName: TastyName.TypeName, flags: TastyFlagSet): Symbol = { if (flags.is(FlagSets.Creation.ObjectClassDef)) { log(s"!!! visited module class $typeName first") val module = owner.newModule(encodeTermName(typeName), u.NoPosition, FlagSets.Creation.initial(isJava)) @@ -503,7 +506,7 @@ trait ContextOps { self: TastyUniverse => final def enterClassCompletion(): Symbol = { val cls = globallyVisibleOwner.asClass val assumedSelfSym = { - if (cls.is(Object, isJava = false) && cls.owner.isClass) { + if (cls.is(Object) && cls.owner.isClass) { cls.sourceModule } else { @@ -515,7 +518,7 @@ trait ContextOps { self: TastyUniverse => } /** sets up value class machinery */ - final def processParents(cls: Symbol, parentTypes: List[Type], isJava: Boolean): parentTypes.type = { + final def processParents(cls: Symbol, parentTypes: List[Type]): parentTypes.type = { if (parentTypes.head.typeSymbolDirect === u.definitions.AnyValClass) { // TODO [tasty]: please reconsider if there is some shared optimised logic that can be triggered instead. withPhaseNoLater("extmethods") { ctx0 => @@ -549,7 +552,7 @@ trait ContextOps { self: TastyUniverse => inheritedAccess = sym.repr.tflags ) val selfTpe = defn.SingleType(sym.owner.thisPrefix, sym) - val ctor = newConstructor(moduleCls, isJava = false, selfTpe) + val ctor = newConstructor(moduleCls, selfTpe) moduleCls.typeOfThis = selfTpe moduleCls.flags = newSymbolFlagSet(moduleClsFlags, isJava = false) moduleCls.info = defn.ClassInfoType(intersectionParts(tpe), ctor :: Nil, moduleCls) @@ -557,7 +560,7 @@ trait ContextOps { self: TastyUniverse => } final def redefineSymbol(symbol: Symbol, completer: TastyCompleter, privateWithin: Symbol): symbol.type = { - symbol.flags = newSymbolFlagSet(completer.tflags, completer.isJava) + symbol.flags = newSymbolFlagSet(completer.tflags, isJava) unsafeSetInfoAndPrivate(symbol, completer, privateWithin) } diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala index afc1f2802a82..1e703eba4721 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/FlagOps.scala @@ -64,19 +64,19 @@ trait FlagOps { self: TastyUniverse => flags | (if (isJava) ModifierFlags.JAVA else ModifierFlags.SCALA3X) implicit final class SymbolFlagOps(val sym: Symbol) { - def reset(tflags: TastyFlagSet, isJava: Boolean)(implicit ctx: Context): sym.type = - ctx.resetFlag0(sym, unsafeEncodeTastyFlagSet(tflags, isJava)) - def isOneOf(mask: TastyFlagSet, isJava: Boolean): Boolean = - sym.hasFlag(unsafeEncodeTastyFlagSet(mask, isJava)) - def is(mask: TastyFlagSet, isJava: Boolean): Boolean = - sym.hasAllFlags(unsafeEncodeTastyFlagSet(mask, isJava)) - def is(mask: TastyFlagSet, butNot: TastyFlagSet, isJava: Boolean): Boolean = + def reset(tflags: TastyFlagSet)(implicit ctx: Context): sym.type = + ctx.resetFlag0(sym, unsafeEncodeTastyFlagSet(tflags, ctx.isJava)) + def isOneOf(mask: TastyFlagSet)(implicit ctx: Context): Boolean = + sym.hasFlag(unsafeEncodeTastyFlagSet(mask, ctx.isJava)) + def is(mask: TastyFlagSet)(implicit ctx: Context): Boolean = + sym.hasAllFlags(unsafeEncodeTastyFlagSet(mask, ctx.isJava)) + def is(mask: TastyFlagSet, butNot: TastyFlagSet)(implicit ctx: Context): Boolean = if (!butNot) - sym.is(mask, isJava) + sym.is(mask) else - sym.is(mask, isJava) && sym.not(butNot, isJava) - def not(mask: TastyFlagSet, isJava: Boolean): Boolean = - sym.hasNoFlags(unsafeEncodeTastyFlagSet(mask, isJava)) + sym.is(mask) && sym.not(butNot) + def not(mask: TastyFlagSet)(implicit ctx: Context): Boolean = + sym.hasNoFlags(unsafeEncodeTastyFlagSet(mask, ctx.isJava)) } /** encodes a `TastyFlagSet` as a `symbolTable.FlagSet`, the flags in `FlagSets.TastyOnlyFlags` are ignored. diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala index 2cad3bbb7ca0..866454d34583 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/SymbolOps.scala @@ -40,7 +40,7 @@ trait SymbolOps { self: TastyUniverse => case u.NoSymbol => ctx.log(s"could not retrieve symbol from type ${showType(space)}") case termSym if termSym.isTerm => - if (termSym.is(Object, isJava = false)) { + if (termSym.is(Object)) { termSym.ensureCompleted(SpaceForce) termSym.moduleClass.ensureCompleted(DeepForce | SpaceForce) } @@ -137,15 +137,15 @@ trait SymbolOps { self: TastyUniverse => } } - private[bridge] def lookupSymbol(space: Type, tname: TastyName, isJava: Boolean)(implicit ctx: Context): Symbol = { + private[bridge] def lookupSymbol(space: Type, tname: TastyName)(implicit ctx: Context): Symbol = { deepComplete(space) tname match { case SignedName(qual, sig, target) => lookupSigned(space, qual, sig.map(_.encode), target) - case _ => lookupSimple(space, tname, isJava) + case _ => lookupSimple(space, tname) } } - private def lookupSimple(space: Type, tname: TastyName, isJava: Boolean)(implicit ctx: Context): Symbol = { + private def lookupSimple(space: Type, tname: TastyName)(implicit ctx: Context): Symbol = { // TODO [tasty]: dotty uses accessibleDenot which asserts that `fetched.isAccessibleFrom(pre)`, // or else filters for non private. // There should be an investigation to see what code makes that false, and what is an equivalent check. @@ -167,7 +167,7 @@ trait SymbolOps { self: TastyUniverse => } } if (isSymbol(member) && hasType(member)) member - else if (isJava && space.termSymbol.isModule && !space.termSymbol.hasPackageFlag) { + else if (ctx.isJava && space.termSymbol.isModule && !space.termSymbol.hasPackageFlag) { // TODO [tasty]: remove this workaround for https://github.com/lampepfl/dotty/issues/19619 // Use heuristic that we are accidentally looking in the static scope for some class/object, // when really we should be looking in the instance scope. In this case, we should be always looking for @@ -178,7 +178,7 @@ trait SymbolOps { self: TastyUniverse => val space0 = space.typeSymbol.companionClass.typeOfThis val tname0 = tname.toTypeName - val secondTry = lookupSymbol(space0, tname0, isJava) + val secondTry = lookupSymbol(space0, tname0) if (secondTry.isClass) secondTry // avoid type parameters else errorMissing(space0, tname0) } diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala index 932bfcc13fa7..5ef1d094c0dd 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/TreeOps.scala @@ -35,7 +35,7 @@ trait TreeOps { self: TastyUniverse => } } - def showTree(tree: Tree): String = { + def showTree(tree: Tree)(implicit ctx: Context): String = { // here we want to avoid forcing the symbols of type trees, // so instead substitute the type tree with an Identifier // of the `showType`, which does not force. @@ -56,11 +56,11 @@ trait TreeOps { self: TastyUniverse => @inline final def Ident(name: TastyName)(tpe: Type): Tree = new TastyIdent(name).setType(tpe) - @inline final def Select(qual: Tree, name: TastyName, isJava: Boolean)(implicit ctx: Context): Tree = - selectImpl(qual, name)(implicit ctx => lookupTypeFrom(qual.tpe)(qual.tpe, name, isJava)) + @inline final def Select(qual: Tree, name: TastyName)(implicit ctx: Context): Tree = + selectImpl(qual, name)(implicit ctx => lookupTypeFrom(qual.tpe)(qual.tpe, name)) - @inline final def Select(owner: Type)(qual: Tree, name: TastyName, isJava: Boolean)(implicit ctx: Context): Tree = - selectImpl(qual, name)(implicit ctx => lookupTypeFrom(owner)(qual.tpe, name, isJava)) + @inline final def Select(owner: Type)(qual: Tree, name: TastyName)(implicit ctx: Context): Tree = + selectImpl(qual, name)(implicit ctx => lookupTypeFrom(owner)(qual.tpe, name)) private def selectImpl(qual: Tree, name: TastyName)(lookup: Context => Type)(implicit ctx: Context): Tree = { @@ -158,23 +158,23 @@ trait TreeOps { self: TastyUniverse => @inline final def SeqLiteral(trees: List[Tree], tpt: Tree): Tree = u.ArrayValue(tpt, trees).setType(tpt.tpe) - def AppliedTypeTree(tpt: Tree, args: List[Tree], isJava: Boolean)(implicit ctx: Context): Tree = { + def AppliedTypeTree(tpt: Tree, args: List[Tree])(implicit ctx: Context): Tree = { if (tpt.tpe === AndTpe) { u.CompoundTypeTree(u.Template(args, u.noSelfType, Nil)).setType(u.intersectionType(args.map(_.tpe))) } - else if (isJava && u.definitions.isScalaRepeatedParamType(tpt.tpe)) { + else if (ctx.isJava && u.definitions.isScalaRepeatedParamType(tpt.tpe)) { u.AppliedTypeTree(tpt, args).setType(u.definitions.javaRepeatedType(args.head.tpe)) } else { - u.AppliedTypeTree(tpt, args).setType(defn.AppliedType(tpt.tpe, args.map(_.tpe), isJava)) + u.AppliedTypeTree(tpt, args).setType(defn.AppliedType(tpt.tpe, args.map(_.tpe))) } } - def Annotated(tpt: Tree, annot: Tree, isJava: Boolean)(implicit ctx: Context): Tree = { + def Annotated(tpt: Tree, annot: Tree)(implicit ctx: Context): Tree = { if (annot.tpe.typeSymbol === defn.RepeatedAnnot && tpt.tpe.typeSymbol.isSubClass(u.definitions.SeqClass) && tpt.tpe.typeArgs.length == 1) { - if (isJava) tpd.TypeTree(u.definitions.javaRepeatedType(tpt.tpe.typeArgs.head)) + if (ctx.isJava) tpd.TypeTree(u.definitions.javaRepeatedType(tpt.tpe.typeArgs.head)) else tpd.TypeTree(u.definitions.scalaRepeatedType(tpt.tpe.typeArgs.head)) } else { diff --git a/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala b/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala index 1072725f8117..faef3e5312b9 100644 --- a/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala +++ b/src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala @@ -68,7 +68,7 @@ trait TypeOps { self: TastyUniverse => } } - def showType(tpe: Type, wrap: Boolean = true): String = { + def showType(tpe: Type, wrap: Boolean = true)(implicit ctx: Context): String = { def prefixed(prefix: String)(op: => String) = { val raw = op if (wrap) s"""$prefix"$raw"""" @@ -107,7 +107,7 @@ trait TypeOps { self: TastyUniverse => } case tpe: u.TypeRef => - if (tpe.sym.is(Object, isJava = false)) prefixed("path") { + if (tpe.sym.is(Object)) prefixed("path") { s"${tpe.sym.fullName}.type" } else prefixed("tpelazy") { @@ -166,9 +166,9 @@ trait TypeOps { self: TastyUniverse => final val ObjectTpe: Type = u.definitions.ObjectTpe final val ObjectTpeJava: Type = u.definitions.ObjectTpeJava - def adjustParent(tp: Type, isJava: Boolean): Type = { + def adjustParent(tp: Type)(implicit ctx: Context): Type = { val tpe = tp.dealias - if (isJava && (tpe eq ObjectTpeJava)) ObjectTpe + if (ctx.isJava && (tpe eq ObjectTpeJava)) ObjectTpe else if (tpe.typeSymbolDirect === u.definitions.ObjectClass) u.definitions.AnyRefTpe else tpe } @@ -266,7 +266,7 @@ trait TypeOps { self: TastyUniverse => case tpe => tpe } - def AppliedType(tycon: Type, args: List[Type], isJava: Boolean)(implicit ctx: Context): Type = { + def AppliedType(tycon: Type, args: List[Type])(implicit ctx: Context): Type = { def formatFnType(arrow: String, isErased: Boolean, arity: Int, args: List[Type]): String = { val len = args.length @@ -289,7 +289,7 @@ trait TypeOps { self: TastyUniverse => case ErasedFunctionType(n) => erasedFnIsUnsupported(formatFnType("=>", isErased = true, n, args)) case FunctionXXLType(n) => bigFnIsUnsupported(formatFnType("=>", isErased = false, n, args)) case _ => - if (isJava && tycon.typeSymbol === u.definitions.ArrayClass) { + if (ctx.isJava && tycon.typeSymbol === u.definitions.ArrayClass) { val arg0 = args.head val arg1 = arg0 match { @@ -315,7 +315,7 @@ trait TypeOps { self: TastyUniverse => if (args.exists(tpe => tpe.isInstanceOf[u.TypeBounds] | tpe.isInstanceOf[LambdaPolyType])) { val syms = mutable.ListBuffer.empty[Symbol] def bindWildcards(tpe: Type) = tpe match { - case tpe: u.TypeBounds => ctx.newWildcard(tpe, isJava).tap(syms += _).pipe(_.ref) + case tpe: u.TypeBounds => ctx.newWildcard(tpe).tap(syms += _).pipe(_.ref) case tpe: LambdaPolyType => tpe.toNested case tpe => tpe } @@ -332,8 +332,8 @@ trait TypeOps { self: TastyUniverse => def ParamRef(binder: Type, idx: Int): Type = binder.asInstanceOf[LambdaType].lambdaParams(idx).ref - def NamedType(prefix: Type, sym: Symbol, isJava: Boolean): Type = { - if (isJava && sym.isClass && sym.isJavaDefined) { + def NamedType(prefix: Type, sym: Symbol)(implicit ctx: Context): Type = { + if (ctx.isJava && sym.isClass && sym.isJavaDefined) { def processInner(tp: Type): Type = tp match { case u.TypeRef(pre, sym, args) if !sym.isStatic => u.typeRef(processInner(pre.widen), sym, args) case _ => tp @@ -359,13 +359,13 @@ trait TypeOps { self: TastyUniverse => } } - def TypeRef(prefix: Type, name: TastyName.TypeName, isJava: Boolean)(implicit ctx: Context): Type = - TypeRefIn(prefix, prefix, name, isJava) + def TypeRef(prefix: Type, name: TastyName.TypeName)(implicit ctx: Context): Type = + TypeRefIn(prefix, prefix, name) - def TypeRefIn(prefix: Type, space: Type, name: TastyName.TypeName, isJava: Boolean)(implicit ctx: Context): Type = { + def TypeRefIn(prefix: Type, space: Type, name: TastyName.TypeName)(implicit ctx: Context): Type = { import scala.tools.tasty.TastyName._ - def doLookup = lookupTypeFrom(space)(prefix, name, isJava) + def doLookup = lookupTypeFrom(space)(prefix, name) val preSym = prefix.typeSymbol @@ -390,7 +390,7 @@ trait TypeOps { self: TastyUniverse => } } else { - if (isJava && preSym === u.definitions.JavaLangPackage) { + if (ctx.isJava && preSym === u.definitions.JavaLangPackage) { name match { case TypeName(SimpleName(tpnme.Object)) => ObjectTpeJava // Object =:= scala.Any in Java. case _ => doLookup @@ -401,11 +401,11 @@ trait TypeOps { self: TastyUniverse => } } - def TermRef(prefix: Type, name: TastyName, isJava: Boolean)(implicit ctx: Context): Type = - TermRefIn(prefix, prefix, name, isJava) + def TermRef(prefix: Type, name: TastyName)(implicit ctx: Context): Type = + TermRefIn(prefix, prefix, name) - def TermRefIn(prefix: Type, space: Type, name: TastyName, isJava: Boolean)(implicit ctx: Context): Type = - lookupTypeFrom(space)(prefix, name.toTermName, isJava) + def TermRefIn(prefix: Type, space: Type, name: TastyName)(implicit ctx: Context): Type = + lookupTypeFrom(space)(prefix, name.toTermName) } @@ -568,8 +568,7 @@ trait TypeOps { self: TastyUniverse => abstract class TastyCompleter( isClass: Boolean, - tflags: TastyFlagSet, - val isJava: Boolean + tflags: TastyFlagSet )(implicit capturedCtx: Context) extends BaseTastyCompleter(tflags) { override final val decls: u.Scope = if (isClass) u.newScope else u.EmptyScope @@ -641,8 +640,8 @@ trait TypeOps { self: TastyUniverse => def computeInfo(sym: Symbol)(implicit ctx: Context): Unit } - private[bridge] def lookupTypeFrom(owner: Type)(pre: Type, tname: TastyName, isJava: Boolean)(implicit ctx: Context): Type = - defn.NamedType(pre, lookupSymbol(owner, tname, isJava), isJava) + private[bridge] def lookupTypeFrom(owner: Type)(pre: Type, tname: TastyName)(implicit ctx: Context): Type = + defn.NamedType(pre, lookupSymbol(owner, tname)) private def lambdaResultType(resType: Type): Type = resType match { case res: LambdaPolyType => res.toNested