diff options
author | Burak Emir <emir@epfl.ch> | 2006-12-03 00:32:39 +0000 |
---|---|---|
committer | Burak Emir <emir@epfl.ch> | 2006-12-03 00:32:39 +0000 |
commit | ccb5bd1da84a8ae09bee61e16f08ca9d726b3270 (patch) | |
tree | 5cf4586be40870b0ca9389c0b15317bf970e9737 | |
parent | 6cffd12cb90c8353ccd8581a712bffb52a7b4c59 (diff) | |
download | scala-ccb5bd1da84a8ae09bee61e16f08ca9d726b3270.tar.gz scala-ccb5bd1da84a8ae09bee61e16f08ca9d726b3270.tar.bz2 scala-ccb5bd1da84a8ae09bee61e16f08ca9d726b3270.zip |
more on Xkilloption, and a PM fix
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/PatternMatchers.scala | 53 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/StdNames.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 233 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/LiftCode.scala | 2 | ||||
-rw-r--r-- | src/library/scala/xml/Node.scala | 6 | ||||
-rw-r--r-- | test/files/run/patmatnew.scala | 26 | ||||
-rw-r--r-- | test/files/run/unittest_xml.scala | 10 | ||||
-rw-r--r-- | test/pending/run/testSome.scala | 88 |
9 files changed, 333 insertions, 93 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala index d9957c87d0..f704703490 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala @@ -446,36 +446,23 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) { else pConstrPat(tree.pos, tpe.tpe) case t @ Typed(ident, tpe) => // variable pattern - //Console.println("Z"); - val doTest = isSubType(header.getTpe(),tpe.tpe); + // can't optimize using isSubType(header.getTpe(),tpe.tpe); + // leave that (null check!) for later val node = - if(doTest) pDefaultPat(tree.pos, tpe.tpe) - else pConstrPat(tree.pos, tpe.tpe) - if ((null != env) /* && (ident.symbol != defs.PatternWildcard) */) - node match { + pConstrPat(tree.pos, tpe.tpe) + if (null != env) node match { case ConstrPat(casted) => env.newBoundVar(t.expr.symbol, tpe.tpe, Ident( casted ).setType(casted.tpe)); - case _ => - env.newBoundVar(t.expr.symbol, - tpe.tpe, - {if(doTest) - header.selector - else - typed(Ident(node - .asInstanceOf[ConstrPat] - .casted))}); } - node + node case Ident(nme.WILDCARD) => pDefaultPat(tree.pos, header.getTpe()) case Ident(name) => // pattern without args or named constant - if (tree.symbol.isPrimaryConstructor) - scala.Predef.error("error may not happen: ident is primary constructor"+tree.symbol); // Burak - else - pVariablePat(tree.pos, tree); // named constant (capitalized variable Foo) + assert(!tree.symbol.isPrimaryConstructor) // may not happen + pVariablePat(tree.pos, tree); // named constant (capitalized variable Foo) case Select(_, name) => // named constant if (tree.symbol.isPrimaryConstructor) @@ -1179,14 +1166,27 @@ print() case DefaultPat() => return toTree(node.and); - case UnapplyPat(casted, fn @ Apply(fn1, _)) => - val v = newVar(fn.pos, fn.tpe) + case UnapplyPat(casted, fn @ Apply(fn2, _)) => + val fntpe = if(settings.Xkilloption.value) fn.tpe.typeArgs(0) else fn.tpe + //Console.println("unapply "+fntpe) + val v = newVar(fn.pos, fntpe) + var __opt_get__ = if(settings.Xkilloption.value) Ident(v) else typed(Select(Ident(v),nme.get)) + var __opt_nonemp__ = if(settings.Xkilloption.value) NotNull(Ident(v)) else Not(Select(Ident(v), nme.isEmpty)) + + var fn1 = fn2.duplicate; if(settings.Xkilloption.value) { + fn1.setType(transformInfo(owner, fn1.tpe)) + } Or(squeezedBlock( List(ValDef(v,Apply(fn1,List(selector)))), - And(Not(Select(Ident(v), nme.isEmpty)), - squeezedBlock(List(ValDef(casted, typed(Select(Ident(v),nme.get)))),toTree(node.and)))), + And(__opt_nonemp__, + squeezedBlock(List(ValDef(casted, __opt_get__)),toTree(node.and)))), toTree(node.or, selector.duplicate)) + case ConstrPat(casted) => + if(!isSubType(casted.tpe,selector.tpe) && settings.Xkilloption.value && definitions.isOptionType(selector.tpe)) { + // option of options + warning("in pattern match:problem matching "+casted.tpe+" against "+selector.tpe+"\n please avoid options of options!") + } def outerAlwaysEqual(left: Type, right: Type) = Pair(left,right) match { case Pair(TypeRef(lprefix, _,_), TypeRef(rprefix,_,_)) if lprefix =:= rprefix => true @@ -1302,7 +1302,10 @@ print() case VariablePat(tree) => val cmp = if(tree.tpe.symbol.isModuleClass && // objects are compared by eq, not == (avoids unnecessary null-magic) selector.tpe <:< definitions.AnyRefClass.tpe) { - Eq(selector.duplicate, tree) + if(settings.Xkilloption.value && tree.symbol == definitions.NoneClass) + IsNull(selector) + else + Eq(selector.duplicate, tree) } else { Equals(selector.duplicate, tree) } diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 752644d1e5..78354d92f2 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -650,9 +650,9 @@ trait Definitions requires SymbolTable { AnyClass, nme.toString_, List(), StringClass.typeConstructor) Any_isInstanceOf = newPolyMethod( - AnyClass, nme.isInstanceOf, tparam => booltype) setFlag FINAL + AnyClass, nme.isInstanceOf_, tparam => booltype) setFlag FINAL Any_asInstanceOf = newPolyMethod( - AnyClass, nme.asInstanceOf, tparam => tparam.typeConstructor) setFlag FINAL + AnyClass, nme.asInstanceOf_, tparam => tparam.typeConstructor) setFlag FINAL Any_isInstanceOfErased = newPolyMethod( AnyClass, nme.isInstanceOfErased, tparam => booltype) setFlag FINAL //todo: do we need this? diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index c688824a11..d2cc5d66ce 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -230,7 +230,7 @@ trait StdNames requires SymbolTable { val arraycopy = newTermName("arraycopy") val assert_ = newTermName("assert") val assume_ = newTermName("assume") - val asInstanceOf = newTermName("asInstanceOf") + val asInstanceOf_ = newTermName("asInstanceOf") val asInstanceOfErased = newTermName("asInstanceOf$erased") val booleanValue = newTermName("booleanValue") val box = newTermName("box") @@ -263,7 +263,7 @@ trait StdNames requires SymbolTable { val hasNext = newTermName("hasNext") val head = newTermName("head") val identity = newTermName("identity") - val isInstanceOf = newTermName("isInstanceOf") + val isInstanceOf_ = newTermName("isInstanceOf") val isInstanceOfErased = newTermName("isInstanceOf$erased") val isDefinedAt = newTermName("isDefinedAt") val isEmpty = newTermName("isEmpty") diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index f1fad915c0..2080baff5c 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -54,6 +54,71 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter } } +// <removeOption> + /** returns true if tpe was a real option type at prev phase, i.e. + * one that admits to extract an element type. + * @return true for real option type, false for all others, in particular None, scala.None.type, object scala.None + */ + def wasOption(tpe: Type): Boolean = ( tpe ne null ) && (tpe match { + case NoType => + false + case SingleType(_,sym) if sym eq definitions.NoneClass => + false + + case ThisType(sym) if sym eq definitions.SomeClass => // also eliminate Option.this.type? + false + + case SuperType(_,_) => + false + + case _ => + if(definitions.NoneClass eq tpe.symbol.linkedModuleOfClass) { + return false + } + var res: Option[Boolean] = None + atPhase(phase.prev) { + val it = tpe.baseClasses.elements; while(it.hasNext && res.isEmpty) { + val tp = it.next + if(tp.linkedModuleOfClass eq definitions.NoneClass) { + res = Some(false) // extremely rare, only appears in refinements, see dbc library + } + else if(definitions.isOptionType(tp.tpe)) { + res = Some(true) + } + } + } + return if(res.isEmpty) false else res.get + }) + + /** like @see wasOption, additionally tests whether argument is a reference type + */ + def wasOptionRef(tpe:Type): Boolean = try { + wasOption(tpe) && isSubType(getOptionArg(tpe), definitions.AnyRefClass.tpe) + } catch { + case e => + atPhase(phase.prev) { + e.printStackTrace() + Console.println("boom"+e.getMessage()+" tpe is "+tpe) + Console.println("baseclasses are "+tpe.baseClasses) + } + System.exit(-1) + false + } + + /** @precond wasOption(tpe) + */ + def getOptionArg(tpe:Type): Type = { + //Console.println("huh?"+wasOption(tpe)+" bah: "+tpe) + if (tpe.isInstanceOf[SingleType]) + getOptionArg(atPhase(phase.prev){tpe.widen}) + else if(tpe.symbol != null && tpe.symbol.isRefinementClass) { + getOptionArg(tpe.baseType(definitions.OptionClass)) + } else { + atPhase(phase.prev){tpe}.typeArgs(0) + } + } + +//</removeOption> /** <p> * The type transformation method: * </p> @@ -93,7 +158,10 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter * </ol> */ def transformInfo(sym: Symbol, tp: Type): Type = tp match { - case MethodType(formals, restpe1) => + case MethodType(formals1, restpe1) => + //Console.println("hello methodtype"+tp) + val formals = if(settings.Xkilloption.value) {formals1 map {x=>transformInfo(sym, x)}} // removeOption + else formals1 val restpe = transformInfo(sym, restpe1) // removeOption if (sym.owner.isTrait && ((sym hasFlag SUPERACCESSOR) || sym.isModule)) { // 5 sym.makeNotPrivate(sym.owner) @@ -104,7 +172,11 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter else if (restpe ne restpe1) MethodType(formals, restpe) // removeOption else tp - case ClassInfoType(parents, decls, clazz) => + case ClassInfoType(parents1, decls, clazz) => + if(settings.Xkilloption.value && (clazz.linkedModuleOfClass eq definitions.NoneClass)) + return tp + val parents = if(settings.Xkilloption.value) parents1 map {x => transformInfo(sym,x)} + else parents1 var decls1 = decls if (isInner(clazz) && !(clazz hasFlag INTERFACE)) { decls1 = newScope(decls.toList) @@ -131,21 +203,38 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter } } } - if (decls1 eq decls) tp else ClassInfoType(parents, decls1, clazz) + if ((decls1 eq decls)&&(parents1 eq parents)) tp else ClassInfoType(parents, decls1, clazz) case PolyType(tparams, restp) => val restp1 = transformInfo(sym, restp) if (restp eq restp1) tp else PolyType(tparams, restp1) - // <removeOption> - case TypeRef(_, sym, List(tpe)) - if settings.Xkilloption.value - && (sym == definitions.OptionClass || sym == definitions.SomeClass) - && isSubType(tpe, definitions.AnyRefClass.tpe) => - tpe + case TypeRef(pre,sym,args) if(settings.Xkilloption.value) => + if(wasOptionRef(tp)) { // ((sym eq definitions.OptionClass) || (sym eq definitions.SomeClass)) { + getOptionArg(tp) + } else { + val t = typeRef(pre,sym, args.map {t=>transformInfo(sym,t)}) + //Console.println("turning typeref "+tp+" to "+t) + t + } + // </removeOption> case _ => - tp + if(!settings.Xkilloption.value) + tp + else { // bq: gross hack for removing options in refinements (e.g. dbc). YMMV + if(tp.symbol.isRefinementClass) { + if(settings.debug.value) + Console.println("[k.o.] rewriting refinement ") + for(val d <- tp.decls.elements) { + val otpe = d.tpe + d setInfo transformInfo(tp.symbol, d.tpe) + if(settings.debug.value) + Console.println(" "+otpe+"-->"+d.tpe) + } + } + tp + } } /** A base class for transformers that maintain <code>outerParam</code> @@ -321,17 +410,6 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter /** The main transformation method */ override def transform(tree: Tree): Tree = { - def wasNone(tpe:Type) = atPhase(phase.prev){tpe}.symbol == definitions.NoneClass - def wasOption(tpe:Type) = { - def ntpe = if(tpe.isInstanceOf[SingleType]) tpe.widen else tpe - definitions.isOptionType(atPhase(phase.prev){ntpe}) - } - def wasOptionRef(tpe:Type) = { - def ntpe = if(tpe.isInstanceOf[SingleType]) tpe.widen else tpe - val otpe = atPhase(phase.prev){ntpe} - definitions.isOptionType(otpe) && isSubType(otpe.typeArgs(0), definitions.AnyRefClass.tpe) - } - val sym = tree.symbol if ((sym ne null) && sym.isType) {//(9) if (sym hasFlag PRIVATE) sym setFlag notPRIVATE @@ -341,41 +419,92 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter // <removeOption> - case sm @ Apply(fn, List(vlue)) // scala.Some(x:T) -> x if T <: AnyRef + case sm @ Apply(fn1, List(vlue)) // scala.Some(x:T) -> x if T <: AnyRef if settings.Xkilloption.value - && definitions.isSomeType(sm.tpe) - && fn.symbol.isClassConstructor - && isSubType(sm.tpe.typeArgs(0), definitions.AnyRefClass.tpe) => - vlue - + && wasOptionRef(sm.tpe) + && ((fn1.symbol eq null) // in patterns, symbol is null + || fn1.symbol.isClassConstructor) => + + val fn = transform(fn1) + if(settings.debug.value) + Console.println("[k.o. (apply)]"+tree+" ==> "+vlue) + if((fn.symbol eq null) && (vlue.symbol ne null/*isInstanceOf[Ident]*/)) { + val argtpe = getOptionArg(sm.tpe) + Typed(vlue, TypeTree().setType(argtpe)).setType(argtpe) // pattern matcher optimizes to null check + } else vlue + + case Ident(_) if settings.Xkilloption.value && (definitions.NoneClass eq tree.symbol) => // only appears in actors/Channel, possibly bug + if(settings.debug.value) + Console.println("[k.o. (ident)]"+tree+" ==> null") + atPos(tree.pos) { typer.typed { Literal(Constant(null)) }} case nne: Select // scala.None -> null - if settings.Xkilloption.value && wasNone(nne.tpe) => + if settings.Xkilloption.value && nne.symbol == definitions.NoneClass => // wasNone(nne.tpe) => + + if(settings.debug.value) + Console.println("[k.o. (select)]"+tree+" ==> null") atPos(tree.pos) { typer.typed { Literal(Constant(null)) }} case Apply(Select(t, nme.isEmpty),List()) // t.isEmpty -> t eq null if settings.Xkilloption.value && wasOption(t.tpe) => + if(settings.debug.value) + Console.println("[k.o. (isEmpty)]"+tree+" ==> "+t+" eq null") IsNull(t) case Apply(Select(t, nme.get),List()) // t.get -> t if T <: Option[AnyRef] if settings.Xkilloption.value && wasOptionRef(t.tpe) => + if(settings.debug.value) + Console.println("[k.o. (get)]"+tree+" ==> "+t) t + case Apply(TypeApply(Select(t, nme.isInstanceOf_), List(tt)), _) if settings.Xkilloption.value && wasOptionRef(t.tpe) => + NotNull(t) + + case Apply(ta@TypeApply(s@Select(t, nme.asInstanceOf_), List(tt)), List()) if settings.Xkilloption.value && wasOptionRef(t.tpe) => //&& definitions.isSomeType(tt.tpe) => + val tpe = tt.tpe + copy.Apply(tree, copy.TypeApply(ta, transform(s), List(TypeTree(tpe))), List()) + case Select(t, n) // methods ... + if settings.Xkilloption.value && wasOptionRef(t.tpe) && n != nme.get => + + val s = transform(t) + val tmp = currentOwner.newVariable(tree.pos, cunit.fresh.newName("opt")).setInfo(s.tpe) // careful: pos has special meaning + val nt = atPos(tree.pos) { typer.typed { + Block(List(ValDef(tmp,s)), + If(NotNull(Ident(tmp)), + Apply(Select(New(TypeTree(definitions.someType(s.tpe))), nme.CONSTRUCTOR), List(Ident(tmp))), + gen.mkAttributedRef(definitions.NoneClass) ) + ) + }} + val ntree = copy.Select(tree,nt,n) + if(settings.debug.value) + Console.println("[k.o. (select)]"+tree+" ==> "+ntree) + ntree + case Select(t, n) // methods ... - if settings.Xkilloption.value && wasOption(t.tpe) && n != nme.get => + if settings.Xkilloption.value && wasOption(t.tpe) && n != nme.get && t.symbol!=null => + def ntpe = if(t.tpe.isInstanceOf[SingleType]) t.tpe.widen else t.tpe val otpe = atPhase(phase.prev){ntpe} val nt = atPos(tree.pos) { typer.typed { If(NotNull(t), - Apply(Select(New(TypeTree( definitions.someType(otpe.typeArgs(0)))), nme.CONSTRUCTOR), List(t)), + t, gen.mkAttributedRef(definitions.NoneClass)) }} - copy.Select(tree,nt,n) + val ntree = copy.Select(tree,nt,n) + if(settings.debug.value) + Console.println("[k.o. (select2)]"+tree+" ==> "+ntree) + ntree case _ // e.g. map.get("bar") -> fix type if settings.Xkilloption.value && wasOptionRef(tree.tpe) => - super.transform(tree.setType(atPhase(phase.prev){tree.tpe}.typeArgs(0))) + if(settings.debug.value) { + Console.println("[k.o.] setting type of "+tree+" which is a "+tree.getClass) + Console.println(" ... to "+getOptionArg(tree.tpe)) + } + + val argtpe = getOptionArg(tree.tpe) + transform(tree.setType(argtpe)) // need to transform? super.transform? // </removeOption> @@ -394,8 +523,8 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter } } super.transform( - copy.Template(tree, parents, if (newDefs.isEmpty) decls else decls ::: newDefs.toList)) - + copy.Template(tree, parents, if (newDefs.isEmpty) decls else decls ::: newDefs.toList) + ) case DefDef(mods, name, tparams, vparamss, tpt, rhs) => if (sym.isClassConstructor) { rhs match { @@ -416,11 +545,14 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter } else { //todo: see whether we can move this to transformInfo if (sym.owner.isTrait && (sym hasFlag (ACCESSOR | SUPERACCESSOR))) sym.makeNotPrivate(sym.owner); //(2) - if(settings.Xkilloption.value - && definitions.isOptionType(tpt.tpe) - && isSubType(tpt.tpe.typeArgs(0), definitions.AnyRefClass.tpe)) { - return super.transform(copy.DefDef(tree,mods,name,tparams,vparamss, TypeTree(tpt.tpe.typeArgs(0)), rhs)) + if(settings.Xkilloption.value) { + //Console.println("vparamss"+vparamss) + val nvparamss = vparamss.map { x => super.transformValDefs(x) /*x.map { y => transform(y) if(wasOptionRef(y.tpe)) y.setType(getOptionArg(y.tpe)) */} + //Console.println("nvparamss"+nvparamss) + val ntpt = if(wasOptionRef(tpt.tpe)) TypeTree(getOptionArg(tpt.tpe)) else tpt + + return super.transform(copy.DefDef(tree,mods,name,tparams,nvparamss, ntpt, rhs)) } super.transform(tree) } @@ -470,7 +602,7 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter } val nselector = transform(selector) - assert(nselector.tpe =:= selector.tpe) + assert(nselector.tpe =:= selector.tpe || settings.Xkilloption.value) val ncases = transformCaseDefs(cases) ExplicitOuter.this.resultType = tree.tpe @@ -478,7 +610,8 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter //Console.println("TransMatcher selector.tpe ="+selector.tpe+")") //Console.println("TransMatcher resultType ="+resultType+")") - val t_untyped = handlePattern(nselector, ncases, currentOwner, transform) + val t_untyped = handlePattern(nselector, ncases, currentOwner, transform) + try { //Console.println("t_untyped "+t_untyped.toString()) val t = atPos(tree.pos) { localTyper.typed(t_untyped, resultType) } @@ -489,9 +622,25 @@ abstract class ExplicitOuter extends InfoTransform with TransMatcher with Patter if (settings.debug.value) Console.println("finished translation of " + tid) t - + } catch { + case e => + e.printStackTrace() + //treeBrowser.browse(Seq.single(unit).elements) + Console.println("[died while typechecking the translated pattern match:]") + Console.println(t_untyped) + System.exit(-1) + null + } + //<removeOption> + case TypeTree() if settings.Xkilloption.value => + tree setType transformInfo(currentOwner, tree.tpe) + tree case _ => - super.transform(tree) + val x = super.transform(tree) + + if(x.tpe eq null) x else { + x setType transformInfo(currentOwner, x.tpe) + } } } diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index b197146f74..bd6050f99a 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -52,7 +52,7 @@ abstract class LiftCode extends Transform { case None => targets.update(name, None) None - case Some(None) => None + //case Some(None) => None //bq:redundant case Some(tgt) => tgt } def hasAllTargets: Boolean = diff --git a/src/library/scala/xml/Node.scala b/src/library/scala/xml/Node.scala index e9d233af13..fcffd0ce07 100644 --- a/src/library/scala/xml/Node.scala +++ b/src/library/scala/xml/Node.scala @@ -67,7 +67,7 @@ abstract class Node extends NodeSeq { * @return the namespace if <code>scope != null</code> and prefix was * found, else <code>null</code> */ - def getNamespace(pre: String) = if (scope eq null) null else scope.getURI(pre) + def getNamespace(pre: String): String = if (scope eq null) null else scope.getURI(pre) /** * Convenience method, looks up an unprefixed attribute in attributes of this node. @@ -77,7 +77,7 @@ abstract class Node extends NodeSeq { * @return value of <code>UnprefixedAttribute</code> with given key * in attributes, if it exists, otherwise <code>null</code>. */ - final def attribute(key: String) = attributes.get(key) + final def attribute(key: String): Option[Seq[Node]] = attributes.get(key) /** * Convenience method, looks up a prefixed attribute in attributes of this node. @@ -88,7 +88,7 @@ abstract class Node extends NodeSeq { * @return value of <code>PrefixedAttribute</code> with given namespace * and given key, otherwise <code>null</code>. */ - final def attribute(uri: String, key: String) = attributes.get(uri, this, key) + final def attribute(uri: String, key: String): Option[Seq[Node]] = attributes.get(uri, this, key) /** * Returns attribute meaning all attributes of this node, prefixed and unprefixed, diff --git a/test/files/run/patmatnew.scala b/test/files/run/patmatnew.scala index d7cb9aec6f..377e89a267 100644 --- a/test/files/run/patmatnew.scala +++ b/test/files/run/patmatnew.scala @@ -20,7 +20,7 @@ object Test { val tr = new TestResult new TestSuite( - new Test01 + new Test717 ).run(tr) @@ -31,7 +31,7 @@ object Test { class Foo(j:Int) { case class Bar(i:Int) } - class Test01 extends TestCase("bir (#717 test path of case classes)") { + class Test717 extends TestCase("#717 test path of case classes") { val foo1 = new Foo(1) val foo2 = new Foo(2) @@ -43,4 +43,26 @@ object Test { assertTrue("ok", res); } } + + class Test806_818 { // #806, #811 compile only -- type of bind + // bug811 + trait Core { + trait NodeImpl; + trait OtherImpl extends NodeImpl; + trait DoubleQuoteImpl extends NodeImpl; + def asDQ(node : OtherImpl) = node match { + case dq : DoubleQuoteImpl => dq; + } + } + + trait IfElseMatcher { + type Node <: NodeImpl; + trait NodeImpl; + trait IfImpl; + private def coerceIf(node : Node) = node match { + case node : IfImpl => node; // var node is of type Node with IfImpl! + case _ => null; + } + } + } } diff --git a/test/files/run/unittest_xml.scala b/test/files/run/unittest_xml.scala index 5f7c523996..99284f144e 100644 --- a/test/files/run/unittest_xml.scala +++ b/test/files/run/unittest_xml.scala @@ -2,9 +2,14 @@ object Test { import scala.testing.SUnit._ - import scala.xml.{MetaData, Null, PrefixedAttribute, UnprefixedAttribute } + import scala.xml.{MetaData, Null, Parsing, PrefixedAttribute, UnprefixedAttribute } - class MetaDataTest extends TestCase("collection.mutable.ArrayBuffer") with Assert { + class ParsingTest extends TestCase("scala.xml.Parsing") with Assert { + override def runTest = { + assertTrue(Parsing.isNameStart('b')) + } + } + class MetaDataTest extends TestCase("scala.xml.MetaData") with Assert { import scala.xml.{TopScope, NamespaceBinding, Atom, Text } @@ -44,6 +49,7 @@ object Test { def main(args:Array[String]) = { val ts = new TestSuite( + new ParsingTest, new MetaDataTest //, ) val tr = new TestResult() diff --git a/test/pending/run/testSome.scala b/test/pending/run/testSome.scala index 9ed3a35558..4320adb681 100644 --- a/test/pending/run/testSome.scala +++ b/test/pending/run/testSome.scala @@ -1,43 +1,103 @@ import testing.SUnit._ +//trait Foo { +// def bar:Option[Seq[xml.Node]] = Some(Nil) +//} object testSome extends Assert { + //val x: Option[String] = Some("foo") - val x: Option[String] = Some("foo") + //val x1: Option[Int] = Some(3) - val x1: Option[Int] = Some(3) + //val y: Option[String] = None - val y: Option[String] = None - - val y1: Option[Int] = None + //val y1: Option[Int] = None def main(args:Array[String]) = { - assertFalse("some[string].isEmpty ", x.isEmpty) // x eq null - assertFalse("some[int].isEmpty ", x1.isEmpty) + //assertFalse("some[string].isEmpty ", x.isEmpty) // x eq null + //assertFalse("some[int].isEmpty ", x1.isEmpty) - assertTrue("none<:opt[string].isEmpty ", y.isEmpty) + // assertTrue("some[string].isInstanceOf[Some] ", x.isInstanceOf[Some[String]]) + // assertTrue("some[int].isInstanceOf[Some] ", x1.isInstanceOf[Some[Int]]) + //assertTrue("some[string].asInstanceOf[Some] ", {x.asInstanceOf[Some[String]];true}) + //assertTrue("some[int].asInstanceOf[Some] ", {x1.asInstanceOf[Some[Int]]; true}) + /* + assertTrue("none<:opt[string].isEmpty ", y.isEmpty) assertTrue("non<:opt[int].isEmpty ", y1.isEmpty) - Console.println(x.get) // x - - Console.println(x1.get) + assertEquals("Some(foo).get ", "foo", x.get) + assertEquals("Some(3).get ", 3, x1.get) val f = {x:String => Some(x.length)} val len:Option[Int] = x.flatMap(f) Console.println("len: (3) "+len) + val g = {x:String => x.charAt(0) == 'f'} Console.println("filter: (foo) "+x.filter(g)) - // to do: - - //assertEquals("equals", len == Some(3)) +// assertEquals("equals", len == Some(3)) // matching + x match { + case Some("foo") => true + case None => false + } + // matching + x match { + case Some(z) => z + case _ => null + } + x match { + case None => "3" + case Some(z) => "4" + } +*/ + + new collection.mutable.HashMap[Int,Option[String]]().get(1) match { + case Some(Some(x)) => 1 + case _ => 2 + } // unapply } +/* + def foobar(x:Foo) = {x.bar == 42} // nonsense + val zz : Option[Int] = try { Some(1/0) } catch { case _ => None} + + trait ZyGo { + def impolite: Option[String] + } + val foo = new ZyGo { + val impolite = None + } + + class Fu { + def bar: Option[String] = Some("foo") + } + new Fu().bar + + def isNullable (metadata:java.sql.ResultSetMetaData, index:Int): Option[scala.Boolean] = + metadata.isNullable(index) match { + case java.sql.ResultSetMetaData.columnNoNulls => Some(false); + case java.sql.ResultSetMetaData.columnNullable => Some(true); + //case java.sql.ResultSetMetaData.columnNoNulls => None; // bq:unreachable code + } + + + def names_get_self : Option[scala.Symbol] = None + + def send: Tuple1[String] = { + val senderName = new collection.mutable.HashMap[String, scala.Symbol].get("foo") match { + case None => + "foo" + case Some(name) => + "bar" + } + Tuple1(senderName) + } +*/ } |