Skip to content

Commit 17a1abb

Browse files
committed
SI-8852 Support joint compilation of Java interfaces w. statics
We had to change the java parser to accomodate this language change in Java 8. The enclosed test does not require JDK8 to run, it only tests JavaParsers. Here is a transcript of my manual testing using Java 8. ``` % tail test/files/run/8852b/{Interface.java,client.scala} ==> test/files/run/8852b/Interface.java <== public interface Interface { public static int staticMethod() { return 42; } } ==> test/files/run/8852b/client.scala <== object Test extends App { assert(Interface.staticMethod() == 42) } // Under separate compilation, statics in interfaces were already working % rm /tmp/*.class 2> /dev/null; javac -d /tmp test/files/run/8852b/Interface.java && scalac-hash v2.11.2 -classpath /tmp -d /tmp test/files/run/8852b/client.scala && scala-hash v2.11.2 -classpath /tmp -nc Test // Under joint compilation, statics in interfaces now work. % rm /tmp/*.class 2> /dev/null; qscalac -d /tmp test/files/run/8852b/{client.scala,Interface.java} && javac -d /tmp test/files/run/8852b/Interface.java && qscala -classpath /tmp -nc Test ```
1 parent 223e207 commit 17a1abb

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

src/compiler/scala/tools/nsc/javac/JavaParsers.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
488488
val vparams = formalParams()
489489
if (!isVoid) rtpt = optArrayBrackets(rtpt)
490490
optThrows()
491-
val bodyOk = !inInterface || (mods hasFlag Flags.DEFAULTMETHOD)
491+
val isStatic = mods hasFlag Flags.STATIC
492+
val bodyOk = !inInterface || ((mods hasFlag Flags.DEFAULTMETHOD) || isStatic)
492493
val body =
493494
if (bodyOk && in.token == LBRACE) {
494495
methodBody()
@@ -507,7 +508,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
507508
EmptyTree
508509
}
509510
}
510-
if (inInterface) mods1 |= Flags.DEFERRED
511+
if (inInterface && !isStatic) mods1 |= Flags.DEFERRED
511512
List {
512513
atPos(pos) {
513514
DefDef(mods1, name.toTermName, tparams, List(vparams), rtpt, body)

test/files/run/t8852a.scala

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import scala.tools.partest._
2+
3+
// Test that static methods in Java interfaces (new in Java 8)
4+
// are callable from jointly compiler Scala code.
5+
object Test extends CompilerTest {
6+
import global._
7+
8+
override lazy val units: List[CompilationUnit] = {
9+
// This test itself does not depend on JDK8.
10+
javaCompilationUnits(global)(staticMethodInInterface) ++
11+
compilationUnits(global)(scalaClient)
12+
}
13+
14+
private def staticMethodInInterface = """
15+
public interface Interface {
16+
public static int staticMethod() {
17+
return 42;
18+
}
19+
}
20+
21+
"""
22+
23+
private def scalaClient = """
24+
object Test {
25+
val x: Int = Interface.staticMethod()
26+
}
27+
28+
class C extends Interface // expect no errors about unimplemented members.
29+
30+
"""
31+
32+
// We're only checking we can compile it.
33+
def check(source: String, unit: global.CompilationUnit): Unit = ()
34+
}

0 commit comments

Comments
 (0)