Skip to content

Commit

Permalink
add test cases for abstract methods
Browse files Browse the repository at this point in the history
  • Loading branch information
lihaoyi committed Feb 11, 2024
1 parent 3b91875 commit 3d437a5
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 2 deletions.
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# unroll
# @Unroll


Unroll provides an experimental `@Unroll` annotation that can be applied to methods, classes,
Expand Down Expand Up @@ -145,6 +145,37 @@ object Unrolled{
}
```

### Abstract Methods

```scala
import unroll.Unroll

trait Unrolled{
def foo(s: String, n: Int = 1, @Unroll b: Boolean = true): String
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true) = s + n + b
}
```

Unrolls to:

```scala
trait Unrolled{
def foo(s: String, n: Int = 1, @Unroll b: Boolean = true): String
def foo(s: String, n: Int = 1): String = foo(s, n, true)
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true) = s + n + b
}
```

Note that only the abstract method needs to be `@Unroll`ed, as the generated forwarder
methods are concrete. The concrete implementation `class` or `object` does not need to
`@Unroll` its implementation method, as it only needs to implement the abstract `@Unroll`ed
method and not the concrete forwarders.

## Limitations

Expand Down
4 changes: 3 additions & 1 deletion build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ trait UnrollModule extends Cross.Module[String]{
"methodWithImplicit",
"primaryConstructor",
"secondaryConstructor",
"caseclass"
"caseclass",
"abstractTraitMethod",
"abstractClassMethod"
)


Expand Down
41 changes: 41 additions & 0 deletions unroll/tests/abstractClassMethod/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package unroll

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val instance = new Unrolled {}
val cls = classOf[Unrolled]

assert(scala.util.Try(cls.getMethod("foo", classOf[String])).isFailure)
println()
assert(
cls.getMethod("foo", classOf[String], classOf[Int]).invoke(instance, "hello", 2: Integer) ==
"hello2true0"
)
assert(
cls.getMethod("foo", classOf[String], classOf[Int], classOf[Boolean])
.invoke(instance, "hello", 2: Integer, java.lang.Boolean.FALSE) ==
"hello2false0"
)
assert(
cls.getMethod("foo", classOf[String], classOf[Int], classOf[Boolean], classOf[Long])
.invoke(instance, "hello", 2: Integer, java.lang.Boolean.FALSE, 3: Integer) ==
"hello2false3"
)

cls.getMethods.filter(_.getName.contains("foo")).foreach(println)
}
}














13 changes: 13 additions & 0 deletions unroll/tests/abstractClassMethod/v1/src/Unrolled.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package unroll

abstract class Unrolled{
def foo(s: String, n: Int = 1): String
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1) = s + n
}

class UnrolledCls extends Unrolled{
def foo(s: String, n: Int = 1) = s + n
}
14 changes: 14 additions & 0 deletions unroll/tests/abstractClassMethod/v1/test/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package unroll

import unroll.TestUtils.logAssertStartsWith

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val unrolled = new UnrolledCls
logAssertStartsWith(unrolled.foo("cow"), "cow1")
logAssertStartsWith(unrolled.foo("cow", 2), "cow2")

logAssertStartsWith(Unrolled.foo("cow"), "cow1")
logAssertStartsWith(Unrolled.foo("cow", 2), "cow2")
}
}
13 changes: 13 additions & 0 deletions unroll/tests/abstractClassMethod/v2/src/Unrolled.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package unroll

abstract class Unrolled{
def foo(s: String, n: Int = 1, @Unroll b: Boolean = true): String
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true) = s + n + b
}

class UnrolledCls extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true) = s + n + b
}
30 changes: 30 additions & 0 deletions unroll/tests/abstractClassMethod/v2/test/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package unroll

import unroll.TestUtils.logAssertStartsWith

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val unrolled = new UnrolledCls
logAssertStartsWith(unrolled.foo("cow"), "cow1true")
logAssertStartsWith(unrolled.foo("cow", 2), "cow2true")
logAssertStartsWith(unrolled.foo("cow", 2, false), "cow2false")

logAssertStartsWith(Unrolled.foo("cow"), "cow1true")
logAssertStartsWith(Unrolled.foo("cow", 2), "cow2true")
logAssertStartsWith(Unrolled.foo("cow", 2, false), "cow2false")
}
}














12 changes: 12 additions & 0 deletions unroll/tests/abstractClassMethod/v3/src/Unrolled.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package unroll

abstract class Unrolled{
def foo(s: String, n: Int = 1, @Unroll b: Boolean = true, l: Long = 0): String
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true, l: Long = 0) = s + n + b + l
}
class UnrolledCls extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true, l: Long = 0) = s + n + b + l
}
32 changes: 32 additions & 0 deletions unroll/tests/abstractClassMethod/v3/test/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package unroll

import unroll.TestUtils.logAssertStartsWith

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val unrolled = new UnrolledCls
logAssertStartsWith(unrolled.foo("cow"), "cow1true0")
logAssertStartsWith(unrolled.foo("cow", 2), "cow2true0")
logAssertStartsWith(unrolled.foo("cow", 2, false), "cow2false0")
logAssertStartsWith(unrolled.foo("cow", 2, false, 3), "cow2false3")

logAssertStartsWith(Unrolled.foo("cow"), "cow1true0")
logAssertStartsWith(Unrolled.foo("cow", 2), "cow2true0")
logAssertStartsWith(Unrolled.foo("cow", 2, false), "cow2false0")
logAssertStartsWith(Unrolled.foo("cow", 2, false, 3), "cow2false3")
}
}














41 changes: 41 additions & 0 deletions unroll/tests/abstractTraitMethod/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package unroll

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val instance = new Unrolled {}
val cls = classOf[Unrolled]

assert(scala.util.Try(cls.getMethod("foo", classOf[String])).isFailure)
println()
assert(
cls.getMethod("foo", classOf[String], classOf[Int]).invoke(instance, "hello", 2: Integer) ==
"hello2true0"
)
assert(
cls.getMethod("foo", classOf[String], classOf[Int], classOf[Boolean])
.invoke(instance, "hello", 2: Integer, java.lang.Boolean.FALSE) ==
"hello2false0"
)
assert(
cls.getMethod("foo", classOf[String], classOf[Int], classOf[Boolean], classOf[Long])
.invoke(instance, "hello", 2: Integer, java.lang.Boolean.FALSE, 3: Integer) ==
"hello2false3"
)

cls.getMethods.filter(_.getName.contains("foo")).foreach(println)
}
}














13 changes: 13 additions & 0 deletions unroll/tests/abstractTraitMethod/v1/src/Unrolled.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package unroll

trait Unrolled{
def foo(s: String, n: Int = 1): String
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1) = s + n
}

class UnrolledCls extends Unrolled{
def foo(s: String, n: Int = 1) = s + n
}
14 changes: 14 additions & 0 deletions unroll/tests/abstractTraitMethod/v1/test/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package unroll

import unroll.TestUtils.logAssertStartsWith

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val unrolled = new UnrolledCls
logAssertStartsWith(unrolled.foo("cow"), "cow1")
logAssertStartsWith(unrolled.foo("cow", 2), "cow2")

logAssertStartsWith(Unrolled.foo("cow"), "cow1")
logAssertStartsWith(Unrolled.foo("cow", 2), "cow2")
}
}
13 changes: 13 additions & 0 deletions unroll/tests/abstractTraitMethod/v2/src/Unrolled.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package unroll

trait Unrolled{
def foo(s: String, n: Int = 1, @Unroll b: Boolean = true): String
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true) = s + n + b
}

class UnrolledCls extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true) = s + n + b
}
30 changes: 30 additions & 0 deletions unroll/tests/abstractTraitMethod/v2/test/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package unroll

import unroll.TestUtils.logAssertStartsWith

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val unrolled = new UnrolledCls
logAssertStartsWith(unrolled.foo("cow"), "cow1true")
logAssertStartsWith(unrolled.foo("cow", 2), "cow2true")
logAssertStartsWith(unrolled.foo("cow", 2, false), "cow2false")

logAssertStartsWith(Unrolled.foo("cow"), "cow1true")
logAssertStartsWith(Unrolled.foo("cow", 2), "cow2true")
logAssertStartsWith(Unrolled.foo("cow", 2, false), "cow2false")
}
}














12 changes: 12 additions & 0 deletions unroll/tests/abstractTraitMethod/v3/src/Unrolled.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package unroll

trait Unrolled{
def foo(s: String, n: Int = 1, @Unroll b: Boolean = true, l: Long = 0): String
}

object Unrolled extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true, l: Long = 0) = s + n + b + l
}
class UnrolledCls extends Unrolled{
def foo(s: String, n: Int = 1, b: Boolean = true, l: Long = 0) = s + n + b + l
}
32 changes: 32 additions & 0 deletions unroll/tests/abstractTraitMethod/v3/test/src/UnrollTestMain.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package unroll

import unroll.TestUtils.logAssertStartsWith

object UnrollTestMain{
def main(args: Array[String]): Unit = {
val unrolled = new UnrolledCls
logAssertStartsWith(unrolled.foo("cow"), "cow1true0")
logAssertStartsWith(unrolled.foo("cow", 2), "cow2true0")
logAssertStartsWith(unrolled.foo("cow", 2, false), "cow2false0")
logAssertStartsWith(unrolled.foo("cow", 2, false, 3), "cow2false3")

logAssertStartsWith(Unrolled.foo("cow"), "cow1true0")
logAssertStartsWith(Unrolled.foo("cow", 2), "cow2true0")
logAssertStartsWith(Unrolled.foo("cow", 2, false), "cow2false0")
logAssertStartsWith(Unrolled.foo("cow", 2, false, 3), "cow2false3")
}
}














0 comments on commit 3d437a5

Please sign in to comment.