@@ -600,121 +600,6 @@ object Erasure extends TypeTestsCasts{
600600 super .typedStats(stats1, exprOwner)
601601 }
602602
603- // this implementation doesn't check for bridge clashes with value types!
604- def addBridges (oldStats : List [untpd.Tree ], newStats : List [tpd.Tree ])(implicit ctx : Context ): List [tpd.Tree ] = {
605- val beforeCtx = ctx.withPhase(ctx.erasurePhase)
606- def traverse (after : List [Tree ], before : List [untpd.Tree ],
607- emittedBridges : ListBuffer [tpd.DefDef ] = ListBuffer [tpd.DefDef ]()): List [tpd.DefDef ] = {
608- after match {
609- case Nil => emittedBridges.toList
610- case (member : DefDef ) :: newTail =>
611- before match {
612- case Nil => emittedBridges.toList
613- case (oldMember : untpd.DefDef ) :: oldTail =>
614- try {
615- val oldSymbol = oldMember.symbol(beforeCtx)
616- val newSymbol = member.symbol(ctx)
617- assert(oldSymbol.name(beforeCtx) == newSymbol.name,
618- s " ${oldSymbol.name(beforeCtx)} bridging with ${newSymbol.name}" )
619- if (! oldMember.symbol.is(Flags .Deferred )) {
620- val newOverridden = oldSymbol.denot.allOverriddenSymbols.toSet
621- // TODO: clarify new <-> old in a comment; symbols are swapped here
622- val oldOverridden = newSymbol.allOverriddenSymbols(beforeCtx).toSet
623-
624- // TODO: can we find a more efficient impl? newOverridden does not have to be a set!
625- def stillInBaseClass (sym : Symbol ) = ctx.owner derivesFrom sym.owner
626-
627- val neededBridges = (oldOverridden -- newOverridden).filter(stillInBaseClass)
628-
629- var minimalSet = Set [Symbol ]()
630- // compute minimal set of bridges that are needed:
631- for (bridge <- neededBridges) {
632- val isRequired = minimalSet.forall(nxtBridge => ! (bridge.info =:= nxtBridge.info))
633-
634- if (isRequired) {
635- // check for clashes
636- val clash : Option [Symbol ] = oldSymbol.owner.info.decls.lookupAll(bridge.name).find {
637- sym =>
638- (sym.name eq bridge.name) && sym.info.widen =:= bridge.info.widen
639- }.orElse(
640- emittedBridges.find(stat => (stat.name == bridge.name) && stat.tpe.widen =:= bridge.info.widen)
641- .map(_.symbol))
642- clash match {
643- case Some (cl) =>
644- ctx.error(i " bridge for method ${newSymbol.showLocated(beforeCtx)} of type ${newSymbol.info(beforeCtx)}\n " +
645- i " clashes with ${cl.symbol.showLocated(beforeCtx)} of type ${cl.symbol.info(beforeCtx)}\n " +
646- i " both have same type after erasure: ${bridge.symbol.info}" )
647- case None => minimalSet += bridge
648- }
649- }
650- }
651-
652- val bridgeImplementations = minimalSet.map {
653- sym => makeBridgeDef(member, sym)(ctx)
654- }
655- emittedBridges ++= bridgeImplementations
656- }
657- } catch {
658- case ex : MergeError => ctx.error(ex.getMessage, member.pos)
659- }
660-
661- traverse(newTail, oldTail, emittedBridges)
662- case notADefDef :: oldTail =>
663- traverse(after, oldTail, emittedBridges)
664- }
665- case notADefDef :: newTail =>
666- traverse(newTail, before, emittedBridges)
667- }
668- }
669-
670- traverse(newStats, oldStats)
671- }
672-
673- private final val NoBridgeFlags = Flags .Accessor | Flags .Deferred | Flags .Lazy | Flags .ParamAccessor
674-
675- /** Create a bridge DefDef which overrides a parent method.
676- *
677- * @param newDef The DefDef which needs bridging because its signature
678- * does not match the parent method signature
679- * @param parentSym A symbol corresponding to the parent method to override
680- * @return A new DefDef whose signature matches the parent method
681- * and whose body only contains a call to newDef
682- */
683- def makeBridgeDef (newDef : tpd.DefDef , parentSym : Symbol )(implicit ctx : Context ): tpd.DefDef = {
684- val newDefSym = newDef.symbol
685- val currentClass = newDefSym.owner.asClass
686-
687- def error (reason : String ) = {
688- assert(false , s " failure creating bridge from ${newDefSym} to ${parentSym}, reason: $reason" )
689- ???
690- }
691- var excluded = NoBridgeFlags
692- if (! newDefSym.is(Flags .Protected )) excluded |= Flags .Protected // needed to avoid "weaker access" assertion failures in expandPrivate
693- val bridge = ctx.newSymbol(currentClass,
694- parentSym.name, parentSym.flags &~ excluded | Flags .Bridge , parentSym.info, coord = newDefSym.owner.coord).asTerm
695- bridge.enteredAfter(ctx.phase.prev.asInstanceOf [DenotTransformer ]) // this should be safe, as we're executing in context of next phase
696- ctx.debuglog(s " generating bridge from ${newDefSym} to $bridge" )
697-
698- val sel : Tree = This (currentClass).select(newDefSym.termRef)
699-
700- val resultType = parentSym.info.widen.resultType
701-
702- val bridgeCtx = ctx.withOwner(bridge)
703-
704- tpd.DefDef (bridge, { paramss : List [List [tpd.Tree ]] =>
705- implicit val ctx = bridgeCtx
706-
707- val rhs = paramss.foldLeft(sel)((fun, vparams) =>
708- fun.tpe.widen match {
709- case mt : MethodType =>
710- Apply (fun, (vparams, mt.paramInfos).zipped.map(adapt(_, _, untpd.EmptyTree )))
711- case a =>
712- error(s " can not resolve apply type $a" )
713- })
714- adapt(rhs, resultType)
715- })
716- }
717-
718603 override def adapt (tree : Tree , pt : Type , original : untpd.Tree )(implicit ctx : Context ): Tree =
719604 ctx.traceIndented(i " adapting ${tree.showSummary}: ${tree.tpe} to $pt" , show = true ) {
720605 assert(ctx.phase == ctx.erasurePhase.next, ctx.phase)
0 commit comments