diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-12-15 19:19:19 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-12-18 21:17:13 +0100 |
commit | 7552739730bab440009241c0d645ab8c6b8a042c (patch) | |
tree | 94a03a8670c59f1d58bed798bb40708bcdf82476 /src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala | |
parent | 36b1014ac63205a38e73ae18a05ac6f956c3410f (diff) | |
download | scala-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.scala | 28 |
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) + } } |