diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-03-16 16:14:27 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-03-18 11:49:33 +1000 |
commit | c8e6050c3c190dd064642b6b77fc179f27b0495d (patch) | |
tree | 467cd7042e9d889c797bde34bc00be676d668cac /test/junit/scala/tools/nsc/symtab | |
parent | 699a5d907943330c59cea8e7b1abb536af8e5885 (diff) | |
download | scala-c8e6050c3c190dd064642b6b77fc179f27b0495d.tar.gz scala-c8e6050c3c190dd064642b6b77fc179f27b0495d.tar.bz2 scala-c8e6050c3c190dd064642b6b77fc179f27b0495d.zip |
New trait encoding: use default methods, jettison impl classes
Until now, concrete methods in traits were encoded with
"trait implementation classes".
- Such a trait would compile to two class files
- the trait interface, a Java interface, and
- the implementation class, containing "trait implementation methods"
- trait implementation methods are static methods has an explicit self
parameter.
- some methods don't require addition of an interface method, such as
private methods. Calls to these directly call the implementation method
- classes that mixin a trait install "trait forwarders", which implement
the abstract method in the interface by forwarding to the trait
implementation method.
The new encoding:
- no longer emits trait implementation classes or trait implementation
methods.
- instead, concrete methods are simply retained in the interface, as JVM 8
default interface methods (the JVM spec changes in
[JSR-335](http://download.oracle.com/otndocs/jcp/lambda-0_9_3-fr-eval-spec/index.html)
pave the way)
- use `invokespecial` to call private or particular super implementations
of a method (rather `invokestatic`)
- in cases when we `invokespecial` to a method in an indirect ancestor, we add
that ancestor redundantly as a direct parent. We are investigating alternatives
approaches here.
- we still emit trait fowrarders, although we are
[investigating](https://github.com/scala/scala-dev/issues/98) ways to only do
this when the JVM would be unable to resolve the correct method using its rules
for default method resolution.
Here's an example:
```
trait T {
println("T")
def m1 = m2
private def m2 = "m2"
}
trait U extends T {
println("T")
override def m1 = super[T].m1
}
class C extends U {
println("C")
def test = m1
}
```
The old and new encodings are displayed and diffed here: https://gist.github.com/retronym/f174d23f859f0e053580
Some notes in the implementation:
- No need to filter members from class decls at all in AddInterfaces
(although we do have to trigger side effecting info transformers)
- We can now emit an EnclosingMethod attribute for classes nested
in private trait methods
- Created a factory method for an AST shape that is used in
a number of places to symbolically bind to a particular
super method without needed to specify the qualifier of
the `Super` tree (which is too limiting, as it only allows
you to refer to direct parents.)
- I also found a similar tree shape created in Delambdafy,
that is better expressed with an existing tree creation
factory method, mkSuperInit.
Diffstat (limited to 'test/junit/scala/tools/nsc/symtab')
-rw-r--r-- | test/junit/scala/tools/nsc/symtab/FlagsTest.scala | 1 |
1 files changed, 0 insertions, 1 deletions
diff --git a/test/junit/scala/tools/nsc/symtab/FlagsTest.scala b/test/junit/scala/tools/nsc/symtab/FlagsTest.scala index 08a37fcb3c..96eae38011 100644 --- a/test/junit/scala/tools/nsc/symtab/FlagsTest.scala +++ b/test/junit/scala/tools/nsc/symtab/FlagsTest.scala @@ -33,7 +33,6 @@ class FlagsTest { def testTimedFlags(): Unit = { testLate(lateDEFERRED, _.isDeferred) testLate(lateFINAL, _.isFinal) - testLate(lateINTERFACE, _.isInterface) testLate(lateMETHOD, _.isMethod) testLate(lateMODULE, _.isModule) testNot(PROTECTED | notPROTECTED, _.isProtected) |