devirtualize.scala.notyet
来自「JAVA 语言的函数式编程扩展」· NOTYET 代码 · 共 410 行
NOTYET
410 行
/* NSC -- new Scala compiler * Copyright 2005-2007 LAMP/EPFL * @author Martin Odersky */// $Id: RefChecks.scala 13735 2008-01-18 17:18:58Z odersky $package scala.tools.nsc.typecheckerimport symtab.Flags._import transform.InfoTransformimport scala.tools.nsc.util.{Position, NoPosition}abstract class DeVirtualize extends InfoTransform { import global._ import definitions._ import typer.{typed, typedOperator, atOwner} import posAssigner.atPos /** the following two members override abstract members in Transform */ val phaseName: String = "devirtualize" /** The phase might set the following new flags: */ override def phaseNewFlags: Long = notOVERRIDE | notFINAL def newTransformer(unit: CompilationUnit): DeVirtualizeTransformer = new DeVirtualizeTransformer(unit) override def changesBaseClasses = false lazy val ownPhase = phaseNamed(phaseName) def transformInfo(sym: Symbol, tp: Type): Type = devirtualizeMap(tp) /* todo: check: overriding classes must have same type params virtual classes cannot have self types */ /** Do the following transformations everywhere in a type: * * 1. If a class defines virtual classes VC, add abstract types VA, * worker traits VT and factories VF instead (@see devirtualize). * 2. Convert VC.this where VC is a virtual class to WT.this where WT is the worker trait for VC * (@see workerTrait) * 3. Convert TypeRef's to VC where VC is a virtual class to TypeRef's to AT, where AT * is the abstract type corresponding to VC. * * Note: If a class inherits vc's from two different paths, a vc in the * inheriting class has to be created beforehand. This is done in phase ??? */ object devirtualizeMap extends TypeMap { def apply(tp: Type): Type = mapOver(tp) match { case tp1 @ ClassInfoType(parents, decls, clazz) => val ds = decls.toList if (ds exists (_.isVirtualClass)) { transformOwnerInfo(clazz) val decls1 = newScope(ds) for (m <- m.info.decls) if (m.isVirtualClass) devirtualize(m, decls1) for (m <- classesInNeedOfFactories(clazz)) addFactory(m, clazz, decls1) ClassInfoType(parents, decls1, clazz) } else tp1 case ThisType(clazz) if clazz.isVirtualClass => ThisType(workerTrait(clazz)) case TypeRef(pre, clazz, args) if sym.isVirtualClass => TypeRef(pre, abstractType(clazz), args) case _ => tp } } /** Transform owner of given clazz symbol */ protected def transformOwnerInfo(clazz: Symbol) { atPhase(ownPhase.next) { clazz.owner.info } } protected def workerTraitName(clazzName: Name) = newTypeName(clazzName+"$trait") protected def concreteClassName(clazzName: Name) = newTypeName(clazzName+"$fix") protected def factoryName(clazzName: Name) = newTermName("new$"+clazzName) protected def definedVirtuals(clazz: Symbol) = m.info.decls.toList filter (_.isVirtual) protected def classesInNeedOfFactories(clazz: Symbol) = atPhase(ownPhase) { def isDefinedVirtual(c: Symbol) = c.isVirtualClass && c.owner == clazz val buf: ListBuffer[Symbol] for (m <- clazz.info.members) if (m.isVirtualClass && !(m hasFlag ABSTRACT) && (m.baseClasses exists isDefinedVirtual)) buf += m buf.toList } /** The abstract type corresponding to a virtual class. */ protected def abstractType(clazz: Symbol): Symbol = atPhase(ownPhase.next) { val tsym = clazz.info.owner.member(clazz.name) assert(tsym.isAbstractType, clazz) tsym } /** The worker trait corresponding to a virtual class. */ protected def workerTrait(clazz: Symbol) = atPhase(ownPhase.next) { val tsym = clazz.info.owner.member(workerTraitName(clazz.name)) assert(tsym.isTrait, clazz) tsym } /** The factory corresponding to a virtual class. */ protected def factory(clazz: Symbol) = atPhase(ownPhase.next) { val fsym = clazz.info.owner.member(factoryName(clazz.name.toTermName)) assert(fsym.isMethod, clazz) fsym } /** A reference to workertrait VT[Us] as from symbol `base'. Renames type parameters * Us to those of `base' and also substitutes this to this of base's owner. */ protected def workerTypeRef(wtrait: Symbol, base: Symbol): Type = wtrait.tpe.subst(wtrait.typeParams, base.typeParams).substThis(wtrait.owner, base.owner) /** The flags that a worker trait can inherit from its virtual class */ protected val traitFlagMask = AccessFlags | FINAL /** The flags that an abstract type can inherit from its virtual class */ protected val absTypeFlagMask = AccessFlags | DEFERRED /** The flags that a factory method can inherit from its virtual class */ protected val factoryFlagMask = AccessFlags /** Create a polytype with given type parameters and given type, or return just the type * if type params is empty. */ protected def mkPolyType(tparams: List[Symbol], tp: Type) = if (tparams.isEmpty) tp else PolyType(tparams, tp) /** Set info of `dst' to `tp', potentially wrapped by copies of any type * parameters of `src' */ def setPolyInfo(dst: Symbol, from: Symbol, tp: Type) = { val tparams = cloneSymbols(from.typeParams, dst) dst setInfo mkPolyType(tparams, tp subst (from.typeParams, tparams)) } /** The virtual classes overridden by given virtual class `clazz' * Classes appear in linearization order (with superclasses before subclasses) */ protected def overriddenVirtuals(clazz: Symbol): List[Symbol] = atPhase(ownPhase) { for (bc <- clazz.owner.info.baseClasses oc <- bc.info.member(clazz.name).alternatives if oc.isVirtualClass) yield oc }.reverse /** Replace a virtual class * * attrs mods class VC[Ts] <: Ps { decls } * * with overridden classes _VC[Us]'s * * by the following symbols * * attrs mods1 type VC[Ts] <: dvm(Ps) with _VC$trait[Ts]'s with VC$trait[Ts] * attrs mods2 trait VC$trait[Ts] extends Object with ScalaObject { * this: VC[Ts] with VC$trait[Ts] => decls1 * } * * Furthermore, for all virtual member classes VC which * are not abstract and which are or inherit from a virtual class definedalso add a factory: * * attrs mods3 def new$VC[Ts](): VC[Ts] = { * class VC$fix extends VC$trait's[Ts] with VC$trait[Ts] * * where * * dvm is the devirtalization mapping which converts refs to * virtual classes to refs to their abstract types (@see devirtualize) * mods1 are the modifiers inherited from abstract types * mods2 are the modifiers inherited from worker traits * mods3 are the modifiers inherited from factories * decls1 is decls but members that have an override modifier * lose it and any final modifier as well. */ protected def devirtualize(clazz: Symbol, scope: Scope) { scope.unlink(clazz) val cabstype = clazz.owner.newAbstractType(clazz.pos, clazz.name) .setFlag(clazz.flags & absTypeFlagMask) scope.enter(cabstype) cabstype setInfo new LazyType { override val typeParams = cloneSymbols(clazz.typeParams, cabstype) override def complete(sym: Symbol) { def parentTypeRef(tp: Type) = devirtualizeMap(tp.subst(clazz.typeParams, typeParams)) val parents1 = clazz.info.parents map parentTypeRef val parents2 = overriddenVirtuals(clazz) map (oc => workerTypeRef(workerTrait(oc), cabstype)) sym.setInfo( mkPolyType(typeParams, mkTypeBounds(AllClass.tpe, intersectionType(parents1 ::: parents2)))) } } val wtrait = clazz.owner.newClass(clazz.pos, workerTraitName(clazz.name)) .setFlag(clazz.flags & traitFlagMask | TRAIT) .setAttributes(clazz.atttributes) scope.enter(wtrait) val decls1 = clazz.info.decls.toList for (val m <- decls1) if (m hasFlag OVERRIDE) m serFlag (notOVERRIDE | notFINAL) setPolyInfo( wtrait, clazz, ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), new Scope(decls1), wtrait)) wtrait.setTypeOfThis(intersectionType(List(cabstype.tpe, wtrait.tpe)), clazz) } def addFactory(clazz: Symbol, owner: Symbol, scope: Scope) { val pos = if (clazz.owner == owner) clazz.pos else owner.pos val factory = owner.newMethod(pos, factoryName(clazz)) .setFlag(clazz.flags & factoryFlagMask) scope.enter(factory) val cabstype = abstractType(clazz) setPolyInfo(factory, cabstype, MethodType(List(), cabstype.tpe)) } protected def concreteClassSym(clazz: Symbol, factory: Symbol) = { val cclazz = factory.newClass(clazz.pos, concreteClassName(clazz)) .setFlag(clazz.flags) .setAttributes(clazz.atttributes) cclazz setInfo new LazyType { override def complete(sym: Symbol) { sym setInfo ClassInfoType( overriddenVirtuals(clazz) map (oc => workerTypeRef(workerTrait(oc), factory)) new Scope(), cclazz) } } cclazz } /** (new VC).init() => new$VC * add stuff to onwing class * transform types */ class DeVirtualizeTransformer(unit: CompilationUnit) extends TypingTransformer { override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = { val stats1 = for (stat <- stats; stat1 <- transformStat(stat)) yield transform(stat1) val newDefs = new ListBuffer[Tree] if (currentOwner.isClass && currentOwner.info.decls.toList exists (_.isVirtualClass)) { for (m <- classesInNeedOfFactories(currentOwner)) newDefs += factoryDef(m) } if (newDefs.isEmpty) stats1 else stats1 ::: newDefs.toList } protected def transformStat(tree: Tree): List[Tree] = tree match { case ClassDef(mods, name, tparams, Template(parents, self, body)) if (tree.symbol.isVirtualClass) => val clazz = tree.symbol val absTypeSym = abstractType(clazz) val workerTraitSym = workerTrait(clazz) val abstypeDef = TypeDef(abstractType(clazz)) val selfDef = ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(clazz.tpe), EmptyTree) val traitTemplate = atPos(templ.pos) { Template( List.map2(workerTraitSym.parents, parents) ((ptpe, ptree) => TypeTree(ptpe) setPos ptree.pos), selfDef, Modifiers(), List(List()), List(List()), body) } new ChangeOwnerTraverser(templ.symbol.owner, workerTrait)( new ChangeOwnerTraverser(templ.symbol, traitTemplate.symbol)(traitTemplate)) var newdefs = List(abstypeDef, traitTemplate) if (!clazz.hasFlag(ABSTRACT)) { val factorySym = factory(clazz) val cclazzSym = concreteClassSym(clazz, factorySym) def overrideBridge(m: Symbol) = atPos(m.pos) { val bridge = m.cloneSymbol(cclazzSym) .resetFlag(notOVERRIDE | notFINAL) val superRef = Select(Super(cclazzSym, nme.EMPTY.toTypeName), m) DefDef(bridge, vparamss => (superRef /: vparamss)((fn, vparams) => Apply(fn, vparams map (param => Ident(param.symbol) setPos param.pos)))) } val overrideBridges = for (m <- workerTraitSym.info.decls.toList if m hasFlag notOVERRIDE) yield overrideBridge(m) val cclazzDef = ClassDef(cclazzSym, Modifiers(), List(List()), List(List()), overrideBridges) val factoryExpr = atPos(templ.pos) { Block(cclazzDef, New(TypeTree(cclazzSym.tpe), List(List()))) } val factoryDef = DefDef(factorySym, vparamss => factoryExpr) newdefs = newdefs ::: List(factoryDef) } newdefs map localTyper.typed case _ => List(tree) } override def transform(tree: Tree): Tree = tree match { case ClassDef(mods, name, tparams, Template(parents, self, body)) => case This(_) | Super(_, _) if tree.symbol.isVirtualClass => tree setSymbol workerTrait(tree.symbol) case Select(New(tpt), name) if (tree.symbol.isConstructor && tree.symbol.owner.isVirtualClass) => val clazz = tpt.tpe.typeSymbol val fn = mkAttributedRef(factory(clazz)) val targs = tpt.tpe.typeArgs atPos(tree.pos) { if (targs.isEmpty) fn else TypeApply(fn, targs map TypeTree) setType tpt.tpe } case _ => super.transform(tree) } setType devirtualizeMap(tree.tpe) override def transformUnit(unit: CompilationUnit) = atPhase(ownPhase.next) { super.transformUnit(unit) } }} scope.enter(wtrait) .setInfo scope.enter(cabstype) setPolyType(wtrait, ClassInfoType( List(ObjectClass.tpe, ScalaObjectClass.tpe), new Scope(clazz.info.decls), wtrait)) setPolyType(cabstype, mkTypeBounds( AllClass.tpe, (overridden map (workerTrait(_).tpe)) ::: (clazz.parents map devirtualizeMap))) val cfix = ... val cfactory = ... val virBound = { mkTypeBounds( AllClass.tpe, c.info.parents ::: overridden.map(oc => virTrait(oc).tpe)) c.setInfo(mkTypeBounds(AllClass.tpe, intersectionType( ).tpe), c.owner))) }/* class A { class C[X, Y](x: X) <: { var y = x ; def f(z: Y): X } class D[Y](z) extends C[Int, Y](f(z)) { override def f(z:Int) = 3 } } class B extends A { class C[X, Y](x: X) <: { def g = 2 } }maps to: class A { type C[X, Y] <: CT[X, Y] trait CT[X, Y] { self: C => protected[this] val x: Int; val y = x; def f(z:Int) = z + 1 } type D <: C with DT trait DT extends { self: D => def f(z:Int) = z + 2 } trait preDT extends { self: D => val z: Int; val x = f(z) } def newC(x: Int): C def newD(x: Int): D //type C = CT //type D = C with DT class CC(_x:Int) extends { val x = _x } with CT def newC[X, Y](x:Int): C = new CC(x).asInstanceOf[C] class DC(_z:Int) extends { val z = _z } with preDT with CT with DT { override def f(z:Int) = super.f(z) } def newD(z:Int):D = new DC(z).asInstanceOf[D] } class B extends A { type C <: CT with CT2 trait CT2 { self : C => def g = 2 } //type C = CT with CT2 //type D = C with DT class CC2(_x:Int) extends { val x = _x } with CT with CT2 def newC(x:Int): C = new CC2(x).asInstanceOf[C] class DC2(_z:Int) extends { val z = _z } with preDT with CT with CT2 with DT { override def f(z:Int) = super.f(z) } def newD(z:Int): D = new DC2(z).asInstanceOf[D] }*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?