diff options
author | Martin Odersky <odersky@gmail.com> | 2006-05-05 13:39:29 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-05-05 13:39:29 +0000 |
commit | 12a9f76471f19c8b134b3ea5bba32042020d6ca6 (patch) | |
tree | b5154894ca54902f59ee0cc4e257016e93f84dca /src/compiler | |
parent | 1f5bd8a590e9c29fdaabb53adeae1bf5c22258f4 (diff) | |
download | scala-12a9f76471f19c8b134b3ea5bba32042020d6ca6.tar.gz scala-12a9f76471f19c8b134b3ea5bba32042020d6ca6.tar.bz2 scala-12a9f76471f19c8b134b3ea5bba32042020d6ca6.zip |
added support of class literals
Diffstat (limited to 'src/compiler')
30 files changed, 245 insertions, 119 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 9e94572c40..5bec4e39d7 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -278,6 +278,10 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable val global: Global.this.type = Global.this } + object cleanup extends CleanUp { + val global: Global.this.type = Global.this + } + object sampleTransform extends SampleTransform { val global: Global.this.type = Global.this } @@ -324,6 +328,7 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable constructors, flatten, mixer, + cleanup, genicode, inliner, genJVM, diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala index bd6498fca9..ff23178c4a 100644 --- a/src/compiler/scala/tools/nsc/Main.scala +++ b/src/compiler/scala/tools/nsc/Main.scala @@ -54,7 +54,7 @@ object Main extends Object with EvalLoop { if (command.settings.resident.value) resident(compiler); else if (command.files.isEmpty) - reporter.info(null, command.usageMsg, true) + reporter.info(null, command.usageMsg, true) else { val run = new compiler.Run run compile command.files diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 6fc46319fd..112932be3a 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -82,7 +82,7 @@ class Settings(error: String => unit) { val encoding = StringSetting ("-encoding", "encoding", "Specify character encoding used by source files", encodingDefault) val windowtitle = StringSetting ("-windowtitle", "windowtitle", "Specify window title of generated HTML documentation", windowtitleDefault) val documenttitle = StringSetting ("-documenttitle", "documenttitle", "Specify document title of generated HTML documentation", documenttitleDefault) - val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm", "msil", "cldc"), "jvm") + val target = ChoiceSetting ("-target", "Specify which backend to use", List("jvm-1.5", "jvm-1.4", "msil", "cldc"), "jvm-1.4") val migrate = BooleanSetting("-migrate", "Assist in migrating from Scala version 1.0") val debug = BooleanSetting("-debug", "Output debugging messages") val statistics = BooleanSetting("-statistics", "Print compiler statistics") diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index b9934346cf..fde60bf684 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -18,16 +18,16 @@ abstract class TreeGen { /** Builds a reference to value whose type is given stable prefix. */ - def mkQualifier(tpe: Type): Tree = tpe match { + def mkAttributedQualifier(tpe: Type): Tree = tpe match { case NoPrefix => EmptyTree case ThisType(clazz) => - if (clazz.isRoot || clazz.isEmptyPackageClass) EmptyTree else This(clazz) + if (clazz.isRoot || clazz.isEmptyPackageClass) EmptyTree else mkAttributedThis(clazz) case SingleType(pre, sym) => if (sym.isThisSkolem) { - mkQualifier(ThisType(sym.deSkolemize)) + mkAttributedQualifier(ThisType(sym.deSkolemize)) } else { - val qual = mkStableRef(pre, sym); + val qual = mkAttributedStableRef(pre, sym); qual.tpe match { case MethodType(List(), restpe) => Apply(qual, List()) setType restpe @@ -38,27 +38,27 @@ abstract class TreeGen { case TypeRef(pre, sym, args) => assert(phase.erasedTypes); if (sym.isModuleClass && !sym.isRoot) { - val qual = Select(mkQualifier(sym.owner.tpe), sym.sourceModule); + val qual = mkAttributedSelect(mkAttributedQualifier(sym.owner.tpe), sym.sourceModule); qual.tpe match { case MethodType(List(), restpe) => Apply(qual, List()) setType restpe case _ => qual } - } else This(sym) + } else mkAttributedThis(sym) case _ => throw new Error("bad qualifier: " + tpe) } /** Builds a reference to given symbol with given stable prefix. */ - def mkRef(pre: Type, sym: Symbol): Tree = { - val qual = mkQualifier(pre); - if (qual == EmptyTree) Ident(sym) else Select(qual, sym) + def mkAttributedRef(pre: Type, sym: Symbol): Tree = { + val qual = mkAttributedQualifier(pre); + if (qual == EmptyTree) mkAttributedIdent(sym) else mkAttributedSelect(qual, sym) } /** Builds a reference to given symbol. */ - def mkRef(sym: Symbol): Tree = - if (sym.owner.isClass) mkRef(sym.owner.thisType, sym) else Ident(sym); + def mkAttributedRef(sym: Symbol): Tree = + if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym) else mkAttributedIdent(sym); /** Replaces tree type with a stable type if possible */ def stabilize(tree: Tree): Tree = tree match { @@ -66,43 +66,46 @@ abstract class TreeGen { if (tree.symbol.isStable) tree.setType(singleType(tree.symbol.owner.thisType, tree.symbol)) else tree case Select(qual, _) => - if (tree.symbol.isStable && qual.tpe.isStable) tree.setType(singleType(qual.tpe, tree.symbol)) + assert(tree.symbol != null); + assert(qual.tpe != null) + if (tree.symbol.isStable && qual.tpe.isStable) + tree.setType(singleType(qual.tpe, tree.symbol)) else tree case _ => tree } /** Cast `tree' to type `pt' */ - def cast(tree: Tree, pt: Type): Tree = { + def mkAttributedCast(tree: Tree, pt: Type): Tree = { if (settings.debug.value) log("casting " + tree + ":" + tree.tpe + " to " + pt); assert(!tree.tpe.isInstanceOf[MethodType], tree); typer.typed { atPos(tree.pos) { - Apply(TypeApply(Select(tree, Object_asInstanceOf), List(TypeTree(pt))), List()) + Apply(TypeApply(mkAttributedSelect(tree, Object_asInstanceOf), List(TypeTree(pt))), List()) } } } /** Builds a reference with stable type to given symbol */ - def mkStableRef(pre: Type, sym: Symbol): Tree = stabilize(mkRef(pre, sym)); - def mkStableRef(sym: Symbol): Tree = stabilize(mkRef(sym)); + def mkAttributedStableRef(pre: Type, sym: Symbol): Tree = stabilize(mkAttributedRef(pre, sym)); + def mkAttributedStableRef(sym: Symbol): Tree = stabilize(mkAttributedRef(sym)); - def This(sym: Symbol): Tree = - global.This(sym.name) setSymbol sym setType sym.thisType; + def mkAttributedThis(sym: Symbol): Tree = + This(sym.name) setSymbol sym setType sym.thisType; - def Ident(sym: Symbol): Tree = { + def mkAttributedIdent(sym: Symbol): Tree = { assert(sym.isTerm); - global.Ident(sym.name) setSymbol sym setType sym.tpe; + Ident(sym.name) setSymbol sym setType sym.tpe; } - def Select(qual: Tree, sym: Symbol): Tree = + def mkAttributedSelect(qual: Tree, sym: Symbol): Tree = if (qual.symbol != null && (qual.symbol.name.toTermName == nme.ROOT || qual.symbol.name.toTermName == nme.EMPTY_PACKAGE_NAME)) { - this.Ident(sym) + mkAttributedIdent(sym) } else { assert(sym.isTerm); - val result = global.Select(qual, sym.name) setSymbol sym; + val result = Select(qual, sym.name) setSymbol sym; if (qual.tpe != null) result setType qual.tpe.memberType(sym); result } @@ -119,7 +122,7 @@ abstract class TreeGen { */ Apply( TypeApply( - Select(value, sym), + mkAttributedSelect(value, sym), List(TypeTree(tpe))), List()) } @@ -138,7 +141,7 @@ abstract class TreeGen { Apply( TypeApply( - Select(value, sym), + mkAttributedSelect(value, sym), List(TypeTree(tpe))), List()) } @@ -150,14 +153,27 @@ abstract class TreeGen { /** Builds a list with given head and tail. */ def mkNewCons(head: Tree, tail: Tree): Tree = - New(Apply(mkRef(definitions.ConsClass), List(head,tail))); + New(Apply(mkAttributedRef(definitions.ConsClass), List(head,tail))); /** Builds a list with given head and tail. */ def mkNil: Tree = - mkRef(definitions.NilModule); + mkAttributedRef(definitions.NilModule); /** Builds a pair */ def mkNewPair(left: Tree, right: Tree) = - New(Apply(mkRef(definitions.TupleClass(2)), List(left,right))); + New(Apply(mkAttributedRef(definitions.TupleClass(2)), List(left,right))); + + def mkCached(cvar: Symbol, expr: Tree): Tree = { + val cvarRef = if (cvar.owner.isClass) Select(This(cvar.owner), cvar) else Ident(cvar); + Block( + List( + If(Apply(Select(cvarRef, nme.eq), List(Literal(Constant(null)))), + Assign(cvarRef, expr), + EmptyTree)), + cvarRef + ) + } + def mkRuntimeCall(meth: Name, args: List[Tree]): Tree = + Apply(Select(mkAttributedRef(ScalaRunTimeModule), meth), args); } diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 3477a84f03..f428e13411 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -260,6 +260,7 @@ abstract class TreePrinters { print(x.tag match { case NullTag => "null" case StringTag => "\"" + x.stringValue + "\"" + case ClassTag => x.stringValue + ".class" case CharTag => "\'" + x.charValue + "\'" case LongTag => x.longValue.toString() + "L"; case _ => x.value.toString() diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 77656ea50d..c475ece753 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -474,8 +474,6 @@ trait Trees requires Global { // if (pos == 74) Thread.dumpStack(); ret; } - - } def Select(qualifier: Tree, sym: Symbol): Select = diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 35bb620932..0ecfeb9b3e 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -10,6 +10,8 @@ import util.ListBuffer; import symtab.Flags; import Tokens._; +//todo verify when stableId's should be just plain qualified type ids + /** Performs the following context-free rewritings: * (1) Places all pattern variables in Bind nodes. In a pattern, for identifiers `x': * x => x @ _ @@ -236,7 +238,6 @@ trait Parsers requires SyntaxAnalyzer { case Select(qual, name) => Select(qual, name.toTypeName).setPos(tree.pos) case _ => - System.out.println(tree);//debug syntaxError(tree.pos, "identifier expected", false); errorTypeTree } @@ -348,14 +349,14 @@ trait Parsers requires SyntaxAnalyzer { if (in.token == THIS) { t = atPos(in.skipToken()) { This(nme.EMPTY.toTypeName) } if (!thisOK || in.token == DOT) - t = { selectors(t, typeOK, accept(DOT)) } + t = selectors(t, typeOK, accept(DOT)) } else if (in.token == SUPER) { t = atPos(in.skipToken()) { Super(nme.EMPTY.toTypeName, mixinQualifierOpt()) } t = atPos(accept(DOT)) { selector(t) } if (in.token == DOT) - t = { selectors(t, typeOK, in.skipToken()) } + t = selectors(t, typeOK, in.skipToken()) } else { val i = atPos(in.currentPos) { Ident(ident()) } t = i; @@ -365,15 +366,15 @@ trait Parsers requires SyntaxAnalyzer { in.nextToken(); t = atPos(i.pos) { This(i.name.toTypeName) } if (!thisOK || in.token == DOT) - t = { selectors(t, typeOK, accept(DOT)) } + t = selectors(t, typeOK, accept(DOT)) } else if (in.token == SUPER) { in.nextToken(); t = atPos(i.pos) { Super(i.name.toTypeName, mixinQualifierOpt()) } - t = atPos(accept(DOT)) { selector(t)} + t = atPos(accept(DOT)) {selector(t)} if (in.token == DOT) - t = { selectors(t, typeOK, in.skipToken()) } + t = selectors(t, typeOK, in.skipToken()) } else { - t = { selectors(t, typeOK, pos) } + t = selectors(t, typeOK, pos) } } } @@ -804,6 +805,7 @@ trait Parsers requires SyntaxAnalyzer { * SimpleExpr1 ::= literal * | xLiteral * | Path + * | StableId `.' class * | `(' [Expr] `)' * | BlockExpr * | SimpleExpr `.' Id @@ -874,7 +876,7 @@ trait Parsers requires SyntaxAnalyzer { while (true) { in.token match { case DOT => - t = atPos(in.skipToken()) { selector(t) } + t = atPos(in.skipToken()) { selector(t) } case LBRACKET => t match { case Ident(_) | Select(_, _) => diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala index d123f0c9fd..8470d6ef10 100644 --- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala +++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala @@ -212,7 +212,7 @@ trait CodeFactory requires TransMatcher { /* Apply( TypeApply( - gen.mkRef(definitions.MatchError_fail), + gen.mkAttributedRef(definitions.MatchError_fail), List(TypeTree(tpe)) ), List( @@ -225,7 +225,7 @@ trait CodeFactory requires TransMatcher { /* // ?! def ThrowMatchError(pos:int , tree:Tree ) = Apply( - gen.mkRef(definitions.MatchError_report), + gen.mkAttributedRef(definitions.MatchError_report), List( Literal(cunit.toString()), Literal(Position.line(cunit.source, pos)), @@ -242,7 +242,7 @@ trait CodeFactory requires TransMatcher { def newPair(left: Tree, right: Tree) = New( Apply( - gen.mkRef(definitions.TupleClass(2)), + gen.mkAttributedRef(definitions.TupleClass(2)), List(left,right) ) ); diff --git a/src/compiler/scala/tools/nsc/matching/RightTracers.scala b/src/compiler/scala/tools/nsc/matching/RightTracers.scala index 0041c4351f..d95aad1d2a 100644 --- a/src/compiler/scala/tools/nsc/matching/RightTracers.scala +++ b/src/compiler/scala/tools/nsc/matching/RightTracers.scala @@ -256,7 +256,7 @@ abstract class RightTracerInScala extends Autom2Scala { tmapBody.get(I).asInstanceOf[Tree] ) :: ncases; //i = i + 1 } - //gen.Switch( gen.Ident( pos, targetSym ), + //gen.Switch( gen.mkAttributedIdent( pos, targetSym ), // tags, // targets, // code_error()/*cannot happen*/ ); @@ -314,7 +314,7 @@ abstract class RightTracerInScala extends Autom2Scala { //j = j + 1; } if( n > 0 ) - //gen.Switch( gen.Ident( pos, targetSym ), tags, targets, code_error() ); + //gen.Switch( gen.mkAttributedIdent( pos, targetSym ), tags, targets, code_error() ); Match(Ident( targetSym ), ncases); else code_error(); @@ -438,7 +438,7 @@ abstract class RightTracerInScala extends Autom2Scala { var it = vars.iterator(); while(it.hasNext()) { val vble = it.next().asInstanceOf[Symbol]; - val rhs = gen.Ident( curSym ); + val rhs = gen.mkAttributedIdent( curSym ); stms = prependToHelpVar( vble , rhs) :: stms; } diff --git a/src/compiler/scala/tools/nsc/matching/SequenceMatchers.scala b/src/compiler/scala/tools/nsc/matching/SequenceMatchers.scala index 3d4508a747..f3b8d30170 100644 --- a/src/compiler/scala/tools/nsc/matching/SequenceMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/SequenceMatchers.scala @@ -143,7 +143,7 @@ trait SequenceMatchers requires TransMatcher { new WordAutomInScala{ val dfa = dfa1; val owner = _m.owner; - val optim = settings.target == "jvm"; + val optim = settings.target.value startsWith "jvm"; val elementType = elementType1; } scalaAut.translate(); diff --git a/src/compiler/scala/tools/nsc/symtab/Constants.scala b/src/compiler/scala/tools/nsc/symtab/Constants.scala index 263a02a46a..e040a0c84b 100644 --- a/src/compiler/scala/tools/nsc/symtab/Constants.scala +++ b/src/compiler/scala/tools/nsc/symtab/Constants.scala @@ -2,7 +2,6 @@ * Copyright 2005 LAMP/EPFL * @author Martin Odersky */ - // $Id$ package scala.tools.nsc.symtab; @@ -24,9 +23,10 @@ trait Constants requires SymbolTable { final val DoubleTag = LITERALdouble - LITERAL; final val StringTag = LITERALstring - LITERAL; final val NullTag = LITERALnull - LITERAL; - final val ZeroTag = LITERALzero - LITERAL; + final val ClassTag = LITERALclass - LITERAL; case class Constant(value: Any) { + val tag: int = if (value.isInstanceOf[unit]) UnitTag else if (value.isInstanceOf[boolean]) BooleanTag @@ -38,6 +38,7 @@ trait Constants requires SymbolTable { else if (value.isInstanceOf[float]) FloatTag else if (value.isInstanceOf[double]) DoubleTag else if (value.isInstanceOf[String]) StringTag + else if (value.isInstanceOf[Type]) ClassTag else if (value == null) NullTag else throw new Error("bad constant value: " + value); @@ -53,6 +54,7 @@ trait Constants requires SymbolTable { case DoubleTag => DoubleClass.tpe case StringTag => StringClass.tpe case NullTag => AllRefClass.tpe + case ClassTag => ClassClass.tpe } /** We need the equals method to take account of tags as well as values */ @@ -184,10 +186,13 @@ trait Constants requires SymbolTable { } def stringValue: String = - if (value == null) "null" else value.toString(); + if (value == null) "null" + else if (tag == ClassTag) signature(typeValue) + else value.toString(); + + def typeValue: Type = value.asInstanceOf[Type] override def hashCode(): int = if (value == null) 0 else value.hashCode() * 41 + 17; } - } diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 443ccc509f..ec055b0614 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -34,6 +34,7 @@ trait Definitions requires SymbolTable { var AllRefClass: Symbol = _; var AllClass: Symbol = _; + var ClassClass: Symbol = _; var StringClass: Symbol = _; var ThrowableClass: Symbol = _; var NullPointerExceptionClass: Symbol = _; @@ -75,6 +76,7 @@ trait Definitions requires SymbolTable { var ArrayClass: Symbol = _; var SerializableClass: Symbol = _; var PredefModule: Symbol = _; + def Predef_classOf = getMember(PredefModule, nme.classOf) var ConsoleModule: Symbol = _; var MatchErrorClass: Symbol = _; var MatchErrorModule: Symbol = _; @@ -444,6 +446,7 @@ trait Definitions requires SymbolTable { AllClass = newClass(ScalaPackageClass, nme.All, anyparam) .setFlag(ABSTRACT | TRAIT | FINAL); + ClassClass = getClass("java.lang.Class"); StringClass = getClass("java.lang.String"); ThrowableClass = getClass("java.lang.Throwable"); NullPointerExceptionClass = getClass("java.lang.NullPointerException"); diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index 39975e0c2c..e841813272 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -226,6 +226,7 @@ trait StdNames requires SymbolTable { val caseElement = newTermName("caseElement"); val caseName = newTermName("caseName"); val checkCastability = newTermName("checkCastability"); + val classOf = newTermName("classOf"); val coerce = newTermName("coerce"); val defaultValue = newTermName("defaultValue"); val dummy = newTermName("$dummy"); @@ -235,11 +236,11 @@ trait StdNames requires SymbolTable { val equals_ = newTermName("equals"); val ex = newTermName("ex"); val fail = newTermName("fail"); - val report = newTermName("report"); val false_ = newTermName("false"); val filter = newTermName("filter"); val finalize_ = newTermName("finalize"); val flatMap = newTermName("flatMap"); + val forName = newTermName("forName"); val foreach = newTermName("foreach"); val getClass_ = newTermName("getClass"); val hasAsInstance = newTermName("hasAsInstance"); @@ -263,6 +264,7 @@ trait StdNames requires SymbolTable { val null_ = newTermName("null"); val predef = newTermName("predef"); val print = newTermName("print"); + val report = newTermName("report"); val runtime = newTermName("runtime"); val readResolve = newTermName("readResolve"); val scala_ = newTermName("scala"); diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala index fc7dc39a7a..b75dbeaf39 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/PickleFormat.scala @@ -43,7 +43,7 @@ object PickleFormat { * | 32 LITERALdouble len_Nat value_Long * | 33 LITERALstring len_Nat name_Ref * | 34 LITERALnull len_Nat - * | 35 LITERALzero len_Nat + * | 35 LITERALclass len_Nat type_Ref * | 40 ATTRIBUTE sym_Ref type_Ref {constant_Ref} <not yet> * | 72 PosTYPEsym len_Nat pos_Nat SymbolInfo * | 73 PosALIASsym len_Nat pos_Nat SymbolInfo @@ -94,7 +94,7 @@ object PickleFormat { final val LITERALdouble = 32; final val LITERALstring = 33; final val LITERALnull = 34; - final val LITERALzero = 35; + final val LITERALclass = 35; final val ATTRIBUTE = 40; final val firstSymTag = NONEsym; diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 58bd438d1b..7f70bb4bf9 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -130,7 +130,10 @@ abstract class Pickler extends SubComponent { private def putTypes(tps: List[Type]): unit = tps foreach putType; private def putConstant(c: Constant) = - if (putEntry(c) && c.tag == StringTag) putEntry(newTermName(c.stringValue)); + if (putEntry(c)) { + if (c.tag == StringTag) putEntry(newTermName(c.stringValue)) + else if (c.tag == ClassTag) putEntry(c.typeValue) + } /* private def putAttribute(attr: AttrInfo): unit = if (putEntry(attr)) { @@ -226,6 +229,7 @@ abstract class Pickler extends SubComponent { else if (c.tag == FloatTag) writeLong(Float.floatToIntBits(c.floatValue)) else if (c.tag == DoubleTag) writeLong(Double.doubleToLongBits(c.doubleValue)); else if (c.tag == StringTag) writeRef(newTermName(c.stringValue)); + else if (c.tag == ClassTag) writeRef(c.typeValue); LITERAL + c.tag /* case Pair(tp, cs) => diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index fea767d9dc..d57fef08c2 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -244,6 +244,7 @@ abstract class UnPickler { case LITERALdouble => Constant(Double.longBitsToDouble(readLong(len))) case LITERALstring => Constant(readNameRef().toString()) case LITERALnull => Constant(null) + case LITERALclass => Constant(readTypeRef()) case _ => errorBadSignature("bad constant tag: " + tag) } }; diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala new file mode 100755 index 0000000000..7803e3f701 --- /dev/null +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -0,0 +1,97 @@ +/* NSC -- new scala compiler + * Copyright 2005 LAMP/EPFL + * @author + */ +// $Id: Mixin.scala 7249 2006-04-25 16:01:59 +0200 (Tue, 25 Apr 2006) odersky $ +package scala.tools.nsc.transform; + +import symtab._; +import Flags._; +import scala.tools.nsc.util.Position; +import scala.collection.mutable.{ListBuffer, HashMap}; + +abstract class CleanUp extends Transform { + import global._; + import definitions._; + import posAssigner.atPos; + + /** the following two members override abstract members in Transform */ + val phaseName: String = "cleanup"; + + protected def newTransformer(unit: CompilationUnit): Transformer = new CleanUpTransformer(unit); + + class CleanUpTransformer(unit: CompilationUnit) extends Transformer { + + private val newDefs = new ListBuffer[Tree] + private val classConstantMeth = new HashMap[String, Symbol] + + private var localTyper: analyzer.Typer = null; + + private def freshClassConstantMethName() = unit.fresh.newName("class$Method") + private def freshClassConstantVarName() = unit.fresh.newName("class$Cache") + + private def classConstantMethod(pos: int, sig: String): Symbol = classConstantMeth.get(sig) match { + case Some(meth) => + meth + case None => + val forName = getMember(ClassClass.linkedModule, nme.forName) + val owner = currentOwner.enclClass + + val cvar = owner.newVariable(pos, freshClassConstantVarName()) + .setFlag(PRIVATE | STATIC | MUTABLE | SYNTHETIC).setInfo(ClassClass.tpe) + owner.info.decls.enter(cvar) + val cdef = + localTyper.typed { + atPos(pos) { + ValDef(cvar, Literal(Constant(null))) + } + } + + val meth = owner.newMethod(pos, freshClassConstantMethName()) + .setFlag(PRIVATE | STATIC | SYNTHETIC).setInfo(MethodType(List(), ClassClass.tpe)) + owner.info.decls.enter(meth) + val mdef = + localTyper.typed { + atPos(pos) { + DefDef(meth, vparamss => + gen.mkCached( + cvar, + Apply( + gen.mkAttributedRef(forName), List(Literal(sig))))) + } + } + + newDefs.append(cdef, mdef); + classConstantMeth.update(sig, meth) + meth + } + + override def transformUnit(unit: CompilationUnit) = + if (settings.target.value != "jvm-1.5") { + unit.body = transform(unit.body) + } + + override def transform(tree: Tree): Tree = tree match { + case Template(parents, body) => + classConstantMeth.clear + newDefs.clear + localTyper = typer.atOwner(tree, currentOwner) + val body1 = transformTrees(body) + copy.Template(tree, parents, newDefs.toList ::: body1) + case Literal(c) if (c.tag == ClassTag) => + val tpe = c.typeValue + atPos(tree.pos) { + localTyper.typed { + if (isValueClass(tpe.symbol)) + gen.mkRuntimeCall(tpe.symbol.name.toString() + "TYPE", List()) + else + Apply( + gen.mkAttributedRef(classConstantMethod(tree.pos, signature(tpe))), + List()) + } + } + case _ => + super.transform(tree) + } + } +} diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 34627ce939..8839a3f27b 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -57,10 +57,10 @@ abstract class Constructors extends Transform { override def transform(tree: Tree): Tree = tree match { case Apply(Select(This(_), _), List()) if ((tree.symbol hasFlag PARAMACCESSOR) && tree.symbol.owner == clazz) => - gen.Ident(parameter(tree.symbol.accessed)) setPos tree.pos; - case Select(This(_), _) - if ((tree.symbol hasFlag PARAMACCESSOR) && tree.symbol.owner == clazz) => - gen.Ident(parameter(tree.symbol)) setPos tree.pos; + gen.mkAttributedIdent(parameter(tree.symbol.accessed)) setPos tree.pos; + case Select(This(_), _) + if ((tree.symbol hasFlag PARAMACCESSOR) && tree.symbol.owner == clazz) => + gen.mkAttributedIdent(parameter(tree.symbol)) setPos tree.pos case This(_) => thisRefSeen = true; super.transform(tree) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 50c1ee16be..64474cb030 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -155,8 +155,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { atPos(tree.pos) { val sym = tree.tpe.symbol; if (sym == UnitClass) { - if (treeInfo.isPureExpr(tree)) gen.mkRef(BoxedUnit_UNIT) - else Block(List(tree), gen.mkRef(BoxedUnit_UNIT)) + if (treeInfo.isPureExpr(tree)) gen.mkAttributedRef(BoxedUnit_UNIT) + else Block(List(tree), gen.mkAttributedRef(BoxedUnit_UNIT)) } else if (sym == ArrayClass) { val elemClass = tree.tpe.typeArgs.head.symbol; val boxedClass = if (isValueClass(elemClass)) boxedArrayClass(elemClass) @@ -164,7 +164,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { Apply(Select(New(TypeTree(boxedClass.tpe)), nme.CONSTRUCTOR), List(tree)) } else { val boxedModule = boxedClass(tree.tpe.symbol).linkedModule; - Apply(Select(gen.mkRef(boxedModule), nme.box), List(tree)) + Apply(Select(gen.mkAttributedRef(boxedModule), nme.box), List(tree)) } } } @@ -173,7 +173,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { private def boxArray(tree: Tree): Tree = typed { atPos(tree.pos) { - runtimeCall(nme.boxArray, List(tree)) + gen.mkRuntimeCall(nme.boxArray, List(tree)) } } @@ -185,9 +185,6 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { 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 { @@ -198,21 +195,21 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { } else { if (pt.symbol == BooleanClass) { val tree1 = adaptToType(tree, boxedClass(BooleanClass).tpe); - runtimeCall(nme.booleanValue, List(tree1)) + gen.mkRuntimeCall(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()) + gen.mkRuntimeCall(newTermName(elemClass.name.toString() + "Tag"), List()) else Literal(signature(pt.typeArgs.head)); //System.out.println("unboxing " + tree + ":" + tree.tpe + " to " + pt);//DEBUG - runtimeCall(nme.arrayValue, List(tree1, elemTag)) + gen.mkRuntimeCall(nme.arrayValue, List(tree1, elemTag)) } else { assert(isNumericValueClass(pt.symbol)); val tree1 = adaptToType(tree, BoxedNumberClass.tpe); - runtimeCall(unboxOp(pt), List(tree1)) + gen.mkRuntimeCall(unboxOp(pt), List(tree1)) } } } @@ -223,14 +220,14 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { typed { atPos(tree.pos) { evalOnce(tree, x => - gen.cast( + gen.mkAttributedCast( If( Apply( TypeApply( Select(x(), Object_isInstanceOf), List(TypeTree(BoxedArrayClass.tpe))), List()), - unbox(gen.cast(x(), BoxedArrayClass.tpe), pt), + unbox(gen.mkAttributedCast(x(), BoxedArrayClass.tpe), pt), x()), pt)) } @@ -239,7 +236,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { typed { atPos(tree.pos) { evalOnce(tree, x => - gen.cast( + gen.mkAttributedCast( If( Apply( TypeApply( @@ -251,7 +248,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer { pt)) } } - else gen.cast(tree, pt); + else gen.mkAttributedCast(tree, pt); /** Is symbol a member of unboxed arrays (which will be expanded directly later)? */ private def isUnboxedArrayMember(sym: Symbol) = ( diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 4f71be7b62..5acda1e704 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -96,8 +96,8 @@ abstract class ExplicitOuter extends InfoTransform { /** The first outer selection from currently transformed tree */ protected def outerValue: Tree = - if (outerParam != NoSymbol) gen.Ident(outerParam) - else outerSelect(gen.This(currentOwner.enclClass)); + if (outerParam != NoSymbol) gen.mkAttributedIdent(outerParam) + else outerSelect(gen.mkAttributedThis(currentOwner.enclClass)); /** The path * `base'.$outer ... .$outer @@ -295,13 +295,13 @@ abstract class ExplicitOuter extends InfoTransform { //System.out.println("adding mixin constructor for " + currentOwner.enclClass + " " + mclazz + " " + currentOwner.enclClass.thisType.baseType(mclazz));//DEBUG var pre = currentOwner.enclClass.thisType.baseType(mclazz).prefix; if (pre == NoPrefix) pre = outerClass(mclazz).thisType; - gen.mkQualifier(pre) + gen.mkAttributedQualifier(pre) } else if (qual.isInstanceOf[This]) { assert(outerParam != NoSymbol); outerValue } else { var pre = qual.tpe.prefix; if (pre == NoPrefix) pre = outerClass(sym.owner).thisType; - gen.mkQualifier(pre) + gen.mkAttributedQualifier(pre) } } copy.Apply(tree, sel, args ::: List(outerVal)) diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index d2165492d1..53ddc8dce2 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -90,7 +90,7 @@ abstract class Flatten extends InfoTransform { case Select(qual, name) if (sym.isStaticModule && !sym.owner.isPackageClass) => atPhase(phase.next) { atPos(tree.pos) { - gen.mkRef(sym) + gen.mkAttributedRef(sym) } } case _ => diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index ccd30c1728..739bdf90ab 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -238,21 +238,21 @@ abstract class LambdaLift extends InfoTransform { private def memberRef(sym: Symbol) = { val clazz = sym.owner.enclClass - val qual = if (clazz == currentOwner.enclClass) gen.This(clazz) - else { - sym resetFlag(LOCAL | PRIVATE) - if (clazz.isStaticOwner) gen.mkQualifier(clazz.thisType) - else outerPath(outerValue, clazz) - } + val qual = if (clazz == currentOwner.enclClass) gen.mkAttributedThis(clazz) + else { + sym resetFlag(LOCAL | PRIVATE); + if (clazz.isStaticOwner) gen.mkAttributedQualifier(clazz.thisType) + else outerPath(outerValue, clazz) + } Select(qual, sym) setType sym.tpe } private def proxyRef(sym: Symbol) = { if (sym.owner.isLabel) // - gen.Ident(sym) // bq: account for the fact that LambdaLift does not know how to handle references to LabelDef parameters. + gen.mkAttributedIdent(sym) // bq: account for the fact that LambdaLift does not know how to handle references to LabelDef parameters. else { // val psym = proxy(sym); - if (psym.isLocal) gen.Ident(psym) else memberRef(psym) + if (psym.isLocal) gen.mkAttributedIdent(psym) else memberRef(psym) } } @@ -334,7 +334,7 @@ abstract class LambdaLift extends InfoTransform { atPos(tree.pos) { val tp = tree.tpe val elemTree = typed { Select(tree1 setType sym.tpe, nme.elem) } - if (elemTree.tpe.symbol != tp.symbol) gen.cast(elemTree, tp) else elemTree + if (elemTree.tpe.symbol != tp.symbol) gen.mkAttributedCast(elemTree, tp) else elemTree } else tree1 case _ => diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index 9a93b6c85a..f3eb029040 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -201,7 +201,7 @@ abstract class LiftCode extends Transform { case x: Double => Literal(Constant(x)) case c: CaseClass => val name = objectName(c); - if (name.length() != 0) gen.mkRef(definitions.getModule(name)) + if (name.length() != 0) gen.mkAttributedRef(definitions.getModule(name)) else { val name = className(c); if (name.length() == 0) throw new Error("don't know how to inject " + value); @@ -210,7 +210,7 @@ abstract class LiftCode extends Transform { injectedArgs += inject(c.caseElement(i)); New(Ident(definitions.getClass(name)), List(injectedArgs.toList)) } - case null => gen.mkRef(definitions.getModule("scala.reflect.NoType")) + case null => gen.mkAttributedRef(definitions.getModule("scala.reflect.NoType")) case _ => throw new Error("don't know how to inject " + value); } @@ -261,3 +261,4 @@ abstract class LiftCode extends Transform { // case Alternative(trees) => // case Star(elem) => // case Bind(name, body) => + diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index e8f36bf785..6c96c3985d 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -246,7 +246,7 @@ abstract class Mixin extends InfoTransform { } } - private def selfRef(pos: int) = gen.Ident(self) setPos pos; + private def selfRef(pos: int) = gen.mkAttributedIdent(self) setPos pos; private def staticRef(sym: Symbol) = { sym.owner.info; @@ -254,7 +254,7 @@ abstract class Mixin extends InfoTransform { if (sym.owner.sourceModule == NoSymbol) { assert(false, "" + sym + " in " + sym.owner + " in " + sym.owner.owner + " " + sym.owner.owner.info.decls.toList);//debug } - Select(gen.mkRef(sym.owner.sourceModule), sym); + Select(gen.mkAttributedRef(sym.owner.sourceModule), sym); } private def addNewDefs(clazz: Symbol, stats: List[Tree]): List[Tree] = { @@ -319,7 +319,7 @@ abstract class Mixin extends InfoTransform { } else { assert(sym.alias != NoSymbol, sym); addDefDef(sym, vparams => - Apply(staticRef(sym.alias), gen.This(clazz) :: (vparams map Ident))) + Apply(staticRef(sym.alias), gen.mkAttributedThis(clazz) :: (vparams map Ident))) } } } @@ -350,7 +350,7 @@ abstract class Mixin extends InfoTransform { val qual1 = if (!qual.isInstanceOf[Super]) qual else if (currentOwner.enclClass.isImplClass) selfRef(qual.pos) - else gen.This(currentOwner.enclClass); + else gen.mkAttributedThis(currentOwner.enclClass); Apply(staticRef(target), qual1 :: args) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index a5905db70d..259e5e248e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -29,7 +29,7 @@ trait Contexts requires Analyzer { var sc = startContext; def addImport(pkg: Symbol): unit = { assert(pkg != null); - val qual = gen.mkStableRef(pkg); + val qual = gen.mkAttributedStableRef(pkg); sc = sc.makeNewImport( Import(qual, List(Pair(nme.WILDCARD, null))) .setSymbol(NoSymbol.newImport(Position.NOPOS).setInfo(ImportType(qual))) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 386d369d71..cfe1b02f76 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -61,20 +61,12 @@ abstract class RefChecks extends InfoTransform { } // def m: T = { if (m$ == null) m$ = new m$class; m$ } - def newModuleAccessDef(accessor: Symbol, mvar: Symbol) = { - var mvarRef = if (mvar.owner.isClass) Select(This(mvar.owner), mvar) else Ident(mvar); + def newModuleAccessDef(accessor: Symbol, mvar: Symbol) = DefDef(accessor, vparamss => - Block( - List( - If( - Apply(Select(mvarRef, nme.eq), List(Literal(Constant(null)))), - Assign(mvarRef, - New(TypeTree(mvar.tpe), - List(for (val pt <- mvar.tpe.symbol.primaryConstructor.info.paramTypes) - yield This(accessor.owner.enclClass)))),//??? - EmptyTree)), - mvarRef)) - } + gen.mkCached(mvar, + New(TypeTree(mvar.tpe), + List(for (val pt <- mvar.tpe.symbol.primaryConstructor.info.paramTypes) + yield This(accessor.owner.enclClass))))) // def m: T; def newModuleAccessDcl(accessor: Symbol) = @@ -619,7 +611,7 @@ abstract class RefChecks extends InfoTransform { val tree1 = Select(This(base), superAcc); if (settings.debug.value) log("super-replacement: " + tree + "=>" + tree1); result = atPos(tree.pos) { - Select(gen.This(base), superAcc) setType superAcc.tpe + Select(gen.mkAttributedThis(base), superAcc) setType superAcc.tpe } } case This(_) => diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 4eb38f349b..eb528c8eae 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -60,7 +60,7 @@ abstract class SuperAccessors extends transform.Transform { accDefBuf(clazz) += typed(DefDef(superAcc, vparamss => EmptyTree)) } atPos(sup.pos) { - Select(gen.This(clazz), superAcc) setType tree.tpe; + Select(gen.mkAttributedThis(clazz), superAcc) setType tree.tpe; } } else tree case Apply(fn, args) => diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index cc0f89f4ea..6b11c5818f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -44,7 +44,7 @@ trait SyntheticMethods requires Analyzer { def caseElementMethod: Tree = { val method = syntheticMethod( nme.caseElement, FINAL, MethodType(List(IntClass.tpe), AnyClass.tpe)); - val caseFields = clazz.caseFieldAccessors map gen.mkRef; + val caseFields = clazz.caseFieldAccessors map gen.mkAttributedRef; typed( DefDef(method, vparamss => if (caseFields.isEmpty) Literal(Constant(null)) @@ -83,7 +83,7 @@ trait SyntheticMethods requires Analyzer { val method = syntheticMethod( name, 0, MethodType(target.tpe.paramTypes.tail, target.tpe.resultType)); typed(DefDef(method, vparamss => - Apply(gen.mkRef(target), This(clazz) :: (vparamss.head map Ident)))); + Apply(gen.mkAttributedRef(target), This(clazz) :: (vparamss.head map Ident)))); } def isSerializable(clazz: Symbol): Boolean = @@ -94,7 +94,7 @@ trait SyntheticMethods requires Analyzer { // but then it is renamed !!! val method = newSyntheticMethod(nme.readResolve, PROTECTED, MethodType(List(), ObjectClass.tpe)); - typed(DefDef(method, vparamss => gen.mkRef(clazz.sourceModule))) + typed(DefDef(method, vparamss => gen.mkAttributedRef(clazz.sourceModule))) } def newAccessorMethod(tree: Tree): Tree = tree match { @@ -136,7 +136,7 @@ trait SyntheticMethods requires Analyzer { if (getter != NoSymbol) ts += typed(DefDef( getter, - vparamss => if (sym hasFlag DEFERRED) EmptyTree else gen.mkRef(sym))) + vparamss => if (sym hasFlag DEFERRED) EmptyTree else gen.mkAttributedRef(sym))) } def addBeanSetterMethod(sym: Symbol) = { @@ -146,7 +146,7 @@ trait SyntheticMethods requires Analyzer { setter, vparamss => if (sym hasFlag DEFERRED) EmptyTree - else Apply(gen.mkRef(sym), List(Ident(vparamss.head.head))))) + else Apply(gen.mkAttributedRef(sym), List(Ident(vparamss.head.head))))) } if (!phase.erasedTypes) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 9680a32292..0474700a1b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1005,7 +1005,10 @@ trait Typers requires Analyzer { if (tparams.length == args.length) { val targs = args map (.tpe) checkBounds(tree.pos, tparams, targs, "") - copy.TypeApply(tree, fun, args) setType restpe.subst(tparams, targs) + if (fun.symbol == Predef_classOf) + Literal(Constant(targs.head)) setPos tree.pos setType ClassClass.tpe + else + copy.TypeApply(tree, fun, args) setType restpe.subst(tparams, targs) } else { errorTree(tree, "wrong number of type parameters for "+treeSymTypeMsg(fun)) } @@ -1237,7 +1240,7 @@ trait Typers requires Analyzer { else if (!defSym.owner.isClass || defSym.owner.isPackageClass || defSym.isTypeParameterOrSkolem) pre = NoPrefix else - qual = atPos(tree.pos)(gen.mkQualifier(pre)) + qual = atPos(tree.pos)(gen.mkAttributedQualifier(pre)) } else { if (impSym.exists) { var impSym1 = NoSymbol @@ -1568,7 +1571,6 @@ trait Typers requires Analyzer { else typedIdent(name) - // todo: try with case Literal(Constant(())) case Literal(value) => tree setType ( if (value.tag == UnitTag) UnitClass.tpe diff --git a/src/compiler/scala/tools/nsc/util/ShowPickled.scala b/src/compiler/scala/tools/nsc/util/ShowPickled.scala index 56f0b4e965..c96a089217 100644 --- a/src/compiler/scala/tools/nsc/util/ShowPickled.scala +++ b/src/compiler/scala/tools/nsc/util/ShowPickled.scala @@ -44,7 +44,7 @@ object ShowPickled extends Names { case LITERALdouble => "LITERALdouble"; case LITERALstring => "LITERALstring"; case LITERALnull => "LITERALnull"; - case LITERALzero => "LITERALzero"; + case LITERALclass => "LITERALclass"; case _ => "***BAD TAG***(" + tag + ")"; } |