1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
scala> class Annot(obj: Any) extends annotation.Annotation with annotation.TypeConstraint
defined class Annot
scala>
scala> class A {
val x = "hello"
val y: Int @Annot(x) = 10
override def toString = "an A"
}
defined class A
scala>
scala> val a = new A
a: A = an A
scala> val y = a.y // should rewrite "this.x" to "a.x"
y: Int @Annot(a.x) = 10
scala> var a2 = new A
a2: A = an A
scala> val y2 = a2.y // should drop the annotation
y2: Int = 10
scala>
scala> object Stuff {
val x = "hello"
val y : Int @Annot(x) = 10
}
defined object Stuff
scala>
scala> val y = Stuff.y // should rewrite the annotation
y: Int @Annot(Stuff.x) = 10
scala>
scala> class B {
val y: Int @Annot(Stuff.x) = 10
override def toString = "a B"
}
defined class B
scala>
scala> val b = new B
b: B = a B
scala> val y = b.y // should keep the annotation
y: Int @Annot(Stuff.x) = 10
scala> def m(x: String): String @Annot(x) = x
m: (x: String)String @Annot(x)
scala>
scala> val three = "three"
three: String = three
scala> val three2 = m(three:three.type) // should change x to three
three2: String @Annot(three) = three
scala> var four = "four"
four: String = four
scala> val four2 = m(four) // should have an existential bound
warning: there was one feature warning; re-run with -feature for details
four2: String @Annot(x) forSome { val x: String } = four
scala> val four3 = four2 // should have the same type as four2
warning: there was one feature warning; re-run with -feature for details
four3: String @Annot(x) forSome { val x: String } = four
scala> val stuff = m("stuff") // should not crash
stuff: String @Annot("stuff") = stuff
scala>
scala> class peer extends annotation.Annotation // should not crash
defined class peer
scala>
scala> class NPE[T <: NPE[T] @peer] // should not crash
defined class NPE
scala>
scala> def m = {
val x = "three"
val y : String @Annot(x) = x
y
} // x should not escape the local scope with a narrow type
warning: there was one feature warning; re-run with -feature for details
m: String @Annot(x) forSome { val x: String }
scala>
scala> 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
warning: there was one feature warning; re-run with -feature for details
n: (y: String)String @Annot(x) forSome { val x: String }
scala>
scala> class rep extends annotation.Annotation { }
defined class rep
scala>
scala> object A { val x = "hello" : String @ rep }
defined object A
warning: previously defined class A is not a companion to object A.
Companions must be defined together; you may wish to use :paste mode for this.
scala>
scala> val y = a.x // should drop the annotation
y: String = hello
scala>
scala> val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
<console>:12: error: not found: value e
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
<console>:12: error: not found: value f
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
<console>:12: error: not found: value g
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
<console>:12: error: not found: value h
val x = 3 : Int @Annot(e+f+g+h) // should have a graceful error message
^
scala> :quit
|