summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-04 11:23:16 -0800
committerPaul Phillips <paulp@improving.org>2012-02-04 11:30:31 -0800
commit6b8aed72e4f7a7135a434533399a772bf7078101 (patch)
treee5042a572ccdbdf85da2ef7b86bb2a79b2379d1b
parent2b7fb460dd1e666ed37ccba49a82aab959413c22 (diff)
downloadscala-6b8aed72e4f7a7135a434533399a772bf7078101.tar.gz
scala-6b8aed72e4f7a7135a434533399a772bf7078101.tar.bz2
scala-6b8aed72e4f7a7135a434533399a772bf7078101.zip
Made Any parents work more.
Working on type printing logic.
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala42
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala49
-rw-r--r--src/compiler/scala/reflect/internal/transform/Erasure.scala8
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala13
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala22
-rw-r--r--src/library/scala/AnyVal.scala8
-rw-r--r--src/library/scala/NotNull.scala2
10 files changed, 91 insertions, 67 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 47c711e81c..82d7f947e6 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -232,14 +232,15 @@ trait Definitions extends reflect.api.StandardDefinitions {
private var oldValueScheme = true
- lazy val AnyValClass = ScalaPackageClass.info member tpnme.AnyVal orElse {
-// println("new anyval")
- oldValueScheme = true
- val anyval = enterNewClass(ScalaPackageClass, tpnme.AnyVal, anyparam, 0L)
- val av_constr = anyval.newClassConstructor(NoPosition)
- anyval.info.decls enter av_constr
- anyval
- }
+ lazy val AnyValClass = ScalaPackageClass.info member tpnme.AnyVal
+// lazy val AnyValClass = ScalaPackageClass.info member tpnme.AnyVal orElse {
+// // println("new anyval")
+// oldValueScheme = true
+// val anyval = enterNewClass(ScalaPackageClass, tpnme.AnyVal, anyparam, 0L)
+// val av_constr = anyval.newClassConstructor(NoPosition)
+// anyval.info.decls enter av_constr
+// anyval
+// }
lazy val AnyVal_getClass = enterNewMethod(AnyValClass, nme.getClass_, Nil, getClassReturnType(AnyValClass.tpe))
// bottom types
@@ -722,6 +723,31 @@ trait Definitions extends reflect.api.StandardDefinitions {
}
}
+ /** Remove references to class Object (other than the head) in a list of parents */
+ def removeLaterObjects(tps: List[Type]): List[Type] = tps match {
+ case Nil => Nil
+ case x :: xs => x :: xs.filter(_.typeSymbol != ObjectClass)
+ }
+ /** Order a list of types with non-trait classes before others. */
+ def classesFirst(tps: List[Type]): List[Type] = {
+ val (classes, others) = tps partition (t => t.typeSymbol.isClass && !t.typeSymbol.isTrait)
+ if (classes.isEmpty || others.isEmpty || (tps startsWith classes)) tps
+ else classes ::: others
+ }
+ /** The following transformations applied to a list of parents.
+ * If any parent is a class/trait, all parents which are Object
+ * or an alias of it are discarded. Otherwise, all Objects other
+ * the head of the list are discarded.
+ */
+ def normalizedParents(parents: List[Type]): List[Type] = {
+ if (parents exists (t => (t.typeSymbol ne ObjectClass) && t.typeSymbol.isClass))
+ parents filterNot (_.typeSymbol eq ObjectClass)
+ else
+ removeLaterObjects(parents)
+ }
+ def parentsString(parents: List[Type]) =
+ normalizedParents(parents) mkString " with "
+
// members of class java.lang.{ Object, String }
lazy val Object_## = enterNewMethod(ObjectClass, nme.HASHHASH, Nil, inttype, FINAL)
lazy val Object_== = enterNewMethod(ObjectClass, nme.EQ, anyrefparam, booltype, FINAL)
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 3ed6544613..89664bad9f 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -410,6 +410,11 @@ trait Types extends api.Types { self: SymbolTable =>
* inherited by typerefs, singleton types, and refinement types,
* The empty list for all other types */
def parents: List[Type] = List()
+
+ /** For a class with nonEmpty parents, the first parent.
+ * Otherwise some specific fixed top type.
+ */
+ def firstParent = if (parents.nonEmpty) parents.head else ObjectClass.tpe
/** For a typeref or single-type, the prefix of the normalized type (@see normalize).
* NoType for all other types. */
@@ -1412,10 +1417,10 @@ trait Types extends api.Types { self: SymbolTable =>
// override def isNullable: Boolean =
// parents forall (p => p.isNullable && !p.typeSymbol.isAbstractType);
- override def safeToString: String =
- parents.mkString(" with ") +
+ override def safeToString: String = parentsString(parents) + (
(if (settings.debug.value || parents.isEmpty || (decls.elems ne null))
decls.mkString("{", "; ", "}") else "")
+ )
}
protected def defineBaseTypeSeqOfCompoundType(tpe: CompoundType) = {
@@ -1477,7 +1482,7 @@ trait Types extends api.Types { self: SymbolTable =>
else {
//Console.println("computing base classes of " + typeSymbol + " at phase " + phase);//DEBUG
// optimized, since this seems to be performance critical
- val superclazz = tpe.parents.head
+ val superclazz = tpe.firstParent
var mixins = tpe.parents.tail
val sbcs = superclazz.baseClasses
var bcs = sbcs
@@ -1524,7 +1529,7 @@ trait Types extends api.Types { self: SymbolTable =>
)
override def typeParams =
- if (isHigherKinded) parents.head.typeParams
+ if (isHigherKinded) firstParent.typeParams
else super.typeParams
//@M may result in an invalid type (references to higher-order args become dangling )
@@ -2142,12 +2147,12 @@ trait Types extends api.Types { self: SymbolTable =>
)
else ""
)
+
private def finishPrefix(rest: String) = (
if (sym.isPackageClass) packagePrefix + rest
else if (sym.isModuleClass) objectPrefix + rest
else if (!sym.isInitialized) rest
- else if (sym.isAnonymousClass && !phase.erasedTypes)
- thisInfo.parents.mkString("", " with ", refinementString)
+ else if (sym.isAnonymousClass && !phase.erasedTypes) parentsString(thisInfo.parents) + refinementString
else if (sym.isRefinementClass) "" + thisInfo
else rest
)
@@ -3225,11 +3230,21 @@ trait Types extends api.Types { self: SymbolTable =>
* comment or in the code?
*/
def intersectionType(tps: List[Type], owner: Symbol): Type = tps match {
- case List(tp) =>
- tp
- case _ =>
- refinedType(tps, owner)
-/*
+ case tp :: Nil => tp
+ case _ => refinedType(tps, owner)
+ }
+ /** A creator for intersection type where intersections of a single type are
+ * replaced by the type itself.
+ */
+ def intersectionType(tps: List[Type]): Type = tps match {
+ case tp :: Nil => tp
+ case _ => refinedType(tps, commonOwner(tps))
+ }
+
+/**** This implementation to merge parents was checked in in commented-out
+ form and has languished unaltered for five years. I think we should
+ use it or lose it.
+
def merge(tps: List[Type]): List[Type] = tps match {
case tp :: tps1 =>
val tps1a = tps1 filter (_.typeSymbol.==(tp.typeSymbol))
@@ -3244,14 +3259,6 @@ trait Types extends api.Types { self: SymbolTable =>
}
refinedType(merge(tps), owner)
*/
- }
-
- /** A creator for intersection type where intersections of a single type are
- * replaced by the type itself. */
- def intersectionType(tps: List[Type]): Type = tps match {
- case List(tp) => tp
- case _ => refinedType(tps, commonOwner(tps))
- }
/** A creator for type applications */
def appliedType(tycon: Type, args: List[Type]): Type =
@@ -4504,9 +4511,7 @@ trait Types extends api.Types { self: SymbolTable =>
else {
commonOwnerMap.clear()
tps foreach (commonOwnerMap traverse _)
- val result = if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol
- debuglog(tps.mkString("commonOwner(", ", ", ") == " + result))
- result
+ if (commonOwnerMap.result ne null) commonOwnerMap.result else NoSymbol
}
}
diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala
index 4775541855..7c360e1f25 100644
--- a/src/compiler/scala/reflect/internal/transform/Erasure.scala
+++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala
@@ -225,13 +225,7 @@ trait Erasure {
/** Type reference after erasure */
def erasedTypeRef(sym: Symbol): Type =
- typeRef(erasure(sym, sym.owner.tpe), sym, List())
-
- /** Remove duplicate references to class Object in a list of parent classes */
- private def removeLaterObjects(tps: List[Type]): List[Type] = tps match {
- case tp :: rest => tp :: (rest filter (_.typeSymbol != ObjectClass))
- case _ => tps
- }
+ typeRef(erasure(sym, sym.owner.tpe), sym, Nil)
/** The symbol's erased info. This is the type's erasure, except for the following symbols:
*
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 40e7d88a3b..8e5a0139a5 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -2753,19 +2753,18 @@ self =>
val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart
atPos(tstart0) {
- if (isPrimitiveType(name)) {
- Template(List(scalaDot(tpnme.AnyVal)), self, body)
- }
+ if (isPrimitiveType(name))
+ Template(List(scalaAnyValConstr), self, body)
else if (parents0 exists isReferenceToAnyVal) {
// @inline and other restrictions enforced in refchecks
Template(parents0, self, body)
}
- else if (name == tpnme.AnyVal) {
- Template(List(scalaDot(tpnme.Any)), self, body)
- }
else {
val parents = (
- if (parents0.isEmpty) List(scalaAnyRefConstr)
+ if (parents0.isEmpty) {
+ if (inScalaPackage && name == tpnme.AnyVal) List(scalaAnyConstr)
+ else List(scalaAnyRefConstr)
+ }
/*if (!isInterface(mods, body) && !isScalaArray(name))
parents0 /* :+ scalaScalaObjectConstr*/
else*/
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 906932f591..40389466e2 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -29,11 +29,13 @@ abstract class TreeBuilder {
def rootId(name: Name) = gen.rootId(name)
def rootScalaDot(name: Name) = gen.rootScalaDot(name)
def scalaDot(name: Name) = gen.scalaDot(name)
- def scalaAnyRefConstr = gen.scalaAnyRefConstr
- def scalaUnitConstr = gen.scalaUnitConstr
- def productConstr = gen.productConstr
+ def scalaAnyRefConstr = scalaDot(tpnme.AnyRef)
+ def scalaAnyValConstr = scalaDot(tpnme.AnyVal)
+ def scalaAnyConstr = scalaDot(tpnme.Any)
+ def scalaUnitConstr = scalaDot(tpnme.Unit)
+ def productConstr = scalaDot(tpnme.Product)
def productConstrN(n: Int) = scalaDot(newTypeName("Product" + n))
- def serializableConstr = gen.serializableConstr
+ def serializableConstr = scalaDot(tpnme.Serializable)
def convertToTypeName(t: Tree) = gen.convertToTypeName(t)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 30bfdbaf5b..efbfe4da41 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -714,7 +714,7 @@ abstract class Erasure extends AddInterfaces
var bridges: List[Tree] = List()
val opc = atPhase(currentRun.explicitouterPhase) {
new overridingPairs.Cursor(owner) {
- override def parents: List[Type] = List(owner.info.parents.head)
+ override def parents: List[Type] = List(owner.info.firstParent)
override def exclude(sym: Symbol): Boolean =
!sym.isMethod || sym.isPrivate || super.exclude(sym)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 3a3c244d1c..359e72e3e4 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -228,7 +228,7 @@ trait NamesDefaults { self: Analyzer =>
case Select(sp @ Super(_, _), _) if isConstr =>
// 'moduleQual' fixes #3207. selection of the companion module of the
// superclass needs to have the same prefix as the superclass.
- blockWithoutQualifier(moduleQual(baseFun.pos, sp.symbol.tpe.parents.head))
+ blockWithoutQualifier(moduleQual(baseFun.pos, sp.symbol.tpe.firstParent))
// self constructor calls (in secondary constructors)
case Select(tp, name) if isConstr =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index a20e78a81f..fdeab7b565 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1208,7 +1208,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val supertpt1 = typedType(supertpt)
if (!supertpt1.isErrorTyped) {
mixins = supertpt1 :: mixins
- supertpt = TypeTree(supertpt1.tpe.parents.head) setPos supertpt.pos.focus
+ supertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
}
}
if (supertpt.tpe.typeSymbol == AnyClass && firstParent.isTrait && firstParent != AnyValClass)
@@ -1302,12 +1302,15 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
else xs
)
}
+
fixDuplicates(supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(clazz, tpt))
}
catch {
case ex: TypeError =>
// fallback in case of cyclic errors
// @H none of the tests enter here but I couldn't rule it out
+ log("Type error calculating parents in template " + templ)
+ log("Error: " + ex)
ParentTypesError(templ, ex)
List(TypeTree(AnyRefClass.tpe))
}
@@ -1415,7 +1418,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
_.typedTemplate(cdef.impl, parentTypes(cdef.impl))
}
val impl2 = finishMethodSynthesis(impl1, clazz, context)
- if (clazz.isTrait && clazz.info.parents.nonEmpty && clazz.info.parents.head.typeSymbol == AnyClass)
+ if (clazz.isTrait && clazz.info.parents.nonEmpty && clazz.info.firstParent.typeSymbol == AnyClass)
for (stat <- impl2.body)
if (!treeInfo.isAllowedInAnyTrait(stat))
unit.error(stat.pos, "this statement is not allowed in trait extending from class Any: "+stat)
@@ -3670,16 +3673,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
- val owntype =
- if (mix.isEmpty) {
- if ((mode & SUPERCONSTRmode) != 0)
- if (clazz.info.parents.isEmpty) AnyRefClass.tpe // can happen due to cyclic references ==> #1036
- else clazz.info.parents.head
- else intersectionType(clazz.info.parents)
- } else {
- findMixinSuper(clazz.tpe)
- }
-
+ val owntype = (
+ if (!mix.isEmpty) findMixinSuper(clazz.tpe)
+ else if ((mode & SUPERCONSTRmode) != 0) clazz.info.firstParent
+ else intersectionType(clazz.info.parents)
+ )
treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype)
}
diff --git a/src/library/scala/AnyVal.scala b/src/library/scala/AnyVal.scala
index ed32fb7302..daad6f6f5e 100644
--- a/src/library/scala/AnyVal.scala
+++ b/src/library/scala/AnyVal.scala
@@ -25,8 +25,8 @@ package scala
* The ''integer types'' include the subrange types as well as [[scala.Int]] and [[scala.Long]].
* The ''floating point types'' are [[scala.Float]] and [[scala.Double]].
*/
-trait AnyVal extends NotNull {
-// disabled for now to make the standard build go through.
-// Once we have a new strap we can uncomment this and delete the AnyVal_getClass entry in Definitions.
-// def getClass(): Class[_ <: AnyVal] = ???
+trait AnyVal extends Any with NotNull {
+ // disabled for now to make the standard build go through.
+ // Once we have a new strap we can uncomment this and delete the AnyVal_getClass entry in Definitions.
+ def getClass(): Class[_ <: AnyVal] = ???
}
diff --git a/src/library/scala/NotNull.scala b/src/library/scala/NotNull.scala
index f90b95c789..64f999a932 100644
--- a/src/library/scala/NotNull.scala
+++ b/src/library/scala/NotNull.scala
@@ -12,4 +12,4 @@ package scala
* A marker trait for things that are not allowed to be null
* @since 2.5
*/
-trait NotNull {}
+trait NotNull extends Any {}