From 3ba2f2b49e0635255bbb40958e05cc5dccde0424 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 20 Jan 2006 15:50:55 +0000 Subject: --- .../scala/tools/nsc/ast/TreePrinters.scala | 18 ++++++++- src/compiler/scala/tools/nsc/symtab/StdNames.scala | 2 + .../scala/tools/nsc/transform/Erasure.scala | 43 ++++++++++++---------- .../tools/nsc/typechecker/SyntheticMethods.scala | 3 +- .../scala/tools/nsc/typechecker/Typers.scala | 31 ++++++++-------- 5 files changed, 60 insertions(+), 37 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 53b1f7da6e..ba3eaf6fd7 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -96,6 +96,14 @@ abstract class TreePrinters { if (s.length() != 0) print(s + " ") } + def printAttributes(attrs: List[AttrInfo]): unit = { + def attrToString(attr: AttrInfo): String = attr match { + case Pair(tp, List()) => tp.toString() + case Pair(tp, args) => tp.toString()+args.mkString("(", ",", ")") + } + if (!attrs.isEmpty) print(attrs.map(attrToString).mkString("[", ",", "]")) + } + def print(str: String): unit = out.print(str); def print(name: Name): unit = print(name.toString()); @@ -105,6 +113,7 @@ abstract class TreePrinters { print(""); case ClassDef(mods, name, tparams, tp, impl) => + printAttributes(tree.symbol.attributes); printModifiers(tree, mods); print("class " + symName(tree, name)); printTypeParams(tparams); @@ -114,10 +123,12 @@ abstract class TreePrinters { print("package "); print(packaged); printColumn(stats, " {", ";", "}") case ModuleDef(mods, name, impl) => + printAttributes(tree.symbol.attributes); printModifiers(tree, mods); print("object " + symName(tree, name)); print(" extends "); print(impl); case ValDef(mods, name, tp, rhs) => + printAttributes(tree.symbol.attributes); printModifiers(tree, mods); print(if (mods.hasFlag(MUTABLE)) "var " else "val "); print(symName(tree, name)); @@ -128,15 +139,18 @@ abstract class TreePrinters { } case DefDef(mods, name, tparams, vparamss, tp, rhs) => + printAttributes(tree.symbol.attributes); printModifiers(tree, mods); print("def " + symName(tree, name)); printTypeParams(tparams); vparamss foreach printValueParams; printOpt(": ", tp); printOpt(" = ", rhs); case AbsTypeDef(mods, name, lo, hi) => + printAttributes(tree.symbol.attributes); printModifiers(tree, mods); print("type "); printParam(tree); case AliasTypeDef(mods, name, tparams, rhs) => + printAttributes(tree.symbol.attributes); printModifiers(tree, mods); print("type " + symName(tree, name)); printTypeParams(tparams); printOpt(" = ", rhs); @@ -151,7 +165,9 @@ abstract class TreePrinters { print(selectors.map(selectorToString).mkString(".{", ", ", "}")) case Attributed(attr, definition) => - print("["); print(attr); print("]"); println; print(definition); + if (tree.symbol == NoSymbol) { + print("["); print(attr); print("]"); println; print(definition); + } case DocDef(comment, definition) => print(comment); println; print(definition); diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index 8a4cc204df..26e941cd87 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -215,11 +215,13 @@ mixin class StdNames requires SymbolTable { val While = newTermName("While"); val apply = newTermName("apply"); val array = newTermName("array"); + val arrayValue = newTermName("arrayValue"); val arraycopy = newTermName("arraycopy"); val assert_ = newTermName("assert"); val assume_ = newTermName("assume"); val asInstanceOf = newTermName("asInstanceOf"); val asInstanceOfErased = newTermName("asInstanceOf$erased"); + val booleanValue = newTermName("booleanValue"); val box = newTermName("box"); val caseArity = newTermName("caseArity"); val caseElement = newTermName("caseElement"); diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 3555bee62b..bd84f6ed6f 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -161,12 +161,16 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { } /** The method-name xxxValue, where Xxx is a numeric value class name */ - def unboxOp(tp: Type) = { + def unboxOp(tp: Type): Name = { val clazzName = tp.symbol.name.toString(); - (String.valueOf((clazzName.charAt(0) + ('a' - 'A')).asInstanceOf[char]) + - clazzName.substring(1) + "Value") + newTermName( + String.valueOf((clazzName.charAt(0) + ('a' - 'A')).asInstanceOf[char]) + + clazzName.substring(1) + "Value") } + private def runtimeCall(meth: Name, args: List[Tree]): Tree = + Apply(Select(gen.mkRef(ScalaRunTimeModule), meth), args); + /** Unbox `tree' of boxed type to expected type `pt' */ private def unbox(tree: Tree, pt: Type): Tree = typed { @@ -174,23 +178,24 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { if (pt.symbol == UnitClass) { if (treeInfo.isPureExpr(tree)) Literal(()) else Block(List(tree), Literal(())) - } else if (pt.symbol == BooleanClass) { - val tree1 = adaptToType(tree, boxedClass(BooleanClass).tpe); - Apply(Select(tree1, "booleanValue"), List()) - } else if (pt.symbol == ArrayClass) { - val tree1 = adaptToType(tree, BoxedArrayClass.tpe); - val elemClass = pt.typeArgs.head.symbol; - val elemTag = - if (isValueClass(elemClass)) - Apply( - Select(gen.mkRef(ScalaRunTimeModule), newTermName(elemClass.name.toString() + "Tag")), - List()) - else Literal(signature(pt.typeArgs.head)); - Apply(Select(tree1, "unbox"), List(elemTag)) } else { - assert(isNumericValueClass(pt.symbol)); - val tree1 = adaptToType(tree, BoxedNumberClass.tpe); - Apply(Select(tree1, unboxOp(pt)), List()) + if (pt.symbol == BooleanClass) { + val tree1 = adaptToType(tree, boxedClass(BooleanClass).tpe); + runtimeCall(nme.booleanValue, List(tree1)) + } else if (pt.symbol == ArrayClass) { + val tree1 = adaptToType(tree, BoxedArrayClass.tpe); + val elemClass = pt.typeArgs.head.symbol; + val elemTag = + if (isValueClass(elemClass)) + runtimeCall(newTermName(elemClass.name.toString() + "Tag"), List()) + else + Literal(signature(pt.typeArgs.head)); + runtimeCall(nme.arrayValue, List(tree1, elemTag)) + } else { + assert(isNumericValueClass(pt.symbol)); + val tree1 = adaptToType(tree, BoxedNumberClass.tpe); + runtimeCall(unboxOp(pt), List(tree1)) + } } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 71b21084a0..28d36b2494 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -88,12 +88,11 @@ mixin class SyntheticMethods requires Analyzer { val SerializableAttr = definitions.SerializableAttr; - def isSerializable(clazz: Symbol): Boolean = { + def isSerializable(clazz: Symbol): Boolean = clazz.attributes.exists(p => p match { case Pair(SerializableAttr, _) => true; case _ => false }) - } def readResolveMethod: Tree = { // !!! the synthetic method "readResolve" should be private, diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 7aa79333d9..cb83e6abbe 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -240,17 +240,6 @@ mixin class Typers requires Analyzer { tparam.symbol.deSkolemize } - def attrInfo(attr: Tree): AttrInfo = attr match { - case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => - Pair(tpt.tpe, args map { - case Literal(value) => - value - case arg => - error(arg.pos, "attribute argument needs to be a constant; found: "+arg) - null - }) - } - /** The qualifying class of a this or super with prefix `qual' */ def qualifyingClassContext(tree: Tree, qual: Name): Context = { if (qual.isEmpty) { @@ -1164,10 +1153,22 @@ mixin class Typers requires Analyzer { case Attributed(attr, defn) => val attr1 = typed(attr, AttributeClass.tpe) - val defn1 = typed(defn, mode, pt) - val ai = attrInfo(attr1) - if (ai != null) defn1.symbol.attributes = defn1.symbol.attributes ::: List(ai) - defn1 + val attrInfo = attr1 match { + case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => + Pair(tpt.tpe, args map { + case Literal(value) => + value + case arg => + error(arg.pos, "attribute argument needs to be a constant; found: "+arg) + null + }) + } + if (attrInfo != null) { + val attributed = + if (defn.symbol.isModule) defn.symbol.moduleClass else defn.symbol; + attributed.attributes = attributed.attributes ::: List(attrInfo) + } + typed(defn, mode, pt) case DocDef(comment, defn) => typed(defn, mode, pt) -- cgit v1.2.3