aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-07-08 11:05:55 +0200
committerMartin Odersky <odersky@gmail.com>2013-07-11 10:07:32 +0200
commitc9679f6c0f3c8200e1b1f537e89488094cfc2576 (patch)
tree59f142f2b241049737bfb71838235a4451d40cc1 /src/dotty/tools/dotc/ast
parent0af96c0f5179104fca02cf1aa144c6176bdb71eb (diff)
downloaddotty-c9679f6c0f3c8200e1b1f537e89488094cfc2576.tar.gz
dotty-c9679f6c0f3c8200e1b1f537e89488094cfc2576.tar.bz2
dotty-c9679f6c0f3c8200e1b1f537e89488094cfc2576.zip
Added functionality to deal with function applications.
- Added Applications class to represent applications - Added Constraint class to represent type constraints - Added TyperState class to represent typer state - Added Diagnostic class to buffer errors and warnings - Added Inferencing class that contains some common functionality for type inferencing (this one's still rudimentary). - Added extractor for FunctionType in Definitions - Added desugaring of default parameters to default getters in Desugar - Added flags to deal with default parameters - Added substitutions that replace bound parameters
Diffstat (limited to 'src/dotty/tools/dotc/ast')
-rw-r--r--src/dotty/tools/dotc/ast/CheckTrees.scala4
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala68
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala15
-rw-r--r--src/dotty/tools/dotc/ast/TypedTrees.scala3
4 files changed, 74 insertions, 16 deletions
diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala
index 4c3413ada..4790f231b 100644
--- a/src/dotty/tools/dotc/ast/CheckTrees.scala
+++ b/src/dotty/tools/dotc/ast/CheckTrees.scala
@@ -36,7 +36,7 @@ object CheckTrees {
case NamedArg(argName, _) =>
check(argName == name)
case SeqLiteral(_, _) =>
- check(defn.RepeatedParamClasses contains formal.typeSymbol)
+ check(formal.isRepeatedParam)
case _ =>
check(arg.isValue)
}
@@ -187,7 +187,7 @@ object CheckTrees {
case nme.unapplySeq =>
// args need to be wrapped in (...: _*)
check(args.length == 1)
- check(args.head.tpe.typeSymbol == defn.RepeatedParamClass)
+ check(args.head.tpe.isRepeatedParam)
case nme.unapply =>
val rtp = funtpe.resultType
val rsym = rtp.dealias.typeSymbol
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index faa015793..ae1a06a74 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -34,7 +34,7 @@ object desugar {
}
}
- def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false): DefDef = {
+ def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false): Tree = {
val DefDef(mods, name, tparams, vparamss, tpt, rhs) = meth
val epbuf = new ListBuffer[ValDef]
val tparams1 = tparams mapConserve {
@@ -49,7 +49,8 @@ object desugar {
case tparam =>
tparam
}
- epbuf.toList match {
+
+ val meth1 = epbuf.toList match {
case Nil =>
meth
case evidenceParams =>
@@ -61,6 +62,42 @@ object desugar {
}
meth.derivedDefDef(mods, name, tparams1, vparamss1, tpt, rhs)
}
+
+ def take(vparamss: List[List[ValDef]], n: Int): List[List[ValDef]] = vparamss match {
+ case vparams :: vparamss1 =>
+ val len = vparams.length
+ if (len <= n) vparams :: take(vparamss1, n - len) else Nil
+ case _ =>
+ Nil
+ }
+
+ def defaultGetters(vparamss: List[List[ValDef]], n: Int = 0): List[DefDef] = vparamss match {
+ case (vparam :: vparams) :: vparamss1 =>
+ def defaultGetter: DefDef =
+ DefDef(
+ mods = vparam.mods & AccessFlags,
+ name = meth.name.defaultGetterName(n + 1),
+ tparams = meth.tparams,
+ vparamss = take(meth.vparamss, n),
+ tpt = TypeTree(),
+ rhs = vparam.rhs)
+ val rest = defaultGetters(vparams :: vparamss1, n + 1)
+ if (vparam.rhs.isEmpty) rest else defaultGetter :: rest
+ case Nil :: vparamss1 =>
+ defaultGetters(vparamss1)
+ case nil =>
+ Nil
+ }
+
+ val defGetters = defaultGetters(vparamss)
+ if (defGetters.isEmpty) meth1
+ else {
+ val mods1 = meth1.mods | DefaultParameterized
+ val vparamss1 = vparamss map (_ map (vparam =>
+ vparam.derivedValDef(vparam.mods, vparam.name, vparam.tpt, EmptyTree)))
+ val meth2 = meth1.derivedDefDef(mods1, meth1.name, meth1.tparams, vparamss1, meth1.tpt, meth1.rhs)
+ Thicket(meth2 :: defGetters)
+ }
}
def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = {
@@ -81,7 +118,10 @@ object desugar {
val TypeDef(
mods, name, impl @ Template(constr0, parents, self, body)) = cdef
- val constr1 = defDef(constr0, isPrimaryConstructor = true)
+ val (constr1, defaultGetters) = defDef(constr0, isPrimaryConstructor = true) match {
+ case meth: DefDef => (meth, Nil)
+ case Thicket((meth: DefDef) :: defaults) => (meth, defaults)
+ }
val tparams = constr1.tparams.map(tparam => tparam.derivedTypeDef(
Modifiers(Param), tparam.name, tparam.rhs, tparam.tparams))
@@ -129,10 +169,18 @@ object desugar {
}
else Nil
- val caseCompanions =
+ def anyRef = ref(defn.AnyRefAlias.typeConstructor)
+
+ def companionDefs(parent: Tree, defs: List[Tree]) =
+ moduleDef(
+ ModuleDef(
+ Modifiers(Synthetic), name.toTermName,
+ Template(emptyConstructor, parent :: Nil, EmptyValDef(), defs))).toList
+
+ val companions =
if (mods is Case) {
val parent =
- if (tparams.nonEmpty) ref(defn.AnyRefAlias.typeConstructor)
+ if (tparams.nonEmpty) anyRef
else (vparamss :\ classTypeRef) ((vparams, restpe) => Function(vparams map (_.tpt), restpe))
val applyMeths =
if (mods is Abstract) Nil
@@ -141,12 +189,10 @@ object desugar {
val unapplyParam = makeSyntheticParameter(tpt = classTypeRef)
DefDef(synthetic, nme.unapply, tparams, (unapplyParam :: Nil) :: Nil, EmptyTree, This(EmptyTypeName))
}
- moduleDef(
- ModuleDef(
- Modifiers(Synthetic), name.toTermName,
- Template(emptyConstructor, parent :: Nil, EmptyValDef(), applyMeths ::: unapplyMeth :: Nil))
- ).toList
+ companionDefs(parent, applyMeths ::: unapplyMeth :: defaultGetters)
}
+ else if (defaultGetters.nonEmpty)
+ companionDefs(anyRef, defaultGetters)
else Nil
val implicitWrappers =
@@ -163,7 +209,7 @@ object desugar {
val cdef1 = cdef.derivedTypeDef(mods, name,
impl.derivedTemplate(constr, parents, self,
constr1.tparams ::: constr1.vparamss.flatten ::: body ::: caseClassMeths))
- Thicket.make(cdef1 :: caseCompanions ::: implicitWrappers)
+ Thicket.make(cdef1 :: companions ::: implicitWrappers)
}
/** Expand to:
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 7e9c404eb..a3af19263 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -94,7 +94,7 @@ abstract class TreeInfo {
def recur(params: List[Symbol], args: List[Tree[T]]): Boolean = params match {
case Nil => args.isEmpty
case param :: params1 =>
- if (defn.RepeatedParamClasses contains param.info.typeSymbol) {
+ if (param.info.isRepeatedParam) {
for (arg <- args) f(param, arg)
true
} else args match {
@@ -128,10 +128,19 @@ abstract class TreeInfo {
case Apply(fn, _) => methPart(fn)
case TypeApply(fn, _) => methPart(fn)
case AppliedTypeTree(fn, _) => methPart(fn)
- case Block(stats, expr) if stats forall (_.isInstanceOf[ValDef[_]]) => methPart(expr)
+ case Block(stats, expr) => methPart(expr)
case _ => tree
}
+ /** The number of arguments in an application */
+ def numArgs[T >: Untyped](tree: Tree[T]): Int = tree match {
+ case Apply(fn, args) => numArgs(fn) + args.length
+ case TypeApply(fn, args) => numArgs(fn) + args.length
+ case AppliedTypeTree(fn, args) => numArgs(fn) + args.length
+ case Block(stats, expr) => numArgs(expr)
+ case _ => 0
+ }
+
/** Is symbol potentially a getter of a mutable variable?
*/
def mayBeVarGetter(sym: Symbol)(implicit ctx: Context): Boolean = {
@@ -237,7 +246,7 @@ abstract class TreeInfo {
/** Is tpt a vararg type of the form T* ? */
def isRepeatedParamType(tpt: Tree[_ >: Untyped])(implicit ctx: Context) = tpt match {
- case tpt: TypeTree[_] => defn.RepeatedParamClasses contains tpt.typeOpt.typeSymbol
+ case tpt: TypeTree[_] => tpt.typeOpt.isRepeatedParam
case AppliedTypeTree(Select(_, tpnme.REPEATED_PARAM_CLASS), _) => true
case AppliedTypeTree(Select(_, tpnme.JAVA_REPEATED_PARAM_CLASS), _) => true
case _ => false
diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala
index 5e4f7342d..cce905d92 100644
--- a/src/dotty/tools/dotc/ast/TypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/TypedTrees.scala
@@ -87,6 +87,9 @@ object tpd extends Trees.Instance[Type] {
blk.withType(widen(expr.tpe))
}
+ def maybeBlock(stats: List[Tree], expr: Tree)(implicit ctx: Context): Tree =
+ if (stats.isEmpty) expr else Block(stats, expr)
+
def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
Trees.If(cond, thenp, elsep).withType(thenp.tpe | elsep.tpe).checked