summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2006-08-31 18:43:11 +0000
committerBurak Emir <emir@epfl.ch>2006-08-31 18:43:11 +0000
commitcda2954e7b55f74fb7e20d7f789df3f2075415f6 (patch)
tree4fb57cc2c3b501d1453d9f1f441aa44499b9588b
parentc216472d2f6a1794be8859efc47ee341fdb1107b (diff)
downloadscala-cda2954e7b55f74fb7e20d7f789df3f2075415f6.tar.gz
scala-cda2954e7b55f74fb7e20d7f789df3f2075415f6.tar.bz2
scala-cda2954e7b55f74fb7e20d7f789df3f2075415f6.zip
pattern matching deals with outer instances now
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala91
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala3
5 files changed, 99 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index e2d5052f54..6d655809bb 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -345,9 +345,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
liftcode,
uncurry,
tailCalls,
+ explicitOuter,
transMatcher,
// checkDefined,
- explicitOuter,
erasure,
lambdaLift,
// detach,
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index e53bcdcbee..3199c7b925 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -122,6 +122,8 @@ class Settings(error: String => unit) {
val Xscript = BooleanSetting("-Xscript", "compile script file");
val XinnerClasses = BooleanSetting("-XinnerClasses", "generate InnerClasses attribute for Java interoperability");
+ val Xnofancymatch = BooleanSetting("-Xnofancymatch", "don't match outer instances");
+
/** A list of all settings */
def allSettings: List[Setting] = allsettings.reverse
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 0eee9f8552..527f41f21d 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -978,7 +978,96 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w
return toTree(node.and);
case ConstrPat(casted) =>
- return myIf(gen.mkIsInstanceOf(selector.duplicate, node.getTpe()),
+ 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(currentOwner.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
+ }
+
+ 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 == currentOwner.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)
+ /*
+ 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
+ }
+ }
+ return myIf(cond,
Block(
List(ValDef(casted,
gen.mkAsInstanceOf(selector.duplicate, node.getTpe(), true))),
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 3e18fc8907..4aa3d2f0de 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -480,13 +480,13 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
* in the template.
*/
private def bridgeDefs(owner: Symbol): List[Tree] = {
- //System.out.println("computing bridges for " + owner)//DEBUG
+ //Console.println("computing bridges for " + owner)//DEBUG
val site = owner.thisType
val bridgesScope = newScope
val bridgeTarget = new HashMap[Symbol, Symbol]
var bridges: List[Tree] = List()
- val opc = atPhase(phase.prev) { // to avoid DEFERRED flags for interfaces
- new overridingPairs.Cursor(owner) {
+ val opc = atPhase(phase.prev.prev) { // bq: who understands prev comment "to avoid DEFERRED flags for interfaces"
+ new overridingPairs.Cursor(owner) { // it seems we want types *before* explicitOuter
override def parents: List[Type] = List(owner.info.parents.head)
override def exclude(sym: Symbol): boolean =
!sym.isMethod || (sym hasFlag (PRIVATE | BRIDGE)) || super.exclude(sym)
@@ -495,8 +495,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
while (opc.hasNext) {
val member = opc.overriding
val other = opc.overridden
- //System.out.println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString);//DEBUG
- if (!atPhase(phase.prev)(member hasFlag DEFERRED)) {
+ //Console.println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString);//DEBUG
+ if (!atPhase(phase.prev.prev)(member hasFlag DEFERRED)) {
val otpe = erasure(other.tpe);
val bridgeNeeded = atPhase(phase.next) (
!(other.tpe =:= member.tpe) &&
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index 63e27168e8..444077f838 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -119,7 +119,7 @@ abstract class OverridingPairs {
}
if (nextEntry != null) {
overridden = nextEntry.sym;
- //System.out.println("yield: " + overriding + overriding.locationString + " / " + overridden + overridden.locationString);//DEBUG
+ //Console.println("yield: " + overriding + overriding.locationString + " / " + overridden + overridden.locationString);//DEBUG
visited addEntry nextEntry
} else {
do {
@@ -133,4 +133,3 @@ abstract class OverridingPairs {
next
}
}
-