diff options
author | Burak Emir <emir@epfl.ch> | 2006-09-06 13:13:37 +0000 |
---|---|---|
committer | Burak Emir <emir@epfl.ch> | 2006-09-06 13:13:37 +0000 |
commit | 0482a0c416de901c9e3cb4f5efc3b6134358ee55 (patch) | |
tree | 09104c82b97cbf9043d428729619fb9d87f41179 /src | |
parent | 55f38ed459fdbbd2bd5d52b3807e663f9cf9b591 (diff) | |
download | scala-0482a0c416de901c9e3cb4f5efc3b6134358ee55.tar.gz scala-0482a0c416de901c9e3cb4f5efc3b6134358ee55.tar.bz2 scala-0482a0c416de901c9e3cb4f5efc3b6134358ee55.zip |
prelim outer stuff
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/PatternMatchers.scala | 117 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 34 |
2 files changed, 47 insertions, 104 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala index dd8c16bbbf..7e5bfc10e8 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala @@ -1113,101 +1113,34 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) { return toTree(node.and); case ConstrPat(casted) => + def outerAlwaysEqual(left: Type, right: Type) = Pair(left,right) match { + case Pair(TypeRef(lprefix, _,_), TypeRef(rprefix,_,_)) if lprefix =:= rprefix => + true + case _ => + false + } var cond = gen.mkIsInstanceOf(selector.duplicate, node.getTpe()) - if(!settings.Xnofancymatch.value) { - // compare outer instance for patterns like foo1.Bar foo2.Bar if not statically known to match - casted.tpe match { - case TypeRef(prefix,_,_) if (prefix.symbol.isTerm && !prefix.symbol.isPackage) => - selector.tpe match { - case TypeRef(oprefix,_,_) => - if(oprefix =:= prefix) - {} // statically known to match - else { - - /* <-- start borrowed from explicitOuter */ - - def outerClass(clazz: Symbol): Symbol = - if (clazz.owner.isClass) clazz.owner - else outerClass(if (clazz.isClassLocalToConstructor) clazz.owner.owner else clazz.owner) - - /** The first outer selection from currently transformed tree - */ - def outerValue: Tree = - outerSelect(gen.mkAttributedThis(owner.enclClass)) - - /** The path - * `base'.$outer ... .$outer - * which refers to the outer instance 'to' of value 'base' - */ - def outerPath(base: Tree, to: Symbol): Tree = - if (base.tpe.symbol == to) base else outerPath(outerSelect(base), to) - - /** Select and apply outer accessor from 'base' - */ - def outerSelect(base: Tree): Tree = { - val otp = outerClass(base.tpe.symbol).thisType - Apply( - Select(base, outerMember(base.tpe)) setType MethodType(List(), otp), - List()) setType otp - } + // compare outer instance for patterns like foo1.Bar foo2.Bar if not statically known to match + + if(!outerAlwaysEqual(casted.tpe, selector.tpe)) { + casted.tpe match { + case TypeRef(prefix,_,_) if (prefix.symbol.isTerm && !prefix.symbol.isPackage) => + var theRef = gen.mkAttributedRef(prefix.prefix, prefix.symbol) // needs explicitouter treatment + if(global.settings.debug.value) { + Console.println("theRef "+theRef) + Console.println("handleOuter(theRef) "+handleOuter(theRef)) + } + theRef = handleOuter(theRef) - def outerMember(tp: Type): Symbol = { - var e = tp.symbol.info.decls.elems - // note: tp.decls does not work here, because tp might be a ThisType, in which case - // its decls would be the decls of the required type of the class. - while (e != null && !(e.sym.originalName.startsWith(nme.OUTER) && (e.sym hasFlag Flags.ACCESSOR))) - e = e.next; - assert(e != null, tp) - e.sym - } - /* <-- end borrowed from explicitOuter */ -// Console.println(prefix) -// Console.println(prefix.symbol) -// Console.println(prefix.symbol.isModule) -// Console.println("pre.pre "+prefix.prefix) -// Console.println("pre.pre asSF "+prefix.prefix.asSeenFrom(owner.enclClass.tpe, owner.enclClass)) - var theRef = gen.mkAttributedRef(prefix.prefix, prefix.symbol) // problem: this needs explicitouter treatment - - // transform explicitOuter - /** The first-step transformation method */ - def mytransform(tree: Tree): Tree = { - val sym = tree.symbol - tree match { - case This(qual) => - if (sym == owner.enclClass || (sym hasFlag Flags.MODULE) && sym.isStatic) tree - else posAssigner.atPos(tree.pos)(outerPath(outerValue, sym)); // (5) - case Select(qual,name) => - Select(mytransform(qual),name) - } - } - //theRef = mytransform(theRef) - if(global.settings.debug.value) { - Console.println("theRef "+theRef) - Console.println("mytransform(theRef) "+mytransform(theRef)) - Console.println("handleOuter(theRef) "+handleOuter(theRef)) - } - theRef = handleOuter(theRef) - /* - val tpe = prefix.prefix - if( - prefix.prefix match { - case ThisType(q) => - Console.println("hello"+q) - Console.println("but enclClass"+prefix.symbol.enclClass) - case x => Console.println("hola"+x.getClass()) - } - */ - cond = And(cond, - Eq(Apply(Select( - gen.mkAsInstanceOf(selector.duplicate, node.getTpe(), true), nme.OUTER),List()), theRef)) - } - case _ => - //ignore - } - case _ => - //ignore + if(node.getTpe().decls.lookup(nme.OUTER) != NoSymbol) { // some guys don't have outers :-( + cond = And(cond, + Eq(Apply(Select( + gen.mkAsInstanceOf(selector.duplicate, node.getTpe(), true), nme.OUTER),List()), theRef)) + } + case _ => + //ignore ; + } } - } return myIf(cond, Block( List(ValDef(casted, diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 5811c279c8..762572b7af 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -337,10 +337,21 @@ with PatternMatchers { */ private val secondTransformer = new OuterPathTransformer { + def handleSelect(tree:Select) = tree match { + case Select(qual, name) => + val sym = tree.symbol + val enclClass = currentOwner.enclClass + if (enclClass != sym.owner && enclClass != sym.moduleClass) // (3) + sym.makeNotPrivate(sym.owner); + val qsym = qual.tpe.widen.symbol + if ((sym hasFlag PROTECTED) && //(4) + (qsym.isTrait || !(qual.isInstanceOf[Super] || (qsym isSubClass enclClass)))) + sym setFlag notPROTECTED; + } + /** The second-step transformation method */ override def transform(tree: Tree): Tree = { val sym = tree.symbol - val tree1 = if(tree.isInstanceOf[Match]) { //Console.println("calling super.transform of Match with ncases "+ @@ -354,18 +365,11 @@ with PatternMatchers { if (sym.owner.isTrait && (sym hasFlag (ACCESSOR | SUPERACCESSOR))) sym.makeNotPrivate(sym.owner); //(2) tree1 - case Select(qual, name) => - val enclClass = currentOwner.enclClass - if (enclClass != sym.owner && enclClass != sym.moduleClass) // (3) - sym.makeNotPrivate(sym.owner); - val qsym = qual.tpe.widen.symbol - if ((sym hasFlag PROTECTED) && //(4) - (qsym.isTrait || !(qual.isInstanceOf[Super] || (qsym isSubClass enclClass)))) - sym setFlag notPROTECTED; + case tree @ Select(qual, name) => + handleSelect(tree) tree1 -/*<--- begin transmatch experimental */ - case Match(selector, cases) => + case Match(selector, cases) => // <----- transmatch hook val tid = cunit.fresh.newName("tidmark") if(settings.debug.value) @@ -385,7 +389,13 @@ with PatternMatchers { if (sym == currentOwner.enclClass || (sym hasFlag Flags.MODULE) && sym.isStatic) tree else atPos(tree.pos)(outerPath(outerValue, sym)); // (5) case Select(qual,name) => - Select(mytransform(qual),name) + val s = copy.Select(tree, mytransform(qual), name) + handleSelect(s) + s + case x => + if(settings.debug.value) + Console.println(x.getClass()) + x } } val t_untyped = ExplicitOuter.this.handlePattern(nselector, ncases.asInstanceOf[List[CaseDef]], currentOwner, mytransform) |