@@ -1999,7 +1999,7 @@ object Types {
19991999
20002000// --- NamedTypes ------------------------------------------------------------------
20012001
2002- abstract class NamedType extends CachedProxyType with ValueType with SignatureCachingType { self =>
2002+ abstract class NamedType extends CachedProxyType with ValueType { self =>
20032003
20042004 type ThisType >: this .type <: NamedType
20052005 type ThisName <: Name
@@ -2015,11 +2015,13 @@ object Types {
20152015 private var lastSymbol : Symbol = null
20162016 private var checkedPeriod : Period = Nowhere
20172017 private var myStableHash : Byte = 0
2018+ private var mySignature : Signature = _
2019+ private var mySignatureRunId : Int = NoRunId
20182020
20192021 // Invariants:
2020- // (1) checkedPeriod != Nowhere => lastDenotation != null
2021- // (2) lastDenotation != null => lastSymbol != null
2022- // (3) mySigRunId != NoRunId => mySig != null
2022+ // (1) checkedPeriod != Nowhere => lastDenotation != null
2023+ // (2) lastDenotation != null => lastSymbol != null
2024+ // (3) mySignatureRunId != NoRunId => mySignature != null
20232025
20242026 def isType : Boolean = isInstanceOf [TypeRef ]
20252027 def isTerm : Boolean = isInstanceOf [TermRef ]
@@ -2037,15 +2039,22 @@ object Types {
20372039 case sym : Symbol => sym.originDenotation.name
20382040 }
20392041
2040- /** The signature computed from the last known denotation with `sigFromDenot`,
2041- * or if there is none, the signature of the symbol. Signatures are always
2042- * computed before erasure, since some symbols change their signature at erasure.
2043- */
2044- protected [dotc] def computeSignature (using Context ): Signature =
2045- val lastd = lastDenotation
2046- if lastd != null then sigFromDenot(lastd)
2047- else if ctx.erasedTypes then atPhase(erasurePhase)(computeSignature)
2048- else symbol.asSeenFrom(prefix).signature
2042+ final override def signature (using Context ): Signature =
2043+ /** The signature computed from the last known denotation with `sigFromDenot`,
2044+ * or if there is none, the signature of the symbol. Signatures are always
2045+ * computed before erasure, since some symbols change their signature at erasure.
2046+ */
2047+ def computeSignature (using Context ): Signature =
2048+ val lastd = lastDenotation
2049+ if lastd != null then sigFromDenot(lastd)
2050+ else if ctx.erasedTypes then atPhase(erasurePhase)(computeSignature)
2051+ else symbol.asSeenFrom(prefix).signature
2052+
2053+ if ctx.runId != mySignatureRunId then
2054+ mySignature = computeSignature
2055+ if ! mySignature.isUnderDefined then mySignatureRunId = ctx.runId
2056+ mySignature
2057+ end signature
20492058
20502059 /** The signature computed from the current denotation with `sigFromDenot` if it is
20512060 * known without forcing.
@@ -3219,39 +3228,11 @@ object Types {
32193228 // is that most poly types are cyclic via poly params,
32203229 // and therefore two different poly types would never be equal.
32213230
3222- /** A trait that mixes in functionality for signature caching */
3223- trait SignatureCachingType extends TermType {
3224- protected var mySignature : Signature = _
3225- protected var mySignatureRunId : Int = NoRunId
3226-
3227- protected [dotc] def computeSignature (using Context ): Signature
3228-
3229- final override def signature (using Context ): Signature = {
3230- if (ctx.runId != mySignatureRunId) {
3231- mySignature = computeSignature
3232- if (! mySignature.isUnderDefined) mySignatureRunId = ctx.runId
3233- }
3234- mySignature
3235- }
3236- }
3237-
3238- trait MethodicType extends TermType {
3239- protected def resultSignature (using Context ): Signature = try resultType match {
3240- case rtp : MethodicType => rtp.signature
3241- case tp =>
3242- if (tp.isRef(defn.UnitClass )) Signature (Nil , defn.UnitClass .fullName.asTypeName)
3243- else Signature (tp, isJava = false )
3244- }
3245- catch {
3246- case ex : AssertionError =>
3247- println(i " failure while taking result signature of $this: $resultType" )
3248- throw ex
3249- }
3250- }
3231+ trait MethodicType extends TermType
32513232
32523233 /** A by-name parameter type of the form `=> T`, or the type of a method with no parameter list. */
32533234 abstract case class ExprType (resType : Type )
3254- extends CachedProxyType with TermType with MethodicType {
3235+ extends CachedProxyType with MethodicType {
32553236 override def resultType (using Context ): Type = resType
32563237 override def underlying (using Context ): Type = resType
32573238
@@ -3371,7 +3352,66 @@ object Types {
33713352 final override def equals (that : Any ): Boolean = equals(that, null )
33723353 }
33733354
3374- abstract class MethodOrPoly extends UncachedGroundType with LambdaType with MethodicType with SignatureCachingType {
3355+ /** The superclass of MethodType and PolyType. */
3356+ sealed abstract class MethodOrPoly extends UncachedGroundType with LambdaType with MethodicType {
3357+
3358+ // Invariants:
3359+ // (1) mySignatureRunId != NoRunId => mySignature != null
3360+ // (2) myJavaSignatureRunId != NoRunId => myJavaSignature != null
3361+
3362+ private var mySignature : Signature = _
3363+ private var mySignatureRunId : Int = NoRunId
3364+ private var myJavaSignature : Signature = _
3365+ private var myJavaSignatureRunId : Int = NoRunId
3366+
3367+ /** If `isJava` is false, the Scala signature of this method. Otherwise, its Java signature.
3368+ *
3369+ * This distinction is needed because the same method type
3370+ * might be part of both a Java and Scala class and each language has
3371+ * different type erasure rules.
3372+ *
3373+ * Invariants:
3374+ * - Two distinct method overloads defined in the same _Scala_ class will
3375+ * have distinct _Scala_ signatures.
3376+ * - Two distinct methods overloads defined in the same _Java_ class will
3377+ * have distinct _Java_ signatures.
3378+ *
3379+ * @see SingleDenotation#signature
3380+ */
3381+ def signature (isJava : Boolean )(using Context ): Signature =
3382+ def computeSignature (isJava : Boolean )(using Context ): Signature =
3383+ val resultSignature = resultType match
3384+ case tp : MethodOrPoly => tp.signature(isJava)
3385+ case tp : ExprType => tp.signature
3386+ case tp =>
3387+ if tp.isRef(defn.UnitClass ) then Signature (Nil , defn.UnitClass .fullName.asTypeName)
3388+ else Signature (tp, isJava = false )
3389+ this match
3390+ case tp : MethodType =>
3391+ val params = if (isErasedMethod) Nil else tp.paramInfos
3392+ resultSignature.prependTermParams(params, isJava)
3393+ case tp : PolyType =>
3394+ resultSignature.prependTypeParams(tp.paramNames.length)
3395+
3396+ if isJava then
3397+ if ctx.runId != myJavaSignatureRunId then
3398+ myJavaSignature = computeSignature(isJava)
3399+ if ! myJavaSignature.isUnderDefined then myJavaSignatureRunId = ctx.runId
3400+ myJavaSignature
3401+ else
3402+ if ctx.runId != mySignatureRunId then
3403+ mySignature = computeSignature(isJava)
3404+ if ! mySignature.isUnderDefined then mySignatureRunId = ctx.runId
3405+ mySignature
3406+ end signature
3407+
3408+ final override def signature (using Context ): Signature =
3409+ def isJava (tp : Type ): Boolean = tp match
3410+ case tp : PolyType => isJava(tp.resultType)
3411+ case tp : MethodType => tp.isJavaMethod
3412+ case _ => false
3413+ signature(isJava = isJava(this ))
3414+
33753415 final override def hashCode : Int = System .identityHashCode(this )
33763416
33773417 final override def equals (that : Any ): Boolean = equals(that, null )
@@ -3531,11 +3571,6 @@ object Types {
35313571 companion.eq(ContextualMethodType ) ||
35323572 companion.eq(ErasedContextualMethodType )
35333573
3534- protected [dotc] def computeSignature (using Context ): Signature = {
3535- val params = if (isErasedMethod) Nil else paramInfos
3536- resultSignature.prependTermParams(params, isJavaMethod)
3537- }
3538-
35393574 protected def prefixString : String = companion.prefixString
35403575 }
35413576
@@ -3766,9 +3801,6 @@ object Types {
37663801 assert(resType.isInstanceOf [TermType ], this )
37673802 assert(paramNames.nonEmpty)
37683803
3769- protected [dotc] def computeSignature (using Context ): Signature =
3770- resultSignature.prependTypeParams(paramNames.length)
3771-
37723804 override def isContextualMethod = resType.isContextualMethod
37733805 override def isImplicitMethod = resType.isImplicitMethod
37743806
0 commit comments