summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-07-28 10:00:31 +0000
committerMartin Odersky <odersky@gmail.com>2008-07-28 10:00:31 +0000
commitd492b489b176a3d2a4da0d199756af86514be352 (patch)
treee5cf7bedfa037a03f0fbf1bb72564114473edef0
parentc8b3af98b9dd45a358332f60e3bc8f5b8b3c604a (diff)
downloadscala-d492b489b176a3d2a4da0d199756af86514be352.tar.gz
scala-d492b489b176a3d2a4da0d199756af86514be352.tar.bz2
scala-d492b489b176a3d2a4da0d199756af86514be352.zip
fixed #842, #945, #83, #996, #1016, + some perf...
fixed #842, #945, #83, #996, #1016, + some performace tuning.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala2
-rwxr-xr-xsrc/compiler/scala/tools/nsc/javac/JavaParsers.scala3
-rwxr-xr-xsrc/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala12
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala7
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala14
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala44
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala11
-rw-r--r--src/library/scala/util/matching/Regex.scala64
-rw-r--r--test/files/neg/t0764.check2
-rw-r--r--test/files/neg/t0842.check4
-rwxr-xr-xtest/files/neg/t0842.scala1
-rwxr-xr-xtest/files/pos/t0872.scala8
-rw-r--r--test/pending/pos/t0756.scala8
-rw-r--r--test/pending/pos/t0774/unrelated.scala9
-rw-r--r--test/pending/pos/t0805.scala9
-rwxr-xr-xtest/pending/run/t0508x.scala21
-rw-r--r--test/pending/run/t0818.scala4
18 files changed, 165 insertions, 67 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 8a96dfbb38..cbad27aea5 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -400,7 +400,7 @@ abstract class GenJVM extends SubComponent {
def addGenericSignature(jmember: JMember, sym: Symbol, tp: Type) {
if (settings.target.value == "jvm-1.5" && erasure.needsJavaSig(tp)) {
val sig = erasure.javaSig(tp)
- if (settings.verbose.value) println("add generic sig "+sym+":"+tp+" ==> "+sig)
+ if (settings.debug.value && settings.verbose.value) println("add generic sig "+sym+":"+tp+" ==> "+sig)
val buf = ByteBuffer.allocate(2)
buf.putShort(jmember.getConstantPool().addUtf8(sig).toShort)
addAttribute(jmember, nme.SignatureATTR, buf)
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 3e0f336b60..e187a07138 100755
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -564,8 +564,7 @@ trait JavaParsers extends JavaScanners {
in.nextToken
if (in.token == IDENTIFIER) { // if there's an ident after the comma ...
val name = ident()
- in.nextToken
- if (in.token == ASSIGN) { // ... followed by an `=', we know it's a real variable definition
+ if (in.token == ASSIGN || in.token == SEMI) { // ... followed by a `=' or `;', we know it's a real variable definition
buf ++= maybe
buf += varDecl(in.currentPos, mods, tpt.duplicate, name)
maybe.clear()
diff --git a/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala b/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala
index 8bc68d8ff1..c1c251c9bd 100755
--- a/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala
+++ b/src/compiler/scala/tools/nsc/symtab/BaseTypeSeqs.scala
@@ -87,7 +87,17 @@ trait BaseTypeSeqs {
/** Compute new base type sequence where every element is mapped
* with function `f'. Lazy types are mapped but not evaluated */
- def map(f: Type => Type): BaseTypeSeq = new BaseTypeSeq(parents, elems map f)
+ def map(f: Type => Type): BaseTypeSeq = {
+ // inlined `elems map f' for performance
+ val len = length
+ var arr = new Array[Type](len)
+ var i = 0
+ while (i < len) {
+ arr(i) = f(elems(i))
+ i += 1
+ }
+ new BaseTypeSeq(parents, arr)
+ }
def exists(p: Type => Boolean): Boolean = elems exists p
// (0 until length) exists (i => p(this(i)))
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 16eb6dd01b..de08a7ef66 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -181,14 +181,20 @@ trait StdNames {
val WILDCARD = newTermName("_")
val WILDCARD_STAR = newTermName("_*")
val COMPOUND_NAME = newTermName("<ct>")
+
val ANON_CLASS_NAME = newTermName("$anon")
+ val ANON_CLASS_NAME_tn = ANON_CLASS_NAME.toTypeName
val ANON_FUN_NAME = newTermName("$anonfun")
+ val ANON_FUN_NAME_tn = ANON_FUN_NAME.toTypeName
val REFINE_CLASS_NAME = newTermName("<refinement>")
+ val REFINE_CLASS_NAME_tn = REFINE_CLASS_NAME.toTypeName
val EMPTY_PACKAGE_NAME = newTermName("<empty>")
+ val EMPTY_PACKAGE_NAME_tn = EMPTY_PACKAGE_NAME.toTypeName
val IMPORT = newTermName("<import>")
val ZERO = newTermName("<zero>")
val STAR = newTermName("*")
val ROOT = newTermName("<root>")
+ val ROOT_tn = ROOT.toTypeName
val ROOTPKG = newTermName("_root_")
val REPEATED_PARAM_CLASS_NAME = newTermName("<repeated>")
val BYNAME_PARAM_CLASS_NAME = newTermName("<byname>")
@@ -336,6 +342,7 @@ trait StdNames {
val runtime = newTermName("runtime")
val sameElements = newTermName("sameElements")
val scala_ = newTermName("scala")
+ val scala_tn = scala_.toTypeName
val self = newTermName("self")
val synchronized_ = newTermName("synchronized")
val tag = newTermName("$tag")
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 1f4e9ec57e..ad3d99b680 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -388,7 +388,7 @@ trait Types {
*/
def asSeenFrom(pre: Type, clazz: Symbol): Type =
if (!isTrivial && (!phase.erasedTypes || pre.typeSymbol == ArrayClass)) {
- val m = new AsSeenFromMap(pre, clazz)
+ val m = new AsSeenFromMap(pre.normalize, clazz)
val tp = m apply this
existentialAbstraction(m.capturedParams, tp)
} else this
@@ -917,7 +917,7 @@ trait Types {
override def safeToString: String =
if (sym.isRoot) "<root>"
else if (sym.isEmptyPackageClass) "<empty>"
- else super.toString
+ else super.safeToString
override def narrow: Type = this
override def kind = "ThisType"
}
@@ -1746,7 +1746,7 @@ A type's typeSymbol should never be inspected directly.
val level = skolemizationLevel
def setInst(tp: Type) {
- assert(!(tp containsTp this), this)
+// assert(!(tp containsTp this), this)
constr.inst = tp
}
@@ -3073,14 +3073,6 @@ A type's typeSymbol should never be inspected directly.
sym
} else {
var rebind0 = pre.findMember(sym.name, BRIDGE, 0, true)(NoSymbol)
-/*
- if (rebind0 == NoSymbol && (sym hasFlag EXPANDEDNAME)) {
- // problem is that symbols with expanded names might be in the wrong hash bucket
- // in a previous scope. We account for that by re-creating the hash as a last attempt.
- sym.owner.info.decls.createHash()
- rebind0 = pre.findMember(sym.name, BRIDGE, 0, true)
- }
-*/
if (rebind0 == NoSymbol) { assert(false, ""+pre+"."+sym+" does no longer exist, phase = "+phase) }
/** The two symbols have the same fully qualified name */
def corresponds(sym1: Symbol, sym2: Symbol): Boolean =
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index ce98eac3ff..4da75b3e4f 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -707,29 +707,31 @@ abstract class ClassfileParser {
}
/** Parse and return a single annotation. If it is malformed,
- * throw an exception. If it contains a nested annotation,
- * return None.
+ * or it contains a nested annotation, return None.
*/
- def parseAnnotation(attrNameIndex: Char): Option[AnnotationInfo] = {
- val attrType = pool.getType(attrNameIndex)
- val nargs = in.nextChar
- val nvpairs = new ListBuffer[(Name,AnnotationArgument)]
- var nestedAnnot = false // if a nested annotation is seen,
- // then skip this annotation
- for (i <- 0 until nargs) {
- val name = pool.getName(in.nextChar)
- val argConst = parseTaggedConstant
- if (argConst.tag == AnnotationTag)
- nestedAnnot = true
- else
- nvpairs += ((name, new AnnotationArgument(argConst)))
- }
+ def parseAnnotation(attrNameIndex: Char): Option[AnnotationInfo] =
+ try {
+ val attrType = pool.getType(attrNameIndex)
+ val nargs = in.nextChar
+ val nvpairs = new ListBuffer[(Name,AnnotationArgument)]
+ var nestedAnnot = false // if a nested annotation is seen,
+ // then skip this annotation
+ for (i <- 0 until nargs) {
+ val name = pool.getName(in.nextChar)
+ val argConst = parseTaggedConstant
+ if (argConst.tag == AnnotationTag)
+ nestedAnnot = true
+ else
+ nvpairs += ((name, new AnnotationArgument(argConst)))
+ }
- if (nestedAnnot)
- None
- else
- Some(AnnotationInfo(attrType, List(), nvpairs.toList))
- }
+ if (nestedAnnot)
+ None
+ else
+ Some(AnnotationInfo(attrType, List(), nvpairs.toList))
+ } catch {
+ case ex: Throwable => None // ignore malformed annotations ==> t1135
+ }
/** Parse a sequence of annotations and attach them to the
* current symbol sym.
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 3bf2931a70..52e247db02 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -90,10 +90,15 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
apply(restpe)
case ExistentialType(tparams, restpe) =>
apply(restpe)
- case MethodType(formals, restpe) =>
+ case mt @ MethodType(formals, restpe) =>
MethodType(
formals map apply,
- if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) else apply(restpe))
+ if (restpe.typeSymbol == UnitClass)
+ erasedTypeRef(UnitClass)
+ else if (settings.Xexperimental.value)
+ apply(mt.resultType(formals)) // this gets rid of DeBruijnTypes
+ else
+ apply(restpe))
case RefinedType(parents, decls) =>
if (parents.isEmpty) erasedTypeRef(ObjectClass)
else apply(parents.head)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6974684ac2..d410bf6eee 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2963,10 +2963,10 @@ trait Typers { self: Analyzer =>
def typedAppliedTypeTree(tpt: Tree, args: List[Tree]) = {
val tpt1 = typed1(tpt, mode | FUNmode | TAPPmode, WildcardType)
- // @S: shouldn't be necessary now, fixed a problem with SimpleTypeProxy not relaying typeParams calls.
- // if (inIDE) tpt1.symbol.info // @S: seems like typeParams call doesn't force completion of symbol type in IDE.
if (tpt1.tpe.isError) {
setError(tree)
+ } else if (!tpt1.hasSymbol) {
+ errorTree(tree, tpt1.tpe+" does not take type parameters")
} else {
val tparams = tpt1.symbol.typeParams
if (tparams.length == args.length) {
@@ -3280,7 +3280,7 @@ trait Typers { self: Analyzer =>
tree.tpe = null
if (tree.hasSymbol) tree.symbol = NoSymbol
}
- //Console.println("typing "+tree+", "+context.undetparams);//DEBUG
+// Console.println("typing "+tree+", "+context.undetparams);//DEBUG
def dropExistential(tp: Type): Type = tp match {
case ExistentialType(tparams, tpe) =>
if (settings.debug.value) println("drop ex "+tree+" "+tp)
@@ -3291,14 +3291,13 @@ trait Typers { self: Analyzer =>
if (tp1 eq tp0) tp else tp1
case _ => tp
}
-// Console.println("typing "+tree+" at "+tree.pos);//DEBUG
var tree1 = if (tree.tpe ne null) tree else typed1(tree, mode, dropExistential(pt))
-// Console.println("typed "+tree1+":"+tree1.tpe+", "+context.undetparams);//DEBUG
+// Console.println("typed "+tree1+":"+tree1.tpe+", "+context.undetparams);//DEBUG
tree1.tpe = addAnnotations(tree1, tree1.tpe)
val result = if (tree1.isEmpty || (inIDE && tree1.tpe == null)) tree1 else adapt(tree1, mode, pt)
-// Console.println("adapted "+tree1+":"+tree1.tpe+" to "+pt+", "+context.undetparams);//DEBUG
+// Console.println("adapted "+tree1+":"+tree1.tpe+" to "+pt+", "+context.undetparams);//DEBUG
// if ((mode & TYPEmode) != 0) println("type: "+tree1+" has type "+tree1.tpe)
result
} catch {
diff --git a/src/library/scala/util/matching/Regex.scala b/src/library/scala/util/matching/Regex.scala
index 0db6372655..56c90f1073 100644
--- a/src/library/scala/util/matching/Regex.scala
+++ b/src/library/scala/util/matching/Regex.scala
@@ -132,41 +132,61 @@ object Regex {
/** The names of the groups, or some empty sequence if one defined */
val groupNames: Seq[String]
- /** The index of the first matched character */
+ /** The number of subgroups in the pattern (not all of these need to match!) */
+ def groupCount: Int
+
+ /** The index of the first matched character, or -1 if nothing was matched */
def start: Int
- /** The index of the first matched character in group <code>i</code> */
+ /** The index of the first matched character in group <code>i</code>,
+ * or -1 if nothing was matched for that group */
def start(i: Int): Int
- /** The index of the last matched character */
+ /** The index of the last matched character, or -1 if nothing was matched */
def end: Int
- /** The number of subgroups */
- def groupCount: Int
-
- /** The index following the last matched character in group <code>i</code> */
+ /** The index following the last matched character in group <code>i</code>,
+ * or -1 if nothing was matched for that group */
def end(i: Int): Int
- /** The matched string */
- def matched: String = source.subSequence(start, end).toString
+ /** The matched string,
+ * of <code>null</code> if nothing was matched */
+ def matched: String =
+ if (start >= 0) source.subSequence(start, end).toString
+ else null
- /** The matched string in group <code>i</code> */
- def group(i: Int): String = source.subSequence(start(i), end(i)).toString
+ /** The matched string in group <code>i</code>,
+ * or <code>null</code> if nothing was matched */
+ def group(i: Int): String =
+ if (start(i) >= 0) source.subSequence(start(i), end(i)).toString
+ else null
/** All matched subgroups, i.e. not including group(0) */
def subgroups: List[String] = (1 to groupCount).toList map group
- /** The char sequence before first character of match */
- def before: java.lang.CharSequence = source.subSequence(0, start)
-
- /** The char sequence before first character of match in group <code>i</code> */
- def before(i: Int): java.lang.CharSequence = source.subSequence(0, start(i))
-
- /** Returns char sequence after last character of match */
- def after: java.lang.CharSequence = source.subSequence(end, source.length)
-
- /** The char sequence after last character of match in group <code>i</code> */
- def after(i: Int): java.lang.CharSequence = source.subSequence(end(i), source.length)
+ /** The char sequence before first character of match,
+ * or <code>null</code> if nothing was matched */
+ def before: java.lang.CharSequence =
+ if (start >= 0) source.subSequence(0, start)
+ else null
+
+ /** The char sequence before first character of match in group <code>i</code>,
+ * or <code>null</code> if nothing was matched for that group */
+ def before(i: Int): java.lang.CharSequence =
+ if (start(i) >= 0) source.subSequence(0, start(i))
+ else null
+
+ /** Returns char sequence after last character of match,
+ * or <code>null</code> if nothing was matched */
+ def after: java.lang.CharSequence =
+ if (end >= 0) source.subSequence(end, source.length)
+ else null
+
+ /** The char sequence after last character of match in group <code>i</code>,
+ * or <code>null</code> if nothing was matched for that group */
+ def after(i: Int): java.lang.CharSequence =
+ if (end(i) >= 0) source.subSequence(end(i), source.length)
+ else null
private lazy val nameToIndex: Map[String, Int] = Map() ++ ("" :: groupNames.toList).zipWithIndex
diff --git a/test/files/neg/t0764.check b/test/files/neg/t0764.check
index b622f17c5e..9f0cedc69b 100644
--- a/test/files/neg/t0764.check
+++ b/test/files/neg/t0764.check
@@ -1,5 +1,5 @@
t0764.scala:13: error: type mismatch;
- found : java.lang.Object with Node{type T = _1.type} where val _1: Main.this.AType
+ found : java.lang.Object with Node{type T = _1.type} where val _1: Node{type T = NextType}
required: Node{type T = Main.this.AType}
new Main[AType]( (value: AType).prepend )
^
diff --git a/test/files/neg/t0842.check b/test/files/neg/t0842.check
new file mode 100644
index 0000000000..5f88f08194
--- /dev/null
+++ b/test/files/neg/t0842.check
@@ -0,0 +1,4 @@
+t0842.scala:1: error: A.this.type does not take type parameters
+trait A[T] { def m: this.type[T] = this }
+ ^
+one error found
diff --git a/test/files/neg/t0842.scala b/test/files/neg/t0842.scala
new file mode 100755
index 0000000000..f32c2ba26d
--- /dev/null
+++ b/test/files/neg/t0842.scala
@@ -0,0 +1 @@
+trait A[T] { def m: this.type[T] = this }
diff --git a/test/files/pos/t0872.scala b/test/files/pos/t0872.scala
new file mode 100755
index 0000000000..8f4c1c4436
--- /dev/null
+++ b/test/files/pos/t0872.scala
@@ -0,0 +1,8 @@
+object Main {
+ def main(args : Array[String]) {
+ val fn = (a : Int, str : String) => "a: " + a + ", str: " + str
+ implicit def fx[T](f : (T,String) => String) = (x:T) => f(x,null)
+ println(fn(1))
+ ()
+ }
+}
diff --git a/test/pending/pos/t0756.scala b/test/pending/pos/t0756.scala
new file mode 100644
index 0000000000..a778bd63d0
--- /dev/null
+++ b/test/pending/pos/t0756.scala
@@ -0,0 +1,8 @@
+object Test {
+ for {
+ n <- Some(42)
+
+ _
+ m <- Some(24)
+ } yield n
+}
diff --git a/test/pending/pos/t0774/unrelated.scala b/test/pending/pos/t0774/unrelated.scala
new file mode 100644
index 0000000000..1efdb2505e
--- /dev/null
+++ b/test/pending/pos/t0774/unrelated.scala
@@ -0,0 +1,9 @@
+object Outer {
+ import Inner._
+
+ deathname
+
+ object Inner {
+ def deathname: Int = 1
+ }
+}
diff --git a/test/pending/pos/t0805.scala b/test/pending/pos/t0805.scala
new file mode 100644
index 0000000000..565a2a6527
--- /dev/null
+++ b/test/pending/pos/t0805.scala
@@ -0,0 +1,9 @@
+package fr.up5.mi.noel.scala
+object Test {
+ def make(t: Test) : Test = TestList(t.args.toList)
+}
+case class TestList[T](elements: List[T])(implicit f: T => Test)
+
+class Test {
+ val args: Array[Test]
+}
diff --git a/test/pending/run/t0508x.scala b/test/pending/run/t0508x.scala
new file mode 100755
index 0000000000..0c1ffde3ed
--- /dev/null
+++ b/test/pending/run/t0508x.scala
@@ -0,0 +1,21 @@
+ final object Test extends java.lang.Object with Application {
+
+ class Foo(val s: String, val n: Int) extends java.lang.Object {
+ };
+
+ def foo[A >: Nothing <: Any, B >: Nothing <: Any, C >: Nothing <: Any]
+ (unapply1: (A) => Option[(B, C)], v: A): Unit =
+ unapply1.apply(v) match {
+ case Some((fst @ _, snd @ _)) =>
+ scala.Predef.println(scala.Tuple2.apply[java.lang.String, java.lang.String]("first: ".+(fst), " second: ".+(snd)))
+ case _ => scala.Predef.println(":(")
+ }
+ Test.this.foo[Test.Foo, String, Int]({
+ ((eta$0$1: Test.Foo) => Test.this.Foo.unapply(eta$0$1))
+ }, Test.this.Foo.apply("this might be fun", 10));
+ final object Foo extends java.lang.Object with ((String, Int) => Test.Foo) {
+ def unapply(x$0: Test.Foo): Some[(String, Int)] = scala.Some.apply[(String, Int)](scala.Tuple2.apply[String, Int](x$0.s, x$0.n));
+ def apply(s: String, n: Int): Test.Foo = new Test.this.Foo(s, n)
+ }
+ }
+
diff --git a/test/pending/run/t0818.scala b/test/pending/run/t0818.scala
new file mode 100644
index 0000000000..677b85d920
--- /dev/null
+++ b/test/pending/run/t0818.scala
@@ -0,0 +1,4 @@
+object Seth extends Application {
+ println(
+ new java.util.ArrayList[String]().toArray(Array[String]()))
+}