summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-09-18 16:01:57 +1000
committerJason Zaugg <jzaugg@gmail.com>2014-09-18 16:01:57 +1000
commit17a1abbff6816d0693bb98869cd26c25f695cffa (patch)
treed7db88ab5d0a81d0c1b3a2dc1a5aa21042cf4185
parent223e207e5a4904bf9a6bd70972fa69452d228529 (diff)
downloadscala-17a1abbff6816d0693bb98869cd26c25f695cffa.tar.gz
scala-17a1abbff6816d0693bb98869cd26c25f695cffa.tar.bz2
scala-17a1abbff6816d0693bb98869cd26c25f695cffa.zip
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 ```
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala5
-rw-r--r--test/files/run/t8852a.scala34
2 files changed, 37 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 37b00aa9a3..9433ddcf31 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -488,7 +488,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val vparams = formalParams()
if (!isVoid) rtpt = optArrayBrackets(rtpt)
optThrows()
- val bodyOk = !inInterface || (mods hasFlag Flags.DEFAULTMETHOD)
+ val isStatic = mods hasFlag Flags.STATIC
+ val bodyOk = !inInterface || ((mods hasFlag Flags.DEFAULTMETHOD) || isStatic)
val body =
if (bodyOk && in.token == LBRACE) {
methodBody()
@@ -507,7 +508,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
EmptyTree
}
}
- if (inInterface) mods1 |= Flags.DEFERRED
+ if (inInterface && !isStatic) mods1 |= Flags.DEFERRED
List {
atPos(pos) {
DefDef(mods1, name.toTermName, tparams, List(vparams), rtpt, body)
diff --git a/test/files/run/t8852a.scala b/test/files/run/t8852a.scala
new file mode 100644
index 0000000000..cbff8ab75b
--- /dev/null
+++ b/test/files/run/t8852a.scala
@@ -0,0 +1,34 @@
+import scala.tools.partest._
+
+// Test that static methods in Java interfaces (new in Java 8)
+// are callable from jointly compiler Scala code.
+object Test extends CompilerTest {
+ import global._
+
+ override lazy val units: List[CompilationUnit] = {
+ // This test itself does not depend on JDK8.
+ javaCompilationUnits(global)(staticMethodInInterface) ++
+ compilationUnits(global)(scalaClient)
+ }
+
+ private def staticMethodInInterface = """
+public interface Interface {
+ public static int staticMethod() {
+ return 42;
+ }
+}
+
+ """
+
+ private def scalaClient = """
+object Test {
+ val x: Int = Interface.staticMethod()
+}
+
+class C extends Interface // expect no errors about unimplemented members.
+
+ """
+
+ // We're only checking we can compile it.
+ def check(source: String, unit: global.CompilationUnit): Unit = ()
+}