From 6450c69588af3d807cfce93a0c311de59e4a3661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2023 16:37:40 +0100 Subject: [PATCH 1/4] Introduce `memoized` to scrap boilerplate. We have a lot of methods whose results are cached using what is essentially a thread-unsafe Context-dependent lazy val. We encode the common shape of the initialization logic in an internal method `Utils.memoized`. --- build.sbt | 3 + .../main/scala/tastyquery/Annotations.scala | 45 ++-- .../src/main/scala/tastyquery/Symbols.scala | 196 ++++++------------ .../src/main/scala/tastyquery/Trees.scala | 32 +-- .../src/main/scala/tastyquery/Types.scala | 87 +++----- .../src/main/scala/tastyquery/Utils.scala | 15 ++ 6 files changed, 133 insertions(+), 245 deletions(-) create mode 100644 tasty-query/shared/src/main/scala/tastyquery/Utils.scala diff --git a/build.sbt b/build.sbt index 14f16c10..62474e57 100644 --- a/build.sbt +++ b/build.sbt @@ -126,6 +126,9 @@ lazy val tastyQuery = mimaBinaryIssueFilters ++= { import com.typesafe.tools.mima.core.* Seq( + // private[tastyquery], not an issue + ProblemFilters.exclude[MissingClassProblem]("tastyquery.Utils"), + ProblemFilters.exclude[MissingClassProblem]("tastyquery.Utils$"), // Everything in tastyquery.reader is private[tastyquery] at most ProblemFilters.exclude[Problem]("tastyquery.reader.*"), ) diff --git a/tasty-query/shared/src/main/scala/tastyquery/Annotations.scala b/tasty-query/shared/src/main/scala/tastyquery/Annotations.scala index ee0c1d6a..06620f73 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Annotations.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Annotations.scala @@ -9,6 +9,7 @@ import tastyquery.Names.* import tastyquery.Symbols.* import tastyquery.Trees.* import tastyquery.Types.* +import tastyquery.Utils.* object Annotations: final class Annotation(val tree: TermTree): @@ -18,13 +19,15 @@ object Annotations: /** The annotation class symbol. */ def symbol(using Context): ClassSymbol = - val local = mySymbol - if local != null then local - else - val computed = computeAnnotSymbol(tree) - mySymbol = computed - mySafeSymbol = Some(computed) - computed + memoized( + mySymbol, + { computed => + mySymbol = computed + mySafeSymbol = Some(computed) + } + ) { + computeAnnotSymbol(tree) + } end symbol /** Tests whether the annotation has the given class symbol. @@ -32,14 +35,15 @@ object Annotations: * If the class of this annotation cannot be successfully resolved, returns `false`. */ private[tastyquery] def safeHasSymbol(cls: ClassSymbol)(using Context): Boolean = - val safeSymbol = - val local = mySafeSymbol - if local != null then local - else - val local = computeSafeAnnotSymbol(tree) - local.foreach(mySymbol = _) - mySafeSymbol = local - local + val safeSymbol = memoized( + mySafeSymbol, + { computed => + computed.foreach(mySymbol = _) + mySafeSymbol = computed + } + ) { + computeSafeAnnotSymbol(tree) + } safeSymbol.contains(cls) end safeHasSymbol @@ -60,14 +64,9 @@ object Annotations: * `NamedArg`s are not visible with this method. They are replaced by * their right-hand-side. */ - def arguments: List[TermTree] = - val local = myArguments - if local != null then local - else - val computed = computeAnnotArguments(tree) - myArguments = computed - computed - end arguments + def arguments: List[TermTree] = memoized(myArguments, myArguments = _) { + computeAnnotArguments(tree) + } def argCount: Int = arguments.size diff --git a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala index 4e8cca47..c94d8bef 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala @@ -14,6 +14,7 @@ import tastyquery.Signatures.* import tastyquery.Spans.* import tastyquery.Trees.* import tastyquery.Types.* +import tastyquery.Utils.* import tastyquery.reader.Loaders.Loader @@ -233,9 +234,7 @@ object Symbols { */ def localRef: NamedType = // overridden in subclasses to provide a better-known result type - val local = myLocalRef - if local != null then local - else + memoized(myLocalRef, myLocalRef = _) { val pre = this match case self: ClassSymbol if self.isRefinementClass => /* Refinement classes are not declarations of their owner. @@ -247,9 +246,8 @@ object Symbols { case owner: PackageSymbol => owner.packageRef case owner: ClassSymbol => owner.thisType case _ => NoPrefix - val computed = NamedType(pre, this) - myLocalRef = computed - computed + NamedType(pre, this) + } end localRef /** The source language in which this symbol was defined. @@ -624,25 +622,11 @@ object Symbols { private[tastyquery] final def needsSignature: Boolean = declaredType.isInstanceOf[MethodicType] - final def signature(using Context): Signature = - val local = mySignature - if local != null then local - else - val sig = Signature.fromType(declaredType, sourceLanguage, Option.when(isConstructor)(owner.asClass)) - mySignature = sig - sig - end signature - - final def targetName(using Context): UnsignedTermName = - val local = myTargetName - if local != null then local - else - val computed = computeTargetName() - myTargetName = computed - computed - end targetName + final def signature(using Context): Signature = memoized(mySignature, mySignature = _) { + Signature.fromType(declaredType, sourceLanguage, Option.when(isConstructor)(owner.asClass)) + } - private def computeTargetName()(using Context): UnsignedTermName = + final def targetName(using Context): UnsignedTermName = memoized(myTargetName, myTargetName = _) { if annotations.isEmpty then name else defn.targetNameAnnotClass match @@ -651,7 +635,7 @@ object Symbols { getAnnotation(targetNameAnnotClass) match case None => name case Some(annot) => termName(annot.argIfConstant(0).get.stringValue) - end computeTargetName + } /** Returns the possibly signed name of this symbol. * @@ -661,16 +645,10 @@ object Symbols { * If the `owner` of this symbol is a `DeclaringSymbol`, then `owner.getDecl(signedName)` * will return this symbol. This is not always the case with `name`. */ - final def signedName(using Context): TermName = - val local = mySignedName - if local != null then local - else - val computed = - if needsSignature then SignedName(name, signature, targetName) - else name - mySignedName = computed - computed - end signedName + final def signedName(using Context): TermName = memoized(mySignedName, mySignedName = _) { + if needsSignature then SignedName(name, signature, targetName) + else name + } protected final def matchingDecl(inClass: ClassSymbol, siteClass: ClassSymbol)(using Context): Option[TermSymbol] = val candidates = inClass.getAllOverloadedDecls(name).filterNot(_.isPrivate) @@ -1079,12 +1057,9 @@ object Symbols { computeErasedName(owner.owner, filledName) end computeErasedName - val local = mySignatureName - if local != null then local - else - val computed = computeErasedName(owner, name.toTermName.asInstanceOf[SignatureNameItem]) - mySignatureName = computed - computed + memoized(mySignatureName, mySignatureName = _) { + computeErasedName(owner, name.toTermName.asInstanceOf[SignatureNameItem]) + } end signatureName private[tastyquery] final def withTypeParams(tparams: List[ClassTypeParamSymbol]): this.type = @@ -1102,16 +1077,7 @@ object Symbols { myParents = parents this - final def parents(using Context): List[Type] = - val localParents = myParents - if localParents != null then localParents - else - val computed = computeParents() - myParents = computed - computed - end parents - - private def computeParents()(using Context): List[Type] = + final def parents(using Context): List[Type] = memoized(myParents, myParents = _) { val tree = this.tree.getOrElse { throw IllegalStateException(s"$this was not assigned parents") } @@ -1123,7 +1089,7 @@ object Symbols { case parent: TypeTree => parent.toType } - end computeParents + } def parentClasses(using Context): List[ClassSymbol] = parents.map(tpe => @@ -1142,59 +1108,32 @@ object Symbols { if local == null then throw new IllegalStateException(s"givenSelfType not initialized for $this") else local - final def appliedRefInsideThis: Type = - val local = myAppliedRef - if local != null then local - else - val computed = - if typeParams.isEmpty then localRef - else AppliedType(localRef, typeParams.map(_.localRef)) - myAppliedRef = computed - computed - end appliedRefInsideThis - - final def selfType: Type = - val local = mySelfType - if local != null then local - else - val computed = givenSelfType match - case None => - appliedRefInsideThis - case Some(givenSelf) => - if isModuleClass then givenSelf - else AndType(givenSelf, appliedRefInsideThis) - mySelfType = computed - computed - end selfType - - final def linearization(using Context): List[ClassSymbol] = - val local = myLinearization - if local != null then local - else - val computed = computeLinearization() - myLinearization = computed - computed + final def appliedRefInsideThis: Type = memoized(myAppliedRef, myAppliedRef = _) { + if typeParams.isEmpty then localRef + else AppliedType(localRef, typeParams.map(_.localRef)) + } + + final def selfType: Type = memoized(mySelfType, mySelfType = _) { + givenSelfType match + case None => + appliedRefInsideThis + case Some(givenSelf) => + if isModuleClass then givenSelf + else AndType(givenSelf, appliedRefInsideThis) + } - private def computeLinearization()(using Context): List[ClassSymbol] = + final def linearization(using Context): List[ClassSymbol] = memoized(myLinearization, myLinearization = _) { val parentsLin = parentClasses.foldLeft[List[ClassSymbol]](Nil) { (lin, parent) => parent.linearization.filter(c => !lin.contains(c)) ::: lin } this :: parentsLin + } final def isSubClass(that: ClassSymbol)(using Context): Boolean = linearization.contains(that) /** The erasure of this class; nonsensical for `scala.Array`. */ - private[tastyquery] final def erasure(using Context): ErasedTypeRef.ClassRef = - val local = myErasure - if local != null then local - else - val computed = computeErasure() - myErasure = computed - computed - end erasure - - private def computeErasure()(using Context): ErasedTypeRef.ClassRef = + private[tastyquery] final def erasure(using Context): ErasedTypeRef.ClassRef = memoized(myErasure, myErasure = _) { (specialKind: @switch) match case SpecialKind.Any | SpecialKind.AnyVal | SpecialKind.Matchable | SpecialKind.Singleton => defn.ObjectClass.erasure @@ -1205,7 +1144,7 @@ object Symbols { defn.scalaPackage.findDecl(correspondingFunctionNName).asClass.erasure case _ => ErasedTypeRef.ClassRef(this) - end computeErasure + } private[tastyquery] final def boxedClass(using Context): ClassSymbol = specialKind match case SpecialKind.Unit => defn.ErasedBoxedUnitClass @@ -1591,14 +1530,9 @@ object Symbols { private var myThisType: ThisType | Null = null /** The `ThisType` for this class, as visible from inside this class. */ - final def thisType: ThisType = - val local = myThisType - if local != null then local - else - val computed = ThisType(localRef) - myThisType = computed - computed - end thisType + final def thisType: ThisType = memoized(myThisType, myThisType = _) { + ThisType(localRef) + } /** Directly sets the sealed children of this class. * @@ -1626,27 +1560,20 @@ object Symbols { * The results are ordered by their declaration order in the source. */ final def sealedChildren(using Context): List[ClassSymbol | TermSymbol] = - val local = mySealedChildren - if local != null then local - else - val computed: List[SealedChild] = - if !flags.is(Sealed) then Nil - else computeSealedChildren() - mySealedChildren = computed - computed - end sealedChildren - - private def computeSealedChildren()(using Context): List[SealedChild] = - myScala2SealedChildren match - case Some(scala2Children) => - scala2Children.map(extractSealedChildFromScala2(_)) - case None => - defn.internalChildAnnotClass match + memoized(mySealedChildren, mySealedChildren = _) { + if !flags.is(Sealed) then Nil + else + myScala2SealedChildren match + case Some(scala2Children) => + scala2Children.map(extractSealedChildFromScala2(_)) case None => - Nil - case Some(annotClass) => - getAnnotations(annotClass).map(extractSealedChildFromChildAnnot(_)) - end computeSealedChildren + defn.internalChildAnnotClass match + case None => + Nil + case Some(annotClass) => + getAnnotations(annotClass).map(extractSealedChildFromChildAnnot(_)) + } + end sealedChildren private def extractSealedChildFromScala2(scala2Child: Symbol | Scala2ExternalSymRef)(using Context): SealedChild = val sym = scala2Child match @@ -1952,21 +1879,14 @@ object Symbols { // See PackageRef.findMember private[tastyquery] def allPackageObjectDecls()(using Context): List[ClassSymbol] = - val local = myAllPackageObjectDecls - if local != null then local - else - val computed = computeAllPackageObjectDecls() - myAllPackageObjectDecls = computed - computed + memoized(myAllPackageObjectDecls, myAllPackageObjectDecls = _) { + loadingNewRoots(_.loadAllPackageObjectRoots(this)) + myDeclarations.valuesIterator.collect { + case cls: ClassSymbol if cls.name.isPackageObjectClassName => cls + }.toList + .sortBy(_.name.toString) // sort for determinism + } end allPackageObjectDecls - - private def computeAllPackageObjectDecls()(using Context): List[ClassSymbol] = - loadingNewRoots(_.loadAllPackageObjectRoots(this)) - myDeclarations.valuesIterator.collect { - case cls: ClassSymbol if cls.name.isPackageObjectClassName => cls - }.toList - .sortBy(_.name.toString) // sort for determinism - end computeAllPackageObjectDecls } private[tastyquery] object PackageSymbol: diff --git a/tasty-query/shared/src/main/scala/tastyquery/Trees.scala b/tasty-query/shared/src/main/scala/tastyquery/Trees.scala index 068253d7..e14ae3f8 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Trees.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Trees.scala @@ -14,6 +14,7 @@ import tastyquery.Spans.* import tastyquery.Symbols.* import tastyquery.Traversers.* import tastyquery.Types.* +import tastyquery.Utils.* object Trees { @@ -93,13 +94,8 @@ object Trees { protected def calculateType(using Context): TermType /** The term type of this tree. */ - final def tpe(using Context): TermType = { - val local = myType - if local != null then local - else - val computed = calculateType - myType = computed - computed + final def tpe(using Context): TermType = memoized(myType, myType = _) { + calculateType } end TermTree @@ -726,14 +722,9 @@ object Trees { def withPos(pos: SourcePosition): TypeTree - final def toPrefix: NonEmptyPrefix = - val local = myType - if local == null then - val computed = calculateType - myType = calculateType - computed - else local - end toPrefix + final def toPrefix: NonEmptyPrefix = memoized(myType, myType = _) { + calculateType + } final def toType: Type = toPrefix.requireType @@ -893,14 +884,9 @@ object Trees { final case class WildcardTypeArgTree(bounds: TypeBoundsTree)(pos: SourcePosition) extends TypeArgTree(pos) { private var myTypeOrWildcard: WildcardTypeArg | Null = null - def toTypeOrWildcard: TypeOrWildcard = - val local = myTypeOrWildcard - if local != null then local - else - val computed = WildcardTypeArg(bounds.toTypeBounds) - myTypeOrWildcard = computed - computed - end toTypeOrWildcard + def toTypeOrWildcard: TypeOrWildcard = memoized(myTypeOrWildcard, myTypeOrWildcard = _) { + WildcardTypeArg(bounds.toTypeBounds) + } override final def withPos(pos: SourcePosition): WildcardTypeArgTree = WildcardTypeArgTree(bounds)(pos) diff --git a/tasty-query/shared/src/main/scala/tastyquery/Types.scala b/tasty-query/shared/src/main/scala/tastyquery/Types.scala index 6ab6c446..20c28a4c 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Types.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Types.scala @@ -15,6 +15,7 @@ import tastyquery.Names.* import tastyquery.Signatures.* import tastyquery.Symbols.* import tastyquery.Trees.* +import tastyquery.Utils.* /** Types in the Scala type system. * @@ -938,23 +939,16 @@ object Types { */ def name: Name - protected final def nameImpl: ThisName = { - val local = myName - if local == null then - val computed = computeName - myName = computed - computed - else local.asInstanceOf[ThisName] // do not remove - it is needed to satisfy the debugger's expression evaluator + protected final def nameImpl: ThisName = memoized(myName, myName = _) { + (designator match { + case name: Name => name + case sym: TermOrTypeSymbol => sym.name + case LookupIn(_, name) => name + case LookupTypeIn(_, name) => name + case designator: Scala2ExternalSymRef => designator.name + }).asInstanceOf[ThisName] } - private def computeName: ThisName = (designator match { - case name: Name => name - case sym: TermOrTypeSymbol => sym.name - case LookupIn(_, name) => name - case LookupTypeIn(_, name) => name - case designator: Scala2ExternalSymRef => designator.name - }).asInstanceOf[ThisName] - def optSymbol(using Context): Option[TermOrTypeSymbol] /** A selection of the same kind, but with potentially a different prefix. @@ -1439,17 +1433,11 @@ object Types { final class ThisType(val tref: TypeRef) extends SingletonType { private var myUnderlying: Type | Null = null - override def underlying(using Context): Type = - val local = myUnderlying - if local != null then local - else - val cls = this.cls - val computed = - if cls.isStatic then cls.selfType - else cls.selfType.asSeenFrom(tref.prefix, cls) - myUnderlying = computed - computed - end underlying + override def underlying(using Context): Type = memoized(myUnderlying, myUnderlying = _) { + val cls = this.cls + if cls.isStatic then cls.selfType + else cls.selfType.asSeenFrom(tref.prefix, cls) + } final def cls(using Context): ClassSymbol = tref.asClass @@ -1463,14 +1451,9 @@ object Types { final class SuperType(val thistpe: ThisType, val explicitSupertpe: Option[Type]) extends TypeProxy with SingletonType: private var mySupertpe: Type | Null = explicitSupertpe.orNull - private[tastyquery] final def supertpe(using Context): Type = - val local = mySupertpe - if local != null then local - else - val computed = thistpe.cls.parents.reduceLeft(_ & _) - mySupertpe = computed - computed - end supertpe + private[tastyquery] final def supertpe(using Context): Type = memoized(mySupertpe, mySupertpe = _) { + thistpe.cls.parents.reduceLeft(_ & _) + } override def underlying(using Context): Type = supertpe @@ -1574,14 +1557,9 @@ object Types { final class RepeatedType(val elemType: Type) extends TypeProxy: private var myUnderlying: Type | Null = null - override def underlying(using Context): Type = - val local = myUnderlying - if local != null then local - else - val computed = defn.SeqTypeOf(elemType) - myUnderlying = computed - computed - end underlying + override def underlying(using Context): Type = memoized(myUnderlying, myUnderlying = _) { + defn.SeqTypeOf(elemType) + } private[tastyquery] def derivedRepeatedType(elemType: Type): RepeatedType = if elemType eq this.elemType then this else RepeatedType(elemType) @@ -2085,15 +2063,10 @@ object Types { require(!(isStable && isMethodic), s"Ill-formed $this") - private[tastyquery] def signedName(using Context): SignedName = - val local = mySignedName - if local != null then local - else - val sig = Signature.fromType(refinedType, SourceLanguage.Scala3, optCtorReturn = None) - val computed = SignedName(refinedName, sig) - mySignedName = computed - computed - end signedName + private[tastyquery] def signedName(using Context): SignedName = memoized(mySignedName, mySignedName = _) { + val sig = Signature.fromType(refinedType, SourceLanguage.Scala3, optCtorReturn = None) + SignedName(refinedName, sig) + } private[tastyquery] override def resolveMember(name: Name, pre: Type)(using Context): ResolveMemberResult = refinedType match @@ -2282,17 +2255,9 @@ object Types { def underlying(using Context): Type = bound - def reduced(using Context): Option[Type] = - val local = myReduced - if local != null then local - else - val computed = computeReduced() - myReduced = computed - computed - end reduced - - private def computeReduced()(using Context): Option[Type] = + def reduced(using Context): Option[Type] = memoized(myReduced, myReduced = _) { TypeMatching.matchCases(scrutinee, cases) + } override def toString(): String = s"MatchType($bound, $scrutinee, $cases)" diff --git a/tasty-query/shared/src/main/scala/tastyquery/Utils.scala b/tasty-query/shared/src/main/scala/tastyquery/Utils.scala new file mode 100644 index 00000000..33ba80f7 --- /dev/null +++ b/tasty-query/shared/src/main/scala/tastyquery/Utils.scala @@ -0,0 +1,15 @@ +package tastyquery + +private[tastyquery] object Utils: + /** A memoized computation `computed`, stored in `memo` using the `store` setter. */ + inline def memoized[A](memo: A | Null, inline store: A => Unit)(inline compute: => A): A = + if memo != null then memo + else + // Extracted in a separate def for good jitting of the code calling `memoized` + def computeAndStore(): A = + val computed = compute + store(computed) + computed + computeAndStore() + end memoized +end Utils From d9be8f0508cd85855d0368beb93dacf1d7e44e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2023 17:04:24 +0100 Subject: [PATCH 2/4] Introduce `assignOnce`/`getAssignedOnce` to scrap some boilerplate. `Symbols` have a number of fields that are set after their creation by the readers. They must be set exactly once, and must be set before they are read. We extract `assignOnce` and `getAssignedOnce` to encode the boilerplate of that pattern. --- .../src/main/scala/tastyquery/Symbols.scala | 66 ++++++------------- .../src/main/scala/tastyquery/Utils.scala | 13 ++++ 2 files changed, 32 insertions(+), 47 deletions(-) diff --git a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala index c94d8bef..b383c053 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala @@ -122,27 +122,18 @@ object Symbols { end setFlags private[tastyquery] final def setPrivateWithin(privateWithin: Option[DeclaringSymbol]): this.type = - if myPrivateWithin != null then throw IllegalStateException(s"reassignment of privateWithin to $this") - else - myPrivateWithin = privateWithin - this - end setPrivateWithin + assignOnce(myPrivateWithin, (myPrivateWithin = privateWithin))(s"reassignment of privateWithin to $this") + this private[tastyquery] final def setAnnotations(annots: List[Annotation]): this.type = - if myAnnotations != null then throw IllegalStateException(s"reassignment of annotations to $this") - else - myAnnotations = annots - this + assignOnce(myAnnotations, (myAnnotations = annots))(s"reassignment of annotations to $this") + this final def annotations: List[Annotation] = - val local = myAnnotations - if local != null then local - else throw IllegalStateException(s"annotations of $this have not been initialized") + getAssignedOnce(myAnnotations)(s"annotations of $this have not been initialized") protected final def privateWithin: Option[DeclaringSymbol] = - val local = myPrivateWithin - if local != null then local - else throw IllegalStateException(s"privateWithin of $this has not been initialized") + getAssignedOnce(myPrivateWithin)(s"privateWithin of $this has not been initialized") protected final def flags: FlagSet = if isFlagsInitialized then myFlags @@ -455,8 +446,7 @@ object Symbols { end doCheckCompleted private[tastyquery] final def withDeclaredType(tpe: TypeOrMethodic): this.type = - if myDeclaredType != null then throw new IllegalStateException(s"reassignment of declared type to $this") - myDeclaredType = tpe + assignOnce(myDeclaredType, (myDeclaredType = tpe))(s"reassignment of declared type to $this") this /** You should not need this; it is a hack for patching Scala 2 constructors in `PickleReader`. */ @@ -465,15 +455,12 @@ object Symbols { this def declaredType: TypeOrMethodic = - val local = myDeclaredType - if local != null then local - else throw new IllegalStateException(s"$this was not assigned a declared type") + getAssignedOnce(myDeclaredType)(s"$this was not assigned a declared type") private lazy val isPrefixDependent: Boolean = TypeOps.isPrefixDependent(declaredType) private[tastyquery] final def setParamSymss(paramSymss: List[ParamSymbolsClause]): this.type = - if myParamSymss != null then throw IllegalStateException(s"reassignment of paramSymss to $this") - myParamSymss = paramSymss + assignOnce(myParamSymss, (myParamSymss = paramSymss))(s"reassignment of paramSymss to $this") this private[tastyquery] final def autoFillParamSymss(): this.type = @@ -516,9 +503,7 @@ object Symbols { end autoComputeParamSymss def paramSymss: List[ParamSymbolsClause] = - val local = myParamSymss - if local != null then local - else throw IllegalStateException(s"$this was not assigned its paramSymss") + getAssignedOnce(myParamSymss)(s"$this was not assigned its paramSymss") /** Is this symbol a module val, i.e., the term of an `object`? * @@ -770,14 +755,11 @@ object Symbols { if myDeclaredBounds == null then failNotCompleted("bounds are not initialized") private[tastyquery] final def setDeclaredBounds(bounds: TypeBounds): this.type = - if myDeclaredBounds != null then throw IllegalStateException(s"Trying to re-set the bounds of $this") - myDeclaredBounds = bounds + assignOnce(myDeclaredBounds, (myDeclaredBounds = bounds))(s"Trying to re-set the bounds of $this") this final def declaredBounds: TypeBounds = - val local = myDeclaredBounds - if local == null then throw IllegalStateException(s"$this was not assigned type bounds") - else local + getAssignedOnce(myDeclaredBounds)(s"$this was not assigned type bounds") end TypeParamSymbol final class ClassTypeParamSymbol private (name: TypeName, override val owner: ClassSymbol) @@ -859,14 +841,11 @@ object Symbols { if myDefinition == null then failNotCompleted("type member definition not initialized") private[tastyquery] final def withDefinition(definition: TypeMemberDefinition): this.type = - if myDefinition != null then throw IllegalStateException(s"Reassignment of the definition of $this") - myDefinition = definition + assignOnce(myDefinition, (myDefinition = definition))(s"Reassignment of the definition of $this") this final def typeDef: TypeMemberDefinition = - val local = myDefinition - if local == null then throw IllegalStateException("$this was not assigned a definition") - else local + getAssignedOnce(myDefinition)("$this was not assigned a definition") final def declaredBounds: TypeBounds = typeDef match case TypeMemberDefinition.TypeAlias(alias) => TypeAlias(alias) @@ -1063,18 +1042,14 @@ object Symbols { end signatureName private[tastyquery] final def withTypeParams(tparams: List[ClassTypeParamSymbol]): this.type = - if myTypeParams != null then throw new IllegalStateException(s"reassignment of type parameters to $this") - myTypeParams = tparams + assignOnce(myTypeParams, (myTypeParams = tparams))(s"reassignment of type parameters to $this") this final def typeParams: List[ClassTypeParamSymbol] = - val local = myTypeParams - if local == null then throw new IllegalStateException(s"type params not initialized for $this") - else local + getAssignedOnce(myTypeParams)(s"type params not initialized for $this") private[tastyquery] final def withParentsDirect(parents: List[Type]): this.type = - if myParents != null then throw IllegalStateException(s"reassignment of parents of $this") - myParents = parents + assignOnce(myParents, (myParents = parents))(s"reassignment of parents of $this") this final def parents(using Context): List[Type] = memoized(myParents, myParents = _) { @@ -1099,14 +1074,11 @@ object Symbols { ) private[tastyquery] final def withGivenSelfType(givenSelfType: Option[Type]): this.type = - if myGivenSelfType != null then throw new IllegalStateException(s"reassignment of givenSelfType for $this") - myGivenSelfType = givenSelfType + assignOnce(myGivenSelfType, (myGivenSelfType = givenSelfType))(s"reassignment of givenSelfType for $this") this final def givenSelfType: Option[Type] = - val local = myGivenSelfType - if local == null then throw new IllegalStateException(s"givenSelfType not initialized for $this") - else local + getAssignedOnce(myGivenSelfType)(s"givenSelfType not initialized for $this") final def appliedRefInsideThis: Type = memoized(myAppliedRef, myAppliedRef = _) { if typeParams.isEmpty then localRef diff --git a/tasty-query/shared/src/main/scala/tastyquery/Utils.scala b/tasty-query/shared/src/main/scala/tastyquery/Utils.scala index 33ba80f7..f02d229c 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Utils.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Utils.scala @@ -12,4 +12,17 @@ private[tastyquery] object Utils: computed computeAndStore() end memoized + + inline def assignOnce(existing: Any, inline assign: => Unit)(inline msgIfAlreadyAssigned: => String): Unit = + // Methods calling `assignOnce` are not in fast paths, so no need to extract the exception in a local def + if existing != null then throw IllegalStateException(msgIfAlreadyAssigned) + assign + + inline def getAssignedOnce[A](value: A | Null)(inline msgIfNotAssignedYet: => String): A = + if value != null then value + else + // Extracted in a separate def for good jitting of the code calling `getAssignedOnce` + def notAssignedYet(): Nothing = + throw IllegalStateException(msgIfNotAssignedYet) + notAssignedYet() end Utils From f07a2dffe00853a69b020d4b364e761273335b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2023 17:10:23 +0100 Subject: [PATCH 3/4] Rename the `withX` methods that mutate the instance to `setX`. We keep `withX` names for methods that return new instances without changing the original. --- .../main/scala/tastyquery/Definitions.scala | 48 +++++++++---------- .../src/main/scala/tastyquery/Symbols.scala | 30 ++++++------ .../reader/classfiles/ClassfileParser.scala | 26 +++++----- .../reader/classfiles/JavaSignatures.scala | 8 ++-- .../reader/pickles/PickleReader.scala | 20 ++++---- .../reader/tasties/TreeUnpickler.scala | 14 +++--- 6 files changed, 73 insertions(+), 73 deletions(-) diff --git a/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala b/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala index 6f924ee7..efa21c9c 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Definitions.scala @@ -98,10 +98,10 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS private def createSpecialClass(name: SimpleTypeName, parents: List[Type], flags: FlagSet): ClassSymbol = val cls = ClassSymbol.create(name, scalaPackage) - cls.withTypeParams(Nil) - cls.withParentsDirect(parents) - cls.withGivenSelfType(None) - cls.withFlags(flags, None) + cls.setTypeParams(Nil) + cls.setParentsDirect(parents) + cls.setGivenSelfType(None) + cls.setFlags(flags, None) cls.setAnnotations(Nil) cls.checkCompleted() cls @@ -115,8 +115,8 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS ): TermSymbol = val sym = TermSymbol .create(name, owner) - .withFlags(Method | flags, privateWithin = None) - .withDeclaredType(tpe) + .setFlags(Method | flags, privateWithin = None) + .setDeclaredType(tpe) .setAnnotations(Nil) .autoFillParamSymss(termParamFlags) sym.paramSymss.foreach(_.merge.foreach(_.setAnnotations(Nil))) @@ -139,8 +139,8 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS private[tastyquery] val scala2FakeOwner: TermSymbol = TermSymbol .createNotDeclaration(termName(""), scalaPackage) - .withFlags(Synthetic, None) - .withDeclaredType(AnyType) + .setFlags(Synthetic, None) + .setDeclaredType(AnyType) .setAnnotations(Nil) .checkCompleted() end scala2FakeOwner @@ -148,8 +148,8 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS private[tastyquery] val scala2MacroInfoFakeMethod: TermSymbol = TermSymbol .createNotDeclaration(nme.m_macro, scalaPackage) - .withFlags(Synthetic, None) - .withDeclaredType(NothingType) + .setFlags(Synthetic, None) + .setDeclaredType(NothingType) .setAnnotations(Nil) .checkCompleted() end scala2MacroInfoFakeMethod @@ -161,8 +161,8 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS alias: Type ): TypeMemberSymbol = val sym = TypeMemberSymbol.create(name, owner) - sym.withFlags(flags, None) - sym.withDefinition(TypeMemberDefinition.TypeAlias(alias)) + sym.setFlags(flags, None) + sym.setDefinition(TypeMemberDefinition.TypeAlias(alias)) sym.setAnnotations(Nil) sym.checkCompleted() sym @@ -177,8 +177,8 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS val andOrParamNames = List(typeName("A"), typeName("B")) val andTypeAlias = TypeMemberSymbol.create(typeName("&"), scalaPackage) - andTypeAlias.withFlags(EmptyFlagSet, None) - andTypeAlias.withDefinition( + andTypeAlias.setFlags(EmptyFlagSet, None) + andTypeAlias.setDefinition( TypeMemberDefinition.TypeAlias( TypeLambda(andOrParamNames)( pt => List(NothingAnyBounds, NothingAnyBounds), @@ -190,8 +190,8 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS andTypeAlias.checkCompleted() val orTypeAlias = TypeMemberSymbol.create(typeName("|"), scalaPackage) - orTypeAlias.withFlags(EmptyFlagSet, None) - orTypeAlias.withDefinition( + orTypeAlias.setFlags(EmptyFlagSet, None) + orTypeAlias.setDefinition( TypeMemberDefinition.TypeAlias( TypeLambda(andOrParamNames)( pt => List(NothingAnyBounds, NothingAnyBounds), @@ -364,32 +364,32 @@ final class Definitions private[tastyquery] (ctx: Context, rootPackage: PackageS val name = typeName("ContextFunction" + n) val cls = ClassSymbol.create(name, scalaPackage) - cls.withFlags(Trait | NoInitsInterface, None) - cls.withParentsDirect(ObjectType :: Nil) + cls.setFlags(Trait | NoInitsInterface, None) + cls.setParentsDirect(ObjectType :: Nil) cls.setAnnotations(Nil) - cls.withGivenSelfType(None) + cls.setGivenSelfType(None) val inputTypeParams = List.tabulate(n) { i => ClassTypeParamSymbol .create(typeName("T" + i), cls) - .withFlags(Contravariant, None) + .setFlags(Contravariant, None) .setDeclaredBounds(NothingAnyBounds) .setAnnotations(Nil) } val resultTypeParam = ClassTypeParamSymbol .create(typeName("R"), cls) - .withFlags(Covariant, None) + .setFlags(Covariant, None) .setDeclaredBounds(NothingAnyBounds) .setAnnotations(Nil) val allTypeParams = inputTypeParams :+ resultTypeParam allTypeParams.foreach(_.checkCompleted()) - cls.withTypeParams(allTypeParams) + cls.setTypeParams(allTypeParams) val applyMethod = TermSymbol.create(termName("apply"), cls) - applyMethod.withFlags(Method | Abstract, None) - applyMethod.withDeclaredType( + applyMethod.setFlags(Method | Abstract, None) + applyMethod.setDeclaredType( MethodType(List.tabulate(n)(i => termName("x" + i)))( mt => inputTypeParams.map(_.localRef), mt => resultTypeParam.localRef diff --git a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala index b383c053..457e2231 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala @@ -100,7 +100,7 @@ object Symbols { if myPrivateWithin == null then throw failNotCompleted("privateWithin was not initialized") if myAnnotations == null then throw failNotCompleted("annotations were not initialized") - private[tastyquery] def withTree(t: DefiningTreeType): this.type = + private[tastyquery] def setTree(t: DefiningTreeType): this.type = require(!isPackage, s"Multiple trees correspond to one package, a single tree cannot be assigned") myTree = Some(t) this @@ -108,7 +108,7 @@ object Symbols { final def tree: Option[DefiningTreeType] = myTree - private[tastyquery] final def withFlags(flags: FlagSet, privateWithin: Option[DeclaringSymbol]): this.type = + private[tastyquery] final def setFlags(flags: FlagSet, privateWithin: Option[DeclaringSymbol]): this.type = setFlags(flags) setPrivateWithin(privateWithin) @@ -445,7 +445,7 @@ object Symbols { throw IllegalArgumentException(s"illegal non-empty paramSymss $myParamSymss for $this") end doCheckCompleted - private[tastyquery] final def withDeclaredType(tpe: TypeOrMethodic): this.type = + private[tastyquery] final def setDeclaredType(tpe: TypeOrMethodic): this.type = assignOnce(myDeclaredType, (myDeclaredType = tpe))(s"reassignment of declared type to $this") this @@ -480,8 +480,8 @@ object Symbols { val paramSyms = tpe.paramNames.lazyZip(tpe.paramTypes).map { (name, paramType) => TermSymbol .createNotDeclaration(name, this) - .withFlags(termParamFlags, privateWithin = None) - .withDeclaredType(paramType) + .setFlags(termParamFlags, privateWithin = None) + .setDeclaredType(paramType) } Left(paramSyms) :: autoComputeParamSymss(tpe.resultType, termParamFlags) @@ -489,7 +489,7 @@ object Symbols { val paramSyms = tpe.paramNames.map { name => LocalTypeParamSymbol .create(name, this) - .withFlags(EmptyFlagSet, privateWithin = None) + .setFlags(EmptyFlagSet, privateWithin = None) } val paramSymRefs = paramSyms.map(_.localRef) def subst(t: TypeOrMethodic): t.ThisTypeMappableType = @@ -840,7 +840,7 @@ object Symbols { super.doCheckCompleted() if myDefinition == null then failNotCompleted("type member definition not initialized") - private[tastyquery] final def withDefinition(definition: TypeMemberDefinition): this.type = + private[tastyquery] final def setDefinition(definition: TypeMemberDefinition): this.type = assignOnce(myDefinition, (myDefinition = definition))(s"Reassignment of the definition of $this") this @@ -1041,14 +1041,14 @@ object Symbols { } end signatureName - private[tastyquery] final def withTypeParams(tparams: List[ClassTypeParamSymbol]): this.type = + private[tastyquery] final def setTypeParams(tparams: List[ClassTypeParamSymbol]): this.type = assignOnce(myTypeParams, (myTypeParams = tparams))(s"reassignment of type parameters to $this") this final def typeParams: List[ClassTypeParamSymbol] = getAssignedOnce(myTypeParams)(s"type params not initialized for $this") - private[tastyquery] final def withParentsDirect(parents: List[Type]): this.type = + private[tastyquery] final def setParentsDirect(parents: List[Type]): this.type = assignOnce(myParents, (myParents = parents))(s"reassignment of parents of $this") this @@ -1073,7 +1073,7 @@ object Symbols { } ) - private[tastyquery] final def withGivenSelfType(givenSelfType: Option[Type]): this.type = + private[tastyquery] final def setGivenSelfType(givenSelfType: Option[Type]): this.type = assignOnce(myGivenSelfType, (myGivenSelfType = givenSelfType))(s"reassignment of givenSelfType for $this") this @@ -1693,10 +1693,10 @@ object Symbols { private[tastyquery] def createRefinedClassSymbol(owner: Symbol, objectType: TypeRef, flags: FlagSet): ClassSymbol = val cls = ClassSymbol(tpnme.RefinedClassMagic, owner) // by-pass `owner.addDeclIfDeclaringSym` cls - .withTypeParams(Nil) - .withParentsDirect(objectType :: Nil) - .withGivenSelfType(None) - .withFlags(flags, None) + .setTypeParams(Nil) + .setParentsDirect(objectType :: Nil) + .setGivenSelfType(None) + .setFlags(flags, None) .setAnnotations(Nil) cls.checkCompleted() cls @@ -1721,7 +1721,7 @@ object Symbols { val packageRef: PackageRef = new PackageRef(this) private var myAllPackageObjectDecls: List[ClassSymbol] | Null = null - this.withFlags(EmptyFlagSet, None) + this.setFlags(EmptyFlagSet, None) this.setAnnotations(Nil) private lazy val _fullName: PackageFullName = diff --git a/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/ClassfileParser.scala b/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/ClassfileParser.scala index 3b88112d..d2c127da 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/ClassfileParser.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/ClassfileParser.scala @@ -168,17 +168,17 @@ private[reader] object ClassfileParser { val moduleClass = ClassSymbol .create(name.withObjectSuffix.toTypeName, classOwner) - .withTypeParams(Nil) - .withFlags(clsFlags | Flags.ModuleClassCreationFlags, clsPrivateWithin) + .setTypeParams(Nil) + .setFlags(clsFlags | Flags.ModuleClassCreationFlags, clsPrivateWithin) .setAnnotations(Nil) - .withParentsDirect(rctx.ObjectType :: Nil) - .withGivenSelfType(None) + .setParentsDirect(rctx.ObjectType :: Nil) + .setGivenSelfType(None) allRegisteredSymbols += moduleClass val module = TermSymbol .create(name, classOwner) - .withDeclaredType(moduleClass.localRef) - .withFlags(clsFlags | Flags.ModuleValCreationFlags, clsPrivateWithin) + .setDeclaredType(moduleClass.localRef) + .setFlags(clsFlags | Flags.ModuleValCreationFlags, clsPrivateWithin) .setAnnotations(Nil) allRegisteredSymbols += module @@ -236,7 +236,7 @@ private[reader] object ClassfileParser { else parsedType adaptedType end declaredType - sym.withDeclaredType(declaredType) + sym.setDeclaredType(declaredType) // Compute the flags for the symbol val flags = @@ -245,7 +245,7 @@ private[reader] object ClassfileParser { if isSignaturePolymorphic(isMethod, javaFlags, declaredType) then flags1 |= SignaturePolymorphic flags1 end flags - sym.withFlags(flags, privateWithin(javaFlags)) + sym.setFlags(flags, privateWithin(javaFlags)) // Read and fill annotations val annots = readAnnotations(sym, attributes) @@ -314,11 +314,11 @@ private[reader] object ClassfileParser { val parents1 = if parents.head eq rctx.FromJavaObjectType then rctx.ObjectType :: parents.tail else parents - cls.withParentsDirect(parents1) + cls.setParentsDirect(parents1) end initParents - cls.withGivenSelfType(None) - cls.withFlags(clsFlags, clsPrivateWithin) + cls.setGivenSelfType(None) + cls.setFlags(clsFlags, clsPrivateWithin) initParents() // Intercept special classes to create their magic methods @@ -331,8 +331,8 @@ private[reader] object ClassfileParser { if cls.isTrait then val ctor = TermSymbol .create(nme.Constructor, cls) - .withDeclaredType(cls.makePolyConstructorType(MethodType(Nil, Nil, rctx.UnitType))) - .withFlags(Method | JavaDefined, None) + .setDeclaredType(cls.makePolyConstructorType(MethodType(Nil, Nil, rctx.UnitType))) + .setFlags(Method | JavaDefined, None) .setAnnotations(Nil) .autoFillParamSymss() ctor.paramSymss.foreach(_.merge.foreach(_.setAnnotations(Nil))) diff --git a/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/JavaSignatures.scala b/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/JavaSignatures.scala index 01f16e28..49c2c141 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/JavaSignatures.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/reader/classfiles/JavaSignatures.scala @@ -31,7 +31,7 @@ private[classfiles] object JavaSignatures: InnerClasses, Resolver ): List[Type] = - cls.withTypeParams(Nil) + cls.setTypeParams(Nil) if cls.isObject then rctx.AnyType :: rctx.MatchableType :: Nil else val superRef = superClass.map(classRef).getOrElse(rctx.ObjectType) @@ -329,16 +329,16 @@ private[classfiles] object JavaSignatures: val tparams = tparamNames.map { tname => val paramSym = ClassTypeParamSymbol.create(tname, cls) allRegisteredSymbols += paramSym - paramSym.withFlags(JavaDefined, None).setAnnotations(Nil) + paramSym.setFlags(JavaDefined, None).setAnnotations(Nil) paramSym } val lookup = tparamNames.lazyZip(tparams).toMap val tparamBounds = typeParamsRest(lookup) tparams.lazyZip(tparamBounds).foreach((tparam, bounds) => tparam.setDeclaredBounds(bounds)) - cls.withTypeParams(tparams) + cls.setTypeParams(tparams) classRest(lookup) else - cls.withTypeParams(Nil) + cls.setTypeParams(Nil) classRest(null) def fieldSignature: Type = diff --git a/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala b/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala index b9c59716..155ce69f 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala @@ -210,7 +210,7 @@ private[pickles] class PickleReader { else LocalTypeParamSymbol.create(name, owner) else if pickleFlags.isExistential then TypeMemberSymbol.createNotDeclaration(name, owner) else TypeMemberSymbol.create(name, owner) - sym.withFlags(flags, privateWithin) + sym.setFlags(flags, privateWithin) case CLASSsym if name1 == tpnme.RefinedClassMagic => // return to by-pass the addition to localSymbolInfoRefs @@ -231,7 +231,7 @@ private[pickles] class PickleReader { if !atEnd then localClassGivenSelfTypeRefs(cls) = pkl.readNat() if cls.owner == rctx.scalaPackage && name == tpnme.PredefModule then rctx.createPredefMagicMethods(cls) - cls.withFlags(flags, privateWithin) + cls.setFlags(flags, privateWithin) case MODULEsym | VALsym => val name2 = name1.asInstanceOf[SimpleName] @@ -272,7 +272,7 @@ private[pickles] class PickleReader { val sym = if pickleFlags.isExistential || forceNotDeclaration then TermSymbol.createNotDeclaration(name, owner) else TermSymbol.create(name, owner) - sym.withFlags(flags, privateWithin) + sym.setFlags(flags, privateWithin) case _ => errorBadSignature("bad symbol tag: " + tag) @@ -306,7 +306,7 @@ private[pickles] class PickleReader { case _ => throw Scala2PickleFormatException(s"Type or type bounds expected for $sym gut found $tpe") sym match case sym: TypeMemberSymbol => - sym.withDefinition(bounds match + sym.setDefinition(bounds match case bounds: AbstractTypeBounds => TypeMemberDefinition.AbstractType(bounds) case TypeAlias(alias) => TypeMemberDefinition.TypeAlias(alias) ) @@ -324,7 +324,7 @@ private[pickles] class PickleReader { case tpe => throw Scala2PickleFormatException(s"unexpected type $tpe for $cls, owner is ${cls.owner}") - cls.withTypeParams(typeParams) + cls.setTypeParams(typeParams) val parentTypes = if cls.isAnyVal then @@ -334,10 +334,10 @@ private[pickles] class PickleReader { // Patch the superclass of TupleN classes to inherit from *: rctx.GenericTupleTypeOf(typeParams.map(_.localRef)) :: scala2ParentTypes.tail else scala2ParentTypes - cls.withParentsDirect(parentTypes) + cls.setParentsDirect(parentTypes) val givenSelfType = localClassGivenSelfTypeRefs.remove(cls).map(addr => at(addr)(readTrueType())) - cls.withGivenSelfType(givenSelfType) + cls.setGivenSelfType(givenSelfType) case sym: TermSymbol => val storedType = tpe match @@ -351,10 +351,10 @@ private[pickles] class PickleReader { val cls = sym.owner.asClass completeSymbolType(cls) for typeParam <- cls.typeParams do completeSymbolType(typeParam) - sym.withDeclaredType(patchConstructorType(cls, unwrappedTpe)) + sym.setDeclaredType(patchConstructorType(cls, unwrappedTpe)) sym.setParamSymss(patchConstructorParamSymss(sym, paramSymss)) else - sym.withDeclaredType(unwrappedTpe) + sym.setDeclaredType(unwrappedTpe) sym.setParamSymss(paramSymss) end completeSymbolType @@ -394,7 +394,7 @@ private[pickles] class PickleReader { val ctorTypeParams = clsTypeParams.map { clsTypeParam => LocalTypeParamSymbol .create(clsTypeParam.name, ctor) - .withFlags(EmptyFlagSet, privateWithin = None) + .setFlags(EmptyFlagSet, privateWithin = None) .setAnnotations(Nil) } diff --git a/tasty-query/shared/src/main/scala/tastyquery/reader/tasties/TreeUnpickler.scala b/tasty-query/shared/src/main/scala/tastyquery/reader/tasties/TreeUnpickler.scala index 8374f8df..7b110a30 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/reader/tasties/TreeUnpickler.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/reader/tasties/TreeUnpickler.scala @@ -516,7 +516,7 @@ private[tasties] class TreeUnpickler private ( throw TastyFormatException( s"typeDef $typeDef inconsistent with Opaque flag $isOpaque for $symbol at $posErrorMsg" ) - symbol.withDefinition(typeDef) + symbol.setDefinition(typeDef) definingTree(symbol, TypeMember(name, typeDefTree, symbol)(spn)) } readAnnotationsInModifiers(typeDef.symbol, end) @@ -674,7 +674,7 @@ private[tasties] class TreeUnpickler private ( reader.readByte() val end = reader.readEnd() val tparams = readTypeParams - cls.withTypeParams(tparams.map(_.symbol.asInstanceOf[ClassTypeParamSymbol])) + cls.setTypeParams(tparams.map(_.symbol.asInstanceOf[ClassTypeParamSymbol])) val params = readParams val parents: List[Apply | Block | TypeTree] = reader.collectWhile(reader.nextByte != SELFDEF && reader.nextByte != DEFDEF) { @@ -697,7 +697,7 @@ private[tasties] class TreeUnpickler private ( case _ => self0 - cls.withGivenSelfType(self.map(_.tpt.toType)) + cls.setGivenSelfType(self.map(_.tpt.toType)) // The first entry is the constructor val cstr = readStat.asInstanceOf[DefDef] val body = readStats(end) @@ -770,14 +770,14 @@ private[tasties] class TreeUnpickler private ( // Work around https://github.com/lampepfl/dotty/issues/19237 if tag == PARAM && symbol.owner.name.isInstanceOf[InlineAccessorName] then rctx.NothingType else throw TastyFormatException(s"unexpected type $packageRef for $symbol in $posErrorMsg") - symbol.withDeclaredType(tpe) + symbol.setDeclaredType(tpe) definingTree(symbol, ValDef(name, tpt, rhs, symbol)(spn)) case DEFDEF => val normalizedParams = if name == nme.Constructor then normalizeCtorParamClauses(params) else params - symbol.withDeclaredType(ParamsClause.makeDefDefType(normalizedParams, tpt)) + symbol.setDeclaredType(ParamsClause.makeDefDefType(normalizedParams, tpt)) symbol.setParamSymss(normalizedParams.map(paramsClauseToParamSymbolsClause(_))) definingTree(symbol, DefDef(name, normalizedParams, tpt, rhs, symbol)(spn)) } @@ -816,7 +816,7 @@ private[tasties] class TreeUnpickler private ( reader.until(end)(readTerm) def definingTree(symbol: Symbol, tree: symbol.DefiningTreeType): tree.type = - symbol.withTree(tree) + symbol.setTree(tree) tree private def makeIdent(name: UnsignedTermName, tpe: TermType, pos: SourcePosition): Ident = @@ -854,7 +854,7 @@ private[tasties] class TreeUnpickler private ( val body = readPattern val symbol = caches.getSymbol[TermSymbol](start) readAnnotationsInModifiers(symbol, end) - symbol.withDeclaredType(typ) + symbol.setDeclaredType(typ) definingTree(symbol, Bind(name, body, symbol)(spn)) case ALTERNATIVE => val spn = span From 0ed0945f22cb0460c7a22d990b23f634509a7bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 20 Dec 2023 17:14:27 +0100 Subject: [PATCH 4/4] Remove useless `throw`s of a `Nothing`-returning method. --- tasty-query/shared/src/main/scala/tastyquery/Symbols.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala index 457e2231..722a82bd 100644 --- a/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala +++ b/tasty-query/shared/src/main/scala/tastyquery/Symbols.scala @@ -96,9 +96,9 @@ object Symbols { * If a check fail, it should be reported with [[failNotCompleted]]. */ protected def doCheckCompleted(): Unit = - if !isFlagsInitialized then throw failNotCompleted("flags were not initialized") - if myPrivateWithin == null then throw failNotCompleted("privateWithin was not initialized") - if myAnnotations == null then throw failNotCompleted("annotations were not initialized") + if !isFlagsInitialized then failNotCompleted("flags were not initialized") + if myPrivateWithin == null then failNotCompleted("privateWithin was not initialized") + if myAnnotations == null then failNotCompleted("annotations were not initialized") private[tastyquery] def setTree(t: DefiningTreeType): this.type = require(!isPackage, s"Multiple trees correspond to one package, a single tree cannot be assigned")