diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Constants.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/Importers.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/Path.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/LiftCode.scala | 28 | ||||
-rw-r--r-- | src/library/scala/math/BigDecimal.scala | 4 |
6 files changed, 47 insertions, 16 deletions
diff --git a/src/compiler/scala/reflect/internal/Constants.scala b/src/compiler/scala/reflect/internal/Constants.scala index 9c4b2b2245..c328cc49cb 100644 --- a/src/compiler/scala/reflect/internal/Constants.scala +++ b/src/compiler/scala/reflect/internal/Constants.scala @@ -45,7 +45,7 @@ trait Constants extends api.Constants { case x: Char => CharTag case x: Type => ClassTag case x: Symbol => EnumTag - case _ => throw new Error("bad constant value: " + value) + case _ => throw new Error("bad constant value: " + value + " of class " + value.getClass) } def isByteRange: Boolean = isIntRange && Byte.MinValue <= intValue && intValue <= Byte.MaxValue diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 23b443919a..4f5b28d370 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -145,8 +145,8 @@ trait Importers { self: SymbolTable => PolyType(tparams map importSymbol, importType(restpe)) case from.NullaryMethodType(restpe) => NullaryMethodType(importType(restpe)) - case from.ConstantType(from.Constant(value)) => - ConstantType(Constant(value)) + case from.ConstantType(constant @ from.Constant(_)) => + ConstantType(importConstant(constant)) case from.SuperType(thistpe, supertpe) => SuperType(importType(thistpe), importType(supertpe)) case from.TypeBounds(lo, hi) => @@ -194,8 +194,8 @@ trait Importers { self: SymbolTable => }) def importAnnotArg(arg: from.ClassfileAnnotArg): ClassfileAnnotArg = arg match { - case from.LiteralAnnotArg(from.Constant(value)) => - LiteralAnnotArg(Constant(value)) + case from.LiteralAnnotArg(constant @ from.Constant(_)) => + LiteralAnnotArg(importConstant(constant)) case from.ArrayAnnotArg(args) => ArrayAnnotArg(args map importAnnotArg) case from.ScalaSigBytes(bytes) => @@ -303,8 +303,8 @@ trait Importers { self: SymbolTable => case _ => new Ident(importName(name)) } - case from.Literal(from.Constant(value)) => - new Literal(Constant(value)) + case from.Literal(constant @ from.Constant(_)) => + new Literal(importConstant(constant)) case from.TypeTree() => new TypeTree() case from.Annotated(annot, arg) => @@ -339,5 +339,10 @@ trait Importers { self: SymbolTable => def importRefTree(tree: from.RefTree): RefTree = importTree(tree).asInstanceOf[RefTree] def importIdent(tree: from.Ident): Ident = importTree(tree).asInstanceOf[Ident] def importCaseDef(tree: from.CaseDef): CaseDef = importTree(tree).asInstanceOf[CaseDef] + def importConstant(constant: from.Constant): Constant = new Constant(constant.tag match { + case ClassTag => importType(constant.value.asInstanceOf[from.Type]) + case EnumTag => importSymbol(constant.value.asInstanceOf[from.Symbol]) + case _ => constant.value + }) } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 4478fb6128..dae264fffe 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -84,6 +84,8 @@ trait Scanners extends ScannersCommon { abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon { private def isDigit(c: Char) = java.lang.Character isDigit c + + def isAtEnd = charOffset >= buf.length def flush = { charOffset = offset; nextChar(); this } @@ -449,7 +451,7 @@ trait Scanners extends ScannersCommon { case ']' => nextChar(); token = RBRACKET case SU => - if (charOffset >= buf.length) token = EOF + if (isAtEnd) token = EOF else { syntaxError("illegal character") nextChar() @@ -771,10 +773,10 @@ trait Scanners extends ScannersCommon { putChar(ch) } - private def getLitChars(delimiter: Char) = - while (ch != delimiter && (ch != CR && ch != LF && ch != SU || isUnicodeEscape)) { + private def getLitChars(delimiter: Char) = { + while (ch != delimiter && !isAtEnd && (ch != SU && ch != CR && ch != LF || isUnicodeEscape)) getLitChar() - } + } /** read fractional part and exponent of floating point number * if one is present. diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala index 9efff089ba..a1b8e5e4d5 100644 --- a/src/compiler/scala/tools/nsc/io/Path.scala +++ b/src/compiler/scala/tools/nsc/io/Path.scala @@ -48,7 +48,7 @@ object Path { implicit def jfile2path(jfile: JFile): Path = apply(jfile) // java 7 style, we don't use it yet - // object AccessMode extends Enumeration("AccessMode") { + // object AccessMode extends Enumeration { // val EXECUTE, READ, WRITE = Value // } // def checkAccess(modes: AccessMode*): Boolean = { diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index c5475fa0f2..f1182fc2a9 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -129,7 +129,13 @@ abstract class LiftCode extends Transform with TypingTransformers { if (reifyCopypaste) printCopypaste(result) result } - } finally printTypings = saved + } catch { + case ex: ReifierError => + unit.error(ex.pos, ex.msg) + tree + } finally { + printTypings = saved + } case _ => super.transform(tree) } @@ -396,6 +402,10 @@ abstract class LiftCode extends Transform with TypingTransformers { if (thereAreOnlyTTs && ttsAreNotEssential) reifyTree(hk) else reifyProduct(ta) case global.emptyValDef => mirrorSelect(nme.emptyValDef) + case Literal(constant @ Constant(tpe: Type)) if boundSyms exists (tpe contains _) => + CannotReifyClassOfBoundType(tree, tpe) + case Literal(constant @ Constant(sym: Symbol)) if boundSyms contains sym => + CannotReifyClassOfBoundEnum(tree, constant.tpe) case _ => if (tree.isDef) boundSyms += tree.symbol @@ -494,8 +504,20 @@ abstract class LiftCode extends Transform with TypingTransformers { symDefs.toList ++ fillIns.toList } + } + + /** A throwable signalling a reification error */ + class ReifierError(var pos: Position, val msg: String) extends Throwable(msg) { + def this(msg: String) = this(NoPosition, msg) + } + + def CannotReifyClassOfBoundType(tree: Tree, tpe: Type) = { + val msg = "cannot reify classOf[%s] which refers to a type declared inside the block being reified".format(tpe) + throw new ReifierError(tree.pos, msg) + } - private def cannotReify(value: Any): Nothing = - abort("don't know how to reify " + value + " of " + value.getClass) + def CannotReifyClassOfBoundEnum(tree: Tree, tpe: Type) = { + val msg = "cannot reify classOf[%s] which refers to an enum declared inside the block being reified".format(tpe) + throw new ReifierError(tree.pos, msg) } } diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala index 497de92c80..c1f45eccfb 100644 --- a/src/library/scala/math/BigDecimal.scala +++ b/src/library/scala/math/BigDecimal.scala @@ -33,8 +33,10 @@ object BigDecimal { /** Cache ony for defaultMathContext using BigDecimals in a small range. */ private lazy val cache = new Array[BigDecimal](maxCached - minCached + 1) - object RoundingMode extends Enumeration(java.math.RoundingMode.values map (_.toString) : _*) with Serializable { + object RoundingMode extends Enumeration { type RoundingMode = Value + // These are supposed to be the same as java.math.RoundingMode.values, + // though it seems unwise to rely on the correspondence. val UP, DOWN, CEILING, FLOOR, HALF_UP, HALF_DOWN, HALF_EVEN, UNNECESSARY = Value } |