summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-01-07 15:00:26 -0800
committerPaul Phillips <paulp@improving.org>2012-01-07 22:51:02 -0800
commit04af2eb976bf5b3aec9577837ca03db327d09825 (patch)
treea352edd06f8e44d3c6703fe85c0502ce88989489 /src
parentf7ae1388324e6f0062ebe1cc348177304dd6419d (diff)
downloadscala-04af2eb976bf5b3aec9577837ca03db327d09825.tar.gz
scala-04af2eb976bf5b3aec9577837ca03db327d09825.tar.bz2
scala-04af2eb976bf5b3aec9577837ca03db327d09825.zip
Cleanups in Cleanup.
Seeing about getting delayedInit working (not to mention the breakage it is inflicting elsewhere) which led me into Cleanup and some of its buddies.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala7
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala18
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala147
-rw-r--r--src/library/scala/Symbol.scala4
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java18
6 files changed, 120 insertions, 85 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index aee3938715..d3af8e2623 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -267,10 +267,11 @@ trait Definitions extends reflect.api.StandardDefinitions {
(sym.name == name) && (sym.owner == PredefModule.moduleClass)
)
- lazy val ConsoleModule: Symbol = getRequiredModule("scala.Console")
+ lazy val ConsoleModule: Symbol = getRequiredModule("scala.Console")
lazy val ScalaRunTimeModule: Symbol = getRequiredModule("scala.runtime.ScalaRunTime")
- lazy val SymbolModule: Symbol = getRequiredModule("scala.Symbol")
- lazy val Symbol_apply = getMember(SymbolModule, nme.apply)
+ lazy val SymbolModule: Symbol = getRequiredModule("scala.Symbol")
+ lazy val Symbol_apply = SymbolModule.info decl nme.apply
+
def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq)
def arrayApplyMethod = getMember(ScalaRunTimeModule, nme.array_apply)
def arrayUpdateMethod = getMember(ScalaRunTimeModule, nme.array_update)
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index db1cf7f257..ea5565c581 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -578,6 +578,9 @@ trait StdNames extends NameManglers { self: SymbolTable =>
val testLessOrEqualThan: NameType = "testLessOrEqualThan"
val testLessThan: NameType = "testLessThan"
val testNotEqual: NameType = "testNotEqual"
+
+ val isBoxedNumberOrBoolean: NameType = "isBoxedNumberOrBoolean"
+ val isBoxedNumber: NameType = "isBoxedNumber"
def toUnaryName(name: TermName): TermName = name match {
case raw.MINUS => UNARY_-
@@ -628,6 +631,21 @@ trait StdNames extends NameManglers { self: SymbolTable =>
case _ => NO_NAME
}
+ val reflPolyCacheName: NameType = "reflPoly$Cache"
+ val reflClassCacheName: NameType = "reflClass$Cache"
+ val reflParamsCacheName: NameType = "reflParams$Cache"
+ val reflMethodCacheName: NameType = "reflMethod$Cache"
+ val reflMethodName: NameType = "reflMethod$Method"
+
+ private val reflectionCacheNames = Set[NameType](
+ reflPolyCacheName,
+ reflClassCacheName,
+ reflParamsCacheName,
+ reflMethodCacheName,
+ reflMethodName
+ )
+ def isReflectionCacheName(name: Name) = reflectionCacheNames exists (name startsWith _)
+
@switch def productAccessorName(j: Int): TermName = j match {
case 1 => nme._1
case 2 => nme._2
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 4ca55f53ea..96f2c5cc45 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -248,10 +248,13 @@ trait Trees extends api.Trees { self: SymbolTable =>
/** Block factory that flattens directly nested blocks.
*/
- def Block(stats: Tree*): Block = stats match {
- case Seq(b @ Block(_, _)) => b
- case Seq(stat) => Block(stats.toList, Literal(Constant(())))
- case Seq(_, rest @ _*) => Block(stats.init.toList, stats.last)
+ def Block(stats: Tree*): Block = {
+ if (stats.isEmpty) Block(Nil, Literal(Constant(())))
+ else stats match {
+ case Seq(b @ Block(_, _)) => b
+ case Seq(stat) => Block(stats.toList, Literal(Constant(())))
+ case Seq(_, rest @ _*) => Block(stats.init.toList, stats.last)
+ }
}
// --- specific traversers and transformers
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 575e3a9141..034628e95f 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -22,9 +22,35 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
new CleanUpTransformer(unit)
class CleanUpTransformer(unit: CompilationUnit) extends Transformer {
- private val newStaticMembers = mutable.Buffer.empty[Tree]
- private val newStaticInits = mutable.Buffer.empty[Tree]
+ private val newStaticMembers = mutable.Buffer.empty[Tree]
+ private val newStaticInits = mutable.Buffer.empty[Tree]
private val symbolsStoredAsStatic = mutable.Map.empty[String, Symbol]
+ private def clearStatics() {
+ newStaticMembers.clear()
+ newStaticInits.clear()
+ symbolsStoredAsStatic.clear()
+ }
+ private def savingStatics[T](body: => T): T = {
+ val savedNewStaticMembers : mutable.Buffer[Tree] = newStaticMembers.clone()
+ val savedNewStaticInits : mutable.Buffer[Tree] = newStaticInits.clone()
+ val savedSymbolsStoredAsStatic : mutable.Map[String, Symbol] = symbolsStoredAsStatic.clone()
+ val result = body
+
+ clearStatics()
+ newStaticMembers ++= savedNewStaticMembers
+ newStaticInits ++= savedNewStaticInits
+ symbolsStoredAsStatic ++= savedSymbolsStoredAsStatic
+
+ result
+ }
+ private def transformTemplate(tree: Tree) = {
+ val Template(parents, self, body) = tree
+ clearStatics()
+ val newBody = transformTrees(body)
+ val templ = treeCopy.Template(tree, parents, self, transformTrees(newStaticMembers.toList) ::: newBody)
+ try addStaticInits(templ) // postprocess to include static ctors
+ finally clearStatics()
+ }
private def mkTerm(prefix: String): TermName = unit.freshTermName(prefix)
/** Kludge to provide a safe fix for #4560:
@@ -60,7 +86,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
}
private def typedWithPos(pos: Position)(tree: Tree) =
- localTyper typed { atPos(pos)(tree) }
+ localTyper.typedPos(pos)(tree)
/** A value class is defined to be only Java-compatible values: unit is
* not part of it, as opposed to isValueClass in definitions. scala.Int is
@@ -71,7 +97,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/** The boxed type if it's a primitive; identity otherwise.
*/
def toBoxedType(tp: Type) = if (isJavaValueType(tp)) boxedClass(tp.typeSymbol).tpe else tp
-
+
override def transform(tree: Tree): Tree = tree match {
/* Transforms dynamic calls (i.e. calls to methods that are undefined
@@ -116,11 +142,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* ### CREATING THE METHOD CACHE ### */
- def addStaticVariableToClass(forName: String, forType: Type, forInit: Tree, isFinal: Boolean): Symbol = {
+ def addStaticVariableToClass(forName: TermName, forType: Type, forInit: Tree, isFinal: Boolean): Symbol = {
val varSym = (
- currentClass.newVariable(ad.pos, mkTerm(forName))
- setFlag (PRIVATE | STATIC | SYNTHETIC)
- setInfo (forType)
+ currentClass.newVariable(ad.pos, mkTerm("" + forName))
+ setFlag PRIVATE | STATIC | SYNTHETIC
+ setInfo forType
)
if (isFinal) varSym setFlag FINAL
else varSym.addAnnotation(VolatileAttr)
@@ -168,9 +194,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
*/
val reflParamsCacheSym: Symbol =
- addStaticVariableToClass("reflParams$Cache", theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
+ addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
- addStaticMethodToClass("reflMethod$Method", List(ClassClass.tpe), MethodClass.tpe) {
+ addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) {
case Pair(reflMethodSym, List(forReceiverSym)) =>
(REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))
}
@@ -197,18 +223,18 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
*/
val reflParamsCacheSym: Symbol =
- addStaticVariableToClass("reflParams$Cache", theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
+ addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
val reflMethodCacheSym: Symbol =
- addStaticVariableToClass("reflMethod$Cache", MethodClass.tpe, NULL, false)
+ addStaticVariableToClass(nme.reflMethodCacheName, MethodClass.tpe, NULL, false)
val reflClassCacheSym: Symbol =
- addStaticVariableToClass("reflClass$Cache", SoftReferenceClass.tpe, NULL, false)
+ addStaticVariableToClass(nme.reflClassCacheName, SoftReferenceClass.tpe, NULL, false)
def isCacheEmpty(receiver: Symbol): Tree =
reflClassCacheSym.IS_NULL() OR (reflClassCacheSym.GET() OBJ_NE REF(receiver))
- addStaticMethodToClass("reflMethod$Method", List(ClassClass.tpe), MethodClass.tpe) {
+ addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) {
case Pair(reflMethodSym, List(forReceiverSym)) =>
BLOCK(
IF (isCacheEmpty(forReceiverSym)) THEN BLOCK(
@@ -244,13 +270,15 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
*/
val reflParamsCacheSym: Symbol =
- addStaticVariableToClass("reflParams$Cache", theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
+ addStaticVariableToClass(nme.reflParamsCacheName, theTypeClassArray, fromTypesToClassArrayLiteral(paramTypes), true)
def mkNewPolyCache = gen.mkSoftRef(NEW(TypeTree(EmptyMethodCacheClass.tpe)))
- val reflPolyCacheSym: Symbol = addStaticVariableToClass("reflPoly$Cache", SoftReferenceClass.tpe, mkNewPolyCache, false)
+ val reflPolyCacheSym: Symbol = (
+ addStaticVariableToClass(nme.reflPolyCacheName, SoftReferenceClass.tpe, mkNewPolyCache, false)
+ )
def getPolyCache = gen.mkCast(fn(safeREF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe)
- addStaticMethodToClass("reflMethod$Method", List(ClassClass.tpe), MethodClass.tpe)
+ addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe)
{ case Pair(reflMethodSym, List(forReceiverSym)) =>
val methodSym = reflMethodSym.newVariable(ad.pos, mkTerm("method")) setInfo MethodClass.tpe
@@ -274,24 +302,13 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* ### HANDLING METHODS NORMALLY COMPILED TO OPERATORS ### */
- // Can't shortcut on BoxedNumber because BoxesRunTime
- // is unforgiving of other Numbers showing up.
- def testForNumber(qual1: Tree): Tree = (
- (qual1 IS_OBJ BoxedIntClass.tpe)
- OR (qual1 IS_OBJ BoxedLongClass.tpe)
- OR (qual1 IS_OBJ BoxedDoubleClass.tpe)
- OR (qual1 IS_OBJ BoxedFloatClass.tpe)
- OR (qual1 IS_OBJ BoxedByteClass.tpe)
- OR (qual1 IS_OBJ BoxedShortClass.tpe)
- OR (qual1 IS_OBJ BoxedCharacterClass.tpe)
- )
- def testForBoolean(qual1: Tree): Tree = (
- (qual1 IS_OBJ BoxedBooleanClass.tpe)
- )
- def testForName(name: Name): Tree => Tree = (
- if (nme.CommonOpNames(name)) t => testForNumber(t) OR testForBoolean(t)
- else if (nme.BooleanOpNames(name)) testForBoolean
- else testForNumber
+ def testForName(name: Name): Tree => Tree = t => (
+ if (nme.CommonOpNames(name))
+ gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean), t :: Nil)
+ else if (nme.BooleanOpNames(name))
+ t IS_OBJ BoxedBooleanClass.tpe
+ else
+ gen.mkMethodCall(getMember(BoxesRunTimeClass, nme.isBoxedNumber), t :: Nil)
)
/** The Tree => Tree function in the return is necessary to prevent the original qual
@@ -525,31 +542,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* constructor. */
case Template(parents, self, body) =>
localTyper = typer.atOwner(tree, currentClass)
- var savedNewStaticMembers : mutable.Buffer[Tree] = null
- var savedNewStaticInits : mutable.Buffer[Tree] = null
- var savedSymbolsStoredAsStatic : mutable.Map[String, Symbol] = null
- if(forMSIL) {
- savedNewStaticMembers = newStaticMembers.clone
- savedNewStaticInits = newStaticInits.clone
- savedSymbolsStoredAsStatic = symbolsStoredAsStatic.clone
- }
- newStaticMembers.clear
- newStaticInits.clear
- symbolsStoredAsStatic.clear
- val transformedTemplate: Template = {
- var newBody = transformTrees(body)
- treeCopy.Template(tree, parents, self, transformTrees(newStaticMembers.toList) ::: newBody)
- }
- val res = addStaticInits(transformedTemplate) // postprocess to include static ctors
- newStaticMembers.clear
- newStaticInits.clear
- symbolsStoredAsStatic.clear
- if(forMSIL) {
- newStaticMembers ++= savedNewStaticMembers
- newStaticInits ++= savedNewStaticInits
- symbolsStoredAsStatic ++= savedSymbolsStoredAsStatic
- }
- res
+ if (forMSIL) savingStatics( transformTemplate(tree) )
+ else transformTemplate(tree)
case Literal(c) if (c.tag == ClassTag) && !forMSIL=>
val tpe = c.typeValue
@@ -612,15 +606,12 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* And, finally, be advised - scala symbol literal and the Symbol class of the compiler
* have little in common.
*/
- case symapp @ Apply(Select(Select(a @ Ident(nme.scala_), b @ nme.Symbol), nme.apply),
- List(Literal(Constant(symname: String)))) =>
+ case Apply(fn, (arg @ Literal(Constant(symname: String))) :: Nil) if fn.symbol == Symbol_apply =>
// add the symbol name to a map if it's not there already
- val rhs = gen.mkCast(Apply(gen.scalaDot(nme.Symbol), List(Literal(Constant(symname)))), symbolType)
- val staticFieldSym = getSymbolStaticField(symapp.pos, symname, rhs, symapp)
-
+ val rhs = gen.mkMethodCall(Symbol_apply, arg :: Nil)
+ val staticFieldSym = getSymbolStaticField(tree.pos, symname, rhs, tree)
// create a reference to a static field
- val ntree = typedWithPos(symapp.pos)(safeREF(staticFieldSym))
-
+ val ntree = typedWithPos(tree.pos)(safeREF(staticFieldSym))
super.transform(ntree)
// This transform replaces Array(Predef.wrapArray(Array(...)), <manifest>)
@@ -640,19 +631,21 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
* If it doesn't exist, i.e. the symbol is encountered the first time,
* it creates a new static field definition and initialization and returns it.
*/
- private def getSymbolStaticField(pos: Position, symname: String, rhs: Tree, tree: Tree): Symbol =
+ private def getSymbolStaticField(pos: Position, symname: String, rhs: Tree, tree: Tree): Symbol = {
symbolsStoredAsStatic.getOrElseUpdate(symname, {
val theTyper = typer.atOwner(tree, currentClass)
// create a symbol for the static field
- val stfieldSym = currentClass.newVariable(pos, mkTerm("symbol$"))
- .setFlag(PRIVATE | STATIC | SYNTHETIC | FINAL)
- .setInfo(symbolType)
+ val stfieldSym = (
+ currentClass.newVariable(pos, mkTerm("symbol$"))
+ setFlag PRIVATE | STATIC | SYNTHETIC | FINAL
+ setInfo SymbolClass.tpe
+ )
currentClass.info.decls enter stfieldSym
// create field definition and initialization
- val stfieldDef = theTyper.typed { atPos(pos)(VAL(stfieldSym) === rhs) }
- val stfieldInit = theTyper.typed { atPos(pos)(safeREF(stfieldSym) === rhs) }
+ val stfieldDef = theTyper.typedPos(pos)(VAL(stfieldSym) === rhs)
+ val stfieldInit = theTyper.typedPos(pos)(safeREF(stfieldSym) === rhs)
// add field definition to new defs
newStaticMembers append stfieldDef
@@ -660,6 +653,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
stfieldSym
})
+ }
/* finds the static ctor DefDef tree within the template if it exists. */
private def findStaticCtor(template: Template): Option[Tree] =
@@ -671,7 +665,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
/* changes the template for the class so that it contains a static constructor with symbol fields inits,
* augments an existing static ctor if one already existed.
*/
- private def addStaticInits(template: Template): Template =
+ private def addStaticInits(template: Template): Template = {
if (newStaticInits.isEmpty)
template
else {
@@ -693,11 +687,12 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
// create new static ctor
val staticCtorSym = currentClass.newStaticConstructor(template.pos)
val rhs = Block(newStaticInits.toList, Literal(Constant()))
- val staticCtorTree = DefDef(staticCtorSym, rhs)
- localTyper.typed { atPos(template.pos)(staticCtorTree) }
+
+ localTyper.typedPos(template.pos)(DefDef(staticCtorSym, rhs))
}
treeCopy.Template(template, template.parents, template.self, newCtor :: template.body)
}
+ }
} // CleanUpTransformer
diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala
index 8a17ae87b0..8851f1ab91 100644
--- a/src/library/scala/Symbol.scala
+++ b/src/library/scala/Symbol.scala
@@ -31,8 +31,8 @@ final class Symbol private (val name: String) extends Serializable {
override def equals(other: Any) = this eq other.asInstanceOf[AnyRef]
}
-object Symbol extends UniquenessCache[String, Symbol]
-{
+object Symbol extends UniquenessCache[String, Symbol] {
+ override def apply(name: String): Symbol = super.apply(name)
protected def valueFromKey(name: String): Symbol = new Symbol(name)
protected def keyFromValue(sym: Symbol): Option[String] = Some(sym.name)
}
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index c726c56d0e..b19c8d086c 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -769,6 +769,24 @@ public final class BoxesRunTime
}
throw new NoSuchMethodException();
}
+
+ public static boolean isBoxedNumberOrBoolean(Object arg) {
+ if (arg instanceof java.lang.Boolean)
+ return true;
+ else
+ return isBoxedNumber(arg);
+ }
+ public static boolean isBoxedNumber(Object arg) {
+ return (
+ (arg instanceof java.lang.Integer)
+ || (arg instanceof java.lang.Long)
+ || (arg instanceof java.lang.Double)
+ || (arg instanceof java.lang.Float)
+ || (arg instanceof java.lang.Short)
+ || (arg instanceof java.lang.Character)
+ || (arg instanceof java.lang.Byte)
+ );
+ }
/** arg.toChar */
public static java.lang.Character toCharacter(Object arg) throws NoSuchMethodException {