diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-06-07 12:51:51 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2015-08-11 14:28:05 +1000 |
commit | 658b62a4425ff7b774cd95e3323d9627b5af3c72 (patch) | |
tree | 63cc1a49a574b4f2489171bd0c4e55a169e05b18 /src | |
parent | 2bde3928833ae194fc7e2094b8955112b70fd31f (diff) | |
download | scala-658b62a4425ff7b774cd95e3323d9627b5af3c72.tar.gz scala-658b62a4425ff7b774cd95e3323d9627b5af3c72.tar.bz2 scala-658b62a4425ff7b774cd95e3323d9627b5af3c72.zip |
Allow BCode to emit default interface methods
A DefDef owned by a trait may now have have a method body.
Such a method must be emitted without ACC_ABSTRACT, and
with the code attribute.
Tested by intercepting the compile pipeline and adding the
DEFAULTMETHOD flag and a method body before running
the backend.
Diffstat (limited to 'src')
4 files changed, 7 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 64146585e5..c0e0240210 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -9,6 +9,7 @@ package backend package icode import scala.collection.{ mutable, immutable } +import scala.reflect.internal.Flags import scala.reflect.internal.util.{ SourceFile, NoSourceFile } trait ReferenceEquality { @@ -217,7 +218,7 @@ trait Members { /** Is this method deferred ('abstract' in Java sense)? */ - def isAbstractMethod = symbol.isDeferred || symbol.owner.isInterface || native + def isAbstractMethod = symbol.isDeferred || (symbol.owner.isInterface && !symbol.hasFlag(Flags.JAVA_DEFAULTMETHOD)) || native def isStatic: Boolean = symbol.isStaticMember diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala index a9b6a312e9..df4a715245 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala @@ -587,10 +587,10 @@ abstract class BCodeSkelBuilder extends BCodeHelpers { } val isNative = methSymbol.hasAnnotation(definitions.NativeAttr) - val isAbstractMethod = (methSymbol.isDeferred || methSymbol.owner.isInterface) + val isAbstractMethod = (methSymbol.isDeferred || methSymbol.owner.isInterface) && !methSymbol.hasFlag(Flags.JAVA_DEFAULTMETHOD) val flags = GenBCode.mkFlags( javaFlags(methSymbol), - if (claszSymbol.isInterface) asm.Opcodes.ACC_ABSTRACT else 0, + if (isAbstractMethod) asm.Opcodes.ACC_ABSTRACT else 0, if (methSymbol.isStrictFP) asm.Opcodes.ACC_STRICT else 0, if (isNative) asm.Opcodes.ACC_NATIVE else 0 // native methods of objects are generated in mirror classes ) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala index 45d9cc3ff3..88d07ce917 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala @@ -571,7 +571,7 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { import asm.Opcodes._ GenBCode.mkFlags( if (privateFlag) ACC_PRIVATE else ACC_PUBLIC, - if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0, + if ((sym.isDeferred && !sym.hasFlag(symtab.Flags.JAVA_DEFAULTMETHOD))|| sym.hasAbstractFlag) ACC_ABSTRACT else 0, if (sym.isInterface) ACC_INTERFACE else 0, if (finalFlag && !sym.hasAbstractFlag) ACC_FINAL else 0, if (sym.isStaticMember) ACC_STATIC else 0, diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 7096f16d75..872feefc8e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -1391,10 +1391,11 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self => var resTpe: asm.Type = javaType(m.symbol.tpe.resultType) if (m.symbol.isClassConstructor) resTpe = asm.Type.VOID_TYPE + val isAbstractTraitMeth = isJInterface && !m.symbol.hasFlag(Flags.JAVA_DEFAULTMETHOD) val flags = mkFlags( javaFlags(m.symbol), - if (isJInterface) asm.Opcodes.ACC_ABSTRACT else 0, + if (isAbstractTraitMeth) asm.Opcodes.ACC_ABSTRACT else 0, if (m.symbol.isStrictFP) asm.Opcodes.ACC_STRICT else 0, if (method.native) asm.Opcodes.ACC_NATIVE else 0, // native methods of objects are generated in mirror classes if(isDeprecated(m.symbol)) asm.Opcodes.ACC_DEPRECATED else 0 // ASM pseudo access flag |