@@ -582,11 +582,30 @@ object Denotations {
582
582
*/
583
583
def prefix : Type = NoPrefix
584
584
585
+ /** Either the Scala or Java signature of the info, depending on where the
586
+ * symbol is defined.
587
+ *
588
+ * Invariants:
589
+ * - Before erasure, the signature of a denotation is always equal to the
590
+ * signature of its corresponding initial denotation.
591
+ * - Two distinct overloads will have SymDenotations with distinct
592
+ * signatures (the SELECTin tag in Tasty relies on this to refer to an
593
+ * overload unambiguously). Note that this only applies to
594
+ * SymDenotations, in general we cannot assume that distinct
595
+ * SingleDenotations will have distinct signatures (cf #9050).
596
+ */
585
597
final def signature (using Context ): Signature =
586
- if (isType) Signature .NotAMethod // don't force info if this is a type SymDenotation
598
+ signature(isJava = ! isType && symbol.is(JavaDefined ))
599
+
600
+ /** Overload of `signature` which lets the caller pick between the Java and
601
+ * Scala signature of the info. Useful to match denotations defined in
602
+ * different classes (see `matchesLoosely`).
603
+ */
604
+ def signature (isJava : Boolean )(using Context ): Signature =
605
+ if (isType) Signature .NotAMethod // don't force info if this is a type denotation
587
606
else info match {
588
- case info : MethodicType =>
589
- try info.signature
607
+ case info : MethodOrPoly =>
608
+ try info.signature(isJava)
590
609
catch { // !!! DEBUG
591
610
case scala.util.control.NonFatal (ex) =>
592
611
report.echo(s " cannot take signature of $info" )
@@ -992,34 +1011,45 @@ object Denotations {
992
1011
symbol.hasTargetName(other.symbol.targetName)
993
1012
&& matchesLoosely(other)
994
1013
995
- /** matches without a target name check */
1014
+ /** `matches` without a target name check.
1015
+ *
1016
+ * We consider a Scala method and a Java method to match if they have
1017
+ * matching Scala signatures. This allows us to override some Java
1018
+ * definitions even if they have a different erasure (see i8615b,
1019
+ * i9109b), Erasure takes care of adding any necessary bridge to make
1020
+ * this work at runtime.
1021
+ */
996
1022
def matchesLoosely (other : SingleDenotation )(using Context ): Boolean =
997
- val d = signature.matchDegree(other.signature)
998
- d match
999
- case FullMatch =>
1000
- true
1001
- case MethodNotAMethodMatch =>
1002
- ! ctx.erasedTypes && {
1003
- val isJava = symbol.is(JavaDefined )
1004
- val otherIsJava = other.symbol.is(JavaDefined )
1005
- // A Scala zero-parameter method and a Scala non-method always match.
1006
- if ! isJava && ! otherIsJava then
1007
- true
1008
- // Java allows defining both a field and a zero-parameter method with the same name,
1009
- // so they must not match.
1010
- else if isJava && otherIsJava then
1011
- false
1012
- // A Java field never matches a Scala method.
1013
- else if isJava then
1014
- symbol.is(Method )
1015
- else // otherIsJava
1016
- other.symbol.is(Method )
1017
- }
1018
- case ParamMatch =>
1019
- // The signatures do not tell us enough to be sure about matching
1020
- ! ctx.erasedTypes && info.matches(other.info)
1021
- case noMatch =>
1022
- false
1023
+ if isType then true
1024
+ else
1025
+ val isJava = symbol.is(JavaDefined )
1026
+ val otherIsJava = other.symbol.is(JavaDefined )
1027
+ val useJavaSig = isJava && otherIsJava
1028
+ val sig = signature(isJava = useJavaSig)
1029
+ val otherSig = other.signature(isJava = useJavaSig)
1030
+ sig.matchDegree(otherSig) match
1031
+ case FullMatch =>
1032
+ true
1033
+ case MethodNotAMethodMatch =>
1034
+ ! ctx.erasedTypes && {
1035
+ // A Scala zero-parameter method and a Scala non-method always match.
1036
+ if ! isJava && ! otherIsJava then
1037
+ true
1038
+ // Java allows defining both a field and a zero-parameter method with the same name,
1039
+ // so they must not match.
1040
+ else if isJava && otherIsJava then
1041
+ false
1042
+ // A Java field never matches a Scala method.
1043
+ else if isJava then
1044
+ symbol.is(Method )
1045
+ else // otherIsJava
1046
+ other.symbol.is(Method )
1047
+ }
1048
+ case ParamMatch =>
1049
+ // The signatures do not tell us enough to be sure about matching
1050
+ ! ctx.erasedTypes && info.matches(other.info)
1051
+ case noMatch =>
1052
+ false
1023
1053
1024
1054
def mapInherited (ownDenots : PreDenotation , prevDenots : PreDenotation , pre : Type )(using Context ): SingleDenotation =
1025
1055
if hasUniqueSym && prevDenots.containsSym(symbol) then NoDenotation
0 commit comments