summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/files/run/constrained-types.check136
-rw-r--r--test/files/run/constrained-types.scala103
2 files changed, 239 insertions, 0 deletions
diff --git a/test/files/run/constrained-types.check b/test/files/run/constrained-types.check
new file mode 100644
index 0000000000..c8f0a83ad3
--- /dev/null
+++ b/test/files/run/constrained-types.check
@@ -0,0 +1,136 @@
+class Annot(obj: Any) extends Annotation with TypeConstraint
+defined class Annot
+
+-----
+class A {
+ val x = "hello"
+ val y: Int @Annot(x) = 10
+ override def toString = "an A"
+}
+defined class A
+
+-----
+val a = new A
+a: A = an A
+
+-----
+val y = a.y // should rewrite "this.x" to "a.x"
+y: Int @Annot(a.x) = 10
+
+-----
+var a2 = new A
+a2: A = an A
+
+-----
+val y2 = a2.y // should drop the annotation
+y2: Int = 10
+
+-----
+object Stuff {
+ val x = "hello"
+ val y : Int @Annot(x) = 10
+}
+defined module Stuff
+
+-----
+val y = Stuff.y // should rewrite the annotation
+y: Int @Annot(Stuff.x) = 10
+
+-----
+class B {
+ val y: Int @Annot(Stuff.x) = 10
+ override def toString = "a B"
+}
+defined class B
+
+-----
+val b = new B
+b: B = a B
+
+-----
+val y = b.y // should keep the annotation
+y: Int @Annot(Stuff.x) = 10
+
+-----
+def m(x: String): String @Annot(x) = x // m should be annotated with a debruijn
+m: (x$0:String)String @Annot(x)
+
+-----
+val three = "three"
+three: java.lang.String = three
+
+-----
+val three2 = m(three:three.type) // should change x to three
+three2: String @Annot(three) = three
+
+-----
+var four = "four"
+four: java.lang.String = four
+
+-----
+val four2 = m(four) // should have an existential bound
+four2: String @Annot(x) forSome { val x: java.lang.String } = four
+
+-----
+val four3 = four2 // should have the same type as four2
+four3: String @Annot(x) forSome { val x: java.lang.String } = four
+
+-----
+val stuff = m("stuff") // should not crash
+stuff: String @Annot("stuff") = stuff
+
+-----
+class peer extends Annotation // should not crash
+defined class peer
+
+-----
+class NPE[T <: NPE[T] @peer] // should not crash
+error: illegal cyclic reference involving class NPE
+
+-----
+def m = {
+ val x = "three"
+ val y : String @Annot(x) = x
+ y
+} // x should be existentially bound
+m: String @Annot(x) forSome { val x: java.lang.String }
+
+-----
+def n(y: String) = {
+ def m(x: String) : String @Annot(x) = {
+ (if (x == "")
+ m("default")
+ else
+ x)
+ }
+ m("stuff".stripMargin)
+} // x should be existentially bound
+n: (String)String @Annot(x) forSome { val x: String }
+
+-----
+class rep extends Annotation
+defined class rep
+
+-----
+object A { val x = "hello" : String @ rep }
+defined module A
+
+-----
+val y = a.x // should drop the annotation
+y: java.lang.String = hello
+
+-----
+val x = 3 : Int @Annot(e+f+g+h) //should have a graceful error message
+<console>:5: error: not found: value e
+ val x = 3 : Int @Annot(e+f+g+h) //should have a graceful error message
+ ^
+
+-----
+class Where(condition: Boolean) extends Annotation
+defined class Where
+
+-----
+val x : Int @Where(self > 0 && self < 100) = 3
+x: Int @Where(self.>(0).&&(self.<(100))) = 3
+
+-----
diff --git a/test/files/run/constrained-types.scala b/test/files/run/constrained-types.scala
new file mode 100644
index 0000000000..9a6d31cf6d
--- /dev/null
+++ b/test/files/run/constrained-types.scala
@@ -0,0 +1,103 @@
+/* Check on the processing of annotated types. Initially this tested
+ * asSeenFrom, but now it also tests packedType and the treatment
+ * of DeBruijn's . It runs the test using the interpreter so that
+ * the resulting annotated types can be printed out.
+ */
+import scala.tools.nsc._
+import java.io._
+import scala.Console
+
+object Test {
+
+ val testCode = List(
+ "class Annot(obj: Any) extends Annotation with TypeConstraint",
+
+ """class A {
+ | val x = "hello"
+ | val y: Int @Annot(x) = 10
+ | override def toString = "an A"
+ |} """,
+
+
+
+ "val a = new A",
+
+ """val y = a.y // should rewrite "this.x" to "a.x" """,
+
+
+ "var a2 = new A",
+ "val y2 = a2.y // should drop the annotation",
+
+
+ """object Stuff {
+ | val x = "hello"
+ | val y : Int @Annot(x) = 10
+ |}""",
+
+ "val y = Stuff.y // should rewrite the annotation",
+
+ """class B {
+ | val y: Int @Annot(Stuff.x) = 10
+ | override def toString = "a B"
+ |}""",
+
+ "val b = new B",
+ "val y = b.y // should keep the annotation",
+
+
+ "def m(x: String): String @Annot(x) = x // m should be annotated with a debruijn",
+ "val three = \"three\"",
+ "val three2 = m(three:three.type) // should change x to three",
+ "var four = \"four\"",
+ "val four2 = m(four) // should have an existential bound",
+ "val four3 = four2 // should have the same type as four2",
+
+ """val stuff = m("stuff") // should not crash""",
+
+ """class peer extends Annotation // should not crash""", // reported by Manfred Stock
+ """class NPE[T <: NPE[T] @peer] // should not crash""", // reported by Manfred Stock
+
+ """def m = {
+ | val x = "three"
+ | val y : String @Annot(x) = x
+ | y
+ |} // x should be existentially bound""",
+
+ """def n(y: String) = {
+ | def m(x: String) : String @Annot(x) = {
+ | (if (x == "")
+ | m("default")
+ | else
+ | x)
+ | }
+ | m("stuff".stripMargin)
+ |} // x should be existentially bound""",
+
+ "class rep extends Annotation",
+ """object A { val x = "hello" : String @ rep }""",
+ "val y = a.x // should drop the annotation",
+
+ "val x = 3 : Int @Annot(e+f+g+h) //should have a graceful error message",
+
+ "class Where(condition: Boolean) extends Annotation",
+ "val x : Int @Where(self > 0 && self < 100) = 3"
+ ).map(_.stripMargin)
+
+
+
+ def main(args: Array[String]) {
+ val settings = new Settings
+ settings.Xplugtypes.value = true
+ settings.Xexperimental.value = true
+ settings.selfInAnnots.value = true
+
+ val interp = new Interpreter(settings)
+
+ for (cmd <- testCode) {
+ println(cmd)
+ interp.interpret(cmd)
+ println()
+ println("-----")
+ }
+ }
+}