aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-09-05 11:51:14 +0200
committerMartin Odersky <odersky@gmail.com>2016-10-02 16:11:21 +0200
commit1d932642eaed2ec9829be951f3272d32b4393a39 (patch)
tree6e7263cc14896b604d0522f01c73644f6d54ea54 /src/dotty/tools/dotc/typer
parent0bd955e7780c95d41a0b6c4b7ca221f00e3cfd92 (diff)
downloaddotty-1d932642eaed2ec9829be951f3272d32b4393a39.tar.gz
dotty-1d932642eaed2ec9829be951f3272d32b4393a39.tar.bz2
dotty-1d932642eaed2ec9829be951f3272d32b4393a39.zip
Handle outer this in Inliner
Also, do some refactorings and fix some bugs in Inliner.
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Inliner.scala58
1 files changed, 28 insertions, 30 deletions
diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala
index fbb847e9d..970d31e47 100644
--- a/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/src/dotty/tools/dotc/typer/Inliner.scala
@@ -40,7 +40,7 @@ object Inliner {
sym.getAnnotation(defn.InlineAnnot).get.tree
.attachment(InlinedBody).body
- private class Typer extends ReTyper {
+ private object InlineTyper extends ReTyper {
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
val acc = tree.symbol
super.typedSelect(tree, pt) match {
@@ -117,12 +117,12 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
private val (methPart, targs, argss) = decomposeCall(call)
private val meth = methPart.symbol
- private lazy val prefix = methPart match {
+ private val prefix = methPart match {
case Select(qual, _) => qual
case _ => tpd.This(ctx.owner.enclosingClass.asClass)
}
- private val thisProxy = new mutable.HashMap[Type, NamedType]
+ private val thisProxy = new mutable.HashMap[Type, TermRef]
private val paramProxy = new mutable.HashMap[Type, Type]
private val paramBinding = new mutable.HashMap[Name, Type]
val bindingsBuf = new mutable.ListBuffer[MemberDef]
@@ -167,20 +167,20 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
}
private def registerType(tpe: Type): Unit = tpe match {
- case tpe: ThisType if !thisProxy.contains(tpe) =>
- if (!ctx.owner.isContainedIn(tpe.cls) && !tpe.cls.is(Package))
- if (tpe.cls.isStaticOwner)
- thisProxy(tpe) = tpe.cls.sourceModule.termRef
- else {
- def outerDistance(cls: Symbol): Int = {
- assert(cls.exists, i"not encl: ${meth.owner.enclosingClass} ${tpe.cls}")
- if (tpe.cls eq cls) 0
- else outerDistance(cls.owner.enclosingClass) + 1
- }
- val n = outerDistance(meth.owner)
- thisProxy(tpe) = newSym(nme.SELF ++ n.toString, EmptyFlags, tpe.widen).termRef
- }
- case tpe: NamedType if tpe.symbol.is(Param) && tpe.symbol.owner == meth && !paramProxy.contains(tpe) =>
+ case tpe: ThisType
+ if !ctx.owner.isContainedIn(tpe.cls) && !tpe.cls.is(Package) &&
+ !thisProxy.contains(tpe) =>
+ if (tpe.cls.isStaticOwner)
+ thisProxy(tpe) = tpe.cls.sourceModule.termRef
+ else {
+ val proxyName = s"${tpe.cls.name}_this".toTermName
+ val proxyType = tpe.asSeenFrom(prefix.tpe, meth.owner)
+ thisProxy(tpe) = newSym(proxyName, EmptyFlags, proxyType).termRef
+ registerType(meth.owner.thisType) // make sure we have a base from which to outer-select
+ }
+ case tpe: NamedType
+ if tpe.symbol.is(Param) && tpe.symbol.owner == meth &&
+ !paramProxy.contains(tpe) =>
paramProxy(tpe) = paramBinding(tpe.name)
case _ =>
}
@@ -190,25 +190,23 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
case _ =>
}
- private def outerLevel(sym: Symbol) = sym.name.drop(nme.SELF.length).toString.toInt
-
def inlined(pt: Type) = {
+ if (!isIdempotentExpr(prefix)) registerType(meth.owner.thisType) // make sure prefix is computed
rhs.foreachSubTree(registerLeaf)
- val accessedSelfSyms =
- (for ((tp: ThisType, ref) <- thisProxy) yield ref.symbol.asTerm).toSeq.sortBy(outerLevel)
+ def classOf(sym: Symbol) = sym.info.widen.classSymbol
+ def outerSelector(sym: Symbol) = classOf(sym).name.toTermName ++ nme.OUTER_SELECT
+ def outerLevel(sym: Symbol) = classOf(sym).ownersIterator.length
+ val accessedSelfSyms = thisProxy.values.toList.map(_.symbol).sortBy(-outerLevel(_))
var lastSelf: Symbol = NoSymbol
for (selfSym <- accessedSelfSyms) {
val rhs =
- if (!lastSelf.exists) prefix
- else {
- val outerDelta = outerLevel(selfSym) - outerLevel(lastSelf)
- def outerSelect(ref: Tree, dummy: Int): Tree = ???
- //ref.select(ExplicitOuter.outerAccessorTBD(ref.tpe.widen.classSymbol.asClass))
- (ref(lastSelf) /: (0 until outerDelta))(outerSelect)
- }
- bindingsBuf += ValDef(selfSym, rhs.ensureConforms(selfSym.info))
+ if (!lastSelf.exists)
+ prefix
+ else
+ untpd.Select(ref(lastSelf), outerSelector(selfSym)).withType(selfSym.info)
+ bindingsBuf += ValDef(selfSym.asTerm, rhs)
lastSelf = selfSym
}
@@ -239,7 +237,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
val bindings = bindingsBuf.toList.map(_.withPos(call.pos))
val expansion = inliner(rhs.withPos(call.pos))
- val expansion1 = new Typer().typed(expansion, pt)(inlineContext(call))
+ val expansion1 = InlineTyper.typed(expansion, pt)(inlineContext(call))
val result = tpd.Inlined(call, bindings, expansion1)
inlining.println(i"inlining $call\n --> \n$result")