summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McDirmid <sean.mcdirmid@gmail.com>2007-10-19 12:53:52 +0000
committerSean McDirmid <sean.mcdirmid@gmail.com>2007-10-19 12:53:52 +0000
commita49cbca4e93d573b0687023d3458bb8a1473e463 (patch)
tree8eb31f12568cad9e1d08a15b5d17024ad5edcc27
parent7305b72eb8b11872613801b3ce5130b30e362a2d (diff)
downloadscala-a49cbca4e93d573b0687023d3458bb8a1473e463.tar.gz
scala-a49cbca4e93d573b0687023d3458bb8a1473e463.tar.bz2
scala-a49cbca4e93d573b0687023d3458bb8a1473e463.zip
* Fixed array cast bug in Errasure.
* Tweaked GenerateIDEs to have more coverage * Deprecated * in favor of ** for sets
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala23
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala27
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala1
-rw-r--r--src/library/scala/collection/jcl/ArrayList.scala18
-rw-r--r--src/library/scala/collection/jcl/Buffer.scala25
-rw-r--r--src/library/scala/collection/jcl/BufferIterator.scala1
-rw-r--r--src/library/scala/collection/jcl/MutableIterable.scala2
-rw-r--r--src/library/scala/collection/jcl/Set.scala6
-rw-r--r--src/library/scala/collection/mutable/Map.scala1
-rw-r--r--src/library/scala/runtime/ScalaRunTime.scala2
-rw-r--r--test/files/run/array_casts.check16
-rw-r--r--test/files/run/array_casts.scala42
15 files changed, 133 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index c9dc436b6d..04bc33e043 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -103,7 +103,10 @@ trait Definitions {
def Iterable_hasNext = getMember(IterableClass, nme.hasNext)
lazy val IteratorClass: Symbol = getClass("scala.Iterator")
lazy val SeqClass: Symbol = getClass("scala.Seq")
- def Seq_length = getMember(SeqClass, nme.length)
+ lazy val RandomAccessSeqMutableClass: Symbol = getMember(getModule("scala.RandomAccessSeq"), nme.Mutable)
+ def Seq_length = getMember(SeqClass, nme.length)
+
+
lazy val ListClass: Symbol = getClass("scala.List")
def List_isEmpty = getMember(ListClass, nme.isEmpty)
def List_head = getMember(ListClass, nme.head)
diff --git a/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala b/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala
index a137ed7490..0aa900529a 100644
--- a/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala
+++ b/src/compiler/scala/tools/nsc/symtab/GenerateIdeMaps.scala
@@ -335,7 +335,23 @@ abstract class GenerateIdeMaps extends SubComponent {
dup.tpe = tree.tpe
f(dup)
} else f(tree.ref)
- case tree : SelectFromTypeTree => f(tree.qualifier)
+ case tree : CompoundTypeTree => f(tree.templ)
+ case tree : Template => fs(tree.parents); f(tree.self); fs(tree.body)
+ case tree : SelectFromTypeTree => {
+ if (tree.qualifier.tpe == null) tree.tpe match {
+ case tpe : TypeRef =>
+ // give it a type!
+ tree.qualifier.tpe = tpe.prefix
+ case _ =>
+ // tree.tpe.pre
+ }
+ f(tree.qualifier)
+ }
+ case tree : Literal =>
+ if (tree.tpe != null && tree.tpe.typeSymbol == definitions.ClassClass) {
+ // nothing we can do without original tree.
+ }
+
case tree : Typed => f(tree.expr); f(tree.tpt)
case tree : Block => fs(tree.stats); f(tree.expr)
case tree: CaseDef => f(tree.pat);f(tree.guard);f(tree.body)
@@ -392,8 +408,9 @@ abstract class GenerateIdeMaps extends SubComponent {
if (sym.linkedModuleOfClass eq NoSymbol) {
if (isRoot(sym.owner)) {
return sym.name.toString
- }
- throw new Error(sym + " " + sym.moduleClass + " " + sym.isPackage + " " + sym.owner)
+ } else if (sym.owner != NoSymbol) return sym2url(sym.owner) + "." + sym.name.toString
+ Console.println("XXX: " + sym + " " + sym.moduleClass + " " + sym.isPackage + " " + sym.owner)
+ return sym.name.toString
}
return sym2url(sym.linkedModuleOfClass)
}
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index ed3348e838..105a6466d4 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -296,6 +296,7 @@ trait StdNames {
val lengthCompare = newTermName("lengthCompare")
val lift_ = newTermName("lift")
val map = newTermName("map")
+ val Mutable = newTypeName("Mutable")
val n = newTermName("n")
val ne = newTermName("ne")
val nobinding = newTermName("nobinding")
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 6031aeec16..06209194b7 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -330,7 +330,9 @@ abstract class ClassfileParser {
val c = pool.getClassSymbol(in.nextChar)
if (c != clazz) {
assert(true)
- throw new IOException("class file '" + in.file + "' contains wrong " + c)
+ if (inIDE) {
+ Console.println("WRONG CLASS: expected: " + clazz + " found " + c)
+ } else throw new IOException("class file '" + in.file + "' contains wrong " + c)
}
val superType = if (isAnnotation) { in.nextChar; definitions.AnnotationClass.tpe }
else pool.getSuperClass(in.nextChar).tpe
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index a2575e59ad..8e6e315f7d 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -180,6 +180,11 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
private def isSeqClass(sym: Symbol) =
(SeqClass isNonBottomSubClass sym) && (sym != ObjectClass)
+ /** Decides if sym is a supertype of array, right now that includes
+ from RandomAccessSeq.Mutable */
+ private def isArraySuper(sym: Symbol) =
+ (RandomAccessSeqMutableClass isNonBottomSubClass sym) //&& (sym != ObjectClass)
+
// -------- boxing/unboxing --------------------------------------------------------
override def newTyper(context: Context) = new Eraser(context)
@@ -277,8 +282,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
private def cast(tree: Tree, pt: Type): Tree = {
assert(pt eq pt.normalize)
- if (tree.tpe.typeSymbol == ObjectClass) {
- if (pt.typeSymbol == ArrayClass)
+ if (isArraySuper(tree.tpe.typeSymbol)) { // == ObjectClass) {
+ if (pt.typeSymbol == ArrayClass) {
typed {
atPos(tree.pos) {
gen.evalOnce(tree, context.owner, context.unit) { x =>
@@ -295,7 +300,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
}
}
}
- else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass)
+ } else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass) {
typed {
atPos(tree.pos) {
gen.evalOnce(tree, context.owner, context.unit) { x =>
@@ -312,7 +317,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
}
}
}
- else if (isSeqClass(pt.typeSymbol))
+ } else if (isArraySuper(pt.typeSymbol)) {
typed {
atPos(tree.pos) {
gen.evalOnce(tree, context.owner, context.unit) { x =>
@@ -329,7 +334,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
}
}
}
- else gen.mkAttributedCast(tree, pt)
+ } else gen.mkAttributedCast(tree, pt)
} else gen.mkAttributedCast(tree, pt)
}
@@ -439,16 +444,18 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
val qual1 = typedQualifier(qual)
val qualClass = qual1.tpe.typeSymbol
val targClass = targ.tpe.typeSymbol
+
/*
if (isNumericValueClass(qualClass) && isNumericValueClass(targClass))
// convert numeric type casts
atPos(tree.pos)(Apply(Select(qual1, "to" + targClass.name), List()))
else
*/
+ assert(true)
if (isValueType(targClass) ||
(targClass == ArrayClass && (qualClass isNonBottomSubClass BoxedArrayClass)))
unbox(qual1, targ.tpe)
- else if (targClass == ArrayClass && qualClass == ObjectClass || isSeqClass(targClass))
+ else if (((targClass == ArrayClass || isArraySuper(targClass)) && isArraySuper(qualClass)))
cast(qual1, targ.tpe)
else
tree
@@ -825,7 +832,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
}
}
case _ =>
- if (isSeqClass(targ.tpe.typeSymbol)) {
+ if (isArraySuper(targ.tpe.typeSymbol)) {
atPos(tree.pos) {
gen.evalOnce(qual, currentOwner, unit) { q =>
gen.mkOr(
@@ -835,6 +842,12 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
})
}
}
+ } else if (isArraySuper(qual.tpe.typeSymbol) && targ.tpe.typeSymbol == ArrayClass) {
+ gen.evalOnce(qual, currentOwner, unit) { q =>
+ atPos(tree.pos) {
+ Apply(gen.mkAttributedRef(isArrayMethod), List(q()))
+ }
+ }
} else tree
}
case _ => tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ef07b183f3..9737cc906b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3036,6 +3036,7 @@ trait Typers { self: Analyzer =>
result
} catch {
case ex: TypeError =>
+ if (inIDE) throw ex
tree.tpe = null
//Console.println("caught "+ex+" in typed");//DEBUG
reportTypeError(tree.pos, ex)
diff --git a/src/library/scala/collection/jcl/ArrayList.scala b/src/library/scala/collection/jcl/ArrayList.scala
index 2b433cd059..166dcc7314 100644
--- a/src/library/scala/collection/jcl/ArrayList.scala
+++ b/src/library/scala/collection/jcl/ArrayList.scala
@@ -14,22 +14,6 @@ package scala.collection.jcl;
*
* @author Sean McDirmid
*/
-class ArrayList[A](override val underlying : java.util.ArrayList) extends RandomAccessSeq.Mutable[A] with BufferWrapper[A] {
+class ArrayList[A](override val underlying : java.util.ArrayList) extends BufferWrapper[A] {
def this() = this(new java.util.ArrayList);
- override def elements = super[BufferWrapper].elements;
-
- trait Projection0[A] extends MutableSeq.Projection[A] with RandomAccessSeq.Projection[A] {
- override def projection : Projection0[A] = this
- override def elements : SeqIterator[Int,A] = new DefaultSeqIterator
-
- protected class MapProjection[B](f : A => B) extends super.MapProjection[B](f) with Projection0[B] {
- override def projection = this
- }
- override def map[B](f: A => B) : Projection0[B] = new MapProjection[B](f)
- }
- class Projection extends Buffer.Projection[A] with RandomAccessSeq.MutableProjection[A] with Projection0[A] {
- override def elements : BufferIterator[Int,A] = new DefaultBufferIterator
- override def projection : Projection = this
- }
- override def projection : Projection = new Projection
}
diff --git a/src/library/scala/collection/jcl/Buffer.scala b/src/library/scala/collection/jcl/Buffer.scala
index d6dd45c501..a0a3348d0a 100644
--- a/src/library/scala/collection/jcl/Buffer.scala
+++ b/src/library/scala/collection/jcl/Buffer.scala
@@ -14,7 +14,7 @@ package scala.collection.jcl;
*
* @author Sean McDirmid
*/
-trait Buffer[A] extends Ranged[Int,A] with MutableSeq[A] with Collection[A] {
+trait Buffer[A] extends RandomAccessSeq.Mutable[A] with Ranged[Int,A] with MutableSeq[A] with Collection[A] {
final protected type SortedSelf = Buffer[A];
override def projection : Buffer.Projection[A] = new Buffer.Projection[A] {
@@ -200,13 +200,26 @@ trait Buffer[A] extends Ranged[Int,A] with MutableSeq[A] with Collection[A] {
}
}
}
- def replace(startOffset : Int, length : Int, added : Iterable[A]) : Unit = {
-
+ /*
+ protected class Map[B](f : A => B) extends super.Map[B](f) with Buffer.Projection[B] {
+ override def elements = Buffer.this.elements.map[B](f);
+ //override def apply(idx : Int) = f(MutableSeq.this.apply(idx));
+ //override def size = length;
}
-
+ */
}
object Buffer {
- trait Projection[A] extends MutableSeq.Projection[A] with Collection.Projection[A] with Buffer[A] {
- override def projection = this
+ trait Projection0[A] extends MutableSeq.Projection[A] with RandomAccessSeq.Projection[A] {
+ override def projection : Projection0[A] = this
+ override def elements : SeqIterator[Int,A] = new DefaultSeqIterator
+
+ protected class MapProjection[B](f : A => B) extends super.MapProjection[B](f) with Projection0[B] {
+ override def projection = this
+ }
+ override def map[B](f: A => B) : Projection0[B] = new MapProjection[B](f)
+ }
+ class Projection[A] extends Collection.Projection[A] with RandomAccessSeq.MutableProjection[A] with Projection0[A] with Buffer[A] {
+ override def elements : BufferIterator[Int,A] = new DefaultBufferIterator
+ override def projection : Buffer.Projection[A] = this
}
}
diff --git a/src/library/scala/collection/jcl/BufferIterator.scala b/src/library/scala/collection/jcl/BufferIterator.scala
index 3faeb0b354..bb7b79d099 100644
--- a/src/library/scala/collection/jcl/BufferIterator.scala
+++ b/src/library/scala/collection/jcl/BufferIterator.scala
@@ -28,5 +28,4 @@ trait BufferIterator[K,A] extends SeqIterator[K,A] {
* If previous was last called, "a" is inserted before the element returned.
*/
def add(a: A): Unit;
-
}
diff --git a/src/library/scala/collection/jcl/MutableIterable.scala b/src/library/scala/collection/jcl/MutableIterable.scala
index 5683e6bd3e..0fed9954e5 100644
--- a/src/library/scala/collection/jcl/MutableIterable.scala
+++ b/src/library/scala/collection/jcl/MutableIterable.scala
@@ -42,7 +42,7 @@ trait MutableIterable[A] extends scala.Collection[A] {
def -(t : A) : this.type = { remove(t); this; }
/** retain only elements in the collection that predicate p is true for.
*/
- def retain(p : A => Boolean) : Unit = elements.retain(p);
+ def retainOnly(p : A => Boolean) : Unit = elements.retain(p);
/** retain only elements that are also in that.
*/
def retainAll(that : Iterable[A]) : Boolean = elements.retain(s => that.exists(t => t == s));
diff --git a/src/library/scala/collection/jcl/Set.scala b/src/library/scala/collection/jcl/Set.scala
index 604e647f52..85c5b11148 100644
--- a/src/library/scala/collection/jcl/Set.scala
+++ b/src/library/scala/collection/jcl/Set.scala
@@ -24,7 +24,7 @@ trait Set[A] extends scala.collection.mutable.Set[A] with Collection[A] {
override def --(i: Iterable[A]) : this.type = super[Collection].--(i)
override def +(t: A) : this.type = super[Collection].+(t)
override def -(t: A) : this.type = super[Collection].-(t)
- override def retain(f: A => Boolean) = super[Collection].retain(f)
+ override final def retain(f: A => Boolean) = retainOnly(f)
override def isEmpty = super[Collection].isEmpty
override def clear() = super.clear()
override def subsetOf(set : scala.collection.Set[A]) = set match {
@@ -46,8 +46,8 @@ trait Set[A] extends scala.collection.mutable.Set[A] with Collection[A] {
}
class Filter(pp : A => Boolean) extends super.Filter with Set.Projection[A] {
override def p(a : A) = pp(a)
- override def retain(p0 : A => Boolean): Unit =
- Set.this.retain(e => !p(e) || p0(e))
+ override def retainOnly(p0 : A => Boolean): Unit =
+ Set.this.retainOnly(e => !p(e) || p0(e))
override def add(a : A) = {
if (!p(a)) throw new IllegalArgumentException
else Set.this.add(a)
diff --git a/src/library/scala/collection/mutable/Map.scala b/src/library/scala/collection/mutable/Map.scala
index 1f065cb6eb..0b5504a5e8 100644
--- a/src/library/scala/collection/mutable/Map.scala
+++ b/src/library/scala/collection/mutable/Map.scala
@@ -202,6 +202,7 @@ trait Map[A, B] extends AnyRef
* <code>p</code> returns <code>true</code>.
*
* @param p The test predicate
+ * @deprecated cannot be type inferred because if retain in Iterable.
*/
def retain(p: (A, B) => Boolean): Unit = toList foreach {
case (key, value) => if (!p(key, value)) -=(key)
diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala
index 73e9bfa749..f631a2688a 100644
--- a/src/library/scala/runtime/ScalaRunTime.scala
+++ b/src/library/scala/runtime/ScalaRunTime.scala
@@ -28,7 +28,7 @@ object ScalaRunTime {
val DoubleTag = ".Double"
val BooleanTag = ".Boolean"
- def isArray(x: AnyRef): Boolean = x != null && x.getClass.isArray
+ def isArray(x: AnyRef): Boolean = (x != null && x.getClass.isArray) || (x != null && x.isInstanceOf[BoxedArray])
def isValueTag(tag: String) = tag.charAt(0) == '.'
def isValueClass(clazz: Class) = clazz.isPrimitive()
diff --git a/test/files/run/array_casts.check b/test/files/run/array_casts.check
new file mode 100644
index 0000000000..f7d3e5036c
--- /dev/null
+++ b/test/files/run/array_casts.check
@@ -0,0 +1,16 @@
+is object - true
+is seq - true
+is collection - true
+is random-access-seq - true
+is random-access-seq-mutable - true
+not string - true
+not list - true
+class [I
+Array(10)
+Array(10)
+Array(10)
+Array(10)
+Good, arrays are not lists
+Good, arrays are not rich strings
+is-seq array true
+class [I
diff --git a/test/files/run/array_casts.scala b/test/files/run/array_casts.scala
new file mode 100644
index 0000000000..9d298bbc2b
--- /dev/null
+++ b/test/files/run/array_casts.scala
@@ -0,0 +1,42 @@
+object Test {
+ val a = Array(10)
+ def main(args : Array[String]) : Unit = {
+ val a = this.a : AnyRef
+ Console.println("is object - " + a.isInstanceOf[Object])
+ Console.println("is seq - " + a.isInstanceOf[Seq[_]])
+ Console.println("is collection - " + a.isInstanceOf[Collection[_]])
+ Console.println("is random-access-seq - " + a.isInstanceOf[RandomAccessSeq[_]])
+ Console.println("is random-access-seq-mutable - " + a.isInstanceOf[RandomAccessSeq.Mutable[_]])
+ Console.println("not string - " + !a.isInstanceOf[String])
+ Console.println("not list - " + !a.isInstanceOf[List[_]])
+ try {
+ Console.println(a.asInstanceOf[Object].getClass)
+ } catch { case ex : ClassCastException => Console.println("Bad, arrays should be objects") }
+ try {
+ Console.println(a.asInstanceOf[Seq[_]])
+ } catch { case ex : ClassCastException => Console.println("Bad, arrays should be seqs") }
+ try {
+ Console.println(a.asInstanceOf[Collection[_]])
+ } catch { case ex : ClassCastException => Console.println("Bad, arrays should be collections") }
+ try {
+ Console.println(a.asInstanceOf[RandomAccessSeq[_]])
+ } catch { case ex : ClassCastException => Console.println("Bad, arrays should be random access seqs") }
+ try {
+ Console.println(a.asInstanceOf[RandomAccessSeq.Mutable[_]])
+ } catch { case ex : ClassCastException => Console.println("Bad, arrays should be mutable random access seqs") }
+ try {
+ Console.println("not expected: " + a.asInstanceOf[List[_]])
+ } catch { case ex : ClassCastException => Console.println("Good, arrays are not lists") }
+ try {
+ Console.println("not expected: " + a.asInstanceOf[runtime.RichString])
+ throw new Error("not expected")
+ } catch { case ex : ClassCastException => Console.println("Good, arrays are not rich strings") }
+ // check that arrays as seqs are still dynamically typed as arrays
+ val s = this.a : Seq[Int]
+ Console.println("is-seq array " + s.isInstanceOf[Array[Char]])
+ try {
+ Console.println(s.asInstanceOf[Array[Int]].getClass)
+ } catch { case ex : ClassCastException => Console.println("Bad, arrays as seqs should still be arrays of int") }
+ ()
+ }
+}