summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Fields.scala59
-rw-r--r--src/library/scala/reflect/NameTransformer.scala19
-rw-r--r--src/library/scala/util/Either.scala28
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala19
4 files changed, 62 insertions, 63 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala
index 6cf6a5abce..aa2ccd9788 100644
--- a/src/compiler/scala/tools/nsc/transform/Fields.scala
+++ b/src/compiler/scala/tools/nsc/transform/Fields.scala
@@ -193,20 +193,6 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
// not be emitted as ACC_FINAL. They are FINAL in the Scala sense, though: cannot be overridden.
private final val ModuleOrLazyFieldFlags = FINAL | PrivateLocal | SYNTHETIC | NEEDS_TREES
- private def newModuleVarSymbol(owner: Symbol, module: Symbol, tp: Type): TermSymbol = {
-// println(s"new module var in $site for $module of type $tp")
- val flags = MODULEVAR | (if (owner.isClass) ModuleOrLazyFieldFlags else 0)
-
- val moduleVar =
- (owner.newVariable(nme.moduleVarName(module.name.toTermName), module.pos.focus, flags)
- setInfo tp
- addAnnotation VolatileAttr)
-
- moduleOrLazyVarOf(module) = moduleVar
-
- moduleVar
- }
-
private def moduleInit(module: Symbol, moduleVar: Symbol) = {
// println(s"moduleInit for $module in ${module.ownerChain} --> ${moduleVarOf.get(module)}")
def moduleVarRef = gen.mkAttributedRef(moduleVar)
@@ -380,8 +366,16 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
(existingGetter ne NoSymbol) && (tp matches (site memberInfo existingGetter).resultType) // !existingGetter.isDeferred && -- see (3)
}
- def newModuleVarMember(member: Symbol): TermSymbol =
- newModuleVarSymbol(clazz, member, site.memberType(member).resultType)
+ def newModuleVarMember(module: Symbol): TermSymbol = {
+ val moduleVar =
+ (clazz.newVariable(nme.moduleVarName(module.name.toTermName), module.pos.focus, MODULEVAR | ModuleOrLazyFieldFlags)
+ setInfo site.memberType(module).resultType
+ addAnnotation VolatileAttr)
+
+ moduleOrLazyVarOf(module) = moduleVar
+
+ moduleVar
+ }
def newLazyVarMember(member: Symbol): TermSymbol =
Fields.this.newLazyVarMember(clazz, member, site.memberType(member).resultType)
@@ -531,7 +525,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
def mkTypedValDef(sym: Symbol, rhs: Tree = EmptyTree) = typedPos(sym.pos)(ValDef(sym, rhs)).asInstanceOf[ValDef]
/**
- * Desugar a local `lazy val x: Int = rhs` into
+ * Desugar a local `lazy val x: Int = rhs`
+ * or a local `object x { ...}` (the rhs will be instantiating the module's class) into:
+ *
* ```
* val x$lzy = new scala.runtime.LazyInt()
* def x$lzycompute(): Int =
@@ -541,22 +537,24 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
* }
* def x(): Int = if (x$lzy.initialized()) x$lzy.value() else x$lzycompute()
* ```
+ *
+ * The expansion is the same for local lazy vals and local objects,
+ * except for the suffix of the underlying val's name ($lzy or $module)
*/
- private def mkLazyLocalDef(lazyVal: Symbol, rhs: Tree): Tree = {
+ private def mkLazyLocalDef(lazySym: Symbol, rhs: Tree): Tree = {
import CODE._
- import scala.reflect.NameTransformer.LAZY_LOCAL_SUFFIX_STRING
- val owner = lazyVal.owner
+ import scala.reflect.{NameTransformer => nx}
+ val owner = lazySym.owner
- val lazyValType = lazyVal.tpe.resultType
+ val lazyValType = lazySym.tpe.resultType
val refClass = lazyHolders.getOrElse(lazyValType.typeSymbol, LazyRefClass)
val isUnit = refClass == LazyUnitClass
val refTpe = if (refClass != LazyRefClass) refClass.tpe else appliedType(refClass.typeConstructor, List(lazyValType))
- val lazyName = lazyVal.name.toTermName
- val pos = lazyVal.pos.focus
+ val lazyName = lazySym.name.toTermName
+ val pos = lazySym.pos.focus
- // used twice: once in the same owner as the lazy val, another time inside the compute method
- val localLazyName = lazyName append LAZY_LOCAL_SUFFIX_STRING
+ val localLazyName = lazyName append (if (lazySym.isModule) nx.MODULE_VAR_SUFFIX_STRING else nx.LAZY_LOCAL_SUFFIX_STRING)
// The lazy holder val need not be mutable, as we write to its field.
// In fact, it MUST not be mutable to avoid capturing it as an ObjectRef in lambdalift
@@ -576,14 +574,14 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
val computerSym =
owner.newMethod(lazyName append nme.LAZY_SLOW_SUFFIX, pos, ARTIFACT | PRIVATE) setInfo MethodType(Nil, lazyValType)
- val rhsAtComputer = rhs.changeOwner(lazyVal -> computerSym)
+ val rhsAtComputer = rhs.changeOwner(lazySym -> computerSym)
val computer = mkAccessor(computerSym)(gen.mkSynchronized(Ident(holderSym))(
If(initialized, getValue,
if (isUnit) Block(rhsAtComputer :: Nil, Apply(initialize, Nil))
else Apply(initialize, rhsAtComputer :: Nil))))
- val accessor = mkAccessor(lazyVal)(
+ val accessor = mkAccessor(lazySym)(
If(initialized, getValue,
Apply(Ident(computerSym), Nil)))
@@ -591,7 +589,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
// remove STABLE: prevent replacing accessor call of type Unit by BoxedUnit.UNIT in erasure
// remove ACCESSOR: prevent constructors from eliminating the method body if the lazy val is
// lifted into a trait (TODO: not sure about the details here)
- lazyVal.resetFlag(STABLE | ACCESSOR)
+ lazySym.resetFlag(STABLE | ACCESSOR)
Thicket(mkTypedValDef(holderSym, New(refTpe)) :: computer :: accessor :: Nil)
}
@@ -730,8 +728,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
val cd = super.transform(ClassDef(statSym.moduleClass, impl) setType NoType)
if (currOwner.isClass) cd
else { // local module -- symbols cannot be generated by info transformer, so do it all here
- val moduleVar = newModuleVarSymbol(currOwner, statSym, statSym.info.resultType)
- Thicket(cd :: mkTypedValDef(moduleVar) :: mkAccessor(statSym)(moduleInit(statSym, moduleVar)) :: Nil)
+ val Block(stats, _) = mkLazyLocalDef(statSym, gen.newModule(statSym, statSym.info.resultType))
+
+ Thicket(cd :: stats)
}
case tree =>
diff --git a/src/library/scala/reflect/NameTransformer.scala b/src/library/scala/reflect/NameTransformer.scala
index ae36f5edc2..bdf5165df5 100644
--- a/src/library/scala/reflect/NameTransformer.scala
+++ b/src/library/scala/reflect/NameTransformer.scala
@@ -13,15 +13,16 @@ package reflect
* Also provides some constants.
*/
object NameTransformer {
- // XXX Short term: providing a way to alter these without having to recompile
- // the compiler before recompiling the compiler.
- val MODULE_SUFFIX_STRING = sys.props.getOrElse("SCALA_MODULE_SUFFIX_STRING", "$")
- val NAME_JOIN_STRING = sys.props.getOrElse("SCALA_NAME_JOIN_STRING", "$")
- val MODULE_INSTANCE_NAME = "MODULE$"
- val LOCAL_SUFFIX_STRING = " "
- val LAZY_LOCAL_SUFFIX_STRING = "$lzy"
- val SETTER_SUFFIX_STRING = "_$eq"
- val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
+ // TODO: reduce duplication with and in StdNames
+ // I made these constants because we cannot change them without bumping our major version anyway.
+ final val NAME_JOIN_STRING = "$"
+ final val MODULE_SUFFIX_STRING = "$"
+ final val MODULE_INSTANCE_NAME = "MODULE$"
+ final val LOCAL_SUFFIX_STRING = " "
+ final val LAZY_LOCAL_SUFFIX_STRING = "$lzy"
+ final val MODULE_VAR_SUFFIX_STRING = "$module"
+ final val SETTER_SUFFIX_STRING = "_$eq"
+ final val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$"
private val nops = 128
private val ncodes = 26 * 26
diff --git a/src/library/scala/util/Either.scala b/src/library/scala/util/Either.scala
index 169786d31b..c332f18295 100644
--- a/src/library/scala/util/Either.scala
+++ b/src/library/scala/util/Either.scala
@@ -95,13 +95,15 @@ sealed abstract class Either[+A, +B] extends Product with Serializable {
/**
* Projects this `Either` as a `Left`.
*/
- @deprecated("use swap instead", "2.12.0")
def left = Either.LeftProjection(this)
/**
* Projects this `Either` as a `Right`.
+ *
+ * Because `Either` is right-biased, this method is not normally needed.
+ * (It is retained in the API for now for easy cross-compilation between Scala
+ * 2.11 and 2.12.)
*/
- @deprecated("Either is now right-biased", "2.12.0")
def right = Either.RightProjection(this)
/**
@@ -245,7 +247,7 @@ sealed abstract class Either[+A, +B] extends Product with Serializable {
/**
* Returns `true` if `Left` or returns the result of the application of
- * the given function to the `Right` value.
+ * the given predicate to the `Right` value.
*
* {{{
* Right(12).forall(_ > 10) // true
@@ -260,7 +262,7 @@ sealed abstract class Either[+A, +B] extends Product with Serializable {
/**
* Returns `false` if `Left` or returns the result of the application of
- * the given function to the `Right` value.
+ * the given predicate to the `Right` value.
*
* {{{
* Right(12).exists(_ > 10) // true
@@ -426,7 +428,10 @@ object Either {
/**
* Projects an `Either` into a `Left`.
*
- * This allows for-comprehensions over Either instances - for example {{{
+ * This allows for-comprehensions over the left side of Either instances,
+ * reversing Either's usual right-bias.
+ *
+ * For example {{{
* for (s <- Left("flower").left) yield s.length // Left(6)
* }}}
*
@@ -472,7 +477,6 @@ object Either {
* @author <a href="mailto:research@workingmouse.com">Tony Morris</a>, Workingmouse
* @version 1.0, 11/10/2008
*/
- @deprecated("use swap instead", "2.12.0")
final case class LeftProjection[+A, +B](e: Either[A, B]) {
/**
* Returns the value from this `Left` or throws `java.util.NoSuchElementException`
@@ -624,19 +628,13 @@ object Either {
/**
* Projects an `Either` into a `Right`.
*
- * This allows for-comprehensions over Either instances - for example {{{
- * for (s <- Right("flower").right) yield s.length // Right(6)
- * }}}
- *
- * Continuing the analogy with [[scala.Option]], a `RightProjection` declares
- * that `Right` should be analogous to `Some` in some code.
- *
- * Analogous to `LeftProjection`, see example usage in its documentation above.
+ * Because `Either` is already right-biased, this class is not normally needed.
+ * (It is retained in the library for now for easy cross-compilation between Scala
+ * 2.11 and 2.12.)
*
* @author <a href="mailto:research@workingmouse.com">Tony Morris</a>, Workingmouse
* @version 1.0, 11/10/2008
*/
- @deprecated("Either is now right-biased", "2.12.0")
final case class RightProjection[+A, +B](e: Either[A, B]) {
/**
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 1a6c84b19e..2e820a68e0 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -92,14 +92,15 @@ trait StdNames {
def flattenedName(segments: Name*): NameType =
compactify(segments mkString NAME_JOIN_STRING)
- val NAME_JOIN_STRING: String = NameTransformer.NAME_JOIN_STRING
- val MODULE_SUFFIX_STRING: String = NameTransformer.MODULE_SUFFIX_STRING
- val LOCAL_SUFFIX_STRING: String = NameTransformer.LOCAL_SUFFIX_STRING
- val LAZY_LOCAL_SUFFIX_STRING: String = NameTransformer.LAZY_LOCAL_SUFFIX_STRING
-
- val TRAIT_SETTER_SEPARATOR_STRING: String = NameTransformer.TRAIT_SETTER_SEPARATOR_STRING
-
- val SINGLETON_SUFFIX: String = ".type"
+ // TODO: what is the purpose of all this duplication!?!?!
+ // I made these constants because we cannot change them without bumping our major version anyway.
+ final val NAME_JOIN_STRING = NameTransformer.NAME_JOIN_STRING
+ final val MODULE_SUFFIX_STRING = NameTransformer.MODULE_SUFFIX_STRING
+ final val MODULE_VAR_SUFFIX_STRING = NameTransformer.MODULE_VAR_SUFFIX_STRING
+ final val LOCAL_SUFFIX_STRING = NameTransformer.LOCAL_SUFFIX_STRING
+ final val LAZY_LOCAL_SUFFIX_STRING = NameTransformer.LAZY_LOCAL_SUFFIX_STRING
+ final val TRAIT_SETTER_SEPARATOR_STRING = NameTransformer.TRAIT_SETTER_SEPARATOR_STRING
+ final val SINGLETON_SUFFIX = ".type"
val ANON_CLASS_NAME: NameType = "$anon"
val DELAMBDAFY_LAMBDA_CLASS_NAME: NameType = "$lambda"
@@ -108,7 +109,7 @@ trait StdNames {
val EMPTY_PACKAGE_NAME: NameType = "<empty>"
val IMPORT: NameType = "<import>"
val MODULE_SUFFIX_NAME: NameType = MODULE_SUFFIX_STRING
- val MODULE_VAR_SUFFIX: NameType = "$module"
+ val MODULE_VAR_SUFFIX: NameType = MODULE_VAR_SUFFIX_STRING
val PACKAGE: NameType = "package"
val ROOT: NameType = "<root>"
val SPECIALIZED_SUFFIX: NameType = "$sp"