diff options
Diffstat (limited to 'test')
37 files changed, 471 insertions, 58 deletions
diff --git a/test/files/neg/t7636.check b/test/files/neg/t7636.check index f70d50bee3..12391cccc8 100644 --- a/test/files/neg/t7636.check +++ b/test/files/neg/t7636.check @@ -4,7 +4,7 @@ t7636.scala:3: error: illegal inheritance; ^ t7636.scala:3: error: type mismatch; found : Either[_$2,_$3(in constructor C)] where type _$3(in constructor C), type _$2 - required: Either[_, _$3(in object Main)] where type _$3(in object Main) + required: Either[_, _$3(in value <local Main>)] where type _$3(in value <local Main>) class C extends ResultTable(Left(5):Either[_,_])(5) ^ two errors found diff --git a/test/files/pos/t3439.scala b/test/files/pos/t3439.scala new file mode 100644 index 0000000000..ccc75cc4cf --- /dev/null +++ b/test/files/pos/t3439.scala @@ -0,0 +1,26 @@ +class Base[M](i: Int) + +// was "implicit modifier not allowed on top level objects" +class D1()(implicit i: Int) extends Base({println(i); 0}) + +// what "no implicit value of type Int found" +class D2()(implicit i: Int) extends Base(implicitly[Int]) + + +abstract class ParametricMessage[M: Manifest](msg: M) { def message = msg } +case class ParametricMessage1[M: Manifest](msg: M, p1: Class[_]) extends ParametricMessage(msg) + + +class Wrap { + class Base[M](i: Int) + + // was "implicit modifier not allowed on top level objects" + class D1()(implicit i: Int) extends Base({println(i); 0}) + + // what "no implicit value of type Int found" + class D2()(implicit i: Int) extends Base(implicitly[Int]) + + + abstract class ParametricMessage[M: Manifest](msg: M) { def message = msg } + case class ParametricMessage1[M: Manifest](msg: M, p1: Class[_]) extends ParametricMessage(msg) +} diff --git a/test/files/pos/t5454.scala b/test/files/pos/t5454.scala new file mode 100644 index 0000000000..4045f3b57b --- /dev/null +++ b/test/files/pos/t5454.scala @@ -0,0 +1,10 @@ +object IllegalInheritance { + trait A + implicit def a = new A {} // def => val + //val r = implicitly[A] // uncomment + + class B[T](t : T)(implicit a : A) // remove implicit param block + + class C extends B/*[Int]*/(23) // uncomment + val c = new C // comment +} diff --git a/test/files/pos/t8900.scala b/test/files/pos/t8900.scala new file mode 100644 index 0000000000..376bd786f2 --- /dev/null +++ b/test/files/pos/t8900.scala @@ -0,0 +1,11 @@ +package foo +package lambdaking + +class Test { + def byname(b: => Any) = ??? + def foo: Any = { + def bar: Any = { + byname(bar) + } + } +} diff --git a/test/files/pos/t8934a/A_1.scala b/test/files/pos/t8934a/A_1.scala new file mode 100644 index 0000000000..6c1f29d030 --- /dev/null +++ b/test/files/pos/t8934a/A_1.scala @@ -0,0 +1,18 @@ +import language.experimental.macros +import reflect.macros.whitebox.Context + +object Unapply { + def impl1(c: Context)(a: c.Tree): c.Tree = { + import c.universe._ + q"(new { def unapply[T](a: String): Option[(Int, String)] = ??? }).unapply($a)" + } + def unapply(a: Any): Any = macro impl1 +} + +object UnapplySeq { + def impl1(c: Context)(a: c.Tree): c.Tree = { + import c.universe._ + q"(new { def unapplySeq[T](a: String): Option[(Int, Seq[String])] = ??? }).unapplySeq($a)" + } + def unapplySeq(a: Any): Any = macro impl1 +} diff --git a/test/files/pos/t8934a/Test_2.flags b/test/files/pos/t8934a/Test_2.flags new file mode 100644 index 0000000000..618dfe2b75 --- /dev/null +++ b/test/files/pos/t8934a/Test_2.flags @@ -0,0 +1 @@ +-Ystop-after:typer -Ymacro-expand:discard -nowarn diff --git a/test/files/pos/t8934a/Test_2.scala b/test/files/pos/t8934a/Test_2.scala new file mode 100644 index 0000000000..e1792ed3c5 --- /dev/null +++ b/test/files/pos/t8934a/Test_2.scala @@ -0,0 +1,12 @@ +object Test { + "" match { + case Unapply(a, b) => + a: Int + b: String + case UnapplySeq(a, b1, b2) => + a: Int + b1: String + b2: String + } +} +// These used to fail `too many patterns` under -Ymacro-expand:discard diff --git a/test/files/presentation/private-case-class-members.check b/test/files/presentation/private-case-class-members.check new file mode 100644 index 0000000000..678f9a34e6 --- /dev/null +++ b/test/files/presentation/private-case-class-members.check @@ -0,0 +1 @@ +Test OK diff --git a/test/files/presentation/private-case-class-members/Test.scala b/test/files/presentation/private-case-class-members/Test.scala new file mode 100644 index 0000000000..e64c8238ea --- /dev/null +++ b/test/files/presentation/private-case-class-members/Test.scala @@ -0,0 +1,34 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest +import scala.reflect.internal.util.SourceFile +import scala.tools.nsc.interactive.Response + +object Test extends InteractiveTest { + override def execute(): Unit = { + val source = loadSourceAndWaitUntilTypechecked("State.scala") + checkErrors(source) + } + + private def loadSourceAndWaitUntilTypechecked(sourceName: String): SourceFile = { + val sourceFile = sourceFiles.find(_.file.name == sourceName).head + compiler.askToDoFirst(sourceFile) + val res = new Response[Unit] + compiler.askReload(List(sourceFile), res) + res.get + askLoadedTyped(sourceFile).get + // the second round of type-checking makes it fail + compiler.askReload(List(sourceFile), res) + res.get + askLoadedTyped(sourceFile).get + + sourceFile + } + + private def checkErrors(source: SourceFile): Unit = compiler.getUnitOf(source) match { + case Some(unit) => + val problems = unit.problems.toList + if(problems.isEmpty) reporter.println("Test OK") + else problems.foreach(problem => reporter.println(problem.msg)) + + case None => reporter.println("No compilation unit found for " + source.file.name) + } +} diff --git a/test/files/presentation/private-case-class-members/src/State.scala b/test/files/presentation/private-case-class-members/src/State.scala new file mode 100644 index 0000000000..c31817076c --- /dev/null +++ b/test/files/presentation/private-case-class-members/src/State.scala @@ -0,0 +1,5 @@ +object State +case class State(private val foo: Int) + +case class State2(private val foo: Int) +object State2 diff --git a/test/files/presentation/quasiquotes.flags b/test/files/presentation/quasiquotes.flags new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/presentation/quasiquotes.flags diff --git a/test/files/presentation/t8934.check b/test/files/presentation/t8934.check new file mode 100644 index 0000000000..0ece87f808 --- /dev/null +++ b/test/files/presentation/t8934.check @@ -0,0 +1,2 @@ +reload: Source.scala +Test OK diff --git a/test/files/presentation/t8934/Runner.scala b/test/files/presentation/t8934/Runner.scala new file mode 100644 index 0000000000..944f458391 --- /dev/null +++ b/test/files/presentation/t8934/Runner.scala @@ -0,0 +1,27 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest +import scala.reflect.internal.util.SourceFile +import scala.tools.nsc.interactive.Response + +object Test extends InteractiveTest { + + override def execute(): Unit = { + val src = loadSourceAndWaitUntilTypechecked("Source.scala") + checkErrors(src) + } + + private def loadSourceAndWaitUntilTypechecked(sourceName: String): SourceFile = { + val sourceFile = sourceFiles.find(_.file.name == sourceName).head + askReload(List(sourceFile)).get + askLoadedTyped(sourceFile).get + sourceFile + } + + private def checkErrors(source: SourceFile): Unit = compiler.getUnitOf(source) match { + case Some(unit) => + val problems = unit.problems.toList + if(problems.isEmpty) reporter.println("Test OK") + else problems.foreach(problem => reporter.println(problem.msg)) + + case None => reporter.println("No compilation unit found for " + source.file.name) + } +} diff --git a/test/files/presentation/t8934/src/Source.scala b/test/files/presentation/t8934/src/Source.scala new file mode 100644 index 0000000000..769c8fd38b --- /dev/null +++ b/test/files/presentation/t8934/src/Source.scala @@ -0,0 +1,10 @@ +class Quasi { + import reflect.runtime.universe._ + + def test: Unit = { + (null: Any) match { + case q"$foo($bar)" => + } + () + } +} diff --git a/test/files/presentation/t8941.check b/test/files/presentation/t8941.check new file mode 100644 index 0000000000..341804903a --- /dev/null +++ b/test/files/presentation/t8941.check @@ -0,0 +1,7 @@ +reload: Source.scala + +askType at Source.scala(6,7) +================================================================================ +[response] askTypeAt (6,7) +scala.this.Predef.??? +================================================================================ diff --git a/test/files/presentation/t8941/Runner.scala b/test/files/presentation/t8941/Runner.scala new file mode 100644 index 0000000000..0a8923a583 --- /dev/null +++ b/test/files/presentation/t8941/Runner.scala @@ -0,0 +1,11 @@ +import scala.tools.nsc.interactive.tests.InteractiveTest + +object Test extends InteractiveTest { + override def runDefaultTests() { + // make sure typer is done.. the virtual pattern matcher might translate + // some trees and mess up positions. But we'll catch it red handed! + // sourceFiles foreach (src => askLoadedTyped(src).get) + super.runDefaultTests() + } + +} diff --git a/test/files/presentation/t8941/src/Source.scala b/test/files/presentation/t8941/src/Source.scala new file mode 100644 index 0000000000..7438cccb03 --- /dev/null +++ b/test/files/presentation/t8941/src/Source.scala @@ -0,0 +1,8 @@ +object Foo { + implicit class MatCreator(val ctx: StringContext) extends AnyVal { + def m(args: Any*): Unit = { + ctx.checkLengths(args) + } + ???/*?*/ + } +} diff --git a/test/files/presentation/t8941b/IdempotencyTest.scala b/test/files/presentation/t8941b/IdempotencyTest.scala new file mode 100644 index 0000000000..af01b36898 --- /dev/null +++ b/test/files/presentation/t8941b/IdempotencyTest.scala @@ -0,0 +1,73 @@ +package scala.tools.nsc +package interactive +package tests.core + +import reporters.{Reporter => CompilerReporter} +import scala.tools.nsc.interactive.InteractiveReporter +import scala.reflect.internal.util.SourceFile + +/** Determistically interrupts typechecking of `code` when a defintion named + * `MagicInterruptionMarker` is typechecked, and then performs a targetted + * typecheck of the tree at the specal comment marker marker + */ +abstract class IdempotencyTest { self => + private val settings = new Settings + settings.usejavacp.value = true + + private object Break extends scala.util.control.ControlThrowable + + private val compilerReporter: CompilerReporter = new InteractiveReporter { + override def compiler = self.compiler + } + + object compiler extends Global(settings, compilerReporter) { + override def checkForMoreWork(pos: Position) { + } + override def signalDone(context: Context, old: Tree, result: Tree) { + // println("signalDone: " + old.toString.take(50).replaceAll("\n", "\\n")) + if (!interrupted && analyzer.lockedCount == 0 && interruptsEnabled && shouldInterrupt(result)) { + interrupted = true + val typed = typedTreeAt(markerPosition) + checkTypedTree(typed) + throw Break + } + super.signalDone(context, old, result) + } + + // we're driving manually using our own thread, disable the check here. + override def assertCorrectThread() {} + } + + import compiler._ + + private var interrupted = false + + // Extension points + protected def code: String + protected def shouldInterrupt(tree: Tree): Boolean = { + tree.symbol != null && tree.symbol.name.toString == "MagicInterruptionMarker" + } + protected def checkTypedTree(tree: Tree): Unit = {} + + + private val source: SourceFile = newSourceFile(code) + private def markerPosition: Position = source.position(code.indexOf("/*?*/")) + + def assertNoProblems() { + val problems = getUnit(source).get.problems + assert(problems.isEmpty, problems.mkString("\n")) + } + + def show() { + reloadSource(source) + try { + typedTree(source, true) + assert(false, "Expected to break out of typechecking.") + } catch { + case Break => // expected + } + assertNoProblems() + } + + def main(args: Array[String]) { show() } +} diff --git a/test/files/presentation/t8941b/Test.scala b/test/files/presentation/t8941b/Test.scala new file mode 100644 index 0000000000..7269a14286 --- /dev/null +++ b/test/files/presentation/t8941b/Test.scala @@ -0,0 +1,53 @@ +import scala.tools.nsc.interactive.tests.core.IdempotencyTest + +// At the time of writing this test, removing any part of `enterExistingSym` +// leads to a failure. +object Test { + def main(args: Array[String]) { + test(""" + object Foo { + def term { + def foo(c: String = "") = c + class MagicInterruptionMarker + foo()/*?*/ + } + } + """) + + test(""" + object Foo { + def term { + def foo = 42 + class MagicInterruptionMarker + foo/*?*/ + } + } + """) + + test(""" + object Foo { + def term { + lazy val foo = 42 + class MagicInterruptionMarker + foo/*?*/ + } + } + """) + + test(""" + object Foo { + implicit class C(val a: String) extends AnyVal + class MagicInterruptionMarker + ""/*?*/ + } + """) + } + + def test(code0: String) { + val t = new IdempotencyTest { + def code = code0 + } + t.show() + } +} + diff --git a/test/files/res/t6613.check b/test/files/res/t6613.check new file mode 100644 index 0000000000..bbd9331b16 --- /dev/null +++ b/test/files/res/t6613.check @@ -0,0 +1,5 @@ + +nsc> +nsc> +nsc> +nsc> diff --git a/test/files/res/t6613.res b/test/files/res/t6613.res new file mode 100644 index 0000000000..e3fa000fdd --- /dev/null +++ b/test/files/res/t6613.res @@ -0,0 +1,3 @@ +t6613/Enummy.java +t6613/Broken.scala +t6613/Broken.scala diff --git a/test/files/res/t6613/Broken.scala b/test/files/res/t6613/Broken.scala new file mode 100644 index 0000000000..9bcd12dbe1 --- /dev/null +++ b/test/files/res/t6613/Broken.scala @@ -0,0 +1 @@ +class Broken() { def broken() = Enummy.Broke.CHIP } diff --git a/test/files/res/t6613/Enummy.java b/test/files/res/t6613/Enummy.java new file mode 100644 index 0000000000..1863ef1297 --- /dev/null +++ b/test/files/res/t6613/Enummy.java @@ -0,0 +1 @@ +public class Enummy { public enum Broke { SHARD, CHIP } } diff --git a/test/files/res/t8871.check b/test/files/res/t8871.check new file mode 100644 index 0000000000..bbd9331b16 --- /dev/null +++ b/test/files/res/t8871.check @@ -0,0 +1,5 @@ + +nsc> +nsc> +nsc> +nsc> diff --git a/test/files/res/t8871.res b/test/files/res/t8871.res new file mode 100644 index 0000000000..9b1a5fb57f --- /dev/null +++ b/test/files/res/t8871.res @@ -0,0 +1,4 @@ +t8871/tag.scala +t8871/usetag.scala +t8871/usetag.scala + diff --git a/test/files/res/t8871/tag.scala b/test/files/res/t8871/tag.scala new file mode 100644 index 0000000000..1a1803b77d --- /dev/null +++ b/test/files/res/t8871/tag.scala @@ -0,0 +1,3 @@ +class Tag { + @inline def apply[@specialized A, T](a: A): A = a +} diff --git a/test/files/res/t8871/usetag.scala b/test/files/res/t8871/usetag.scala new file mode 100644 index 0000000000..139d768552 --- /dev/null +++ b/test/files/res/t8871/usetag.scala @@ -0,0 +1,6 @@ +trait Foo + +object Test { + val y = new Tag().apply[Double, Foo](3.3) + // under FSC, this gave t8871/usetag.scala:4: error: wrong number of type parameters for method apply$mDc$sp: [T](a: Double)Double +} diff --git a/test/files/run/global-showdef.check b/test/files/run/global-showdef.check index 4c2fd41a1a..4ac96b4315 100644 --- a/test/files/run/global-showdef.check +++ b/test/files/run/global-showdef.check @@ -1,14 +1,14 @@ <<-- class foo.bar.Bippy after phase 'typer' -->> def showdefTestMemberClass1: Int +<<-- object foo.bar.Bippy after phase 'typer' -->> + def showdefTestMemberObject2: String <<-- type foo.bar.Bippy.BippyType after phase 'typer' -->> def showdefTestMemberType1: Unit +<<-- object foo.bar.Bippy.Boppity.Boo after phase 'typer' -->> + def showdefTestMemberObject1: String <<-- type foo.bar.Bippy.BippyType after phase 'typer' -->> def showdefTestMemberType2: Unit <<-- class foo.bar.Bippy.Boppity after phase 'typer' -->> def showdefTestMemberClass2: Int <<-- class foo.bar.Bippy.Boppity.Boo after phase 'typer' -->> def showdefTestMemberClass3: Int -<<-- object foo.bar.Bippy after phase 'typer' -->> - def showdefTestMemberObject2: String -<<-- object foo.bar.Bippy.Boppity.Boo after phase 'typer' -->> - def showdefTestMemberObject1: String diff --git a/test/files/run/global-showdef.scala b/test/files/run/global-showdef.scala index 1d4891fd1f..276fcc1e7c 100644 --- a/test/files/run/global-showdef.scala +++ b/test/files/run/global-showdef.scala @@ -1,11 +1,10 @@ -import scala.tools.nsc._ -import scala.reflect.io.AbstractFile +import scala.tools.partest.DirectTest import scala.tools.nsc.util.stringFromStream -import scala.reflect.internal.util.{ SourceFile, BatchSourceFile } -import scala.tools.nsc.reporters.ConsoleReporter -object Test { - val src: SourceFile = new BatchSourceFile("src", """ +object Test extends DirectTest { + override def extraSettings: String = "-usejavacp -Yshow:typer -Ystop-after:typer" + + override def code = """ package foo.bar class Bippy { @@ -32,39 +31,28 @@ object Bippy { def showdefTestMemberObject2 = "abc" } - """) + """ + + override def show(): Unit = { + val classes = List("Bippy", "Bippy#BippyType", "Bippy.BippyType", "Bippy#Boppity", "Bippy#Boppity#Boo") + val objects = List("Bippy", "Bippy#Boppity#Boo") + + def interesting(line: String) = (line contains "def showdefTestMember") || (line startsWith "<<-- ") - def mkCompiler(args: String*) = { - val settings = new Settings() - val command = new CompilerCommand("-usejavacp" :: args.toList, settings) + def run(args: String*) = slurp(args: _*).lines filter interesting foreach println - new Global(settings) + classes.zipAll(objects, "", "") foreach { + case (c, "") => run("-Xshow-class", c) + case (c, o) => run("-Xshow-class", c, "-Xshow-object", o) + } } - def slurp(body: => Unit): String = stringFromStream { stream => + // slurp the compilation result + def slurp(args: String*): String = stringFromStream { stream => Console.withOut(stream) { Console.withErr(stream) { - body + compile(args: _*) } } } - def lines(args: String*): List[String] = { - val output = slurp { - val compiler = mkCompiler(args: _*) - val run = new compiler.Run() - run.compileSources(List(src)) - } - output.lines.toList - } - def showClass(name: String) = lines("-Yshow:typer", "-Xshow-class", name) - def showObject(name: String) = lines("-Yshow:typer", "-Xshow-object", name) - - def show(xs: List[String]) = { - xs filter (x => (x contains "def showdefTestMember") || (x startsWith "<<-- ")) foreach println - } - - def main(args: Array[String]) { - show(List("Bippy", "Bippy#BippyType", "Bippy.BippyType", "Bippy#Boppity", "Bippy#Boppity#Boo") flatMap showClass) - show(List("Bippy", "Bippy#Boppity#Boo") flatMap showObject) - } } diff --git a/test/files/run/t4332.scala b/test/files/run/t4332.scala index 1c7e7d73de..5a67922911 100644 --- a/test/files/run/t4332.scala +++ b/test/files/run/t4332.scala @@ -12,7 +12,7 @@ object Test extends DirectTest { } def isExempt(sym: Symbol) = { - val exempt = Set("view", "repr", "sliceWithKnownDelta", "sliceWithKnownBound", "transform", "filterImpl") + val exempt = Set("view", "repr", "sliceWithKnownDelta", "sliceWithKnownBound", "transform") (exempt contains sym.name.decoded) } diff --git a/test/files/run/t4950.check b/test/files/run/t4950.check new file mode 100644 index 0000000000..3f3a302b62 --- /dev/null +++ b/test/files/run/t4950.check @@ -0,0 +1,9 @@ +Type in expressions to have them evaluated. +Type :help for more information. + +scala> val 1 = 2 +scala.MatchError: 2 (of class java.lang.Integer) + +scala> val List(1) = List(1) + +scala> :quit diff --git a/test/files/run/t4950.scala b/test/files/run/t4950.scala new file mode 100644 index 0000000000..cef06027bf --- /dev/null +++ b/test/files/run/t4950.scala @@ -0,0 +1,12 @@ +import scala.tools.partest.ReplTest + +object Test extends ReplTest { + // Filter out the abbreviated stacktrace "... X elided" + // because the number seems to differ between versions/platforms/... + override def show = eval() filterNot (_ contains "elided") foreach println + def code = +""" +val 1 = 2 +val List(1) = List(1) +""" +} diff --git a/test/files/run/t8907.scala b/test/files/run/t8907.scala new file mode 100644 index 0000000000..7952ac82d9 --- /dev/null +++ b/test/files/run/t8907.scala @@ -0,0 +1,39 @@ +import scala.tools.partest._ +import java.io.File + +object Test extends StoreReporterDirectTest { + def code = ??? + + def compileCode(code: String) = { + val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator") + compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code) + } + + def show(): Unit = { + compileCode(""" + class C { class Inner } + + class D { + object O { + def foo(c: C)(i: c.Inner): c.Inner = ??? + } + } + """) + assert(filteredInfos.isEmpty, filteredInfos) + deleteClass("C") + compileCode(""" + class E { + def foo = { + (null: D).toString + } + } + """) + assert(storeReporter.infos.isEmpty, storeReporter.infos.mkString("\n")) // Included a MissingRequirementError before. + } + + def deleteClass(name: String) { + val classFile = new File(testOutput.path, name + ".class") + assert(classFile.exists) + assert(classFile.delete()) + } +} diff --git a/test/junit/scala/collection/immutable/StreamTest.scala b/test/junit/scala/collection/immutable/StreamTest.scala deleted file mode 100644 index 6dc1c79a48..0000000000 --- a/test/junit/scala/collection/immutable/StreamTest.scala +++ /dev/null @@ -1,18 +0,0 @@ -package scala.collection.immutable - -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 -import org.junit.Test -import org.junit.Assert._ - -@RunWith(classOf[JUnit4]) -class StreamTest { - - @Test - def t6727_and_t6440(): Unit = { - assertTrue(Stream.continually(()).filter(_ => true).take(2) == Seq((), ())) - assertTrue(Stream.continually(()).filterNot(_ => false).take(2) == Seq((), ())) - assertTrue(Stream(1,2,3,4,5).filter(_ < 4) == Seq(1,2,3)) - assertTrue(Stream(1,2,3,4,5).filterNot(_ > 4) == Seq(1,2,3,4)) - } -} diff --git a/test/junit/scala/issues/BytecodeTests.scala b/test/junit/scala/issues/BytecodeTests.scala index 7a05472277..d4ed063a03 100644 --- a/test/junit/scala/issues/BytecodeTests.scala +++ b/test/junit/scala/issues/BytecodeTests.scala @@ -4,6 +4,7 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.junit.Test import scala.tools.asm.Opcodes +import scala.tools.nsc.backend.jvm.AsmUtils import scala.tools.nsc.backend.jvm.CodeGenTools._ import org.junit.Assert._ import scala.collection.JavaConverters._ @@ -36,4 +37,44 @@ class BytecodeTests { assertTrue(getSingleMethod(c, "f").instructions.count(_.isInstanceOf[TableSwitch]) == 1) assertTrue(getSingleMethod(c, "g").instructions.count(_.isInstanceOf[LookupSwitch]) == 1) } + + @Test + def t8926(): Unit = { + import scala.reflect.internal.util.BatchSourceFile + + // this test cannot be implemented using partest because of its mixed-mode compilation strategy: + // partest first compiles all files with scalac, then the java files, and then again the scala + // using the output classpath. this shadows the bug SI-8926. + + val annotA = + """import java.lang.annotation.Retention; + |import java.lang.annotation.RetentionPolicy; + |@Retention(RetentionPolicy.RUNTIME) + |public @interface AnnotA { } + """.stripMargin + val annotB = "public @interface AnnotB { }" + + val scalaSrc = + """@AnnotA class A + |@AnnotB class B + """.stripMargin + + val compiler = newCompiler() + val run = new compiler.Run() + run.compileSources(List(new BatchSourceFile("AnnotA.java", annotA), new BatchSourceFile("AnnotB.java", annotB), new BatchSourceFile("Test.scala", scalaSrc))) + val outDir = compiler.settings.outputDirs.getSingleOutput.get + val outfiles = (for (f <- outDir.iterator if !f.isDirectory) yield (f.name, f.toByteArray)).toList + + def check(classfile: String, annotName: String) = { + val f = (outfiles collect { case (`classfile`, bytes) => AsmUtils.readClass(bytes) }).head + val descs = f.visibleAnnotations.asScala.map(_.desc).toList + assertTrue(descs.toString, descs exists (_ contains annotName)) + } + + check("A.class", "AnnotA") + + // known issue SI-8928: the visibility of AnnotB should be CLASS, but annotation classes without + // a @Retention annotation are currently emitted as RUNTIME. + check("B.class", "AnnotB") + } } diff --git a/test/junit/scala/reflect/internal/PrintersTest.scala b/test/junit/scala/reflect/internal/PrintersTest.scala index ca9b4671b2..7043c26d5e 100644 --- a/test/junit/scala/reflect/internal/PrintersTest.scala +++ b/test/junit/scala/reflect/internal/PrintersTest.scala @@ -354,6 +354,13 @@ trait ClassPrintTests { | def y = "test" |}""") + @Test def testClassConstructorModifiers = assertPrintedCode("class X private (x: scala.Int)") + + @Test def testClassConstructorModifierVisibility = assertPrintedCode(sm""" + |object A { + | class X protected[A] (x: scala.Int) + |}""") + @Test def testClassWithPublicParams = assertPrintedCode("class X(val x: scala.Int, val s: scala.Predef.String)") @Test def testClassWithParams1 = assertPrintedCode("class X(x: scala.Int, s: scala.Predef.String)") diff --git a/test/pending/pos/t3439.scala b/test/pending/pos/t3439.scala deleted file mode 100644 index 425f1aeeb5..0000000000 --- a/test/pending/pos/t3439.scala +++ /dev/null @@ -1,2 +0,0 @@ -abstract class ParametricMessage[M: Manifest](msg: M) { def message = msg } -case class ParametricMessage1[M: Manifest](msg: M, p1: Class[_]) extends ParametricMessage(msg) |