summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala12
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala30
-rw-r--r--test/pending/pos/unapply.scala55
6 files changed, 32 insertions, 83 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 67cd870036..f40a759dc3 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1903,13 +1903,7 @@ trait Parsers requires SyntaxAnalyzer {
if (name != nme.ScalaObject.toTypeName)
parents += scalaScalaObjectConstr
if (mods.hasFlag(Flags.CASE)) {
- if (!vparamss.isEmpty) {
- val argtypes: List[Tree] = vparamss.head map (.tpt.duplicate) //remove type annotation and you will get an interesting error message!!!
- checkSize("case class parameters", argtypes.length, definitions.MaxProductArity)
- if (argtypes.length <= definitions.MaxProductArity) parents += productConstr(argtypes)
- } else {
- parents += productConstr(Nil)
- }
+ parents += productConstr
}
val ps = parents.toList
newLineOptWhenFollowedBy(LBRACE)
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 0aec97dcdd..3fe1bd28b8 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -27,16 +27,8 @@ abstract class TreeBuilder {
scalaDot(nme.Unit.toTypeName)
def scalaScalaObjectConstr: Tree =
scalaDot(nme.ScalaObject.toTypeName)
-
- def productConstr(typeArgs: List[Tree]) = {
- def repeatedToSeq(tpt: Tree) = tpt match {
- case AppliedTypeTree(Select(qual, name), args) if (name == nme.REPEATED_PARAM_CLASS_NAME.toTypeName) =>
- AppliedTypeTree(Select(qual, nme.Seq.toTypeName), args)
- case _ =>
- tpt
- }
- AppliedTypeTree(scalaDot(newTypeName("Product"+typeArgs.length)), typeArgs map repeatedToSeq)
- }
+ def productConstr: Tree =
+ scalaDot(nme.Product.toTypeName)
/** Convert all occurrences of (lower-case) variables in a pattern as follows:
* x becomes x @ _
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
index d92106e52e..f6bed76977 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
@@ -335,9 +335,9 @@ trait Opcodes requires ICodes {
* Stack: ...:size(int)
* ->: ...:arrayref
*/
- case class CREATE_ARRAY(element: TypeKind) extends Instruction {
+ case class CREATE_ARRAY(elem: TypeKind) extends Instruction {
/** Returns a string representation of this instruction */
- override def toString(): String ="CREATE_ARRAY "+element.toString();
+ override def toString(): String ="CREATE_ARRAY "+elem.toString();
override def consumed = 1;
override def produced = 1;
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 29dc359287..fee88151f2 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -205,6 +205,7 @@ trait StdNames requires SymbolTable {
val Object = newTermName("Object")
val PartialFunction = newTermName("PartialFunction")
val Predef = newTermName("Predef")
+ val Product = newTermName("Product")
val ScalaObject = newTermName("ScalaObject")
val ScalaRunTime = newTermName("ScalaRunTime")
val Seq = newTermName("Seq")
@@ -235,9 +236,8 @@ trait StdNames requires SymbolTable {
val booleanValue = newTermName("booleanValue")
val box = newTermName("box")
val boxArray = newTermName("boxArray")
- val caseArity = newTermName("caseArity")
- val caseElement = newTermName("caseElement")
- val caseName = newTermName("caseName")
+ val arity = newTermName("arity")
+ val element = newTermName("element")
val checkCastability = newTermName("checkCastability")
val classOf = newTermName("classOf")
val coerce = newTermName("coerce")
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 1a714600c0..b9f31edec7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -12,7 +12,7 @@ import scala.collection.mutable.ListBuffer
/** <ul>
* <li>
- * <code>caseArity</code>, <code>caseElement</code> implementations added
+ * <code>productArity</code>, <code>element</code> implementations added
* to case classes
* </li>
* <li>
@@ -61,16 +61,34 @@ trait SyntheticMethods requires Analyzer {
method
}
+ /*
def productSelectorMethod(n: int, accessor: Symbol): Tree = {
val method = syntheticMethod(newTermName("_"+n), FINAL, accessor.tpe)
typed(DefDef(method, vparamss => gen.mkAttributedRef(accessor)))
}
-
+ */
def productPrefixMethod: Tree = {
val method = syntheticMethod(nme.productPrefix, FINAL, PolyType(List(), StringClass.tpe))
typed(DefDef(method, vparamss => Literal(Constant(clazz.name.decode))))
}
+ def productArityMethod(nargs:Int ): Tree = {
+ val method = syntheticMethod(nme.arity, FINAL, PolyType(List(), IntClass.tpe))
+ typed(DefDef(method, vparamss => Literal(Constant(nargs))))
+ }
+
+ def productElementMethod(accs: List[Symbol]): Tree = {
+ val method = syntheticMethod(nme.element, FINAL, MethodType(List(IntClass.tpe), AnyClass.tpe))
+ typed(DefDef(method, vparamss => Match(Ident(vparamss.head.head), {
+ (for(val Pair(sym,i) <- accs.zipWithIndex) yield {
+ CaseDef(Literal(Constant(i)),EmptyTree, Ident(sym))
+ }):::List(CaseDef(Ident(nme.WILDCARD), EmptyTree,
+ Throw(New(TypeTree(IndexOutOfBoundsExceptionClass.tpe), List(List(
+ Select(Ident(vparamss.head.head), nme.toString_)
+ ))))))
+ })))
+ }
+
def moduleToStringMethod: Tree = {
val method = syntheticMethod(nme.toString_, FINAL, MethodType(List(), StringClass.tpe))
typed(DefDef(method, vparamss => Literal(Constant(clazz.name.decode))))
@@ -211,10 +229,10 @@ trait SyntheticMethods requires Analyzer {
if (!hasDirectImplementation(nme.productPrefix)) ts += productPrefixMethod
val accessors = clazz.caseFieldAccessors
- for (val i <- 0 until accessors.length) {
- val acc = accessors(i)
- if (acc.name.toString != "_"+(i+1)) ts += productSelectorMethod(i+1, acc)
- }
+ if (!hasImplementation(nme.arity))
+ ts += productArityMethod(accessors.length)
+ if (!hasImplementation(nme.element))
+ ts += productElementMethod(accessors)
}
if (clazz.isModuleClass && isSerializable(clazz)) {
diff --git a/test/pending/pos/unapply.scala b/test/pending/pos/unapply.scala
deleted file mode 100644
index 4ddc93120b..0000000000
--- a/test/pending/pos/unapply.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-object Test {
- def main(args:Array[String]) = {
- Foo.run
- Mas.run
- }
-}
-object Foo {
- def unapply(x: Any): Option[Product2[Int, String]] = x match {
- case y: Bar => Some(Tuple(y.size, y.name))
- case _ => None
- }/*
- // ERROR: test/pending/pos/unapply.scala:6 error: method unapply is defined twice
- def unapply(x: Any): Option[Product1[String]] = x match {
- case y: Bar => Some(Tuple(y.name))
- case _ => None
- }*/
- def run: Unit = {
- val b = new Bar
- b match {
- case Foo(s:Int, n:String) => Console.println("size "+s+" name "+n)
- }
- b.size = 54
- b.name = "large"
- b match {
- case Foo(s:Int, n:String) => Console.println("size "+s+" name "+n)
- }/*
- b match {
- case Foo(n) => Console.println("name " + n)
- }*/
- }
-}
-
-class Bar {
- var size: Int = 50
- var name: String = "medium"
-}
-
-object Mas {
- object Gaz {
- def unapply(x: Any): Option[Product2[Int, String]] = x match {
- case y: Baz => Some(Tuple(y.size, y.name))
- case _ => None
- }
- }
- class Baz {
- var size: Int = 60
- var name: String = "too large"
- }
- def run: Unit = {
- val b = new Baz
- b match {
- case Gaz(s:Int, n:String) => Console.println("size "+s+" name "+n)
- }
- }
-}