summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2014-12-15 19:19:19 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2014-12-18 21:17:13 +0100
commit7552739730bab440009241c0d645ab8c6b8a042c (patch)
tree94a03a8670c59f1d58bed798bb40708bcdf82476 /src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
parent36b1014ac63205a38e73ae18a05ac6f956c3410f (diff)
downloadscala-7552739730bab440009241c0d645ab8c6b8a042c.tar.gz
scala-7552739730bab440009241c0d645ab8c6b8a042c.tar.bz2
scala-7552739730bab440009241c0d645ab8c6b8a042c.zip
SI-9044 Fix order of interfaces in classfiles
It was reversed since ced3ca8ae1. The reason is that the backend used `mixinClasses` to obtain the parents of a class, which returns them in linearization order. `mixinClasses` als returns all ancestors (not only direct parents), which means more work for `minimizeInterfaces`. This was introduced in cd62f52 for unclear reasons. So we switch back to using `parents`.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
index 328ec8a033..a5f33aa786 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
@@ -162,4 +162,32 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
assoc.collectFirst {
case (`nme`.value, LiteralAnnotArg(Constant(value: Symbol))) => value
}).flatten.getOrElse(AnnotationRetentionPolicyClassValue)
+
+ def implementedInterfaces(classSym: Symbol): List[Symbol] = {
+ // Additional interface parents based on annotations and other cues
+ def newParentForAnnotation(ann: AnnotationInfo): Option[Type] = ann.symbol match {
+ case RemoteAttr => Some(RemoteInterfaceClass.tpe)
+ case _ => None
+ }
+
+ def isInterfaceOrTrait(sym: Symbol) = sym.isInterface || sym.isTrait
+
+ val allParents = classSym.info.parents ++ classSym.annotations.flatMap(newParentForAnnotation)
+
+ // We keep the superClass when computing minimizeParents to eliminate more interfaces.
+ // Example: T can be eliminated from D
+ // trait T
+ // class C extends T
+ // class D extends C with T
+ val interfaces = erasure.minimizeParents(allParents) match {
+ case superClass :: ifs if !isInterfaceOrTrait(superClass.typeSymbol) =>
+ ifs
+ case ifs =>
+ // minimizeParents removes the superclass if it's redundant, for example:
+ // trait A
+ // class C extends Object with A // minimizeParents removes Object
+ ifs
+ }
+ interfaces.map(_.typeSymbol)
+ }
}