@@ -1999,7 +1999,7 @@ object Types {
1999
1999
2000
2000
// --- NamedTypes ------------------------------------------------------------------
2001
2001
2002
- abstract class NamedType extends CachedProxyType with ValueType with SignatureCachingType { self =>
2002
+ abstract class NamedType extends CachedProxyType with ValueType { self =>
2003
2003
2004
2004
type ThisType >: this .type <: NamedType
2005
2005
type ThisName <: Name
@@ -2015,11 +2015,13 @@ object Types {
2015
2015
private var lastSymbol : Symbol = null
2016
2016
private var checkedPeriod : Period = Nowhere
2017
2017
private var myStableHash : Byte = 0
2018
+ private var mySignature : Signature = _
2019
+ private var mySignatureRunId : Int = NoRunId
2018
2020
2019
2021
// 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
2023
2025
2024
2026
def isType : Boolean = isInstanceOf [TypeRef ]
2025
2027
def isTerm : Boolean = isInstanceOf [TermRef ]
@@ -2037,15 +2039,22 @@ object Types {
2037
2039
case sym : Symbol => sym.originDenotation.name
2038
2040
}
2039
2041
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
2049
2058
2050
2059
/** The signature computed from the current denotation with `sigFromDenot` if it is
2051
2060
* known without forcing.
@@ -3219,39 +3228,11 @@ object Types {
3219
3228
// is that most poly types are cyclic via poly params,
3220
3229
// and therefore two different poly types would never be equal.
3221
3230
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
3251
3232
3252
3233
/** A by-name parameter type of the form `=> T`, or the type of a method with no parameter list. */
3253
3234
abstract case class ExprType (resType : Type )
3254
- extends CachedProxyType with TermType with MethodicType {
3235
+ extends CachedProxyType with MethodicType {
3255
3236
override def resultType (using Context ): Type = resType
3256
3237
override def underlying (using Context ): Type = resType
3257
3238
@@ -3371,7 +3352,58 @@ object Types {
3371
3352
final override def equals (that : Any ): Boolean = equals(that, null )
3372
3353
}
3373
3354
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.
3368
+ * Otherwise, the signature of this method assuming it is part
3369
+ * of a Java class. This distinction is needed because
3370
+ * the same method type might be part of both a Java and Scala
3371
+ * class and each language has different type erasure rules.
3372
+ */
3373
+ def signature (isJava : Boolean )(using Context ): Signature =
3374
+ def computeSignature (isJava : Boolean )(using Context ): Signature =
3375
+ val resultSignature = resultType match
3376
+ case tp : MethodOrPoly => tp.signature(isJava)
3377
+ case tp : ExprType => tp.signature
3378
+ case tp =>
3379
+ if tp.isRef(defn.UnitClass ) then Signature (Nil , defn.UnitClass .fullName.asTypeName)
3380
+ else Signature (tp, isJava = false )
3381
+ this match
3382
+ case tp : MethodType =>
3383
+ val params = if (isErasedMethod) Nil else tp.paramInfos
3384
+ resultSignature.prependTermParams(params, isJava)
3385
+ case tp : PolyType =>
3386
+ resultSignature.prependTypeParams(tp.paramNames.length)
3387
+
3388
+ if isJava then
3389
+ if ctx.runId != myJavaSignatureRunId then
3390
+ myJavaSignature = computeSignature(isJava)
3391
+ if ! myJavaSignature.isUnderDefined then myJavaSignatureRunId = ctx.runId
3392
+ myJavaSignature
3393
+ else
3394
+ if ctx.runId != mySignatureRunId then
3395
+ mySignature = computeSignature(isJava)
3396
+ if ! mySignature.isUnderDefined then mySignatureRunId = ctx.runId
3397
+ mySignature
3398
+ end signature
3399
+
3400
+ final override def signature (using Context ): Signature =
3401
+ def isJava (tp : Type ): Boolean = tp match
3402
+ case tp : PolyType => isJava(tp.resultType)
3403
+ case tp : MethodType => tp.isJavaMethod
3404
+ case _ => false
3405
+ signature(isJava = isJava(this ))
3406
+
3375
3407
final override def hashCode : Int = System .identityHashCode(this )
3376
3408
3377
3409
final override def equals (that : Any ): Boolean = equals(that, null )
@@ -3531,11 +3563,6 @@ object Types {
3531
3563
companion.eq(ContextualMethodType ) ||
3532
3564
companion.eq(ErasedContextualMethodType )
3533
3565
3534
- protected [dotc] def computeSignature (using Context ): Signature = {
3535
- val params = if (isErasedMethod) Nil else paramInfos
3536
- resultSignature.prependTermParams(params, isJavaMethod)
3537
- }
3538
-
3539
3566
protected def prefixString : String = companion.prefixString
3540
3567
}
3541
3568
@@ -3766,9 +3793,6 @@ object Types {
3766
3793
assert(resType.isInstanceOf [TermType ], this )
3767
3794
assert(paramNames.nonEmpty)
3768
3795
3769
- protected [dotc] def computeSignature (using Context ): Signature =
3770
- resultSignature.prependTypeParams(paramNames.length)
3771
-
3772
3796
override def isContextualMethod = resType.isContextualMethod
3773
3797
override def isImplicitMethod = resType.isImplicitMethod
3774
3798
0 commit comments