summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2006-10-26 14:55:40 +0000
committerBurak Emir <emir@epfl.ch>2006-10-26 14:55:40 +0000
commit21808a3d775b20f8e0d6cd894bf6dbbb69deb731 (patch)
tree4b9333c7f33e980e7e97076d44fcb56910034fd7 /src
parent4a56a364a4a54821b58eee385ea1a822b9d99bb5 (diff)
downloadscala-21808a3d775b20f8e0d6cd894bf6dbbb69deb731.tar.gz
scala-21808a3d775b20f8e0d6cd894bf6dbbb69deb731.tar.bz2
scala-21808a3d775b20f8e0d6cd894bf6dbbb69deb731.zip
unapply patch
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala114
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternNodes.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala29
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala99
-rw-r--r--src/library/scala/Product1.scala18
-rw-r--r--src/library/scala/Product2.scala19
-rw-r--r--src/library/scala/Product3.scala20
-rw-r--r--src/library/scala/Product4.scala21
-rw-r--r--src/library/scala/Product5.scala22
-rw-r--r--src/library/scala/Product6.scala23
-rw-r--r--src/library/scala/Product7.scala24
-rw-r--r--src/library/scala/Product8.scala25
-rw-r--r--src/library/scala/Product9.scala26
14 files changed, 421 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 0292cec24c..72b7fd9d79 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -93,11 +93,9 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
def pSequencePat(pos: PositionType, tpe: Type, len: int) = {
//assert (tpe != null)
val sym = newVar(FirstPos, tpe)
- //Console.println("pncrea::sequencePat sym.pos = "+sym.pos)
val node = new SequencePat(sym, len)
node.pos = pos
node.tpe = tpe
- //Console.println("pncrea::sequencePat sym.pos = "+sym.pos)
node
}
@@ -139,6 +137,22 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
node
}
+ def pUnapplyPat(pos: PositionType, fn: Tree) = {
+ // the type of the "child" of unapply is AnyRef, because want to check
+ // against null and in this way, this is done using the isInstanceOf
+ // magic. @todo, replace this with null check
+ val tpe = definitions.AnyRefClass.tpe
+ /* val tpe = fn.tpe match {
+ case MethodType(_,TypeRef(_,_,args)) => // pedantic? add if sym==defs.TupleClass(args.length).
+ if(args.isEmpty) definitions.UnitClass.tpe else definitions.tupleType(args)
+ } */
+ val node = new UnapplyPat(newVar(pos, tpe), fn)
+ //Console.println("!pUnapply sym = "+node.symbol+" tpe "+tpe)
+ node.pos = pos
+ node.setType(definitions.AnyRefClass.tpe)
+ node
+ }
+
def pConstantPat(pos: PositionType, tpe: Type, value: Any) = {
//assert (tpe != null)
val node = new ConstantPat(value)
@@ -328,6 +342,14 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
tree.body = nb
}
+ protected def isUnapply(tree:Tree): Boolean = tree match {
+ case Apply(fn, args) if (settings.Xunapply.value && fn.symbol != null && fn.symbol.name == nme.unapply) =>
+ //Console.println("isUnapply:"+tree)
+ true
+ case _ =>
+ false
+ }
+
/** returns the child patterns of a pattern
*/
protected def patternArgs(tree: Tree): List[Tree] = {
@@ -360,15 +382,13 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
}
protected def patternNode(tree:Tree , header:Header , env: CaseEnv ): PatternNode = {
- //if(tree!=null) Console.println("patternNode("+tree+","+header+")");
+ //Console.println("patternNode("+tree+","+header+")");
//else scala.Predef.error("got null tree in patternNode");
//Console.println("tree.tpe "+tree.tpe);
//Console.println("tree.getClass() "+tree.getClass());
- tree match {
+ val t = tree match {
case Bind(name, Typed(Ident( nme.WILDCARD ), tpe)) => // x@_:Type
- if (false && isSubType(header.getTpe(),tpe.tpe)) {
- // this optimization is not correct, because
- // null.isInstanceOf will return false
+ if (isSubType(header.getTpe(),tpe.tpe)) {
val node = pDefaultPat(tree.pos, tpe.tpe)
env.newBoundVar(tree.symbol, tree.tpe, header.selector)
node
@@ -397,6 +417,10 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
}
node
+ case t @ Apply(fn, args) if isUnapply(t) =>
+ //t.setType(definitions.AnyRefClass.tpe) // hack to avoid stupid effects
+ pUnapplyPat(tree.pos, fn)
+
case t @ Apply(fn, args) => // pattern with args
//Console.println("Apply node: "+t);
//Console.println("isSeqApply "+isSeqApply(t));
@@ -518,6 +542,8 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
Predef.error("unit = " + cunit + "; tree = " +
(if (tree == null) "null" else tree))
}
+ //Console.print(t);
+ t
}
protected def enter(pat: Tree, index: Int, target: PatternNode,
@@ -547,7 +573,23 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
List(Literal(Constant(index)))))
val seqType = t.tpe
pHeader( pos, seqType, t )
+ } else if (defs.isProductType(casted.tpe)) {
+ val acc = defs.productProj(casted.tpe.typeArgs.length, index+1)
+ val accTree = typed(Apply(Select(ident, acc), List())) // nsc !
+ pHeader(pos, accTree.tpe, accTree)
} else {
+ //Console.println("NOT FIRSTPOS");
+ //Console.println("newHeader :: ");
+ /*
+ if(!casted.tpe.symbol.hasFlag(Flags.CASE)) {
+ Console.println(" newHeader :: casted="+casted);
+ Console.println(" newHeader :: casted.pos="+casted.pos);
+ Console.println(" newHeader :: casted.pos==Position.FIRSTPOS"+(casted.pos == Position.FIRSTPOS));
+ Console.println(" newHeader :: casted.tpe="+casted.tpe);
+ Console.println(" newHeader :: casted.tpe.symbol="+casted.tpe.symbol);
+ throw new Error("internal problem, trying casefield access for no case class") //DBG
+ }
+ */
val caseAccs = casted.tpe.symbol.caseFieldAccessors;
if (caseAccs.length <= index) System.out.println("selecting " + index + " in case fields of " + casted.tpe.symbol + "=" + casted.tpe.symbol.caseFieldAccessors);//debug
val ts = caseAccs(index);
@@ -594,6 +636,11 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
//Console.println(" -- adding new header")
//assert index >= 0 : casted;
if (index < 0) { Predef.error("error entering:" + casted); return null }
+
+ if(!target.isInstanceOf[UnapplyPat] && !isUnapply(pat)) { // most common case
+ //Console.println("Hello 3, target "+target)
+ //access the index'th child of a case class
+
curHeader = newHeader(pat.pos, casted, index)
target.and = curHeader; // (*)
@@ -601,9 +648,37 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
curHeader.or = patternNode(pat, curHeader, env)
enter(patArgs, curHeader.or, casted, env)
+
+ } else if(target.isInstanceOf[UnapplyPat]) target match { // parent is unapply
+ case UnapplyPat(ncasted, fn) =>
+ // do a pHeader for "Some", but skip one for Product
+ //Console.println("Hello 2")
+ // @todo this erases existing unapply pat children -- if optimizing unapply, need to revisit
+ val curHeader = pHeader(pat.pos, ncasted.tpe, Ident(ncasted) setType ncasted.tpe)
+ target.and = curHeader
+ val pn = patternNode(pat, curHeader, env)
+ //Console.println("ncasted.tpe "+ncasted.tpe)
+ //Console.println("pn ="+pn)
+ curHeader.or = pn
+ //Console.println("patArgs = "+patArgs)
+ //Console.println("curHeader = "+curHeader)
+ //Console.println("curHeader.or = "+curHeader.or)
+ //Console.println("pn.sym = "+pn.symbol)
+ enter(patArgs, curHeader.or, pn.symbol, env)
+ } else pat match { // isUnapply(pat) holds;
+ case Apply(fn,args) => // load the result of fn(casted)
+ Console.println("Hello 1")
+ val ident = Ident(casted)
+ curHeader = pHeader( pat.pos, definitions.AnyRefClass.tpe, Apply(fn,List(ident)))
+ target.and = curHeader
+ //test
+ curHeader.or = patternNode(pat, curHeader, env)
+ //Console.println("have to add a header and casted is "+casted+" casted.tpe is "+casted.tpe) // DBG ;
+ enter(patArgs, curHeader.or, casted, env)
}
- else {
- //Console.println(" -- reusing old header")
+
+ } else {
+ //Console.println(" enter: using old header for casted = "+casted) // DBG
// find most recent header
while (curHeader.next != null)
curHeader = curHeader.next
@@ -659,6 +734,8 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
var target = target1
var casted = casted1
target match {
+ case UnapplyPat(newCasted, fn) =>
+ casted = newCasted
case ConstrPat(newCasted) =>
casted = newCasted
case SequencePat(newCasted, len) =>
@@ -711,8 +788,8 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
//print()
generalSwitchToTree()
}
- if(settings.statistics.value)
- Console.println("could remove "+(nremoved+nsubstituted)+" ValDefs, "+nremoved+" by deleting and "+nsubstituted+" by substitution")
+ //if(settings.statistics.value)
+ //Console.println("could remove "+(nremoved+nsubstituted)+" ValDefs, "+nremoved+" by deleting and "+nsubstituted+" by substitution")
return t
}
case class Break(res:Boolean) extends java.lang.Throwable
@@ -727,9 +804,9 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
while (({node = node.or; node}) != null) {
node match {
case VariablePat(tree) =>
- //Console.println(((tree.symbol.flags & Flags.CASE) != 0));
+ //Konsole.println(((tree.symbol.flags & Flags.CASE) != 0));
case ConstrPat(_) =>
- //Console.println(node.getTpe().toString() + " / " + ((node.getTpe().symbol.flags & Flags.CASE) != 0));
+ //Konsole.println(node.getTpe().toString() + " / " + ((node.getTpe().symbol.flags & Flags.CASE) != 0));
var inner = node.and;
def funct(inner: PatternNode): Boolean = {
//outer: while (true) {
@@ -749,7 +826,6 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
throw Break2() // break outer
case _ =>
- //Console.println(inner)
throw Break(false)
}
}
@@ -964,7 +1040,6 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
var node = node1;
var res: Tree = typed(Literal(Constant(false))); //.setInfo(defs.BooleanClass);
- //Console.println("pm.toTree res.tpe "+res.tpe);
while (node != null)
node match {
@@ -972,7 +1047,6 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
val selector = _h.selector;
val next = _h.next;
//res = And(mkNegate(res), toTree(node.or, selector));
- //Console.println("HEADER TYPE = " + _h.selector.tpe);
if (optimize1(node.getTpe(), node.or))
res = Or(res, toOptTree(node.or, selector));
else
@@ -1116,8 +1190,7 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
Or(And(cond, thenp), elsep)
protected def toTree(node: PatternNode, selector:Tree): Tree = {
- //Console.println("pm.toTree("+node+","+selector+")")
- //Console.println("pm.toTree selector.tpe = "+selector.tpe+")")
+ //Konsole.println("pm.toTree("+node+","+selector+") selector.tpe = "+selector.tpe+")")
if (selector.tpe == null)
scala.Predef.error("cannot go on")
if (node == null)
@@ -1127,6 +1200,9 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
case DefaultPat() =>
return toTree(node.and);
+ case UnapplyPat(casted,fn) =>
+ return Or(Block(List(ValDef(casted, Apply(fn,List(selector)))), toTree(node.and)),
+ toTree(node.or, selector.duplicate))
case ConstrPat(casted) =>
def outerAlwaysEqual(left: Type, right: Type) = Pair(left,right) match {
case Pair(TypeRef(lprefix, _,_), TypeRef(rprefix,_,_)) if lprefix =:= rprefix =>
@@ -1166,7 +1242,6 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
return myIf(cond, succ, fail)
case SequencePat(casted, len) =>
- //Console.println("(8945)"+node)
val ntpe = node.getTpe
val tpetest =
@@ -1181,7 +1256,6 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes) {
else
selector.duplicate
- //Console.println("SequencePat! casted="+casted+" selector "+selector)
val succ: Tree = squeezedBlock(
List(ValDef(casted, treeAsSeq)),
toTree(node.and))
diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
index 46ef9373d6..7f6abff21a 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
@@ -58,6 +58,8 @@ trait PatternNodes requires transform.ExplicitOuter {
}
def symbol: Symbol = this match {
+ case UnapplyPat(casted, fn) =>
+ casted
case ConstrPat(casted) =>
casted
case SequencePat(casted, _) =>
@@ -163,6 +165,8 @@ trait PatternNodes requires transform.ExplicitOuter {
"ConstantPat(" + value + ")"
case VariablePat(tree) =>
"VariablePat"
+ case UnapplyPat(casted,fn) =>
+ "UnapplyPat(" + casted + ")"
case _ =>
"<unknown pat>"
}
@@ -267,6 +271,7 @@ trait PatternNodes requires transform.ExplicitOuter {
case class DefaultPat()extends PatternNode
case class ConstrPat(casted:Symbol) extends PatternNode
+ case class UnapplyPat(tple:Symbol, fn:Tree) extends PatternNode
case class ConstantPat(value: Any /*AConstant*/) extends PatternNode
case class VariablePat(tree: Tree) extends PatternNode
case class AltPat(subheader: Header) extends PatternNode
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 4449433102..bbfa7d6d5b 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -145,8 +145,8 @@ trait Definitions requires SymbolTable {
}
def someType(tp: Type) =
typeRef(SomeClass.typeConstructor.prefix, SomeClass, List(tp))
- /* </unapply> */
+ /* </unapply> */
val MaxFunctionArity = 9
val FunctionClass: Array[Symbol] = new Array(MaxFunctionArity + 1)
def functionApply(n: Int) = getMember(FunctionClass(n), nme.apply)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index a4dd9f394d..1ef4585800 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -400,7 +400,34 @@ trait Namers requires Analyzer {
case _ => tpe
});
- private def templateSig(templ: Template): Type = {
+ //<unapply>bq: this should probably be in SyntheticMethods, but needs the typer
+ private def getCaseFields(templ_stats:List[Tree]):List[Pair[Type,Name]] =
+ for(val z <- templ_stats; // why does `z: ValDef <- ' not work? because translation of `for' is buggy?
+ z.isInstanceOf[ ValDef ];
+ val x = z.asInstanceOf[ ValDef ];
+ x.mods.hasFlag( CASEACCESSOR ))
+ yield Pair(typer.typedType(x.tpt).tpe, x.name)
+ //</unapply>
+
+ private def templateSig(templ0: Template): Type = {
+ var templ = templ0
+ //<unapply>
+ if(settings.Xunapply.value && (context.owner hasFlag CASE)) {
+ val caseFields = getCaseFields(templ.body)
+ if(caseFields.length > 0) {
+ //if(settings.debug.value) Console.println("[ templateSig("+templ+") of case class")
+ val addparent = TypeTree(productType(caseFields map (._1)))
+ var i = 0;
+ // CAREFUL for Tuple1, name `_1' will be added later by synthetic methods :/
+ val addimpl = caseFields map { x =>
+ val ident = Ident(x._2)
+ i = i + 1
+ DefDef(Modifiers(OVERRIDE | FINAL), "__"+i.toString(), List(), List(List()), TypeTree(x._1), ident) // pick __1 for now
+ }
+ templ = copy.Template(templ, templ.parents:::List(addparent),templ.body:::addimpl)
+ }
+ }
+ //</unapply>
val clazz = context.owner
def checkParent(tpt: Tree): Type = {
val tp = tpt.tpe
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 8b5cabc8f8..e2e100b831 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -397,6 +397,9 @@ trait Typers requires Analyzer {
* instance of its primary constructor that is a subtype of the expected type.
* (5.2) Otherwise, if this type is a subtype of scala.Seq[A], set trees' type
* to a method type from a repeated parameter sequence type A* to the expected type.
+ * (5.3beta) unapply-pattern matching: fix reference to object containing
+ * unapply or unapplySeq method.
+ *
* (6) Convert all other types to TypeTree nodes.
* (7) When in TYPEmode nut not FUNmode, check that types are fully parameterized
* (8) When in both EXPRmode and FUNmode, add apply method calls to values of object type.
@@ -491,6 +494,19 @@ trait Typers requires Analyzer {
case ErrorType =>
setError(tree)
}
+ } else if (settings.Xunapply.value) { /*unapply (5.3beta) */
+ // fix symbol -- we are using the module not the class
+ val consp = if(clazz.isModule) clazz else {
+ val obj = clazz.linkedModuleOfClass
+ tree.setSymbol(obj)
+ obj
+ }
+ var unapp = { // find unapply[Seq] mehod
+ val x = consp.tpe.decl(nme.unapply)
+ if (x != NoSymbol) x else consp.tpe.decl(nme.unapplySeq)
+ }
+ if(unapp != NoSymbol) tree
+ else errorTree(tree, "" + clazz + " does not have unapply/unapplySeq method")
} else {
errorTree(tree, "" + clazz + " is neither a case class nor a sequence class")
}
@@ -706,8 +722,14 @@ trait Typers requires Analyzer {
reenterTypeParams(cdef.tparams)
val tparams1 = List.mapConserve(cdef.tparams)(typedAbsTypeDef)
val tpt1 = checkNoEscaping.privates(clazz.thisSym, typedType(cdef.tpt))
- val impl1 = newTyper(context.make(cdef.impl, clazz, newTemplateScope(cdef.impl, clazz)))
- .typedTemplate(cdef.impl, parentTypes(cdef.impl))
+ //<unapply> // add ProductN before typing
+ var impl0 = if(settings.Xunapply.value && (clazz hasFlag CASE) && !phase.erasedTypes) {
+ addProductParts(clazz, cdef.impl)
+ } else
+ cdef.impl
+ //</unapply>
+ val impl1 = newTyper(context.make(impl0, clazz, newScope))
+ .typedTemplate(impl0, parentTypes(impl0))
val impl2 = addSyntheticMethods(impl1, clazz, context.unit)
val ret = copy.ClassDef(cdef, cdef.mods, cdef.name, tparams1, tpt1, impl2)
.setType(NoType)
@@ -719,7 +741,7 @@ trait Typers requires Analyzer {
* @return ...
*/
def typedModuleDef(mdef: ModuleDef): Tree = {
- //System.out.println("sourcefile of " + mdef.symbol + "=" + mdef.symbol.sourceFile)
+ System.out.println("sourcefile of " + mdef.symbol + "=" + mdef.symbol.sourceFile)
attributes(mdef)
val clazz = mdef.symbol.moduleClass
val impl1 = newTyper(context.make(mdef.impl, clazz, newTemplateScope(mdef.impl, clazz)))
@@ -1149,6 +1171,64 @@ trait Typers requires Analyzer {
val args1 = typedArgs(args, mode)
inferMethodAlternative(fun, context.undetparams, args1 map (.tpe.deconst), pt)
typedApply(tree, adapt(fun, funMode(mode), WildcardType), args1, mode, pt)
+/* --- begin unapply --- */
+ case otpe @ SingleType(_,sym) if settings.Xunapply.value => // normally, an object 'Foo' cannot be applied -> unapply pattern
+
+ val unapp = otpe.decl(nme.unapply)
+ if(unapp.exists) unapp.tpe match { // try unapply first
+ case MethodType(formals0,restpe) => // must take (x:Any)
+
+ if(formals0.length != 1)
+ return errorTree(tree,"unapply should take exactly one argument but takes "+formals0)
+
+ val argt = formals0(0) // @todo: check this against pt, e.g. cons[int](_hd:int_, tl:List[int])
+
+ var prodtpe: Type = null
+ var nargs: Int = -1 // signals error
+
+ val sometpe = restpe match {
+ case TypeRef(_,sym, List(stpe)) if sym == definitions.getClass("scala.Option") => stpe
+ case _ => return errorTree(tree,"unapply should return option[.], not "+restpe); null
+ }
+
+ val rsym = sometpe.symbol
+
+ sometpe.baseClasses.find { x => isProductType(x.tpe) } match {
+ case Some(x) =>
+ prodtpe = sometpe.baseType(x)
+ nargs = x.tpe.asInstanceOf[TypeRef].args.length
+ case _ =>
+ if(sometpe =:= definitions.UnitClass.tpe)
+ nargs = 0
+ else
+ return errorTree(tree, "result type '"+sometpe+"' of unapply is neither option[product] nor option[unit]")
+ }
+
+ if(nargs != args.length)
+ return errorTree(tree, "wrong number of arguments for unapply, expects "+formals0)
+
+ // check arg types
+ val child = for(val Pair(arg,atpe) <- args.zip(sometpe.typeArgs)) yield typed(arg, mode, atpe)
+
+ // Product_N(...)
+ val child1 = Apply(Ident(prodtpe.symbol.name) setType prodtpe setSymbol prodtpe.symbol, child) setSymbol prodtpe.symbol setType prodtpe
+
+ // Some(Product_N(...)) DBKK
+ val some = typed(Apply(Ident(nme.Some), List(child1)), mode, definitions.optionType(prodtpe) /*AnyClass.tpe*/)
+
+ // Foo.unapply(Some(Product_N(...)))
+ return Apply(gen.mkAttributedSelect(fun0,unapp), List(some)) setType pt
+
+ case PolyType(params,restpe) =>
+ errorTree(tree, "polym unapply not implemented")
+ case tpe =>
+ errorTree(tree, " can't handle unapply of type "+tpe)
+ } // no unapply
+
+ val unappSeq = otpe.decl(nme.unapplySeq)
+ errorTree(tree, " can't handle unapplySeq")
+
+/* --- end unapply --- */
case MethodType(formals0, restpe) =>
val formals = formalTypes(formals0, args.length)
if (formals.length != args.length) {
@@ -1277,6 +1357,7 @@ trait Typers requires Analyzer {
protected def typedHookForTree(tree : Tree, mode : Int, pt : Type): Tree = null;
protected def typed1(tree: Tree, mode: int, pt: Type): Tree = {
+ //Console.println("typed1("+tree.getClass()+","+Integer.toHexString(mode)+","+pt+")")
{ // IDE hook
val ret = typedHookForTree(tree, mode, pt)
if (ret != null) return ret
@@ -1484,6 +1565,17 @@ trait Typers requires Analyzer {
if (defSym == NoSymbol) cx = cx.outer
}
}
+ /*<unapply>*/
+ if(settings.Xunapply.value)
+ // unapply: in patterns, look for an object if can't find type
+ if(name.isTypeName && defSym == NoSymbol && (mode & PATTERNmode) != 0) {
+ typedIdent(name.toTermName) match {
+ case t if t.symbol.isModule =>
+ return t
+ case _ => // found methsym (case class handling...), ignore
+ }
+ }
+ /*</unapply>*/
val symDepth = if (defEntry == null) cx.depth
else cx.depth - (cx.scope.nestingLevel - defEntry.owner.nestingLevel)
var impSym: Symbol = NoSymbol; // the imported symbol
@@ -1942,7 +2034,6 @@ trait Typers requires Analyzer {
val ret = typedHookForType(tree, mode, pt);
if (ret != null) return ret;
}
-
//System.out.println("typing "+tree+", "+context.undetparams);//DEBUG
val tree1 = if (tree.tpe != null) tree else typed1(tree, mode, pt)
//System.out.println("typed "+tree1+":"+tree1.tpe+", "+context.undetparams);//DEBUG
diff --git a/src/library/scala/Product1.scala b/src/library/scala/Product1.scala
new file mode 100644
index 0000000000..a3d94ca8ab
--- /dev/null
+++ b/src/library/scala/Product1.scala
@@ -0,0 +1,18 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product1 [+T1] {
+ def __1:T1
+
+}
diff --git a/src/library/scala/Product2.scala b/src/library/scala/Product2.scala
new file mode 100644
index 0000000000..d607efbabb
--- /dev/null
+++ b/src/library/scala/Product2.scala
@@ -0,0 +1,19 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product2 [+T1, +T2] {
+ def __1:T1
+ def __2:T2
+
+}
diff --git a/src/library/scala/Product3.scala b/src/library/scala/Product3.scala
new file mode 100644
index 0000000000..6561294b1b
--- /dev/null
+++ b/src/library/scala/Product3.scala
@@ -0,0 +1,20 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product3 [+T1, +T2, +T3] {
+ def __1:T1
+ def __2:T2
+ def __3:T3
+
+}
diff --git a/src/library/scala/Product4.scala b/src/library/scala/Product4.scala
new file mode 100644
index 0000000000..3fe2008f0d
--- /dev/null
+++ b/src/library/scala/Product4.scala
@@ -0,0 +1,21 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product4 [+T1, +T2, +T3, +T4] {
+ def __1:T1
+ def __2:T2
+ def __3:T3
+ def __4:T4
+
+}
diff --git a/src/library/scala/Product5.scala b/src/library/scala/Product5.scala
new file mode 100644
index 0000000000..649d14fa35
--- /dev/null
+++ b/src/library/scala/Product5.scala
@@ -0,0 +1,22 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product5 [+T1, +T2, +T3, +T4, +T5] {
+ def __1:T1
+ def __2:T2
+ def __3:T3
+ def __4:T4
+ def __5:T5
+
+}
diff --git a/src/library/scala/Product6.scala b/src/library/scala/Product6.scala
new file mode 100644
index 0000000000..d30bd51fb2
--- /dev/null
+++ b/src/library/scala/Product6.scala
@@ -0,0 +1,23 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product6 [+T1, +T2, +T3, +T4, +T5, +T6] {
+ def __1:T1
+ def __2:T2
+ def __3:T3
+ def __4:T4
+ def __5:T5
+ def __6:T6
+
+}
diff --git a/src/library/scala/Product7.scala b/src/library/scala/Product7.scala
new file mode 100644
index 0000000000..6416ec2303
--- /dev/null
+++ b/src/library/scala/Product7.scala
@@ -0,0 +1,24 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product7 [+T1, +T2, +T3, +T4, +T5, +T6, +T7] {
+ def __1:T1
+ def __2:T2
+ def __3:T3
+ def __4:T4
+ def __5:T5
+ def __6:T6
+ def __7:T7
+
+}
diff --git a/src/library/scala/Product8.scala b/src/library/scala/Product8.scala
new file mode 100644
index 0000000000..cb7dd82698
--- /dev/null
+++ b/src/library/scala/Product8.scala
@@ -0,0 +1,25 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product8 [+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8] {
+ def __1:T1
+ def __2:T2
+ def __3:T3
+ def __4:T4
+ def __5:T5
+ def __6:T6
+ def __7:T7
+ def __8:T8
+
+}
diff --git a/src/library/scala/Product9.scala b/src/library/scala/Product9.scala
new file mode 100644
index 0000000000..545648beea
--- /dev/null
+++ b/src/library/scala/Product9.scala
@@ -0,0 +1,26 @@
+
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2006, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// generated on Tue Oct 03 14:50:06 CEST 2006
+package scala
+
+import Predef._
+
+trait Product9 [+T1, +T2, +T3, +T4, +T5, +T6, +T7, +T8, +T9] {
+ def __1:T1
+ def __2:T2
+ def __3:T3
+ def __4:T4
+ def __5:T5
+ def __6:T6
+ def __7:T7
+ def __8:T8
+ def __9:T9
+
+}