aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-07-07 11:52:38 +0200
committerMartin Odersky <odersky@gmail.com>2014-07-17 11:02:00 +0200
commit3eabbb77c8f8bd3e08b39e5335e8a67e2d68e659 (patch)
tree3443ff1c5613c5e1fd3a6659571c1454c8d18695 /src/dotty
parentab8d873430c22337c6fc6332cad5708514fd5fa0 (diff)
downloaddotty-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.scala26
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala10
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala7
-rw-r--r--src/dotty/tools/dotc/transform/ExtensionMethods.scala5
-rw-r--r--src/dotty/tools/dotc/transform/SuperAccessors.scala3
-rw-r--r--src/dotty/tools/dotc/transform/ValueClasses.scala36
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
+
+}