summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-12-02 05:53:25 +0000
committerMartin Odersky <odersky@gmail.com>2010-12-02 05:53:25 +0000
commitd7de71e9d31dae56b5afc62e3777fa03112ee1e1 (patch)
tree9f73d08e117755a5cb8e822858cde3de9961a3ed /src
parentb9a25c8acf843c015b2313f9ca66b1b264672d34 (diff)
downloadscala-d7de71e9d31dae56b5afc62e3777fa03112ee1e1.tar.gz
scala-d7de71e9d31dae56b5afc62e3777fa03112ee1e1.tar.bz2
scala-d7de71e9d31dae56b5afc62e3777fa03112ee1e1.zip
delayed init now supported
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala3
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala10
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala90
-rw-r--r--src/library/scala/package.scala23
-rwxr-xr-xsrc/library/scala/reflect/generic/StdNames.scala2
6 files changed, 130 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index da4b5a83da..db757a66f5 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -169,7 +169,13 @@ trait Definitions extends reflect.generic.StandardDefinitions {
def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements)
// classes with special meanings
- lazy val NotNullClass = getClass("scala.NotNull")
+ lazy val NotNullClass = getClass("scala.NotNull")
+ lazy val DelayedInitClass = getClass("scala.DelayedInit")
+ def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit)
+ // a dummy value that communicates that a delayedInit call is compiler-generated
+ // from phase UnCurry to phase Constructors
+ def delayedInitArgVal = EmptyPackageClass.newValue(NoPosition, nme.delayedInitArg)
+ .setInfo(UnitClass.tpe)
lazy val TypeConstraintClass = getClass("scala.TypeConstraint")
lazy val SingletonClass = newClass(ScalaPackageClass, nme.Singleton, anyparam) setFlag (ABSTRACT | TRAIT | FINAL)
lazy val SerializableClass = getClass("scala.Serializable")
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 64dc254f28..e3a23b2b43 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -12,6 +12,7 @@ trait StdNames extends reflect.generic.StdNames with NameManglers {
self: SymbolTable =>
object nme extends StandardNames with NameMangling {
+
/** Translate a String into a list of simple TypeNames and TermNames.
* In all segments before the last, type/term is determined by whether
* the following separator char is '.' or '#'. In the last segment,
@@ -222,6 +223,8 @@ trait StdNames extends reflect.generic.StdNames with NameManglers {
val identity = newTermName("identity")
val conforms = newTermName("conforms")
val copy = newTermName("copy")
+ val delayedInit = newTermName("delayedInit")
+ val delayedInitArg = newTermName("delayedInit$body")
val dottype = newTermName(".type")
val drop = newTermName("drop")
val elem = newTermName("elem")
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 824d047d6b..31992c5d0b 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -523,6 +523,10 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
isClass && (isAnonymousClass || isRefinementClass || isLocal ||
!owner.isPackageClass && owner.isLocalClass)
+/* code for fixing nested objects
+ override final def isModuleClass: Boolean =
+ super.isModuleClass && !isExpandedModuleClass
+*/
/** Is this class or type defined as a structural refinement type?
*/
final def isStructuralRefinement: Boolean =
@@ -1451,7 +1455,13 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
if (isType) name = name.toTypeName
}
}
+/* code for fixing nested objects
+ def expandModuleClassName() {
+ name = newTypeName(name.toString + "$")
+ }
+ def isExpandedModuleClass: Boolean = name(name.length - 1) == '$'
+*/
def sourceFile: AbstractFile =
(if (isModule) moduleClass else toplevelClass).sourceFile
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index ed479763e5..091e10c170 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -155,7 +155,8 @@ abstract class Constructors extends Transform with ast.TreeDSL {
// The list of statements that go into constructor after superclass constructor call
val constrStatBuf = new ListBuffer[Tree]
- // The list of statements that go into constructor before superclass constructor call
+ // The list of statements that go into constructor before and including the
+ // superclass constructor call
val constrPrefixBuf = new ListBuffer[Tree]
// The early initialized field definitions of the class (these are the class members)
@@ -163,14 +164,14 @@ abstract class Constructors extends Transform with ast.TreeDSL {
// generate code to copy pre-initialized fields
for (stat <- constrBody.stats) {
- constrStatBuf += stat
+ constrPrefixBuf += stat
stat match {
case ValDef(mods, name, _, _) if (mods hasFlag PRESUPER) =>
// stat is the constructor-local definition of the field value
val fields = presupers filter (
vdef => nme.localToGetter(vdef.name) == name)
assert(fields.length == 1)
- constrStatBuf += mkAssign(fields.head.symbol, Ident(stat.symbol))
+ constrPrefixBuf += mkAssign(fields.head.symbol, Ident(stat.symbol))
case _ =>
}
}
@@ -404,12 +405,87 @@ abstract class Constructors extends Transform with ast.TreeDSL {
} else stats0
}
+ def isInitDef(stat: Tree) = stat match {
+ case dd: DefDef => dd.symbol == delayedInitMethod
+ case _ => false
+ }
+
+ def delayedInitClosure(stats: List[Tree]) =
+ localTyper.typed {
+ atPos(impl.pos) {
+ val closureClass = clazz.newClass(impl.pos, nme.delayedInitArg.toTypeName)
+ .setFlag(SYNTHETIC | FINAL)
+ val closureParents = List(AbstractFunctionClass(0).tpe, ScalaObjectClass.tpe)
+ closureClass.setInfo(new ClassInfoType(closureParents, new Scope, closureClass))
+
+ val outerField = clazz.newValue(impl.pos, nme.OUTER)
+ .setFlag(PRIVATE | LOCAL)
+ .setInfo(clazz.tpe)
+
+ val applyMethod = closureClass.newMethod(impl.pos, nme.apply)
+ .setFlag(FINAL)
+ .setInfo(MethodType(List(), ObjectClass.tpe))
+
+ closureClass.info.decls enter outerField
+ closureClass.info.decls enter applyMethod
+
+ val outerFieldDef = ValDef(outerField)
+
+ val changeOwner = new ChangeOwnerTraverser(impl.symbol, applyMethod)
+ val constrStatTransformer = new Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case This(`clazz`) =>
+ localTyper.typed {
+ atPos(tree.pos) {
+ Select(This(closureClass), outerField)
+ }
+ }
+ case _ =>
+ changeOwner traverse tree
+ tree
+ }
+ }
+
+ def applyMethodStats = constrStatTransformer.transformTrees(stats)
+
+ val applyMethodDef = DefDef(
+ sym = applyMethod,
+ vparamss = List(List()),
+ rhs = Block(applyMethodStats, gen.mkAttributedRef(BoxedUnit_UNIT)))
+
+ util.trace("delayedInit: ") { ClassDef(
+ sym = closureClass,
+ constrMods = Modifiers(0),
+ vparamss = List(List(outerFieldDef)),
+ argss = List(List()),
+ body = List(outerFieldDef, applyMethodDef),
+ superPos = impl.pos)
+ }}
+ }
+
+ def delayedInitCall(closure: Tree) =
+ localTyper.typed {
+ atPos(impl.pos) {
+ Apply(
+ Select(This(clazz), delayedInitMethod),
+ List(New(TypeTree(closure.symbol.tpe), List(List(This(clazz))))))
+ }
+ }
+
+ val needsDelayedInit =
+ false && (clazz isSubClass DelayedInitClass) && !(defBuf exists isInitDef) && constrStatBuf.nonEmpty
+
+ var constrStats = constrStatBuf.toList
+ if (needsDelayedInit) {
+ constrStats = List(delayedInitCall(delayedInitClosure(constrStats)))
+ }
+
// Assemble final constructor
defBuf += treeCopy.DefDef(
constr, constr.mods, constr.name, constr.tparams, constr.vparamss, constr.tpt,
treeCopy.Block(
constrBody,
- paramInits ::: constrPrefixBuf.toList ::: guardSpecializedInitializer(constrStatBuf.toList),
+ paramInits ::: constrPrefixBuf.toList ::: guardSpecializedInitializer(constrStats),
constrBody.expr));
// Followed by any auxiliary constructors
@@ -424,6 +500,12 @@ abstract class Constructors extends Transform with ast.TreeDSL {
defBuf.toList filter (stat => mustbeKept(stat.symbol)))
} // transformClassTemplate
+ def hasDelayedInit(clazz: Symbol) = false &&
+ (clazz isSubClass DelayedInitClass) &&
+ (clazz.info.decls lookup nme.delayedInit) == NoSymbol
+
+ def delayedInitCall(stats: List[Tree]): Tree = null
+
override def transform(tree: Tree): Tree =
tree match {
case ClassDef(mods, name, tparams, impl) if !tree.symbol.isInterface =>
diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala
index 86efe7c379..a6b974b4d3 100644
--- a/src/library/scala/package.scala
+++ b/src/library/scala/package.scala
@@ -102,6 +102,23 @@ package object scala {
type PartialOrdering[T] = scala.math.PartialOrdering[T]
type PartiallyOrdered[T] = scala.math.PartiallyOrdered[T]
+ // Annotations which we might move to annotation.*
+/*
+ type SerialVersionUID = annotation.SerialVersionUID
+ type cloneable = annotation.cloneable
+ type deprecated = annotation.deprecated
+ type deprecatedName = annotation.deprecatedName
+ type inline = annotation.inline
+ type native = annotation.native
+ type noinline = noannotation.inline
+ type remote = annotation.remote
+ type serializable = annotation.serializable
+ type specialized = annotation.specialized
+ type transient = annotation.transient
+ type throws = annotation.throws
+ type unchecked = annotation.unchecked.unchecked
+ type volatile = annotation.volatile
+ */
@deprecated("Use Tuple1(x) to create a 1-tuple.")
def Tuple[A1](x1: A1) = Tuple1(x1)
@deprecated("Use ((x1, x2, ...)) syntax to create Tuples")
@@ -160,4 +177,10 @@ package object scala {
@deprecated("use IndexedSeq instead") type RandomAccessSeq[+A] = scala.collection.IndexedSeq[A]
@deprecated("use IndexedSeq instead") val RandomAccessSeq = scala.collection.IndexedSeq
+/* the following classes should be moved to annotation and the aliases should be enabled
+ @deprecated("use annotation.Annotation instead") type Annotation = annotation.Annotation
+ @deprecated("use annotation.ClassfileAnnotation instead") type ClassfileAnnotation = annotation.Annotation
+ @deprecated("use annotation.StaticAnnotation instead") type StaticAnnotation = annotation.Annotation
+ @deprecated("use annotation.TypeConstraint instead") type TypeConstraint = annotation.TypeConstraint
+*/
}
diff --git a/src/library/scala/reflect/generic/StdNames.scala b/src/library/scala/reflect/generic/StdNames.scala
index f6f89c9100..7d2e0fde6a 100755
--- a/src/library/scala/reflect/generic/StdNames.scala
+++ b/src/library/scala/reflect/generic/StdNames.scala
@@ -30,6 +30,6 @@ trait StdNames { self: Universe =>
newTermName(base.fullName('$') + separator + name)
def moduleVarName(name: Name): Name =
- newTermName(name.toString() + MODULE_SUFFIX)
+ newTermName(name.toString + MODULE_SUFFIX)
}
}