summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala9
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala4
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala20
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala37
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala4
6 files changed, 67 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
index 7b2686e7a9..f6b640bea4 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
@@ -1145,8 +1145,7 @@ object BTypes {
final case class InlineInfo(isEffectivelyFinal: Boolean,
sam: Option[String],
methodInfos: Map[String, MethodInlineInfo],
- warning: Option[ClassInlineInfoWarning]) {
- }
+ warning: Option[ClassInlineInfoWarning])
val EmptyInlineInfo = InlineInfo(false, None, Map.empty, None)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
index 1a4590e7d1..e0f0f269cb 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala
@@ -557,9 +557,16 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
var warning = Option.empty[ClassSymbolInfoFailureSI9111]
+ def keepMember(sym: Symbol) = sym.isMethod && !scalaPrimitives.isPrimitive(sym)
+ val classMethods = classSym.info.decls.iterator.filter(keepMember)
+ val methods = if (!classSym.isJavaDefined) classMethods else {
+ val staticMethods = classSym.companionModule.info.decls.iterator.filter(m => !m.isConstructor && keepMember(m))
+ staticMethods ++ classMethods
+ }
+
// Primitive methods cannot be inlined, so there's no point in building a MethodInlineInfo. Also, some
// primitive methods (e.g., `isInstanceOf`) have non-erased types, which confuses [[typeToBType]].
- val methodInlineInfos = classSym.info.decls.iterator.filter(m => m.isMethod && !scalaPrimitives.isPrimitive(m)).flatMap({
+ val methodInlineInfos = methods.flatMap({
case methodSym =>
if (completeSilentlyAndCheckErroneous(methodSym)) {
// Happens due to SI-9111. Just don't provide any MethodInlineInfo for that method, we don't need fail the compiler.
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
index 7b640ac54f..72a371cabc 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
@@ -96,8 +96,8 @@ object BackendReporting {
val missingClassWarning = missingClass match {
case None => ""
case Some(c) =>
- if (c.definedInJavaSource) s"\nNote that the parent class ${c.internalName} is defined in a Java source (mixed compilation), no bytecode is available."
- else s"\nNote that the parent class ${c.internalName} could not be found on the classpath."
+ if (c.definedInJavaSource) s"\nNote that class ${c.internalName} is defined in a Java source (mixed compilation), no bytecode is available."
+ else s"\nNote that class ${c.internalName} could not be found on the classpath."
}
s"The method $name$descriptor could not be found in the class $ownerInternalName or any of its parents." + missingClassWarning
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala
index a691d63471..6f098e1432 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineInfoTest.scala
@@ -2,18 +2,20 @@ package scala.tools.nsc
package backend.jvm
package opt
+import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import scala.collection.JavaConverters._
import scala.collection.generic.Clearable
+import scala.tools.nsc.backend.jvm.BTypes.MethodInlineInfo
import scala.tools.nsc.backend.jvm.BackendReporting._
import scala.tools.testing.BytecodeTesting
@RunWith(classOf[JUnit4])
class InlineInfoTest extends BytecodeTesting {
- import compiler.global
+ import compiler._
import global.genBCode.bTypes
override def compilerArgs = "-opt:l:classpath"
@@ -59,4 +61,20 @@ class InlineInfoTest extends BytecodeTesting {
assert(fromSyms == fromAttrs)
}
+
+ @Test // scala-dev#20
+ def javaStaticMethodsInlineInfoInMixedCompilation(): Unit = {
+ val jCode =
+ """public class A {
+ | public static final int bar() { return 100; }
+ | public final int baz() { return 100; }
+ |}
+ """.stripMargin
+ compileClasses("class C { new A }", javaCode = List((jCode, "A.java")))
+ val info = global.genBCode.bTypes.classBTypeFromInternalName("A").info.get.inlineInfo
+ assertEquals(info.methodInfos, Map(
+ "bar()I" -> MethodInlineInfo(true,false,false),
+ "<init>()V" -> MethodInlineInfo(false,false,false),
+ "baz()I" -> MethodInlineInfo(true,false,false)))
+ }
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
index 5254d7e1f2..5bd2ce68f1 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
@@ -75,12 +75,12 @@ class InlineWarningTest extends BytecodeTesting {
val warns = List(
"""failed to determine if bar should be inlined:
|The method bar()I could not be found in the class A or any of its parents.
- |Note that the parent class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin,
+ |Note that class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin,
"""B::flop()I is annotated @inline but could not be inlined:
|Failed to check if B::flop()I can be safely inlined to B without causing an IllegalAccessError. Checking instruction INVOKESTATIC A.bar ()I failed:
|The method bar()I could not be found in the class A or any of its parents.
- |Note that the parent class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin)
+ |Note that class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin)
var c = 0
val List(b) = compileToBytes(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; warns.tail.exists(i.msg contains _)})
@@ -168,4 +168,37 @@ class InlineWarningTest extends BytecodeTesting {
compileToBytes(code, allowMessage = i => { c += 1; i.msg contains warn })
assert(c == 1, c)
}
+
+ @Test // scala-dev#20
+ def mixedCompilationSpuriousWarning(): Unit = {
+ val jCode =
+ """public class A {
+ | public static final int bar() { return 100; }
+ | public final int baz() { return 100; }
+ |}
+ """.stripMargin
+
+ val sCode =
+ """class C {
+ | @inline final def foo = A.bar()
+ | @inline final def fii(a: A) = a.baz()
+ | def t = foo + fii(new A)
+ |}
+ """.stripMargin
+
+ val warns = List(
+ """C::foo()I is annotated @inline but could not be inlined:
+ |Failed to check if C::foo()I can be safely inlined to C without causing an IllegalAccessError. Checking instruction INVOKESTATIC A.bar ()I failed:
+ |The method bar()I could not be found in the class A or any of its parents.
+ |Note that class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin,
+
+ """C::fii(LA;)I is annotated @inline but could not be inlined:
+ |Failed to check if C::fii(LA;)I can be safely inlined to C without causing an IllegalAccessError. Checking instruction INVOKEVIRTUAL A.baz ()I failed:
+ |The method baz()I could not be found in the class A or any of its parents.
+ |Note that class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin
+ )
+ var c = 0
+ compileClasses(sCode, javaCode = List((jCode, "A.java")), allowMessage = i => { c += 1; warns.exists(i.msg.contains)})
+ assert(c == 2)
+ }
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
index f531ce9322..0f292517ef 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -416,7 +416,7 @@ class InlinerTest extends BytecodeTesting {
"""B::flop()I is annotated @inline but could not be inlined:
|Failed to check if B::flop()I can be safely inlined to B without causing an IllegalAccessError. Checking instruction INVOKESTATIC A.bar ()I failed:
|The method bar()I could not be found in the class A or any of its parents.
- |Note that the parent class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin
+ |Note that class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin
var c = 0
val List(b) = compile(scalaCode, List((javaCode, "A.java")), allowMessage = i => {c += 1; i.msg contains warn})
@@ -819,7 +819,7 @@ class InlinerTest extends BytecodeTesting {
val warn =
"""failed to determine if <init> should be inlined:
|The method <init>()V could not be found in the class A$Inner or any of its parents.
- |Note that the parent class A$Inner could not be found on the classpath.""".stripMargin
+ |Note that class A$Inner could not be found on the classpath.""".stripMargin
var c = 0