diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Fields.scala | 59 | ||||
-rw-r--r-- | src/library/scala/reflect/NameTransformer.scala | 19 | ||||
-rw-r--r-- | src/library/scala/util/Either.scala | 28 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/StdNames.scala | 19 |
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" |