From 8bc8b83f0bd7daef62b41b4a0c87b4e9b7344284 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 3 May 2012 17:11:30 -0700 Subject: Moved passing tests from pending to files. Most are pattern matcher bugs fixed by virtpatmat. A few are reifier, package object, or miscellaneous. I threw in an original test for SI-2337, to go with those for SI-1697, SI-3705, SI-4415, and SI-1357, all of which (in the interests of making sure this basket has all the eggs) I am closing. --- test/files/neg/dbldef.check | 14 +++++ test/files/neg/dbldef.scala | 1 + test/files/pos/no-widen-locals.scala | 19 +++++++ test/files/pos/t1357.scala | 21 ++++++++ test/files/pos/t5240.scala | 11 ++++ test/files/run/reify_csv.check | 10 ++++ test/files/run/reify_csv.scala | 35 +++++++++++++ test/files/run/reify_lazyevaluation.check | 8 +++ test/files/run/reify_lazyevaluation.scala | 58 +++++++++++++++++++++ test/files/run/reify_properties.check | 2 + test/files/run/reify_properties.scala | 56 ++++++++++++++++++++ test/files/run/t1697.scala | 19 +++++++ test/files/run/t2337.check | 4 ++ test/files/run/t2337.scala | 21 ++++++++ test/files/run/t3705.scala | 17 ++++++ test/files/run/t4415.scala | 86 +++++++++++++++++++++++++++++++ test/files/run/t5258a.check | 1 + test/files/run/t5258a.scala | 7 +++ 18 files changed, 390 insertions(+) create mode 100644 test/files/neg/dbldef.check create mode 100644 test/files/neg/dbldef.scala create mode 100644 test/files/pos/no-widen-locals.scala create mode 100644 test/files/pos/t1357.scala create mode 100644 test/files/pos/t5240.scala create mode 100644 test/files/run/reify_csv.check create mode 100644 test/files/run/reify_csv.scala create mode 100644 test/files/run/reify_lazyevaluation.check create mode 100644 test/files/run/reify_lazyevaluation.scala create mode 100644 test/files/run/reify_properties.check create mode 100644 test/files/run/reify_properties.scala create mode 100644 test/files/run/t1697.scala create mode 100644 test/files/run/t2337.check create mode 100644 test/files/run/t2337.scala create mode 100644 test/files/run/t3705.scala create mode 100644 test/files/run/t4415.scala create mode 100644 test/files/run/t5258a.check create mode 100644 test/files/run/t5258a.scala (limited to 'test/files') diff --git a/test/files/neg/dbldef.check b/test/files/neg/dbldef.check new file mode 100644 index 0000000000..3ee63475e4 --- /dev/null +++ b/test/files/neg/dbldef.check @@ -0,0 +1,14 @@ +dbldef.scala:1: error: x is already defined as value x +case class test0(x: Int, x: Float) + ^ +dbldef.scala:1: error: type mismatch; + found : Float + required: Int +case class test0(x: Int, x: Float) + ^ +dbldef.scala:1: error: type mismatch; + found : Float + required: Int +case class test0(x: Int, x: Float) + ^ +three errors found diff --git a/test/files/neg/dbldef.scala b/test/files/neg/dbldef.scala new file mode 100644 index 0000000000..c70fb97b2c --- /dev/null +++ b/test/files/neg/dbldef.scala @@ -0,0 +1 @@ +case class test0(x: Int, x: Float) diff --git a/test/files/pos/no-widen-locals.scala b/test/files/pos/no-widen-locals.scala new file mode 100644 index 0000000000..013e63f0a2 --- /dev/null +++ b/test/files/pos/no-widen-locals.scala @@ -0,0 +1,19 @@ +// Worked from r23262 until that was reverted somewhere +// around r25016. +import annotation.switch + +object Test { + def f(x: Int) = { + val X1 = 5 + val X2 = 10 + val X3 = 15 + val X4 = 20 + + (x: @switch) match { + case X1 => 1 + case X2 => 2 + case X3 => 3 + case X4 => 4 + } + } +} diff --git a/test/files/pos/t1357.scala b/test/files/pos/t1357.scala new file mode 100644 index 0000000000..7bc6d45034 --- /dev/null +++ b/test/files/pos/t1357.scala @@ -0,0 +1,21 @@ +object NonEmptyCons { + def unapply[H, T](c: (H, T)): Option[(H, T)] = Some(c) +} + + +object Main { + + type BT[+H, +T <: Tuple2[Tuple2[H, T], Tuple2[H, T]]] = Tuple2[H, T] + + // type T = Tuple2[String,String] + type BinaryTree[+E] = BT[E, T forSome { type T <: Tuple2[BT[E, T], BT[E, T]] }] + + def foo[E](tree: BinaryTree[E]): Unit = tree match { + case NonEmptyCons(_, tail) => { + tail match { + case NonEmptyCons(_, _) => { + } + } + } + } +} \ No newline at end of file diff --git a/test/files/pos/t5240.scala b/test/files/pos/t5240.scala new file mode 100644 index 0000000000..2db689c27d --- /dev/null +++ b/test/files/pos/t5240.scala @@ -0,0 +1,11 @@ + + + + + + +package object foo { + + var labels: Array[_ <: String] = null + +} diff --git a/test/files/run/reify_csv.check b/test/files/run/reify_csv.check new file mode 100644 index 0000000000..b56f4bb50b --- /dev/null +++ b/test/files/run/reify_csv.check @@ -0,0 +1,10 @@ +List(phase name, id, description) +record(parser,1,parse source into ASTs, perform simple desugaring) +record(namer,2,resolve names, attach symbols to named trees) +record(packageobjects,3,load package objects) +record(typer,4,the meat and potatoes: type the trees) +record(superaccessors,5,add super accessors in traits and nested classes) +record(pickler,6,serialize symbol tables) +record(refchecks,7,reference/override checking, translate nested objects) +record(selectiveanf,8,) +record(liftcode,9,reify trees) diff --git a/test/files/run/reify_csv.scala b/test/files/run/reify_csv.scala new file mode 100644 index 0000000000..966521575c --- /dev/null +++ b/test/files/run/reify_csv.scala @@ -0,0 +1,35 @@ +import scala.reflect.mirror._ + +object Test extends App { + val csv = """ + | phase name; id; description + | parser; 1; parse source into ASTs, perform simple desugaring + | namer; 2; resolve names, attach symbols to named trees + |packageobjects; 3; load package objects + | typer; 4; the meat and potatoes: type the trees + |superaccessors; 5; add super accessors in traits and nested classes + | pickler; 6; serialize symbol tables + | refchecks; 7; reference/override checking, translate nested objects + | selectiveanf; 8; + | liftcode; 9; reify trees""".stripMargin.split("\n").map{_.trim()}.drop(1).toList + + val fields = csv.head.split(";").map{_.trim()}.toList + println(fields) + + reify({ + object Csv { + case class record(`phase name`: String, id: String, description: String) + + object record { + def parse(lines: List[String]) = { + lines drop(1) map { line => line.split(";", -1).toList match { + case phase$whitespace$name :: id :: description :: _ => record(phase$whitespace$name.trim(), id.trim(), description.trim()) + case _ => throw new Exception("format error") + }} + } + } + } + + Csv.record.parse(csv) foreach println + }).eval +} diff --git a/test/files/run/reify_lazyevaluation.check b/test/files/run/reify_lazyevaluation.check new file mode 100644 index 0000000000..1c7f96cd96 --- /dev/null +++ b/test/files/run/reify_lazyevaluation.check @@ -0,0 +1,8 @@ +s = Susp(?) +evaluating... +s() = 3 +s = Susp(3) +2 + s = 5 +sl2 = Susp(?) +sl2() = Some(3) +sl2 = Susp(Some(3)) diff --git a/test/files/run/reify_lazyevaluation.scala b/test/files/run/reify_lazyevaluation.scala new file mode 100644 index 0000000000..1a0c858914 --- /dev/null +++ b/test/files/run/reify_lazyevaluation.scala @@ -0,0 +1,58 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + object lazyLib { + + /** Delay the evaluation of an expression until it is needed. */ + def delay[A](value: => A): Susp[A] = new SuspImpl[A](value) + + /** Get the value of a delayed expression. */ + implicit def force[A](s: Susp[A]): A = s() + + /** + * Data type of suspended computations. (The name froms from ML.) + */ + abstract class Susp[+A] extends Function0[A] + + /** + * Implementation of suspended computations, separated from the + * abstract class so that the type parameter can be invariant. + */ + class SuspImpl[A](lazyValue: => A) extends Susp[A] { + private var maybeValue: Option[A] = None + + override def apply() = maybeValue match { + case None => + val value = lazyValue + maybeValue = Some(value) + value + case Some(value) => + value + } + + override def toString() = maybeValue match { + case None => "Susp(?)" + case Some(value) => "Susp(" + value + ")" + } + } + } + + import lazyLib._ + + val s: Susp[Int] = delay { println("evaluating..."); 3 } + + println("s = " + s) // show that s is unevaluated + println("s() = " + s()) // evaluate s + println("s = " + s) // show that the value is saved + println("2 + s = " + (2 + s)) // implicit call to force() + + val sl = delay { Some(3) } + val sl1: Susp[Some[Int]] = sl + val sl2: Susp[Option[Int]] = sl1 // the type is covariant + + println("sl2 = " + sl2) + println("sl2() = " + sl2()) + println("sl2 = " + sl2) + }.eval +} diff --git a/test/files/run/reify_properties.check b/test/files/run/reify_properties.check new file mode 100644 index 0000000000..d769bea4b0 --- /dev/null +++ b/test/files/run/reify_properties.check @@ -0,0 +1,2 @@ +user1: MR. ROBERT +user2: MR. BOB KUZ diff --git a/test/files/run/reify_properties.scala b/test/files/run/reify_properties.scala new file mode 100644 index 0000000000..5cacc262ac --- /dev/null +++ b/test/files/run/reify_properties.scala @@ -0,0 +1,56 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + /** A mutable property whose getter and setter may be customized. */ + case class Property[T](init: T) { + private var value: T = init + + /** The getter function, defaults to identity. */ + private var setter: T => T = identity[T] + + /** The setter function, defaults to identity. */ + private var getter: T => T = identity[T] + + /** Retrive the value held in this property. */ + def apply(): T = getter(value) + + /** Update the value held in this property, through the setter. */ + def update(newValue: T) = value = setter(newValue) + + /** Change the getter. */ + def get(newGetter: T => T) = { getter = newGetter; this } + + /** Change the setter */ + def set(newSetter: T => T) = { setter = newSetter; this } + } + + class User { + // Create a property with custom getter and setter + val firstname = Property("") + .get { v => v.toUpperCase() } + .set { v => "Mr. " + v } + val lastname = Property("") + + /** Scala provides syntactic sugar for calling 'apply'. Simply + * adding a list of arguments between parenthesis (in this case, + * an empty list) is translated to a call to 'apply' with those + * arguments. + */ + override def toString() = firstname() + " " + lastname() + } + + val user1 = new User + + // Syntactic sugar for 'update': an assignment is translated to a + // call to method 'update' + user1.firstname() = "Robert" + + val user2 = new User + user2.firstname() = "bob" + user2.lastname() = "KUZ" + + println("user1: " + user1) + println("user2: " + user2) + }.eval +} diff --git a/test/files/run/t1697.scala b/test/files/run/t1697.scala new file mode 100644 index 0000000000..01590dd405 --- /dev/null +++ b/test/files/run/t1697.scala @@ -0,0 +1,19 @@ +class Term +case class Num(n: Int) extends Term +case class Add(x: Term, y: Term) extends Term + +object Value { + def unapply(term: Any): Boolean = true +} + +object Test { + def main(args: Array[String]) { + val term = Add(Num(1), Add(Num(2), Num(3))) + val res = term match { + case Add(Num(x), Num(y)) => "Add(Num, Num)" + case Add(Value(), y) => "Add(Value, ?)" + case _ => "?" + } + assert(res == "Add(Value, ?)") + } +} diff --git a/test/files/run/t2337.check b/test/files/run/t2337.check new file mode 100644 index 0000000000..18f1f66fc3 --- /dev/null +++ b/test/files/run/t2337.check @@ -0,0 +1,4 @@ +(Both Int,-1,-1) +(Both Float,1,1) +(Float then Int,0,0) +(Int then Float,0,0) diff --git a/test/files/run/t2337.scala b/test/files/run/t2337.scala new file mode 100644 index 0000000000..86a372ce56 --- /dev/null +++ b/test/files/run/t2337.scala @@ -0,0 +1,21 @@ + +object Test { + + def compare(first: Any, second: Any): Any = { + (first, second) match { + case (k: Int, o: Int) => k compare o + //why the next case matches (Float, Int) but does not match (Int, Float) ??? + case (k: Number, o: Number) => k.doubleValue() compare o.doubleValue() + case _ => "BOGON" + // throw new Exception("Unsupported compare " + first + "; " + second) + } + } + + def main(args: Array[String]): Unit = { + println("Both Int", -1, compare(0, 1)) + println("Both Float", 1, compare(1.0, 0.0)) + println("Float then Int", 0, compare(10.0, 10)) + println("Int then Float", 0, compare(10, 10.0)) //this fails with an exception + } +} + diff --git a/test/files/run/t3705.scala b/test/files/run/t3705.scala new file mode 100644 index 0000000000..fcc020f28c --- /dev/null +++ b/test/files/run/t3705.scala @@ -0,0 +1,17 @@ +// package foo + +import scala.xml._ +object Test { + def updateNodes(ns: Seq[Node]): Seq[Node] = + for(subnode <- ns) yield subnode match { + case {_} if true => abc + case Elem(prefix, label, attribs, scope, children @ _*) => + Elem(prefix, label, attribs, scope, updateNodes(children) : _*) + case other => other + } + def main(args: Array[String]): Unit = { + updateNodes() + + } +} + diff --git a/test/files/run/t4415.scala b/test/files/run/t4415.scala new file mode 100644 index 0000000000..f96031d650 --- /dev/null +++ b/test/files/run/t4415.scala @@ -0,0 +1,86 @@ +/** + * Demonstration of issue with Extractors. If lines 15/16 are not present, get at runtime: + * + * Exception in thread "main" java.lang.VerifyError: (class: ExtractorIssue$$, method: convert signature: (LTopProperty;)LMyProp;) Accessing value from uninitialized register 5 + * at ExtractorIssue.main(ExtractorIssue.scala) + * at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)] + * + * If lines 15/16 are present, the compiler crashes: + * + * fatal error (server aborted): not enough arguments for method body%3: (val p: MyProp[java.lang.String])MyProp[_33]. + * Unspecified value parameter p. + */ +object Test { + + def main(args: Array[String]) { + convert(new SubclassProperty) + } + + def convert(prop: TopProperty): MyProp[_] = { + prop match { + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //case SubclassSecondMatch(p) => p // if these lines are present, the compiler crashes. If commented, unsafe byte + //case SecondMatch(p) => p // byte code is generated, which causes a java.lang.VerifyError at runtime + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + case SubclassMatch(p) => p + case StandardMatch(p) => p + } + } +} + +class TopProperty + +class StandardProperty extends TopProperty +class SubclassProperty extends StandardProperty + +class SecondProperty extends TopProperty +class SubclassSecondProperty extends StandardProperty + +trait MyProp[T] +case class MyPropImpl[T] extends MyProp[T] + +object SubclassMatch { + + def unapply(prop: SubclassProperty) : Option[MyProp[String]] = { + Some(new MyPropImpl) + } + + def apply(prop: MyProp[String]) : SubclassProperty = { + new SubclassProperty() + } +} + +object StandardMatch { + + def unapply(prop: StandardProperty) : Option[MyProp[String]] = { + Some(new MyPropImpl) + } + + def apply(prop: MyProp[String]) : StandardProperty = { + new StandardProperty() + } +} + +object SubclassSecondMatch { + + def unapply(prop: SubclassSecondProperty) : Option[MyProp[BigInt]] = { + Some(new MyPropImpl) + } + + def apply(prop: MyProp[String]) : SubclassSecondProperty = { + new SubclassSecondProperty() + } +} + +object SecondMatch { + + def unapply(prop: SecondProperty) : Option[MyProp[BigInt]] = { + Some(new MyPropImpl) + } + + def apply(prop: MyProp[String]) : SecondProperty = { + new SecondProperty() + } +} \ No newline at end of file diff --git a/test/files/run/t5258a.check b/test/files/run/t5258a.check new file mode 100644 index 0000000000..4e0b2da04c --- /dev/null +++ b/test/files/run/t5258a.check @@ -0,0 +1 @@ +int \ No newline at end of file diff --git a/test/files/run/t5258a.scala b/test/files/run/t5258a.scala new file mode 100644 index 0000000000..127829c724 --- /dev/null +++ b/test/files/run/t5258a.scala @@ -0,0 +1,7 @@ +import scala.reflect.mirror._ + +object Test extends App { + reify { + println(classOf[Int]) + }.eval +} \ No newline at end of file -- cgit v1.2.3