diff options
author | Martin Odersky <odersky@gmail.com> | 2014-07-07 11:52:38 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-07-17 11:02:00 +0200 |
commit | 3eabbb77c8f8bd3e08b39e5335e8a67e2d68e659 (patch) | |
tree | 3443ff1c5613c5e1fd3a6659571c1454c8d18695 /src/dotty | |
parent | ab8d873430c22337c6fc6332cad5708514fd5fa0 (diff) | |
download | dotty-3eabbb77c8f8bd3e08b39e5335e8a67e2d68e659.tar.gz dotty-3eabbb77c8f8bd3e08b39e5335e8a67e2d68e659.tar.bz2 dotty-3eabbb77c8f8bd3e08b39e5335e8a67e2d68e659.zip |
Move valueclass functionality into its own ValueClass module.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 26 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ExtensionMethods.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/SuperAccessors.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ValueClasses.scala | 36 |
6 files changed, 53 insertions, 34 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index ba57909a0..f55817505 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -329,6 +329,12 @@ object SymDenotations { final def isAnonymousClass(implicit ctx: Context): Boolean = initial.asSymDenotation.name startsWith tpnme.ANON_CLASS + /** Is symbol a primitive value class? */ + def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains symbol + + /** Is symbol a phantom class for which no runtime representation exists? */ + def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains symbol + /** Is this symbol a class representing a refinement? These classes * are used only temporarily in Typer and Unpickler as an intermediate * step for creating Refinement types. @@ -403,14 +409,6 @@ object SymDenotations { /** Is this a user defined "def" method? Excluded are accessors. */ final def isSourceMethod(implicit ctx: Context) = this is (Method, butNot = Accessor) - /** This this a method in a value class that is implemented as an extension method? */ - final def isMethodWithExtension(implicit ctx: Context) = - isSourceMethod && - owner.isDerivedValueClass && - !isConstructor && - !is(SuperAccessor) && - !is(Macro) - /** Is this a setter? */ final def isGetter(implicit ctx: Context) = (this is Accessor) && !originalName.isSetterName @@ -1335,18 +1333,6 @@ object SymDenotations { decls.denotsNamed(cname).first.symbol } - /** The member that of a derived value class that unboxes it. */ - def valueClassUnbox(implicit ctx: Context): Symbol = - // (info.decl(nme.unbox)).orElse(...) uncomment once we accept unbox methods - classInfo.decls - .find(d => d.isTerm && d.symbol.is(ParamAccessor)) - .map(_.symbol) - .getOrElse(NoSymbol) - - /** The unboxed type that underlies a derived value class */ - def underlyingOfValueClass(implicit ctx: Context): Type = - valueClassUnbox.info.resultType - /** If this class has the same `decls` scope reference in `phase` and * `phase.next`, install a new denotation with a cloned scope in `phase.next`. * @pre Can only be called in `phase.next`. diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index 6421018e5..9d60c9985 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -391,14 +391,8 @@ object Symbols { /** Is this symbol a user-defined value class? */ final def isDerivedValueClass(implicit ctx: Context): Boolean = - false && // value classes are not supported yet - isClass && denot.derivesFrom(defn.AnyValClass) && !isPrimitiveValueClass - - /** Is symbol a primitive value class? */ - def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains this - - /** Is symbol a phantom class for which no runtime representation exists? */ - def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains this + false // will migrate to ValueClasses.isDerivedValueClass; + // unsupported value class code will continue to use this stub while it exists /** The current name of this symbol */ final def name(implicit ctx: Context): ThisName = denot.name.asInstanceOf[ThisName] diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 44ee5db5a..35742ac8c 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -22,6 +22,7 @@ import dotty.tools.dotc.ast.{Trees, tpd, untpd} import ast.Trees._ import scala.collection.mutable.ListBuffer import dotty.tools.dotc.core.Flags +import ValueClasses._ class Erasure extends Phase with DenotTransformer { @@ -90,7 +91,7 @@ object Erasure { final def box(tree: Tree, target: => String = "")(implicit ctx: Context): Tree = ctx.traceIndented(i"boxing ${tree.showSummary}: ${tree.tpe} into $target") { tree.tpe.widen match { case ErasedValueType(clazz, _) => - New(clazz.typeRef, cast(tree, clazz.underlyingOfValueClass) :: Nil) // todo: use adaptToType? + New(clazz.typeRef, cast(tree, underlyingOfValueClass(clazz)) :: Nil) // todo: use adaptToType? case tp => val cls = tp.classSymbol if (cls eq defn.UnitClass) constant(tree, ref(defn.BoxedUnit_UNIT)) @@ -117,7 +118,7 @@ object Erasure { unbox(tree, underlying) else adaptToType(tree, clazz.typeRef) - .select(clazz.valueClassUnbox) + .select(valueClassUnbox(clazz)) .appliedToNone cast(tree1, pt) case _ => @@ -365,4 +366,4 @@ object Erasure { if (tree.isEmpty) tree else adaptToType(tree, pt) } } -}
\ No newline at end of file +} diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala index 73a0ed458..b64f529bf 100644 --- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -6,6 +6,7 @@ package dotty.tools.dotc package transform import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer} +import ValueClasses._ import dotty.tools.dotc.ast.{Trees, tpd} import scala.collection.{ mutable, immutable } import mutable.ListBuffer @@ -96,7 +97,7 @@ class ExtensionMethods extends MacroTransform with IdentityDenotTransformer { th if (seen contains clazz) ctx.error("value class may not unbox to itself", pos) else { - val unboxed = clazz.underlyingOfValueClass.typeSymbol + val unboxed = underlyingOfValueClass(clazz).typeSymbol if (unboxed.isDerivedValueClass) checkNonCyclic(pos, seen + clazz, unboxed.asClass) } @@ -122,7 +123,7 @@ class ExtensionMethods extends MacroTransform with IdentityDenotTransformer { th tree1 } } else tree - case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension => + case DefDef(mods, name, tparams, vparamss, tpt, rhs) if isMethodWithExtension(tree.symbol) => val origMeth = tree.symbol val origClass = ctx.owner.asClass val origTParams = tparams.map(_.symbol) ::: origClass.typeParams // method type params ++ class type params diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala index 0fbf33869..52306956e 100644 --- a/src/dotty/tools/dotc/transform/SuperAccessors.scala +++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala @@ -4,6 +4,7 @@ package transform import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer} import dotty.tools.dotc.ast.{Trees, tpd} import scala.collection.{ mutable, immutable } +import ValueClasses._ import mutable.ListBuffer import scala.annotation.tailrec import core._ @@ -368,7 +369,7 @@ class SuperAccessors extends MacroTransform with IdentityDenotTransformer { this transformSelect case DefDef(mods, name, tparams, vparamss, tpt, rhs) => - val rhs1 = if (sym.isMethodWithExtension) withInvalidOwner(transform(rhs)) else transform(rhs) + val rhs1 = if (isMethodWithExtension(sym)) withInvalidOwner(transform(rhs)) else transform(rhs) cpy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs1) case TypeApply(sel @ Select(qual, name), args) => diff --git a/src/dotty/tools/dotc/transform/ValueClasses.scala b/src/dotty/tools/dotc/transform/ValueClasses.scala new file mode 100644 index 000000000..c5cf44552 --- /dev/null +++ b/src/dotty/tools/dotc/transform/ValueClasses.scala @@ -0,0 +1,36 @@ +package dotty.tools.dotc +package transform + +import core._ +import Types._ +import Symbols._ +import SymDenotations._ +import Contexts._ +import Flags._ + +/** Methods that apply to user-defined value classes */ +object ValueClasses { + + def isDerivedValueClass(d: SymDenotation)(implicit ctx: Context) = + d.isClass && d.derivesFrom(defn.AnyValClass) && !d.isPrimitiveValueClass + + def isMethodWithExtension(d: SymDenotation)(implicit ctx: Context) = + d.isSourceMethod && + isDerivedValueClass(d.owner) && + !d.isConstructor && + !d.is(SuperAccessor) && + !d.is(Macro) + + /** The member that of a derived value class that unboxes it. */ + def valueClassUnbox(d: ClassDenotation)(implicit ctx: Context): Symbol = + // (info.decl(nme.unbox)).orElse(...) uncomment once we accept unbox methods + d.classInfo.decls + .find(d => d.isTerm && d.symbol.is(ParamAccessor)) + .map(_.symbol) + .getOrElse(NoSymbol) + + /** The unboxed type that underlies a derived value class */ + def underlyingOfValueClass(d: ClassDenotation)(implicit ctx: Context): Type = + valueClassUnbox(d).info.resultType + +} |