diff options
author | Paul Phillips <paulp@improving.org> | 2012-02-22 19:54:36 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-02-22 20:09:40 -0800 |
commit | 06384c052ec31db4bd094b949bed0f3cb3fb644b (patch) | |
tree | 221fe6e2905ebfdf186cc7c828c729ea65450789 /test | |
parent | a983f2b30c352f3d62f0ac615044dcd45b1b1618 (diff) | |
download | scala-06384c052ec31db4bd094b949bed0f3cb3fb644b.tar.gz scala-06384c052ec31db4bd094b949bed0f3cb3fb644b.tar.bz2 scala-06384c052ec31db4bd094b949bed0f3cb3fb644b.zip |
Reworked and restored elidable.
Found a better elidable implementation which is robust against other
parts of the compiler doing their things. Calls to elidable methods are
replaced with zero of the same type. Elidable methods themselves remain
in place, but with their body replaced with a zero of the method return
type.
Thus is everything to be found where it is expected to be found, but
nothing will be found where nothing ought to be found. Nothing of course
will never be found.
Diffstat (limited to 'test')
-rw-r--r-- | test/files/neg/elide-to-nothing.check | 4 | ||||
-rw-r--r-- | test/files/neg/elide-to-nothing.flags | 1 | ||||
-rw-r--r-- | test/files/neg/elide-to-nothing.scala | 31 | ||||
-rw-r--r-- | test/files/run/elidable-opt.check | 14 | ||||
-rw-r--r-- | test/files/run/elidable-opt.flags | 1 | ||||
-rw-r--r-- | test/files/run/elidable-opt.scala | 85 | ||||
-rw-r--r-- | test/files/run/elidable.check | 15 | ||||
-rw-r--r-- | test/files/run/elidable.scala | 73 |
8 files changed, 221 insertions, 3 deletions
diff --git a/test/files/neg/elide-to-nothing.check b/test/files/neg/elide-to-nothing.check new file mode 100644 index 0000000000..3ef05aac9a --- /dev/null +++ b/test/files/neg/elide-to-nothing.check @@ -0,0 +1,4 @@ +elide-to-nothing.scala:14: error: Cannot elide where Nothing is required. + val b: Nothing = unimplemented() + ^ +one error found diff --git a/test/files/neg/elide-to-nothing.flags b/test/files/neg/elide-to-nothing.flags new file mode 100644 index 0000000000..59a512e547 --- /dev/null +++ b/test/files/neg/elide-to-nothing.flags @@ -0,0 +1 @@ +-Xelide-below 500 diff --git a/test/files/neg/elide-to-nothing.scala b/test/files/neg/elide-to-nothing.scala new file mode 100644 index 0000000000..5008e8bc1d --- /dev/null +++ b/test/files/neg/elide-to-nothing.scala @@ -0,0 +1,31 @@ + +/** Test which should fail compilation */ +class ElysianFailed { + + import ElysianField._ + + // fine + val a: Int = myInt + + // fine + unimplemented() + + // not fine + val b: Nothing = unimplemented() + +} + +object ElysianField { + + import annotation.elidable + + @elidable(100) def unimplemented(): Nothing = throw new UnsupportedOperationException + + @elidable(100) def myInt: Int = 17 + +} + + + + + diff --git a/test/files/run/elidable-opt.check b/test/files/run/elidable-opt.check new file mode 100644 index 0000000000..88cf98e0d1 --- /dev/null +++ b/test/files/run/elidable-opt.check @@ -0,0 +1,14 @@ +Good for me, I was not elided. Test.f3 +Good for me, I was not elided. O.f3 +Good for me, I was not elided. C.f1 +Good for me, I was not elided. C.f2 +() +false +0 +0 +0 +0 +0 +0.0 +0.0 +null diff --git a/test/files/run/elidable-opt.flags b/test/files/run/elidable-opt.flags new file mode 100644 index 0000000000..62897ff218 --- /dev/null +++ b/test/files/run/elidable-opt.flags @@ -0,0 +1 @@ +-optimise -Xelide-below 900 diff --git a/test/files/run/elidable-opt.scala b/test/files/run/elidable-opt.scala new file mode 100644 index 0000000000..a2f29d2caf --- /dev/null +++ b/test/files/run/elidable-opt.scala @@ -0,0 +1,85 @@ +import annotation._ +import elidable._ + +trait T { + @elidable(FINEST) def f1() + @elidable(SEVERE) def f2() + @elidable(FINEST) def f3() = assert(false, "Should have been elided.") + def f4() +} + +class C extends T { + def f1() = println("Good for me, I was not elided. C.f1") + def f2() = println("Good for me, I was not elided. C.f2") + @elidable(FINEST) def f4() = assert(false, "Should have been elided.") +} + +object O { + @elidable(FINEST) def f1() = assert(false, "Should have been elided.") + @elidable(INFO) def f2() = assert(false, "Should have been elided.") + @elidable(SEVERE) def f3() = println("Good for me, I was not elided. O.f3") + @elidable(INFO) def f4 = assert(false, "Should have been elided (no parens).") +} + +object Test { + @elidable(FINEST) def f1() = assert(false, "Should have been elided.") + @elidable(INFO) def f2() = assert(false, "Should have been elided.") + @elidable(SEVERE) def f3() = println("Good for me, I was not elided. Test.f3") + @elidable(INFO) def f4 = assert(false, "Should have been elided (no parens).") + + @elidable(FINEST) def f5() = {} + @elidable(FINEST) def f6() = true + @elidable(FINEST) def f7() = 1:Byte + @elidable(FINEST) def f8() = 1:Short + @elidable(FINEST) def f9() = 1:Char + @elidable(FINEST) def fa() = 1 + @elidable(FINEST) def fb() = 1l + @elidable(FINEST) def fc() = 1.0f + @elidable(FINEST) def fd() = 1.0 + @elidable(FINEST) def fe() = "s" + + def main(args: Array[String]): Unit = { + f1() + f2() + f3() + f4 + O.f1() + O.f2() + O.f3() + O.f4 + + val c = new C + c.f1() + c.f2() + c.f3() + c.f4() + + // make sure a return value is still available when eliding a call + println(f5()) + println(f6()) + println(f7()) + println(f8()) + println(f9().toInt) + println(fa()) + println(fb()) + println(fc()) + println(fd()) + println(fe()) + + // this one won't show up in the output because a call to f1 is elidable when accessed through T + (c:T).f1() + + // Test whether the method definitions are still available. + List("Test", "Test$", "O", "O$", "C", "T") foreach { className => + List("f1", "f2", "f3", "f4") foreach { methodName => + Class.forName(className).getMethod(methodName) + } + } + List("Test", "Test$") foreach { className => + List("f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe") foreach { methodName => + Class.forName(className).getMethod(methodName) + } + } + Class.forName("T$class").getMethod("f3", classOf[T]) + } +} diff --git a/test/files/run/elidable.check b/test/files/run/elidable.check index 4ce04f0040..88cf98e0d1 100644 --- a/test/files/run/elidable.check +++ b/test/files/run/elidable.check @@ -1 +1,14 @@ -Good for me, I was not elided. +Good for me, I was not elided. Test.f3 +Good for me, I was not elided. O.f3 +Good for me, I was not elided. C.f1 +Good for me, I was not elided. C.f2 +() +false +0 +0 +0 +0 +0 +0.0 +0.0 +null diff --git a/test/files/run/elidable.scala b/test/files/run/elidable.scala index 264efbad59..a2f29d2caf 100644 --- a/test/files/run/elidable.scala +++ b/test/files/run/elidable.scala @@ -1,16 +1,85 @@ import annotation._ import elidable._ +trait T { + @elidable(FINEST) def f1() + @elidable(SEVERE) def f2() + @elidable(FINEST) def f3() = assert(false, "Should have been elided.") + def f4() +} + +class C extends T { + def f1() = println("Good for me, I was not elided. C.f1") + def f2() = println("Good for me, I was not elided. C.f2") + @elidable(FINEST) def f4() = assert(false, "Should have been elided.") +} + +object O { + @elidable(FINEST) def f1() = assert(false, "Should have been elided.") + @elidable(INFO) def f2() = assert(false, "Should have been elided.") + @elidable(SEVERE) def f3() = println("Good for me, I was not elided. O.f3") + @elidable(INFO) def f4 = assert(false, "Should have been elided (no parens).") +} + object Test { @elidable(FINEST) def f1() = assert(false, "Should have been elided.") @elidable(INFO) def f2() = assert(false, "Should have been elided.") - @elidable(SEVERE) def f3() = println("Good for me, I was not elided.") + @elidable(SEVERE) def f3() = println("Good for me, I was not elided. Test.f3") @elidable(INFO) def f4 = assert(false, "Should have been elided (no parens).") - + + @elidable(FINEST) def f5() = {} + @elidable(FINEST) def f6() = true + @elidable(FINEST) def f7() = 1:Byte + @elidable(FINEST) def f8() = 1:Short + @elidable(FINEST) def f9() = 1:Char + @elidable(FINEST) def fa() = 1 + @elidable(FINEST) def fb() = 1l + @elidable(FINEST) def fc() = 1.0f + @elidable(FINEST) def fd() = 1.0 + @elidable(FINEST) def fe() = "s" + def main(args: Array[String]): Unit = { f1() f2() f3() f4 + O.f1() + O.f2() + O.f3() + O.f4 + + val c = new C + c.f1() + c.f2() + c.f3() + c.f4() + + // make sure a return value is still available when eliding a call + println(f5()) + println(f6()) + println(f7()) + println(f8()) + println(f9().toInt) + println(fa()) + println(fb()) + println(fc()) + println(fd()) + println(fe()) + + // this one won't show up in the output because a call to f1 is elidable when accessed through T + (c:T).f1() + + // Test whether the method definitions are still available. + List("Test", "Test$", "O", "O$", "C", "T") foreach { className => + List("f1", "f2", "f3", "f4") foreach { methodName => + Class.forName(className).getMethod(methodName) + } + } + List("Test", "Test$") foreach { className => + List("f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe") foreach { methodName => + Class.forName(className).getMethod(methodName) + } + } + Class.forName("T$class").getMethod("f3", classOf[T]) } } |