summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-01-17 16:37:27 +0000
committerMartin Odersky <odersky@gmail.com>2008-01-17 16:37:27 +0000
commit76c06b4661b70e934530a0debad34a5766ee43e9 (patch)
tree4abb85699a2d663681a9ca31fb7ccff45b80746f
parente5ca1a3906ae29c1d6db5de333932bbfc189cedc (diff)
downloadscala-76c06b4661b70e934530a0debad34a5766ee43e9.tar.gz
scala-76c06b4661b70e934530a0debad34a5766ee43e9.tar.bz2
scala-76c06b4661b70e934530a0debad34a5766ee43e9.zip
build target is now 1.5
case classes now generate objects not factory methods. some small cleanups for type inference
-rw-r--r--build.xml26
-rw-r--r--lib/scala-compiler.jar.desired.sha12
-rw-r--r--lib/scala-library.jar.desired.sha12
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala21
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala16
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala6
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternNodes.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Flags.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala16
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala37
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Analyzer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala111
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala125
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala109
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala88
-rw-r--r--src/library/scala/collection/jcl/SortedSet.scala4
-rwxr-xr-xtest/files/jvm/serialization.check146
-rwxr-xr-xtest/files/jvm/serialization.scala345
-rwxr-xr-xtest/files/jvm/typerep.check47
-rwxr-xr-xtest/files/jvm/typerep.scala374
-rw-r--r--test/files/neg/bug414.check4
-rw-r--r--test/files/neg/bug692.check2
-rw-r--r--test/files/neg/bug692.scala2
-rw-r--r--test/files/neg/bug783.check6
-rw-r--r--test/files/neg/bug960.check5
-rwxr-xr-xtest/files/neg/bug961.scala2
-rw-r--r--test/files/neg/scopes.check7
-rw-r--r--test/files/pos/bug432.scala2
-rw-r--r--test/files/run/caseclasses.check2
-rw-r--r--test/files/run/caseclasses.scala15
-rw-r--r--test/files/run/classof.check (renamed from test/pending/run/classof.check)0
-rwxr-xr-x[-rw-r--r--]test/files/run/classof.scala (renamed from test/pending/run/classof.scala)2
-rwxr-xr-x[-rw-r--r--]test/pending/run/bug874.scala (renamed from test/files/run/bug874.scala)11
41 files changed, 1373 insertions, 223 deletions
diff --git a/build.xml b/build.xml
index 1043c8f97a..125cf87864 100644
--- a/build.xml
+++ b/build.xml
@@ -493,7 +493,7 @@ BUILD QUICK-TEST LAYER
srcdir="${src.dir}/library"
destdir="${quick.dir}/lib/library"
usepredefs="no"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes"
scalacdebugging="${nsc.log-files}"
classpath="${quick.dir}/lib/library"
@@ -501,7 +501,7 @@ BUILD QUICK-TEST LAYER
<locker
srcdir="${src.dir}/library"
destdir="${quick.dir}/lib/library"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes"
scalacdebugging="${nsc.log-files}"
classpath="${quick.dir}/lib/library">
@@ -526,7 +526,7 @@ BUILD QUICK-TEST LAYER
<locker
srcdir="${src.dir}/dbc"
destdir="${quick.dir}/lib/dbc"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes"
scalacdebugging="${nsc.log-files}">
<classpath>
@@ -547,7 +547,7 @@ BUILD QUICK-TEST LAYER
<locker
srcdir="${src.dir}/actors"
destdir="${quick.dir}/lib/actors"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes"
scalacdebugging="${nsc.log-files}">
<classpath>
@@ -562,7 +562,7 @@ BUILD QUICK-TEST LAYER
<locker
srcdir="${src.dir}/compiler"
destdir="${quick.dir}/lib/compiler"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes"
scalacdebugging="${nsc.log-files}">
<classpath>
@@ -591,7 +591,7 @@ BUILD QUICK-TEST LAYER
<locker
srcdir="${src.dir}/partest"
destdir="${quick.dir}/lib/partest"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes">
<classpath>
<pathelement location="${quick.dir}/lib/library"/>
@@ -1207,14 +1207,14 @@ TEST
srcdir="${src.dir}/library"
destdir="${strap.dir}/lib/library"
usepredefs="no"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes"
classpath="${strap.dir}/lib/library"
includes="scala/Predef.scala"/>
<quick
srcdir="${src.dir}/library"
destdir="${strap.dir}/lib/library"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes"
classpath="${strap.dir}/lib/library">
<include name="**/*.scala"/>
@@ -1238,7 +1238,7 @@ TEST
<quick
srcdir="${src.dir}/dbc"
destdir="${strap.dir}/lib/dbc"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes">
<classpath>
<pathelement location="${strap.dir}/lib/library"/>
@@ -1258,7 +1258,7 @@ TEST
<quick
srcdir="${src.dir}/actors"
destdir="${strap.dir}/lib/actors"
- addparams="${nsc.params}" target="jvm-1.4">
+ addparams="${nsc.params}" target="jvm-1.5">
<classpath>
<pathelement location="${strap.dir}/lib/library"/>
<pathelement location="${strap.dir}/lib/actors"/>
@@ -1271,7 +1271,7 @@ TEST
<quick
srcdir="${src.dir}/compiler"
destdir="${strap.dir}/lib/compiler"
- addparams="${nsc.params}" target="jvm-1.4">
+ addparams="${nsc.params}" target="jvm-1.5">
<classpath>
<pathelement location="${strap.dir}/lib/library"/>
<pathelement location="${strap.dir}/lib/compiler"/>
@@ -1298,7 +1298,7 @@ TEST
<quick
srcdir="${src.dir}/partest"
destdir="${strap.dir}/lib/partest"
- addparams="${nsc.params}" target="jvm-1.4"
+ addparams="${nsc.params}" target="jvm-1.5"
deprecation="yes" unchecked="yes">
<classpath>
<pathelement location="${strap.dir}/lib/library"/>
@@ -1463,7 +1463,7 @@ DOCUMENTATION
<quick
srcdir="${src.dir}/manual"
destdir="${tooldocs.dir}/classes"
- deprecation="yes" target="jvm-1.4"
+ deprecation="yes" target="jvm-1.5"
classpathref="manual.classpath">
<include name="**/*.scala"/>
</quick>
diff --git a/lib/scala-compiler.jar.desired.sha1 b/lib/scala-compiler.jar.desired.sha1
index 20b6d0396f..c25fab0e6c 100644
--- a/lib/scala-compiler.jar.desired.sha1
+++ b/lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
-89ceb76a10d98baef63a75a90038c0a15b84bcc3 ?scala-compiler.jar
+abff2e45f1331c5e794712eb3b541d91977833c1 ?scala-compiler.jar
diff --git a/lib/scala-library.jar.desired.sha1 b/lib/scala-library.jar.desired.sha1
index ffa7465d0f..9724c9631e 100644
--- a/lib/scala-library.jar.desired.sha1
+++ b/lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
-93774afad0ec5a940628a89348e097050bb25467 ?scala-library.jar
+bb122f3e11a64e6c5b60e849cdda1db4129cb3f2 ?scala-library.jar
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 1aaa2f41bf..f37a34ae74 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -18,6 +18,21 @@ abstract class TreeGen {
import definitions._
import posAssigner.atPos
+ def scalaDot(name: Name): Tree =
+ Select(Ident(nme.scala_) setSymbol ScalaPackage, name)
+ def scalaAnyRefConstr: Tree =
+ scalaDot(nme.AnyRef.toTypeName)
+ def scalaUnitConstr: Tree =
+ scalaDot(nme.Unit.toTypeName)
+ def scalaScalaObjectConstr: Tree =
+ scalaDot(nme.ScalaObject.toTypeName)
+ def productConstr: Tree =
+ scalaDot(nme.Product.toTypeName)
+
+ def scalaFunctionConstr(argtpes: List[Tree], restpe: Tree): Tree =
+ AppliedTypeTree(
+ scalaDot(newTypeName("Function"+argtpes.length)),
+ argtpes ::: List(restpe))
/** Builds a reference to value whose type is given stable prefix.
* The type must be suitable for this. For example, it
@@ -135,7 +150,6 @@ abstract class TreeGen {
This(sym.name) setSymbol sym setType sym.thisType
def mkAttributedIdent(sym: Symbol): Tree = {
- assert(sym.isTerm, sym)
Ident(sym.name) setSymbol sym setType sym.tpe
}
@@ -145,7 +159,6 @@ abstract class TreeGen {
qual.symbol.name.toTermName == nme.EMPTY_PACKAGE_NAME)) {
mkAttributedIdent(sym)
} else {
- assert(sym.isTerm)
val result = Select(qual, sym.name) setSymbol sym
if (qual.tpe ne null) result setType qual.tpe.memberType(sym)
result
@@ -207,7 +220,9 @@ abstract class TreeGen {
/** Builds a tuple */
def mkTuple(elems: List[Tree]): Tree =
if (elems.isEmpty) Literal(())
- else Apply(mkAttributedRef(definitions.TupleClass(elems.length).caseFactory), elems)
+ else Apply(
+ Select(mkAttributedRef(definitions.TupleClass(elems.length).caseModule), nme.apply),
+ elems)
def mkAnd(tree1: Tree, tree2: Tree) =
Apply(Select(tree1, Boolean_and), List(tree2))
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
index d814c5cd6c..b6dd026a84 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala
@@ -244,22 +244,6 @@ abstract class TreeInfo {
case _ => false
}
- /** is this pattern of the form S(...) where S is a subclass of Seq
- * and S is not a case class? The pattern might be wrapped in binds or alternatives.
- */
- def isSequencePattern(tree: Tree): Boolean = tree match {
- case Apply(fn, _) =>
- (fn.symbol ne null) &&
- !fn.symbol.hasFlag(CASE) &&
- fn.symbol.isNonBottomSubClass(definitions.SeqClass)
- case Bind(name, body) =>
- isSequencePattern(body)
- case Alternative(ts) =>
- ts forall isSequencePattern
- case _ =>
- false
- }
-
/** The method part of an application node
*/
def methPart(tree: Tree): Tree = tree match {
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 4412aa0896..81f10c7a31 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -755,6 +755,8 @@ trait Trees {
case class TypeTree() extends TypTree {
var original: Tree = _
+ override def symbol = tpe.typeSymbol
+
def setOriginal(tree: Tree): this.type = {
original = tree
setPos(tree.pos)
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index 4fb9f310b1..b7355c86ff 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -244,7 +244,7 @@ abstract class DeadCodeElimination extends SubComponent {
def find(bb: BasicBlock): Option[(BasicBlock, Int)] = {
var xs = bb.toList
xs.zipWithIndex find { hd => hd._1 eq i } match {
- case Some(_, idx) => Some(bb, idx)
+ case Some((_, idx)) => Some(bb, idx)
case None => None
}
}
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index d019b4cc89..6814ef7465 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -673,9 +673,9 @@ trait ParallelMatching {
pat match {
case Bind(_,p) =>
subpatterns(p)
- case app @ Apply(fn, pats) if isCaseClass(app.tpe) && (fn.symbol eq null)=>
+ case app @ Apply(fn, pats) if isCaseClass(app.tpe) && fn.isType =>
if (isCaseHead) pats else dummies
- case Apply(fn,xs) => assert((xs.isEmpty) && (fn.symbol ne null), "strange Apply"); dummies // named constant
+ case Apply(fn,xs) => assert((xs.isEmpty) && (!fn.isType), "strange Apply"); dummies // named constant
case _: UnApply =>
dummies
case pat =>
@@ -1230,7 +1230,7 @@ trait ParallelMatching {
*/
final def applyRule(implicit theOwner: Symbol, rep: RepFactory): RuleApplication = row match {
case Nil =>
- ErrorRule
+ ErrorRule()
case Row(pats, subst, g, bx)::xs =>
var px = 0; var rpats = pats; var bnd = subst; var temps = temp; while((bnd ne null) && (rpats ne Nil)) {
val (vs,p) = strip(rpats.head);
diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
index 92b59ff20f..030e46175f 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
@@ -78,14 +78,14 @@ trait PatternNodes { self: transform.ExplicitOuter =>
}
object Apply_Value {
- def unapply(x:Apply) = if ((x.symbol ne null) && (x.args eq Nil)) Some(x.tpe.prefix, x.symbol) else None
+ def unapply(x:Apply) = if (!x.fun.isType && x.args.isEmpty) Some(x.tpe.prefix, x.symbol) else None
}
object Apply_CaseClass_NoArgs {
- def unapply(x:Apply) = if ((x.symbol eq null) && (x.args eq Nil)) Some(x.tpe) else None
+ def unapply(x:Apply) = if (x.fun.isType && x.args.isEmpty) Some(x.tpe) else None
}
object Apply_CaseClass_WithArgs {
- def unapply(x:Apply) = if (x.symbol eq null) true else false
+ def unapply(x:Apply) = x.fun.isType
}
object __UnApply {
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala
index eefc6457e4..7befdc9719 100644
--- a/src/compiler/scala/tools/nsc/symtab/Flags.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala
@@ -126,7 +126,7 @@ object Flags extends Enumeration {
final val PickledFlags: Long = 0xFFFFFFFFL
/** Module flags inherited by their module-class */
- final val ModuleToClassFlags: Long = AccessFlags | PACKAGE | CASE
+ final val ModuleToClassFlags: Long = AccessFlags | MODULE | PACKAGE | CASE | SYNTHETIC
private def listToString(ss: List[String]): String =
ss.filter("" !=).mkString("", " ", "")
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 68e5e35f60..f6a2904a45 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -215,6 +215,7 @@ trait StdNames {
val Finally = newTermName("Finally")
val Float = newTermName("Float")
val Function = newTermName("Function")
+ val Function1 = newTermName("Function1")
val Int = newTermName("Int")
val Labelled = newTermName("Labelled")
val Long = newTermName("Long")
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 5bec708d45..e085c13e9c 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -261,9 +261,9 @@ trait Symbols {
final def isPrimaryConstructor =
isConstructor && owner.primaryConstructor == this
- /** Is this symbol a case class factory method? */
- final def isCaseFactory =
- isMethod && hasFlag(CASE)
+ /** Is this symbol a synthetic apply or unapply method in a companion object of a case class? */
+ final def isCaseApplyOrUnapply =
+ isMethod && hasFlag(CASE) && hasFlag(SYNTHETIC)
/** Is this symbol an implementation class for a mixin? */
final def isImplClass: Boolean = isClass && hasFlag(IMPLCLASS)
@@ -930,14 +930,14 @@ trait Symbols {
final def setter(base: Symbol): Symbol =
base.info.decl(nme.getterToSetter(nme.getterName(name))) filter (_.hasFlag(ACCESSOR))
- /** The case factory corresponding to this case class
+ /** The case module corresponding to this case class
* @pre case class is a member of some other class or package
*/
- final def caseFactory: Symbol = {
- var facname = name.toTermName
+ final def caseModule: Symbol = {
+ var modname = name.toTermName
if (privateWithin.isClass && !privateWithin.isModuleClass && !hasFlag(EXPANDEDNAME))
- facname = privateWithin.expandedName(facname)
- initialize.owner.info.decl(facname).suchThat(_.isCaseFactory)
+ modname = privateWithin.expandedName(modname)
+ initialize.owner.info.decl(modname).suchThat(_.isModule)
}
/** If this symbol is a type parameter skolem (not an existential skolem!)
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index f690766561..1f24ff1bf6 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -139,6 +139,7 @@ trait Types {
override def termSymbol = underlying.termSymbol
override def termSymbolDirect = underlying.termSymbolDirect
override def typeParams = underlying.typeParams
+ override def boundSyms = underlying.boundSyms
override def typeSymbol = underlying.typeSymbol
override def typeSymbolDirect = underlying.typeSymbolDirect
override def widen = underlying.widen
@@ -172,7 +173,6 @@ trait Types {
override def paramSectionCount = 0
override def paramTypes: List[Type] = List()
override def typeArgs = underlying.typeArgs
- override def typeParams = underlying.typeParams
override def notNull = maybeRewrap(underlying.notNull)
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = underlying.instantiateTypeParams(formals, actuals)
override def skolemizeExistential(owner: Symbol, origin: AnyRef) = underlying.skolemizeExistential(owner, origin)
@@ -296,10 +296,14 @@ trait Types {
* the empty list for all other types */
def paramTypes: List[Type] = List()
- /** For a poly type, its type parameters,
+ /** For a (potentially wrapped) poly type, its type parameters,
* the empty list for all other types */
def typeParams: List[Symbol] = List()
+ /** For a (potentially wrapped) poly or existential type, its bound symbols,
+ * the empty list for all other types */
+ def boundSyms: List[Symbol] = List()
+
/** Mixin a NotNull trait unless type already has one */
def notNull: Type =
if (isNotNull || phase.erasedTypes) this else NotNullType(this)
@@ -709,8 +713,8 @@ trait Types {
var skolems: List[Symbol] = List()
for (t <- this) {
t match {
- case ExistentialType(tparams, qtpe) =>
- boundSyms = boundSyms ::: tparams
+ case ExistentialType(quantified, qtpe) =>
+ boundSyms = boundSyms ::: quantified
case TypeRef(_, sym, _) =>
if ((sym hasFlag EXISTENTIAL) && !(boundSyms contains sym) && !(skolems contains sym))
skolems = sym :: skolems
@@ -1610,6 +1614,7 @@ A type's typeSymbol should never be inspected directly.
override def decls: Scope = resultType.decls
override def termSymbol: Symbol = resultType.termSymbol
override def typeSymbol: Symbol = resultType.typeSymbol
+ override def boundSyms: List[Symbol] = typeParams
override def prefix: Type = resultType.prefix
override def closure: Array[Type] = resultType.closure
override def closureDepth: Int = resultType.closureDepth
@@ -1654,6 +1659,7 @@ A type's typeSymbol should never be inspected directly.
override def isStable: Boolean = false
override def bounds = TypeBounds(maybeRewrap(underlying.bounds.lo), maybeRewrap(underlying.bounds.hi))
override def parents = underlying.parents map maybeRewrap
+ override def boundSyms: List[Symbol] = quantified
override def prefix = maybeRewrap(underlying.prefix)
override def typeArgs = underlying.typeArgs map maybeRewrap
override def paramTypes = underlying.paramTypes map maybeRewrap
@@ -2648,8 +2654,22 @@ A type's typeSymbol should never be inspected directly.
else if (matches(from.head, sym)) toType(tp, to.head)
else subst(tp, sym, from.tail, to.tail)
+ private def renameBoundSyms(tp: Type) = tp match {
+ case PolyType(bs, restp) =>
+ val bs1 = cloneSymbols(bs)
+ PolyType(bs1, restp.substSym(bs, bs1))
+ case ExistentialType(bs, restp) =>
+ val bs1 = cloneSymbols(bs)
+ ExistentialType(bs1, restp.substSym(bs, bs1))
+ case _ =>
+ tp
+ }
+
def apply(tp0: Type): Type = if (from.isEmpty) tp0 else {
- val tp = mapOver(tp0)
+ val boundSyms = tp0.boundSyms
+ val tp1 = if (boundSyms.isEmpty || !(boundSyms exists (from contains))) tp0
+ else renameBoundSyms(tp0)
+ val tp = mapOver(tp1)
tp match {
// @M
@@ -2673,13 +2693,6 @@ A type's typeSymbol should never be inspected directly.
}
case SingleType(NoPrefix, sym) =>
subst(tp, sym, from, to)
- case PolyType(tparams, restp) =>
- assert(!(tparams exists (from contains)))
- tp
- case ExistentialType(tparams, restp) =>
- if (tparams exists (from contains))
- assert(false, "["+from.mkString(",")+":="+to.mkString(",")+"]"+tp)
- tp
case _ =>
tp
}
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index b03c05ce3b..d7150d981f 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -154,12 +154,18 @@ abstract class Constructors extends Transform {
if (stat.symbol.tpe.isInstanceOf[ConstantType])
assert(stat.symbol.getter(stat.symbol.owner) != NoSymbol, stat)
else {
+ try {
if (rhs != EmptyTree && !stat.symbol.hasFlag(LAZY)) {
val rhs1 = intoConstructor(stat.symbol, rhs);
(if (canBeMoved(stat)) constrPrefixBuf else constrStatBuf) += mkAssign(
stat.symbol, rhs1)
}
defBuf += copy.ValDef(stat, mods, name, tpt, EmptyTree)
+ } catch {
+ case ex: Throwable =>
+ println("error when transforming "+stat+" in "+stats)
+ throw ex
+ }
}
case ClassDef(_, _, _, _) =>
defBuf += (new ConstructorTransformer).transform(stat)
@@ -205,14 +211,13 @@ abstract class Constructors extends Transform {
defBuf.toList filter (stat => isAccessed(stat.symbol)))
}
- override def transform(tree: Tree): Tree = {
+ override def transform(tree: Tree): Tree =
tree match {
case ClassDef(mods, name, tparams, impl) if !tree.symbol.hasFlag(INTERFACE) =>
copy.ClassDef(tree, mods, name, tparams, transformClassTemplate(impl))
case _ =>
super.transform(tree)
}
- }
} // ConstructorTransformer
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 80a1fc1f0c..a83c68f797 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -763,7 +763,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
*/
private val preTransformer = new Transformer {
override def transform(tree: Tree): Tree = {
- if (tree.symbol == ArrayClass) return tree
+ if (tree.symbol == ArrayClass && !tree.isType) return tree
val tree1 = tree match {
case ClassDef(mods, name, tparams, impl) =>
if (settings.debug.value)
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 8bf0994af6..144081efcb 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -59,7 +59,7 @@ abstract class Mixin extends InfoTransform {
* inherits the trait.
*/
private def isForwarded(sym: Symbol) =
- isImplementedStatically(sym) && !sym.isImplOnly && !sym.isCaseFactory
+ isImplementedStatically(sym) && !sym.isImplOnly
/** Maps the type of an implementation class to its interface;
* maps all other types to themselves.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
index defcc6ce2e..4ede3dec3b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala
@@ -35,7 +35,7 @@ trait Analyzer extends AnyRef
val global: Analyzer.this.global.type = Analyzer.this.global
val phaseName = "typer"
def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) {
- resetTyper
+ resetTyper()
def apply(unit: CompilationUnit) {
unit.body = newTyper(rootContext(unit)).typed(unit.body)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index f0311dd885..782c003b25 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -76,7 +76,7 @@ trait Contexts { self: Analyzer =>
c
}
- def resetContexts {
+ def resetContexts() {
var sc = startContext
while (sc != NoContext) {
sc.tree match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 8571148479..ea2a4c59c8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -512,12 +512,33 @@ trait Infer {
if (targ.typeSymbol == AllClass && (varianceInType(restpe)(tparam) & COVARIANT) == 0) {
uninstantiated += tparam
tparam.tpe //@M TODO: might be affected by change to tpe in Symbol
- } else targ.widen
+ } else if (targ.typeSymbol == RepeatedParamClass) {
+ targ.baseType(SeqClass)
+ } else {
+ targ.widen
+ }
}
// println("meth type args "+", tparams = "+tparams+", formals = "+formals+", restpe = "+restpe+", argtpes = "+argtpes+", underlying = "+(argtpes map (_.widen))+", pt = "+pt+", uninstantiated = "+uninstantiated.toList+", result = "+res) //DEBUG
// res
}
+ def followApply(tp: Type): Type = tp match {
+ case PolyType(List(), restp) =>
+ val restp1 = followApply(restp)
+ if (restp1 eq restp) tp else restp1
+ case _ =>
+ val appmeth = tp.nonPrivateMember(nme.apply) filter (_.isPublic)
+ if (appmeth == NoSymbol) tp
+ else OverloadedType(tp, appmeth.alternatives)
+ }
+
+ def hasExactlyNumParams(tp: Type, n: Int): Boolean = tp match {
+ case OverloadedType(pre, alts) =>
+ alts exists (alt => hasExactlyNumParams(pre.memberType(alt), n))
+ case _ =>
+ formalTypes(tp.paramTypes, n).length == n
+ }
+
/** Is there an instantiation of free type variables <code>undetparams</code>
* such that function type <code>ftpe</code> is applicable to
* <code>argtpes</code> and its result conform to <code>pt</code>?
@@ -531,6 +552,8 @@ trait Infer {
def isApplicable(undetparams: List[Symbol], ftpe: Type,
argtpes0: List[Type], pt: Type): Boolean =
ftpe match {
+ case OverloadedType(pre, alts) =>
+ alts exists (alt => isApplicable(undetparams, pre.memberType(alt), argtpes0, pt))
case ExistentialType(tparams, qtpe) =>
isApplicable(undetparams, qtpe, argtpes0, pt)
case MethodType(formals0, _) =>
@@ -573,29 +596,70 @@ trait Infer {
}
}
- /** Does type <code>ftpe1</code> specialize type <code>ftpe2</code>
+ /** Is type <code>ftpe1</code> strictly more specific than type <code>ftpe2</code>
* when both are alternatives in an overloaded function?
+ * @see SLS (sec:overloading-resolution)
*
* @param ftpe1 ...
* @param ftpe2 ...
* @return ...
*/
- def specializes(ftpe1: Type, ftpe2: Type): Boolean = ftpe1 match {
+ def isMoreSpecific(ftpe1: Type, ftpe2: Type): Boolean = ftpe1 match {
+ case OverloadedType(pre, alts) =>
+ alts exists (alt => isMoreSpecific(pre.memberType(alt), ftpe2))
case et: ExistentialType =>
- et.withTypeVars(specializes(_, ftpe2))
- case MethodType(formals, _) =>
+ et.withTypeVars(isStrictlyMoreSpecific(_, ftpe2))
+ case MethodType(formals @ (x :: xs), _) =>
isApplicable(List(), ftpe2, formals, WildcardType)
- case PolyType(tparams, MethodType(formals, _)) =>
+ case PolyType(_, MethodType(formals @ (x :: xs), _)) =>
isApplicable(List(), ftpe2, formals, WildcardType)
case ErrorType =>
true
case _ =>
- false
+ ftpe2 match {
+ case OverloadedType(pre, alts) =>
+ alts forall (alt => isMoreSpecific(ftpe1, pre.memberType(alt)))
+ case et: ExistentialType =>
+ et.withTypeVars(isStrictlyMoreSpecific(ftpe1, _))
+ case MethodType(_, _) | PolyType(_, MethodType(_, _)) =>
+ true
+ case _ =>
+ isMoreSpecificValueType(ftpe1, ftpe2, List(), List())
+ }
}
+ def isStrictlyMoreSpecific(ftpe1: Type, ftpe2: Type): Boolean =
+ ftpe1.isError || isMoreSpecific(ftpe1, ftpe2) &&
+ (!isMoreSpecific(ftpe2, ftpe1) ||
+ !ftpe1.isInstanceOf[OverloadedType] && ftpe2.isInstanceOf[OverloadedType])
+
+ def isMoreSpecificValueType(tpe1: Type, tpe2: Type, undef1: List[Symbol], undef2: List[Symbol]): Boolean = (tpe1, tpe2) match {
+ case (PolyType(tparams1, rtpe1), _) =>
+ isMoreSpecificValueType(rtpe1, tpe2, undef1 ::: tparams1, undef2)
+ case (_, PolyType(tparams2, rtpe2)) =>
+ isMoreSpecificValueType(tpe1, rtpe2, undef1, undef2 ::: tparams2)
+ case _ =>
+ existentialAbstraction(undef1, tpe1) <:< existentialAbstraction(undef2, tpe2)
+ }
+
+/*
/** Is type `tpe1' a strictly better expression alternative than type `tpe2'?
*/
def isStrictlyBetterExpr(tpe1: Type, tpe2: Type) = {
+ isMethod(tpe2) && !isMethod(tpe1) ||
+ isNullary(tpe1) && !isNullary(tpe2) ||
+ isStrictlyBetter(tpe1, tpe2)
+ }
+
+ /** Is type `tpe1' a strictly better alternative than type `tpe2'?
+ * non-methods are always strictly better than methods
+ * nullary methods are always strictly better than non-nullary
+ * if both are non-nullary methods, then tpe1 is strictly better than tpe2 if
+ * - tpe1 specializes tpe2 and tpe2 does not specialize tpe1
+ * - tpe1 and tpe2 specialize each other and tpe1 has a strictly better resulttype than
+ * tpe2
+ */
+ def isStrictlyBetter(tpe1: Type, tpe2: Type) = {
def isNullary(tpe: Type): Boolean = tpe match {
case tp: RewrappingTypeProxy => isNullary(tp.underlying)
case _ => tpe.paramSectionCount == 0 || tpe.paramTypes.isEmpty
@@ -605,16 +669,21 @@ trait Infer {
case MethodType(_, _) | PolyType(_, _) => true
case _ => false
}
- isMethod(tpe2) && !isMethod(tpe1) ||
+ def hasStrictlyBetterResult =
+ resultIsBetter(tpe1, tpe2, List(), List()) && !resultIsBetter(tpe2, tpe1, List(), List())
+ if (!isMethod(tpe1))
+ isMethod(tpe2) || hasStrictlyBetterResult
+
isNullary(tpe1) && !isNullary(tpe2) ||
- isStrictlyBetter(tpe1, tpe2)
- }
+ is
- /** Is type `tpe1' a strictly better alternative than type `tpe2'?
- */
- def isStrictlyBetter(tpe1: Type, tpe2: Type) =
- specializes(tpe1, tpe2) && !specializes(tpe2, tpe1)
+ else if (isNullary(tpe1))
+ isMethod(tpe2) && (!isNullary(tpe2) || hasStrictlyBetterResult)
+ else
+ specializes(tpe1, tpe2) && (!specializes(tpe2, tpe1) || hasStrictlyBetterResult)
+ }
+*/
/** error if arguments not within bounds. */
def checkBounds(pos: Position, pre: Type, owner: Symbol,
tparams: List[Symbol], targs: List[Type], prefix: String) = {
@@ -715,7 +784,7 @@ trait Infer {
else if (s.isContravariant) "contravariant"
else "invariant";
- def qualify(a0: Symbol, b0: Symbol): String = if(a0.toString != b0.toString) "" else {
+ def qualify(a0: Symbol, b0: Symbol): String = if (a0.toString != b0.toString) "" else {
assert((a0 ne b0) && (a0.owner ne b0.owner));
var a = a0; var b = b0
while (a.owner.name == b.owner.name) { a = a.owner; b = b.owner}
@@ -1123,7 +1192,7 @@ trait Infer {
*/
def inferExprAlternative(tree: Tree, pt: Type): Unit = tree.tpe match {
case OverloadedType(pre, alts) => tryTwice {
- var alts1 = alts filter (alt => isCompatible(pre.memberType(alt), pt))
+ var alts1 = alts filter (alt => isWeaklyCompatible(pre.memberType(alt), pt))
var secondTry = false
if (alts1.isEmpty) {
alts1 = alts
@@ -1134,8 +1203,8 @@ trait Infer {
{ val tp1 = pre.memberType(sym1)
val tp2 = pre.memberType(sym2)
(tp2 == ErrorType ||
- !global.typer.infer.isCompatible(tp2, pt) && global.typer.infer.isCompatible(tp1, pt) ||
- isStrictlyBetterExpr(tp1, tp2)) }
+ !global.typer.infer.isWeaklyCompatible(tp2, pt) && global.typer.infer.isWeaklyCompatible(tp1, pt) ||
+ isStrictlyMoreSpecific(tp1, tp2)) }
val best = ((NoSymbol: Symbol) /: alts1) ((best, alt) =>
if (improves(alt, best)) alt else best)
val competing = alts1 dropWhile (alt => best == alt || improves(best, alt))
@@ -1161,7 +1230,7 @@ trait Infer {
}
} else {
val applicable = alts1 filter (alt =>
- global.typer.infer.isCompatible(pre.memberType(alt), pt))
+ global.typer.infer.isWeaklyCompatible(pre.memberType(alt), pt))
checkNotShadowed(tree.pos, pre, best, applicable)
tree.setSymbol(best).setType(pre.memberType(best))
}
@@ -1180,10 +1249,10 @@ trait Infer {
case OverloadedType(pre, alts) =>
tryTwice {
if (settings.debug.value) log("infer method alt " + tree.symbol + " with alternatives " + (alts map pre.memberType) + ", argtpes = " + argtpes + ", pt = " + pt)
- val applicable = alts filter (alt => isApplicable(undetparams, pre.memberType(alt), argtpes, pt))
+ val applicable = alts filter (alt => isApplicable(undetparams, followApply(pre.memberType(alt)), argtpes, pt))
def improves(sym1: Symbol, sym2: Symbol) =
sym2 == NoSymbol || sym2.isError ||
- isStrictlyBetter(pre.memberType(sym1), pre.memberType(sym2))
+ isStrictlyMoreSpecific(followApply(pre.memberType(sym1)), followApply(pre.memberType(sym2)))
val best = ((NoSymbol: Symbol) /: applicable) ((best, alt) =>
if (improves(alt, best)) alt else best)
val competing = applicable dropWhile (alt => best == alt || improves(best, alt))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index e236f0f7e7..4f6d1682ad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -6,6 +6,7 @@
package scala.tools.nsc.typechecker
+import scala.collection.mutable.HashMap
import scala.tools.nsc.util.Position
import symtab.Flags
import symtab.Flags._
@@ -18,6 +19,7 @@ import symtab.Flags._
trait Namers { self: Analyzer =>
import global._
import definitions._
+ import posAssigner.atPos
/** Convert to corresponding type parameters all skolems which satisfy one
* of the following two conditions:
@@ -41,6 +43,12 @@ trait Namers { self: Analyzer =>
private class NormalNamer(context : Context) extends Namer(context)
def newNamer(context : Context) : Namer = new NormalNamer(context)
+ private val caseClassOfModuleClass = new HashMap[Symbol, ClassDef]
+
+ def resetNamer() {
+ caseClassOfModuleClass.clear
+ }
+
abstract class Namer(val context: Context) {
val typer = newTyper(context)
@@ -51,6 +59,14 @@ trait Namers { self: Analyzer =>
sym
}
+
+ def inConstructorFlag: Long =
+ if (context.owner.isConstructor && !context.inConstructorSuffix || context.owner.isEarly) INCONSTRUCTOR
+ else 0l
+
+ def moduleClassFlags(moduleFlags: Long) =
+ (moduleFlags & ModuleToClassFlags) | FINAL | inConstructorFlag
+
def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = {
if (settings.debug.value) log("overwriting " + sym)
val lockedFlag = sym.flags & LOCKED
@@ -58,7 +74,7 @@ trait Namers { self: Analyzer =>
sym setPos pos
sym.flags = flags | lockedFlag
if (sym.isModule && sym.moduleClass != NoSymbol)
- updatePosFlags(sym.moduleClass, pos, (flags & ModuleToClassFlags) | MODULE | FINAL)
+ updatePosFlags(sym.moduleClass, pos, moduleClassFlags(flags))
if (sym.owner.isPackageClass &&
(sym.linkedSym.rawInfo.isInstanceOf[loaders.SymbolLoader] ||
sym.linkedSym.rawInfo.isComplete && runId(sym.validTo) != currentRunId))
@@ -112,13 +128,20 @@ trait Namers { self: Analyzer =>
!((newS.owner.isTypeParameter || newS.owner.isAbstractType) &&
newS.name.length==1 && newS.name(0)=='_') //@M: allow repeated use of `_' for higher-order type params
}
+
+ // IDE hook
protected def setInfo[Sym <: Symbol](sym : Sym)(tpe : LazyType) : Sym = sym.setInfo(tpe)
+
private def doubleDefError(pos: Position, sym: Symbol) {
context.error(pos,
sym.name.toString() + " is already defined as " +
(if (sym.hasFlag(CASE)) "case class " + sym.name else sym.toString()))
}
+ private def inCurrentScope(m: Symbol) =
+ if (context.owner.isClass) context.owner == m.owner
+ else context.scope == m.owner.info.decls
+
def enterInScope(sym: Symbol): Symbol = {
// allow for overloaded methods
if (!(sym.isSourceMethod && sym.owner.isClass && !sym.owner.isPackageClass)) {
@@ -149,10 +172,6 @@ trait Namers { self: Analyzer =>
}
}
- def inConstructorFlag: Long =
- if (context.owner.isConstructor && !context.inConstructorSuffix || context.owner.isEarly) INCONSTRUCTOR
- else 0l
-
def enterClassSymbol(tree : ClassDef): Symbol = {
var c: Symbol = context.scope.lookup(tree.name);
if (!inIDE && c.isType && context.scope == c.owner.info.decls && !currentRun.compiles(c)) {
@@ -179,21 +198,25 @@ trait Namers { self: Analyzer =>
assert(c.name.toString.indexOf('(') == -1)
c
}
+
+ /** Enter a module symbol. The tree parameter can be either a module definition
+ * or a class definition */
def enterModuleSymbol(tree : ModuleDef): Symbol = {
// .pos, mods.flags | MODULE | FINAL, name
- assert(tree.name.isTermName)
var m: Symbol = context.scope.lookup(tree.name)
- if (!inIDE && m.isModule && !m.isPackage && (context.scope == m.owner.info.decls) &&
- !currentRun.compiles(m)) {
- updatePosFlags(m, tree.pos, tree.mods.flags|MODULE|FINAL)
+ val moduleFlags = tree.mods.flags | MODULE | FINAL
+ if (!inIDE && m.isModule && !m.isPackage && inCurrentScope(m) &&
+ (!currentRun.compiles(m) || (m hasFlag SYNTHETIC))) {
+ updatePosFlags(m, tree.pos, moduleFlags)
setPrivateWithin(tree, m, tree.mods)
+ synthetics -= m
} else {
m = context.owner.newModule(tree.pos, tree.name)
- m.setFlag(tree.mods.flags)
+ m.setFlag(moduleFlags)
m = setPrivateWithin(tree, m, tree.mods)
m = enterInScope(m)
- m.moduleClass.setFlag(tree.mods.flags|MODULE|FINAL| inConstructorFlag)
+ m.moduleClass.setFlag(moduleClassFlags(moduleFlags))
setPrivateWithin(tree, m.moduleClass, tree.mods)
}
if (m.owner.isPackageClass) {
@@ -203,26 +226,6 @@ trait Namers { self: Analyzer =>
m
}
- def enterCaseFactorySymbol(tree : ClassDef): Symbol = {
- val pos = tree.pos
- val flags = tree.mods.flags & AccessFlags | METHOD | CASE
- val name = tree.name.toTermName
- var m: Symbol = context.scope.lookup(name)
- if (!inIDE && m.isTerm && !m.isPackage && !currentRun.compiles(m) && context.scope == m.owner.info.decls) {
- updatePosFlags(m, pos, flags)
- setPrivateWithin(tree, m, tree.mods)
- } else {
- // recycle the old fashion way.
- m = enterInScope{
- var sym = context.owner.newMethod(pos, name).setFlag(flags)
- sym = setPrivateWithin(tree, sym, tree.mods)
- sym
- }
- }
- if (m.owner.isPackageClass)
- currentRun.symSource(m) = context.unit.source.file
- m
- }
def enterSyms(trees: List[Tree]): Namer = {
var namer : Namer = this
for (tree <- trees) {
@@ -231,6 +234,7 @@ trait Namers { self: Analyzer =>
}
namer
}
+
def newTypeSkolems(tparams: List[Symbol]): List[Symbol] = {
val tskolems = tparams map (_.newTypeSkolem)
val ltp = new LazyType {
@@ -280,7 +284,6 @@ trait Namers { self: Analyzer =>
}
def finish = finishWith(List())
-
if (tree.symbol == NoSymbol) {
val owner = context.owner
tree match {
@@ -292,9 +295,12 @@ trait Namers { self: Analyzer =>
case tree @ ClassDef(mods, name, tparams, impl) =>
tree.symbol = enterClassSymbol(tree)
finishWith(tparams)
- if ((mods.flags & CASE) != 0) { // enter case factory method.
- val sym = enterCaseFactorySymbol(tree)
- setInfo(sym)(namerOf(sym).caseFactoryCompleter(reuse(tree)))
+ if ((mods.flags & CASE) != 0) {
+ var m: Symbol = context.scope.lookup(tree.name.toTermName).filter(! _.isSourceMethod)
+ if (!(m.isModule && inCurrentScope(m) && currentRun.compiles(m))) {
+ m = enterSyntheticSym(caseModuleDef(tree))
+ }
+ caseClassOfModuleClass(m.moduleClass) = tree
}
case tree @ ModuleDef(mods, name, _) =>
tree.symbol = enterModuleSymbol(tree)
@@ -370,6 +376,12 @@ trait Namers { self: Analyzer =>
this.context
}
+ def enterSyntheticSym(tree: Tree): Symbol = {
+ enterSym(tree)
+ synthetics(tree.symbol) = tree
+ tree.symbol
+ }
+
// --- Lazy Type Assignment --------------------------------------------------
def typeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>
@@ -421,14 +433,6 @@ trait Namers { self: Analyzer =>
sym.setInfo(selftpe)
}
- def caseFactoryCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>
- val clazz = tree.symbol
- var tpe = clazz.primaryConstructor.tpe
- val tparams = clazz.typeParams
- if (!tparams.isEmpty) tpe = PolyType(tparams, tpe).cloneInfo(sym);
- sym.setInfo(tpe)
- }
-
private def widenIfNotFinal(sym: Symbol, tpe: Type, pt: Type): Type = {
val getter =
if (sym.isValue && sym.owner.isClass && (sym hasFlag PRIVATE))
@@ -508,7 +512,14 @@ trait Namers { self: Analyzer =>
val parents = typer.parentTypes(templ) map checkParent
enterSelf(templ.self)
val decls = newClassScope(clazz)
- newNamer(context.make(templ, clazz, decls)).enterSyms(templ.body)
+ val templateNamer = newNamer(context.make(templ, clazz, decls))
+ .enterSyms(templ.body)
+ caseClassOfModuleClass get clazz match {
+ case Some(cdef) =>
+ addApplyUnapply(cdef, templateNamer)
+ caseClassOfModuleClass -= clazz
+ case None =>
+ }
ClassInfoType(parents, decls, clazz)
}
@@ -733,6 +744,28 @@ trait Namers { self: Analyzer =>
else polyType(tparamSyms, tp)
}
+ /** Given a case class
+ *
+ * case class C[Ts] (ps: Us)
+ *
+ * Add the following methods to toScope:
+ *
+ * 1. if case class is not abstract, add
+ *
+ * <synthetic> <case> def apply[Ts](ps: Us): C[Ts] = new C[Ts](ps)
+ *
+ * 2. add a method
+ *
+ * <synthetic> <case> def unapply[Ts](x: C[Ts]) = <ret-val>
+ *
+ * where <ret-val> is the caseClassUnapplyReturnValue of class C (see UnApplies.scala)
+ */
+ def addApplyUnapply(cdef: ClassDef, namer: Namer) {
+ if (!(cdef.symbol hasFlag ABSTRACT))
+ namer.enterSyntheticSym(caseModuleApplyMeth(cdef))
+ namer.enterSyntheticSym(caseModuleUnapplyMeth(cdef))
+ }
+
def typeSig(tree: Tree): Type = {
val sym: Symbol = tree.symbol
tree match {
@@ -758,7 +791,7 @@ trait Namers { self: Analyzer =>
val clazz = sym.moduleClass
clazz.setInfo(newNamer(context.makeNewScope(tree, clazz)).templateSig(impl))
//clazz.typeOfThis = singleType(sym.owner.thisType, sym);
- clazz.tpe;
+ clazz.tpe
case DefDef(_, _, tparams, vparamss, tpt, rhs) =>
val result =
@@ -884,7 +917,7 @@ trait Namers { self: Analyzer =>
checkNoConflict(PRIVATE, PROTECTED)
checkNoConflict(PRIVATE, OVERRIDE)
checkNoConflict(DEFERRED, FINAL)
- checkNoConflict(ABSTRACT, CASE)
+// checkNoConflict(ABSTRACT, CASE)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 5c7841651b..e098224e59 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -373,7 +373,7 @@ abstract class RefChecks extends InfoTransform {
var state = CoVariance
while (sym != clazz && state != AnyVariance) {
//Console.println("flip: " + sym + " " + sym.isParameter());//DEBUG
- if ((sym hasFlag PARAM) && !sym.owner.isConstructor && !sym.owner.isCaseFactory &&
+ if ((sym hasFlag PARAM) && !sym.owner.isConstructor && !sym.owner.isCaseApplyOrUnapply &&
!(tvar.isTypeParameterOrSkolem && sym.isTypeParameterOrSkolem &&
tvar.owner == sym.owner)) state = -state;
else if (!sym.owner.isClass ||
@@ -574,9 +574,6 @@ abstract class RefChecks extends InfoTransform {
}
}
- def isConcreteLocalCaseFactory(clazz: Symbol) =
- (clazz hasFlag CASE) && !(clazz hasFlag ABSTRACT) && !(clazz.owner hasFlag PACKAGE)
-
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
pushLevel()
enterSyms(stats)
@@ -635,32 +632,6 @@ abstract class RefChecks extends InfoTransform {
else transformTrees(List(cdef, vdef, ddef))
}
- case ClassDef(_, _, _, _) if isConcreteLocalCaseFactory(tree.symbol) =>
- val clazz = tree.symbol
- val factory = clazz.caseFactory
- if (factory == NoSymbol) {
- assert(clazz.owner.isTerm, clazz)
- List(transform(tree))
- } else {
- def mkArgument(vparam: Symbol) = {
- val id = Ident(vparam)
- if (vparam.tpe.typeSymbol == RepeatedParamClass) Typed(id, Ident(nme.WILDCARD_STAR.toTypeName))
- else id
- }
- val caseFactoryDef =
- localTyper.typed {
- atPos(tree.pos) {
- DefDef(
- factory,
- vparamss =>
- (toConstructor(tree.pos, factory.tpe) /: vparamss) {
- (fn, vparams) => Apply(fn, vparams map mkArgument)
- })
- }
- }
- List(transform(tree), caseFactoryDef)
- }
-
case ValDef(_, _, _, _) =>
val tree1 = transform(tree); // important to do before forward reference check
val ValDef(_, _, _, rhs) = tree1
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 7429c9ccf7..ff31a95c8a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -38,13 +38,16 @@ trait Typers { self: Analyzer =>
private val superDefs = new HashMap[Symbol, ListBuffer[Tree]]
- def resetTyper {
+ val synthetics = new HashMap[Symbol, Tree]
+
+ def resetTyper() {
resetContexts
+ resetNamer()
transformed.clear
superDefs.clear
+ synthetics.clear
}
-
object UnTyper extends Traverser {
override def traverse(tree: Tree) = {
if (tree != EmptyTree) tree.tpe = null
@@ -708,27 +711,32 @@ trait Typers { self: Analyzer =>
case _ => TypeTree(tree.tpe) setOriginal(tree)
}
} else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode)) { // (5)
- val constr = tree.symbol.filter(_.isCaseFactory)
- val clazz = constr.tpe.finalResultType.typeSymbol
- if ((constr != NoSymbol) && (clazz hasFlag CASE)) {
- val prefix = tree.tpe.finalResultType.prefix
- val tree1 = TypeTree(clazz.primaryConstructor.tpe.asSeenFrom(prefix, clazz.owner)) setOriginal tree
- try {
- inferConstructorInstance(tree1, clazz.typeParams, pt)
- } catch {
- case tpe : TypeError => throw tpe
- case t : Exception =>
- logError("CONTEXT: " + (tree.pos).dbgString, t)
- throw t
- }
- tree1
- } else {
- val extractor = tree.symbol.filter(sym => unapplyMember(sym.tpe).exists)
- if (extractor != NoSymbol) {
- tree setSymbol extractor
+ val extractor = tree.symbol.filter(sym => unapplyMember(sym.tpe).exists)
+ if (extractor != NoSymbol) {
+ tree setSymbol extractor
+ val unapply = unapplyMember(extractor.tpe)
+ val clazz = if (unapply.tpe.paramTypes.length == 1) unapply.tpe.paramTypes.head.typeSymbol
+ else NoSymbol
+ if ((unapply hasFlag CASE) && (clazz hasFlag CASE)) {
+ if (!phase.erasedTypes) checkStable(tree) //todo: do we need to demand this?
+ // convert synthetic unapply of case class to case class constructor
+ val prefix = tree.tpe.prefix
+ val tree1 = TypeTree(clazz.primaryConstructor.tpe.asSeenFrom(prefix, clazz.owner))
+ .setOriginal(tree)
+ try {
+ inferConstructorInstance(tree1, clazz.typeParams, pt)
+ } catch {
+ case tpe : TypeError => throw tpe
+ case t : Exception =>
+ logError("CONTEXT: " + (tree.pos).dbgString, t)
+ throw t
+ }
+ tree1
} else {
- errorTree(tree, tree.symbol + " is not a case class constructor, nor does it have an unapply/unapplySeq method")
+ tree
}
+ } else {
+ errorTree(tree, tree.symbol + " is not a case class constructor, nor does it have an unapply/unapplySeq method")
}
} else if ((mode & (EXPRmode | FUNmode)) == (EXPRmode | FUNmode) &&
!tree.tpe.isInstanceOf[MethodType] &&
@@ -1440,7 +1448,14 @@ trait Typers { self: Analyzer =>
if (vparam.tpt.isEmpty)
vparam.tpt.tpe =
if (isFullyDefined(argpt)) argpt
- else { error(vparam.pos, "missing parameter type"); ErrorType }
+ else {
+ error(
+ vparam.pos,
+ "missing parameter type"+
+ (if (vparam.mods.hasFlag(SYNTHETIC)) " for expanded function "+fun
+ else ""))
+ ErrorType
+ }
enterSym(context, vparam)
if (context.retyping) context.scope enter vparam.symbol
vparam.symbol
@@ -1479,7 +1494,9 @@ trait Typers { self: Analyzer =>
def typedImport(imp : Import) : Import = imp;
def typedStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
+
val inBlock = exprOwner == context.owner
+
def typedStat(stat: Tree): Tree = {
if (context.owner.isRefinementClass && !treeInfo.isDeclaration(stat))
errorTree(stat, "only declarations allowed here")
@@ -1510,14 +1527,19 @@ trait Typers { self: Analyzer =>
result
}
}
+
def accesses(accessor: Symbol, accessed: Symbol) =
(accessed hasFlag LOCAL) && (accessed hasFlag PARAMACCESSOR) ||
(accessor hasFlag ACCESSOR) &&
!(accessed hasFlag ACCESSOR) && accessed.isPrivateLocal
- def checkNoDoubleDefs(stats: List[Tree]) {
+
+ def checkNoDoubleDefsAndAddSynthetics(stats: List[Tree]): List[Tree] = {
val scope = if (inBlock) context.scope else context.owner.info.decls;
+ val newStats = new ListBuffer[Tree]
var e = scope.elems;
while ((e ne null) && e.owner == scope) {
+
+ // check no double def
var e1 = scope.lookupNextEntry(e);
while ((e1 ne null) && e1.owner == scope) {
if (!accesses(e.sym, e1.sym) && !accesses(e1.sym, e.sym) &&
@@ -1527,12 +1549,23 @@ trait Typers { self: Analyzer =>
{if(!settings.debug.value) "" else " in "+unit.toString})
e1 = scope.lookupNextEntry(e1);
}
+
+ // add synthetics
+ synthetics get e.sym match {
+ case Some(tree) =>
+ newStats += tree
+ synthetics -= e.sym
+ case None =>
+ }
+
e = e.next
}
+ if (newStats.isEmpty) stats
+ else stats ::: (newStats.toList map typedStat)
}
val result = List.mapConserve(stats)(typedStat)
- if (!phase.erasedTypes) checkNoDoubleDefs(result)
- result
+ if (phase.erasedTypes) result
+ else checkNoDoubleDefsAndAddSynthetics(result)
}
def typedArg(arg: Tree, mode: Int, newmode: Int, pt: Type): Tree =
@@ -1571,13 +1604,11 @@ trait Typers { self: Analyzer =>
val argtypes = args map (arg => AllClass.tpe)
val pre = fun.symbol.tpe.prefix
var sym = fun.symbol filter { alt =>
- isApplicableSafe(context.undetparams, pre.memberType(alt), argtypes, pt)
+ isApplicableSafe(context.undetparams, followApply(pre.memberType(alt)), argtypes, pt)
}
if (sym hasFlag OVERLOADED) {
// eliminate functions that would result from tupling transforms
- val sym1 = sym filter { alt =>
- formalTypes(alt.tpe.paramTypes, argtypes.length).length == argtypes.length
- }
+ val sym1 = sym filter (alt => hasExactlyNumParams(followApply(alt.tpe), argtypes.length))
if (sym1 != NoSymbol) sym = sym1
}
if (sym != NoSymbol)
@@ -1922,6 +1953,7 @@ trait Typers { self: Analyzer =>
trackSetInfo(quantified setFlag EXISTENTIAL)(bound.cloneInfo(quantified))
}
val typeParamTypes = typeParams map (_.tpe) // don't trackSetInfo here, since type already set!
+ //println("ex trans "+rawSyms+" . "+tp+" "+typeParamTypes+" "+(typeParams map (_.info)))//DEBUG
for (tparam <- typeParams) tparam.setInfo(tparam.info.subst(rawSyms, typeParamTypes))
(typeParams, tp.subst(rawSyms, typeParamTypes))
}
@@ -2237,7 +2269,9 @@ trait Typers { self: Analyzer =>
} else {
if (!lhs1.tpe.isError) {
//println(lhs1+" = "+rhs)//DEBUG
- error(tree.pos, "assignment to non-variable ")
+ error(tree.pos, "assignment to "+
+ (if ((varsym ne null) && varsym.isValue) "immutable value"
+ else "non variable"))
}
setError(tree)
}
@@ -2629,7 +2663,6 @@ trait Typers { self: Analyzer =>
case SelectFromTypeTree(_, _) => copy.SelectFromTypeTree(tree, qual, name)
}
val result = stabilize(checkAccessible(tree1, sym, qual.tpe, qual), qual.tpe, mode, pt)
- if (sym.isCaseFactory && !phase.erasedTypes) checkStable(qual)
if (!global.phase.erasedTypes && settings.Xchecknull.value &&
!sym.isConstructor &&
!(qual.tpe <:< NotNullClass.tpe) && !qual.tpe.isNotNull)
@@ -2676,14 +2709,13 @@ trait Typers { self: Analyzer =>
var defSym: Symbol = tree.symbol // the directly found symbol
var pre: Type = NoPrefix // the prefix type of defSym, if a class member
var qual: Tree = EmptyTree // the qualififier tree if transformed tree is a select
- // if we are in a constructor of a pattern, ignore all methods
- // which are not case factories (note if we don't do that
+
+ // if we are in a constructor of a pattern, ignore all definitions
+ // which are methods (note: if we don't do that
// case x :: xs in class List would return the :: method).
def qualifies(sym: Symbol): Boolean =
sym.exists &&
- ((mode & PATTERNmode | FUNmode) != (PATTERNmode | FUNmode) ||
- !sym.isSourceMethod || sym.isCaseFactory)
-
+ ((mode & PATTERNmode | FUNmode) != (PATTERNmode | FUNmode) || !sym.isSourceMethod)
if (defSym == NoSymbol) {
var defEntry: ScopeEntry = null // the scope entry of defSym, if defined in a local scope
@@ -2795,8 +2827,7 @@ trait Typers { self: Analyzer =>
if (inIDE) {
Ident(defSym.name) setType tree1.tpe setSymbol defSym setPos tree.pos
} else tree1
- }
- else {
+ } else {
var tree1 = if (qual == EmptyTree) tree
else atPos(tree.pos)(Select(qual, name))
// atPos necessary because qualifier might come from startContext
@@ -3380,7 +3411,7 @@ trait Typers { self: Analyzer =>
def improves(info1: ImplicitInfo, info2: ImplicitInfo) =
(info2 == NoImplicitInfo) ||
(info1 != NoImplicitInfo) &&
- isStrictlyBetterExpr(info1.tpe, info2.tpe)
+ isStrictlyMoreSpecific(info1.tpe, info2.tpe)
val shadowed = new HashSet[Name](8)
def isApplicable(info: ImplicitInfo): Boolean =
!containsError(info.tpe) &&
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 98c6935953..c0be7a9454 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -6,6 +6,8 @@
package scala.tools.nsc.typechecker
+import symtab.Flags._
+
/*
* @author Martin Odersky
* @version 1.0
@@ -14,6 +16,7 @@ trait Unapplies { self: Analyzer =>
import global._
import definitions._
+ import posAssigner.atPos
/** returns type list for return type of the extraction */
def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
@@ -79,7 +82,6 @@ trait Unapplies { self: Analyzer =>
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)
@@ -92,4 +94,88 @@ trait Unapplies { self: Analyzer =>
if (unapp == NoSymbol) unapp = tp.member(nme.unapplySeq)
unapp
}
+
+ private def copyUntyped[T <: Tree](tree: T): T = {
+ val tree1 = tree.duplicate
+ UnTyper.traverse(tree1)
+ tree1
+ }
+
+ private def classType(cdef: ClassDef, tparams: List[TypeDef]): Tree = {
+ val tycon = gen.mkAttributedRef(cdef.symbol)
+ if (tparams.isEmpty) tycon else AppliedTypeTree(tycon, tparams map (x => Ident(x.name)))
+ }
+
+ private def constrParams(cdef: ClassDef): List[List[ValDef]] = {
+ val constr = treeInfo.firstConstructor(cdef.impl.body)
+ (constr: @unchecked) match {
+ case DefDef(_, _, _, vparamss, _, _) => vparamss map (_ map copyUntyped[ValDef])
+ }
+ }
+
+ /** The return value of an unapply method of a case class C[Ts]
+ * @param param The name of the parameter of the unapply method, assumed to be of type C[Ts]
+ * @param caseclazz The case class C[Ts]
+ */
+ private def caseClassUnapplyReturnValue(param: Name, caseclazz: Symbol) = {
+ def caseFieldAccessorValue(selector: Symbol) = Select(Ident(param), selector)
+ val accessors = caseclazz.caseFieldAccessors
+ if (accessors.isEmpty) Literal(true)
+ else if (accessors.tail.isEmpty) caseFieldAccessorValue(accessors.head)
+ else Apply(gen.scalaDot(newTermName( "Tuple" + accessors.length)), accessors map caseFieldAccessorValue)
+ }
+
+ /** The module corresponding to a case class; without any member definitions
+ */
+ def caseModuleDef(cdef: ClassDef): ModuleDef = atPos(cdef.pos) {
+ var parents = List(gen.scalaScalaObjectConstr)
+ if (cdef.tparams.isEmpty && constrParams(cdef).length == 1)
+ parents = gen.scalaFunctionConstr(constrParams(cdef).head map (_.tpt),
+ Ident(cdef.name)) :: parents
+ ModuleDef(
+ Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
+ cdef.name.toTermName,
+ Template(parents, emptyValDef, Modifiers(0), List(), List(List()), List()))
+ }
+
+ /** The apply method corresponding to a case class
+ */
+ def caseModuleApplyMeth(cdef: ClassDef): DefDef = {
+ val tparams = cdef.tparams map copyUntyped[TypeDef]
+ def paramToArg(param: ValDef) = {
+ val id = Ident(param.name)
+ val RP = nme.REPEATED_PARAM_CLASS_NAME.toTypeName
+ param.tpt match {
+ case AppliedTypeTree(Select(_, RP), _) => Typed(id, Ident(nme.WILDCARD_STAR.toTypeName))
+ case _ =>id
+ }
+ }
+ val cparams = constrParams(cdef)
+ atPos(cdef.pos) {
+ DefDef(
+ Modifiers(SYNTHETIC | CASE),
+ nme.apply,
+ tparams,
+ cparams,
+ classType(cdef, tparams),
+ New(classType(cdef, tparams), cparams map (_ map paramToArg)))
+ }
+ }
+
+ /** The unapply method corresponding to a case class
+ */
+ def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = {
+ val tparams = cdef.tparams map copyUntyped[TypeDef]
+ val unapplyParamName = newTermName("x$0")
+ atPos(cdef.pos) {
+ DefDef(
+ Modifiers(SYNTHETIC | CASE),
+ nme.unapply,
+ tparams,
+ List(List(ValDef(Modifiers(PARAM | SYNTHETIC), unapplyParamName,
+ classType(cdef, tparams), EmptyTree))),
+ TypeTree(),
+ caseClassUnapplyReturnValue(unapplyParamName, cdef.symbol))
+ }
+ }
}
diff --git a/src/library/scala/collection/jcl/SortedSet.scala b/src/library/scala/collection/jcl/SortedSet.scala
index d1317096ad..0e59eb5c43 100644
--- a/src/library/scala/collection/jcl/SortedSet.scala
+++ b/src/library/scala/collection/jcl/SortedSet.scala
@@ -9,6 +9,7 @@
// $Id$
package scala.collection.jcl;
+import Predef._
object SortedSet {
trait Projection[A] extends Set.Projection[A] with SortedSet[A] {
@@ -49,7 +50,8 @@ trait SortedSet[A] extends scala.collection.SortedSet[A] with jcl.Set[A] with So
override def has(a : A) : Boolean = SortedSet.this.has(a)
}
- protected class Filter(p : A => Boolean) extends super.Filter(p) with SortedSet.Projection[A] {
+ protected class Filter(pp : A => Boolean) extends super.Filter(pp) with SortedSet.Projection[A] {
+ override def p(a : A) = pp(a)
def compare(a0 : A, a1 : A) : Int = SortedSet.this.compare(a0, a1);
override def filter(p0 : A => Boolean) = SortedSet.this.projection.filter(k => p(k) && p0(k));
}
diff --git a/test/files/jvm/serialization.check b/test/files/jvm/serialization.check
new file mode 100755
index 0000000000..144e31603f
--- /dev/null
+++ b/test/files/jvm/serialization.check
@@ -0,0 +1,146 @@
+x1 = List()
+y1 = List()
+x1 eq y1: true - y1 eq x1: true
+
+x2 = None
+y2 = None
+x2 eq y2: true - y2 eq x2: true
+
+x3 = Array[1,2,3]
+y3 = Array[1,2,3]
+arrayEquals(x3, y3): true
+
+x4 = <na>
+y4 = <na>
+x4(2): 4 - y4(2): 4
+
+x = List((buffers,20), (layers,2), (title,3))
+y = List((buffers,20), (layers,2), (title,3))
+x equals y: true - y equals x: true
+
+x = Map(buffers -> 20, layers -> 2, title -> 3)
+y = Map(buffers -> 20, layers -> 2, title -> 3)
+x equals y: true - y equals x: true
+
+x = Set(2, 3)
+y = Set(2, 3)
+x equals y: true - y equals x: true
+
+x = Set(5, 3)
+y = Set(5, 3)
+x equals y: true - y equals x: true
+
+x = Queue(a,b,c)
+y = Queue(a,b,c)
+x equals y: true - y equals x: true
+
+x = Stack(c, b, a)
+y = Stack(c, b, a)
+x equals y: true - y equals x: true
+
+x = Map(42 -> FortyTwo)
+y = Map(42 -> FortyTwo)
+x equals y: true - y equals x: true
+
+x = Set(0, 2)
+y = Set(0, 2)
+x equals y: true - y equals x: true
+
+x = ArrayBuffer(one, two)
+y = ArrayBuffer(one, two)
+x equals y: true - y equals x: true
+
+x = Map(title -> 3, buffers -> 20, layers -> 2)
+y = Map(title -> 3, buffers -> 20, layers -> 2)
+x equals y: true - y equals x: true
+
+x = Set(0, 8, 9)
+y = Set(0, 8, 9)
+x equals y: true - y equals x: true
+
+x = Set(layers, buffers, title)
+y = Set(layers, buffers, title)
+x equals y: true - y equals x: true
+
+x = LinkedList(2, 3)
+y = LinkedList(2, 3)
+x equals y: true - y equals x: true
+
+x = Queue(20, 2, 3)
+y = Queue(20, 2, 3)
+x equals y: true - y equals x: true
+
+x = Stack(20, 2, 3)
+y = Stack(20, 2, 3)
+x equals y: true - y equals x: true
+
+x = ListBuffer(white, black)
+y = ListBuffer(white, black)
+x equals y: true - y equals x: true
+
+x = <html><title>title</title><body></body></html>
+y = <html><title>title</title><body></body></html>
+x equals y: true - y equals x: true
+
+x = <html>
+ <body>
+ <table cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Last Name</th>
+ <th>First Name</th>
+ </tr>
+ <tr>
+ <td> Tom </td>
+ <td> 20 </td>
+ </tr><tr>
+ <td> Bob </td>
+ <td> 22 </td>
+ </tr><tr>
+ <td> James </td>
+ <td> 19 </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+y = <html>
+ <body>
+ <table cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Last Name</th>
+ <th>First Name</th>
+ </tr>
+ <tr>
+ <td> Tom </td>
+ <td> 20 </td>
+ </tr><tr>
+ <td> Bob </td>
+ <td> 22 </td>
+ </tr><tr>
+ <td> James </td>
+ <td> 19 </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+x equals y: true - y equals x: true
+
+x = Tim
+y = Tim
+x equals y: true - y equals x: true
+
+x = Bob
+y = Bob
+x equals y: true - y equals x: true
+
+x = John
+y = John
+x equals y: true - y equals x: true
+
+x = Bill
+y = Bill
+x equals y: true - y equals x: true
+
+x = Paul
+y = Paul
+x equals y: true - y equals x: true
+
diff --git a/test/files/jvm/serialization.scala b/test/files/jvm/serialization.scala
new file mode 100755
index 0000000000..3049d7815b
--- /dev/null
+++ b/test/files/jvm/serialization.scala
@@ -0,0 +1,345 @@
+//############################################################################
+// Serialization
+//############################################################################
+// $Id: serialization.scala 12990 2007-10-03 16:52:05Z michelou $
+
+import java.lang.System
+
+object EqualityTest {
+ def check[A, B](x: A, y: B) {
+ println("x = " + x)
+ println("y = " + y)
+ println("x equals y: " + (x equals y) + " - y equals x: " + (y equals x))
+ println()
+ }
+}
+
+object Serialize {
+ @throws(classOf[java.io.IOException])
+ def write[A](o: A): Array[Byte] = {
+ val ba = new java.io.ByteArrayOutputStream(512)
+ val out = new java.io.ObjectOutputStream(ba)
+ out.writeObject(o)
+ out.close()
+ ba.toByteArray()
+ }
+ @throws(classOf[java.io.IOException])
+ @throws(classOf[ClassNotFoundException])
+ def read[A](buffer: Array[Byte]): A = {
+ val in =
+ new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(buffer))
+ in.readObject().asInstanceOf[A]
+ }
+}
+
+//############################################################################
+// Test classes in package "scala"
+
+@serializable
+object Test1_scala {
+
+ private def arrayToString[A](arr: Array[A]): String =
+ List.fromArray(arr).mkString("Array[",",","]")
+
+ private def arrayEquals[A, B](a1: Array[A], a2: Array[B]) =
+ (a1.length == a2.length) &&
+ (Iterator.range(0, a1.length) forall { i => a1(i) == a2(i) })
+
+ val x1 = Nil
+ val x2 = None
+ val x3 = Array(1, 2, 3)
+ val x4 = { x: Int => 2 * x }
+
+ try {
+ val y1: List[Nothing] = Serialize.read(Serialize.write(x1))
+ val y2: Option[Nothing] = Serialize.read(Serialize.write(x2))
+ val y3: Array[Int] = Serialize.read(Serialize.write(x3))
+ val y4: Function[Int, Int] = Serialize.read(Serialize.write(x4))
+
+ println("x1 = " + x1)
+ println("y1 = " + y1)
+ println("x1 eq y1: " + (x1 eq y1) + " - y1 eq x1: " + (y1 eq x1))
+ println
+ println("x2 = " + x2)
+ println("y2 = " + y2)
+ println("x2 eq y2: " + (x2 eq y2) + " - y2 eq x2: " + (y2 eq x2))
+ println
+ println("x3 = " + arrayToString(x3))
+ println("y3 = " + arrayToString(y3))
+ println("arrayEquals(x3, y3): " + arrayEquals(x3, y3))
+ println
+ println("x4 = <na>")
+ println("y4 = <na>")
+ println("x4(2): " + x4(2) + " - y4(2): " + y4(2))
+ println
+ }
+ catch {
+ case e: Exception =>
+ e.printStackTrace()
+ println("Error in Test1_scala: " + e)
+ }
+}
+
+//############################################################################
+// Test classes in package "scala.collection.immutable"
+
+@serializable
+object Test2_immutable {
+ import scala.collection.immutable.{
+ BitSet, ListMap, ListSet, Queue, Stack, TreeSet, TreeMap}
+
+ val x1 = List(
+ Pair("buffers", 20),
+ Pair("layers", 2),
+ Pair("title", 3)
+ )
+
+ val x2 = new ListMap[String, Int]
+ .incl(Pair("buffers", 20))
+ .incl(Pair("layers", 2))
+ .incl(Pair("title", 3))
+
+ val x3 = {
+ val bs = new collection.mutable.BitSet()
+ bs += 2; bs += 3
+ bs.toImmutable
+ }
+
+ val x4 = new ListSet[Int]().incl(3).incl(5)
+
+ val x5 = new Queue("a", "b", "c")
+
+ val x6 = new Stack().push("a", "b", "c")
+
+ val x7 = new TreeMap[Int, String] + 42 -> "FortyTwo"
+
+ val x8 = new TreeSet[Int]().incl(2).incl(0)
+
+ try {
+ val y1: List[Pair[String, Int]] = Serialize.read(Serialize.write(x1))
+ val y2: ListMap[String, Int] = Serialize.read(Serialize.write(x2))
+ val y3: BitSet = Serialize.read(Serialize.write(x3))
+ val y4: ListSet[Int] = Serialize.read(Serialize.write(x4))
+ val y5: Queue[String] = Serialize.read(Serialize.write(x5))
+ val y6: Stack[String] = Serialize.read(Serialize.write(x6))
+ val y7: TreeMap[Int, String] = Serialize.read(Serialize.write(x7))
+ val y8: TreeSet[Int] = Serialize.read(Serialize.write(x8))
+
+ EqualityTest.check(x1, y1)
+ EqualityTest.check(x2, y2)
+ EqualityTest.check(x3, y3)
+ EqualityTest.check(x4, y4)
+ EqualityTest.check(x5, y5)
+ EqualityTest.check(x6, y6)
+ EqualityTest.check(x7, y7)
+ EqualityTest.check(x8, y8)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test2_immutable: " + e)
+ throw e
+ }
+}
+
+//############################################################################
+// Test classes in package "scala.collection.mutable"
+
+object Test3_mutable {
+ import scala.collection.mutable.{
+ ArrayBuffer, BitSet, HashMap, HashSet, History, LinkedList, ListBuffer,
+ Publisher, Queue, RevertableHistory, Stack}
+
+ val x0 = new ArrayBuffer[String]
+ x0 ++= List("one", "two")
+
+ val x2 = new BitSet()
+ x2 += 0
+ x2 += 8
+ x2 += 9
+
+ val x1 = new HashMap[String, Int]
+ x1 ++= Test2_immutable.x1
+
+ val x3 = new HashSet[String]
+ x3 ++= Test2_immutable.x1.map(p => p._1)
+
+ @serializable
+ class Feed extends Publisher[String, Feed]
+
+ val x8 = new History[String, Feed]
+
+ val x4 = new LinkedList[Int](2, null)
+ x4.append(new LinkedList(3, null))
+
+ val x7 = new ListBuffer[String]
+ x7 ++= List("white", "black")
+
+ val x5 = new Queue[Int]
+ x5 ++= Test2_immutable.x1.map(p => p._2)
+
+ val x6 = new Stack[Int]
+ x6 ++= x5
+
+ try {
+ val y0: ArrayBuffer[String] = Serialize.read(Serialize.write(x0))
+ val y1: HashMap[String, Int] = Serialize.read(Serialize.write(x1))
+ val y2: BitSet = Serialize.read(Serialize.write(x2))
+ val y3: HashSet[String] = Serialize.read(Serialize.write(x3))
+ val y4: LinkedList[Int] = Serialize.read(Serialize.write(x4))
+ val y5: Queue[Int] = Serialize.read(Serialize.write(x5))
+ val y6: Stack[Int] = Serialize.read(Serialize.write(x6))
+ val y7: ListBuffer[String] = Serialize.read(Serialize.write(x7))
+ val y8: History[String, Feed] = Serialize.read(Serialize.write(x8))
+
+ EqualityTest.check(x0, y0)
+ EqualityTest.check(x1, y1)
+ EqualityTest.check(x2, y2)
+ EqualityTest.check(x3, y3)
+ EqualityTest.check(x4, y4)
+ EqualityTest.check(x5, y5)
+ EqualityTest.check(x6, y6)
+ EqualityTest.check(x7, y7)
+ //EqualityTest.check(x8, y8) //todo
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test3_mutable: " + e)
+ }
+}
+
+//############################################################################
+// Test classes in package "scala.xml"
+
+object Test4_xml {
+ import scala.xml.Elem
+
+ val x1 = <html><title>title</title><body></body></html>;
+
+ case class Person(name: String, age: Int)
+
+ class AddressBook(a: Person*) {
+ private val people: List[Person] = a.toList
+ def toXHTML =
+ <table cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Last Name</th>
+ <th>First Name</th>
+ </tr>
+ { for (val p <- people) yield
+ <tr>
+ <td> { p.name } </td>
+ <td> { p.age.toString() } </td>
+ </tr> }
+ </table>;
+ }
+
+ val people = new AddressBook(
+ Person("Tom", 20),
+ Person("Bob", 22),
+ Person("James", 19))
+
+ val x2 =
+ <html>
+ <body>
+ { people.toXHTML }
+ </body>
+ </html>;
+
+ try {
+ val y1: scala.xml.Elem = Serialize.read(Serialize.write(x1))
+ val y2: scala.xml.Elem = Serialize.read(Serialize.write(x2))
+
+ EqualityTest.check(x1, y1)
+ EqualityTest.check(x2, y2)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test4_xml: " + e)
+ }
+}
+
+//############################################################################
+// Test user-defined classes WITHOUT nesting
+
+@serializable
+class Person(_name: String) {
+ private var name = _name
+ override def toString() = name
+ override def equals(that: Any): Boolean =
+ that.isInstanceOf[Person] &&
+ (name == that.asInstanceOf[Person].name)
+}
+
+@serializable
+class Employee(_name: String) {
+ private var name = _name
+ override def toString() = name
+}
+@serializable
+object bob extends Employee("Bob")
+
+object Test5 {
+ val x1 = new Person("Tim")
+ val x2 = bob
+
+ try {
+ val y1: Person = Serialize.read(Serialize.write(x1))
+ val y2: Employee = Serialize.read(Serialize.write(x2))
+
+ EqualityTest.check(x1, y1)
+ EqualityTest.check(x2, y2)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test5: " + e)
+ }
+}
+
+//############################################################################
+// Test user-defined classes WITH nesting
+
+@serializable
+object Test6 {
+ @serializable
+ object bill extends Employee("Bill") {
+ val x = paul
+ }
+ @serializable
+ object paul extends Person("Paul") {
+ val x = 4 // bill; => StackOverflowException !!!
+ }
+ val x1 = new Person("John")
+ val x2 = bill
+ val x3 = paul
+
+ try {
+ val y1: Person = Serialize.read(Serialize.write(x1))
+ val y2: Employee = Serialize.read(Serialize.write(x2))
+ val y3: Person = Serialize.read(Serialize.write(x3))
+
+ EqualityTest.check(x1, y1)
+ EqualityTest.check(x2, y2)
+ EqualityTest.check(x3, y3)
+ }
+ catch {
+ case e: Exception =>
+ println("Error in Test6: " + e)
+ }
+}
+
+//############################################################################
+// Test code
+
+object Test {
+ def main(args: Array[String]) {
+ Test1_scala
+ Test2_immutable
+ Test3_mutable
+ Test4_xml
+ Test5
+ Test6
+ }
+}
+
+//############################################################################
+
diff --git a/test/files/jvm/typerep.check b/test/files/jvm/typerep.check
new file mode 100755
index 0000000000..ff98348304
--- /dev/null
+++ b/test/files/jvm/typerep.check
@@ -0,0 +1,47 @@
+Boolean
+Boolean
+true
+Byte
+Char
+Int
+Long
+Float
+Double
+String
+Unit
+
+Some[Int]
+Some[Int]
+Some[Some[Int]]
+None
+None
+
+List[Int]
+List[Int]
+List[List[Int]]
+Nil
+List[Any]
+
+Array[Int]
+Array[Array[Int]]
+Array[Int]
+Array[Int]
+Array[Int]
+Array[Int]
+
+Tuple2[Int, String]
+Tuple3[Char, Char, String]
+Tuple2[Tuple2[Int, String], Tuple2[Int, String]]
+Tuple2[Tuple2[Some[Char], Int], Tuple2[Some[Char], Int]]
+
+Function1[Int, Int]
+Int
+Function1[Int, Int]
+Int
+Function1[Int, Function1[Int, Int]]
+Function1[Int, Int]
+Int
+Function3[Boolean, List[Char], Int, Int]
+Function2[Function1[Int, Int], Int, Int]
+Int
+
diff --git a/test/files/jvm/typerep.scala b/test/files/jvm/typerep.scala
new file mode 100755
index 0000000000..b133d7ce99
--- /dev/null
+++ b/test/files/jvm/typerep.scala
@@ -0,0 +1,374 @@
+//############################################################################
+// Type Representation at runtime
+//############################################################################
+// $Id: $
+
+import TypeRep._
+
+object Test extends Application {
+ testPrimitives
+ testOptions
+ testLists
+ testArrays
+ testTuples
+ testFuncs
+ testClasses
+}
+
+object serialize {
+ import java.io._
+
+ @throws(classOf[IOException])
+ def write[A](o: A): Array[Byte] = {
+ val ba = new ByteArrayOutputStream(512)
+ val out = new ObjectOutputStream(ba)
+ out.writeObject(o)
+ out.close()
+ ba.toByteArray()
+ }
+ @throws(classOf[IOException])
+ @throws(classOf[ClassNotFoundException])
+ def read[A](buffer: Array[Byte]): A = {
+ val in =
+ new ObjectInputStream(new ByteArrayInputStream(buffer))
+ in.readObject().asInstanceOf[A]
+ }
+}
+
+object testPrimitives {
+ println(getType(true))
+ val b = false; val bt = getType(b)
+ println(bt)
+ val bt1: TypeRep[Boolean] = serialize.read(serialize.write(bt))
+ println(bt1 == bt)
+ println(getType(16.toByte))
+ println(getType('a'))
+ println(getType(3))
+ println(getType(3l))
+ println(getType(0.0f))
+ println(getType(0.0d))
+ println(getType("abc"))
+ println(getType(())) // Unit
+// println(getType(classOf[Int])) // Class
+ println
+}
+
+object testOptions {
+ println(getType(Some(2)))
+ val x: Option[Int] = Some(2)
+ println(getType(x))
+ println(getType(Some(Some(3))))
+ println(getType(None))
+ val y: Option[Int] = None
+ println(getType(y))
+ println
+}
+
+object testLists {
+ println(getType(List(3)))
+ println(getType(3 :: Nil))
+ println(getType(List(List(3))))
+ println(getType(Nil))
+ println(getType(List(1, "abc")))
+ println
+}
+
+object testArrays {
+ println(getType(Array(3)))
+ println(getType(Array(Array(3), Array(4))))
+ println(getType(new Array[Int](0)))
+ println(getType(List(1).toArray))
+ println(getType(List[Int]().toArray))
+ println(getType(Array(3).drop(1).toArray)) // empty
+ println
+}
+
+object testTuples {
+ println(getType((3, "abc")))
+ println(getType(Triple('a', 'b', "c")))
+ println(getType(((3, "abc"), (4, "xyz"))))
+ println(getType(((Some('b'), 3), (Some('a'), 4))))
+ //println(getType(((Some('b'), 3), (None, 4))))
+ println
+}
+
+object testFuncs {
+ def f1(x: Int): Int = 2 * x
+ println(getType(f1 _))
+ println(getType(f1(2)))
+ val f2 = (x: Int) => 2 * x
+ println(getType(f2))
+ println(getType(f2(2)))
+ val f3 = (x: Int) => (y: Int) => x + y
+ println(getType(f3))
+ println(getType(f3(2)))
+ println(getType(f3(2)(2)))
+ def f4(b: Boolean, c: List[Char], i: Int): Int = i
+ println(getType(f4 _))
+ def f5(f: Int => Int, x: Int) = f(x)
+ println(getType(f5 _))
+ println(getType(f5(f1, 1)))
+ println
+}
+
+class Foo {
+ class Bar(x: Int)
+}
+
+
+object foo extends Foo
+
+package pkg1 {
+ class C1
+ object c1 extends C1
+}
+
+object testClasses {
+ /*
+ case object FooRep extends TypeRep[Foo] {
+ override def toString = "Foo"
+ }
+ implicit def fooRep[A](x: A)(implicit rep: TypeRep[foo.type]): TypeRep[foo.type] = rep
+ println(getType(foo))
+ println(getType(new foo.Bar(0)))
+ val foo2 = new Foo
+ println(getType(foo2))
+ println(getType(new foo2.Bar(1)))
+ println
+
+ println(getType(pkg1.c1))
+ val c1 = new pkg1.C1
+ println(getType(c1))
+ println
+ */
+}
+
+
+/**
+ * @author Stephane Micheloud
+ * @version 1.0
+ */
+abstract class TypeRep[A]
+
+object TypeRep {
+
+ def getType[A](x: A)(implicit rep: TypeRep[A]): TypeRep[A] = rep
+
+ def getType[A](x: Option[A])(implicit rep: TypeRep[A]): TypeRep[Option[A]] = (x match {
+ case Some(v) => SomeRep(rep)
+ case None => NoneRep // or NoneRep(rep)
+ }).asInstanceOf[TypeRep[Option[A]]]
+
+ def getType[A](x: List[A])(implicit rep: TypeRep[A]): TypeRep[List[A]] = (x match {
+ case h :: t => ListRep(getType(h))
+ case Nil => NilRep
+ }).asInstanceOf[TypeRep[List[A]]]
+
+ implicit def boolRep: TypeRep[Boolean] = BooleanRep
+ implicit def byteRep: TypeRep[Byte] = ByteRep
+ implicit def charRep: TypeRep[Char] = CharRep
+ implicit def shortRep: TypeRep[Short] = ShortRep
+ implicit def intRep: TypeRep[Int] = IntRep
+ implicit def longRep: TypeRep[Long] = LongRep
+ implicit def floatRep: TypeRep[Float] = FloatRep
+ implicit def doubleRep: TypeRep[Double] = DoubleRep
+
+ implicit def unitRep: TypeRep[Unit] = UnitRep
+// implicit def classRep: TypeRep[Class] = ClassRep
+ implicit def stringRep: TypeRep[String] = StringRep
+ implicit def noneRep: TypeRep[Option[Nothing]] = NoneRep[Nothing](NothingRep.asInstanceOf[TypeRep[Nothing]])
+ implicit def anyRep: TypeRep[Any] = AnyRep
+ implicit def nothingRep: TypeRep[Nothing] = NothingRep
+
+ implicit def someRep[A](implicit elemrep: TypeRep[A]): TypeRep[Some[A]] =
+ SomeRep(elemrep)
+
+ implicit def listRep[A](implicit elemrep: TypeRep[A]): TypeRep[List[A]] =
+ ListRep(elemrep)
+
+ implicit def arrayRep[A](implicit elemrep: TypeRep[A]): TypeRep[Array[A]] =
+ ArrayRep(elemrep)
+
+ implicit def tuple2Rep[A1, A2](implicit _1: TypeRep[A1], _2: TypeRep[A2]): TypeRep[Tuple2[A1, A2]] =
+ Tuple2Rep(_1, _2)
+ implicit def tuple3Rep[A1, A2, A3](implicit _1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3]): TypeRep[Tuple3[A1, A2, A3]] =
+ Tuple3Rep(_1, _2, _3)
+ implicit def tuple4Rep[A1, A2, A3, A4](implicit _1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4]): TypeRep[Tuple4[A1, A2, A3, A4]] =
+ Tuple4Rep(_1, _2, _3, _4)
+ implicit def tuple5Rep[A1, A2, A3, A4, A5](implicit _1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4], _5: TypeRep[A5]): TypeRep[Tuple5[A1, A2, A3, A4, A5]] =
+ Tuple5Rep(_1, _2, _3, _4, _5)
+ implicit def tuple6Rep[A1, A2, A3, A4, A5, A6](implicit _1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4], _5: TypeRep[A5], _6: TypeRep[A6]): TypeRep[Tuple6[A1, A2, A3, A4, A5, A6]] =
+ Tuple6Rep(_1, _2, _3, _4, _5, _6)
+ implicit def tuple7Rep[A1, A2, A3, A4, A5, A6, A7](implicit _1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4], _5: TypeRep[A5], _6: TypeRep[A6], _7: TypeRep[A7]): TypeRep[Tuple7[A1, A2, A3, A4, A5, A6, A7]] =
+ Tuple7Rep(_1, _2, _3, _4, _5, _6, _7)
+ implicit def tuple8Rep[A1, A2, A3, A4, A5, A6, A7, A8](implicit _1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4], _5: TypeRep[A5], _6: TypeRep[A6], _7: TypeRep[A7], _8: TypeRep[A8]): TypeRep[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] =
+ Tuple8Rep(_1, _2, _3, _4, _5, _6, _7, _8)
+ implicit def tuple9Rep[A1, A2, A3, A4, A5, A6, A7, A8, A9](implicit _1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4], _5: TypeRep[A5], _6: TypeRep[A6], _7: TypeRep[A7], _8: TypeRep[A8], _9: TypeRep[A9]): TypeRep[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] =
+ Tuple9Rep(_1, _2, _3, _4, _5, _6, _7, _8, _9)
+
+ implicit def func1Rep[A1, B](implicit a1: TypeRep[A1], b: TypeRep[B]): TypeRep[Function1[A1, B]] =
+ Function1Rep(a1, b)
+ implicit def func2Rep[A1, A2, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], b: TypeRep[B]): TypeRep[Function2[A1, A2, B]] =
+ Function2Rep(a1, a2, b)
+ implicit def func3Rep[A1, A2, A3, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], b: TypeRep[B]): TypeRep[Function3[A1, A2, A3, B]] =
+ Function3Rep(a1, a2, a3, b)
+ implicit def func4Rep[A1, A2, A3, A4, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], b: TypeRep[B]): TypeRep[Function4[A1, A2, A3, A4, B]] =
+ Function4Rep(a1, a2, a3, a4, b)
+ implicit def func5Rep[A1, A2, A3, A4, A5, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], b: TypeRep[B]): TypeRep[Function5[A1, A2, A3, A4, A5, B]] =
+ Function5Rep(a1, a2, a3, a4, a5, b)
+ implicit def func6Rep[A1, A2, A3, A4, A5, A6, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], b: TypeRep[B]): TypeRep[Function6[A1, A2, A3, A4, A5, A6, B]] =
+ Function6Rep(a1, a2, a3, a4, a5, a6, b)
+ implicit def func7Rep[A1, A2, A3, A4, A5, A6, A7, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], a7: TypeRep[A7], b: TypeRep[B]): TypeRep[Function7[A1, A2, A3, A4, A5, A6, A7, B]] =
+ Function7Rep(a1, a2, a3, a4, a5, a6, a7, b)
+ implicit def func8Rep[A1, A2, A3, A4, A5, A6, A7, A8, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], a7: TypeRep[A7], a8: TypeRep[A8], b: TypeRep[B]): TypeRep[Function8[A1, A2, A3, A4, A5, A6, A7, A8, B]] =
+ Function8Rep(a1, a2, a3, a4, a5, a6, a7, a8, b)
+ implicit def func9Rep[A1, A2, A3, A4, A5, A6, A7, A8, A9, B](implicit a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], a7: TypeRep[A7], a8: TypeRep[A8], a9: TypeRep[A9], b: TypeRep[B]): TypeRep[Function9[A1, A2, A3, A4, A5, A6, A7, A8, A9, B]] =
+ Function9Rep(a1, a2, a3, a4, a5, a6, a7, a8, a9, b)
+/*
+ implicit def objectRep[A <: AnyRef](obj: A)(implicit rep: TypeRep[A]): TypeRep[AnyClass] =
+ ObjectRep(obj.getClass)
+*/
+
+ case object BooleanRep extends TypeRep[Boolean] {
+ override def toString = "Boolean"
+ }
+ case object ByteRep extends TypeRep[Byte] {
+ override def toString = "Byte"
+ }
+ case object CharRep extends TypeRep[Char] {
+ override def toString = "Char"
+ }
+ case object ShortRep extends TypeRep[Short] {
+ override def toString = "Short"
+ }
+ case object IntRep extends TypeRep[Int] {
+ override def toString = "Int"
+ }
+ case object LongRep extends TypeRep[Long] {
+ override def toString = "Long"
+ }
+ case object FloatRep extends TypeRep[Float] {
+ override def toString = "Float"
+ }
+ case object DoubleRep extends TypeRep[Double] {
+ override def toString = "Double"
+ }
+
+ case object UnitRep extends TypeRep[Unit] {
+ override def toString = "Unit"
+ }
+// case object ClassRep extends TypeRep[AnyClass] {
+// override def toString = "Class"
+// }
+ case object StringRep extends TypeRep[String] {
+ override def toString = "String"
+ }
+ case object NoneRep extends TypeRep[Option[Nothing]] {
+ override def toString = "None"
+ }
+ case object NilRep extends TypeRep[Nil.type] {
+ override def toString = "Nil"
+ }
+ case object AnyRep extends TypeRep[Any] {
+ override def toString = "Any"
+ }
+ case object NothingRep extends TypeRep[Nothing] {
+ override def toString = "Nothing"
+ }
+
+ @serializable
+ case class SomeRep[A](elemRep: TypeRep[A]) extends TypeRep[Some[A]] {
+ override def toString = "Some[" + elemRep + "]"
+ }
+ @serializable
+ case class NoneRep[A](elemRep: TypeRep[A]) extends TypeRep[Option[A]] {
+ override def toString = "None[" + elemRep + "]"
+ }
+
+ @serializable
+ case class ListRep[A](elemRep: TypeRep[A]) extends TypeRep[List[A]] {
+ override def toString = "List[" + elemRep + "]"
+ }
+
+ @serializable
+ case class ArrayRep[A](elemRep: TypeRep[A]) extends TypeRep[Array[A]] {
+ override def toString = "Array[" + elemRep + "]"
+ }
+
+ @serializable
+ case class Tuple2Rep[A1, A2](_1: TypeRep[A1], _2: TypeRep[A2]) extends TypeRep[Tuple2[A1, A2]] {
+ override def toString = "Tuple2[" + _1 + ", " + _2 + "]"
+ }
+ @serializable
+ case class Tuple3Rep[A1, A2, A3](_1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3]) extends TypeRep[Tuple3[A1, A2, A3]] {
+ override def toString = "Tuple3[" + _1 + ", " + _2 + ", " + _3 + "]"
+ }
+ @serializable
+ case class Tuple4Rep[A1, A2, A3, A4](_1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4]) extends TypeRep[Tuple4[A1, A2, A3, A4]] {
+ override def toString = "Tuple4[" + _1 + ", " + _2 + ", " + _3 + ", " + _4 + "]"
+ }
+ @serializable
+ case class Tuple5Rep[A1, A2, A3, A4, A5](_1: TypeRep[A1], _2: TypeRep[A2], _3: TypeRep[A3], _4: TypeRep[A4], _5: TypeRep[A5]) extends TypeRep[Tuple5[A1, A2, A3, A4, A5]] {
+ override def toString = "Tuple5[" + _1 + ", " + _2 + ", " + _3 + ", " + _4 + ", " + _5 + "]"
+ }
+ @serializable
+ case class Tuple6Rep[A1, A2, A3, A4, A5, A6](val _1: TypeRep[A1], val _2: TypeRep[A2], val _3: TypeRep[A3], val _4: TypeRep[A4], val _5: TypeRep[A5], val _6: TypeRep[A6]) extends TypeRep[Tuple6[A1, A2, A3, A4, A5, A6]] {
+ override def toString = "Tuple6[" + _1 + ", " + _2 + ", " + _3 + ", " + _4 + ", " + _5 + ", " + _6 + "]"
+ }
+ @serializable
+ case class Tuple7Rep[A1, A2, A3, A4, A5, A6, A7](val _1: TypeRep[A1], val _2: TypeRep[A2], val _3: TypeRep[A3], val _4: TypeRep[A4], val _5: TypeRep[A5], val _6: TypeRep[A6], val _7: TypeRep[A7]) extends TypeRep[Tuple7[A1, A2, A3, A4, A5, A6, A7]] {
+ override def toString = "Tuple7[" + _1 + ", " + _2 + ", " + _3 + ", " + _4 + ", " + _5 + ", " + _6 + ", " + _7 + "]"
+ }
+ @serializable
+ case class Tuple8Rep[A1, A2, A3, A4, A5, A6, A7, A8](val _1: TypeRep[A1], val _2: TypeRep[A2], val _3: TypeRep[A3], val _4: TypeRep[A4], val _5: TypeRep[A5], val _6: TypeRep[A6], val _7: TypeRep[A7], val _8: TypeRep[A8]) extends TypeRep[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] {
+ override def toString = "Tuple8[" + _1 + ", " + _2 + ", " + _3 + ", " + _4 + ", " + _5 + ", " + _6 + ", " + _7 + ", " + _8 + "]"
+ }
+ @serializable
+ case class Tuple9Rep[A1, A2, A3, A4, A5, A6, A7, A8, A9](val _1: TypeRep[A1], val _2: TypeRep[A2], val _3: TypeRep[A3], val _4: TypeRep[A4], val _5: TypeRep[A5], val _6: TypeRep[A6], val _7: TypeRep[A7], val _8: TypeRep[A8], val _9: TypeRep[A9]) extends TypeRep[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] {
+ override def toString = "Tuple9[" + _1 + ", " + _2 + ", " + _3 + ", " + _4 + ", " + _5 + ", " + _6 + ", " + _7 + ", " + _8 + ", " + _9 + "]"
+ }
+
+ @serializable
+ case class Function1Rep[A1, B](a1: TypeRep[A1], b: TypeRep[B]) extends TypeRep[Function1[A1, B]] {
+ override def toString = "Function1[" + a1 + ", " + b + "]"
+ }
+ @serializable
+ case class Function2Rep[A1, A2, B](a1: TypeRep[A1], a2: TypeRep[A2], b: TypeRep[B]) extends TypeRep[Function2[A1, A2, B]] {
+ override def toString = "Function2[" + a1 + ", " + a2 + ", " + b + "]"
+ }
+ @serializable
+ case class Function3Rep[A1, A2, A3, B](a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], b: TypeRep[B]) extends TypeRep[Function3[A1, A2, A3, B]] {
+ override def toString = "Function3[" + a1 + ", " + a2 + ", " + a3 + ", " + b + "]"
+ }
+ @serializable
+ case class Function4Rep[A1, A2, A3, A4, B](a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], b: TypeRep[B]) extends TypeRep[Function4[A1, A2, A3, A4, B]] {
+ override def toString = "Function4[" + a1 + ", " + a2 + ", " + a3 + ", " + a4 + ", " + b + "]"
+ }
+ @serializable
+ case class Function5Rep[A1, A2, A3, A4, A5, B](a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], b: TypeRep[B]) extends TypeRep[Function5[A1, A2, A3, A4, A5, B]] {
+ override def toString = "Function5[" + a1 + ", " + a2 + ", " + a3 + ", " + a4 + ", " + a5 + ", " + b + "]"
+ }
+ @serializable
+ case class Function6Rep[A1, A2, A3, A4, A5, A6, B](a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], b: TypeRep[B]) extends TypeRep[Function6[A1, A2, A3, A4, A5, A6, B]] {
+ override def toString = "Function6[" + a1 + ", " + a2 + ", " + a3 + ", " + a4 + ", " + a5 + ", " + a6 + ", " + b + "]"
+ }
+ @serializable
+ case class Function7Rep[A1, A2, A3, A4, A5, A6, A7, B](a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], a7: TypeRep[A7], b: TypeRep[B]) extends TypeRep[Function7[A1, A2, A3, A4, A5, A6, A7, B]] {
+ override def toString = "Function7[" + a1 + ", " + a2 + ", " + a3 + ", " + a4 + ", " + a5 + ", " + a6 + ", " + a7 + ", " + b + "]"
+ }
+ @serializable
+ case class Function8Rep[A1, A2, A3, A4, A5, A6, A7, A8, B](a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], a7: TypeRep[A7], a8: TypeRep[A8], b: TypeRep[B]) extends TypeRep[Function8[A1, A2, A3, A4, A5, A6, A7, A8, B]] {
+ override def toString = "Function8[" + a1 + ", " + a2 + ", " + a3 + ", " + a4 + ", " + a5 + ", " + a6 + ", " + a7 + ", " + a8 + b + "]"
+ }
+ @serializable
+ case class Function9Rep[A1, A2, A3, A4, A5, A6, A7, A8, A9, B](a1: TypeRep[A1], a2: TypeRep[A2], a3: TypeRep[A3], a4: TypeRep[A4], a5: TypeRep[A5], a6: TypeRep[A6], a7: TypeRep[A7], a8: TypeRep[A8], a9: TypeRep[A9], b: TypeRep[B]) extends TypeRep[Function9[A1, A2, A3, A4, A5, A6, A7, A8, A9, B]] {
+ override def toString = "Function9[" + a1 + ", " + a2 + ", " + a3 + ", " + a4 + ", " + a5 + ", " + a6 + ", " + a7 + ", " + a8 + ", " + b + "]"
+ }
+/*
+ @serializable
+ case class ObjectRep[A](c: Class) extends TypeRep[A] {
+ override def toString = c.getName
+ }
+*/
+}
+
diff --git a/test/files/neg/bug414.check b/test/files/neg/bug414.check
index 67b467ce5d..3396a803f1 100644
--- a/test/files/neg/bug414.check
+++ b/test/files/neg/bug414.check
@@ -1,4 +1,6 @@
-bug414.scala:5: error: stable identifier required, but Empty found.
+bug414.scala:5: error: pattern type is incompatibe with expected type;
+ found : object Empty
+ required: IntMap[a]
case Empty =>
^
bug414.scala:7: error: type mismatch;
diff --git a/test/files/neg/bug692.check b/test/files/neg/bug692.check
index 6eb9f7d8af..308048b80a 100644
--- a/test/files/neg/bug692.check
+++ b/test/files/neg/bug692.check
@@ -2,7 +2,7 @@ bug692.scala:3: error: not found: type T
trait Type[T0] extends Type0[T];
^
bug692.scala:10: error: class Foo takes type parameters
- case class FooType extends ClassType[Foo,AnyRef](ObjectType);
+ case class FooType extends ClassType[Foo,AnyRef](ObjectType());
^
bug692.scala:13: error: class Foo takes type parameters
case class BarType[T3 <: Foo](tpeT : RefType[T3]) extends ClassType[Bar[T3],Foo](FooType);
diff --git a/test/files/neg/bug692.scala b/test/files/neg/bug692.scala
index dc5a9040a0..184a14b4b6 100644
--- a/test/files/neg/bug692.scala
+++ b/test/files/neg/bug692.scala
@@ -7,7 +7,7 @@ abstract class test3 {
abstract class ClassType[C <: Z, Z <: AnyRef](zuper : RefType[Z]) extends RefType[C];
- case class FooType extends ClassType[Foo,AnyRef](ObjectType);
+ case class FooType extends ClassType[Foo,AnyRef](ObjectType());
implicit def typeOfFoo = FooType();
case class BarType[T3 <: Foo](tpeT : RefType[T3]) extends ClassType[Bar[T3],Foo](FooType);
diff --git a/test/files/neg/bug783.check b/test/files/neg/bug783.check
index a7f978ad06..19e3ead2a9 100644
--- a/test/files/neg/bug783.check
+++ b/test/files/neg/bug783.check
@@ -1,4 +1,6 @@
-bug783.scala:12: error: stable identifier required, but Contexts.this.globalInit0 found.
+bug783.scala:12: error: type mismatch;
+ found : Contexts.this.Global#Template
+ required: Contexts.this.global.Template
globalInit0.Template(10, 20);
- ^
+ ^
one error found
diff --git a/test/files/neg/bug960.check b/test/files/neg/bug960.check
index c947223aa3..e61394f2d0 100644
--- a/test/files/neg/bug960.check
+++ b/test/files/neg/bug960.check
@@ -1,4 +1,7 @@
-bug960.scala:18: error: cannot resolve overloaded unapply
+bug960.scala:18: error: ambiguous reference to overloaded definition,
+both method unapply in object List of type [a](List[a])Option[Null]
+and method unapply in object List of type [a](List[a])Option[(a, List[a])]
+match argument types (List[a])
case List(x, xs) => 7
^
bug960.scala:12: error: method unapply is defined twice
diff --git a/test/files/neg/bug961.scala b/test/files/neg/bug961.scala
index eb1620abe1..15309b96b4 100755
--- a/test/files/neg/bug961.scala
+++ b/test/files/neg/bug961.scala
@@ -2,7 +2,7 @@ object Temp{
abstract class A
object B{
private case class B_inner extends A
- def apply: A = B_inner
+ def apply: A = B_inner()
def unapply(a: A) = a match {
case B_inner() => true
case _ => false
diff --git a/test/files/neg/scopes.check b/test/files/neg/scopes.check
index 13f728b01c..bb8e15058b 100644
--- a/test/files/neg/scopes.check
+++ b/test/files/neg/scopes.check
@@ -22,4 +22,9 @@ scopes.scala:15: error: x is already defined as value x
scopes.scala:17: error: x is already defined as value x
case x::x => x
^
-8 errors found
+scopes.scala:1: error: type mismatch;
+ found : float
+ required: int
+case class test0(x: int, x: float)
+ ^
+9 errors found
diff --git a/test/files/pos/bug432.scala b/test/files/pos/bug432.scala
new file mode 100644
index 0000000000..8e3097ac9d
--- /dev/null
+++ b/test/files/pos/bug432.scala
@@ -0,0 +1,2 @@
+case class Tata
+object Tata
diff --git a/test/files/run/caseclasses.check b/test/files/run/caseclasses.check
index d86bac9de5..7eb54ea631 100644
--- a/test/files/run/caseclasses.check
+++ b/test/files/run/caseclasses.check
@@ -1 +1,3 @@
OK
+creating C(hi)
+OK
diff --git a/test/files/run/caseclasses.scala b/test/files/run/caseclasses.scala
index 72a7232d8a..8cba990114 100644
--- a/test/files/run/caseclasses.scala
+++ b/test/files/run/caseclasses.scala
@@ -2,6 +2,16 @@ case class Foo(x: int)(y: int);
case class Bar;
+object M {
+ abstract case class C(x: String) {}
+ object C extends (String => C) {
+ def apply(x: String): C = {
+ println("creating C("+x+")")
+ new C(x) {}
+ }
+ }
+}
+
object Test extends Application {
def fn[a,b](x: a => b) = x;
@@ -18,6 +28,11 @@ object Test extends Application {
case x:IndexOutOfBoundsException =>
}
+ M.C("hi") match {
+ case M.C("hi") => println("OK")
+ case _ => println("NO")
+ }
+
try {
f(2) productElement 3
throw new NullPointerException("duh")
diff --git a/test/pending/run/classof.check b/test/files/run/classof.check
index e9a8fd6b76..e9a8fd6b76 100644
--- a/test/pending/run/classof.check
+++ b/test/files/run/classof.check
diff --git a/test/pending/run/classof.scala b/test/files/run/classof.scala
index b547e5c8c3..5c920d797f 100644..100755
--- a/test/pending/run/classof.scala
+++ b/test/files/run/classof.scala
@@ -2,7 +2,7 @@ class SomeClass
object Test {
def main(args: Array[String]): Unit = {
- val cls: Class[SomeClass] = classOf[SomeClass]
+ val cls: Predef.Class[SomeClass] = classOf[SomeClass]
Console.println(cls.getName())
}
}
diff --git a/test/files/run/bug874.scala b/test/pending/run/bug874.scala
index 945a5bf620..29dfabe0e9 100644..100755
--- a/test/files/run/bug874.scala
+++ b/test/pending/run/bug874.scala
@@ -1,22 +1,17 @@
object Test {
abstract class Base {
- type T;
- def T : T;
- def U[A](x1: A)(x2: int): Any
- T;
+ val U: {
+ def apply[A](x1: A)(x2: int): Any
+ }
U("xyz")(2)
}
class Mix extends Base {
- case class T {
- Console.println("T created")
- }
case class U[A](x1: A)(x2: int) {
Console.println("U created with "+x1+" and "+x2)
}
}
def main(args : Array[String]) : Unit = {
val obvious: Base = new Mix;
- obvious.T
obvious.U("abc")(1)
}
}