From e2fd411f0a2f78547167149cada72dc347394749 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 22 May 2008 15:13:53 +0000 Subject: fixed #911. --- .../scala/tools/nsc/javac/JavaParsers.scala | 5 +++-- .../scala/tools/nsc/javac/JavaScanners.scala | 6 +++--- src/compiler/scala/tools/nsc/symtab/Types.scala | 15 +++++++++----- .../nsc/symtab/classfile/ClassfileParser.scala | 4 ---- .../scala/tools/nsc/typechecker/Namers.scala | 11 +++++++--- .../tools/nsc/typechecker/SuperAccessors.scala | 3 ++- test/files/neg/t0899.check | 10 +++++++++ test/files/neg/t0899.scala | 13 ++++++++++++ test/files/run/t0700.check | 2 ++ test/files/run/t0700.scala | 24 ++++++++++++++++++++++ test/files/run/t0911.scala | 2 +- 11 files changed, 76 insertions(+), 19 deletions(-) create mode 100644 test/files/neg/t0899.check create mode 100644 test/files/neg/t0899.scala create mode 100644 test/files/run/t0700.check create mode 100755 test/files/run/t0700.scala diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 9d43b368df..e2734f996b 100755 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -424,7 +424,7 @@ trait JavaParsers extends JavaScanners { def typeParam(): TypeDef = atPos(in.currentPos) { - val name = ident() + val name = ident().toTypeName val hi = if (in.token == EXTENDS) { in.nextToken @@ -432,7 +432,8 @@ trait JavaParsers extends JavaScanners { } else { scalaDot(nme.Any.toTypeName) } - TypeDef(Modifiers(Flags.JAVA), name, List(), TypeBoundsTree(scalaDot(nme.Nothing.toTypeName), hi)) + TypeDef(Modifiers(Flags.JAVA | Flags.DEFERRED | Flags.PARAM), name, List(), + TypeBoundsTree(scalaDot(nme.Nothing.toTypeName), hi)) } def bound(): Tree = diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala index 7aacdc4559..d76b315ac4 100755 --- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala @@ -309,10 +309,10 @@ trait JavaScanners { def nextToken { if (next.token == EMPTY) { - print("[") + //print("[") val t = fetchToken() - print(this) - print("]") + //print(this) + //print("]") t } else { this copyFrom next diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index e03e63e9d6..8b1abc27a0 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -3564,7 +3564,7 @@ A type's typeSymbol should never be inspected directly. sym2.isClass && (sym2 isNonBottomSubClass ObjectClass) && (!(tp2.normalize.typeSymbol isNonBottomSubClass NotNullClass))) case (MethodType(pts1, res1), MethodType(pts2, res2)) => (pts1.length == pts2.length && - matchingParams(pts1, pts2, tp2.isInstanceOf[JavaMethodType]) && + matchingParams(pts1, pts2, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) && (res1 <:< res2) && tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType]) case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => @@ -3679,7 +3679,7 @@ A type's typeSymbol should never be inspected directly. /** A function implementing `tp1' matches `tp2' */ private def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: Boolean): Boolean = (tp1, tp2) match { case (MethodType(pts1, res1), MethodType(pts2, res2)) => - matchingParams(pts1, pts2, tp2.isInstanceOf[JavaMethodType]) && + matchingParams(pts1, pts2, tp1.isInstanceOf[JavaMethodType], tp2.isInstanceOf[JavaMethodType]) && matchesType(res1, res2, alwaysMatchSimple) && tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType] case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => @@ -3702,11 +3702,12 @@ A type's typeSymbol should never be inspected directly. } /** Are `tps1' and `tps2' lists of pairwise equivalent types? */ - private def matchingParams(tps1: List[Type], tps2: List[Type], tps2isJava: Boolean): Boolean = ( + private def matchingParams(tps1: List[Type], tps2: List[Type], tps1isJava: Boolean, tps2isJava: Boolean): Boolean = tps1.length == tps2.length && List.forall2(tps1, tps2)((tp1, tp2) => - (tp1 =:= tp2) || tps2isJava & tp1.typeSymbol == ObjectClass && tp2.typeSymbol == AnyClass) - ); + (tp1 =:= tp2) || + tps1isJava && tp2.typeSymbol == ObjectClass && tp1.typeSymbol == AnyClass || + tps2isJava && tp1.typeSymbol == ObjectClass && tp2.typeSymbol == AnyClass) /** Prepend type `tp' to closure `cl'. * @@ -4317,4 +4318,8 @@ A type's typeSymbol should never be inspected directly. val s = checkMalformedSwitch try { checkMalformedSwitch = false; op } finally { checkMalformedSwitch = s } } + + def objToAny(tp: Type): Type = + if (!phase.erasedTypes && tp.typeSymbol == ObjectClass) AnyClass.tpe + else tp } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 04783f70e1..bb3a0f58aa 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -469,10 +469,6 @@ abstract class ClassfileParser { assert(sig(index) == ch) index += 1 } - def objToAny(tp: Type): Type = - if (!global.phase.erasedTypes && tp.typeSymbol == definitions.ObjectClass) - definitions.AnyClass.tpe - else tp def subName(isDelimiter: Char => Boolean): Name = { val start = index while (!isDelimiter(sig(index))) { index += 1 } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 01e22eae85..5ac2f17e93 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -380,7 +380,7 @@ trait Namers { self: Analyzer => case TypeDef(mods, name, tparams, _) => var flags: Long = mods.flags if ((flags & PARAM) != 0) flags |= DEFERRED - var sym =new TypeSymbol(owner, tree.pos, name).setFlag(flags) + var sym = new TypeSymbol(owner, tree.pos, name).setFlag(flags) setPrivateWithin(tree, sym, mods) tree.symbol = enterInScope(sym) finishWith(tparams) @@ -640,10 +640,12 @@ trait Namers { self: Analyzer => } def makeMethodType(vparams: List[Symbol], restpe: Type) = { - val formals = vparams map (_.tpe) + val formals = vparams map (vparam => + if (meth hasFlag JAVA) objToAny(vparam.tpe) else vparam.tpe) val restpe1 = convertToDeBruijn(vparams, 1)(restpe) if (!vparams.isEmpty && vparams.head.hasFlag(IMPLICIT)) ImplicitMethodType(formals, restpe1) + else if (meth hasFlag JAVA) JavaMethodType(formals, restpe1) else MethodType(formals, restpe1) } @@ -757,7 +759,10 @@ trait Namers { self: Analyzer => val tp = typer.typedType(rhs).tpe match { case TypeBounds(lt, rt) if (lt.isError || rt.isError) => TypeBounds(AllClass.tpe, AnyClass.tpe) - case tp => tp + case tp @ TypeBounds(lt, rt) if (tpsym hasFlag JAVA) => + TypeBounds(lt, objToAny(rt)) + case tp => + tp } def verifyOverriding(other: Symbol): Boolean = { diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 7e8790aacd..9de0eac908 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -186,7 +186,8 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT case Select(sup @ Super(_, mix), name) => val sym = tree.symbol if (sym.isValue && !sym.isMethod || sym.hasFlag(ACCESSOR)) { - unit.error(tree.pos, "super may be not be used on "+sym) + unit.error(tree.pos, "super may be not be used on "+ + (if (sym.hasFlag(ACCESSOR)) sym.accessed else sym)) } transformSuperSelect(tree) diff --git a/test/files/neg/t0899.check b/test/files/neg/t0899.check new file mode 100644 index 0000000000..8b71be8e0c --- /dev/null +++ b/test/files/neg/t0899.check @@ -0,0 +1,10 @@ +t0899.scala:9: error: super may be not be used on value o + override val o = "Ha! " + super.o + ^ +t0899.scala:11: error: super may be not be used on variable v + super.v = "aa" + ^ +t0899.scala:12: error: super may be not be used on variable v + println(super.v) + ^ +three errors found diff --git a/test/files/neg/t0899.scala b/test/files/neg/t0899.scala new file mode 100644 index 0000000000..817dc19eb4 --- /dev/null +++ b/test/files/neg/t0899.scala @@ -0,0 +1,13 @@ +class Top { + val o = "Hi there!" + var v = "Hi there!" + type T + val x: T +} + +class Bot extends Top { + override val o = "Ha! " + super.o + val y: super.T = x + super.v = "aa" + println(super.v) +} diff --git a/test/files/run/t0700.check b/test/files/run/t0700.check new file mode 100644 index 0000000000..b4eabbab1a --- /dev/null +++ b/test/files/run/t0700.check @@ -0,0 +1,2 @@ +[3.2] parsed: List(2, 2, 2) +[3.2] parsed: List(2, 2, 2) diff --git a/test/files/run/t0700.scala b/test/files/run/t0700.scala new file mode 100755 index 0000000000..5a7180528c --- /dev/null +++ b/test/files/run/t0700.scala @@ -0,0 +1,24 @@ +import java.io.{File,StringReader} + +import scala.util.parsing.combinator.Parsers +import scala.util.parsing.input.{CharArrayReader, StreamReader} + +class TestParsers extends Parsers { + type Elem = Char + + def p: Parser[List[Int]] = rep(p1 | p2) + def p1: Parser[Int] = 'a' ~ nl ~ 'b' ~ nl ^^^ 1 + def p2: Parser[Int] = 'a' ~ nl ^^^ 2 + def nl: Parser[Int] = rep(accept('\n') | accept('\r')) ^^^ 0 +} + +object Test { + def main(args: Array[String]): Unit = { + val tstParsers = new TestParsers + val s = "a\na\na" + val r1 = new CharArrayReader(s.toCharArray()) + val r2 = StreamReader(new StringReader(s)) + println(tstParsers.p(r1)) + println(tstParsers.p(r2)) + } +} diff --git a/test/files/run/t0911.scala b/test/files/run/t0911.scala index f4d93eb571..6f9ad91781 100644 --- a/test/files/run/t0911.scala +++ b/test/files/run/t0911.scala @@ -4,6 +4,6 @@ class IP extends { val baz = "bar"; } with Foo(() => baz); -object Main extends Application{ +object Test extends Application{ (new IP).bar(); } -- cgit v1.2.3