From b31ceb487d7487a64c7d9955e1422bdc939f7998 Mon Sep 17 00:00:00 2001 From: Burak Emir Date: Sun, 25 Feb 2007 17:24:34 +0000 Subject: * fixed x @ unapplypat binding * added Node.unapply, QNode.unapply --- .../scala/tools/nsc/matching/PatternMatchers.scala | 24 ++++++++++---------- .../scala/tools/nsc/matching/PatternNodes.scala | 17 +++++++++----- src/library/scala/xml/Node.scala | 2 ++ src/library/scala/xml/QNode.scala | 26 ++++++++++++++++++++++ test/files/jvm/xmlmore.scala | 9 ++++++++ 5 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 src/library/scala/xml/QNode.scala diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala index bed3aed1fe..8a6a4a9f08 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala @@ -83,7 +83,7 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) { this.root = pConstrPat(selector.pos, selector.tpe.widen); this.root.and = pHeader(selector.pos, selector.tpe.widen, - Ident(root.symbol).setType(root.tpe)); + Ident(root.casted).setType(root.tpe)); //Konsole.println("resultType = "+resultType); //this.optimize = this.optimize && (settings.target.value == "jvm"); } @@ -318,7 +318,7 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) { protected def enter(caseDef: Tree): Unit = caseDef match { case CaseDef(pat, guard, body) => val env = new CaseEnv - val target = enter1(pat, -1, root, root.symbol, env) + val target = enter1(pat, -1, root, root.casted, env) // if (target.and != null) // unit.error(pat.pos, "duplicate case"); if (null == target.and) @@ -426,7 +426,7 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) { case Bind(name, pat) => // x @ p val node = patternNode(pat, header, env) if ((env ne null) && (tree.symbol != defs.PatternWildcard)) { - val theValue = node.symbol match { + val theValue = node.symbol2bind match { case NoSymbol => header.selector case x => Ident(x) setType x.tpe } @@ -525,7 +525,7 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) { subroot.and = { val h = pHeader(header.pos, header.getTpe(), header.selector.duplicate); h.isSubHeader = true; h } val subenv = new CaseEnv var i = 0; while (i < ts.length) { - val target = enter1(ts(i), -1, subroot, subroot.symbol, subenv) + val target = enter1(ts(i), -1, subroot, subroot.casted, subenv) target.and = pBody(tree.pos) i = i + 1 } @@ -702,10 +702,10 @@ print() if (next.isSameAs(patNode)) { // test for patNode already present --> reuse //Console.println(" -- found the same!") // substitute... !!! - patNode.symbol match { + patNode.casted match { case NoSymbol => ; case ocasted => - env.substitute(ocasted, typed(Ident(next.symbol))); + env.substitute(ocasted, typed(Ident(next.casted))); } return enter(patArgs, next, casted, env); } else if (next.isDefaultPat() || // default case reached, or @@ -916,7 +916,7 @@ print() case _ => ncases = ncases + 1 } - val matchError = ThrowMatchError(selector.pos, Ident(root.symbol)) + val matchError = ThrowMatchError(selector.pos, Ident(root.casted)) // without a case, we return a match error if there is no default case if (ncases == 0) return defaultBody(root.and, matchError); @@ -925,8 +925,8 @@ print() root.and.or match { case ConstantPat(value) => return squeezedBlock( - List(ValDef(root.symbol, selector)), - If(Equals(Ident(root.symbol), Literal(value)), + List(ValDef(root.casted, selector)), + If(Equals(Ident(root.casted), Literal(value)), (root.and.or.and).bodyToTree(), defaultBody(root.and, matchError)) ) @@ -1000,7 +1000,7 @@ print() } return Switch(selector, tags, bodies, defaultBody1, resultType); */ - nCases = CaseDef(Ident(nme.WILDCARD), squeezedBlock(List(ValDef(root.symbol, selector)),defaultBody1)) :: nCases; + nCases = CaseDef(Ident(nme.WILDCARD), squeezedBlock(List(ValDef(root.casted, selector)),defaultBody1)) :: nCases; Match(selector, nCases) } @@ -1013,9 +1013,9 @@ print() val result = exit.newValueParameter(root.pos, "result").setInfo( resultType ); squeezedBlock( List( - ValDef(root.symbol, selector), + ValDef(root.casted, selector), typed { toTree(root.and) }, - ThrowMatchError(selector.pos, Ident(root.symbol))) , + ThrowMatchError(selector.pos, Ident(root.casted))) , LabelDef(exit, List(result), Ident(result))) } diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala index ad1a32674f..ae8b7f78c7 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala @@ -23,6 +23,10 @@ trait PatternNodes requires transform.ExplicitOuter { var or: PatternNode = _ var and: PatternNode = _ + def casted: Symbol = NoSymbol + + def symbol2bind: Symbol = casted + def forEachAlternative(f: PatternNode => Unit) { // only for header? var z = this; while(z ne null) { @@ -81,7 +85,7 @@ trait PatternNodes requires transform.ExplicitOuter { res } - def symbol: Symbol = this match { + def _symbol: Symbol = this match { // @todo case UnapplyPat(casted, fn) => casted case ConstrPat(casted) => @@ -427,8 +431,11 @@ trait PatternNodes requires transform.ExplicitOuter { } case class DefaultPat()extends PatternNode - case class ConstrPat(casted:Symbol) extends PatternNode - case class UnapplyPat(casted:Symbol, fn:Tree) extends PatternNode { + case class ConstrPat(override val casted:Symbol) extends PatternNode + case class UnapplyPat(override val casted:Symbol, fn:Tree) extends PatternNode { + + override def symbol2bind = NoSymbol + def returnsOne = { /*val res =*/ definitions.getProductArgs(casted.tpe) match { case Some(Nil) => true // n = 0 @@ -444,9 +451,9 @@ trait PatternNodes requires transform.ExplicitOuter { case class ConstantPat(value: Any /*AConstant*/) extends PatternNode case class VariablePat(tree: Tree) extends PatternNode case class AltPat(subheader: Header) extends PatternNode - case class SequencePat(casted: Symbol, len: int) extends PatternNode // only used in PatternMatcher + case class SequencePat(override val casted: Symbol, len: int) extends PatternNode // only used in PatternMatcher - case class RightIgnoringSequencePat(casted: Symbol, castedRest: Symbol, minlen: int) extends PatternNode //PM + case class RightIgnoringSequencePat(override val casted: Symbol, castedRest: Symbol, minlen: int) extends PatternNode //PM /** the environment for a body of a case * @param owner the owner of the variables created here diff --git a/src/library/scala/xml/Node.scala b/src/library/scala/xml/Node.scala index fcffd0ce07..d40ed6a0b3 100644 --- a/src/library/scala/xml/Node.scala +++ b/src/library/scala/xml/Node.scala @@ -27,6 +27,8 @@ object Node { /** the empty namespace */ val EmptyNamespace = "" + def unapplySeq(n:Node) = Some (Tuple3(n.label, n.attributes, n.child)) + } /** diff --git a/src/library/scala/xml/QNode.scala b/src/library/scala/xml/QNode.scala new file mode 100644 index 0000000000..6324601254 --- /dev/null +++ b/src/library/scala/xml/QNode.scala @@ -0,0 +1,26 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: Node.scala 9454 2006-12-03 01:32:39 +0100 (Sun, 03 Dec 2006) emir $ + + +package scala.xml + +import compat.StringBuilder + +/** + * This object provides an extractor method to match a qualified node with its namespace URI + * + * @author Burak Emir + * @version 1.0 + */ +object QNode { + + def unapplySeq(n:Node) = Some (Tuple4(n.scope.getURI(n.prefix), n.label, n.attributes, n.child)) + +} diff --git a/test/files/jvm/xmlmore.scala b/test/files/jvm/xmlmore.scala index c6322bc1ef..0ba60b05b7 100644 --- a/test/files/jvm/xmlmore.scala +++ b/test/files/jvm/xmlmore.scala @@ -17,4 +17,13 @@ Ours is the portal of hope, come as you are." Console println crz // this guy will escaped, and rightly so Console println nazim Console println "End Test" + + match { + case scala.xml.QNode("gaga","foo",md,child@_*) => + } + + match { + case scala.xml.Node("foo",md,child@_*) => + } + } -- cgit v1.2.3