aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-05-28 14:56:22 +0200
committerMartin Odersky <odersky@gmail.com>2013-05-28 14:56:22 +0200
commitc53ac49cbe7c98c05a99fea3c8e1dcad75275a82 (patch)
tree0eef0f9b2cf63f025f70183846bb90ef7b83dabb /src/dotty/tools/dotc
parent41c54e9b3df245defd774cf06132880479128cb5 (diff)
downloaddotty-c53ac49cbe7c98c05a99fea3c8e1dcad75275a82.tar.gz
dotty-c53ac49cbe7c98c05a99fea3c8e1dcad75275a82.tar.bz2
dotty-c53ac49cbe7c98c05a99fea3c8e1dcad75275a82.zip
wip namer.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala19
-rw-r--r--src/dotty/tools/dotc/ast/UntypedTrees.scala26
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala3
-rw-r--r--src/dotty/tools/dotc/core/Decorators.scala4
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala5
-rw-r--r--src/dotty/tools/dotc/core/Types.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala143
-rw-r--r--src/dotty/tools/dotc/util/FreshNameCreator.scala10
9 files changed, 191 insertions, 22 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 15aa3585b..3b38fed7d 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -302,7 +302,7 @@ object Trees {
* The envelope of a ModDefTree contains the whole definition and his its point
* on the opening keyword (or the next token after that if keyword is missing).
*/
- trait ModDefTree[T >: Untyped] extends DefTree[T] {
+ trait ModDefTree[T >: Untyped] extends NameTree[T] with DefTree[T] {
type ThisTree[T >: Untyped] <: ModDefTree[T]
def mods: Modifiers[T]
override def envelope: Position = mods.pos union pos union initialPos
@@ -465,12 +465,16 @@ object Trees {
/** A type tree that represents an existing or inferred type */
case class TypeTree[T >: Untyped](original: Tree[T] = emptyTree[T])
- extends DenotingTree[T] with TypTree[T] {
+ extends DenotingTree[T] with TypTree[T]
type ThisTree[T >: Untyped] = TypeTree[T]
override def initialPos = NoPosition
override def isEmpty = !hasType && original.isEmpty
}
+ object TypeTree {
+ def apply(tpe: Type): TypeTree[Type] = TypeTree().withType(tpe)
+ }
+
/** ref.type */
case class SingletonTypeTree[T >: Untyped](ref: Tree[T])
extends DenotingTree[T] with TypTree[T] {
@@ -541,14 +545,14 @@ object Trees {
/** mods val name: tpt = rhs */
case class ValDef[T >: Untyped](mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T])
- extends NameTree[T] with ModDefTree[T] {
+ extends ModDefTree[T] {
type ThisTree[T >: Untyped] = ValDef[T]
def withName(name: Name) = this.derivedValDef(mods, name.toTermName, tpt, rhs)
}
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
case class DefDef[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])
- extends NameTree[T] with ModDefTree[T] {
+ extends ModDefTree[T] {
type ThisTree[T >: Untyped] = DefDef[T]
def withName(name: Name) = this.derivedDefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs)
}
@@ -557,7 +561,7 @@ object Trees {
* mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi)
*/
case class TypeDef[T >: Untyped](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], rhs: Tree[T])
- extends NameTree[T] with ModDefTree[T] {
+ extends ModDefTree[T] {
type ThisTree[T >: Untyped] = TypeDef[T]
def withName(name: Name) = this.derivedTypeDef(mods, name.toTypeName, tparams, rhs)
}
@@ -570,7 +574,7 @@ object Trees {
/** mods class name[tparams] impl */
case class ClassDef[T >: Untyped](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T])
- extends NameTree[T] with ModDefTree[T] {
+ extends ModDefTree[T] {
type ThisTree[T >: Untyped] = ClassDef[T]
def withName(name: Name) = this.derivedClassDef(mods, name.toTypeName, tparams, impl)
}
@@ -716,9 +720,6 @@ object Trees {
protected implicit def pos(implicit ctx: Context): Position = ctx.position
def defPos(sym: Symbol)(implicit ctx: Context) = ctx.position union sym.coord.toPosition
-
- def Parameter(pname: TermName, tpe: Tree, mods: Modifiers = Modifiers()): ValDef =
- ValDef(mods | Param, pname, tpe, emptyTree())
}
// ----- Helper functions and classes ---------------------------------------
diff --git a/src/dotty/tools/dotc/ast/UntypedTrees.scala b/src/dotty/tools/dotc/ast/UntypedTrees.scala
index 3087772a8..bc64bc465 100644
--- a/src/dotty/tools/dotc/ast/UntypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/UntypedTrees.scala
@@ -70,13 +70,18 @@ object untpd extends Trees.Instance[Untyped] {
case _ => Tuple(ts)
}
+ def makeParameter(pname: TermName, tpe: Tree, mods: Modifiers = Modifiers()): ValDef =
+ ValDef(mods | Param, pname, tpe, emptyTree())
+
+ def makeSyntheticParameter(n: Int = 1, tpt: Tree = EmptyTree)(implicit ctx: Context): ValDef =
+ ValDef(Modifiers(SyntheticTermParam), nme.syntheticParamName(n), TypeTree(), EmptyTree)
+
+ def refOfDef(tree: NameTree) = Ident(tree.name)
+
// ------ Untyped tree desugaring ------------------------------------------
def desugar(tree: Tree, mode: Mode.Value)(implicit ctx: Context): Tree = {
- def makeSyntheticParameter(): ValDef =
- ValDef(Modifiers(SyntheticTermParam), ctx.freshName().toTermName, TypeTree(), EmptyTree)
-
def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
val ldef = DefDef(Modifiers(Label), lname, Nil, ListOfNil, TypeTree(), rhs)
Block(ldef, call)
@@ -439,6 +444,21 @@ object untpd extends Trees.Instance[Untyped] {
case _ => tree
}
+ /** Expand to:
+ * <module> val name: name$ = New(name$)
+ * <module> final class name$ extends parents { self: name.type => body }
+ */
+ def desugarModuleDef(mdef: ModuleDef): Tree = {
+ val ModuleDef(mods, name, tmpl @ Template(constr, parents, self, body)) = mdef
+ val clsName = name.moduleClassName
+ val clsRef = Ident(clsName)
+ val modul = ValDef(mods | ModuleCreationFlags, name, clsRef, New(clsRef, Nil))
+ val clsSelf = self.derivedValDef(self.mods, self.name, SingletonTypeTree(Ident(name)), self.rhs)
+ val clsTmpl = tmpl.derivedTemplate(constr, parents, clsSelf, body)
+ val cls = ClassDef(mods.toTypeFlags & AccessFlags | ModuleClassCreationFlags, clsName, Nil, clsTmpl)
+ Thicket(modul, cls)
+ }
+
def desugarAnonClass(templ: Template): Tree = {
val x = tpnme.ANON_CLASS
val clsDef = ClassDef(Modifiers(Final), x, Nil, templ)
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index af8bd6e91..6ff6e148d 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -293,8 +293,7 @@ object Contexts {
/** The standard fresh name creator */
val freshNames = new FreshNameCreator.Default
- def freshName(): String = freshNames.newName()
- def freshName(prefix: String): String = freshNames.newName(prefix)
+ def freshName(prefix: String = ""): String = freshNames.newName(prefix)
def freshName(prefix: Name): String = freshName(prefix.toString)
/** The loader that loads the members of _root_ */
diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala
index 031974dfd..094aa7b4a 100644
--- a/src/dotty/tools/dotc/core/Decorators.scala
+++ b/src/dotty/tools/dotc/core/Decorators.scala
@@ -70,6 +70,10 @@ object Decorators {
}
}
+ implicit class ListOfListDecorator[T](val xss: List[List[T]]) extends AnyVal {
+ def nestedMap[U](f: T => U): List[List[U]] = xss map (_ map f)
+ }
+
implicit class TextToString(val text: Text) extends AnyVal {
def show(implicit ctx: Context) = text.mkString(ctx.settings.pageWidth.value)
}
diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index ada74c69d..9ae4729f4 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -380,6 +380,7 @@ object StdNames {
val info: N = "info"
val inlinedEquals: N = "inlinedEquals"
val isArray: N = "isArray"
+ val isDefined: N = "isDefined"
val isDefinedAt: N = "isDefinedAt"
val isEmpty: N = "isEmpty"
val isInstanceOf_ : N = "isInstanceOf"
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index bec55720f..51e03aee7 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -470,6 +470,11 @@ object SymDenotations {
final def enclosingClass(implicit ctx: Context): Symbol =
if (isClass) symbol else owner.enclosingClass
+ final def enclosingClassNamed(name: Name)(implicit ctx: Context): Symbol = {
+ val cls = enclosingClass
+ if (cls.name == name) cls else cls.owner.enclosingClassNamed(name)
+ }
+
/** The top-level class containing this denotation,
* except for a toplevel module, where its module class is returned.
*/
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 1b21567a0..880cb7174 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1556,7 +1556,7 @@ object Types {
/** The type of an import clause tree */
- case class ImportType(expr: SharedTree) extends UncachedGroundType
+ case class ImportType(expr: Tree) extends UncachedGroundType
/** Sentinal for "missing type" */
case object NoType extends CachedGroundType {
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
new file mode 100644
index 000000000..a024ba953
--- /dev/null
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -0,0 +1,143 @@
+package dotty.tools
+package dotc
+package typer
+
+import core._
+import ast._
+import Trees._, Constants._, StdNames._
+import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._
+import util.Positions._
+import util.SourcePosition
+import language.implicitConversions
+
+class Namer {
+
+ import untpd._
+
+ implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition =
+ ctx.source.atPos(pos)
+
+ implicit def posToCoord(pos: Position): Coord = positionCoord(pos)
+
+ def privateWithinClass(mods: Modifiers)(implicit ctx: Context): Symbol = {
+ val pw = mods.privateWithin
+ if (pw.isEmpty) NoSymbol
+ else {
+ val cls = ctx.owner.enclosingClassNamed(pw)
+ if (!cls.exists) ctx.error(s"no enclosing class or object is named $pw", mods.pos)
+ cls
+ }
+ }
+
+ def createSymbol(tree: Tree)(implicit ctx: Context): Symbol = tree match {
+ case tree: ModDefTree =>
+ val sym = ctx.newSymbol(
+ ctx.owner, tree.name, tree.mods.flags, new Completer(tree),
+ privateWithinClass(tree.mods), tree.pos)
+ ctx.scope.enter(sym)
+ sym
+ }
+
+
+ def expansion(tree: Tree)(implicit ctx: Context): Tree = {
+
+ def expandCaseClass(tree: Tree, companion: Tree): Tree = {
+ val ClassDef(mods, cname, tparams, impl @ Template(constr, parents, self, stats)) = tree
+ val constr1 =
+ if (constr.vparamss.nonEmpty) constr
+ else {
+ ctx.error("case classes need to have at least one parameter list")
+ constr.derivedDefDef(constr.mods, constr.name, constr.tparams, ListOfNil, constr.tpt, constr.rhs)
+ }
+ val caseParams = constr1.vparamss.head
+ val caseParamsArray = caseParams.toArray
+ val isDefinedMeth = syntheticProperty(nme.isDefined, Literal(Constant(true)))
+ val productArityMeth = syntheticProperty(nme.productArity, Literal(Constant(caseParamsArray.length)))
+ val productElemMeths = for (i <- 0 until caseParamsArray.length) yield
+ syntheticProperty(("_" + (i + 1)).toTermName, Select(This(EmptyTypeName), caseParamsArray(i).name))
+ val clsTypeRef = AppliedTypeTree(Ident(cname), tparams map refOfDef)
+ val methTparams = for (tparam <- tparams) yield
+ tparam.derivedTypeDef(Modifiers(TypeParam), tparam.name, tparam.tparams, tparam.rhs)
+ val (copyMeths, applyMeths) =
+ if (mods is Abstract) (Nil, Nil)
+ else {
+ val creator = New(clsTypeRef, constr1.vparamss map (_ map refOfDef))
+ val copyFirstParams = caseParams.map(vparam =>
+ vparam.derivedValDef(Modifiers(TermParam), vparam.name, vparam.tpt, refOfDef(vparam)))
+ val copyRestParamss = constr1.vparamss.tail.nestedMap(vparam =>
+ vparam.derivedValDef(Modifiers(TermParam), vparam.name, vparam.tpt, EmptyTree))
+ val applyParamss = constr1.vparamss.nestedMap(vparam =>
+ vparam.derivedValDef(Modifiers(TermParam), vparam.name, vparam.tpt, vparam.rhs))
+ val copyMeth =
+ DefDef(Modifiers(Synthetic), nme.copy, methTparams, copyFirstParams :: copyRestParamss, EmptyTree, creator)
+ val applyMeth =
+ DefDef(Modifiers(Synthetoc), nme.apply, methTparams, applyParamss, EmptyTree, creator)
+ (copyMeth :: Nil, applyMeth :: Nil)
+ }
+ val unapplyMeth = {
+ val unapplyParam = makeSyntheticParameter(tpt = clsTypeRef)
+ DefDef(Modifiers(Synthetic), nme.unapply, methTparams, (unapplyParam :: Nil) :: Nil, clsTypeRef, This(EmptyTypeName))
+ }
+ val newClassDefs = copyMeths ++ isDefinedMeth :: productArityMeth :: productElemMeths.toList
+ val newModuleDefs = applyMeths ++ unapplyMeth :: Nil
+ val cls1 = tree.derivedClassDef(mods, cname, tparams,
+ impl.derivedTemplate(constr, parents, self, stats ++ newClassDefs))
+ val companion1 = companion match {
+ case ModuleDef(mods, name, impl @ Template(constr, parents, self, stats)) =>
+ companion.derivedModuleDef(mods, name,
+ impl.derivedTemplate(constr, parents, self, stats ++ newModuleDefs))
+ case _ =>
+
+ }
+ if (companion.isEmpty)
+ else {
+
+ }
+
+ val applyMeth = {
+ val applyVparamss =
+ DefDef(Modifiers(Synthetic), nme.apply, methTparams, applyVparamss, EmptyTree, )
+ }
+
+ }
+
+ }
+
+
+ tree match {
+ case ValDef(mods, name, tpt, rhs) =>
+ if (!ctx.owner.isClass || (mods is Private)) tree
+ else {
+ val lname = name.toLocalName
+ val field = tree.derivedValDef(mods, lname, tpt, rhs)
+ val getter = tree.derivedDefDef(mods, name, Nil, Nil, tpt, Ident(lname))
+ if (!(mods is Mutable)) Thicket(field, getter)
+ else {
+ val setterParam = makeSyntheticParameter(tpt = TypeTree(field))
+ val setter = tree.derivedDefDef(
+ mods, name.getterToSetter, Nil, (setterParam :: Nil) :: Nil, EmptyTree, refOfDef(setterParam))
+ Thicket(field, getter, setter)
+ }
+ }
+ case tree: ModuleDef =>
+ desugarModuleDef(tree)
+ case tree: ClassDef if tree.mods is Case =>
+ expandCaseClass(tree)
+ }
+
+ def syntheticProperty(name: TermName, rhs: Tree) = DefDef(Modifiers(Synthetic), name, Nil, Nil, EmptyTree, rhs)
+
+ class Completer(tree: Tree) extends LazyType {
+ def complete(sym: Symbol) =>
+ ???
+ }
+
+ def enter(tree: Tree)(implicit ctx: Context) = tree match {
+ case Import(expr, selectors) =>
+ ???
+ case DefDef
+
+
+ }
+
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/util/FreshNameCreator.scala b/src/dotty/tools/dotc/util/FreshNameCreator.scala
index d0c007d94..cc39008ed 100644
--- a/src/dotty/tools/dotc/util/FreshNameCreator.scala
+++ b/src/dotty/tools/dotc/util/FreshNameCreator.scala
@@ -24,15 +24,11 @@ object FreshNameCreator {
* that the returned name has never been returned by a previous
* call to this function (provided the prefix does not end in a digit).
*/
- def newName(prefix: String): String = {
+ def newName(prefix: String = ""): String = {
val safePrefix = prefix.replaceAll("""[<>]""", """\$""")
counters(safePrefix) += 1
-
- safePrefix + counters(safePrefix)
- }
- def newName(): String = {
- counter += 1
- "$" + counter + "$"
+ val counter = counters(safePrefix)
+ if (prefix.isEmpty) "$" + counter + "$" else safePrefix + counter
}
}
}