diff options
author | Martin Odersky <odersky@gmail.com> | 2013-07-08 11:05:55 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-07-11 10:07:32 +0200 |
commit | c9679f6c0f3c8200e1b1f537e89488094cfc2576 (patch) | |
tree | 59f142f2b241049737bfb71838235a4451d40cc1 /src/dotty/tools/dotc/ast | |
parent | 0af96c0f5179104fca02cf1aa144c6176bdb71eb (diff) | |
download | dotty-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.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 68 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeInfo.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TypedTrees.scala | 3 |
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 |