diff options
Diffstat (limited to 'test')
62 files changed, 1221 insertions, 174 deletions
diff --git a/test/files/neg/macro-blackbox-fundep-materialization/Test_2.scala b/test/files/neg/macro-blackbox-fundep-materialization/Test_2.scala index a00f4ed7db..40ca1d549c 100644 --- a/test/files/neg/macro-blackbox-fundep-materialization/Test_2.scala +++ b/test/files/neg/macro-blackbox-fundep-materialization/Test_2.scala @@ -1,4 +1,4 @@ -// see the comments for macroExpandApply.onDelayed for an explanation of what's tested here +// see the comments for macroExpand.onDelayed for an explanation of what's tested here object Test extends App { case class Foo(i: Int, s: String, b: Boolean) def foo[C, L](c: C)(implicit iso: Iso[C, L]): L = iso.to(c) diff --git a/test/files/neg/macro-incompatible-macro-engine.check b/test/files/neg/macro-incompatible-macro-engine.check new file mode 100644 index 0000000000..1d582e5ed6 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine.check @@ -0,0 +1,7 @@ +Test_3.scala:2: error: macro cannot be expanded, because it was compiled by an incompatible macro engine vxxx (implemented in the incompatibleMacroEngine plugin) + Macros.foo + ^ +Test_3.scala:3: error: macro cannot be expanded, because it was compiled by an incompatible macro engine vxxx (implemented in the incompatibleMacroEngine plugin) + Macros.foo + ^ +two errors found diff --git a/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags b/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags new file mode 100644 index 0000000000..966df731d0 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Macros_2.flags @@ -0,0 +1 @@ +-Xplugin:.
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala b/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala new file mode 100644 index 0000000000..ad57a3cb36 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Macros_2.scala @@ -0,0 +1,7 @@ +import scala.language.experimental.macros +import scala.reflect.macros.BlackboxContext + +object Macros { + def impl(c: BlackboxContext) = c.universe.Literal(c.universe.Constant(())) + def foo: Unit = macro impl +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala b/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala new file mode 100644 index 0000000000..44ed91d2fb --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Plugin_1.scala @@ -0,0 +1,35 @@ +package incompatibleMacroEngine + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.{Plugin => NscPlugin} + +class Plugin(val global: Global) extends NscPlugin { + import global._ + import analyzer._ + + val name = "incompatibleMacroEngine" + val description = "A sample analyzer plugin that crafts a macro impl binding with a non-standard macro engine." + val components = Nil + addMacroPlugin(MacroPlugin) + + object MacroPlugin extends MacroPlugin { + def fixupBinding(tree: Tree) = new Transformer { + override def transform(tree: Tree) = { + tree match { + case Literal(const @ Constant(x)) if tree.tpe == null => tree setType ConstantType(const) + case _ if tree.tpe == null => tree setType NoType + case _ => ; + } + super.transform(tree) + } + }.transform(tree) + + override def pluginsTypedMacroBody(typer: Typer, ddef: DefDef): Option[Tree] = { + val result = standardTypedMacroBody(typer, ddef) + val List(AnnotationInfo(atp, List(Apply(nucleus, _ :: others)), Nil)) = ddef.symbol.annotations + val updatedBinding = Apply(nucleus, Assign(Literal(Constant("macroEngine")), Literal(Constant("vxxx (implemented in the incompatibleMacroEngine plugin)"))) :: others) + ddef.symbol.setAnnotations(List(AnnotationInfo(atp, List(fixupBinding(updatedBinding)), Nil))) + Some(result) + } + } +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/Test_3.scala b/test/files/neg/macro-incompatible-macro-engine/Test_3.scala new file mode 100644 index 0000000000..7e4fae5236 --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo + Macros.foo +}
\ No newline at end of file diff --git a/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml b/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml new file mode 100644 index 0000000000..42b9cdd75d --- /dev/null +++ b/test/files/neg/macro-incompatible-macro-engine/scalac-plugin.xml @@ -0,0 +1,4 @@ +<plugin> + <name>incompatible-macro-engine</name> + <classname>incompatibleMacroEngine.Plugin</classname> +</plugin>
\ No newline at end of file diff --git a/test/files/pos/t8120.scala b/test/files/pos/t8120.scala new file mode 100644 index 0000000000..e06f38d5db --- /dev/null +++ b/test/files/pos/t8120.scala @@ -0,0 +1,9 @@ +object A { + class C { + def m(a: Nothing): Int = 0 + } + implicit class RichAny(a: Any) { + def m(a: Any): Int = 0 + } + (new C).m({ case (x, y) => x } : Any => Any) +} diff --git a/test/files/presentation/context-bounds1.check b/test/files/presentation/context-bounds1.check new file mode 100644 index 0000000000..b444de59a4 --- /dev/null +++ b/test/files/presentation/context-bounds1.check @@ -0,0 +1,51 @@ +reload: ContextBounds.scala + +askHyperlinkPos for `Blubb` at (2,23) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `Blubb` at (13,7) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `Foo` at (4,17) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `Foo` at (9,7) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `Blubb` at (4,32) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `Blubb` at (13,7) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `A` at (4,42) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `A` at (4,12) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `A` at (4,51) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `A` at (4,12) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `blubb` at (4,66) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `blubb` at (2,7) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `Foo` at (5,18) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `Foo` at (9,7) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `A` at (5,25) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `A` at (4,12) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `foo` at (5,36) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `foo` at (10,7) ContextBounds.scala +================================================================================ + +askHyperlinkPos for `A` at (10,14) ContextBounds.scala +================================================================================ +[response] found askHyperlinkPos for `A` at (9,11) ContextBounds.scala +================================================================================ diff --git a/test/files/presentation/context-bounds1/Test.scala b/test/files/presentation/context-bounds1/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/context-bounds1/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest
\ No newline at end of file diff --git a/test/files/presentation/context-bounds1/src/ContextBounds.scala b/test/files/presentation/context-bounds1/src/ContextBounds.scala new file mode 100644 index 0000000000..72a8f694a3 --- /dev/null +++ b/test/files/presentation/context-bounds1/src/ContextBounds.scala @@ -0,0 +1,13 @@ +object ContextBound { + val blubb = new Blubb/*#*/ + + def work[A: Foo/*#*/](f: Blubb/*#*/ => A/*#*/): A/*#*/ = f(blubb/*#*/) ensuring { + implicitly[Foo/*#*/[A/*#*/]].foo/*#*/(_) >= 42 + } +} + +trait Foo[A] { + def foo(a: A/*#*/): Int +} + +class Blubb
\ No newline at end of file diff --git a/test/files/presentation/t4287.check b/test/files/presentation/t4287.check new file mode 100644 index 0000000000..a922421e18 --- /dev/null +++ b/test/files/presentation/t4287.check @@ -0,0 +1,11 @@ +reload: Foo.scala + +askHyperlinkPos for `B` at (1,24) Foo.scala +================================================================================ +[response] found askHyperlinkPos for `B` at (3,8) Foo.scala +================================================================================ + +askHyperlinkPos for `a` at (1,31) Foo.scala +================================================================================ +[response] found askHyperlinkPos for `a` at (4,7) Foo.scala +================================================================================ diff --git a/test/files/presentation/t4287/Test.scala b/test/files/presentation/t4287/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/t4287/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest
\ No newline at end of file diff --git a/test/files/presentation/t4287/src/Foo.scala b/test/files/presentation/t4287/src/Foo.scala new file mode 100644 index 0000000000..a744eaabe2 --- /dev/null +++ b/test/files/presentation/t4287/src/Foo.scala @@ -0,0 +1,5 @@ +class Baz(val f: Int = B/*#*/.a/*#*/) + +object B { + val a = 2 +} diff --git a/test/files/presentation/t4287b.check b/test/files/presentation/t4287b.check new file mode 100644 index 0000000000..d4b33650fd --- /dev/null +++ b/test/files/presentation/t4287b.check @@ -0,0 +1,6 @@ +reload: Foo.scala + +askHyperlinkPos for `i` at (14,11) Foo.scala +================================================================================ +[response] found askHyperlinkPos for `i` at (10,9) Foo.scala +================================================================================ diff --git a/test/files/presentation/t4287b/Test.scala b/test/files/presentation/t4287b/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/t4287b/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest
\ No newline at end of file diff --git a/test/files/presentation/t4287b/src/Foo.scala b/test/files/presentation/t4287b/src/Foo.scala new file mode 100644 index 0000000000..47c676e2a2 --- /dev/null +++ b/test/files/presentation/t4287b/src/Foo.scala @@ -0,0 +1,15 @@ +trait Greeting { + val name: String + val msg = "How are you, "+name +} + +object Greeting { + val hello = "hello" +} + +class C(i: Int) extends { + val nameElse = "Bob" +} with Greeting { + val name = "avc" + println(i/*#*/) +}
\ No newline at end of file diff --git a/test/files/presentation/t4287c.check b/test/files/presentation/t4287c.check new file mode 100644 index 0000000000..42fc30997d --- /dev/null +++ b/test/files/presentation/t4287c.check @@ -0,0 +1,11 @@ +reload: Foo.scala + +askHyperlinkPos for `A` at (1,18) Foo.scala +================================================================================ +[response] found askHyperlinkPos for `A` at (3,8) Foo.scala +================================================================================ + +askHyperlinkPos for `a` at (1,25) Foo.scala +================================================================================ +[response] found askHyperlinkPos for `a` at (4,7) Foo.scala +================================================================================ diff --git a/test/files/presentation/t4287c.flags b/test/files/presentation/t4287c.flags new file mode 100644 index 0000000000..d1a8244169 --- /dev/null +++ b/test/files/presentation/t4287c.flags @@ -0,0 +1 @@ +-Yinfer-argument-types
\ No newline at end of file diff --git a/test/files/presentation/t4287c/Test.scala b/test/files/presentation/t4287c/Test.scala new file mode 100644 index 0000000000..bec1131c4c --- /dev/null +++ b/test/files/presentation/t4287c/Test.scala @@ -0,0 +1,3 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest
\ No newline at end of file diff --git a/test/files/presentation/t4287c/src/Foo.scala b/test/files/presentation/t4287c/src/Foo.scala new file mode 100644 index 0000000000..26870b5021 --- /dev/null +++ b/test/files/presentation/t4287c/src/Foo.scala @@ -0,0 +1,9 @@ +class A(a: Int = A/*#*/.a/*#*/) + +object A { + val a = 2 +} + +class B extends A { + def this(a) = this() +}
\ No newline at end of file diff --git a/test/files/run/macro-default-params.check b/test/files/run/macro-default-params.check new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/files/run/macro-default-params.check @@ -0,0 +1 @@ +0 diff --git a/test/files/run/macro-default-params/Macros_1.scala b/test/files/run/macro-default-params/Macros_1.scala new file mode 100644 index 0000000000..47780ea4b8 --- /dev/null +++ b/test/files/run/macro-default-params/Macros_1.scala @@ -0,0 +1,27 @@ +import scala.language.experimental.macros +import scala.reflect.macros.WhiteboxContext + +object Macros { + def id[A]: A = null.asInstanceOf[A] + + def foo: Any = macro impl + def impl(c: WhiteboxContext): c.Tree = { + import c.universe._ + import Flag._ + + lazy val tpe = TypeTree(typeOf[Int]) + + /* If we used this line instead, it would work! */ + // lazy val tpe = tq"Int" + + lazy val param: ValDef = { + val p1 = q"val a: ${tpe.duplicate} = Macros.id[${tpe.duplicate}]" + ValDef(Modifiers(DEFAULTPARAM), p1.name, p1.tpt, p1.rhs) + } + + q""" + class C { def f($param) = a } + println(new C().f()) + """ + } +} diff --git a/test/files/run/macro-default-params/Test_2.scala b/test/files/run/macro-default-params/Test_2.scala new file mode 100644 index 0000000000..5d19639cdd --- /dev/null +++ b/test/files/run/macro-default-params/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +} diff --git a/test/files/run/macro-whitebox-fundep-materialization/Test_2.scala b/test/files/run/macro-whitebox-fundep-materialization/Test_2.scala index a00f4ed7db..40ca1d549c 100644 --- a/test/files/run/macro-whitebox-fundep-materialization/Test_2.scala +++ b/test/files/run/macro-whitebox-fundep-materialization/Test_2.scala @@ -1,4 +1,4 @@ -// see the comments for macroExpandApply.onDelayed for an explanation of what's tested here +// see the comments for macroExpand.onDelayed for an explanation of what's tested here object Test extends App { case class Foo(i: Int, s: String, b: Boolean) def foo[C, L](c: C)(implicit iso: Iso[C, L]): L = iso.to(c) diff --git a/test/files/run/macroPlugins-macroArgs.check b/test/files/run/macroPlugins-macroArgs.check new file mode 100644 index 0000000000..a68f8069b6 --- /dev/null +++ b/test/files/run/macroPlugins-macroArgs.check @@ -0,0 +1,2 @@ +hijacked 1 +hijacked 2 diff --git a/test/files/run/macroPlugins-macroArgs/Macros_2.scala b/test/files/run/macroPlugins-macroArgs/Macros_2.scala new file mode 100644 index 0000000000..d6521dfbcb --- /dev/null +++ b/test/files/run/macroPlugins-macroArgs/Macros_2.scala @@ -0,0 +1,11 @@ +import scala.language.experimental.macros +import scala.reflect.macros.BlackboxContext + +object Macros { + def impl(c: BlackboxContext)(arg: c.Tree) = { + import c.universe._ + q"""println($arg)""" + } + + def foo(arg: String): Unit = macro impl +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroArgs/Plugin_1.scala b/test/files/run/macroPlugins-macroArgs/Plugin_1.scala new file mode 100644 index 0000000000..23e80ced3b --- /dev/null +++ b/test/files/run/macroPlugins-macroArgs/Plugin_1.scala @@ -0,0 +1,21 @@ +package macroArgs + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.{Plugin => NscPlugin} + +class Plugin(val global: Global) extends NscPlugin { + import global._ + import analyzer._ + + val name = "macroArgs" + val description = "A sample analyzer plugin that overrides macroArgs." + val components = Nil + addMacroPlugin(MacroPlugin) + + object MacroPlugin extends MacroPlugin { + override def pluginsMacroArgs(typer: Typer, expandee: Tree): Option[MacroArgs] = { + val MacroArgs(c, List(Literal(Constant(s: String)))) = standardMacroArgs(typer, expandee) + Some(MacroArgs(c, List(Literal(Constant("hijacked " + s))))) + } + } +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroArgs/Test_3.flags b/test/files/run/macroPlugins-macroArgs/Test_3.flags new file mode 100644 index 0000000000..966df731d0 --- /dev/null +++ b/test/files/run/macroPlugins-macroArgs/Test_3.flags @@ -0,0 +1 @@ +-Xplugin:.
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroArgs/Test_3.scala b/test/files/run/macroPlugins-macroArgs/Test_3.scala new file mode 100644 index 0000000000..a54d608178 --- /dev/null +++ b/test/files/run/macroPlugins-macroArgs/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo("1") + Macros.foo("2") +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroArgs/scalac-plugin.xml b/test/files/run/macroPlugins-macroArgs/scalac-plugin.xml new file mode 100644 index 0000000000..0849f0f4ea --- /dev/null +++ b/test/files/run/macroPlugins-macroArgs/scalac-plugin.xml @@ -0,0 +1,4 @@ +<plugin> + <name>macro-args</name> + <classname>macroArgs.Plugin</classname> +</plugin>
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroExpand.check b/test/files/run/macroPlugins-macroExpand.check new file mode 100644 index 0000000000..6f685c2af4 --- /dev/null +++ b/test/files/run/macroPlugins-macroExpand.check @@ -0,0 +1,2 @@ +expanded into println("impl1") +expanded into println("impl2") diff --git a/test/files/run/macroPlugins-macroExpand/Macros_2.scala b/test/files/run/macroPlugins-macroExpand/Macros_2.scala new file mode 100644 index 0000000000..f16503b415 --- /dev/null +++ b/test/files/run/macroPlugins-macroExpand/Macros_2.scala @@ -0,0 +1,18 @@ +import scala.language.experimental.macros +import scala.reflect.macros.BlackboxContext + +object Macros { + def impl1(c: BlackboxContext) = { + import c.universe._ + q"""println("impl1")""" + } + + def impl2(c: BlackboxContext) = { + import c.universe._ + q"""println("impl2")""" + } + + def foo1: Unit = macro impl1 + + def foo2: Unit = macro impl2 +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroExpand/Plugin_1.scala b/test/files/run/macroPlugins-macroExpand/Plugin_1.scala new file mode 100644 index 0000000000..13df85cb23 --- /dev/null +++ b/test/files/run/macroPlugins-macroExpand/Plugin_1.scala @@ -0,0 +1,27 @@ +package macroExpand + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.{Plugin => NscPlugin} + +class Plugin(val global: Global) extends NscPlugin { + import global._ + import analyzer._ + import scala.reflect.internal.Mode + + val name = "macroExpand" + val description = "A sample analyzer plugin that overrides macroExpand." + val components = Nil + addMacroPlugin(MacroPlugin) + + object MacroPlugin extends MacroPlugin { + override def pluginsMacroExpand(typer: Typer, expandee: Tree, mode: Mode, pt: Type): Option[Tree] = { + object expander extends DefMacroExpander(typer, expandee, mode, pt) { + override def onSuccess(expanded: Tree) = { + val message = s"expanded into ${expanded.toString}" + typer.typed(q"println($message)") + } + } + Some(expander(expandee)) + } + } +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroExpand/Test_3.flags b/test/files/run/macroPlugins-macroExpand/Test_3.flags new file mode 100644 index 0000000000..966df731d0 --- /dev/null +++ b/test/files/run/macroPlugins-macroExpand/Test_3.flags @@ -0,0 +1 @@ +-Xplugin:.
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroExpand/Test_3.scala b/test/files/run/macroPlugins-macroExpand/Test_3.scala new file mode 100644 index 0000000000..def9b5608a --- /dev/null +++ b/test/files/run/macroPlugins-macroExpand/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo1 + Macros.foo2 +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroExpand/scalac-plugin.xml b/test/files/run/macroPlugins-macroExpand/scalac-plugin.xml new file mode 100644 index 0000000000..860150865c --- /dev/null +++ b/test/files/run/macroPlugins-macroExpand/scalac-plugin.xml @@ -0,0 +1,4 @@ +<plugin> + <name>macro-expand</name> + <classname>macroExpand.Plugin</classname> +</plugin>
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroRuntime.check b/test/files/run/macroPlugins-macroRuntime.check new file mode 100644 index 0000000000..af16d1ac36 --- /dev/null +++ b/test/files/run/macroPlugins-macroRuntime.check @@ -0,0 +1,2 @@ +hijacked +hijacked diff --git a/test/files/run/macroPlugins-macroRuntime/Macros_2.scala b/test/files/run/macroPlugins-macroRuntime/Macros_2.scala new file mode 100644 index 0000000000..d6521dfbcb --- /dev/null +++ b/test/files/run/macroPlugins-macroRuntime/Macros_2.scala @@ -0,0 +1,11 @@ +import scala.language.experimental.macros +import scala.reflect.macros.BlackboxContext + +object Macros { + def impl(c: BlackboxContext)(arg: c.Tree) = { + import c.universe._ + q"""println($arg)""" + } + + def foo(arg: String): Unit = macro impl +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroRuntime/Plugin_1.scala b/test/files/run/macroPlugins-macroRuntime/Plugin_1.scala new file mode 100644 index 0000000000..a55adadb48 --- /dev/null +++ b/test/files/run/macroPlugins-macroRuntime/Plugin_1.scala @@ -0,0 +1,20 @@ +package macroRuntime + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.{Plugin => NscPlugin} + +class Plugin(val global: Global) extends NscPlugin { + import global._ + import analyzer._ + + val name = "macroRuntime" + val description = "A sample analyzer plugin that overrides macroRuntime." + val components = Nil + addMacroPlugin(MacroPlugin) + + object MacroPlugin extends MacroPlugin { + override def pluginsMacroRuntime(expandee: Tree): Option[MacroRuntime] = Some({ + case MacroArgs(_, List(msg)) => q"""println("hijacked")""" + }) + } +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroRuntime/Test_3.flags b/test/files/run/macroPlugins-macroRuntime/Test_3.flags new file mode 100644 index 0000000000..966df731d0 --- /dev/null +++ b/test/files/run/macroPlugins-macroRuntime/Test_3.flags @@ -0,0 +1 @@ +-Xplugin:.
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroRuntime/Test_3.scala b/test/files/run/macroPlugins-macroRuntime/Test_3.scala new file mode 100644 index 0000000000..a54d608178 --- /dev/null +++ b/test/files/run/macroPlugins-macroRuntime/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo("1") + Macros.foo("2") +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-macroRuntime/scalac-plugin.xml b/test/files/run/macroPlugins-macroRuntime/scalac-plugin.xml new file mode 100644 index 0000000000..8001af1054 --- /dev/null +++ b/test/files/run/macroPlugins-macroRuntime/scalac-plugin.xml @@ -0,0 +1,4 @@ +<plugin> + <name>macro-runtime</name> + <classname>macroRuntime.Plugin</classname> +</plugin>
\ No newline at end of file diff --git a/test/files/run/macroPlugins-namerHooks.check b/test/files/run/macroPlugins-namerHooks.check new file mode 100644 index 0000000000..c2db5935d4 --- /dev/null +++ b/test/files/run/macroPlugins-namerHooks.check @@ -0,0 +1,45 @@ +enterSym(package <empty> { case class C extends scala.Product with scala.Serializable { <caseaccessor> <paramaccessor> val x: Int = _; <caseaccessor> <paramaccessor> val y: Int = _; def <init>(x: Int, y: Int) = { super.<init>(); () } } }) +enterSym(case class C extends scala.Product with scala.Serializable { <caseaccessor> <paramaccessor> val x: Int = _; <caseaccessor> <paramaccessor> val y: Int = _; def <init>(x: Int, y: Int) = { super.<init>(); () } }) +ensureCompanionObject(case class C extends scala.Product with scala.Serializable { <caseaccessor> <paramaccessor> val x: Int = _; <caseaccessor> <paramaccessor> val y: Int = _; def <init>(x: Int, y: Int) = { super.<init>(); () } }, ...) +enterSym(<synthetic> object C extends runtime.this.AbstractFunction2[Int, Int, C] { def <init>() = { super.<init>(); () }; final override <synthetic> def toString() = "C" }) +enterStat(case class C extends scala.Product with scala.Serializable { <caseaccessor> <paramaccessor> val x: Int = _; <caseaccessor> <paramaccessor> val y: Int = _; def <init>(x: Int, y: Int) = { super.<init>(); () } }) +enterSym(<caseaccessor> <paramaccessor> val x: Int = _) +enterSym(<caseaccessor> <paramaccessor> val y: Int = _) +enterSym(def <init>(x: Int, y: Int) = { super.<init>(); () }) +enterSym(<synthetic> def copy(x = x, y = y) = new C(x, y)) +enterStat(<caseaccessor> <paramaccessor> private[this] val x: Int = _) +enterStat(<caseaccessor> <paramaccessor> private[this] val y: Int = _) +enterStat(def <init>(x: Int, y: Int) = { super.<init>(); () }) +enterSym(<caseaccessor> <paramaccessor> private[this] val x: Int = _) +enterSym(<caseaccessor> <paramaccessor> private[this] val y: Int = _) +enterSym(def <init>(x: Int, y: Int) = { super.<init>(); () }) +enterSym(super.<init>()) +enterStat(super.<init>()) +enterSym(<synthetic> def copy$default$1 = x) +enterSym(<synthetic> def copy$default$2 = y) +enterSym(<synthetic> var acc: Int = -889275714) +enterSym(acc = Statics.this.mix(acc, x)) +enterSym(acc = Statics.this.mix(acc, y)) +enterStat(<synthetic> var acc: Int = -889275714) +enterStat(acc = Statics.this.mix(acc, x)) +enterStat(acc = Statics.this.mix(acc, y)) +enterSym(<synthetic> val C$1: C = x$1.asInstanceOf[C]) +enterStat(<synthetic> val C$1: C = x$1.asInstanceOf[C]) +enterSym(def <init>() = { super.<init>(); () }) +enterSym(final override <synthetic> def toString() = "C") +enterSym(case <synthetic> def apply(x: Int, y: Int): C = new C(x, y)) +enterSym(case <synthetic> def unapply(x$0: C) = if (x$0.==(null)) scala.this.None else Some(scala.Tuple2(x$0.x, x$0.y))) +enterStat(def <init>() = { super.<init>(); () }) +enterStat(final override <synthetic> def toString() = "C") +enterSym(def <init>() = { super.<init>(); () }) +enterSym(final override <synthetic> def toString() = "C") +enterSym(super.<init>()) +enterStat(super.<init>()) +enterSym(case <synthetic> val x1: Int = x$1) +enterStat(case <synthetic> val x1: Int = x$1) +enterSym(case <synthetic> val x1: Any = x$1) +enterSym(case5(){ if (x1.isInstanceOf[C]) matchEnd4(true) else case6() }) +enterSym(case6(){ matchEnd4(false) }) +enterStat(case <synthetic> val x1: Any = x$1) +enterStat(case5(){ if (x1.isInstanceOf[C]) matchEnd4(true) else case6() }) +enterStat(case6(){ matchEnd4(false) }) diff --git a/test/files/run/macroPlugins-namerHooks.scala b/test/files/run/macroPlugins-namerHooks.scala new file mode 100644 index 0000000000..a71d685f7f --- /dev/null +++ b/test/files/run/macroPlugins-namerHooks.scala @@ -0,0 +1,38 @@ +import scala.tools.partest._ +import scala.tools.nsc._ + +object Test extends DirectTest { + override def extraSettings: String = "-usejavacp" + + def code = """ + case class C(x: Int, y: Int) + """.trim + + def show() { + val global = newCompiler() + import global._ + import analyzer._ + + val output = collection.mutable.ListBuffer[String]() + + object macroPlugin extends MacroPlugin { + override def pluginsEnterSym(namer: Namer, tree: Tree): Boolean = { + output += s"enterSym(${tree.toString.replace('\n', ' ')})" + namer.standardEnterSym(tree) + true + } + override def pluginsEnsureCompanionObject(namer: Namer, cdef: ClassDef, creator: ClassDef => Tree = companionModuleDef(_)): Option[Symbol] = { + output += s"ensureCompanionObject(${cdef.toString.replace('\n', ' ')}, ...)" + Some(namer.standardEnsureCompanionObject(cdef, creator)) + } + override def pluginsEnterStats(typer: Typer, stats: List[Tree]): List[Tree] = { + stats.foreach(stat => output += s"enterStat(${stat.toString.replace('\n', ' ')})") + stats + } + } + + addMacroPlugin(macroPlugin) + compileString(global)(code) + println(output.mkString("\n")) + } +} diff --git a/test/files/run/macroPlugins-typedMacroBody.check b/test/files/run/macroPlugins-typedMacroBody.check new file mode 100644 index 0000000000..b6f8436189 --- /dev/null +++ b/test/files/run/macroPlugins-typedMacroBody.check @@ -0,0 +1,2 @@ +impl1 +impl2 diff --git a/test/files/run/macroPlugins-typedMacroBody/Macros_2.flags b/test/files/run/macroPlugins-typedMacroBody/Macros_2.flags new file mode 100644 index 0000000000..966df731d0 --- /dev/null +++ b/test/files/run/macroPlugins-typedMacroBody/Macros_2.flags @@ -0,0 +1 @@ +-Xplugin:.
\ No newline at end of file diff --git a/test/files/run/macroPlugins-typedMacroBody/Macros_2.scala b/test/files/run/macroPlugins-typedMacroBody/Macros_2.scala new file mode 100644 index 0000000000..fa8522e729 --- /dev/null +++ b/test/files/run/macroPlugins-typedMacroBody/Macros_2.scala @@ -0,0 +1,18 @@ +import scala.language.experimental.macros +import scala.reflect.macros.BlackboxContext + +object Macros { + def impl1(c: BlackboxContext) = { + import c.universe._ + q"""println("impl1")""" + } + + def impl2(c: BlackboxContext) = { + import c.universe._ + q"""println("impl2")""" + } + + def foo1: Unit = macro 1 + + def foo2: Unit = macro 2 +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-typedMacroBody/Plugin_1.scala b/test/files/run/macroPlugins-typedMacroBody/Plugin_1.scala new file mode 100644 index 0000000000..e99cf7f75d --- /dev/null +++ b/test/files/run/macroPlugins-typedMacroBody/Plugin_1.scala @@ -0,0 +1,21 @@ +package typedMacroBody + +import scala.tools.nsc.Global +import scala.tools.nsc.plugins.{Plugin => NscPlugin} + +class Plugin(val global: Global) extends NscPlugin { + import global._ + import analyzer._ + + val name = "typedMacroBody" + val description = "A sample analyzer plugin that overrides typedMacroBody." + val components = Nil + addMacroPlugin(MacroPlugin) + + object MacroPlugin extends MacroPlugin { + override def pluginsTypedMacroBody(typer: Typer, ddef: DefDef): Option[Tree] = { + val DefDef(_, _, _, _, _, Literal(Constant(num: Int))) = ddef + Some(standardTypedMacroBody(typer, copyDefDef(ddef)(rhs = Ident(TermName("impl" + num))))) + } + } +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-typedMacroBody/Test_3.scala b/test/files/run/macroPlugins-typedMacroBody/Test_3.scala new file mode 100644 index 0000000000..def9b5608a --- /dev/null +++ b/test/files/run/macroPlugins-typedMacroBody/Test_3.scala @@ -0,0 +1,4 @@ +object Test extends App { + Macros.foo1 + Macros.foo2 +}
\ No newline at end of file diff --git a/test/files/run/macroPlugins-typedMacroBody/scalac-plugin.xml b/test/files/run/macroPlugins-typedMacroBody/scalac-plugin.xml new file mode 100644 index 0000000000..e223fa5dca --- /dev/null +++ b/test/files/run/macroPlugins-typedMacroBody/scalac-plugin.xml @@ -0,0 +1,4 @@ +<plugin> + <name>typed-macro-body</name> + <classname>typedMacroBody.Plugin</classname> +</plugin>
\ No newline at end of file diff --git a/test/files/run/mutable-anyrefmap.scala b/test/files/run/mutable-anyrefmap.scala deleted file mode 100644 index ff615d0daf..0000000000 --- a/test/files/run/mutable-anyrefmap.scala +++ /dev/null @@ -1,91 +0,0 @@ -object Test extends App { - - import scala.collection.mutable.HashMap; - import scala.collection.mutable.AnyRefMap; - - val keys = Array( - null, "perch", "herring", "salmon", "pike", "cod", "" - ) - - val rn = new scala.util.Random(42L) - var arm = AnyRefMap.empty[String, Int] - val hm = HashMap.empty[String, Int] - - def checkConsistent = hm.forall{ case (k,v) => arm.get(k).exists(_ == v) } - - assert { - (0 to 10000).forall{ i => - val k = keys(rn.nextInt(keys.length)) - if (rn.nextInt(100) < 2) arm = arm.clone() - if (rn.nextInt(100) < 5) arm.repack() - if (rn.nextBoolean) { - hm += ((k, i)) - rn.nextInt(6) match { - case 0 => arm += ((k, i)) - case 1 => arm += (k, i) - case 2 => arm(k) = i - case 3 => arm.put(k,i) - case 4 => arm ++= List((k,i)) - case _ => if (!arm.contains(k)) arm.getOrElseUpdate(k,i) - else arm += (k,i) - } - } - else { - hm -= k - rn.nextInt(2) match { - case 0 => arm -= k - case _ => arm --= List(k) - } - } - checkConsistent - } - } - - assert { - val mapped = - arm.map{ case (k,v) => (if (k==null) "" else k+k) -> v.toString } - mapped.getClass == arm.getClass - } - - assert { - val arm2 = new AnyRefMap[java.lang.Integer,Unit](2000000) - for (i <- 0 until 1000000) arm2(java.lang.Integer.valueOf(i)) = () - - arm2.size == 1000000 && - (0 to 1100000 by 100000).map(java.lang.Integer.valueOf).forall(i => (arm2 contains i) == i < 1000000) - } - - arm = AnyRefMap("heron" -> 22, "dove" -> 5, "budgie" -> 0) - - assert{ - var s = "" - arm.foreachKey(s += _) - - s.length == "herondovebudgie".length && - s.contains("heron") && - s.contains("dove") && - s.contains("budgie") - } - - assert{ var s = 0L; arm.foreachValue(s += _); s == 27L } - - assert { - val m2 = arm.mapValuesNow(_+2) - arm.transformValues(_+2) - m2 == arm && !(m2 eq arm) && (for ((_,v) <- arm) yield v).sum == 33L - } - - assert { - val arm2 = new AnyRefMap[String, String](x => if (x==null) "null" else x) - arm2 += ("cod" -> "fish", "Rarity" -> "unicorn") - val hm2 = (new HashMap[String,String]) ++= arm2 - - List(null, "cod", "sparrow", "Rarity").forall(i => - arm2.get(i) == hm2.get(i) && - arm2.getOrElse(i, "") == hm2.getOrElse(i, "") && - arm2(i) == hm2.get(i).getOrElse(if (i==null) "null" else i.toString) && - arm2.getOrNull(i) == hm2.get(i).orNull - ) - } -} - diff --git a/test/files/run/mutable-longmap.scala b/test/files/run/mutable-longmap.scala deleted file mode 100644 index 07fd80f6f0..0000000000 --- a/test/files/run/mutable-longmap.scala +++ /dev/null @@ -1,79 +0,0 @@ -object Test extends App { - - import scala.collection.mutable.HashMap; - import scala.collection.mutable.LongMap; - - val keys = Array( - Long.MinValue, Int.MinValue - 1L, Int.MinValue, -9127, -1, - 0, 1, 9127, Int.MaxValue, Long.MaxValue - ) - - val rn = new scala.util.Random(42L) - var lm = LongMap.empty[Long] - val hm = HashMap.empty[Long,Long] - - def checkConsistent = hm.forall{ case (k,v) => lm.get(k).exists(_ == v) } - - assert { - (0 to 10000).forall{ i => - val k = keys(rn.nextInt(keys.length)) - if (rn.nextInt(100) < 2) lm = lm.clone() - if (rn.nextInt(100) < 5) lm.repack() - if (rn.nextBoolean) { - hm += ((k, i)) - rn.nextInt(6) match { - case 0 => lm += ((k, i)) - case 1 => lm += (k, i) - case 2 => lm(k) = i - case 3 => lm.put(k,i) - case 4 => lm ++= List((k,i)) - case _ => if (!lm.contains(k)) lm.getOrElseUpdate(k,i) - else lm += (k,i) - } - } - else { - hm -= k - rn.nextInt(2) match { - case 0 => lm -= k - case _ => lm --= List(k) - } - } - checkConsistent - } - } - - assert { - lm.map{ case (k,v) => -k*k -> v.toString }.getClass == lm.getClass - } - - assert { - val lm2 = new LongMap[Unit](2000000) - for (i <- 0 until 1000000) lm2(i) = () - - lm2.size == 1000000 && - (0 to 1100000 by 100000).forall(i => (lm2 contains i) == i < 1000000) - } - - lm = LongMap(8L -> 22L, -5L -> 5L, Long.MinValue -> 0L) - - assert{ var s = 0L; lm.foreachKey(s += _); s == Long.MinValue + 3 } - assert{ var s = 0L; lm.foreachValue(s += _); s == 27L } - assert { - val m2 = lm.mapValuesNow(_+2) - lm.transformValues(_+2) - m2 == lm && !(m2 eq lm) && (for ((_,v) <- lm) yield v).sum == 33L - } - - assert { - val lm2 = new LongMap[String](_.toString) - lm2 += (5L -> "fish", 0L -> "unicorn") - val hm2 = (new HashMap[Long,String]) ++= lm2 - - List(Long.MinValue, 0L, 1L, 5L).forall(i => - lm2.get(i) == hm2.get(i) && - lm2.getOrElse(i, "") == hm2.getOrElse(i, "") && - lm2(i) == hm2.get(i).getOrElse(i.toString) && - lm2.getOrNull(i) == hm2.get(i).orNull - ) - } -} diff --git a/test/files/run/t4287inferredMethodTypes.check b/test/files/run/t4287inferredMethodTypes.check new file mode 100644 index 0000000000..56e9c097cc --- /dev/null +++ b/test/files/run/t4287inferredMethodTypes.check @@ -0,0 +1,30 @@ +[[syntax trees at end of typer]] // newSource1.scala +[0:92]package [0:0]<empty> { + [0:21]class A extends [7:21][23]scala.AnyRef { + [8:16]<paramaccessor> private[this] val a: [8]Int = _; + <8:20>def <init>(<8:20>a: [11]<type: [11]scala.Int> = [17:20]A.a): [7]A = <8:20>{ + <8:20><8:20><8:20>A.super.<init>(); + <8:20>() + } + }; + [23:47]object A extends [32:47][49]scala.AnyRef { + [49]def <init>(): [32]A.type = [49]{ + [49][49][49]A.super.<init>(); + [32]() + }; + [36:45]private[this] val a: [40]Int = [44:45]2; + [40]<stable> <accessor> def a: [40]Int = [40][40]A.this.a; + [8]<synthetic> def <init>$default$1: [8]Int = [19]A.a + }; + [49:92]class B extends [57:92][65:66]A { + [65]def <init>(): [57]B = [65]{ + [65][65][65]B.super.<init>([65]A.<init>$default$1); + [57]() + }; + [70:90]def <init>([79:80]a: [79]Int): [74]B = [84:90]{ + [84:90][84:90][84]B.this.<init>(); + [84]() + } + } +} + diff --git a/test/files/run/t4287inferredMethodTypes.scala b/test/files/run/t4287inferredMethodTypes.scala new file mode 100644 index 0000000000..f14e672da8 --- /dev/null +++ b/test/files/run/t4287inferredMethodTypes.scala @@ -0,0 +1,25 @@ +import scala.tools.partest.DirectTest + +object Test extends DirectTest { + + override def extraSettings: String = + s"-usejavacp -Yinfer-argument-types -Xprint-pos -Xprint:typer -Yrangepos -Ystop-after:typer -d ${testOutput.path}" + + override def code = """ +class A(a: Int = A.a) + +object A { + val a = 2 +} + +class B extends A { + def this(a) = this() +} + """.trim + + override def show(): Unit = { + Console.withErr(System.out) { + compile() + } + } +}
\ No newline at end of file diff --git a/test/files/run/t5603.check b/test/files/run/t5603.check index 188f39ff82..760a92567c 100644 --- a/test/files/run/t5603.check +++ b/test/files/run/t5603.check @@ -10,10 +10,10 @@ [87:209]class C extends [94:209][151:159]Greeting { [119:139]val nameElse = _; [95:101]<paramaccessor> private[this] val i: [98:101]Int = _; - <119:139>def <init>([95]i: [98]Int) = <119:139>{ + <95:139>def <init>(<95:101>i: [98]Int) = <95:139>{ <119:139>val nameElse = <134:139>"Bob"; [NoPosition][NoPosition][NoPosition]super.<init>(); - [94]() + <95:139>() }; [168:184]val name = [179:184]"avc"; [191:203][191:198]println([199:202]msg) diff --git a/test/files/run/t7974.check b/test/files/run/t7974.check new file mode 100644 index 0000000000..0be496d8d0 --- /dev/null +++ b/test/files/run/t7974.check @@ -0,0 +1,104 @@ +public class Symbols { + + // compiled from: Symbols.scala + + + + // access flags 0x12 + private final Lscala/Symbol; someSymbol3 + + // access flags 0xA + private static Lscala/Symbol; symbol$1 + + // access flags 0xA + private static Lscala/Symbol; symbol$2 + + // access flags 0xA + private static Lscala/Symbol; symbol$3 + + // access flags 0x9 + public static <clinit>()V + L0 + LINENUMBER 2 L0 + GETSTATIC scala/Symbol$.MODULE$ : Lscala/Symbol$; + LDC "Symbolic1" + INVOKEVIRTUAL scala/Symbol$.apply (Ljava/lang/String;)Lscala/Symbol; + PUTSTATIC Symbols.symbol$1 : Lscala/Symbol; + L1 + LINENUMBER 3 L1 + GETSTATIC scala/Symbol$.MODULE$ : Lscala/Symbol$; + LDC "Symbolic2" + INVOKEVIRTUAL scala/Symbol$.apply (Ljava/lang/String;)Lscala/Symbol; + PUTSTATIC Symbols.symbol$2 : Lscala/Symbol; + L2 + LINENUMBER 5 L2 + GETSTATIC scala/Symbol$.MODULE$ : Lscala/Symbol$; + LDC "Symbolic3" + INVOKEVIRTUAL scala/Symbol$.apply (Ljava/lang/String;)Lscala/Symbol; + PUTSTATIC Symbols.symbol$3 : Lscala/Symbol; + RETURN + MAXSTACK = 2 + MAXLOCALS = 0 + + // access flags 0x1 + public someSymbol1()Lscala/Symbol; + L0 + LINENUMBER 2 L0 + GETSTATIC Symbols.symbol$1 : Lscala/Symbol; + ARETURN + L1 + LOCALVARIABLE this LSymbols; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public someSymbol2()Lscala/Symbol; + L0 + LINENUMBER 3 L0 + GETSTATIC Symbols.symbol$2 : Lscala/Symbol; + ARETURN + L1 + LOCALVARIABLE this LSymbols; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public sameSymbol1()Lscala/Symbol; + L0 + LINENUMBER 4 L0 + GETSTATIC Symbols.symbol$1 : Lscala/Symbol; + ARETURN + L1 + LOCALVARIABLE this LSymbols; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public someSymbol3()Lscala/Symbol; + L0 + LINENUMBER 5 L0 + ALOAD 0 + GETFIELD Symbols.someSymbol3 : Lscala/Symbol; + ARETURN + L1 + LOCALVARIABLE this LSymbols; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public <init>()V + L0 + LINENUMBER 6 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object.<init> ()V + L1 + LINENUMBER 5 L1 + ALOAD 0 + GETSTATIC Symbols.symbol$3 : Lscala/Symbol; + PUTFIELD Symbols.someSymbol3 : Lscala/Symbol; + RETURN + L2 + LOCALVARIABLE this LSymbols; L0 L2 0 + MAXSTACK = 2 + MAXLOCALS = 1 +} diff --git a/test/files/run/t7974/Symbols.scala b/test/files/run/t7974/Symbols.scala new file mode 100644 index 0000000000..2363b724eb --- /dev/null +++ b/test/files/run/t7974/Symbols.scala @@ -0,0 +1,6 @@ +class Symbols { + def someSymbol1 = 'Symbolic1 + def someSymbol2 = 'Symbolic2 + def sameSymbol1 = 'Symbolic1 + val someSymbol3 = 'Symbolic3 +} diff --git a/test/files/run/t7974/Test.scala b/test/files/run/t7974/Test.scala new file mode 100644 index 0000000000..9403ea332b --- /dev/null +++ b/test/files/run/t7974/Test.scala @@ -0,0 +1,20 @@ +import java.io.PrintWriter; + +import scala.tools.partest.BytecodeTest +import scala.tools.asm.util._ +import scala.tools.nsc.util.stringFromWriter + +object Test extends BytecodeTest { + def show { + val classNode = loadClassNode("Symbols", skipDebugInfo = false) + val textifier = new Textifier + classNode.accept(new TraceClassVisitor(null, textifier, null)) + + val classString = stringFromWriter(w => textifier.print(w)) + val result = + classString.split('\n') + .dropWhile(elem => elem != "public class Symbols {") + .filterNot(elem => elem.startsWith(" @Lscala/reflect/ScalaSignature") || elem.startsWith(" ATTRIBUTE ScalaSig")) + result foreach println + } +} diff --git a/test/junit/scala/collection/ArraySortingTest.scala b/test/junit/scala/collection/ArraySortingTest.scala new file mode 100644 index 0000000000..4e54b39ce7 --- /dev/null +++ b/test/junit/scala/collection/ArraySortingTest.scala @@ -0,0 +1,29 @@ +package scala.collection.mutable + +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.Test + +/* Tests various maps by making sure they all agree on the same answers. */ +@RunWith(classOf[JUnit4]) +class ArraySortingTest { + + class CantSortMe(val i: Int) { + override def equals(a: Any) = throw new IllegalArgumentException("I cannot be equalled!") + } + + object CanOrder extends Ordering[CantSortMe] { + def compare(a: CantSortMe, b: CantSortMe) = a.i compare b.i + } + + // Tests SI-7837 + @Test + def sortByTest() { + val test = Array(1,2,3,4,1,3,5,7,1,4,8,1,1,1,1) + val cant = test.map(i => new CantSortMe(i)) + java.util.Arrays.sort(test) + scala.util.Sorting.quickSort(cant)(CanOrder) + assert( test(6) == 1 ) + assert( (test,cant).zipped.forall(_ == _.i) ) + } +} diff --git a/test/junit/scala/collection/SetMapConsistencyTest.scala b/test/junit/scala/collection/SetMapConsistencyTest.scala new file mode 100644 index 0000000000..c62b074483 --- /dev/null +++ b/test/junit/scala/collection/SetMapConsistencyTest.scala @@ -0,0 +1,479 @@ +package scala.collection + +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import org.junit.Test +import scala.collection.{mutable => cm, immutable => ci} +import scala.collection.JavaConverters._ + +/* Tests various maps by making sure they all agree on the same answers. */ +@RunWith(classOf[JUnit4]) +class SetMapConsistencyTest { + + trait MapBox[A] { + protected def oor(s: String, n: Int) = throw new IllegalArgumentException(s"Out of range for $s: $n") + def title: String + def adders: Int + def add(n: Int, a: A, v: Int): Unit + def subbers: Int + def sub(n: Int, a: A): Unit + def getters: Int + def get(n: Int, a: A): Int + def fiddlers: Int + def fiddle(n: Int): Unit + def keys: Iterator[A] + def has(a: A): Boolean + } + + + // Mutable map wrappers + + class BoxMutableMap[A, M <: cm.Map[A, Int]](m0: M, title0: String) extends MapBox[A] { + var m = m0 + def title = title0 + def adders = 5 + def add(n: Int, a: A, v: Int) { n match { + case 0 => m += ((a, v)) + case 1 => m(a) = v + case 2 => m.put(a, v) + case 3 => m = (m + ((a, v))).asInstanceOf[M] + case 4 => m = (m ++ List((a, v))).asInstanceOf[M] + case _ => oor("add", n) + }} + def subbers: Int = 3 + def sub(n: Int, a: A) { n match { + case 0 => m -= a + case 1 => m = (m - a).asInstanceOf[M] + case 2 => m = m.filter(_._1 != a).asInstanceOf[M] + case _ => oor("sub", n) + }} + def getters: Int = 3 + def get(n: Int, a: A) = n match { + case 0 => m.get(a).getOrElse(-1) + case 1 => if (m contains a) m(a) else -1 + case 2 => m.getOrElse(a, -1) + case _ => oor("get", n) + } + def fiddlers: Int = 0 + def fiddle(n: Int) { oor("fiddle", n) } + def keys = m.keysIterator + def has(a: A) = m contains a + override def toString = m.toString + } + + def boxMlm[A] = new BoxMutableMap[A, cm.ListMap[A, Int]](new cm.ListMap[A, Int], "mutable.ListMap") + + def boxMhm[A] = new BoxMutableMap[A, cm.HashMap[A, Int]](new cm.HashMap[A, Int], "mutable.HashMap") + + def boxMohm[A] = new BoxMutableMap[A, cm.OpenHashMap[A, Int]](new cm.OpenHashMap[A, Int], "mutable.OpenHashMap") + + def boxMarm[A <: AnyRef] = new BoxMutableMap[A, cm.AnyRefMap[A, Int]](new cm.AnyRefMap[A, Int](_ => -1), "mutable.AnyRefMap") { + private def arm: cm.AnyRefMap[A, Int] = m.asInstanceOf[cm.AnyRefMap[A, Int]] + override def adders = 3 + override def subbers = 1 + override def getters: Int = 4 + override def get(n: Int, a: A) = n match { + case 0 => m.get(a).getOrElse(-1) + case 1 => m(a) + case 2 => m.getOrElse(a, -1) + case 3 => val x = arm.getOrNull(a); if (x==0 && !(arm contains a)) -1 else x + case _ => oor("get", n) + } + override def fiddlers = 2 + override def fiddle(n: Int) { n match { + case 0 => m = arm.clone + case 1 => arm.repack + case _ => oor("fiddle", n) + }} + } + + def boxMjm = new BoxMutableMap[Long, cm.LongMap[Int]](new cm.LongMap[Int](_ => -1), "mutable.LongMap") { + private def lm: cm.LongMap[Int] = m.asInstanceOf[cm.LongMap[Int]] + override def adders = 3 + override def subbers = 1 + override def getters: Int = 4 + override def get(n: Int, a: Long) = n match { + case 0 => m.get(a).getOrElse(-1) + case 1 => m(a) + case 2 => m.getOrElse(a, -1) + case 3 => val x = lm.getOrNull(a); if (x==0 && !(lm contains a)) -1 else x + case _ => oor("get", n) + } + override def fiddlers = 2 + override def fiddle(n: Int) { n match { + case 0 => m = lm.clone + case 1 => lm.repack + case _ => oor("fiddle", n) + }} + } + + def boxJavaM[A] = new BoxMutableMap[A, cm.Map[A, Int]]((new java.util.HashMap[A, Int]).asScala, "java.util.HashMap") { + override def adders = 3 + override def subbers = 1 + } + + + // Immutable map wrappers + + class BoxImmutableMap[A, M <: ci.Map[A, Int]](m0: M, title0: String) extends MapBox[A] { + var m = m0 + def title = title0 + def adders = 2 + def add(n: Int, a: A, v: Int) { n match { + case 0 => m = (m + ((a, v))).asInstanceOf[M] + case 1 => m = (m ++ List((a, v))).asInstanceOf[M] + case _ => oor("add", n) + }} + def subbers: Int = 2 + def sub(n: Int, a: A) { n match { + case 0 => m = (m - a).asInstanceOf[M] + case 1 => m = m.filter(_._1 != a).asInstanceOf[M] + case _ => oor("sub", n) + }} + def getters: Int = 3 + def get(n: Int, a: A) = n match { + case 0 => m.get(a).getOrElse(-1) + case 1 => if (m contains a) m(a) else -1 + case 2 => m.getOrElse(a, -1) + case _ => oor("get", n) + } + def fiddlers: Int = 0 + def fiddle(n: Int) { oor("fiddle", n) } + def keys = m.keysIterator + def has(a: A) = m contains a + override def toString = m.toString + } + + def boxIhm[A] = new BoxImmutableMap[A, ci.HashMap[A,Int]](new ci.HashMap[A, Int], "immutable.HashMap") + + def boxIim = new BoxImmutableMap[Int, ci.IntMap[Int]](ci.IntMap.empty[Int], "immutable.IntMap") + + def boxIjm = new BoxImmutableMap[Long, ci.LongMap[Int]](ci.LongMap.empty[Int], "immutable.LongMap") + + def boxIlm[A] = new BoxImmutableMap[A, ci.ListMap[A, Int]](new ci.ListMap[A, Int], "immutable.ListMap") + + def boxItm[A: Ordering] = new BoxImmutableMap[A, ci.TreeMap[A, Int]](new ci.TreeMap[A, Int], "immutable.TreeMap") + + + // Mutable set wrappers placed into the same framework (everything returns 0) + + class BoxMutableSet[A, M <: cm.Set[A]](s0: M, title0: String) extends MapBox[A] { + protected var m = s0 + def title = title0 + def adders = 5 + def add(n: Int, a: A, v: Int) { n match { + case 0 => m += a + case 1 => m(a) = true + case 2 => m add a + case 3 => m = (m + a).asInstanceOf[M] + case 4 => m = (m ++ List(a)).asInstanceOf[M] + case _ => oor("add", n) + }} + def subbers: Int = 3 + def sub(n: Int, a: A) { n match { + case 0 => m -= a + case 1 => m = (m - a).asInstanceOf[M] + case 2 => m = m.filter(_ != a).asInstanceOf[M] + case _ => oor("sub", n) + }} + def getters: Int = 1 + def get(n: Int, a: A) = if (m(a)) 0 else -1 + def fiddlers: Int = 0 + def fiddle(n: Int) { oor("fiddle", n) } + def keys = m.iterator + def has(a: A) = m(a) + override def toString = m.toString + } + + def boxMbs = new BoxMutableSet[Int, cm.BitSet](new cm.BitSet, "mutable.BitSet") + + def boxMhs[A] = new BoxMutableSet[A, cm.HashSet[A]](new cm.HashSet[A], "mutable.HashSet") + + def boxJavaS[A] = new BoxMutableSet[A, cm.Set[A]]((new java.util.HashSet[A]).asScala, "java.util.HashSet") { + override def adders = 3 + override def subbers = 1 + } + + + // Immutable set wrappers placed into the same framework (everything returns 0) + + class BoxImmutableSet[A, M <: ci.Set[A]](s0: M, title0: String) extends MapBox[A] { + protected var m = s0 + def title = title0 + def adders = 2 + def add(n: Int, a: A, v: Int) { n match { + case 0 => m = (m + a).asInstanceOf[M] + case 1 => m = (m ++ List(a)).asInstanceOf[M] + case _ => oor("add", n) + }} + def subbers: Int = 2 + def sub(n: Int, a: A) { n match { + case 0 => m = (m - a).asInstanceOf[M] + case 1 => m = m.filter(_ != a).asInstanceOf[M] + case _ => oor("sub", n) + }} + def getters: Int = 1 + def get(n: Int, a: A) = if (m(a)) 0 else -1 + def fiddlers: Int = 0 + def fiddle(n: Int) { oor("fiddle", n) } + def keys = m.iterator + def has(a: A) = m(a) + override def toString = m.toString + } + + def boxIbs = new BoxImmutableSet[Int, ci.BitSet](ci.BitSet.empty, "immutable.BitSet") + + def boxIhs[A] = new BoxImmutableSet[A, ci.HashSet[A]](ci.HashSet.empty[A], "mutable.HashSet") + + def boxIls[A] = new BoxImmutableSet[A, ci.ListSet[A]](ci.ListSet.empty[A], "mutable.ListSet") + + def boxIts[A: Ordering] = new BoxImmutableSet[A, ci.TreeSet[A]](ci.TreeSet.empty[A], "mutable.TreeSet") + + + // Random operations on maps + def churn[A](map1: MapBox[A], map2: MapBox[A], keys: Array[A], n: Int = 1000, seed: Int = 42, valuer: Int => Int = identity) = { + def check = map1.keys.forall(map2 has _) && map2.keys.forall(map1 has _) + val rn = new scala.util.Random(seed) + var what = new StringBuilder + what ++= "creation" + for (i <- 0 until n) { + if (!check) { + val temp = map2 match { + case b: BoxImmutableMap[_, _] => b.m match { + case hx: ci.HashMap.HashTrieMap[_,_] => + val h = hx.asInstanceOf[ci.HashMap.HashTrieMap[A, Int]] + Some((h.bitmap.toHexString, h.elems.mkString, h.size)) + case _ => None + } + case _ => None + } + throw new Exception(s"Disagreement after ${what.result} between ${map1.title} and ${map2.title} because ${map1.keys.map(map2 has _).mkString(",")} ${map2.keys.map(map1 has _).mkString(",")} at step $i:\n$map1\n$map2\n$temp") + } + what ++= " (%d) ".format(i) + if (rn.nextInt(10)==0) { + + if (map1.fiddlers > 0) map1.fiddle({ + val n = rn.nextInt(map1.fiddlers) + what ++= ("f"+n) + n + }) + if (map2.fiddlers > 0) map2.fiddle({ + val n = rn.nextInt(map2.fiddlers) + what ++= ("F"+n) + n + }) + } + if (rn.nextBoolean) { + val idx = rn.nextInt(keys.length) + val key = keys(rn.nextInt(keys.length)) + val n1 = rn.nextInt(map1.adders) + val n2 = rn.nextInt(map2.adders) + what ++= "+%s(%d,%d)".format(key,n1,n2) + map1.add(n1, key, valuer(idx)) + map2.add(n2, key, valuer(idx)) + } + else { + val n = rn.nextInt(keys.length) + val key = keys(n) + val n1 = rn.nextInt(map1.subbers) + val n2 = rn.nextInt(map2.subbers) + what ++= "-%s(%d,%d)".format(key, n1, n2) + //println(s"- $key") + map1.sub(n1, key) + map2.sub(n2, key) + } + val j = rn.nextInt(keys.length) + val gn1 = rn.nextInt(map1.getters) + val gn2 = rn.nextInt(map2.getters) + val g1 = map1.get(gn1, keys(j)) + val g2 = map2.get(gn2, keys(j)) + if (g1 != g2) { + val temp = map2 match { + case b: BoxImmutableMap[_, _] => b.m match { + case hx: ci.HashMap.HashTrieMap[_,_] => + val h = hx.asInstanceOf[ci.HashMap.HashTrieMap[A, Int]] + val y = (ci.HashMap.empty[A, Int] ++ h).asInstanceOf[ci.HashMap.HashTrieMap[A, Int]] + Some(((h.bitmap.toHexString, h.elems.mkString, h.size),(y.bitmap.toHexString, y.elems.mkString, y.size))) + case _ => None + } + case _ => None + } + throw new Exception(s"Disagreement after ${what.result} between ${map1.title} and ${map2.title} on get of ${keys(j)} (#$j) on step $i: $g1 != $g2 using methods $gn1 and $gn2 resp.; in full\n$map1\n$map2\n$temp") + } + } + true + } + + + // Actual tests + val smallKeys = Array(0, 1, 42, 9127) + val intKeys = smallKeys ++ Array(-1, Int.MaxValue, Int.MinValue, -129385) + val longKeys = intKeys.map(_.toLong) ++ Array(Long.MaxValue, Long.MinValue, 1397198789151L, -41402148014L) + val stringKeys = intKeys.map(_.toString) ++ Array("", null) + val anyKeys = stringKeys.filter(_ != null) ++ Array(0L) ++ Array(true) ++ Array(math.Pi) + + @Test + def churnIntMaps() { + val maps = Array[() => MapBox[Int]]( + () => boxMlm[Int], () => boxMhm[Int], () => boxMohm[Int], () => boxJavaM[Int], + () => boxIim, () => boxIhm[Int], () => boxIlm[Int], () => boxItm[Int] + ) + assert( maps.sliding(2).forall{ ms => churn(ms(0)(), ms(1)(), intKeys, 2000) } ) + } + + @Test + def churnLongMaps() { + val maps = Array[() => MapBox[Long]]( + () => boxMjm, () => boxIjm, () => boxJavaM[Long], + () => boxMlm[Long], () => boxMhm[Long], () => boxMohm[Long], () => boxIhm[Long], () => boxIlm[Long] + ) + assert( maps.sliding(2).forall{ ms => churn(ms(0)(), ms(1)(), longKeys, 10000) } ) + } + + @Test + def churnStringMaps() { + // Note: OpenHashMap and TreeMap won't store null, so skip strings + val maps = Array[() => MapBox[String]]( + () => boxMlm[String], () => boxMhm[String], () => boxMarm[String], () => boxJavaM[String], + () => boxIhm[String], () => boxIlm[String] + ) + assert( maps.sliding(2).forall{ ms => churn(ms(0)(), ms(1)(), stringKeys, 5000) } ) + } + + @Test + def churnAnyMaps() { + val maps = Array[() => MapBox[Any]]( + () => boxMlm[Any], () => boxMhm[Any], () => boxMohm[Any], () => boxJavaM[Any], () => boxIhm[Any], () => boxIlm[Any] + ) + assert( maps.sliding(2).forall{ ms => churn(ms(0)(), ms(1)(), anyKeys, 10000) } ) + } + + @Test + def churnIntSets() { + val sets = Array[() => MapBox[Int]]( + () => boxMhm[Int], () => boxIhm[Int], () => boxJavaS[Int], + () => boxMbs, () => boxMhs[Int], () => boxIbs, () => boxIhs[Int], () => boxIls[Int], () => boxIts[Int] + ) + assert( sets.sliding(2).forall{ ms => churn(ms(0)(), ms(1)(), smallKeys, 1000, valuer = _ => 0) } ) + } + + @Test + def churnAnySets() { + val sets = Array[() => MapBox[Any]]( + () => boxMhm[Any], () => boxIhm[Any], () => boxJavaS[Any], + () => boxMhs[Any], () => boxIhs[Any], () => boxIls[Any] + ) + assert( sets.sliding(2).forall{ ms => churn(ms(0)(), ms(1)(), anyKeys, 10000, valuer = _ => 0) } ) + } + + @Test + def extraMutableLongMapTests() { + import cm.{LongMap, HashMap} + var lm = LongMap.empty[Long] + longKeys.zipWithIndex.foreach{ case (k,i) => lm(k) = i } + assert{ lm.map{ case (k,v) => -k*k -> v.toString }.getClass == lm.getClass } + + assert { + val lm2 = new LongMap[Unit](2000000) + for (i <- 0 until 1000000) lm2(i) = () + + lm2.size == 1000000 && + (0 to 1100000 by 100000).forall(i => (lm2 contains i) == i < 1000000) + } + + lm = LongMap(8L -> 22L, -5L -> 5L, Long.MinValue -> 0L) + + assert{ var s = 0L; lm.foreachKey(s += _); s == Long.MinValue + 3 } + assert{ var s = 0L; lm.foreachValue(s += _); s == 27L } + assert { + val m2 = lm.mapValuesNow(_+2) + lm.transformValues(_+2) + m2 == lm && !(m2 eq lm) && (for ((_,v) <- lm) yield v).sum == 33L + } + + assert { + val lm2 = new LongMap[String](_.toString) + lm2 += (5L -> "fish", 0L -> "unicorn") + val hm2 = (new HashMap[Long,String]) ++= lm2 + List(Long.MinValue, 0L, 1L, 5L).forall(i => + lm2.get(i) == hm2.get(i) && + lm2.getOrElse(i, "") == hm2.getOrElse(i, "") && + lm2(i) == hm2.get(i).getOrElse(i.toString) && + lm2.getOrNull(i) == hm2.get(i).orNull + ) + } + } + + @Test + def extraMutableAnyRefMapTests() { + import cm.{AnyRefMap, HashMap} + var arm = AnyRefMap.empty[String, Int] + stringKeys.zipWithIndex.foreach{ case (k,i) => arm(k) = i } + + assert{ arm.map{ case (k,v) => (if (k==null) "" else k+k) -> v.toString }.getClass == arm.getClass } + + assert { + val arm2 = new AnyRefMap[java.lang.Integer,Unit](2000000) + for (i <- 0 until 1000000) arm2(java.lang.Integer.valueOf(i)) = () + arm2.size == 1000000 && + (0 to 1100000 by 100000).map(java.lang.Integer.valueOf).forall(i => (arm2 contains i) == i < 1000000) + } + + arm = AnyRefMap("heron" -> 22, "dove" -> 5, "budgie" -> 0) + + assert{ + var s = "" + arm.foreachKey(s += _) + s.length == "herondovebudgie".length && + s.contains("heron") && + s.contains("dove") && + s.contains("budgie") + } + + assert{ var s = 0L; arm.foreachValue(s += _); s == 27L } + + assert { + val m2 = arm.mapValuesNow(_+2) + arm.transformValues(_+2) + m2 == arm && !(m2 eq arm) && (for ((_,v) <- arm) yield v).sum == 33L + } + + assert { + val arm2 = new AnyRefMap[String, String](x => if (x==null) "null" else x) + arm2 += ("cod" -> "fish", "Rarity" -> "unicorn") + val hm2 = (new HashMap[String,String]) ++= arm2 + List(null, "cod", "sparrow", "Rarity").forall(i => + arm2.get(i) == hm2.get(i) && + arm2.getOrElse(i, "") == hm2.getOrElse(i, "") && + arm2(i) == hm2.get(i).getOrElse(if (i==null) "null" else i.toString) && + arm2.getOrNull(i) == hm2.get(i).orNull + ) + } + } + + @Test + def extraFilterTests() { + type M = scala.collection.Map[Int, Boolean] + val manyKVs = (0 to 1000).map(i => i*i*i).map(x => x -> ((x*x*x) < 0)) + val rn = new scala.util.Random(42) + def mhm: M = { val m = new cm.HashMap[Int, Boolean]; m ++= manyKVs; m } + def mohm: M = { val m = new cm.OpenHashMap[Int, Boolean]; m ++= manyKVs; m } + def ihm: M = ci.HashMap.empty[Int, Boolean] ++ manyKVs + val densities = List(0, 0.05, 0.2, 0.5, 0.8, 0.95, 1) + def repeat = rn.nextInt(100) < 33 + def pick(m: M, density: Double) = m.keys.filter(_ => rn.nextDouble < density).toSet + def test: Boolean = { + for (i <- 0 to 100) { + var ms = List(mhm, mohm, ihm) + do { + val density = densities(rn.nextInt(densities.length)) + val keep = pick(ms.head, density) + ms = ms.map(_.filter(keep contains _._1)) + if (!ms.sliding(2).forall(s => s(0) == s(1))) return false + } while (repeat) + } + true + } + assert(test) + } +} diff --git a/test/junit/scala/math/NumericTest.scala b/test/junit/scala/math/NumericTest.scala new file mode 100644 index 0000000000..4f0657f471 --- /dev/null +++ b/test/junit/scala/math/NumericTest.scala @@ -0,0 +1,18 @@ + + +import org.junit.Assert._ +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class NumericTest { + + /* Test for SI-8102 */ + @Test + def testAbs { + assertTrue(-0.0.abs equals 0.0) + assertTrue(-0.0f.abs equals 0.0f) + } +} + |