diff options
Diffstat (limited to 'test')
43 files changed, 474 insertions, 48 deletions
diff --git a/test/benchmarks/src/scala/collection/parallel/benchmarks/misc/Coder.scala b/test/benchmarks/src/scala/collection/parallel/benchmarks/misc/Coder.scala index 9cc1f4a0f6..04e37085b8 100644 --- a/test/benchmarks/src/scala/collection/parallel/benchmarks/misc/Coder.scala +++ b/test/benchmarks/src/scala/collection/parallel/benchmarks/misc/Coder.scala @@ -16,7 +16,7 @@ class SeqCoder(words: List[String]) { '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ") - /** Invert the mnemnonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ + /** Invert the mnemonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ private val charCode: Map[Char, Char] = for ((digit, letters) <- m; letter <- letters) yield letter -> digit @@ -63,7 +63,7 @@ class ParCoder(words: List[String]) { '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ") - /** Invert the mnemnonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ + /** Invert the mnemonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ private val charCode: Map[Char, Char] = for ((digit, letters) <- m; letter <- letters) yield letter -> digit diff --git a/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/SequentialOps.scala b/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/SequentialOps.scala index ba32036002..9300851b5f 100644 --- a/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/SequentialOps.scala +++ b/test/benchmarks/src/scala/collection/parallel/benchmarks/parallel_array/SequentialOps.scala @@ -425,7 +425,7 @@ trait SequentialOps[T] { } def sequentialDiff(sq: Seq[T], sz: Int) = { - val occmap = occurences(sq) + val occmap = occurrences(sq) val b = new collection.mutable.ArrayBuffer[T] var i = 0 @@ -442,7 +442,7 @@ trait SequentialOps[T] { } def sequentialIntersect(sq: Seq[T], sz: Int) = { - val occmap = occurences(sq) + val occmap = occurrences(sq) val b = new collection.mutable.ArrayBuffer[T] var i = 0 @@ -461,7 +461,7 @@ trait SequentialOps[T] { res } - private def occurences(sq: Seq[T]) = { + private def occurrences(sq: Seq[T]) = { val occmap = new collection.mutable.HashMap[T, Int] { override def default(k: T) = 0 } for (elem <- sq.iterator) occmap(elem) += 1 occmap diff --git a/test/disabled/coder/Coder.scala b/test/disabled/coder/Coder.scala index 4e29c2a6ee..62b99e0cf0 100644 --- a/test/disabled/coder/Coder.scala +++ b/test/disabled/coder/Coder.scala @@ -10,7 +10,7 @@ class SeqCoder(words: List[String]) { '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ") - /** Invert the mnemnonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ + /** Invert the mnemonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ private val charCode: Map[Char, Char] = for ((digit, letters) <- m; letter <- letters) yield letter -> digit @@ -65,7 +65,7 @@ class ParCoder(words: List[String]) { '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ") - /** Invert the mnemnonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ + /** Invert the mnemonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ private val charCode: Map[Char, Char] = for ((digit, letters) <- m; letter <- letters) yield letter -> digit diff --git a/test/disabled/run/coder2/Coder2.scala b/test/disabled/run/coder2/Coder2.scala index 43b2e9bcb8..c1ec70b842 100644 --- a/test/disabled/run/coder2/Coder2.scala +++ b/test/disabled/run/coder2/Coder2.scala @@ -10,7 +10,7 @@ class SeqCoder(words: List[String]) { '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ") - /** Invert the mnemnonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ + /** Invert the mnemonics map to give a map from chars 'A' ... 'Z' to '2' ... '9' */ private val charCode: Map[Char, Char] = for ((digit, letters) <- m; letter <- letters) yield letter -> digit diff --git a/test/files/jvm/javaReflection/Test.scala b/test/files/jvm/javaReflection/Test.scala index ae5a36eeb2..199399fec8 100644 --- a/test/files/jvm/javaReflection/Test.scala +++ b/test/files/jvm/javaReflection/Test.scala @@ -31,7 +31,7 @@ getSimpleName / getCanonicalName / isAnonymousClass / isLocalClass / isSynthetic These should be avoided, they yield unexpected results: - isAnonymousClass is always false. Scala-defined classes are never anonymous for Java - reflection. Java reflection insepects the class name to decide whether a class is + reflection. Java reflection inspects the class name to decide whether a class is anonymous, based on the name spec referenced above. Also, the implementation of "isAnonymousClass" calls "getSimpleName", which may throw. diff --git a/test/files/jvm/protectedacc.scala b/test/files/jvm/protectedacc.scala index 89e70b90d8..43d218fa89 100644 --- a/test/files/jvm/protectedacc.scala +++ b/test/files/jvm/protectedacc.scala @@ -74,7 +74,7 @@ package p { package b { import a._; - /** Test interraction with Scala inherited methods and currying. */ + /** Test interaction with Scala inherited methods and currying. */ class B extends A { class C { def m = { diff --git a/test/files/neg/macro-invalidshape.check b/test/files/neg/macro-invalidshape.check index aa694df6d6..5093b87598 100644 --- a/test/files/neg/macro-invalidshape.check +++ b/test/files/neg/macro-invalidshape.check @@ -8,8 +8,9 @@ macro [<static object>].<method name>[[<type args>]] or macro [<macro bundle>].<method name>[[<type args>]] def foo2(x: Any) = macro Impls.foo(null)(null) ^ -Macros_Test_2.scala:4: error: missing arguments for method foo in object Impls; -follow this method with `_' if you want to treat it as a partially applied function +Macros_Test_2.scala:4: error: missing argument list for method foo in object Impls +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `foo _` or `foo(_)(_)` instead of `foo`. def foo3(x: Any) = macro {2; Impls.foo} ^ Macros_Test_2.scala:7: error: macro implementation reference has wrong shape. required: diff --git a/test/files/neg/missing-arg-list.check b/test/files/neg/missing-arg-list.check new file mode 100644 index 0000000000..5a011c36f2 --- /dev/null +++ b/test/files/neg/missing-arg-list.check @@ -0,0 +1,21 @@ +missing-arg-list.scala:9: error: missing argument list for method id in trait T +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `id _` or `id(_)` instead of `id`. + val w = id + ^ +missing-arg-list.scala:10: error: missing argument list for method f in trait T +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `f _` or `f(_)(_)` instead of `f`. + val x = f + ^ +missing-arg-list.scala:11: error: missing argument list for method g in trait T +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `g _` or `g(_,_,_)` instead of `g`. + val y = g + ^ +missing-arg-list.scala:12: error: missing argument list for method h in trait T +Unapplied methods are only converted to functions when a function type is expected. +You can make this conversion explicit by writing `h _` or `h(_,_,_)(_)` instead of `h`. + val z = h + ^ +four errors found diff --git a/test/files/neg/missing-arg-list.scala b/test/files/neg/missing-arg-list.scala new file mode 100644 index 0000000000..c422dd32fe --- /dev/null +++ b/test/files/neg/missing-arg-list.scala @@ -0,0 +1,13 @@ + +trait T { + + def id(i: Int) = i + def f(i: Int)(j: Int) = i+j + def g(i: Int, j: Int, k: Int) = i+j+k + def h(i: Int, j: Int, k: Int)(implicit s: String) = s*(i+j+k) + + val w = id + val x = f + val y = g + val z = h +} diff --git a/test/files/neg/t5120.scala b/test/files/neg/t5120.scala index f28b2cfb4f..0df67bc09b 100644 --- a/test/files/neg/t5120.scala +++ b/test/files/neg/t5120.scala @@ -12,7 +12,7 @@ object Test { str.x1.length } } -// another way demonstrating the same underlying problem, as reported by roman kalukiewicz +// another way demonstrating the same underlying problem, as reported by Roman Kalukiewicz class Holder[_T](_f1 : _T, _f2 : _T) { type T = _T diff --git a/test/files/neg/t6895.check b/test/files/neg/t6895.check new file mode 100644 index 0000000000..df01031fff --- /dev/null +++ b/test/files/neg/t6895.check @@ -0,0 +1,6 @@ +t6895.scala:19: error: polymorphic expression cannot be instantiated to expected type; + found : [F3[F3_P]]Foo[F3] + required: Foo[[X3]Bar[[X1]String]] + val nok: Foo[({type L[X3] = Bar[M]})#L] = barFoo /* Type inference can't unify F with L */ + ^ +one error found diff --git a/test/files/neg/t6895.scala b/test/files/neg/t6895.scala new file mode 100644 index 0000000000..5fb20d8c61 --- /dev/null +++ b/test/files/neg/t6895.scala @@ -0,0 +1,26 @@ +trait Foo[F1[F1_P]] +trait Bar[F2[F2_P]] + +class Test { + def barFoo[F3[F3_P]]: Foo[F3] = ??? + + // Now we can define a couple of type aliases: + type M[X1] = String + type N[X2] = Bar[M] + + // val ok1: Foo[N] = barFoo + // Foo[?F3] <:< Foo[Test.this.N] + // [X2]Test.this.N[X2] <:< [F3_P]?F3[F3_P] + // Test.this.N[X2] <:< ?F3[X2] + // true, ?F3=N + + // val ok2: Foo[({type L[X] = Bar[M]})#L] = barFoo[N] + + val nok: Foo[({type L[X3] = Bar[M]})#L] = barFoo /* Type inference can't unify F with L */ + // Foo[?F3] <:< Foo[[X3]Bar[[X1]String]] + // [X3]Bar[[X1]String] <:< ?F3 + // [X3]Bar[[X1]String] <:< [F3_P]?F3[F3_P] + // Bar[[X1]String] <:< ?F3[X3] + // X3 <:< [X1]String + // false +} diff --git a/test/files/neg/t6895b.check b/test/files/neg/t6895b.check new file mode 100644 index 0000000000..565925127b --- /dev/null +++ b/test/files/neg/t6895b.check @@ -0,0 +1,9 @@ +t6895b.scala:20: error: could not find implicit value for parameter e: Foo[[X]Bar[[X]Or[String,X],X]] + implicitly[Foo[({type L[X] = Bar[StringOr, X]})#L]] + ^ +t6895b.scala:23: error: polymorphic expression cannot be instantiated to expected type; + found : [F[_]]Foo[[X(in type L)]Bar[F,X(in type L)]] + required: Foo[[X(in type L)]Bar[[X]Or[String,X],X(in type L)]] + barFoo(null) : Foo[({type L[X] = Bar[StringOr, X]})#L] + ^ +two errors found diff --git a/test/files/neg/t6895b.scala b/test/files/neg/t6895b.scala new file mode 100644 index 0000000000..c465065011 --- /dev/null +++ b/test/files/neg/t6895b.scala @@ -0,0 +1,39 @@ +trait Foo[F[_]] +trait Bar[F[_], A] + +trait Or[A, B] + +class Test { + implicit def orFoo[A]: Foo[({type L[X] = Or[A, X]})#L] = ??? + implicit def barFoo[F[_]](implicit f: Foo[F]): Foo[({type L[X] = Bar[F, X]})#L] = ??? + + // Now we can define a couple of type aliases: + type StringOr[X] = Or[String, X] + type BarStringOr[X] = Bar[StringOr, X] + + // ok + implicitly[Foo[BarStringOr]] + barFoo[StringOr](null) : Foo[BarStringOr] + barFoo(null) : Foo[BarStringOr] + + // nok + implicitly[Foo[({type L[X] = Bar[StringOr, X]})#L]] + // Let's write the application explicitly, and then + // compile with just this line enabled and -explaintypes. + barFoo(null) : Foo[({type L[X] = Bar[StringOr, X]})#L] + + // Foo[[X]Bar[F,X]] <: Foo[[X]Bar[[X]Or[String,X],X]]? + // Bar[[X]Or[String,X],X] <: Bar[F,X]? + // F[_] <: Or[String,_]? + // false + // false + // false + + // Note that the type annotation above is typechecked as + // Foo[[X]Bar[[X]Or[String,X],X]], ie the type alias `L` + // is eta expanded. + // + // This is done so that it does not escape its defining scope. + // However, one this is done, higher kinded inference + // no longer is able to unify F with `StringOr` (SI-2712) +} diff --git a/test/files/neg/t836.scala b/test/files/neg/t836.scala index 3633b816c6..4b86d04013 100644 --- a/test/files/neg/t836.scala +++ b/test/files/neg/t836.scala @@ -12,5 +12,5 @@ abstract class A { class B extends A { type MyObj = ObjImpl val myString: S = "hello" - val realString: String = myString // error: type missmatch + val realString: String = myString // error: type mismatch } diff --git a/test/files/neg/t8431.scala b/test/files/neg/t8431.scala index 032a1f394d..bc45bb62ae 100644 --- a/test/files/neg/t8431.scala +++ b/test/files/neg/t8431.scala @@ -48,7 +48,7 @@ class TestExplicit { {val c1 = convert2(s); c1.combined} } -// These ones work before and after; infering G=Null doesn't need to contribute an undetermined type param. +// These ones work before and after; inferring G=Null doesn't need to contribute an undetermined type param. class Test3 { import C.{cbf, convert1, convert2} val s: Invariant[Null] = ??? diff --git a/test/files/neg/t8777.check b/test/files/neg/t8777.check new file mode 100644 index 0000000000..cd05f1ec11 --- /dev/null +++ b/test/files/neg/t8777.check @@ -0,0 +1,6 @@ +t8777.scala:3: error: type mismatch; + found : Foo.this.TreePrinter(in trait Printers) + required: Foo.this.TreePrinter(in trait Printers) + super.newCodePrinter(out, tree, printRootPkg) + ^ +one error found diff --git a/test/files/neg/t8777.scala b/test/files/neg/t8777.scala new file mode 100644 index 0000000000..5b7d123202 --- /dev/null +++ b/test/files/neg/t8777.scala @@ -0,0 +1,4 @@ +trait Foo extends scala.tools.nsc.Global { + override def newCodePrinter(out: java.io.PrintWriter, tree: Tree, printRootPkg: Boolean): TreePrinter = + super.newCodePrinter(out, tree, printRootPkg) +} diff --git a/test/files/neg/t8892.check b/test/files/neg/t8892.check new file mode 100644 index 0000000000..5930be58c5 --- /dev/null +++ b/test/files/neg/t8892.check @@ -0,0 +1,7 @@ +t8892.scala:2: error: type mismatch; + found : B + required: C.this.B + (which expands to) String +class C[B](x: B) extends A { def f: B = x } + ^ +one error found diff --git a/test/files/neg/t8892.scala b/test/files/neg/t8892.scala new file mode 100644 index 0000000000..f857e6f115 --- /dev/null +++ b/test/files/neg/t8892.scala @@ -0,0 +1,2 @@ +trait A { type B = String } +class C[B](x: B) extends A { def f: B = x } diff --git a/test/files/neg/warn-unused-privates.scala b/test/files/neg/warn-unused-privates.scala index 2faa07e759..2eda280d40 100644 --- a/test/files/neg/warn-unused-privates.scala +++ b/test/files/neg/warn-unused-privates.scala @@ -21,7 +21,7 @@ class B3(msg0: String) extends A("msg") /*** Early defs warnings disabled primarily due to SI-6595. * The test case is here to assure we aren't issuing false positives; - * the ones labeled "warn" don't warn. + * the ones labelled "warn" don't warn. ***/ class Boppy extends { private val hmm: String = "abc" // no warn, used in early defs diff --git a/test/files/pos/t8947/Macro_1.scala b/test/files/pos/t8947/Macro_1.scala index 4a5de3decb..ace389f339 100644 --- a/test/files/pos/t8947/Macro_1.scala +++ b/test/files/pos/t8947/Macro_1.scala @@ -35,7 +35,7 @@ object X { // symtab.EmptyTree.setAttachments(symtab.NoPosition) // } // - // To make this visible to the macro implementaiton, it will need to be compiled in an earlier stage, + // To make this visible to the macro implementation, it will need to be compiled in an earlier stage, // e.g a separate SBT sub-project. } diff --git a/test/files/run/ReplacementMatching.scala b/test/files/run/ReplacementMatching.scala index 05040d98a3..81034aa510 100644 --- a/test/files/run/ReplacementMatching.scala +++ b/test/files/run/ReplacementMatching.scala @@ -32,12 +32,12 @@ object Test { def groupsMatching { val Date = """(\d+)/(\d+)/(\d+)""".r - for (Regex.Groups(a, b, c) <- Date findFirstMatchIn "1/1/2001 marks the start of the millenium. 31/12/2000 doesn't.") { + for (Regex.Groups(a, b, c) <- Date findFirstMatchIn "1/1/2001 marks the start of the millennium. 31/12/2000 doesn't.") { assert(a == "1") assert(b == "1") assert(c == "2001") } - for (Regex.Groups(a, b, c) <- (Date findAllIn "1/1/2001 marks the start of the millenium. 31/12/2000 doesn't.").matchData) { + for (Regex.Groups(a, b, c) <- (Date findAllIn "1/1/2001 marks the start of the millennium. 31/12/2000 doesn't.").matchData) { assert(a == "1" || a == "31") assert(b == "1" || b == "12") assert(c == "2001" || c == "2000") diff --git a/test/files/run/blame_eye_triple_eee-double.check b/test/files/run/blame_eye_triple_eee-double.check index 5e46d91a8f..53eac99ecd 100644 --- a/test/files/run/blame_eye_triple_eee-double.check +++ b/test/files/run/blame_eye_triple_eee-double.check @@ -6,4 +6,4 @@ if (x != x) is good if (NaN != x) is good x matching was good NaN matching was good -loop with NaN was goood +loop with NaN was good diff --git a/test/files/run/blame_eye_triple_eee-double.scala b/test/files/run/blame_eye_triple_eee-double.scala index 1640aead40..4dcbfe7a7a 100644 --- a/test/files/run/blame_eye_triple_eee-double.scala +++ b/test/files/run/blame_eye_triple_eee-double.scala @@ -56,6 +56,6 @@ object Test extends App { else z = NaN i += 1 } - if (z.isNaN && i == 10) println("loop with NaN was goood") + if (z.isNaN && i == 10) println("loop with NaN was good") else println("loop with NaN was broken") } diff --git a/test/files/run/blame_eye_triple_eee-float.check b/test/files/run/blame_eye_triple_eee-float.check index 5e46d91a8f..53eac99ecd 100644 --- a/test/files/run/blame_eye_triple_eee-float.check +++ b/test/files/run/blame_eye_triple_eee-float.check @@ -6,4 +6,4 @@ if (x != x) is good if (NaN != x) is good x matching was good NaN matching was good -loop with NaN was goood +loop with NaN was good diff --git a/test/files/run/blame_eye_triple_eee-float.scala b/test/files/run/blame_eye_triple_eee-float.scala index 4deb9f3d60..bcc6b195d5 100644 --- a/test/files/run/blame_eye_triple_eee-float.scala +++ b/test/files/run/blame_eye_triple_eee-float.scala @@ -56,6 +56,6 @@ object Test extends App { else z = NaN i += 1 } - if (z.isNaN && i == 10) println("loop with NaN was goood") + if (z.isNaN && i == 10) println("loop with NaN was good") else println("loop with NaN was broken") } diff --git a/test/files/run/finally.check b/test/files/run/finally.check index 901a797426..b0f2293d11 100644 --- a/test/files/run/finally.check +++ b/test/files/run/finally.check @@ -29,7 +29,7 @@ body in finally java.lang.Exception ---------------------------------------- -Running nestedFinalies +Running nestedFinallyBlocks in finally 1 in finally 2 ---------------------------------------- diff --git a/test/files/run/finally.scala b/test/files/run/finally.scala index b66354ca03..467c9e5868 100644 --- a/test/files/run/finally.scala +++ b/test/files/run/finally.scala @@ -94,7 +94,7 @@ object Test extends App { } // nested finally blocks with return value - def nestedFinalies: Int = + def nestedFinallyBlocks: Int = try { try { return 10 @@ -123,5 +123,5 @@ object Test extends App { test(throwBody, "throwBody") test(retFinally, "retFinally") test(throwFinally, "throwFinally") - test(nestedFinalies, "nestedFinalies") + test(nestedFinallyBlocks, "nestedFinallyBlocks") } diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index c364425ec9..7fb4a04546 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -239,7 +239,7 @@ object Test extends App { // result type of default getters: parameter type, except if this one mentions any type // parameter, in which case the result type is inferred. examples: - // result type of default getter is "String => String". if it were infered, the compiler + // result type of default getter is "String => String". if it were inferred, the compiler // would put "Nothing => Nothing", which is useless def transform(s: String, f: String => String = identity _) = f(s) println(transform("my text")) diff --git a/test/files/run/sbt-icode-interface.scala b/test/files/run/sbt-icode-interface.scala new file mode 100644 index 0000000000..84d38cc65a --- /dev/null +++ b/test/files/run/sbt-icode-interface.scala @@ -0,0 +1,42 @@ +import scala.tools.partest._ +import scala.tools.nsc._ + +object Test extends DirectTest { + + def code = """ + class C { class D } + object O + """.trim + + def show() { + for (b <- List("GenASM", "GenBCode")) { + val global = newCompiler("-usejavacp", s"-Ybackend:$b") + import global._ + val r = new Run + r.compileSources(newSourceFile(code) :: Nil) + + val results = collection.mutable.Buffer[(Boolean, String)]() + + // Nailing down defacto compiler API from SBT's usage + // https://github.com/sbt/sbt/blob/adb41611cf73260938274915d8462d924df200c8/compile/interface/src/main/scala/xsbt/Analyzer.scala#L29-L41 + def isTopLevelModule(sym: Symbol) = sym.isTopLevel && sym.isModule + for (unit <- currentRun.units if !unit.isJava) { + val sourceFile = unit.source.file.file + for (iclass <- unit.icode) { + val sym = iclass.symbol + def addGenerated(separatorRequired: Boolean) { + results += (separatorRequired -> sym.fullName) + } + if (sym.isModuleClass && !sym.isImplClass) { + if (isTopLevelModule(sym) && sym.companionClass == NoSymbol) + addGenerated(false) + addGenerated(true) + } else + addGenerated(false) + } + } + val expected = List((false, "C"), (true, "O"), (false, "C$D")) + assert(results.toList == expected, b + ": " + results.toList) + } + } +} diff --git a/test/files/run/t0631.scala b/test/files/run/t0631.scala index c401ed31cb..8d672574ec 100644 --- a/test/files/run/t0631.scala +++ b/test/files/run/t0631.scala @@ -11,6 +11,6 @@ object Test extends App { case class Bar(x: Foo) val b = new Bar(new Foo) - // this should not call Foo.equals, but simply compare object identiy of b + // this should not call Foo.equals, but simply compare object identity of b println(b == b) } diff --git a/test/files/run/t2526.scala b/test/files/run/t2526.scala index 53f3059135..9f3c48ec61 100644 --- a/test/files/run/t2526.scala +++ b/test/files/run/t2526.scala @@ -38,7 +38,7 @@ object Test { /* * Checks foreach of `actual` goes over all the elements in `expected` - * We duplicate the method above because there is no common inteface between Traversable and + * We duplicate the method above because there is no common interface between Traversable and * Iterator and we want to avoid converting between collections to ensure that we test what * we mean to test. */ diff --git a/test/files/run/t6440b.scala b/test/files/run/t6440b.scala index 974aca2844..7ab9529ccb 100644 --- a/test/files/run/t6440b.scala +++ b/test/files/run/t6440b.scala @@ -35,7 +35,7 @@ object Test extends StoreReporterDirectTest { def app2 = """ package pack3 object Test { - pack2.V.u.t // we have to fail if T.class is misisng + pack2.V.u.t // we have to fail if T.class is missing } """ diff --git a/test/files/run/t7817-tree-gen.scala b/test/files/run/t7817-tree-gen.scala index a8317fda6e..094c0d6289 100644 --- a/test/files/run/t7817-tree-gen.scala +++ b/test/files/run/t7817-tree-gen.scala @@ -1,6 +1,6 @@ import scala.tools.partest._ -// Testing that `mkAttributedRef` doesn't incude the package object test.`package`, +// Testing that `mkAttributedRef` doesn't include the package object test.`package`, // under joint and separate compilation. package testSep { class C { object O } } diff --git a/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala b/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala index a3b6137f68..40fb42d63c 100644 --- a/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala +++ b/test/files/scalacheck/quasiquotes/RuntimeErrorProps.scala @@ -68,7 +68,7 @@ object RuntimeErrorProps extends QuasiquoteProperties("errors") { q"for(..$enums) 0" } - property("for inlalid enum") = testFails { + property("for invalid enum") = testFails { val enums = q"foo" :: Nil q"for(..$enums) 0" } diff --git a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala b/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala index d0ffd06b01..ee9580c1c3 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala @@ -6,7 +6,7 @@ import scala.collection.mutable.ListBuffer import scala.reflect.internal.util.BatchSourceFile import scala.reflect.io.VirtualDirectory import scala.tools.asm.Opcodes -import scala.tools.asm.tree.{ClassNode, MethodNode} +import scala.tools.asm.tree.{AbstractInsnNode, ClassNode, MethodNode} import scala.tools.cmd.CommandLineParser import scala.tools.nsc.io.AbstractFile import scala.tools.nsc.reporters.StoreReporter @@ -15,6 +15,7 @@ import scala.tools.nsc.{Settings, Global} import scala.tools.partest.ASMConverters import scala.collection.JavaConverters._ import scala.tools.testing.TempDir +import AsmUtils._ object CodeGenTools { import ASMConverters._ @@ -151,6 +152,17 @@ object CodeGenTools { def getSingleMethod(classNode: ClassNode, name: String): Method = convertMethod(classNode.methods.asScala.toList.find(_.name == name).get) + /** + * Instructions that match `query` when textified. + * If `query` starts with a `+`, the next instruction is returned. + */ + def findInstr(method: MethodNode, query: String): List[AbstractInsnNode] = { + val useNext = query(0) == '+' + val instrPart = if (useNext) query.drop(1) else query + val insns = method.instructions.iterator.asScala.find(i => textify(i) contains instrPart).toList + if (useNext) insns.map(_.getNext) else insns + } + def assertHandlerLabelPostions(h: ExceptionHandler, instructions: List[Instruction], startIndex: Int, endIndex: Int, handlerIndex: Int): Unit = { val insVec = instructions.toVector assertTrue(h.start == insVec(startIndex) && h.end == insVec(endIndex) && h.handler == insVec(handlerIndex)) diff --git a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala index 4086f7dd7b..240d3523f1 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala @@ -28,7 +28,7 @@ class DirectCompileTest extends ClearAfterClass { |} """.stripMargin) def s(i: Int, n: Int) = (bytes(i) & 0xff) << n - assertTrue((s(0, 24) | s(1, 16) | s(2, 8) | s(3, 0)) == 0xcafebabe) // mocha java latte machiatto surpreme dark roasted espresso + assertTrue((s(0, 24) | s(1, 16) | s(2, 8) | s(3, 0)) == 0xcafebabe) // mocha java latte macchiato surpreme dark roasted espresso } @Test diff --git a/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala index 3a85f03da2..94e776aadb 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/NullnessAnalyzerTest.scala @@ -38,17 +38,6 @@ class NullnessAnalyzerTest extends ClearAfterClass { nullnessAnalyzer } - /** - * Instructions that match `query` when textified. - * If `query` starts with a `+`, the next instruction is returned. - */ - def findInstr(method: MethodNode, query: String): List[AbstractInsnNode] = { - val useNext = query(0) == '+' - val instrPart = if (useNext) query.drop(1) else query - val insns = method.instructions.iterator.asScala.find(i => textify(i) contains instrPart).toList - if (useNext) insns.map(_.getNext) else insns - } - def testNullness(analyzer: NullnessAnalyzer, method: MethodNode, query: String, index: Int, nullness: Nullness): Unit = { for (i <- findInstr(method, query)) { val r = analyzer.frameAt(i, method).getValue(index).nullness diff --git a/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala new file mode 100644 index 0000000000..9af9ef54fc --- /dev/null +++ b/test/junit/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerTest.scala @@ -0,0 +1,249 @@ +package scala.tools.nsc +package backend.jvm +package analysis + +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.Assert._ + +import scala.tools.asm.Opcodes +import scala.tools.asm.tree.AbstractInsnNode +import scala.tools.partest.ASMConverters._ +import scala.tools.testing.ClearAfterClass +import CodeGenTools._ +import AsmUtils._ + +object ProdConsAnalyzerTest extends ClearAfterClass.Clearable { + var noOptCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none") + + def clear(): Unit = { + noOptCompiler = null + } +} + +@RunWith(classOf[JUnit4]) +class ProdConsAnalyzerTest extends ClearAfterClass { + ClearAfterClass.stateToClear = ProdConsAnalyzerTest + val noOptCompiler = ProdConsAnalyzerTest.noOptCompiler + + def prodToString(producer: AbstractInsnNode) = producer match { + case p: InitialProducer => p.toString + case p => textify(p) + } + + def testSingleInsn(singletonInsns: Traversable[AbstractInsnNode], expected: String): Unit = { + testInsn(single(singletonInsns), expected) + } + + def testMultiInsns(insns: Traversable[AbstractInsnNode], expected: Traversable[String]): Unit = { + assertTrue(s"Sizes don't match: ${insns.size} vs ${expected.size}", insns.size == expected.size) + for (insn <- insns) { + val txt = prodToString(insn) + assertTrue(s"Instruction $txt not found in ${expected mkString ", "}", expected.exists(txt.contains)) + } + } + + def testInsn(insn: AbstractInsnNode, expected: String): Unit = { + val txt = prodToString(insn) + assertTrue(s"Expected $expected, found $txt", txt contains expected) + } + + def single[T](c: Traversable[T]): T = { + assertTrue(s"Expected singleton collection, got $c", c.size == 1) + c.head + } + + @Test + def parameters(): Unit = { + val List(m) = compileMethods(noOptCompiler)("def f = this.toString") + val a = new ProdConsAnalyzer(m, "C") + val call = findInstr(m, "INVOKEVIRTUAL").head + + testSingleInsn(a.producersForValueAt(call, 1), "ALOAD 0") // producer of stack value + testSingleInsn(a.producersForInputsOf(call), "ALOAD 0") + + testSingleInsn(a.consumersOfValueAt(call.getNext, 1), "ARETURN") // consumer of `toString` result + testSingleInsn(a.consumersOfOutputsFrom(call), "ARETURN") + + testSingleInsn(a.ultimateConsumersOfValueAt(call.getNext, 1), "ARETURN") + + testSingleInsn(a.initialProducersForValueAt(call, 1), "ParameterProducer") + testSingleInsn(a.producersForValueAt(call, 0), "ParameterProducer") + } + + @Test + def parametersInitialProducer(): Unit = { + // mutates a parameter local (not possible in scala, but in bytecode) + import Opcodes._ + val m = genMethod(descriptor = "(I)I")( + Label(0), + VarOp(ILOAD, 1), + Jump(IFNE, Label(1)), + Op(ICONST_1), + VarOp(ISTORE, 1), + Label(1), + VarOp(ILOAD, 1), + Op(IRETURN), + Label(2) + ) + m.maxLocals = 2 + m.maxStack = 1 + val a = new ProdConsAnalyzer(m, "C") + + val ifne = findInstr(m, "IFNE").head + testSingleInsn(a.producersForValueAt(ifne, 1), "ParameterProducer") + + val ret = findInstr(m, "IRETURN").head + testMultiInsns(a.producersForValueAt(ret, 1), List("ParameterProducer", "ISTORE 1")) + } + + @Test + def branching(): Unit = { + val List(m) = compileMethods(noOptCompiler)("def f(x: Int) = { var a = x; if (a == 0) a = 12; a }") + val a = new ProdConsAnalyzer(m, "C") + + val List(ret) = findInstr(m, "IRETURN") + testMultiInsns(a.producersForValueAt(ret, 2), List("ISTORE 2", "ISTORE 2")) + testMultiInsns(a.initialProducersForValueAt(ret, 2), List("BIPUSH 12", "ParameterProducer")) + + val List(bipush) = findInstr(m, "BIPUSH 12") + testSingleInsn(a.consumersOfOutputsFrom(bipush), "ISTORE 2") + testSingleInsn(a.ultimateConsumersOfValueAt(bipush.getNext, 3), "IRETURN") + } + + @Test + def checkCast(): Unit = { + val List(m) = compileMethods(noOptCompiler)("def f(o: Object) = o.asInstanceOf[String]") + val a = new ProdConsAnalyzer(m, "C") + assert(findInstr(m, "CHECKCAST java/lang/String").length == 1) + + val List(ret) = findInstr(m, "ARETURN") + testSingleInsn(a.initialProducersForInputsOf(ret), "ParameterProducer(1)") + } + + @Test + def instanceOf(): Unit = { + val List(m) = compileMethods(noOptCompiler)("def f(o: Object) = o.isInstanceOf[String]") + val a = new ProdConsAnalyzer(m, "C") + assert(findInstr(m, "INSTANCEOF java/lang/String").length == 1) + + val List(ret) = findInstr(m, "IRETURN") + testSingleInsn(a.initialProducersForInputsOf(ret), "INSTANCEOF") + } + + @Test + def unInitLocal(): Unit = { + val List(m) = compileMethods(noOptCompiler)("def f(b: Boolean) = { if (b) { var a = 0; println(a) }; 1 }") + val a = new ProdConsAnalyzer(m, "C") + + val List(store) = findInstr(m, "ISTORE") + val List(call) = findInstr(m, "INVOKEVIRTUAL") + val List(ret) = findInstr(m, "IRETURN") + + testSingleInsn(a.producersForValueAt(store, 2), "UninitializedLocalProducer(2)") + testSingleInsn(a.producersForValueAt(call, 2), "ISTORE") + testMultiInsns(a.producersForValueAt(ret, 2), List("UninitializedLocalProducer", "ISTORE")) + } + + @Test + def dupCopying(): Unit = { + val List(m) = compileMethods(noOptCompiler)("def f = new Object") + val a = new ProdConsAnalyzer(m, "C") + + val List(newO) = findInstr(m, "NEW") + val List(constr) = findInstr(m, "INVOKESPECIAL") + + testSingleInsn(a.producersForInputsOf(constr), "DUP") + testSingleInsn(a.initialProducersForInputsOf(constr), "NEW") + + testSingleInsn(a.consumersOfOutputsFrom(newO), "DUP") + testMultiInsns(a.ultimateConsumersOfOutputsFrom(newO), List("INVOKESPECIAL", "ARETURN")) + } + + @Test + def multiProducer(): Unit = { + import Opcodes._ + val m = genMethod(descriptor = "(I)I")( + VarOp(ILOAD, 1), + VarOp(ILOAD, 1), + Op(DUP2), + Op(IADD), + Op(SWAP), + VarOp(ISTORE, 1), + Op(IRETURN) + ) + m.maxLocals = 2 + m.maxStack = 4 + val a = new ProdConsAnalyzer(m, "C") + + val List(dup2) = findInstr(m, "DUP2") + val List(add) = findInstr(m, "IADD") + val List(swap) = findInstr(m, "SWAP") + val List(store) = findInstr(m, "ISTORE") + val List(ret) = findInstr(m, "IRETURN") + + testMultiInsns(a.producersForInputsOf(dup2), List("ILOAD", "ILOAD")) + testSingleInsn(a.consumersOfValueAt(dup2.getNext, 4), "IADD") + testSingleInsn(a.consumersOfValueAt(dup2.getNext, 5), "IADD") + testMultiInsns(a.consumersOfOutputsFrom(dup2), List("IADD", "SWAP")) + + testSingleInsn(a.ultimateConsumersOfOutputsFrom(dup2), "IADD") // the 'store' is not here: it's a copying instr, so not an ultimate consumer. + testMultiInsns(a.consumersOfOutputsFrom(swap), List("IRETURN", "ISTORE")) + testSingleInsn(a.ultimateConsumersOfOutputsFrom(swap), "IRETURN") // again, no store + testSingleInsn(a.initialProducersForInputsOf(add), "ParameterProducer(1)") + + testMultiInsns(a.producersForInputsOf(swap), List("IADD", "DUP2")) + testSingleInsn(a.consumersOfValueAt(swap.getNext, 4), "ISTORE") + testSingleInsn(a.consumersOfValueAt(swap.getNext, 3), "IRETURN") + testSingleInsn(a.initialProducersForInputsOf(store), "ParameterProducer(1)") + testSingleInsn(a.initialProducersForInputsOf(ret), "IADD") + } + + @Test + def iincProdCons(): Unit = { + import Opcodes._ + val m = genMethod(descriptor = "(I)I")( + Incr(IINC, 1, 1), // producer and cosumer of local variable 1 + VarOp(ILOAD, 1), + Op(IRETURN) + ) + m.maxLocals = 2 + m.maxStack = 1 + val a = new ProdConsAnalyzer(m, "C") + + val List(inc) = findInstr(m, "IINC") + val List(load) = findInstr(m, "ILOAD") + val List(ret) = findInstr(m, "IRETURN") + + testSingleInsn(a.producersForInputsOf(inc), "ParameterProducer(1)") + testSingleInsn(a.consumersOfOutputsFrom(inc), "ILOAD") + testSingleInsn(a.ultimateConsumersOfOutputsFrom(inc), "IRETURN") + testSingleInsn(a.consumersOfValueAt(inc, 1), "IINC") // parameter value has a single consumer, the IINC + testSingleInsn(a.ultimateConsumersOfValueAt(inc, 1), "IINC") + + testSingleInsn(a.producersForInputsOf(load), "IINC") + testSingleInsn(a.producersForValueAt(load, 1), "IINC") + + testSingleInsn(a.initialProducersForInputsOf(ret), "IINC") + } + + @Test + def copyingInsns(): Unit = { + val List(m) = compileMethods(noOptCompiler)("def f = 0l.asInstanceOf[Int]") + val a = new ProdConsAnalyzer(m, "C") + + val List(cnst) = findInstr(m, "LCONST_0") + val List(l2i) = findInstr(m, "L2I") // l2i is not a copying instruction + val List(ret) = findInstr(m, "IRETURN") + + testSingleInsn(a.consumersOfOutputsFrom(cnst), "L2I") + testSingleInsn(a.ultimateConsumersOfOutputsFrom(cnst), "L2I") + + testSingleInsn(a.producersForInputsOf(l2i), "LCONST_0") + testSingleInsn(a.initialProducersForInputsOf(l2i), "LCONST_0") + + testSingleInsn(a.consumersOfOutputsFrom(l2i), "IRETURN") + testSingleInsn(a.producersForInputsOf(ret), "L2I") + } +} diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala index b8c5f85c49..0309bb97cc 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala @@ -503,7 +503,7 @@ class InlinerTest extends ClearAfterClass { |class C extends T """.stripMargin val List(c, t, tClass) = compile(code) - // the static implementaiton method is inlined into the mixin, so there's no invocation in the mixin + // the static implementation method is inlined into the mixin, so there's no invocation in the mixin assertNoInvoke(getSingleMethod(c, "f")) } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala index 1ce1b88ff2..5ef2458c0a 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala @@ -56,7 +56,7 @@ class MethodLevelOpts extends ClearAfterClass { } @Test - def inlineReturnInCachtNotTry(): Unit = { + def inlineReturnInCatchNotTry(): Unit = { val code = "def f: Int = return { try 1 catch { case _: Throwable => 2 } }" // cannot inline the IRETURN into the try block (because RETURN may throw IllegalMonitorState) val m = singleMethod(methodOptCompiler)(code) diff --git a/test/junit/scala/tools/nsc/classpath/FlatClassPathResolverTest.scala b/test/junit/scala/tools/nsc/classpath/FlatClassPathResolverTest.scala index a37ba31b31..5dee488285 100644 --- a/test/junit/scala/tools/nsc/classpath/FlatClassPathResolverTest.scala +++ b/test/junit/scala/tools/nsc/classpath/FlatClassPathResolverTest.scala @@ -42,7 +42,7 @@ class FlatClassPathResolverTest { // In Java TemporaryFolder in JUnit is managed automatically using @Rule. // It would work also in Scala after adding and extending a class like // TestWithTempFolder.java containing it. But in this case it doesn't work when running tests - // from the command line - java class is not compiled due to some, misterious reasons. + // from the command line - java class is not compiled due to some, mysterious reasons. // That's why such dirs are here created and deleted manually. tempDir.create() tempDir.newFile("TestSourceInRootPackage.scala") |