diff options
Diffstat (limited to 'test/files/run')
-rw-r--r-- | test/files/run/constrained-types.check | 136 | ||||
-rw-r--r-- | test/files/run/constrained-types.scala | 103 |
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("-----") + } + } +} |