diff options
author | Antonio Cunei <antonio.cunei@epfl.ch> | 2009-12-18 12:41:49 +0000 |
---|---|---|
committer | Antonio Cunei <antonio.cunei@epfl.ch> | 2009-12-18 12:41:49 +0000 |
commit | 649b9178954c489a444e2b8ab234072cdd0430e5 (patch) | |
tree | 507dbb247cbc9b0ec4dfffad4c4267f05d42eee3 /src/compiler | |
parent | 4e062472536d8cec91313a315b54560b15893910 (diff) | |
download | scala-649b9178954c489a444e2b8ab234072cdd0430e5.tar.gz scala-649b9178954c489a444e2b8ab234072cdd0430e5.tar.bz2 scala-649b9178954c489a444e2b8ab234072cdd0430e5.zip |
Merged revisions 20186,20199,20203,20208-20212,...
Merged revisions 20186,20199,20203,20208-20212,20216-20217 via svnmerge
from https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk
........
r20186 | malayeri | 2009-12-17 13:04:55 +0100 (Thu, 17 Dec 2009) | 1 line
Fixed #2808. Review by odersky.
........
r20199 | odersky | 2009-12-17 16:50:52 +0100 (Thu, 17 Dec 2009) | 1 line
implement new spec for erasure of intersection types. ........ r20203
| odersky | 2009-12-17 18:40:21 +0100 (Thu, 17 Dec 2009) | 1 line
Closed #2795. review by dubochet.
........
r20208 | odersky | 2009-12-17 19:06:47 +0100 (Thu, 17 Dec 2009) | 1 line
Fixed build problem caused by r20203. Need to maintain old structure
for bootstrap. review by dubochet. ........ r20209 | odersky |
2009-12-17 19:16:47 +0100 (Thu, 17 Dec 2009) | 1 line
Another fix for the build problem with r20203. Things are trickier
than they seemed at first. review by dubochet. ........ r20210 | odersky
| 2009-12-17 19:17:10 +0100 (Thu, 17 Dec 2009) | 1 line
Closed #2775. Review by moors.
........
r20211 | extempore | 2009-12-17 21:35:44 +0100 (Thu, 17 Dec 2009) | 2 lines
Added a method to turn a class name into the pile of bytes which
is its classfile on disk. no review. ........ r20212 | extempore |
2009-12-17 21:36:00 +0100 (Thu, 17 Dec 2009) | 4 lines
Began the process of consolidating all the code which is painfully
duplicated between MarkupParsers and MarkupParser. This motivated by the
reappearance of bug #2354 in the exact same form as the one I already
fixed. no review. ........ r20216 | rytz | 2009-12-18 11:43:36 +0100
(Fri, 18 Dec 2009) | 1 line
read the Exceptions attribute from java classfiles. review by dragos
........ r20217 | cunei | 2009-12-18 12:54:07 +0100 (Fri, 18 Dec 2009) |
3 lines
Disabling test for #1801 yet again, still failing on some systems. No
review. ........
Diffstat (limited to 'src/compiler')
8 files changed, 64 insertions, 35 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index 67e1cd8304..bd46d2219d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -50,10 +50,17 @@ trait MarkupParsers import global._ - class MarkupParser(parser: UnitParser, final val preserveWS: Boolean) { + class MarkupParser(parser: UnitParser, final val preserveWS: Boolean) extends scala.xml.parsing.MarkupParserCommon { import Tokens.{ EMPTY, LBRACE, RBRACE } + type PositionType = Position + val eof = false + + def xHandleError(that: Char, msg: String) = + if (ch == SU) throw TruncatedXML + else reportSyntaxError(msg) + var input : CharArrayReader = _ import parser.{ symbXMLBuilder => handle, o2p, r2p } @@ -73,15 +80,6 @@ trait MarkupParsers finally setter(saved) } - /** munch expected XML token, report syntax error for unexpected. - * - * @param that ... - */ - def xToken(that: Char): Unit = - if (ch == that) nextch - else if (ch == SU) throw TruncatedXML - else reportSyntaxError("'%s' expected instead of '%s'".format(that, ch)) - private var debugLastStartElement = new mutable.Stack[(Int, String)] private def debugLastPos = debugLastStartElement.top._1 private def debugLastElem = debugLastStartElement.top._2 @@ -421,18 +419,6 @@ trait MarkupParsers buf.toString.intern } - /** scan [S] '=' [S]*/ - def xEQ = { xSpaceOpt; xToken('='); xSpaceOpt } - - /** skip optional space S? */ - def xSpaceOpt = { while (isSpace(ch)) { nextch }} - - /** scan [3] S ::= (#x20 | #x9 | #xD | #xA)+ */ - def xSpace = - if (isSpace(ch)) { nextch; xSpaceOpt } - else if (ch == SU) throw TruncatedXML - else reportSyntaxError("whitespace expected") - /** '<?' ProcInstr ::= Name [S ({Char} - ({Char}'>?' {Char})]'?>' * * see [15] @@ -558,8 +544,9 @@ trait MarkupParsers */ def xScalaPatterns: List[Tree] = escapeToScala(parser.patterns(true), "pattern") + def reportSyntaxError(pos: Int, str: String) = parser.syntaxError(pos, str) def reportSyntaxError(str: String) = { - parser.syntaxError(curOffset, "in XML literal: " + str) + reportSyntaxError(curOffset, "in XML literal: " + str) nextch } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index fef14e940b..50e16dc6b8 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -93,7 +93,6 @@ abstract class GenJVM extends SubComponent { val TransientAtt = definitions.getClass("scala.transient") val VolatileAttr = definitions.getClass("scala.volatile") val RemoteAttr = definitions.getClass("scala.remote") - val ThrowsAttr = definitions.getClass("scala.throws") val BeanInfoAttr = definitions.getClass("scala.reflect.BeanInfo") val BeanInfoSkipAttr = definitions.getClass("scala.reflect.BeanInfoSkip") val BeanDisplayNameAttr = definitions.getClass("scala.reflect.BeanDisplayName") @@ -333,7 +332,7 @@ abstract class GenJVM extends SubComponent { // put some radom value; the actual number is determined at the end buf.putShort(0xbaba.toShort) - for (AnnotationInfo(tp, List(exc), _) <- excs.removeDuplicates if tp.typeSymbol == ThrowsAttr) { + for (AnnotationInfo(tp, List(exc), _) <- excs.removeDuplicates if tp.typeSymbol == definitions.ThrowsClass) { val Literal(const) = exc buf.putShort( cpool.addClass( @@ -626,7 +625,7 @@ abstract class GenJVM extends SubComponent { } addGenericSignature(jmethod, m.symbol, clasz.symbol) - val (excs, others) = splitAnnotations(m.symbol.annotations, ThrowsAttr) + val (excs, others) = splitAnnotations(m.symbol.annotations, definitions.ThrowsClass) addExceptionsAttribute(jmethod, excs) addAnnotations(jmethod, others) addParamAnnotations(jmethod, m.params.map(_.sym.annotations)) @@ -634,7 +633,7 @@ abstract class GenJVM extends SubComponent { private def addRemoteException(jmethod: JMethod, meth: Symbol) { def isRemoteThrows(ainfo: AnnotationInfo) = ainfo match { - case AnnotationInfo(tp, List(arg), _) if tp.typeSymbol == ThrowsAttr => + case AnnotationInfo(tp, List(arg), _) if tp.typeSymbol == definitions.ThrowsClass => arg match { case Literal(Constant(tpe: Type)) if tpe.typeSymbol == RemoteException.typeSymbol => true case _ => false @@ -645,7 +644,7 @@ abstract class GenJVM extends SubComponent { if (remoteClass || (meth.hasAnnotation(RemoteAttr) && jmethod.isPublic())) { val c = Constant(RemoteException) - val ainfo = AnnotationInfo(ThrowsAttr.tpe, List(Literal(c).setType(c.tpe)), List()) + val ainfo = AnnotationInfo(definitions.ThrowsClass.tpe, List(Literal(c).setType(c.tpe)), List()) if (!meth.annotations.exists(isRemoteThrows)) { meth.addAnnotation(ainfo) } @@ -810,7 +809,7 @@ abstract class GenJVM extends SubComponent { if (!m.hasFlag(Flags.DEFERRED)) addGenericSignature(mirrorMethod, m, module) - val (throws, others) = splitAnnotations(m.annotations, ThrowsAttr) + val (throws, others) = splitAnnotations(m.annotations, definitions.ThrowsClass) addExceptionsAttribute(mirrorMethod, throws) addAnnotations(mirrorMethod, others) addParamAnnotations(mirrorMethod, m.info.params.map(_.annotations)) diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 7e346090e0..e1cf7a5a7e 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -118,6 +118,7 @@ trait Definitions { lazy val uncheckedStableClass = getClass("scala.annotation.unchecked.uncheckedStable") lazy val uncheckedVarianceClass = getClass("scala.annotation.unchecked.uncheckedVariance") lazy val UncheckedClass = getClass("scala.unchecked") + lazy val ThrowsClass = getClass("scala.throws") lazy val TailrecClass = getClass("scala.annotation.tailrec") lazy val SwitchClass = getClass("scala.annotation.switch") lazy val ElidableMethodClass = getClass("scala.annotation.elidable") diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 6f21e3fee9..da4e0aaa49 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -809,6 +809,10 @@ abstract class ClassfileParser { // TODO 2: also parse RuntimeInvisibleAnnotation / RuntimeInvisibleParamAnnotation, // i.e. java annotations with RetentionPolicy.CLASS? + + case nme.ExceptionsATTR if (!isScala) => + parseExceptions(attrLen) + case _ => in.skip(attrLen) } @@ -872,6 +876,20 @@ abstract class ClassfileParser { None // ignore malformed annotations ==> t1135 } + /** + * Parse the "Exceptions" attribute which denotes the exceptions + * thrown by a method. + */ + def parseExceptions(len: Int) { + val nClasses = in.nextChar + for (n <- 0 until nClasses) { + val cls = pool.getClassSymbol(in.nextChar.toInt) + sym.addAnnotation(AnnotationInfo(definitions.ThrowsClass.tpe, + Literal(Constant(cls.tpe)) :: Nil, + Nil)) + } + } + /** 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 d58d95cbfe..9db88af6c6 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -39,7 +39,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. /** Is `tp` an unbounded generic type (i.e. which could be instantiated * with primitive as well as class types)?. */ - private def genericCore(tp: Type): Type = tp match { + private def genericCore(tp: Type): Type = tp.normalize match { case TypeRef(_, argsym, _) if (argsym.isAbstractType && !(argsym.owner hasFlag JAVA)) => tp case ExistentialType(tparams, restp) => @@ -52,7 +52,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. * then Some(N, T) where N is the number of Array constructors enclosing `T`, * otherwise None. Existentials on any level are ignored. */ - def unapply(tp: Type): Option[(Int, Type)] = tp match { + def unapply(tp: Type): Option[(Int, Type)] = tp.normalize match { case TypeRef(_, ArrayClass, List(arg)) => genericCore(arg) match { case NoType => @@ -146,7 +146,17 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. apply(restpe)) case RefinedType(parents, decls) => if (parents.isEmpty) erasedTypeRef(ObjectClass) - else apply(parents.head) + else { + // implement new spec for erasure of refined types. + val psyms = parents map (_.typeSymbol) + def isUnshadowed(psym: Symbol) = + !(psyms exists (qsym => (psym ne qsym) && (qsym isNonBottomSubClass psym))) + val cs = parents.iterator.filter { p => // isUnshadowed is a bit expensive, so try classes first + val psym = p.typeSymbol + psym.isClass && !psym.isTrait && isUnshadowed(psym) + } + apply((if (cs.hasNext) cs else parents.iterator.filter(p => isUnshadowed(p.typeSymbol))).next()) + } case AnnotatedType(_, atp, _) => apply(atp) case ClassInfoType(parents, decls, clazz) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 2bd296b65d..707c91e6ad 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -770,10 +770,16 @@ self: Analyzer => EmptyTree // todo: change to existential parameter manifest else if (sym.isTypeParameterOrSkolem) EmptyTree // a manifest should have been found by normal searchImplicit - else + else { + // the following is tricky! We want to find the parameterized version of + // what will become the erasure of the upper bound. + var era = erasure.erasure(tp1) + if (era.typeSymbol.typeParams.nonEmpty) + era = tp1.baseType(era.typeSymbol) manifestFactoryCall( "abstractType", tp, - findSubManifest(pre) :: Literal(sym.name.toString) :: findManifest(tp1.bounds.hi) :: (args map findSubManifest): _*) + findSubManifest(pre) :: Literal(sym.name.toString) :: gen.mkClassOf(era) :: (args map findSubManifest): _*) + } } else { EmptyTree // a manifest should have been found by normal searchImplicit } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 41cf46c8f3..4c919f227a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -316,7 +316,7 @@ abstract class RefChecks extends InfoTransform { (other hasFlag ACCESSOR) && other.accessed.isVariable && !other.accessed.hasFlag(LAZY)) { overrideError("cannot override a mutable variable") } else if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) && - !(member.owner isSubClass other.owner) && + !(member.owner.thisType.baseClasses exists (_ isSubClass other.owner)) && !member.isDeferred && !other.isDeferred && intersectionIsEmpty(member.allOverriddenSymbols, other.allOverriddenSymbols)) { overrideError("cannot override a concrete member without a third member that's overridden by both "+ diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala index 95396dd95b..95110d6b81 100644 --- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala +++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala @@ -90,4 +90,12 @@ object ScalaClassLoader { search(getContextLoader()) } + + def findBytesForClassName(s: String): Array[Byte] = { + val name = s.replaceAll("""\.""", "/") + ".class" + val url = getSystemLoader.getResource(name) + + if (url == null) Array() + else new io.Streamable.Bytes { def inputStream() = url.openStream } . toByteArray() + } } |