From f61154947b0309c45099500b814d295130ec072b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 18 Jan 2020 15:30:38 +0000 Subject: [PATCH 1/2] MethodChecker: Move out an isClass guard --- .../lib/analyze/method/MethodChecker.scala | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/core/src/main/scala/com/typesafe/tools/mima/lib/analyze/method/MethodChecker.scala b/core/src/main/scala/com/typesafe/tools/mima/lib/analyze/method/MethodChecker.scala index 8073b9bb..b1bb7aef 100644 --- a/core/src/main/scala/com/typesafe/tools/mima/lib/analyze/method/MethodChecker.scala +++ b/core/src/main/scala/com/typesafe/tools/mima/lib/analyze/method/MethodChecker.scala @@ -13,7 +13,7 @@ private[analyze] object MethodChecker { /** Analyze incompatibilities that may derive from new methods in `newclazz`. */ private def checkNew(oldclazz: ClassInfo, newclazz: ClassInfo): List[Problem] = { - checkEmulatedConcreteMethodsProblems(oldclazz, newclazz) ::: + (if (newclazz.isClass) Nil else checkEmulatedConcreteMethodsProblems(oldclazz, newclazz)) ::: checkDeferredMethodsProblems(oldclazz, newclazz) ::: checkInheritedNewAbstractMethodProblems(oldclazz, newclazz) } @@ -108,30 +108,28 @@ private[analyze] object MethodChecker { methods.groupBy(_.parametersDesc).values.collect { case method :: _ => method }.toList private def checkEmulatedConcreteMethodsProblems(oldclazz: ClassInfo, newclazz: ClassInfo): List[Problem] = { - if (oldclazz.isClass && newclazz.isClass) Nil else { - for { - newmeth <- newclazz.emulatedConcreteMethods.iterator - if !oldclazz.hasStaticImpl(newmeth) - problem <- { - if (oldclazz.lookupMethods(newmeth).exists(_.descriptor == newmeth.descriptor)) { - // a static implementation for the same method existed already, therefore - // class that mixed-in the trait already have a forwarder to the implementation - // class. Mind that, despite no binary incompatibility arises, program's - // semantic may be severely affected. - None - } else { - // this means that the method is brand new and therefore the implementation - // has to be injected - Some(ReversedMissingMethodProblem(newmeth)) - } + for { + newmeth <- newclazz.emulatedConcreteMethods.iterator + if !oldclazz.hasStaticImpl(newmeth) + problem <- { + if (oldclazz.lookupMethods(newmeth).exists(_.descriptor == newmeth.descriptor)) { + // a static implementation for the same method existed already, therefore + // classes that mixed-in the trait already have a forwarder to the implementation + // class. Mind that, despite no binary incompatibility arises, program's + // semantic may be severely affected. + None + } else { + // this means that the method is brand new + // and therefore the implementation has to be injected + Some(ReversedMissingMethodProblem(newmeth)) } - } yield problem - }.toList - } + } + } yield problem + }.toList private def checkDeferredMethodsProblems(oldclazz: ClassInfo, newclazz: ClassInfo): List[Problem] = { for { - newmeth <- newclazz.deferredMethods + newmeth <- newclazz.deferredMethods.iterator problem <- oldclazz.lookupMethods(newmeth).find(_.descriptor == newmeth.descriptor) match { case None => Some(ReversedMissingMethodProblem(newmeth)) case Some(oldmeth) => @@ -140,7 +138,7 @@ private[analyze] object MethodChecker { else None } } yield problem - } + }.toList private def checkInheritedNewAbstractMethodProblems(oldclazz: ClassInfo, newclazz: ClassInfo): List[Problem] = { def allInheritedTypes(clazz: ClassInfo) = clazz.superClasses ++ clazz.allInterfaces From fb23c17247d963d81da49f8d8d2a8cd4675cecc7 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 3 Jan 2020 21:27:07 +0000 Subject: [PATCH 2/2] TestsPlugin: Introduce App/App2/testRunApp --- .../tools/mima/lib/CollectProblemsTest.scala | 12 +-- .../app/App.scala | 5 ++ .../v1/A.scala | 6 +- .../v2/A.scala | 4 + .../app/App.scala | 10 +++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../v1/A.scala | 3 + .../v2/A.scala | 4 + .../app/App.scala | 6 ++ .../problems.txt | 4 +- .../v1/A.scala | 7 +- .../v2/A.scala | 7 +- .../app/App.scala | 7 ++ .../v1/A.scala | 5 ++ .../v2/A.scala | 6 ++ .../app/App.scala | 3 + .../app/App.scala | 3 + .../app/App.scala | 3 + .../app/App.scala | 3 + .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../class-added-local-class-ok/app/App.scala | 5 ++ .../class-added-local-method-ok/app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../class-becomes-final-nok/app/App.scala | 5 ++ .../class-becomes-object-nok/app/App.scala | 6 ++ .../class-becomes-trait-nok/app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 7 ++ .../app/App.scala | 6 ++ .../app/App.scala | 6 ++ .../app/App.scala | 6 ++ .../app/App.scala | 7 ++ .../app/App.scala | 7 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../problems.txt | 6 +- .../class-constructor-generics-nok/v1/A.scala | 10 +-- .../class-constructor-generics-nok/v2/A.scala | 5 +- .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 7 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 8 ++ .../class-method-generics-nok/app/App.scala | 19 +++++ .../test/class-method-generics-nok/v1/A.scala | 4 +- .../test/class-method-generics-nok/v2/A.scala | 4 +- .../app/App.scala | 11 +++ .../class-method-pushed-up-ok/app/App.scala | 7 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../src/test/class-missing-nok/app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../class-removed-superclass-nok/v1/A.scala | 4 +- .../class-removed-superclass-nok/v2/A.scala | 4 +- .../app/App.scala | 5 ++ .../class-type-becomes-final-ok/app/App.scala | 5 ++ .../class-val-becomes-final-nok/app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../class-var-becomes-final-nok/app/App.java | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 8 ++ .../app/App.scala | 5 ++ .../app/App.scala | 9 ++ .../lazy-field-becomes-eager-ok/app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../object-becomes-class-nok/app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 7 ++ .../app/App.scala | 5 ++ .../app/App.scala | 10 +++ .../v1/A.scala | 10 +-- .../v2/A.scala | 10 +-- .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.java | 5 ++ .../v1/A.scala | 4 +- .../v2/A.scala | 4 +- .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../v1/A.scala | 3 + .../v2/A.scala | 3 + .../app/App.scala | 7 ++ .../app/App.scala | 18 ++++ .../testAppRun-2.11.pending | 0 .../app/App.scala | 6 ++ .../testAppRun.pending | 0 .../app/App.scala | 18 ++++ .../app/App.scala | 5 ++ .../v1/A.scala | 6 +- .../v2/A.scala | 4 + .../app/App.scala | 5 ++ .../testAppRun-2.11.pending | 0 .../app/App.scala | 5 ++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../v1/A.scala | 6 +- .../v2/A.scala | 6 +- .../app/App.scala | 9 ++ .../testAppRun-2.11.pending | 0 .../app/App.scala | 5 ++ .../app/App.scala | 10 +++ .../v1/A.scala | 7 ++ .../v2/A.scala | 7 ++ .../app/App.scala | 8 ++ .../testAppRun-2.11.pending | 0 .../app/App.scala | 5 ++ .../testAppRun-2.11.pending | 0 .../trait-moving-methods-nok/app/App.scala | 5 ++ .../trait-moving-methods2-nok/app/App.scala | 6 ++ .../app/App.scala | 5 ++ .../v1/A.scala | 6 +- .../v2/A.scala | 6 +- .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 6 ++ .../app/App.scala | 16 ++++ .../app/App.scala | 6 ++ .../app/App.scala | 10 +++ .../app/App.scala | 5 ++ .../app/App.scala | 6 ++ .../app/App.scala | 10 +++ .../testAppRun-2.11.pending | 0 project/TestsPlugin.scala | 82 ++++++++++++++++--- 160 files changed, 932 insertions(+), 67 deletions(-) create mode 100644 functional-tests/src/test/abstract-class-added-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/abstract-class-extending-new-abstract-class-with-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-ok/app/App.scala create mode 100644 functional-tests/src/test/abstract-class-extending-new-trait-with-concrete-method-ok/app/App.scala create mode 100644 functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/app/App.scala create mode 100644 functional-tests/src/test/added-abstract-class-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/added-new-trait-with-abstract-methods-ok/app/App.scala create mode 100644 functional-tests/src/test/added-new-trait-with-concrete-methods-ok/app/App.scala create mode 100644 functional-tests/src/test/added-trait-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/case-class-abstract-becomes-concrete-ok/app/App.scala create mode 100644 functional-tests/src/test/case-class-becomes-final-nok/app/App.scala create mode 100644 functional-tests/src/test/case-class-concrete-becomes-abstract-nok/app/App.scala create mode 100644 functional-tests/src/test/case-class-constructor-becomes-private-ok/app/App.scala create mode 100644 functional-tests/src/test/case-class-was-final-becomes-open-ok/app/App.scala create mode 100644 functional-tests/src/test/class-abstract-becomes-concrete-ok/app/App.scala create mode 100644 functional-tests/src/test/class-added-abstract-method-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/class-added-class-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/class-added-local-class-ok/app/App.scala create mode 100644 functional-tests/src/test/class-added-local-method-ok/app/App.scala create mode 100644 functional-tests/src/test/class-added-method-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/class-added-same-class-in-different-package-is-ok/app/App.scala create mode 100644 functional-tests/src/test/class-added-val-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/class-added-var-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/class-becomes-final-nok/app/App.scala create mode 100644 functional-tests/src/test/class-becomes-object-nok/app/App.scala create mode 100644 functional-tests/src/test/class-becomes-trait-nok/app/App.scala create mode 100644 functional-tests/src/test/class-changed-local-class-ok/app/App.scala create mode 100644 functional-tests/src/test/class-changed-method-with-val-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/class-changed-method-with-var-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/class-changed-val-type-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/class-changed-val-with-method-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/class-changed-var-type-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/class-changed-var-with-method-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/class-concrete-becomes-abstract-nok/app/App.scala create mode 100644 functional-tests/src/test/class-constructor-generics-nok/app/App.scala create mode 100644 functional-tests/src/test/class-constructor-inherited-nok/app/App.scala create mode 100644 functional-tests/src/test/class-deleted-deprecated-method-nok/app/App.scala create mode 100644 functional-tests/src/test/class-inherits-new-trait-with-shadowed-abstract-method-ok/app/App.scala create mode 100644 functional-tests/src/test/class-method-abstract-override-of-concrete-superclass-method-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-abstract-override-of-concrete-supertrait-method-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-becomes-final-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-changed-parameter-type-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-changed-parameters-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-changed-parameters2-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-concrete-override-of-concrete-supertrait-method-ok/app/App.scala create mode 100644 functional-tests/src/test/class-method-generics-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-overload-with-default-parameters-nok/app/App.scala create mode 100644 functional-tests/src/test/class-method-pushed-up-ok/app/App.scala create mode 100644 functional-tests/src/test/class-missing-method-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/class-missing-method-in-root-package-nok/app/App.scala create mode 100644 functional-tests/src/test/class-missing-nok/app/App.scala create mode 100644 functional-tests/src/test/class-narrowing-method-type-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/class-public-method-becomes-private-nok/app/App.scala create mode 100644 functional-tests/src/test/class-push-up-method-maintaining-explicit-bridge-ok/app/App.scala create mode 100644 functional-tests/src/test/class-removed-constructor-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/class-removed-local-class-ok/app/App.scala create mode 100644 functional-tests/src/test/class-removed-local-method-ok/app/App.scala create mode 100644 functional-tests/src/test/class-removed-method-overload-nok/app/App.scala create mode 100644 functional-tests/src/test/class-removed-superclass-nok/app/App.scala create mode 100644 functional-tests/src/test/class-removing-inner-object-nok/app/App.scala create mode 100644 functional-tests/src/test/class-type-becomes-final-ok/app/App.scala create mode 100644 functional-tests/src/test/class-val-becomes-final-nok/app/App.scala create mode 100644 functional-tests/src/test/class-val-becomes-lazy-val-ok/app/App.scala create mode 100644 functional-tests/src/test/class-var-becomes-final-nok/app/App.java create mode 100644 functional-tests/src/test/class-was-final-becomes-not-final-ok/app/App.scala create mode 100644 functional-tests/src/test/class-widening-method-type-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/effectively-final-becomes-final-is-ok/app/App.scala create mode 100644 functional-tests/src/test/final-class-becomes-object-nok/app/App.scala create mode 100644 functional-tests/src/test/ignore-changed-and-added-anonymous-lambdas-ok/app/App.scala create mode 100644 functional-tests/src/test/ignore-changed-and-removed-anonymous-lambdas-ok/app/App.scala create mode 100644 functional-tests/src/test/inner-class-loses-outer-pointer-nok/app/App.scala create mode 100644 functional-tests/src/test/interface-method-becomes-default-method-ok/app/App.scala create mode 100644 functional-tests/src/test/java-class-missing-static-method-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/java-class-static-to-virtual-method-nok/app/App.scala create mode 100644 functional-tests/src/test/java-class-static-varargs-to-scala-object-annotated-varargs-ok/app/App.scala create mode 100644 functional-tests/src/test/java-class-virtual-to-static-method-nok/app/App.scala create mode 100644 functional-tests/src/test/lazy-field-becomes-eager-ok/app/App.scala create mode 100644 functional-tests/src/test/missing-synthetic-classes-are-ignored-ok/app/App.scala create mode 100644 functional-tests/src/test/moving-method-upward-from-trait-to-class-nok/app/App.scala create mode 100644 functional-tests/src/test/object-becomes-class-nok/app/App.scala create mode 100644 functional-tests/src/test/object-becomes-class-with-companion-ok/app/App.scala create mode 100644 functional-tests/src/test/object-removing-inner-object-nok/app/App.scala create mode 100644 functional-tests/src/test/package-missing-in-new-version-is-ok/app/App.scala create mode 100644 functional-tests/src/test/package-nested-with-breaking-change-is-nok/app/App.scala create mode 100644 functional-tests/src/test/package-with-classes-missing-in-new-version-is-nok/app/App.scala create mode 100644 functional-tests/src/test/package-with-classes-splitted-into-two-files-in-new-version-is-ok/app/App.scala create mode 100644 functional-tests/src/test/public-method-becomes-package-private-nok/app/App.java create mode 100644 functional-tests/src/test/public-method-becomes-package-private-ok/app/App.scala create mode 100644 functional-tests/src/test/removing-method-from-class-with-special-characters-nok/app/App.scala create mode 100644 functional-tests/src/test/removing-method-with-special-characters-from-class-nok/app/App.scala create mode 100644 functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-abstract-method-becomes-concrete-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-abstract-method-becomes-concrete2-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-abstract-method-becomes-concrete2-ok/testAppRun-2.11.pending create mode 100644 functional-tests/src/test/trait-abstract-val-becomes-concrete-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-abstract-val-becomes-concrete-nok/testAppRun.pending create mode 100644 functional-tests/src/test/trait-abstract-var-becomes-concrete-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-added-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-added-method-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-added-method-in-new-version-ok/testAppRun-2.11.pending create mode 100644 functional-tests/src/test/trait-added-val-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-added-var-in-new-version-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-deleting-concrete-methods-is-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-extending-new-trait-with-concrete-method-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-extending-new-trait-with-concrete-method-ok/testAppRun-2.11.pending create mode 100644 functional-tests/src/test/trait-inheriting-from-class-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-inherits-new-trait-with-concrete-method-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-inherits-new-trait-with-concrete-method-ok/testAppRun-2.11.pending create mode 100644 functional-tests/src/test/trait-method-overloading-is-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-method-overloading-is-ok/testAppRun-2.11.pending create mode 100644 functional-tests/src/test/trait-moving-methods-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-moving-methods2-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-pushing-up-concrete-methods-is-nok/app/App.scala create mode 100644 functional-tests/src/test/trait-redeclaring-abstract-methods-in-subclass-is-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-removing-abstract-method-declared-in-superclass-is-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-removing-class-type-from-inheritance-relationship-is-ok/app/App.scala create mode 100644 functional-tests/src/test/trait-use-type-alias-in-new-version-ok/app/App.scala create mode 100644 functional-tests/src/test/tuple-parametric-type-change-nok/app/App.scala create mode 100644 functional-tests/src/test/type-parameters-change-breaks-method-signature-nok/app/App.scala create mode 100644 functional-tests/src/test/value-class-added-concrete-method-ok/app/App.scala create mode 100644 functional-tests/src/test/value-class-generic-replacement-nok/app/App.scala create mode 100644 functional-tests/src/test/value-class-generic-replacement-nok/testAppRun-2.11.pending diff --git a/functional-tests/src/main/scala/com/typesafe/tools/mima/lib/CollectProblemsTest.scala b/functional-tests/src/main/scala/com/typesafe/tools/mima/lib/CollectProblemsTest.scala index 34d425b7..52ad52ef 100644 --- a/functional-tests/src/main/scala/com/typesafe/tools/mima/lib/CollectProblemsTest.scala +++ b/functional-tests/src/main/scala/com/typesafe/tools/mima/lib/CollectProblemsTest.scala @@ -11,7 +11,7 @@ import scala.tools.nsc.classpath.AggregateClassPath object CollectProblemsTest { // Called via reflection from TestsPlugin - def runTest(testClasspath: Array[File], testName: String, oldJarOrDir: File, newJarOrDir: File, baseDir: File, scalaVersion: String): Unit = { + def runTest(testClasspath: Array[File], testName: String, oldJarOrDir: File, newJarOrDir: File, baseDir: File, oracleFile: File): Unit = { val testClassPath = aggregateClassPath(testClasspath) val classpath = AggregateClassPath.createAggregate(testClassPath, Config.baseClassPath) val mima = new MiMaLib(classpath) @@ -25,16 +25,6 @@ object CollectProblemsTest { val problems = mima.collectProblems(oldJarOrDir, newJarOrDir).filter(problemFilter) // load oracle - val oracleFile = { - val p = new File(baseDir, "problems.txt") - val p211 = new File(baseDir, "problems-2.11.txt") - val p212 = new File(baseDir, "problems-2.12.txt") - scalaVersion.take(4) match { - case "2.11" => if (p211.exists()) p211 else if (p212.exists()) p212 else p - case "2.12" => if (p212.exists()) p212 else p - case _ => p - } - } val source = Source.fromFile(oracleFile) val expectedProblems = try source.getLines.filter(!_.startsWith("#")).toList finally source.close() diff --git a/functional-tests/src/test/abstract-class-added-abstract-method-nok/app/App.scala b/functional-tests/src/test/abstract-class-added-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..f51eccda --- /dev/null +++ b/functional-tests/src/test/abstract-class-added-abstract-method-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.use(new A {})) + } +} diff --git a/functional-tests/src/test/abstract-class-added-abstract-method-nok/v1/A.scala b/functional-tests/src/test/abstract-class-added-abstract-method-nok/v1/A.scala index 4888a762..60d25cc9 100644 --- a/functional-tests/src/test/abstract-class-added-abstract-method-nok/v1/A.scala +++ b/functional-tests/src/test/abstract-class-added-abstract-method-nok/v1/A.scala @@ -1 +1,5 @@ -abstract class A \ No newline at end of file +abstract class A + +object Usage { + def use(a: A) = () +} diff --git a/functional-tests/src/test/abstract-class-added-abstract-method-nok/v2/A.scala b/functional-tests/src/test/abstract-class-added-abstract-method-nok/v2/A.scala index 5e068b14..e26cb544 100644 --- a/functional-tests/src/test/abstract-class-added-abstract-method-nok/v2/A.scala +++ b/functional-tests/src/test/abstract-class-added-abstract-method-nok/v2/A.scala @@ -1,3 +1,7 @@ abstract class A { def foo(): Unit } + +object Usage { + def use(a: A) = a.foo() +} diff --git a/functional-tests/src/test/abstract-class-extending-new-abstract-class-with-abstract-method-nok/app/App.scala b/functional-tests/src/test/abstract-class-extending-new-abstract-class-with-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..fdaacfd2 --- /dev/null +++ b/functional-tests/src/test/abstract-class-extending-new-abstract-class-with-abstract-method-nok/app/App.scala @@ -0,0 +1,10 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo(new A {})) + println(new C) + println(new D) + + println(new E { def bar(): E = new E { def bar() = this } }.bar()) + println(new F) + } +} diff --git a/functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-nok/app/App.scala b/functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..f8601229 --- /dev/null +++ b/functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo(new A {})) + } +} diff --git a/functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-ok/app/App.scala b/functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-ok/app/App.scala new file mode 100644 index 00000000..9b7d946d --- /dev/null +++ b/functional-tests/src/test/abstract-class-extending-new-trait-with-abstract-method-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { def foo = () }.foo) + } +} diff --git a/functional-tests/src/test/abstract-class-extending-new-trait-with-concrete-method-ok/app/App.scala b/functional-tests/src/test/abstract-class-extending-new-trait-with-concrete-method-ok/app/App.scala new file mode 100644 index 00000000..f8601229 --- /dev/null +++ b/functional-tests/src/test/abstract-class-extending-new-trait-with-concrete-method-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo(new A {})) + } +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/app/App.scala b/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..55fd71b2 --- /dev/null +++ b/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.use(new A {})) + println(Usage.use(new B {})) + } +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v1/A.scala b/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v1/A.scala index 9e458cb4..215702c7 100644 --- a/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v1/A.scala +++ b/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v1/A.scala @@ -5,3 +5,6 @@ abstract class C extends B { } abstract class D extends C +object Usage { + def use(a: A) = () +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v2/A.scala b/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v2/A.scala index fe54a7f7..b1ad6dd9 100644 --- a/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v2/A.scala +++ b/functional-tests/src/test/abstract-class-inherits-new-abstract-class-with-abstract-method-nok/v2/A.scala @@ -8,3 +8,7 @@ abstract class C extends B { def foo(): Unit } abstract class D extends C + +object Usage { + def use(a: A) = a.foo() +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/app/App.scala b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..b66d75ee --- /dev/null +++ b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.useA(new A {}) + 10) + println(Usage.useB(new B {}) + 11) + } +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/problems.txt b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/problems.txt index 0a215038..569f7cf8 100644 --- a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/problems.txt +++ b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/problems.txt @@ -1,2 +1,2 @@ -abstract method foo()Unit in interface AA is inherited by class B in new version. -abstract method foo()Unit in interface AA is inherited by class A in new version. +abstract method foo()Int in interface AA is inherited by class A in new version. +abstract method foo()Int in interface AA is inherited by class B in new version. diff --git a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v1/A.scala b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v1/A.scala index 4108c526..0255b99a 100644 --- a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v1/A.scala +++ b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v1/A.scala @@ -1,2 +1,7 @@ trait A -abstract class B \ No newline at end of file +abstract class B + +object Usage { + def useA(a: A) = 0 + def useB(b: B) = 1 +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v2/A.scala b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v2/A.scala index 91853c7b..143b6299 100644 --- a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v2/A.scala +++ b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method-nok/v2/A.scala @@ -1,6 +1,11 @@ trait AA { - def foo(): Unit + def foo(): Int } trait A extends AA abstract class B extends A + +object Usage { + def useA(a: A) = a.foo() + 1 + def useB(b: B) = b.foo() + 2 +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/app/App.scala b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/app/App.scala new file mode 100644 index 00000000..c0f2e67b --- /dev/null +++ b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.useA(new A {}) + 10) + println(Usage.useB(new B {}) + 11) + println(Usage.useC(new C {}) + 12) + } +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v1/A.scala b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v1/A.scala index c6eed194..49b14512 100644 --- a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v1/A.scala +++ b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v1/A.scala @@ -2,3 +2,8 @@ trait A trait B abstract class C extends A with B +object Usage { + def useA(a: A) = 0 + def useB(b: B) = 0 + def useC(c: C) = 0 +} diff --git a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v2/A.scala b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v2/A.scala index ff858369..1f57e37c 100644 --- a/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v2/A.scala +++ b/functional-tests/src/test/abstract-class-inherits-new-trait-with-abstract-method2-nok/v2/A.scala @@ -4,3 +4,9 @@ trait AA { trait A extends AA trait B extends A abstract class C extends B + +object Usage { + def useA(a: A) = a.foo + 1 + def useB(b: B) = b.foo + 2 + def useC(c: C) = c.foo + 3 +} diff --git a/functional-tests/src/test/added-abstract-class-in-new-version-ok/app/App.scala b/functional-tests/src/test/added-abstract-class-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..57d2c4ee --- /dev/null +++ b/functional-tests/src/test/added-abstract-class-in-new-version-ok/app/App.scala @@ -0,0 +1,3 @@ +object App { + def main(args: Array[String]): Unit = () // v1 is (fundamentally) empty +} diff --git a/functional-tests/src/test/added-new-trait-with-abstract-methods-ok/app/App.scala b/functional-tests/src/test/added-new-trait-with-abstract-methods-ok/app/App.scala new file mode 100644 index 00000000..552412ec --- /dev/null +++ b/functional-tests/src/test/added-new-trait-with-abstract-methods-ok/app/App.scala @@ -0,0 +1,3 @@ +object App { + def main(args: Array[String]): Unit = () // v1 is empty +} diff --git a/functional-tests/src/test/added-new-trait-with-concrete-methods-ok/app/App.scala b/functional-tests/src/test/added-new-trait-with-concrete-methods-ok/app/App.scala new file mode 100644 index 00000000..552412ec --- /dev/null +++ b/functional-tests/src/test/added-new-trait-with-concrete-methods-ok/app/App.scala @@ -0,0 +1,3 @@ +object App { + def main(args: Array[String]): Unit = () // v1 is empty +} diff --git a/functional-tests/src/test/added-trait-in-new-version-ok/app/App.scala b/functional-tests/src/test/added-trait-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..57d2c4ee --- /dev/null +++ b/functional-tests/src/test/added-trait-in-new-version-ok/app/App.scala @@ -0,0 +1,3 @@ +object App { + def main(args: Array[String]): Unit = () // v1 is (fundamentally) empty +} diff --git a/functional-tests/src/test/case-class-abstract-becomes-concrete-ok/app/App.scala b/functional-tests/src/test/case-class-abstract-becomes-concrete-ok/app/App.scala new file mode 100644 index 00000000..006f4d52 --- /dev/null +++ b/functional-tests/src/test/case-class-abstract-becomes-concrete-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A() {}) + println(new A() {}.copy()) + } +} diff --git a/functional-tests/src/test/case-class-becomes-final-nok/app/App.scala b/functional-tests/src/test/case-class-becomes-final-nok/app/App.scala new file mode 100644 index 00000000..4181cf4a --- /dev/null +++ b/functional-tests/src/test/case-class-becomes-final-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { def baz = 2 }.baz) + } +} diff --git a/functional-tests/src/test/case-class-concrete-becomes-abstract-nok/app/App.scala b/functional-tests/src/test/case-class-concrete-becomes-abstract-nok/app/App.scala new file mode 100644 index 00000000..b74bfbea --- /dev/null +++ b/functional-tests/src/test/case-class-concrete-becomes-abstract-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + println(A()) + } +} diff --git a/functional-tests/src/test/case-class-constructor-becomes-private-ok/app/App.scala b/functional-tests/src/test/case-class-constructor-becomes-private-ok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/case-class-constructor-becomes-private-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/case-class-was-final-becomes-open-ok/app/App.scala b/functional-tests/src/test/case-class-was-final-becomes-open-ok/app/App.scala new file mode 100644 index 00000000..efa61f97 --- /dev/null +++ b/functional-tests/src/test/case-class-was-final-becomes-open-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(A()) + } +} diff --git a/functional-tests/src/test/class-abstract-becomes-concrete-ok/app/App.scala b/functional-tests/src/test/class-abstract-becomes-concrete-ok/app/App.scala new file mode 100644 index 00000000..70269ef6 --- /dev/null +++ b/functional-tests/src/test/class-abstract-becomes-concrete-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}) + } +} diff --git a/functional-tests/src/test/class-added-abstract-method-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-added-abstract-method-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/class-added-abstract-method-in-new-version-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/class-added-class-in-new-version-ok/app/App.scala b/functional-tests/src/test/class-added-class-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/class-added-class-in-new-version-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/class-added-local-class-ok/app/App.scala b/functional-tests/src/test/class-added-local-class-ok/app/App.scala new file mode 100644 index 00000000..f1c7ecad --- /dev/null +++ b/functional-tests/src/test/class-added-local-class-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().f()) + } +} diff --git a/functional-tests/src/test/class-added-local-method-ok/app/App.scala b/functional-tests/src/test/class-added-local-method-ok/app/App.scala new file mode 100644 index 00000000..8fe8b7e8 --- /dev/null +++ b/functional-tests/src/test/class-added-local-method-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().f) + } +} diff --git a/functional-tests/src/test/class-added-method-in-new-version-ok/app/App.scala b/functional-tests/src/test/class-added-method-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..0718a56c --- /dev/null +++ b/functional-tests/src/test/class-added-method-in-new-version-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo) + } +} diff --git a/functional-tests/src/test/class-added-same-class-in-different-package-is-ok/app/App.scala b/functional-tests/src/test/class-added-same-class-in-different-package-is-ok/app/App.scala new file mode 100644 index 00000000..a6c4213d --- /dev/null +++ b/functional-tests/src/test/class-added-same-class-in-different-package-is-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new me.A) + } +} diff --git a/functional-tests/src/test/class-added-val-in-new-version-ok/app/App.scala b/functional-tests/src/test/class-added-val-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/class-added-val-in-new-version-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/class-added-var-in-new-version-ok/app/App.scala b/functional-tests/src/test/class-added-var-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/class-added-var-in-new-version-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/class-becomes-final-nok/app/App.scala b/functional-tests/src/test/class-becomes-final-nok/app/App.scala new file mode 100644 index 00000000..4181cf4a --- /dev/null +++ b/functional-tests/src/test/class-becomes-final-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { def baz = 2 }.baz) + } +} diff --git a/functional-tests/src/test/class-becomes-object-nok/app/App.scala b/functional-tests/src/test/class-becomes-object-nok/app/App.scala new file mode 100644 index 00000000..72cd6353 --- /dev/null +++ b/functional-tests/src/test/class-becomes-object-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + println(new A {}) + } +} diff --git a/functional-tests/src/test/class-becomes-trait-nok/app/App.scala b/functional-tests/src/test/class-becomes-trait-nok/app/App.scala new file mode 100644 index 00000000..e877e92a --- /dev/null +++ b/functional-tests/src/test/class-becomes-trait-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + println(new A().foo) + } +} diff --git a/functional-tests/src/test/class-changed-local-class-ok/app/App.scala b/functional-tests/src/test/class-changed-local-class-ok/app/App.scala new file mode 100644 index 00000000..f1c7ecad --- /dev/null +++ b/functional-tests/src/test/class-changed-local-class-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().f()) + } +} diff --git a/functional-tests/src/test/class-changed-method-with-val-in-new-version-ok/app/App.scala b/functional-tests/src/test/class-changed-method-with-val-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..749b580b --- /dev/null +++ b/functional-tests/src/test/class-changed-method-with-val-in-new-version-ok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo) + println(new A { override def foo = 3 }.foo) + println(new A { override val foo = 4 }.foo) + } +} diff --git a/functional-tests/src/test/class-changed-method-with-var-in-new-version-ok/app/App.scala b/functional-tests/src/test/class-changed-method-with-var-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..553d0227 --- /dev/null +++ b/functional-tests/src/test/class-changed-method-with-var-in-new-version-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo) + println(new A { override def foo = 3 }.foo) + } +} diff --git a/functional-tests/src/test/class-changed-val-type-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-changed-val-type-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..1bc6de2d --- /dev/null +++ b/functional-tests/src/test/class-changed-val-type-in-new-version-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val x: Int = new A().foo + println(x + 1) + } +} diff --git a/functional-tests/src/test/class-changed-val-with-method-in-new-version-ok/app/App.scala b/functional-tests/src/test/class-changed-val-with-method-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..0815facf --- /dev/null +++ b/functional-tests/src/test/class-changed-val-with-method-in-new-version-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo) + println(new A { override val foo = 1 }.foo) + } +} diff --git a/functional-tests/src/test/class-changed-var-type-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-changed-var-type-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..6424458d --- /dev/null +++ b/functional-tests/src/test/class-changed-var-type-in-new-version-nok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + val a = new A + a.foo = 3 + println(a.foo + 1) + } +} diff --git a/functional-tests/src/test/class-changed-var-with-method-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-changed-var-with-method-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..5af91b53 --- /dev/null +++ b/functional-tests/src/test/class-changed-var-with-method-in-new-version-nok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + val a = new A + a.foo = 3 + println(a.foo) + } +} diff --git a/functional-tests/src/test/class-concrete-becomes-abstract-nok/app/App.scala b/functional-tests/src/test/class-concrete-becomes-abstract-nok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/class-concrete-becomes-abstract-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/class-constructor-generics-nok/app/App.scala b/functional-tests/src/test/class-constructor-generics-nok/app/App.scala new file mode 100644 index 00000000..b47e8e97 --- /dev/null +++ b/functional-tests/src/test/class-constructor-generics-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val result: String = new OptionPane(("foo", "bar")).show + println("result: " + result) + } +} diff --git a/functional-tests/src/test/class-constructor-generics-nok/problems.txt b/functional-tests/src/test/class-constructor-generics-nok/problems.txt index f5f5fb83..d353f46c 100644 --- a/functional-tests/src/test/class-constructor-generics-nok/problems.txt +++ b/functional-tests/src/test/class-constructor-generics-nok/problems.txt @@ -1,3 +1,3 @@ -method source()scala.Tuple2 in class OptionPane has a different generic signature in new version, where it is ()Lscala/Tuple2;Ljava/lang/String;>; rather than ()Lscala/Tuple2;. See https://github.com/lightbend/mima#incompatiblesignatureproblem -method show()java.lang.Object in class OptionPane has a different generic signature in new version, where it is ()TA; rather than . See https://github.com/lightbend/mima#incompatiblesignatureproblem -method this(scala.Tuple2)Unit in class OptionPane has a different generic signature in new version, where it is (Lscala/Tuple2;Ljava/lang/String;>;)V rather than (Lscala/Tuple2;)V. See https://github.com/lightbend/mima#incompatiblesignatureproblem +method source()scala.Tuple2 in class OptionPane has a different generic signature in new version, where it is ()Lscala/Tuple2;Ljava/lang/String;>; rather than ()Lscala/Tuple2;. See https://github.com/lightbend/mima#incompatiblesignatureproblem +method show()java.lang.String in class OptionPane does not have a correspondent in new version +method this(scala.Tuple2)Unit in class OptionPane has a different generic signature in new version, where it is (Lscala/Tuple2;Ljava/lang/String;>;)V rather than (Lscala/Tuple2;)V. See https://github.com/lightbend/mima#incompatiblesignatureproblem diff --git a/functional-tests/src/test/class-constructor-generics-nok/v1/A.scala b/functional-tests/src/test/class-constructor-generics-nok/v1/A.scala index 125b4f16..d1822320 100644 --- a/functional-tests/src/test/class-constructor-generics-nok/v1/A.scala +++ b/functional-tests/src/test/class-constructor-generics-nok/v1/A.scala @@ -1,10 +1,8 @@ trait DialogSource[+A] { def show(): A } -final class OptionPane(val source: (javax.swing.JOptionPane, String)) extends DialogSource[Any] { - def show(): Any = { - val (pane, title) = source - val jdlg = pane.createDialog(title) - jdlg.setVisible(true) - pane.getValue +final class OptionPane(val source: (String, String)) extends DialogSource[String] { + def show(): String = { + val (content, _) = source + content } } diff --git a/functional-tests/src/test/class-constructor-generics-nok/v2/A.scala b/functional-tests/src/test/class-constructor-generics-nok/v2/A.scala index e4ccc467..8cd0013d 100644 --- a/functional-tests/src/test/class-constructor-generics-nok/v2/A.scala +++ b/functional-tests/src/test/class-constructor-generics-nok/v2/A.scala @@ -2,14 +2,11 @@ trait DialogSource[+A] { def show(): A } final class OptionPane[A](val source: (MyPane[A], String)) extends DialogSource[A] { def show(): A = { - val (pane, title) = source - val jdlg = pane.peer.createDialog(title) - jdlg.setVisible(true) + val (pane, _) = source pane.result } } trait MyPane[A] { - def peer: javax.swing.JOptionPane def result: A } diff --git a/functional-tests/src/test/class-constructor-inherited-nok/app/App.scala b/functional-tests/src/test/class-constructor-inherited-nok/app/App.scala new file mode 100644 index 00000000..6eef13a1 --- /dev/null +++ b/functional-tests/src/test/class-constructor-inherited-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B(2)) + } +} diff --git a/functional-tests/src/test/class-deleted-deprecated-method-nok/app/App.scala b/functional-tests/src/test/class-deleted-deprecated-method-nok/app/App.scala new file mode 100644 index 00000000..9741b914 --- /dev/null +++ b/functional-tests/src/test/class-deleted-deprecated-method-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo2 + 1) + } +} diff --git a/functional-tests/src/test/class-inherits-new-trait-with-shadowed-abstract-method-ok/app/App.scala b/functional-tests/src/test/class-inherits-new-trait-with-shadowed-abstract-method-ok/app/App.scala new file mode 100644 index 00000000..8d46e30f --- /dev/null +++ b/functional-tests/src/test/class-inherits-new-trait-with-shadowed-abstract-method-ok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B().foo) + println(new A { def foo = 1 }.foo) + println(new A { override def foo = 1 }.foo) + } +} diff --git a/functional-tests/src/test/class-method-abstract-override-of-concrete-superclass-method-nok/app/App.scala b/functional-tests/src/test/class-method-abstract-override-of-concrete-superclass-method-nok/app/App.scala new file mode 100644 index 00000000..1a60fd29 --- /dev/null +++ b/functional-tests/src/test/class-method-abstract-override-of-concrete-superclass-method-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B {}.foo + 1) + } +} diff --git a/functional-tests/src/test/class-method-abstract-override-of-concrete-supertrait-method-nok/app/App.scala b/functional-tests/src/test/class-method-abstract-override-of-concrete-supertrait-method-nok/app/App.scala new file mode 100644 index 00000000..6bd7ad27 --- /dev/null +++ b/functional-tests/src/test/class-method-abstract-override-of-concrete-supertrait-method-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B {}.foo) + println(new B { override def foo = 3 }.foo) + } +} diff --git a/functional-tests/src/test/class-method-becomes-final-nok/app/App.scala b/functional-tests/src/test/class-method-becomes-final-nok/app/App.scala new file mode 100644 index 00000000..bda6a982 --- /dev/null +++ b/functional-tests/src/test/class-method-becomes-final-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { override def foo = 3 }.foo) + } +} diff --git a/functional-tests/src/test/class-method-changed-parameter-type-nok/app/App.scala b/functional-tests/src/test/class-method-changed-parameter-type-nok/app/App.scala new file mode 100644 index 00000000..046d0e27 --- /dev/null +++ b/functional-tests/src/test/class-method-changed-parameter-type-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo(11) + 12) + } +} diff --git a/functional-tests/src/test/class-method-changed-parameters-nok/app/App.scala b/functional-tests/src/test/class-method-changed-parameters-nok/app/App.scala new file mode 100644 index 00000000..d87ad339 --- /dev/null +++ b/functional-tests/src/test/class-method-changed-parameters-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo(2)) + } +} diff --git a/functional-tests/src/test/class-method-changed-parameters2-nok/app/App.scala b/functional-tests/src/test/class-method-changed-parameters2-nok/app/App.scala new file mode 100644 index 00000000..111bcc44 --- /dev/null +++ b/functional-tests/src/test/class-method-changed-parameters2-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo(App)(1)) + } +} diff --git a/functional-tests/src/test/class-method-concrete-override-of-concrete-supertrait-method-ok/app/App.scala b/functional-tests/src/test/class-method-concrete-override-of-concrete-supertrait-method-ok/app/App.scala new file mode 100644 index 00000000..e5aa76e1 --- /dev/null +++ b/functional-tests/src/test/class-method-concrete-override-of-concrete-supertrait-method-ok/app/App.scala @@ -0,0 +1,8 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo) + println(new B().foo) + println(new A { override def foo = 10 }.foo) + println(new B { override def foo = 11 }.foo) + } +} diff --git a/functional-tests/src/test/class-method-generics-nok/app/App.scala b/functional-tests/src/test/class-method-generics-nok/app/App.scala new file mode 100644 index 00000000..f4b6269e --- /dev/null +++ b/functional-tests/src/test/class-method-generics-nok/app/App.scala @@ -0,0 +1,19 @@ +object App { + def main(args: Array[String]): Unit = { + val api = new Api + val cov2 = api.cov2[String] + println(cov2) + println(api.con1(App)) + + val abi = new Abi { + def cov1() = App + def cov2[T]() = null.asInstanceOf[T] + + def con1(x: Any) = () + def con2[T](x: T) = () + } + val cov1: Any = abi.cov1 + println(cov1) + println(abi.con2[App.type](App)) + } +} diff --git a/functional-tests/src/test/class-method-generics-nok/v1/A.scala b/functional-tests/src/test/class-method-generics-nok/v1/A.scala index 11e4cf7e..7d38ffc7 100644 --- a/functional-tests/src/test/class-method-generics-nok/v1/A.scala +++ b/functional-tests/src/test/class-method-generics-nok/v1/A.scala @@ -4,8 +4,8 @@ class A { } final class Api { - def cov1(): Any = ??? - def cov2[T](): T = ??? + def cov1(): Any = () + def cov2[T](): T = null.asInstanceOf[T] def con1(x: Any): Unit = () def con2[T](x: T): Unit = () diff --git a/functional-tests/src/test/class-method-generics-nok/v2/A.scala b/functional-tests/src/test/class-method-generics-nok/v2/A.scala index f1f13bd8..3ab580da 100644 --- a/functional-tests/src/test/class-method-generics-nok/v2/A.scala +++ b/functional-tests/src/test/class-method-generics-nok/v2/A.scala @@ -4,8 +4,8 @@ class A { } final class Api { - def cov1[A](): A = ??? // OK - def cov2(): Any = ??? // KO + def cov1[A](): A = null.asInstanceOf[A] // OK + def cov2(): Any = () // KO def con1[A](x: A): Unit = () // KO def con2(x: Any): Unit = () // OK diff --git a/functional-tests/src/test/class-method-overload-with-default-parameters-nok/app/App.scala b/functional-tests/src/test/class-method-overload-with-default-parameters-nok/app/App.scala new file mode 100644 index 00000000..2ad1ddda --- /dev/null +++ b/functional-tests/src/test/class-method-overload-with-default-parameters-nok/app/App.scala @@ -0,0 +1,11 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().copy()) + println(new A().copy(2)) + println(new A().copy(2, "baz")) + println(new A().copy(x = 2)) + println(new A().copy(y = "baz")) + println(new A().copy(x = 2, y = "baz")) + println(new A().copy(y = "baz", x = 2)) + } +} diff --git a/functional-tests/src/test/class-method-pushed-up-ok/app/App.scala b/functional-tests/src/test/class-method-pushed-up-ok/app/App.scala new file mode 100644 index 00000000..a44c4eaf --- /dev/null +++ b/functional-tests/src/test/class-method-pushed-up-ok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B().foo(3)) + println(new A().foo(4)) + println(new A { override def foo(x: Int) = super.foo(x * 10) }.foo(5)) + } +} diff --git a/functional-tests/src/test/class-missing-method-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-missing-method-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..fa8db9ef --- /dev/null +++ b/functional-tests/src/test/class-missing-method-in-new-version-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new some.A().foo[App.type](App)(App)) + } +} diff --git a/functional-tests/src/test/class-missing-method-in-root-package-nok/app/App.scala b/functional-tests/src/test/class-missing-method-in-root-package-nok/app/App.scala new file mode 100644 index 00000000..bba518ff --- /dev/null +++ b/functional-tests/src/test/class-missing-method-in-root-package-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo[App.type](App)(App)) + } +} diff --git a/functional-tests/src/test/class-missing-nok/app/App.scala b/functional-tests/src/test/class-missing-nok/app/App.scala new file mode 100644 index 00000000..026cbb42 --- /dev/null +++ b/functional-tests/src/test/class-missing-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B) + } +} diff --git a/functional-tests/src/test/class-narrowing-method-type-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-narrowing-method-type-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..73e49fcf --- /dev/null +++ b/functional-tests/src/test/class-narrowing-method-type-in-new-version-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val foo: Foo = new A().foo + println(foo) + } +} diff --git a/functional-tests/src/test/class-public-method-becomes-private-nok/app/App.scala b/functional-tests/src/test/class-public-method-becomes-private-nok/app/App.scala new file mode 100644 index 00000000..bba518ff --- /dev/null +++ b/functional-tests/src/test/class-public-method-becomes-private-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo[App.type](App)(App)) + } +} diff --git a/functional-tests/src/test/class-push-up-method-maintaining-explicit-bridge-ok/app/App.scala b/functional-tests/src/test/class-push-up-method-maintaining-explicit-bridge-ok/app/App.scala new file mode 100644 index 00000000..9a9001a2 --- /dev/null +++ b/functional-tests/src/test/class-push-up-method-maintaining-explicit-bridge-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + println(new B().foo) + } +} diff --git a/functional-tests/src/test/class-removed-constructor-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-removed-constructor-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..e063ce20 --- /dev/null +++ b/functional-tests/src/test/class-removed-constructor-in-new-version-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A(1).value) + } +} diff --git a/functional-tests/src/test/class-removed-local-class-ok/app/App.scala b/functional-tests/src/test/class-removed-local-class-ok/app/App.scala new file mode 100644 index 00000000..f1c7ecad --- /dev/null +++ b/functional-tests/src/test/class-removed-local-class-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().f()) + } +} diff --git a/functional-tests/src/test/class-removed-local-method-ok/app/App.scala b/functional-tests/src/test/class-removed-local-method-ok/app/App.scala new file mode 100644 index 00000000..8fe8b7e8 --- /dev/null +++ b/functional-tests/src/test/class-removed-local-method-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().f) + } +} diff --git a/functional-tests/src/test/class-removed-method-overload-nok/app/App.scala b/functional-tests/src/test/class-removed-method-overload-nok/app/App.scala new file mode 100644 index 00000000..13b5ccc3 --- /dev/null +++ b/functional-tests/src/test/class-removed-method-overload-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo(App)) + } +} diff --git a/functional-tests/src/test/class-removed-superclass-nok/app/App.scala b/functional-tests/src/test/class-removed-superclass-nok/app/App.scala new file mode 100644 index 00000000..e15f682b --- /dev/null +++ b/functional-tests/src/test/class-removed-superclass-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val b: A = new B + println(b.foo) + } +} diff --git a/functional-tests/src/test/class-removed-superclass-nok/v1/A.scala b/functional-tests/src/test/class-removed-superclass-nok/v1/A.scala index 439b3cd3..97b0630d 100644 --- a/functional-tests/src/test/class-removed-superclass-nok/v1/A.scala +++ b/functional-tests/src/test/class-removed-superclass-nok/v1/A.scala @@ -1,2 +1,4 @@ -class A +class A { + def foo = 1 +} class B extends A diff --git a/functional-tests/src/test/class-removed-superclass-nok/v2/A.scala b/functional-tests/src/test/class-removed-superclass-nok/v2/A.scala index 1b4e96d8..f6d6a907 100644 --- a/functional-tests/src/test/class-removed-superclass-nok/v2/A.scala +++ b/functional-tests/src/test/class-removed-superclass-nok/v2/A.scala @@ -1,2 +1,4 @@ -class A +class A { + def foo = 1 +} class B diff --git a/functional-tests/src/test/class-removing-inner-object-nok/app/App.scala b/functional-tests/src/test/class-removing-inner-object-nok/app/App.scala new file mode 100644 index 00000000..fc357aae --- /dev/null +++ b/functional-tests/src/test/class-removing-inner-object-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().B) + } +} diff --git a/functional-tests/src/test/class-type-becomes-final-ok/app/App.scala b/functional-tests/src/test/class-type-becomes-final-ok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/class-type-becomes-final-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/class-val-becomes-final-nok/app/App.scala b/functional-tests/src/test/class-val-becomes-final-nok/app/App.scala new file mode 100644 index 00000000..0c8dbecd --- /dev/null +++ b/functional-tests/src/test/class-val-becomes-final-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { override val foo = 3 }.foo) + } +} diff --git a/functional-tests/src/test/class-val-becomes-lazy-val-ok/app/App.scala b/functional-tests/src/test/class-val-becomes-lazy-val-ok/app/App.scala new file mode 100644 index 00000000..a6c92376 --- /dev/null +++ b/functional-tests/src/test/class-val-becomes-lazy-val-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new ClassAnalyzer().superclasses) + } +} diff --git a/functional-tests/src/test/class-var-becomes-final-nok/app/App.java b/functional-tests/src/test/class-var-becomes-final-nok/app/App.java new file mode 100644 index 00000000..00234517 --- /dev/null +++ b/functional-tests/src/test/class-var-becomes-final-nok/app/App.java @@ -0,0 +1,6 @@ +public class App { + public static void main(String[] args) { + // IMO, with no way to fail this in Scala, this shouldn't emit a problem + System.out.println(new A() { public int foo() { return 11; } }.foo() + 12); + } +} diff --git a/functional-tests/src/test/class-was-final-becomes-not-final-ok/app/App.scala b/functional-tests/src/test/class-was-final-becomes-not-final-ok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/class-was-final-becomes-not-final-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/class-widening-method-type-in-new-version-nok/app/App.scala b/functional-tests/src/test/class-widening-method-type-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..3ae582ac --- /dev/null +++ b/functional-tests/src/test/class-widening-method-type-in-new-version-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val foo: Int = new A().foo + println(foo + 1) + } +} diff --git a/functional-tests/src/test/effectively-final-becomes-final-is-ok/app/App.scala b/functional-tests/src/test/effectively-final-becomes-final-is-ok/app/App.scala new file mode 100644 index 00000000..0718a56c --- /dev/null +++ b/functional-tests/src/test/effectively-final-becomes-final-is-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo) + } +} diff --git a/functional-tests/src/test/final-class-becomes-object-nok/app/App.scala b/functional-tests/src/test/final-class-becomes-object-nok/app/App.scala new file mode 100644 index 00000000..30ff850c --- /dev/null +++ b/functional-tests/src/test/final-class-becomes-object-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A) + } +} diff --git a/functional-tests/src/test/ignore-changed-and-added-anonymous-lambdas-ok/app/App.scala b/functional-tests/src/test/ignore-changed-and-added-anonymous-lambdas-ok/app/App.scala new file mode 100644 index 00000000..358c8c7b --- /dev/null +++ b/functional-tests/src/test/ignore-changed-and-added-anonymous-lambdas-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo()) + } +} diff --git a/functional-tests/src/test/ignore-changed-and-removed-anonymous-lambdas-ok/app/App.scala b/functional-tests/src/test/ignore-changed-and-removed-anonymous-lambdas-ok/app/App.scala new file mode 100644 index 00000000..358c8c7b --- /dev/null +++ b/functional-tests/src/test/ignore-changed-and-removed-anonymous-lambdas-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A().foo()) + } +} diff --git a/functional-tests/src/test/inner-class-loses-outer-pointer-nok/app/App.scala b/functional-tests/src/test/inner-class-loses-outer-pointer-nok/app/App.scala new file mode 100644 index 00000000..664ea554 --- /dev/null +++ b/functional-tests/src/test/inner-class-loses-outer-pointer-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val c = new C + println(new c.Inner {}) + } +} diff --git a/functional-tests/src/test/interface-method-becomes-default-method-ok/app/App.scala b/functional-tests/src/test/interface-method-becomes-default-method-ok/app/App.scala new file mode 100644 index 00000000..2e6b8a6f --- /dev/null +++ b/functional-tests/src/test/interface-method-becomes-default-method-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { def foo = "bob" }.foo) + } +} diff --git a/functional-tests/src/test/java-class-missing-static-method-in-new-version-nok/app/App.scala b/functional-tests/src/test/java-class-missing-static-method-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..ceb36180 --- /dev/null +++ b/functional-tests/src/test/java-class-missing-static-method-in-new-version-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(A.foo) + } +} diff --git a/functional-tests/src/test/java-class-static-to-virtual-method-nok/app/App.scala b/functional-tests/src/test/java-class-static-to-virtual-method-nok/app/App.scala new file mode 100644 index 00000000..9fad5256 --- /dev/null +++ b/functional-tests/src/test/java-class-static-to-virtual-method-nok/app/App.scala @@ -0,0 +1,8 @@ +object App { + def main(args: Array[String]): Unit = { + println(A.fld) + println(A.foo(new A)) + println(A.bar) + println(new A.Nested) + } +} diff --git a/functional-tests/src/test/java-class-static-varargs-to-scala-object-annotated-varargs-ok/app/App.scala b/functional-tests/src/test/java-class-static-varargs-to-scala-object-annotated-varargs-ok/app/App.scala new file mode 100644 index 00000000..fca75f82 --- /dev/null +++ b/functional-tests/src/test/java-class-static-varargs-to-scala-object-annotated-varargs-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(A.create("foo")) + } +} diff --git a/functional-tests/src/test/java-class-virtual-to-static-method-nok/app/App.scala b/functional-tests/src/test/java-class-virtual-to-static-method-nok/app/App.scala new file mode 100644 index 00000000..00684395 --- /dev/null +++ b/functional-tests/src/test/java-class-virtual-to-static-method-nok/app/App.scala @@ -0,0 +1,9 @@ +object App { + def main(args: Array[String]): Unit = { + val a = new A + println(a.fld) + println(a.foo(a)) + println(a.bar) + println(new a.Nested) + } +} diff --git a/functional-tests/src/test/lazy-field-becomes-eager-ok/app/App.scala b/functional-tests/src/test/lazy-field-becomes-eager-ok/app/App.scala new file mode 100644 index 00000000..a6c92376 --- /dev/null +++ b/functional-tests/src/test/lazy-field-becomes-eager-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new ClassAnalyzer().superclasses) + } +} diff --git a/functional-tests/src/test/missing-synthetic-classes-are-ignored-ok/app/App.scala b/functional-tests/src/test/missing-synthetic-classes-are-ignored-ok/app/App.scala new file mode 100644 index 00000000..56420b26 --- /dev/null +++ b/functional-tests/src/test/missing-synthetic-classes-are-ignored-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo) + } +} diff --git a/functional-tests/src/test/moving-method-upward-from-trait-to-class-nok/app/App.scala b/functional-tests/src/test/moving-method-upward-from-trait-to-class-nok/app/App.scala new file mode 100644 index 00000000..69349181 --- /dev/null +++ b/functional-tests/src/test/moving-method-upward-from-trait-to-class-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val b: B = new B {} + println(b.foo + 1) + } +} diff --git a/functional-tests/src/test/object-becomes-class-nok/app/App.scala b/functional-tests/src/test/object-becomes-class-nok/app/App.scala new file mode 100644 index 00000000..ee3ec514 --- /dev/null +++ b/functional-tests/src/test/object-becomes-class-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(A) + } +} diff --git a/functional-tests/src/test/object-becomes-class-with-companion-ok/app/App.scala b/functional-tests/src/test/object-becomes-class-with-companion-ok/app/App.scala new file mode 100644 index 00000000..ee3ec514 --- /dev/null +++ b/functional-tests/src/test/object-becomes-class-with-companion-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(A) + } +} diff --git a/functional-tests/src/test/object-removing-inner-object-nok/app/App.scala b/functional-tests/src/test/object-removing-inner-object-nok/app/App.scala new file mode 100644 index 00000000..06e97fd6 --- /dev/null +++ b/functional-tests/src/test/object-removing-inner-object-nok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + println(A.B) + println(A.B.foo + 1) + println(A.B.C) + } +} diff --git a/functional-tests/src/test/package-missing-in-new-version-is-ok/app/App.scala b/functional-tests/src/test/package-missing-in-new-version-is-ok/app/App.scala new file mode 100644 index 00000000..97aa93e1 --- /dev/null +++ b/functional-tests/src/test/package-missing-in-new-version-is-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new me.A { def foo = 2 }.foo) + } +} diff --git a/functional-tests/src/test/package-nested-with-breaking-change-is-nok/app/App.scala b/functional-tests/src/test/package-nested-with-breaking-change-is-nok/app/App.scala new file mode 100644 index 00000000..2afd1052 --- /dev/null +++ b/functional-tests/src/test/package-nested-with-breaking-change-is-nok/app/App.scala @@ -0,0 +1,10 @@ +object App { + def main(args: Array[String]): Unit = { + val bytes: Array[Byte] = Array(1) + println(new A().toHex(bytes)) + println(new p.A().toHex(bytes)) + println(new p.q.A().toHex(bytes)) + println(new p.q.r.A().toHex(bytes)) + println(new p.q.r.s.A().toHex(bytes)) + } +} diff --git a/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v1/A.scala b/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v1/A.scala index f34820f2..38fa07f1 100644 --- a/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v1/A.scala +++ b/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v1/A.scala @@ -1,27 +1,27 @@ class A { - def toHex(bytes: Array[Byte]): String = ??? + def toHex(bytes: Array[Byte]): String = "A" } package p { class A { - def toHex(bytes: Array[Byte]): String = ??? + def toHex(bytes: Array[Byte]): String = "p.A" } } package p.q { class A { - def toHex(bytes: Array[Byte]): String = ??? + def toHex(bytes: Array[Byte]): String = "p.q.A" } } package p.q.r { class A { - def toHex(bytes: Array[Byte]): String = ??? + def toHex(bytes: Array[Byte]): String = "p.q.r.A" } } package p.q.r.s { class A { - def toHex(bytes: Array[Byte]): String = ??? + def toHex(bytes: Array[Byte]): String = "p.q.r.s.A" } } diff --git a/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v2/A.scala b/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v2/A.scala index 2fcbeb95..00777771 100644 --- a/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v2/A.scala +++ b/functional-tests/src/test/package-nested-with-breaking-change-is-nok/v2/A.scala @@ -1,27 +1,27 @@ class A { - def toHex(bytes: Array[Byte], b: Boolean): String = ??? + def toHex(bytes: Array[Byte], b: Boolean): String = "A" } package p { class A { - def toHex(bytes: Array[Byte], b: Boolean): String = ??? + def toHex(bytes: Array[Byte], b: Boolean): String = "p.A" } } package p.q { class A { - def toHex(bytes: Array[Byte], b: Boolean): String = ??? + def toHex(bytes: Array[Byte], b: Boolean): String = "p.q.A" } } package p.q.r { class A { - def toHex(bytes: Array[Byte], b: Boolean): String = ??? + def toHex(bytes: Array[Byte], b: Boolean): String = "p.q.r.A" } } package p.q.r.s { class A { - def toHex(bytes: Array[Byte], b: Boolean): String = ??? + def toHex(bytes: Array[Byte], b: Boolean): String = "p.q.r.s.A" } } diff --git a/functional-tests/src/test/package-with-classes-missing-in-new-version-is-nok/app/App.scala b/functional-tests/src/test/package-with-classes-missing-in-new-version-is-nok/app/App.scala new file mode 100644 index 00000000..eafc0db5 --- /dev/null +++ b/functional-tests/src/test/package-with-classes-missing-in-new-version-is-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new you.B) + } +} diff --git a/functional-tests/src/test/package-with-classes-splitted-into-two-files-in-new-version-is-ok/app/App.scala b/functional-tests/src/test/package-with-classes-splitted-into-two-files-in-new-version-is-ok/app/App.scala new file mode 100644 index 00000000..cb4999a4 --- /dev/null +++ b/functional-tests/src/test/package-with-classes-splitted-into-two-files-in-new-version-is-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new me.A { def foo = 1 }.foo) + println(new you.B) + } +} diff --git a/functional-tests/src/test/public-method-becomes-package-private-nok/app/App.java b/functional-tests/src/test/public-method-becomes-package-private-nok/app/App.java new file mode 100644 index 00000000..4eb4d078 --- /dev/null +++ b/functional-tests/src/test/public-method-becomes-package-private-nok/app/App.java @@ -0,0 +1,5 @@ +public final class App { + public static void main(String[] args) { + System.out.println(bar.A.foo(new App(), new App())); + } +} diff --git a/functional-tests/src/test/public-method-becomes-package-private-nok/v1/A.scala b/functional-tests/src/test/public-method-becomes-package-private-nok/v1/A.scala index a7cbfb97..0ce9d1db 100644 --- a/functional-tests/src/test/public-method-becomes-package-private-nok/v1/A.scala +++ b/functional-tests/src/test/public-method-becomes-package-private-nok/v1/A.scala @@ -1,5 +1,5 @@ package bar object A { - def foo[T](x: T): T = ??? - def foo[T](x: T, y: T): T = ??? + def foo[T](x: T): T = x + def foo[T](x: T, y: T): T = y } diff --git a/functional-tests/src/test/public-method-becomes-package-private-nok/v2/A.scala b/functional-tests/src/test/public-method-becomes-package-private-nok/v2/A.scala index 902fdd15..d792edac 100644 --- a/functional-tests/src/test/public-method-becomes-package-private-nok/v2/A.scala +++ b/functional-tests/src/test/public-method-becomes-package-private-nok/v2/A.scala @@ -1,5 +1,5 @@ package bar object A { - def foo[T]( x: T): T = ??? - private[bar] def foo[T](x: T, y: T): T = ??? + def foo[T](x: T): T = x + private[bar] def foo[T](x: T, y: T): T = y } diff --git a/functional-tests/src/test/public-method-becomes-package-private-ok/app/App.scala b/functional-tests/src/test/public-method-becomes-package-private-ok/app/App.scala new file mode 100644 index 00000000..f3d07593 --- /dev/null +++ b/functional-tests/src/test/public-method-becomes-package-private-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new bar.A().foo("foo")) + println(new bar.A().foo("foo", "bar")) + } +} diff --git a/functional-tests/src/test/removing-method-from-class-with-special-characters-nok/app/App.scala b/functional-tests/src/test/removing-method-from-class-with-special-characters-nok/app/App.scala new file mode 100644 index 00000000..9b5e0195 --- /dev/null +++ b/functional-tests/src/test/removing-method-from-class-with-special-characters-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new ::().++ + 1) + } +} diff --git a/functional-tests/src/test/removing-method-with-special-characters-from-class-nok/app/App.scala b/functional-tests/src/test/removing-method-with-special-characters-from-class-nok/app/App.scala new file mode 100644 index 00000000..d74b1d65 --- /dev/null +++ b/functional-tests/src/test/removing-method-with-special-characters-from-class-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new SpecialChars().++ + 1) + } +} diff --git a/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/app/App.scala b/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/app/App.scala new file mode 100644 index 00000000..d2f15eb4 --- /dev/null +++ b/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(foo.A.giveLt.f + 1) + println(foo.A.giveB.f + 1) + } +} diff --git a/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v1/A.scala b/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v1/A.scala index 32ca72a0..5b5562e2 100644 --- a/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v1/A.scala +++ b/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v1/A.scala @@ -9,4 +9,7 @@ object A { abstract class B { def f: Int } + + def giveLt: < = new < { def f = 1 } + def giveB: B = new B { def f = 2 } } diff --git a/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v2/A.scala b/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v2/A.scala index 86cde035..5303f884 100644 --- a/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v2/A.scala +++ b/functional-tests/src/test/removing-method-with-special-characters-from-inner-class-nok/v2/A.scala @@ -3,4 +3,7 @@ package foo object A { abstract class < abstract class B + + def giveLt: < = new < {} + def giveB: B = new B {} } diff --git a/functional-tests/src/test/trait-abstract-method-becomes-concrete-ok/app/App.scala b/functional-tests/src/test/trait-abstract-method-becomes-concrete-ok/app/App.scala new file mode 100644 index 00000000..614ab3f2 --- /dev/null +++ b/functional-tests/src/test/trait-abstract-method-becomes-concrete-ok/app/App.scala @@ -0,0 +1,7 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { def foo = 2 }.foo) + println(new B().foo) + println(new B { override def foo = 3 }.foo) + } +} diff --git a/functional-tests/src/test/trait-abstract-method-becomes-concrete2-ok/app/App.scala b/functional-tests/src/test/trait-abstract-method-becomes-concrete2-ok/app/App.scala new file mode 100644 index 00000000..64343733 --- /dev/null +++ b/functional-tests/src/test/trait-abstract-method-becomes-concrete2-ok/app/App.scala @@ -0,0 +1,18 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A1 {}) + val a = new A { def foo = 2 } + val aa1: A1 = new A { def foo = 3 } + println(a.bar) + println(a.foo) + println(aa1) + val b = new B + val ba: A = new B + val ba1: A1 = new B + println(b.bar) + println(b.foo) + println(ba.bar) + println(ba.foo) + println(ba1) + } +} diff --git a/functional-tests/src/test/trait-abstract-method-becomes-concrete2-ok/testAppRun-2.11.pending b/functional-tests/src/test/trait-abstract-method-becomes-concrete2-ok/testAppRun-2.11.pending new file mode 100644 index 00000000..e69de29b diff --git a/functional-tests/src/test/trait-abstract-val-becomes-concrete-nok/app/App.scala b/functional-tests/src/test/trait-abstract-val-becomes-concrete-nok/app/App.scala new file mode 100644 index 00000000..25738494 --- /dev/null +++ b/functional-tests/src/test/trait-abstract-val-becomes-concrete-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { val foo = 11 }.foo + 12) + println(new B { override val foo = 13 }.foo + 14) + } +} diff --git a/functional-tests/src/test/trait-abstract-val-becomes-concrete-nok/testAppRun.pending b/functional-tests/src/test/trait-abstract-val-becomes-concrete-nok/testAppRun.pending new file mode 100644 index 00000000..e69de29b diff --git a/functional-tests/src/test/trait-abstract-var-becomes-concrete-ok/app/App.scala b/functional-tests/src/test/trait-abstract-var-becomes-concrete-ok/app/App.scala new file mode 100644 index 00000000..f309ce5d --- /dev/null +++ b/functional-tests/src/test/trait-abstract-var-becomes-concrete-ok/app/App.scala @@ -0,0 +1,18 @@ +object App { + def main(args: Array[String]): Unit = { + val a = new A { var foo = 1 } + println(a.foo) + a.foo = 10 + println(a.foo) + + val b = new B {} + println(b.foo) + b.foo = 11 + println(b.foo) + + val ba: A = new B {} + println(ba.foo) + ba.foo = 11 + println(ba.foo) + } +} diff --git a/functional-tests/src/test/trait-added-abstract-method-nok/app/App.scala b/functional-tests/src/test/trait-added-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..f51eccda --- /dev/null +++ b/functional-tests/src/test/trait-added-abstract-method-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.use(new A {})) + } +} diff --git a/functional-tests/src/test/trait-added-abstract-method-nok/v1/A.scala b/functional-tests/src/test/trait-added-abstract-method-nok/v1/A.scala index 16c5ea48..68adf9c4 100644 --- a/functional-tests/src/test/trait-added-abstract-method-nok/v1/A.scala +++ b/functional-tests/src/test/trait-added-abstract-method-nok/v1/A.scala @@ -1 +1,5 @@ -trait A \ No newline at end of file +trait A + +object Usage { + def use(a: A) = () +} diff --git a/functional-tests/src/test/trait-added-abstract-method-nok/v2/A.scala b/functional-tests/src/test/trait-added-abstract-method-nok/v2/A.scala index 87f70026..7ae2b8a8 100644 --- a/functional-tests/src/test/trait-added-abstract-method-nok/v2/A.scala +++ b/functional-tests/src/test/trait-added-abstract-method-nok/v2/A.scala @@ -1,3 +1,7 @@ trait A { def foo(): Unit } + +object Usage { + def use(a: A) = a.foo() +} diff --git a/functional-tests/src/test/trait-added-method-in-new-version-ok/app/App.scala b/functional-tests/src/test/trait-added-method-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..56420b26 --- /dev/null +++ b/functional-tests/src/test/trait-added-method-in-new-version-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo) + } +} diff --git a/functional-tests/src/test/trait-added-method-in-new-version-ok/testAppRun-2.11.pending b/functional-tests/src/test/trait-added-method-in-new-version-ok/testAppRun-2.11.pending new file mode 100644 index 00000000..e69de29b diff --git a/functional-tests/src/test/trait-added-val-in-new-version-nok/app/App.scala b/functional-tests/src/test/trait-added-val-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..69cc04ac --- /dev/null +++ b/functional-tests/src/test/trait-added-val-in-new-version-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo + 1) + } +} diff --git a/functional-tests/src/test/trait-added-var-in-new-version-nok/app/App.scala b/functional-tests/src/test/trait-added-var-in-new-version-nok/app/App.scala new file mode 100644 index 00000000..69cc04ac --- /dev/null +++ b/functional-tests/src/test/trait-added-var-in-new-version-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo + 1) + } +} diff --git a/functional-tests/src/test/trait-deleting-concrete-methods-is-nok/app/App.scala b/functional-tests/src/test/trait-deleting-concrete-methods-is-nok/app/App.scala new file mode 100644 index 00000000..7d007d94 --- /dev/null +++ b/functional-tests/src/test/trait-deleting-concrete-methods-is-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B() {}.foo) + println(new C().foo) + } +} diff --git a/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/app/App.scala b/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..9dcb32e1 --- /dev/null +++ b/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.use(new A {}) + 10) + } +} diff --git a/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v1/A.scala b/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v1/A.scala index 16c5ea48..cdfe75aa 100644 --- a/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v1/A.scala +++ b/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v1/A.scala @@ -1 +1,5 @@ -trait A \ No newline at end of file +trait A + +object Usage { + def use(a: A) = 0 +} diff --git a/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v2/A.scala b/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v2/A.scala index fd1ff803..696f6e43 100644 --- a/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v2/A.scala +++ b/functional-tests/src/test/trait-extending-new-trait-with-abstract-method-nok/v2/A.scala @@ -2,4 +2,8 @@ trait A extends B trait B { val a: Int def foo: Int -} \ No newline at end of file +} + +object Usage { + def use(a: A) = a.a + a.foo + 1 +} diff --git a/functional-tests/src/test/trait-extending-new-trait-with-concrete-method-ok/app/App.scala b/functional-tests/src/test/trait-extending-new-trait-with-concrete-method-ok/app/App.scala new file mode 100644 index 00000000..aaa06192 --- /dev/null +++ b/functional-tests/src/test/trait-extending-new-trait-with-concrete-method-ok/app/App.scala @@ -0,0 +1,9 @@ +object App { + def main(args: Array[String]): Unit = { + val foldable = new Foldable[Option] { + def foldLeft[A, B](fa: Option[A], z: B)(f: (B, A) => B): B = fa.fold(z)(f(z, _)) + } + println(foldable.foldLeft(Some("abc"), "=")(_ + _)) + println(foldable.foldLeft(None, "=")(_ + _)) + } +} diff --git a/functional-tests/src/test/trait-extending-new-trait-with-concrete-method-ok/testAppRun-2.11.pending b/functional-tests/src/test/trait-extending-new-trait-with-concrete-method-ok/testAppRun-2.11.pending new file mode 100644 index 00000000..e69de29b diff --git a/functional-tests/src/test/trait-inheriting-from-class-nok/app/App.scala b/functional-tests/src/test/trait-inheriting-from-class-nok/app/App.scala new file mode 100644 index 00000000..64e424dc --- /dev/null +++ b/functional-tests/src/test/trait-inheriting-from-class-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo(10) + 1) + } +} diff --git a/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/app/App.scala b/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/app/App.scala new file mode 100644 index 00000000..95f4f5ee --- /dev/null +++ b/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/app/App.scala @@ -0,0 +1,10 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.useAfoo(new A {}) + 11) + println(Usage.useAbar(new A {}) + 12) + println(Usage.useAfoo(new B {}) + 13) + println(Usage.useAbar(new B {}) + 14) + println(Usage.useBfoo(new B {}) + 15) + println(Usage.useBbar(new B {}) + 16) + } +} diff --git a/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v1/A.scala b/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v1/A.scala index 0c762fce..8175d6ab 100644 --- a/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v1/A.scala +++ b/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v1/A.scala @@ -1,2 +1,9 @@ trait A trait B extends A + +object Usage { + def useAfoo(a: A) = 1 + def useAbar(a: A) = 2 + def useBfoo(b: B) = 3 + def useBbar(b: B) = 4 +} diff --git a/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v2/A.scala b/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v2/A.scala index c6699f3d..db3eeb39 100644 --- a/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v2/A.scala +++ b/functional-tests/src/test/trait-inherits-new-trait-with-abstract-method-nok/v2/A.scala @@ -4,3 +4,10 @@ trait AA { } trait A extends AA trait B extends A + +object Usage { + def useAfoo(a: A) = a.foo + 1 + def useAbar(a: A) = a.bar + 2 + def useBfoo(b: B) = b.foo + 3 + def useBbar(b: B) = b.bar + 4 +} diff --git a/functional-tests/src/test/trait-inherits-new-trait-with-concrete-method-ok/app/App.scala b/functional-tests/src/test/trait-inherits-new-trait-with-concrete-method-ok/app/App.scala new file mode 100644 index 00000000..c26c0da3 --- /dev/null +++ b/functional-tests/src/test/trait-inherits-new-trait-with-concrete-method-ok/app/App.scala @@ -0,0 +1,8 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}) + println(new B {}) + val ba: A = new B {} + println(ba) + } +} diff --git a/functional-tests/src/test/trait-inherits-new-trait-with-concrete-method-ok/testAppRun-2.11.pending b/functional-tests/src/test/trait-inherits-new-trait-with-concrete-method-ok/testAppRun-2.11.pending new file mode 100644 index 00000000..e69de29b diff --git a/functional-tests/src/test/trait-method-overloading-is-ok/app/App.scala b/functional-tests/src/test/trait-method-overloading-is-ok/app/App.scala new file mode 100644 index 00000000..48700022 --- /dev/null +++ b/functional-tests/src/test/trait-method-overloading-is-ok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo(1)) + } +} diff --git a/functional-tests/src/test/trait-method-overloading-is-ok/testAppRun-2.11.pending b/functional-tests/src/test/trait-method-overloading-is-ok/testAppRun-2.11.pending new file mode 100644 index 00000000..e69de29b diff --git a/functional-tests/src/test/trait-moving-methods-nok/app/App.scala b/functional-tests/src/test/trait-moving-methods-nok/app/App.scala new file mode 100644 index 00000000..69cc04ac --- /dev/null +++ b/functional-tests/src/test/trait-moving-methods-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo + 1) + } +} diff --git a/functional-tests/src/test/trait-moving-methods2-nok/app/App.scala b/functional-tests/src/test/trait-moving-methods2-nok/app/App.scala new file mode 100644 index 00000000..d5091c0e --- /dev/null +++ b/functional-tests/src/test/trait-moving-methods2-nok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A {}.foo + 10) + println(new A {}.bar + 11) + } +} diff --git a/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/app/App.scala b/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/app/App.scala new file mode 100644 index 00000000..ca6ec6a4 --- /dev/null +++ b/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(Usage.use(new A {}) + 1) + } +} diff --git a/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v1/A.scala b/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v1/A.scala index 3a75747f..d5b18d95 100644 --- a/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v1/A.scala +++ b/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v1/A.scala @@ -4,4 +4,8 @@ trait A trait B extends A { def foo: Int -} \ No newline at end of file +} + +object Usage { + def use(a: A): Int = 0 +} diff --git a/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v2/A.scala b/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v2/A.scala index 783d39d3..fa0a131a 100644 --- a/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v2/A.scala +++ b/functional-tests/src/test/trait-pushing-up-abstract-methods-is-nok/v2/A.scala @@ -4,4 +4,8 @@ trait A { -trait B extends A \ No newline at end of file +trait B extends A + +object Usage { + def use(a: A): Int = a.foo +} diff --git a/functional-tests/src/test/trait-pushing-up-concrete-methods-is-nok/app/App.scala b/functional-tests/src/test/trait-pushing-up-concrete-methods-is-nok/app/App.scala new file mode 100644 index 00000000..0e31151d --- /dev/null +++ b/functional-tests/src/test/trait-pushing-up-concrete-methods-is-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new B() {}.foo) + } +} diff --git a/functional-tests/src/test/trait-redeclaring-abstract-methods-in-subclass-is-ok/app/App.scala b/functional-tests/src/test/trait-redeclaring-abstract-methods-in-subclass-is-ok/app/App.scala new file mode 100644 index 00000000..5d647f0a --- /dev/null +++ b/functional-tests/src/test/trait-redeclaring-abstract-methods-in-subclass-is-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { def foo = 2 }.foo) + println(new B { def foo = 3 }.foo) + } +} diff --git a/functional-tests/src/test/trait-removing-abstract-method-declared-in-superclass-is-ok/app/App.scala b/functional-tests/src/test/trait-removing-abstract-method-declared-in-superclass-is-ok/app/App.scala new file mode 100644 index 00000000..5d647f0a --- /dev/null +++ b/functional-tests/src/test/trait-removing-abstract-method-declared-in-superclass-is-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + println(new A { def foo = 2 }.foo) + println(new B { def foo = 3 }.foo) + } +} diff --git a/functional-tests/src/test/trait-removing-class-type-from-inheritance-relationship-is-ok/app/App.scala b/functional-tests/src/test/trait-removing-class-type-from-inheritance-relationship-is-ok/app/App.scala new file mode 100644 index 00000000..edd1ca0d --- /dev/null +++ b/functional-tests/src/test/trait-removing-class-type-from-inheritance-relationship-is-ok/app/App.scala @@ -0,0 +1,16 @@ +object App { + def main(args: Array[String]): Unit = { + val a = new A {} + val ab: B = new A {} + val b = new B + val c = new C + val cb: B = new C + val ca: A = new C + println(a) + println(ab) + println(b) + println(c) + println(cb) + println(ca) + } +} diff --git a/functional-tests/src/test/trait-use-type-alias-in-new-version-ok/app/App.scala b/functional-tests/src/test/trait-use-type-alias-in-new-version-ok/app/App.scala new file mode 100644 index 00000000..85930588 --- /dev/null +++ b/functional-tests/src/test/trait-use-type-alias-in-new-version-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + val foo: Int = new A {}.foo + println(foo) + } +} diff --git a/functional-tests/src/test/tuple-parametric-type-change-nok/app/App.scala b/functional-tests/src/test/tuple-parametric-type-change-nok/app/App.scala new file mode 100644 index 00000000..5a67c53f --- /dev/null +++ b/functional-tests/src/test/tuple-parametric-type-change-nok/app/App.scala @@ -0,0 +1,10 @@ +object App { + def main(args: Array[String]): Unit = { + val (s, i) = new A().foo + val (ss: String, ii: Int) = (s, i) + println(s + "bar") + println(i + 1) + println(ss + "bar") + println(ii + 1) + } +} diff --git a/functional-tests/src/test/type-parameters-change-breaks-method-signature-nok/app/App.scala b/functional-tests/src/test/type-parameters-change-breaks-method-signature-nok/app/App.scala new file mode 100644 index 00000000..b42217c7 --- /dev/null +++ b/functional-tests/src/test/type-parameters-change-breaks-method-signature-nok/app/App.scala @@ -0,0 +1,5 @@ +object App { + def main(args: Array[String]): Unit = { + println(new Tree().contains(new NodeImpl)) + } +} diff --git a/functional-tests/src/test/value-class-added-concrete-method-ok/app/App.scala b/functional-tests/src/test/value-class-added-concrete-method-ok/app/App.scala new file mode 100644 index 00000000..6fa28edd --- /dev/null +++ b/functional-tests/src/test/value-class-added-concrete-method-ok/app/App.scala @@ -0,0 +1,6 @@ +object App { + def main(args: Array[String]): Unit = { + import A._ + println("foo".c(1)) + } +} diff --git a/functional-tests/src/test/value-class-generic-replacement-nok/app/App.scala b/functional-tests/src/test/value-class-generic-replacement-nok/app/App.scala new file mode 100644 index 00000000..ad124d21 --- /dev/null +++ b/functional-tests/src/test/value-class-generic-replacement-nok/app/App.scala @@ -0,0 +1,10 @@ +object App { + def main(args: Array[String]): Unit = { + val boxed = new Bar().boxedStringy + val unboxed = boxed.get + val string: String = boxed.get + println(boxed) + println(unboxed) + println(string) + } +} diff --git a/functional-tests/src/test/value-class-generic-replacement-nok/testAppRun-2.11.pending b/functional-tests/src/test/value-class-generic-replacement-nok/testAppRun-2.11.pending new file mode 100644 index 00000000..e69de29b diff --git a/project/TestsPlugin.scala b/project/TestsPlugin.scala index 2f964a94..570187a6 100644 --- a/project/TestsPlugin.scala +++ b/project/TestsPlugin.scala @@ -18,7 +18,8 @@ object TestsPlugin extends AutoPlugin { val testFunctional = taskKey[Unit]("Run the functional test") - val testCollectProblems = taskKey[Unit]("Run the 'collect problems' test") + val testCollectProblems = taskKey[Unit]("Test collecting problems") + val testAppRun = taskKey[Unit]("Test running the App, using library v2") } import autoImport._ @@ -29,14 +30,18 @@ object TestsPlugin extends AutoPlugin { ) override def projectSettings = Seq( - testFunctional := dependOnAll(funTestProjects, _ / Test / test).value, - IntegrationTest / test := dependOnAll(intTestProjects, _ / IntegrationTest / test).value, + testFunctional := dependOnAll(funTestProjects, Test / test).value, + testCollectProblems := dependOnAll(funTestProjects, testCollectProblems).value, + testAppRun := dependOnAll(funTestProjects, testAppRun).value, + IntegrationTest / test := dependOnAll(intTestProjects, IntegrationTest / test).value, ) private val functionalTests = LocalProject("functional-tests") - private val V1 = config("v1").extend(Compile) - private val V2 = config("v2").extend(Compile) + private val V1 = config("v1").extend(Compile) // Version 1 of a library + private val V2 = config("v2").extend(Compile) // Version 2 of a library + private val App = config("app").extend(V1) // An App, built against library v1 + private val App2 = config("app2").extend(V2, App) // The App, using library v2 private def testProjects(prefix: String, fileName: String, setup: Project => Project) = { (file("functional-tests") / "src" / prefix * dirContaining(fileName)).get().map { base => @@ -45,7 +50,7 @@ object TestsPlugin extends AutoPlugin { } private def intTestProject(p: Project) = p.settings(intTestProjectSettings) - private def funTestProject(p: Project) = p.settings(funTestProjectSettings).configs(V1, V2) + private def funTestProject(p: Project) = p.settings(funTestProjectSettings).configs(V1, V2, App, App2) private lazy val funTestProjects = testProjects("test", "problems.txt", funTestProject) private lazy val intTestProjects = testProjects( "it" , "test.conf" , intTestProject) @@ -55,6 +60,27 @@ object TestsPlugin extends AutoPlugin { scalaVersion := testScalaVersion.value, ) + private val oracleFile = Def.task { + val p = baseDirectory.value / "problems.txt" + val p211 = baseDirectory.value / "problems-2.11.txt" + val p212 = baseDirectory.value / "problems-2.12.txt" + scalaVersion.value.take(4) match { + case "2.11" => if (p211.exists()) p211 else if (p212.exists()) p212 else p + case "2.12" => if (p212.exists()) p212 else p + case _ => p + } + } + + private val oracleFileCheck = Def.setting { () => + // The test name is must match the expectations of problems.txt (only, not -2.11/-2.12.txt) + val emptyProblemsTxt = IO.readLines(baseDirectory.value / "problems.txt").forall(_.startsWith("#")) + name.value.takeRight(4).dropWhile(_ != '-') match { + case "-ok" => if (!emptyProblemsTxt) sys.error(s"[${name.value}] OK test with non-empty problems.txt") + case "-nok" => if (emptyProblemsTxt) sys.error(s"[${name.value}] NOK test with empty problems.txt") + case _ => sys.error(s"[${name.value}] Missing '-ok' or '-nok' suffix in project name") + } + } + private val runIntegrationTest = Def.task { val cp = (functionalTests / Compile / fullClasspath).value // the test classpath from the functionalTest project for the test val si = (functionalTests / scalaInstance).value // get a reference to the already loaded Scala classes so we get the advantage of a warm jvm @@ -65,7 +91,7 @@ object TestsPlugin extends AutoPlugin { val v1 = getArtifact(depRes, moduleBase % conf.getString("v1"), streams.value.log) val v2 = getArtifact(depRes, moduleBase % conf.getString("v2"), streams.value.log) streams.value.log.info(s"Comparing $v1 -> $v2") - runCollectProblemsTest(cp, si, name.value, v1, v2, baseDirectory.value, scalaVersion.value) + runCollectProblemsTest(cp, si, name.value, v1, v2, baseDirectory.value, oracleFile.value) streams.value.log.info(s"Test '${name.value}' succeeded.") } @@ -86,11 +112,32 @@ object TestsPlugin extends AutoPlugin { (V2 / compile).value: Unit val v1 = (V1 / classDirectory).value // compile the V1 sources and get the classes directory val v2 = (V2 / classDirectory).value // same for V2 - runCollectProblemsTest(cp, si, name.value, v1, v2, baseDirectory.value, scalaVersion.value) + runCollectProblemsTest(cp, si, name.value, v1, v2, baseDirectory.value, oracleFile.value) + } + + private val testAppRunImpl = Def.task { + val p = baseDirectory.value / "testAppRun.pending" + val p211 = baseDirectory.value / "testAppRun-2.11.pending" + val p212 = baseDirectory.value / "testAppRun-2.12.pending" + val pending = scalaVersion.value.take(4) match { + case "2.11" => p211.exists() || p212.exists() || p.exists() + case "2.12" => p212.exists() || p.exists() + case _ => p.exists() + } + (App / fgRun).toTask("").value + val result = (App2 / fgRun).toTask("").result.value + if (IO.read(oracleFile.value).isEmpty) { + if (!pending) Result.tryValue(result) + } else { + if (!pending) result.toEither.foreach { (_: Unit) => + throw new MessageOnlyException(s"Test '${name.value}' failed: expected running App to fail") + } + } } private val runFunctionalTest = Def.task { testCollectProblems.value + testAppRun.value streams.value.log.info(s"Test '${name.value}' succeeded.") } @@ -98,8 +145,17 @@ object TestsPlugin extends AutoPlugin { sharedTestProjectSettings, inConfig(V1)(funTestPerConfigSettings), inConfig(V2)(funTestPerConfigSettings), + inConfig(App)(funTestPerConfigSettings), + inConfig(App2)(Def.settings( + funTestPerConfigSettings, + internalDependencyClasspath --= (V1 / exportedProducts).value, // V2 only, drop V2 classes + run / mainClass := Some("App"), + run / trapExit := false, + )), testCollectProblems := testCollectProblemsImpl.value, + testAppRun := testAppRunImpl.value, Test / test := runFunctionalTest.value, + Global / onLoad += oracleFileCheck.value, ) private def runCollectProblemsTest( @@ -109,7 +165,7 @@ object TestsPlugin extends AutoPlugin { oldJarOrDir: File, newJarOrDir: File, projectPath: File, - scalaVersion: String, + oracleFile: File, ): Unit = { val loader = new URLClassLoader(Attributed.data(cp).map(_.toURI.toURL).toArray, si.loader) @@ -121,7 +177,7 @@ object TestsPlugin extends AutoPlugin { oldJarOrDir: File, newJarOrDir: File, baseDir: File, - scalaVersion: String, + oracleFile: File, ): Unit }] @@ -130,7 +186,7 @@ object TestsPlugin extends AutoPlugin { try { import scala.language.reflectiveCalls - testRunner.runTest(testClasspath, testName, oldJarOrDir, newJarOrDir, projectPath, scalaVersion) + testRunner.runTest(testClasspath, testName, oldJarOrDir, newJarOrDir, projectPath, oracleFile) } catch { case e: Exception => Console.err.println(e.toString) @@ -158,10 +214,10 @@ object TestsPlugin extends AutoPlugin { } } - private def dependOnAll(projects: Seq[Project], f: Project => TaskKey[Unit]): Def.Initialize[Task[Unit]] = + private def dependOnAll(projects: Seq[Project], task: TaskKey[Unit]): Def.Initialize[Task[Unit]] = Def.taskDyn { val structure = Project.structure(state.value) - val allTasks = projects.flatMap(p => f(p).get(structure.data)) + val allTasks = projects.flatMap(p => (p / task).get(structure.data)) Def.task(allTasks.join.map(_ => ()).value) }