aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-06-12 14:50:05 +0200
committerMartin Odersky <odersky@gmail.com>2014-06-12 15:35:57 +0200
commit96196c9ffa9939acd7437103d1621dac96e9abc6 (patch)
treeca87d4f694e47e453ad4d791cff80adb4cf3bbe4 /src/dotty
parent51563aee5478f90a0f86c29385f74d020b8995dd (diff)
downloaddotty-96196c9ffa9939acd7437103d1621dac96e9abc6.tar.gz
dotty-96196c9ffa9939acd7437103d1621dac96e9abc6.tar.bz2
dotty-96196c9ffa9939acd7437103d1621dac96e9abc6.zip
Names and definitions for Lambdas
Adding names and definitions for the Lambda scheme to hk types. Also add HigherKinded flag for HK type parameters and abstract types.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala62
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala7
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala12
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala13
4 files changed, 81 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 6f34efc8b..3f567d87a 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -422,7 +422,7 @@ class Definitions {
def functionArity(tp: Type) = tp.dealias.argInfos.length - 1
// ----- Higher kinds machinery ------------------------------------------
-
+ // tbr
private var _hkTraits: Set[Symbol] = Set()
/** The set of HigherKindedXYZ traits encountered so far */
@@ -476,6 +476,66 @@ class Definitions {
hkTraitOfArity.getOrElseUpdate(vcs, createTrait)
}
+ // ----- LambdaXYZ traits ------------------------------------------
+
+ private var myLambdaTraits: Set[Symbol] = Set()
+
+ /** The set of HigherKindedXYZ traits encountered so far */
+ def lambdaTraits: Set[Symbol] = myLambdaTraits
+
+ private var lambdaTraitForVariances = mutable.Map[List[Int], ClassSymbol]()
+
+ /** The HigherKinded trait corresponding to symbols `boundSyms` (which are assumed
+ * to be the type parameters of a higher-kided type). This is a class symbol that
+ * would be generated by the following schema.
+ *
+ * class LambdaXYZ { type v_1 Arg1; ...; type v_N ArgN; type Apply }
+ *
+ * Here:
+ *
+ * - XYZ is a string of length N with one letter for each variant of a bound symbols,
+ * using `P` (positive variance), `N` (negative variance), `I` (invariant).
+ * - v_i are the variances of the bound symbols (i.e. +, -, or empty).
+ */
+ def lambdaTrait(vcs: List[Int]): ClassSymbol = {
+ assert(vcs.nonEmpty)
+
+ def varianceFlags(v: Int) = v match {
+ case -1 => Contravariant
+ case 0 => EmptyFlags
+ case 1 => Covariant
+ }
+
+ val completer = new LazyType {
+ def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
+ val cls = denot.asClass.classSymbol
+ val paramDecls = newScope
+ for (i <- 0 until vcs.length)
+ newTypeParam(cls, tpnme.lambdaArgName(i), varianceFlags(vcs(i)), paramDecls)
+ newTypeParam(cls, tpnme.Apply, EmptyFlags, paramDecls)
+ val parentTraitRefs =
+ for (i <- 0 until vcs.length if vcs(i) != 0)
+ yield lambdaTrait(vcs.updated(i, 0)).typeRef
+ denot.info = ClassInfo(
+ ScalaPackageClass.thisType, cls, ObjectClass.typeRef :: parentTraitRefs.toList, paramDecls)
+ }
+ }
+
+ val traitName = tpnme.lambdaTraitName(vcs)
+
+ def createTrait = {
+ val cls = newClassSymbol(
+ ScalaPackageClass,
+ traitName,
+ Trait | Interface | Synthetic,
+ completer)
+ myLambdaTraits += cls
+ cls
+ }
+
+ lambdaTraitForVariances.getOrElseUpdate(vcs, createTrait)
+ }
+
// ----- primitive value class machinery ------------------------------------------
lazy val ScalaNumericValueClasses: collection.Set[Symbol] = Set(
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index 9f87120f8..40da7525d 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -198,8 +198,9 @@ object Flags {
final val Final = commonFlag(6, "final")
/** A method symbol. */
- final val MethodCommon = commonFlag(7, "<method>")
- final val Method = MethodCommon.toTermFlags
+ final val MethodOrHKCommon = commonFlag(7, "<method>")
+ final val Method = MethodOrHKCommon.toTermFlags
+ final val HigherKinded = MethodOrHKCommon.toTypeFlags
/** A (term or type) parameter to a class or method */
final val Param = commonFlag(8, "<param>")
@@ -411,7 +412,7 @@ object Flags {
/** Flags guaranteed to be set upon symbol creation */
final val FromStartFlags =
- AccessFlags | Module | Package | Deferred | MethodCommon | Param | Scala2ExistentialCommon | Touched |
+ AccessFlags | Module | Package | Deferred | MethodOrHKCommon | Param | Scala2ExistentialCommon | Touched |
Static | CovariantCommon | ContravariantCommon | ExpandedName | AccessorOrSealed |
CaseAccessorOrTypeArgument | Frozen | Erroneous | ImplicitCommon | Permanent | SelfNameOrImplClass
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index 22a7e5734..187946590 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -87,13 +87,15 @@ object NameOps {
name.last == '=' && name.head != '=' && isOperatorPart(name.head)
}
- /** Is this the name of a higher-kinded type parameter? */
- def isHkParamName: Boolean = name(0) == '_' && name.startsWith(HK_PARAM_PREFIX)
+ /** Is this the name of a higher-kinded type parameter of a Lambda? */
+ def isLambdaArgName = name.startsWith(tpnme.LAMBDA_ARG_PREFIX)
+ def isHkParamName: Boolean = name(0) == '_' && name.startsWith(HK_PARAM_PREFIX) // tbr
/** The index of the higher-kinded type parameter with this name.
- * Pre: isHkParamName.
+ * Pre: isLambdaArgName.
*/
- def hkParamIndex: Int = name.drop(name.lastIndexOf('$') + 1).toString.toInt
+ def lambdaArgIndex: Int = name.drop(name.lastIndexOf('$') + 1).toString.toInt
+ def hkParamIndex: Int = name.drop(name.lastIndexOf('$') + 1).toString.toInt // tbr
/** If the name ends with $nn where nn are
* all digits, strip the $ and the digits.
@@ -181,7 +183,7 @@ object NameOps {
* by this name.
* @pre The name is a higher-kinded trait name, i.e. it starts with HK_TRAIT_PREFIX
*/
- def hkVariances: List[Int] = {
+ def hkVariances: List[Int] = { // tbr
def varianceOfSuffix(suffix: Char): Int = {
val idx = tpnme.varianceSuffixes.indexOf(suffix)
assert(idx >= 0)
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 593feb909..3b1cb63f1 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -166,6 +166,7 @@ object StdNames {
final val WILDCARD_STAR: N = "_*"
final val REIFY_TREECREATOR_PREFIX: N = "$treecreator"
final val REIFY_TYPECREATOR_PREFIX: N = "$typecreator"
+ final val LAMBDA_ARG_PREFIX: N = "$hkArg$"
final val Any: N = "Any"
final val AnyVal: N = "AnyVal"
@@ -249,8 +250,8 @@ object StdNames {
val SKOLEM: N = "<skolem>"
val SPECIALIZED_INSTANCE: N = "specInstance$"
val THIS: N = "_$this"
- val HK_PARAM_PREFIX: N = "_$hk$"
- val HK_TRAIT_PREFIX: N = "$HigherKinded$"
+ val HK_PARAM_PREFIX: N = "_$hk$" // tbr
+ val HK_TRAIT_PREFIX: N = "$HigherKinded$" // tbr
final val Nil: N = "Nil"
final val Predef: N = "Predef"
@@ -286,6 +287,7 @@ object StdNames {
val Flag : N = "Flag"
val Ident: N = "Ident"
val Import: N = "Import"
+ val LambdaPrefix: N = "Lambda$"
val Literal: N = "Literal"
val LiteralAnnotArg: N = "LiteralAnnotArg"
val Modifiers: N = "Modifiers"
@@ -645,8 +647,11 @@ object StdNames {
def syntheticTypeParamNames(num: Int): List[TypeName] =
(0 until num).map(syntheticTypeParamName)(breakOut)
- def higherKindedTraitName(vcs: List[Int]): TypeName = HK_TRAIT_PREFIX ++ vcs.map(varianceSuffix).mkString
- def higherKindedParamName(n: Int) = HK_PARAM_PREFIX ++ n.toString
+ def higherKindedTraitName(vcs: List[Int]): TypeName = HK_TRAIT_PREFIX ++ vcs.map(varianceSuffix).mkString // tbr
+ def higherKindedParamName(n: Int) = HK_PARAM_PREFIX ++ n.toString //tbr
+
+ def lambdaTraitName(vcs: List[Int]): TypeName = LambdaPrefix ++ vcs.map(varianceSuffix).mkString
+ def lambdaArgName(n: Int) = LAMBDA_ARG_PREFIX ++ n.toString
final val Conforms = encode("<:<")