summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-21 20:57:27 +0000
committerPaul Phillips <paulp@improving.org>2009-10-21 20:57:27 +0000
commit7349476e5cf7984acf40055cb55d78cbaed41043 (patch)
tree527229fd0cdab2451fd9feabfcdef2730f9ec453 /src
parent322b823276a3f40db95bb3306c842021e77572df (diff)
downloadscala-7349476e5cf7984acf40055cb55d78cbaed41043.tar.gz
scala-7349476e5cf7984acf40055cb55d78cbaed41043.tar.bz2
scala-7349476e5cf7984acf40055cb55d78cbaed41043.zip
A selection of cleanups stemming from recent in...
A selection of cleanups stemming from recent investigations.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala15
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala27
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala65
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala6
-rw-r--r--src/library/scala/collection/immutable/Stream.scala4
8 files changed, 68 insertions, 55 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 7602696488..a2e30e0cd0 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1172,9 +1172,13 @@ trait Symbols {
*/
def mixinClasses: List[Symbol] = {
val sc = superClass
- info.baseClasses.tail.takeWhile(sc ne)
+ ancestors takeWhile (sc ne)
}
+ /** All directly or indirectly inherited classes.
+ */
+ def ancestors: List[Symbol] = info.baseClasses drop 1
+
/** The package containing this symbol, or NoSymbol if there
* is not one. */
def enclosingPackage: Symbol =
@@ -1308,18 +1312,15 @@ trait Symbols {
if (isClassConstructor) NoSymbol else matchingSymbol(ofclazz, ofclazz.thisType)
final def allOverriddenSymbols: List[Symbol] =
- if (owner.isClass && !owner.info.baseClasses.isEmpty)
- for { bc <- owner.info.baseClasses.tail
- val s = overriddenSymbol(bc)
- if s != NoSymbol } yield s
- else List()
+ if (!owner.isClass) Nil
+ else owner.ancestors map overriddenSymbol filter (_ != NoSymbol)
/** The virtual classes overridden by this virtual class (excluding `clazz' itself)
* Classes appear in linearization order (with superclasses before subclasses)
*/
final def overriddenVirtuals: List[Symbol] =
if (isVirtualTrait && hasFlag(OVERRIDE))
- this.owner.info.baseClasses.tail
+ this.owner.ancestors
.map(_.info.decl(name))
.filter(_.isVirtualTrait)
.reverse
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index a0afdeabaf..24c5493858 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -72,11 +72,11 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
apply(MethodType(List(), restpe))
case PolyType(tparams, restpe) =>
PolyType(tparams, apply(MethodType(List(), restpe)))
- case TypeRef(pre, sym, List(arg)) if (sym == ByNameParamClass) =>
+ case TypeRef(pre, ByNameParamClass, List(arg)) =>
apply(functionType(List(), arg))
- case TypeRef(pre, sym, args) if (sym == RepeatedParamClass) =>
+ case TypeRef(pre, RepeatedParamClass, args) =>
apply(appliedType(SeqClass.typeConstructor, args))
- case TypeRef(pre, sym, args) if (sym == JavaRepeatedParamClass) =>
+ case TypeRef(pre, JavaRepeatedParamClass, args) =>
apply(arrayType(
if (isUnboundedGeneric(args.head)) ObjectClass.tpe else args.head))
case _ =>
@@ -557,12 +557,11 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
inPattern = false
val fn1 = transform(fn)
inPattern = true
- val args1 = transformTrees(
- if (fn.symbol.name == nme.unapply)
- args
- else if (fn.symbol.name == nme.unapplySeq)
- transformArgs(tree.pos, fn.symbol, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe))
- else { assert(false,"internal error: UnApply node has wrong symbol"); null })
+ val args1 = transformTrees(fn.symbol.name match {
+ case nme.unapply => args
+ case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe))
+ case _ => Predef.error("internal error: UnApply node has wrong symbol")
+ })
treeCopy.UnApply(tree, fn1, args1)
case Apply(fn, args) =>
@@ -619,7 +618,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
} setType uncurryTreeType(tree.tpe)
def postTransform(tree: Tree): Tree = atPhase(phase.next) {
- def applyUnary(tree: Tree): Tree =
+ def applyUnary(): Tree =
if (tree.symbol.isMethod &&
(!tree.tpe.isInstanceOf[PolyType] || tree.tpe.typeParams.isEmpty)) {
if (!tree.tpe.isInstanceOf[MethodType]) tree.tpe = MethodType(List(), tree.tpe);
@@ -666,11 +665,9 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
treeCopy.Apply(tree, fn, args ::: args1)
case Ident(name) =>
assert(name != nme.WILDCARD_STAR.toTypeName)
- applyUnary(tree);
- case Select(qual, name) =>
- applyUnary(tree)
- case TypeApply(_, _) =>
- applyUnary(tree)
+ applyUnary()
+ case Select(_, _) | TypeApply(_, _) =>
+ applyUnary()
case Return(expr) if (tree.symbol != currentOwner.enclMethod || currentOwner.hasFlag(LAZY)) =>
if (settings.debug.value) log("non local return in "+tree.symbol+" from "+currentOwner.enclMethod)
atPos(tree.pos)(nonLocalReturnThrow(expr, tree.symbol))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 76e4818a72..54b24bf071 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -624,7 +624,7 @@ self: Analyzer =>
case TypeRef(pre, sym, args) if (!sym.isPackageClass) =>
if (sym.isClass && !sym.isRefinementClass && !sym.isAnonymousClass) {
if (addType(tp)) {
- for (bc <- sym.info.baseClasses.tail)
+ for (bc <- sym.ancestors)
getParts(tp.baseType(bc))
getParts(pre)
args foreach getParts
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 5b1ec93ffb..c619f08ce3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -374,7 +374,7 @@ abstract class RefChecks extends InfoTransform {
// 4. Check that every defined member with an `override' modifier overrides some other member.
for (member <- clazz.info.decls.toList)
if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) &&
- (clazz.info.baseClasses.tail forall {
+ (clazz.ancestors forall {
bc => member.matchingSymbol(bc, clazz.thisType) == NoSymbol
})) {
// for (bc <- clazz.info.baseClasses.tail) Console.println("" + bc + " has " + bc.info.decl(member.name) + ":" + bc.info.decl(member.name).tpe);//DEBUG
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 4fa66a242b..e3d75752f2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -226,7 +226,7 @@ trait SyntheticMethods extends ast.TreeDSL {
if (!phase.erasedTypes) try {
if (clazz hasFlag Flags.CASE) {
- val isTop = !(clazz.info.baseClasses.tail exists (_ hasFlag Flags.CASE))
+ val isTop = !(clazz.ancestors exists (_ hasFlag Flags.CASE))
// case classes are implicitly declared serializable
clazz addAnnotation AnnotationInfo(SerializableAttr.tpe, Nil, Nil)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 7307a0d379..b81c087901 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -879,23 +879,16 @@ trait Typers { self: Analyzer =>
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) &&
- !(clazz.info.baseClasses.tail exists (_ hasFlag CASE))) {
- if (!phase.erasedTypes) checkStable(tree) //todo: do we need to demand this?
+ val clazz = unapplyParameterType(unapply)
+
+ if ((unapply hasFlag CASE) && (clazz hasFlag CASE) && !(clazz.ancestors exists (_ 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
- }
+
+ inferConstructorInstance(tree1, clazz.typeParams, pt)
tree1
} else {
tree
@@ -1051,6 +1044,20 @@ trait Typers { self: Analyzer =>
typed(cbody)
}
+ private def validateNoCaseAncestor(clazz: Symbol) = {
+ // XXX I think this should issue a sharper warning of some kind like
+ // "change your code now!" as there are material bugs (which are very unlikely
+ // to be fixed) associated with case class inheritance.
+ if (!phase.erasedTypes) {
+ for (ancestor <- clazz.ancestors find (_ hasFlag CASE))
+ unit.deprecationWarning(clazz.pos, (
+ "case class `%s' has case class ancestor `%s'. This has been deprecated " +
+ "for unduly complicating both usage and implementation. You should instead " +
+ "use extractors for pattern matching on non-leaf nodes." ).format(clazz, ancestor)
+ )
+ }
+ }
+
def parentTypes(templ: Template): List[Tree] =
if (templ.parents.isEmpty) List()
else try {
@@ -1177,17 +1184,6 @@ trait Typers { self: Analyzer =>
if (psym hasFlag FINAL) {
error(parent.pos, "illegal inheritance from final "+psym)
}
- // XXX I think this should issue a sharper warning of some kind like
- // "change your code now!" as there are material bugs (which will not be fixed)
- // associated with case class inheritance.
- if ((context.owner hasFlag CASE) && !phase.erasedTypes) {
- for (ancestor <- parent.tpe.baseClasses find (_ hasFlag CASE))
- unit.deprecationWarning(parent.pos, (
- "case class `%s' has case class ancestor `%s'. This has been deprecated " +
- "for unduly complicating both usage and implementation. You should instead " +
- "use extractors for pattern matching on non-leaf nodes." ).format(context.owner, ancestor)
- )
- }
if (psym.isSealed && !phase.erasedTypes) {
if (context.unit.source.file != psym.sourceFile)
error(parent.pos, "illegal inheritance from sealed "+psym)
@@ -1435,6 +1431,9 @@ trait Typers { self: Analyzer =>
assert(clazz.info.decls != EmptyScope)
enterSyms(context.outer.make(templ, clazz, clazz.info.decls), templ.body)
validateParentClasses(parents1, selfType)
+ if (clazz hasFlag CASE)
+ validateNoCaseAncestor(clazz)
+
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass)
unit.error(clazz.pos, "inner classes cannot be classfile annotations")
if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
@@ -1897,7 +1896,7 @@ trait Typers { self: Analyzer =>
val stats1 = typedStats(stats, NoSymbol)
for (stat <- stats1 if stat.isDef) {
val member = stat.symbol
- if (!(context.owner.info.baseClasses.tail forall
+ if (!(context.owner.ancestors forall
(bc => member.matchingSymbol(bc, context.owner.thisType) == NoSymbol))) {
member setFlag OVERRIDE
}
@@ -3945,8 +3944,22 @@ trait Typers { self: Analyzer =>
typed(tree, EXPRmode | FUNmode | POLYmode | TAPPmode, WildcardType)
/** Types a pattern with prototype <code>pt</code> */
- def typedPattern(tree: Tree, pt: Type): Tree =
+ def typedPattern(tree: Tree, pt: Type): Tree = {
+ // The commented out code stems from investigation into whether
+ // "abc" match { case Seq('a', 'b', 'c') => true }
+ // can be ruled out statically. At present this is a runtime
+ // error both because there is an implicit from String to Seq
+ // (even though such implicits are not used by the matcher) and
+ // because the typer is fine with concluding that "abc" might
+ // be of type "String with Seq[T]" and thus eligible for a call
+ // to unapplySeq.
+ //
+ // val savedImplicitsEnabled = context.implicitsEnabled
+ // context.implicitsEnabled = false
+ // try
typed(tree, PATTERNmode, pt)
+ // finally context.implicitsEnabled = savedImplicitsEnabled
+ }
/** Types a (fully parameterized) type tree */
def typedType(tree: Tree, mode: Int): Tree =
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index b586298560..262e648e39 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -92,6 +92,12 @@ trait Unapplies extends ast.TreeDSL
case NoSymbol => tp member nme.unapplySeq
case unapp => unapp
}
+ /** returns unapply member's parameter type. */
+ def unapplyParameterType(extractor: Symbol) = {
+ val tps = extractor.tpe.paramTypes
+ if (tps.length == 1) tps.head.typeSymbol
+ else NoSymbol
+ }
def copyUntyped[T <: Tree](tree: T): T =
returning[T](UnTyper traverse _)(tree.duplicate)
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 9550aec2ef..1d9adeab1c 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -79,10 +79,6 @@ self =>
this
}
- /** Does this stream have more than one elements defined?
- */
- private def hasMoreThanOneElements = false
-
/** Prints elements of this stream one by one, separated by commas */
def print() { print(", ") }