summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-08-21 16:45:26 +0000
committerMartin Odersky <odersky@gmail.com>2007-08-21 16:45:26 +0000
commit649289cb6882a3534ef7ac2f4a50e096af84c45f (patch)
treedaa70c139383a7f186c391e6c881bac3d20ae9c2 /src
parent2ddb10dfa4f88208ed651a3d9a0e79720c74462c (diff)
downloadscala-649289cb6882a3534ef7ac2f4a50e096af84c45f.tar.gz
scala-649289cb6882a3534ef7ac2f4a50e096af84c45f.tar.bz2
scala-649289cb6882a3534ef7ac2f4a50e096af84c45f.zip
fixed bug1274
moved a bunch of `unapply' definitions from Definitions to a new trait, typechecker.UnApplies
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala77
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Analyzer.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/UnApplies.scala95
5 files changed, 103 insertions, 84 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index ea94f135c9..fc3572b8f1 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -220,83 +220,6 @@ trait Definitions {
case tpe => tpe
}).normalize
- /** returns type list for return type of the extraction */
- def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
- assert(ufn.isMethod)
- //Console.println("utl "+ufntpe+" "+ufntpe.typeSymbol)
- ufn.name match {
- case nme.unapply => unapplyTypeListFromReturnType(ufntpe)
- case nme.unapplySeq => unapplyTypeListFromReturnTypeSeq(ufntpe)
- case _ => throw new IllegalArgumentException("expected function symbol of extraction")
- }
- }
- /** (the inverse of unapplyReturnTypeSeq)
- * for type Boolean, returns Nil
- * for type Option[T] or Some[T]:
- * - returns T0...Tn if n>0 and T <: Product[T0...Tn]]
- * - returns T otherwise
- */
- def unapplyTypeListFromReturnType(tp1: Type): List[Type] = { // rename: unapplyTypeListFromReturnType
- val tp = unapplyUnwrap(tp1)
- val B = BooleanClass
- val O = OptionClass
- val S = SomeClass
- tp.typeSymbol match { // unapplySeqResultToMethodSig
- case B => Nil
- case O | S =>
- val prod = tp.typeArgs.head
- getProductArgs(prod) match {
- case Some(all @ (x1::x2::xs)) => all // n >= 2
- case _ => prod::Nil // special n == 0 || n == 1
- }
- case _ => throw new IllegalArgumentException(tp.typeSymbol + " in not in {boolean, option, some}")
- }
- }
-
- /** let type be the result type of the (possibly polymorphic) unapply method
- * for type Option[T] or Some[T]
- * -returns T0...Tn-1,Tn* if n>0 and T <: Product[T0...Tn-1,Seq[Tn]]],
- * -returns R* if T = Seq[R]
- */
- def unapplyTypeListFromReturnTypeSeq(tp1: Type): List[Type] = {
- val tp = unapplyUnwrap(tp1)
- val O = OptionClass; val S = SomeClass; tp.typeSymbol match {
- case O | S =>
- val ts = unapplyTypeListFromReturnType(tp1)
- val last1 = ts.last.baseType(SeqClass) match {
- case TypeRef(pre, seqClass, args) => typeRef(pre, RepeatedParamClass, args)
- case _ => throw new IllegalArgumentException("last not seq")
- }
- ts.init ::: List(last1)
- case _ => throw new IllegalArgumentException(tp.typeSymbol + " in not in {option, some}")
- }
- }
-
- /** returns type of the unapply method returning T_0...T_n
- * for n == 0, boolean
- * for n == 1, Some[T0]
- * else Some[Product[Ti]]
- def unapplyReturnType(elems: List[Type], useWildCards: Boolean) =
- if (elems.isEmpty)
- BooleanClass.tpe
- else if (elems.length == 1)
- optionType(if(useWildCards) WildcardType else elems(0))
- else
- productType({val es = elems; if(useWildCards) elems map { x => WildcardType} else elems})
- */
-
- def unapplyReturnTypeExpected(argsLength: Int) = argsLength match {
- case 0 => BooleanClass.tpe
- case 1 => optionType(WildcardType)
- case n => optionType(productType(List.range(0,n).map (arg => WildcardType)))
- }
-
- /** returns unapply or unapplySeq if available */
- def unapplyMember(tp: Type): Symbol = {
- var unapp = tp.member(nme.unapply)
- if (unapp == NoSymbol) unapp = tp.member(nme.unapplySeq)
- unapp
- }
/* </unapply> */
val MaxFunctionArity = 9
val FunctionClass: Array[Symbol] = new Array(MaxFunctionArity + 1)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index b64dfc35d6..96ded10df1 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -421,7 +421,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
if (fn.symbol.name == nme.unapply)
args
else if (fn.symbol.name == nme.unapplySeq)
- transformArgs(tree.pos, args, definitions.unapplyTypeListFromReturnTypeSeq(fn.tpe))
+ transformArgs(tree.pos, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe))
else { assert(false,"internal error: UnApply node has wrong symbol"); null })
copy.UnApply(tree, fn1, args1)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
index 91fcd64d5c..6d95b1a762 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
@@ -15,7 +15,8 @@ trait Analyzer extends AnyRef
with Infer
with Variances
with EtaExpansion
- with SyntheticMethods {
+ with SyntheticMethods
+ with Unapplies {
val global : Global;
import global._;
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c0052ccc10..c162eacc1d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -701,7 +701,7 @@ trait Typers { self: Analyzer =>
}
tree1
} else {
- val extractor = tree.symbol.filter(sym => definitions.unapplyMember(sym.tpe).exists)
+ val extractor = tree.symbol.filter(sym => unapplyMember(sym.tpe).exists)
if (extractor != NoSymbol) {
tree setSymbol extractor
} else {
@@ -1577,7 +1577,7 @@ trait Typers { self: Analyzer =>
if (forMSIL) {
fun match {
case Select(qual, name) =>
- if (isSubType(qual.tpe, definitions.DelegateClass.tpe)
+ if (isSubType(qual.tpe, DelegateClass.tpe)
&& (name == encode("+=") || name == encode("-=")))
{
val n = if (name == encode("+=")) nme.PLUS else nme.MINUS
@@ -1631,8 +1631,8 @@ trait Typers { self: Analyzer =>
setError(copy.Apply(tree, fun, args))
/* --- begin unapply --- */
- case otpe if (mode & PATTERNmode) != 0 && definitions.unapplyMember(otpe).exists =>
- val unapp = definitions.unapplyMember(otpe)
+ case otpe if (mode & PATTERNmode) != 0 && unapplyMember(otpe).exists =>
+ val unapp = unapplyMember(otpe)
assert(unapp.exists, tree)
val unappType = otpe.memberType(unapp)
val argDummyType = pt // was unappArg
@@ -2134,7 +2134,7 @@ trait Typers { self: Analyzer =>
case Select(qual, name) if (forMSIL &&
pt != WildcardType &&
pt != ErrorType &&
- isSubType(pt, definitions.DelegateClass.tpe)) =>
+ isSubType(pt, DelegateClass.tpe)) =>
val scalaCaller = newScalaCaller(pt);
addScalaCallerInfo(scalaCaller, expr1.symbol)
val n: Name = scalaCaller.name
diff --git a/src/compiler/scala/tools/nsc/typechecker/UnApplies.scala b/src/compiler/scala/tools/nsc/typechecker/UnApplies.scala
new file mode 100644
index 0000000000..93e5639fc3
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/UnApplies.scala
@@ -0,0 +1,95 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2006 LAMP/EPFL
+ * @author Martin Odersky
+ */
+// $Id: EtaExpansion.scala 12607 2007-08-21 14:04:16Z odersky $
+
+package scala.tools.nsc.typechecker
+
+/*
+ * @author Martin Odersky
+ * @version 1.0
+ */
+trait Unapplies { self: Analyzer =>
+
+ import global._
+ import definitions._
+
+ /** returns type list for return type of the extraction */
+ def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
+ assert(ufn.isMethod)
+ //Console.println("utl "+ufntpe+" "+ufntpe.typeSymbol)
+ ufn.name match {
+ case nme.unapply => unapplyTypeListFromReturnType(ufntpe)
+ case nme.unapplySeq => unapplyTypeListFromReturnTypeSeq(ufntpe)
+ case _ => throw new TypeError(ufn+" is not an unapply or unapplySeq")
+ }
+ }
+ /** (the inverse of unapplyReturnTypeSeq)
+ * for type Boolean, returns Nil
+ * for type Option[T] or Some[T]:
+ * - returns T0...Tn if n>0 and T <: Product[T0...Tn]]
+ * - returns T otherwise
+ */
+ def unapplyTypeListFromReturnType(tp1: Type): List[Type] = { // rename: unapplyTypeListFromReturnType
+ val tp = unapplyUnwrap(tp1)
+ val B = BooleanClass
+ val O = OptionClass
+ val S = SomeClass
+ tp.typeSymbol match { // unapplySeqResultToMethodSig
+ case B => Nil
+ case O | S =>
+ val prod = tp.typeArgs.head
+ getProductArgs(prod) match {
+ case Some(all @ (x1::x2::xs)) => all // n >= 2
+ case _ => prod::Nil // special n == 0 || n == 1
+ }
+ case _ => throw new TypeError("result type "+tp+" of unapply not in {boolean, Option[_], Some[_]}")
+ }
+ }
+
+ /** let type be the result type of the (possibly polymorphic) unapply method
+ * for type Option[T] or Some[T]
+ * -returns T0...Tn-1,Tn* if n>0 and T <: Product[T0...Tn-1,Seq[Tn]]],
+ * -returns R* if T = Seq[R]
+ */
+ def unapplyTypeListFromReturnTypeSeq(tp1: Type): List[Type] = {
+ val tp = unapplyUnwrap(tp1)
+ val O = OptionClass; val S = SomeClass; tp.typeSymbol match {
+ case O | S =>
+ val ts = unapplyTypeListFromReturnType(tp1)
+ val last1 = ts.last.baseType(SeqClass) match {
+ case TypeRef(pre, seqClass, args) => typeRef(pre, RepeatedParamClass, args)
+ case _ => throw new TypeError("last not seq")
+ }
+ ts.init ::: List(last1)
+ case _ => throw new TypeError("result type "+tp+" of unapply not in {Option[_], Some[_]}")
+ }
+ }
+
+ /** returns type of the unapply method returning T_0...T_n
+ * for n == 0, boolean
+ * for n == 1, Some[T0]
+ * else Some[Product[Ti]]
+ def unapplyReturnType(elems: List[Type], useWildCards: Boolean) =
+ if (elems.isEmpty)
+ BooleanClass.tpe
+ else if (elems.length == 1)
+ optionType(if(useWildCards) WildcardType else elems(0))
+ else
+ productType({val es = elems; if(useWildCards) elems map { x => WildcardType} else elems})
+ */
+
+ def unapplyReturnTypeExpected(argsLength: Int) = argsLength match {
+ case 0 => BooleanClass.tpe
+ case 1 => optionType(WildcardType)
+ case n => optionType(productType(List.range(0,n).map (arg => WildcardType)))
+ }
+
+ /** returns unapply or unapplySeq if available */
+ def unapplyMember(tp: Type): Symbol = {
+ var unapp = tp.member(nme.unapply)
+ if (unapp == NoSymbol) unapp = tp.member(nme.unapplySeq)
+ unapp
+ }
+}