Skip to content

Commit d726234

Browse files
authored
Merge pull request #378 from lightbend/ignoreWhenFirstConstructorParam..
Ignore when first constructor parameter is dropped from Signature
2 parents fc2b616 + 6eefdc7 commit d726234

File tree

4 files changed

+53
-137
lines changed

4 files changed

+53
-137
lines changed

core/src/main/scala/com/typesafe/tools/mima/lib/analyze/method/MethodChecker.scala

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.typesafe.tools.mima.lib.analyze.Checker
55

66
private[analyze] abstract class BaseMethodChecker extends Checker[MethodInfo, ClassInfo] {
77
import MethodRules._
8+
import BaseMethodChecker._
89

910
protected val rules = Seq(AccessModifier, FinalModifier, AbstractModifier, JavaStatic)
1011

@@ -13,7 +14,7 @@ private[analyze] abstract class BaseMethodChecker extends Checker[MethodInfo, Cl
1314
if (meths.isEmpty)
1415
Some(DirectMissingMethodProblem(method))
1516
else {
16-
meths.find(m => m.descriptor == method.descriptor && methSigCheck(method, m)) match {
17+
meths.find(newMethod => hasMatchingDescriptorAndSignature(method, newMethod)) match {
1718
case Some(found) => checkRules(rules)(method, found)
1819
case None =>
1920
val filtered = meths.filter(method.matchesType(_))
@@ -34,15 +35,24 @@ private[analyze] abstract class BaseMethodChecker extends Checker[MethodInfo, Cl
3435
}
3536
}
3637

37-
private def methSigCheck(oldmeth: MethodInfo, newMeth: MethodInfo): Boolean = {
38-
oldmeth.signature == newMeth.signature || (
39-
newMeth.bytecodeName == MemberInfo.ConstructorName && newMeth.signature.isEmpty
40-
)
41-
}
42-
4338
private def uniques(methods: List[MethodInfo]): List[MethodInfo] =
4439
methods.groupBy(_.parametersDesc).values.map(_.head).toList
4540
}
41+
private[analyze] object BaseMethodChecker {
42+
def hasMatchingDescriptorAndSignature(oldMethod: MethodInfo, newMethod: MethodInfo): Boolean =
43+
oldMethod.descriptor == newMethod.descriptor && hasMatchingSignature(oldMethod.signature, newMethod.signature, newMethod.bytecodeName)
44+
45+
// Assumes it is already checked that the descriptors match
46+
def hasMatchingSignature(oldSignature: String, newSignature: String, bytecodeName: String): Boolean =
47+
oldSignature == newSignature ||
48+
// Special case for https://github.com/scala/scala/pull/7975:
49+
(bytecodeName == MemberInfo.ConstructorName &&
50+
(newSignature.isEmpty ||
51+
// The dropped character is the leading '('
52+
oldSignature.endsWith(newSignature.tail)
53+
)
54+
)
55+
}
4656

4757
private[analyze] class ClassMethodChecker extends BaseMethodChecker {
4858
def check(method: MethodInfo, inclazz: ClassInfo): Option[Problem] = {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.typesafe.tools.mima.lib.analyze.method
2+
3+
import com.typesafe.tools.mima.core.MemberInfo
4+
5+
import org.scalatest.Matchers
6+
import org.scalatest.WordSpec
7+
8+
final class MethodCheckerSpec extends WordSpec with Matchers {
9+
"The method checker" should {
10+
val `signatureOn2.12.8` =
11+
"(Lakka/http/impl/engine/server/GracefulTerminatorStage;Lscala/concurrent/Promise<Lscala/Function1<Lscala/concurrent/duration/FiniteDuration;Lscala/concurrent/Future<Lakka/http/scaladsl/Http$HttpTerminated;>;>;>;)V"
12+
val `signatureOn2.12.9` =
13+
"(Lscala/concurrent/Promise<Lscala/Function1<Lscala/concurrent/duration/FiniteDuration;Lscala/concurrent/Future<Lakka/http/scaladsl/Http$HttpTerminated;>;>;>;)V"
14+
15+
"allow dropping the first parameter of the Signature attribute of a constructor" in {
16+
// Assuming the descriptor is the same, dropping the first
17+
// parameter of the Signature attribute can only be explained by
18+
// going from a Scala version that does not have the fix in
19+
// https://github.com/scala/scala/pull/7975 (2.12.8, 2.13.0) to
20+
// one that does
21+
BaseMethodChecker.hasMatchingSignature(
22+
`signatureOn2.12.8`,
23+
`signatureOn2.12.9`,
24+
MemberInfo.ConstructorName
25+
) should be(true)
26+
}
27+
28+
"reject adding the first parameter of the Signature attribute of a constructor back" in {
29+
BaseMethodChecker.hasMatchingSignature(
30+
`signatureOn2.12.9`,
31+
`signatureOn2.12.8`,
32+
MemberInfo.ConstructorName
33+
) should be(false)
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)