diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-02-18 12:57:03 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-03-15 14:43:40 +0100 |
commit | c103926177e1c5b34fc36036af8d686725490180 (patch) | |
tree | 0bc3424f84ed6677666fa8d11224a6b768c3beed /src/dotty/tools/dotc/transform/MixinOps.scala | |
parent | 614a2361ee6b7bcebf5bf6aa7fe159acd5e8ef19 (diff) | |
download | dotty-c103926177e1c5b34fc36036af8d686725490180.tar.gz dotty-c103926177e1c5b34fc36036af8d686725490180.tar.bz2 dotty-c103926177e1c5b34fc36036af8d686725490180.zip |
Mixin: create less forwarders.
There were two sources of inefficiency in previous scheme:
- if symbol was no overriding anything the forwarder was still being
created
- the class that is will have the forwarder was not considered.
Many methods do not require forwarders as JVM will dispatch correctly.
Diffstat (limited to 'src/dotty/tools/dotc/transform/MixinOps.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/MixinOps.scala | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/transform/MixinOps.scala b/src/dotty/tools/dotc/transform/MixinOps.scala index db89f939b..6cebf7197 100644 --- a/src/dotty/tools/dotc/transform/MixinOps.scala +++ b/src/dotty/tools/dotc/transform/MixinOps.scala @@ -41,11 +41,21 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx: ctx.atPhase(thisTransform) { implicit ctx => cls.info.member(sym.name).hasAltWith(_.symbol == sym) } - + + /** Does `method` need a forwarder to in class `cls` + * Method needs a forwarder in those cases: + * - there's a class defining a method with same signature + * - there are multiple traits defining method with same signature + */ def needsForwarder(meth: Symbol): Boolean = { - lazy val overridenSymbols = meth.allOverriddenSymbols - def needsDisambiguation = !overridenSymbols.forall(_ is Deferred) - def hasNonInterfaceDefinition = overridenSymbols.forall(!_.owner.is(Trait)) + lazy val competingMethods = cls.baseClasses.iterator + .filter(_ ne meth.owner) + .map(meth.overriddenSymbol) + .filter(_.exists) + .toList + + def needsDisambiguation = competingMethods.exists(x=> !(x is Deferred)) // multiple implementations are available + def hasNonInterfaceDefinition = competingMethods.exists(!_.owner.is(Trait)) // there is a definition originating from class meth.is(Method, butNot = PrivateOrAccessorOrDeferred) && isCurrent(meth) && (needsDisambiguation || hasNonInterfaceDefinition || meth.owner.is(Scala2x)) |