Skip to content

Commit

Permalink
Removed overloads are missing, not incompatible
Browse files Browse the repository at this point in the history
Previously the method checker didn't take overloading into account,
which means that the loss of a method overloading (which includes the
loss of a static forwarder methods, when upgrading from Scala 2.12.7 to
2.12.8+) was reported as an "incompatible method type" problem or a
"incompatible result type" problem.

With this change these are now correctly reported as "direct missing
method" problems.
  • Loading branch information
dwijnand committed Jul 29, 2019
1 parent ebebf46 commit b4ceddc
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,28 @@ private[analyze] abstract class BaseMethodChecker extends Checker[MethodInfo, Cl

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

protected def check(method: MethodInfo, in: Iterator[MethodInfo]): Option[Problem] = {
val meths = in.filter(method.paramsCount == _.paramsCount).toList
protected def check(method: MethodInfo, newclazz: ClassInfo, methsLookup: ClassInfo => Iterator[MethodInfo]): Option[Problem] = {
val meths = methsLookup(newclazz).filter(method.paramsCount == _.paramsCount).toList // newmeths
if (meths.isEmpty)
Some(DirectMissingMethodProblem(method))
else {
meths.find(m => m.descriptor == method.descriptor && m.signature == method.signature) match {
case Some(found) => checkRules(rules)(method, found)
case None => meths.filter(method.matchesType(_)) match {
case Nil => Some(IncompatibleMethTypeProblem(method, uniques(meths)))
case filtered @ first :: _ => filtered.find(_.tpe.resultType == method.tpe.resultType) match {
case None => Some(IncompatibleResultTypeProblem(method, first))
case None =>
val filtered = meths.filter(method.matchesType(_))
filtered.find(_.tpe.resultType == method.tpe.resultType) match {
case Some(found) => Some(IncompatibleSignatureProblem(method, found))
case None =>
val oldmethsDescriptors = methsLookup(method.owner).map(_.descriptor).toSet
if (meths.forall(newmeth => oldmethsDescriptors.contains(newmeth.descriptor)))
Some(DirectMissingMethodProblem(method))
else {
filtered match {
case Nil => Some(IncompatibleMethTypeProblem(method, uniques(meths)))
case first :: _ => Some(IncompatibleResultTypeProblem(method, first))
}
}
}
}
}
}
}
Expand All @@ -35,9 +43,9 @@ private[analyze] class ClassMethodChecker extends BaseMethodChecker {
if (method.nonAccessible)
None
else if (method.isDeferred)
super.check(method, inclazz.lookupMethods(method.bytecodeName))
super.check(method, inclazz, _.lookupMethods(method.bytecodeName))
else
super.check(method, inclazz.lookupClassMethods(method.bytecodeName))
super.check(method, inclazz, _.lookupClassMethods(method.bytecodeName))
}
}

Expand All @@ -48,7 +56,7 @@ private[analyze] class TraitMethodChecker extends BaseMethodChecker {
else if (method.owner.hasStaticImpl(method))
checkStaticImplMethod(method, inclazz)
else
super.check(method, inclazz.lookupMethods(method.bytecodeName))
super.check(method, inclazz, _.lookupMethods(method.bytecodeName))
}

private def checkStaticImplMethod(method: MethodInfo, inclazz: ClassInfo) = {
Expand All @@ -66,7 +74,7 @@ private[analyze] class TraitMethodChecker extends BaseMethodChecker {
// otherwise we check the all concrete trait methods and report
// either that the method is missing or that no method with the
// same signature exists. Either way, we expect that a problem is reported!
val prob = super.check(method, inclazz.lookupConcreteTraitMethods(method.bytecodeName))
val prob = super.check(method, inclazz, _.lookupConcreteTraitMethods(method.bytecodeName))
assert(prob.isDefined)
prob
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
method foo(java.lang.Object)java.lang.String in class A's type is different in new version, where it is (java.lang.String)java.lang.String instead of (java.lang.Object)java.lang.String
method foo(java.lang.Object)java.lang.String in class A does not have a correspondent in new version

0 comments on commit b4ceddc

Please sign in to comment.