aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
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.scala3
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala44
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala15
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala6
-rw-r--r--src/dotty/tools/dotc/typer/ImportInfo.scala11
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala207
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala21
-rw-r--r--src/dotty/tools/dotc/util/FreshNameCreator.scala5
13 files changed, 241 insertions, 98 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 3b38fed7d..6dfaa9c7b 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -216,6 +216,11 @@ object Trees {
/** Is this tree either the empty tree or the empty ValDef? */
def isEmpty: Boolean = false
+ /** Convert tree to a list. Gives a singleton list, except
+ * for thickets which return their element trees.
+ */
+ def toList: List[Tree[T]] = this :: Nil
+
/** if this tree is the empty tree, the alternative, else this tree */
def orElse(that: => Tree[T]): Tree[T] =
if (this eq EmptyTree) that else this
@@ -465,7 +470,7 @@ 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
@@ -607,7 +612,7 @@ object Trees {
override def withType(tpe: Type) = this.asInstanceOf[ThisTree[Type]]
}
- val EmptyTree: Thicket[_] = Thicket(Array[Tree[Untyped]]())
+ val EmptyTree: Thicket[_] = Thicket(Nil)
def emptyTree[T >: Untyped](): Thicket[T] = EmptyTree.asInstanceOf[Thicket[T]]
@@ -636,18 +641,18 @@ object Trees {
* The contained trees will be integrated when transformed with
* a `transform(List[Tree])` call.
*/
- case class Thicket[T >: Untyped](trees: Array[Tree[T]])
+ case class Thicket[T >: Untyped](trees: List[Tree[T]])
extends Tree[T] with WithoutType[T] {
type ThisTree[T >: Untyped] = Thicket[T]
override def isEmpty: Boolean = trees.isEmpty
+ override def toList: List[Tree[T]] = trees
override def toString = if (isEmpty) "EmptyTree" else "Thicket(" + trees.mkString(", ") + ")"
}
object Thicket {
def apply[T >: Untyped](): Tree[T] = emptyTree()
- def apply[T >: Untyped](x1: Tree[T], x2: Tree[T]): Thicket[T] = Thicket(Array[Tree[T]](x1, x2))
- def apply[T >: Untyped](x1: Tree[T], x2: Tree[T], x3: Tree[T]): Thicket[T] = Thicket(Array[Tree[T]](x1, x2, x3))
- def apply[T >: Untyped](elems: List[Tree[T]]): Thicket[T] = apply(elems.toArray)
+ def apply[T >: Untyped](x1: Tree[T], x2: Tree[T]): Thicket[T] = Thicket(List(x1, x2))
+ def apply[T >: Untyped](x1: Tree[T], x2: Tree[T], x3: Tree[T]): Thicket[T] = Thicket(List(x1, x2, x3))
}
// ----- Auxiliary creation methods ------------------
@@ -888,7 +893,7 @@ object Trees {
case tree: SharedTree[_] if (shared eq tree.shared) => tree
case _ => SharedTree(shared).copyAttr(tree)
}
- def derivedThicket(trees: Array[Tree[T]]): Thicket[T] = tree match {
+ def derivedThicket(trees: List[Tree[T]]): Thicket[T] = tree match {
case tree: Thicket[_] if (trees eq tree.trees) => tree
case _ => Thicket(trees).copyAttr(tree)
}
diff --git a/src/dotty/tools/dotc/ast/UntypedTrees.scala b/src/dotty/tools/dotc/ast/UntypedTrees.scala
index bc64bc465..7e3c906b2 100644
--- a/src/dotty/tools/dotc/ast/UntypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/UntypedTrees.scala
@@ -57,6 +57,9 @@ object untpd extends Trees.Instance[Untyped] {
def makeConstructor(mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree = EmptyTree)(implicit ctx: Context): DefDef =
DefDef(mods, nme.CONSTRUCTOR, Nil, vparamss, TypeTree(), rhs)
+ def emptyConstructor(implicit ctx: Context): DefDef =
+ makeConstructor(Modifiers(), Nil)
+
def makeSelfDef(name: TermName, tpt: Tree)(implicit ctx: Context) =
ValDef(Modifiers(Private), name, tpt, EmptyTree)
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index bef8499b0..221f5c160 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -62,5 +62,5 @@ object Annotations {
}
def ThrowsAnnotation(cls: ClassSymbol)(implicit ctx: Context) =
- Annotation(defn.ThrowsAnnot, Ident(cls.symbolicRef))
+ Annotation(defn.ThrowsAnnot, Ident(cls.symTypeRef))
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 6ff6e148d..98cf7e801 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -8,15 +8,17 @@ import Names._
import Phases._
import Types._
import Symbols._
+import Scopes._
import TypeComparers._, NameOps._, SymDenotations._, util.Positions._
-import ast.tpd._, util.FreshNameCreator
+import ast.Trees._, ast.untpd
+import util.FreshNameCreator
+import typer._
import config.Settings._
-import config.ScalaSettings
import reporting._
import collection.mutable
import collection.immutable.BitSet
import printing._
-import config.{Settings, Platform, JavaPlatform}
+import config.{Settings, ScalaSettings, Platform, JavaPlatform}
import language.implicitConversions
object Contexts {
@@ -48,6 +50,7 @@ object Contexts {
with Symbols
with SymDenotations
with Reporting
+ with NamerContextOps
with Cloneable { thiscontext =>
implicit def ctx: Context = this
@@ -76,6 +79,14 @@ object Contexts {
protected def constraints_=(constraints: Constraints) = _constraints = constraints
def constraints: Constraints = _constraints
+ /** The scope nesting level */
+ private[this] var _scopeNestingLevel: Int = 0
+ def scopeNestingLevel: Int = {
+ if (this._scopeNestingLevel == outer.scopeNestingLevel && this.scope != outer.scope)
+ this._scopeNestingLevel = outer.scopeNestingLevel + 1
+ this._scopeNestingLevel
+ }
+
/** The current type comparer */
private[this] var _typeComparer: TypeComparer = _
protected def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer
@@ -113,9 +124,19 @@ object Contexts {
def sstate: SettingsState = _sstate
/** The current tree */
- private[this] var _tree: Tree = _
- protected def tree_=(tree: Tree) = _tree = tree
- def tree: Tree = _tree
+ private[this] var _tree: Tree[_ >: Untyped] = _
+ protected def tree_=(tree: Tree[_ >: Untyped]) = _tree = tree
+ def tree: Tree[_ >: Untyped] = _tree
+
+ /** The current scope */
+ private[this] var _scope: Scope = _
+ protected def scope_=(scope: Scope) = _scope = scope
+ def scope: Scope = _scope
+
+ /** The currently visible imports */
+ private[this] var _imports: List[ImportInfo] = _
+ protected def imports_=(imports: List[ImportInfo]) = _imports = imports
+ def imports: List[ImportInfo] = _imports
/** The current reporter */
private[this] var _reporter: Reporter = _
@@ -123,7 +144,7 @@ object Contexts {
def reporter: Reporter = _reporter
/** An optional diagostics buffer than is used by some checking code
- * to leave provide more information in the buffer if it exists.
+ * to provide more information in the buffer if it exists.
*/
private var _diagnostics: Option[StringBuilder] = _
protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
@@ -134,6 +155,7 @@ object Contexts {
protected def moreProperties_=(moreProperties: Map[String, Any]) = _moreProperties = moreProperties
def moreProperties: Map[String, Any] = _moreProperties
+
/** If -Ydebug is on, the top of the stack trace where this context
* was created, otherwise `null`.
*/
@@ -165,7 +187,7 @@ object Contexts {
/** The next outer context whose tree is a template or package definition */
def enclTemplate: Context = {
var c = this
- while (c != NoContext && !c.tree.isInstanceOf[Template] && !c.tree.isInstanceOf[PackageDef])
+ while (c != NoContext && !c.tree.isInstanceOf[Template[_]] && !c.tree.isInstanceOf[PackageDef[_]])
c = c.outer
c
}
@@ -232,7 +254,9 @@ object Contexts {
def withRefinedPrinter(printer: Context => Printer): this.type = { this.refinedPrinter = printer; this }
def withOwner(owner: Symbol): this.type = { this.owner = owner; this }
def withSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this }
- def withTree(tree: Tree): this.type = { this.tree = tree; this }
+ def withTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
+ def withScope(scope: Scope): this.type = { this.scope = scope; this }
+ def withImport(importInfo: ImportInfo): this.type = { this.imports = importInfo :: imports; this }
def withReporter(reporter: Reporter): this.type = { this.reporter = reporter; this }
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
def withMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this }
@@ -259,7 +283,7 @@ object Contexts {
refinedPrinter = new RefinedPrinter(_)
owner = NoSymbol
sstate = settings.defaultState
- tree = EmptyTree
+ tree = untpd.EmptyTree
reporter = new ConsoleReporter()(this)
diagnostics = None
moreProperties = Map.empty
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index d8d7f181d..58878a493 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -33,7 +33,7 @@ class Definitions(implicit ctx: Context) {
val paramDecls = newScope
val typeParam = newSyntheticTypeParam(cls, paramDecls)
def instantiate(tpe: Type) =
- if (tpe.typeParams.nonEmpty) tpe.appliedTo(typeParam.symbolicRef)
+ if (tpe.typeParams.nonEmpty) tpe.appliedTo(typeParam.symTypeRef)
else tpe
val parents = parentConstrs.toList map instantiate
val parentRefs: List[TypeRef] = ctx.normalizeToRefs(parents, cls, paramDecls)
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 51e03aee7..56b168102 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -102,7 +102,7 @@ object SymDenotations {
}
}
- protected[core] final def info_=(tp: Type) = {
+ protected[dotc] final def info_=(tp: Type) = {
if ((this is ModuleClass) && !(this is PackageClass))
tp match {
case ClassInfo(_, _, _, _, ost) =>
@@ -585,21 +585,24 @@ object SymDenotations {
* @throws ClassCastException is this is not a type
*/
def typeConstructor(implicit ctx: Context): TypeRef =
- if ((this is PackageClass) || owner.isTerm) symbolicRef
+ if ((this is PackageClass) || owner.isTerm) symTypeRef
else TypeRef(owner.thisType, name.asTypeName).withDenot(this)
/** The symbolic typeref representing the type constructor for this type.
* @throws ClassCastException is this is not a type
*/
- final def symbolicRef(implicit ctx: Context): TypeRef =
+ final def symTypeRef(implicit ctx: Context): TypeRef =
TypeRef.withSym(owner.thisType, symbol.asType)
- /** The termref pointing to this termsymbol
+ /** The symbolic termref pointing to this termsymbol
* @throws ClassCastException is this is not a term
*/
- def termRef(implicit ctx: Context): TermRef =
+ def symTermRef(implicit ctx: Context): TermRef =
TermRef.withSym(owner.thisType, symbol.asTerm)
+ def symRef(implicit ctx: Context): NamedType =
+ NamedType.withSym(owner.thisType, symbol)
+
/** The variance of this type parameter as an Int, with
* +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter
*/
@@ -1042,7 +1045,7 @@ object SymDenotations {
// only apply to the module but not to the module class. The right solution
// is to have the module class completer set the annotations of both the
// class and the module.
- denot.info = mclass.symbolicRef
+ denot.info = mclass.symTypeRef
denot.privateWithin = from.privateWithin
}
}
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 0d6f87cda..23984c7a4 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -226,7 +226,7 @@ trait Symbols { this: Context =>
flags: FlagSet,
boundsFn: List[TypeRef] => List[Type]) = {
val tparams = names map (_ => newNakedSymbol[TypeName](NoCoord))
- val bounds = boundsFn(tparams map (_.symbolicRef))
+ val bounds = boundsFn(tparams map (_.symTypeRef))
(names, tparams, bounds).zipped foreach { (name, tparam, bound) =>
tparam.denot = SymDenotation(tparam, owner, name, flags | TypeParamCreationFlags, bound)
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 880cb7174..c0e338ef1 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -313,7 +313,7 @@ object Types {
// member in Super instead of Sub.
// As an example of this in the wild, see
// loadClassWithPrivateInnerAndSubSelf in ShowClassTests
- tp.cls.symbolicRef.findMember(name, pre, excluded) orElse d
+ tp.cls.symTypeRef.findMember(name, pre, excluded) orElse d
case tp: TypeRef =>
tp.denot.findMember(name, pre, excluded)
case tp: TypeProxy =>
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index f89eeff8f..20f0f1df1 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -264,12 +264,12 @@ object Parsers {
*/
def convertToParam(tree: Tree, mods: Modifiers = Modifiers(), expected: String = "formal parameter"): ValDef = tree match {
case Ident(name) =>
- Parameter(name.asTermName, TypeTree(), mods) withPos tree.pos
+ makeParameter(name.asTermName, TypeTree(), mods) withPos tree.pos
case Typed(Ident(name), tpt) =>
- Parameter(name.asTermName, tpt, mods) withPos tree.pos
+ makeParameter(name.asTermName, tpt, mods) withPos tree.pos
case _ =>
syntaxError(s"not a legal $expected (${tree.getClass})", tree.pos)
- Parameter(nme.ERROR, tree, mods)
+ makeParameter(nme.ERROR, tree, mods)
}
/** Convert (qual)ident to type identifier
diff --git a/src/dotty/tools/dotc/typer/ImportInfo.scala b/src/dotty/tools/dotc/typer/ImportInfo.scala
new file mode 100644
index 000000000..b7c8f47e9
--- /dev/null
+++ b/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -0,0 +1,11 @@
+package dotty.tools
+package dotc
+package typer
+
+import ast.untpd._
+import core._
+import Symbols._
+
+case class ImportInfo(sym: Symbol, selectors: List[Tree], scopeNestingLevel: Int) {
+
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index a024ba953..84a82044b 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -4,21 +4,42 @@ package typer
import core._
import ast._
-import Trees._, Constants._, StdNames._
+import Trees._, Constants._, StdNames._, Scopes._
import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._
import util.Positions._
import util.SourcePosition
+import collection.mutable
import language.implicitConversions
-class Namer {
+trait NamerContextOps { ctx: Context =>
+
+ def enterSym(sym: Symbol) = ctx.owner match {
+ case cls: ClassSymbol => cls.enter(sym)
+ case _ => this.scope.asInstanceOf[MutableScope].enter(sym)
+ }
+}
+
+class Namer(val typer: Typer) {
import untpd._
+ val expandedTrees = new mutable.WeakHashMap[Tree, Tree]()
+ val symOfTree = mutable.Map[Tree, Symbol]()
+
implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition =
ctx.source.atPos(pos)
implicit def posToCoord(pos: Position): Coord = positionCoord(pos)
+ def enclosingStats(implicit ctx: Context): List[Trees.Tree[_ >: Untyped]] =
+ if (ctx == NoContext) Nil
+ else ctx.tree match {
+ case Template(_, _, _, stats) => stats
+ case Block(stats, _) => stats
+ case PackageDef(_, stats) => stats
+ case _ => enclosingStats(ctx.outer)
+ }
+
def privateWithinClass(mods: Modifiers)(implicit ctx: Context): Symbol = {
val pw = mods.privateWithin
if (pw.isEmpty) NoSymbol
@@ -29,39 +50,62 @@ class Namer {
}
}
- 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)
+ def createSymbol(tree: Tree, original: Tree)(implicit ctx: Context): Symbol = {
+ def createSym(name: Name, flags: FlagSet, privateWithin: Symbol) = {
+ val sym = ctx.newSymbol(ctx.owner, name, flags, new Completer(original), privateWithin, original.pos)
+ symOfTree(original) = sym
sym
+ }
+ tree match {
+ case tree: ModDefTree =>
+ val sym = createSym(tree.name, tree.mods.flags, privateWithinClass(tree.mods))
+ ctx.enterSym(sym)
+ sym
+ case imp: Import =>
+ createSym(nme.IMPORT, Synthetic, NoSymbol)
+ case _ =>
+ NoSymbol
+ }
}
+ val synthetic = Modifiers(Synthetic)
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
+ def classTypeRef(cdef: ClassDef) = {
+ val tycon = Ident(cdef.name)
+ if (cdef.tparams.isEmpty) tycon else AppliedTypeTree(tycon, cdef.tparams map refOfDef)
+ }
+
+ def creator(cdef: ClassDef) =
+ New(classTypeRef(cdef), cdef.impl.constr.vparamss.nestedMap(refOfDef))
+
+ def methTypeParams(cdef: ClassDef) =
+ for (tparam <- cdef.tparams) yield
+ tparam.derivedTypeDef(Modifiers(TypeParam), tparam.name, tparam.tparams, tparam.rhs)
+
+ def methParamss(cdef: ClassDef) =
+ cdef.impl.constr.vparamss.nestedMap(vparam =>
+ vparam.derivedValDef(Modifiers(TermParam), vparam.name, vparam.tpt, vparam.rhs))
+
+ def expandCaseClass(cdef: ClassDef): ClassDef = {
+ val ClassDef(mods, cname, tparams, impl @ Template(constr, parents, self, stats)) = cdef
val constr1 =
if (constr.vparamss.nonEmpty) constr
else {
- ctx.error("case classes need to have at least one parameter list")
+ ctx.error("case class needs to have at least one parameter list", cdef.pos)
constr.derivedDefDef(constr.mods, constr.name, constr.tparams, ListOfNil, constr.tpt, constr.rhs)
}
val caseParams = constr1.vparamss.head
val caseParamsArray = caseParams.toArray
+ def syntheticProperty(name: TermName, rhs: Tree) = DefDef(synthetic, name, Nil, Nil, EmptyTree, rhs)
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 =>
@@ -69,75 +113,108 @@ class Namer {
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)
+ DefDef(synthetic, nme.copy, methTypeParams(cdef), copyFirstParams :: copyRestParamss, EmptyTree, creator(cdef))
val applyMeth =
- DefDef(Modifiers(Synthetoc), nme.apply, methTparams, applyParamss, EmptyTree, creator)
+ DefDef(synthetic, nme.apply, methTypeParams(cdef), methParamss(cdef), EmptyTree, creator(cdef))
(copyMeth :: Nil, applyMeth :: Nil)
}
val unapplyMeth = {
- val unapplyParam = makeSyntheticParameter(tpt = clsTypeRef)
- DefDef(Modifiers(Synthetic), nme.unapply, methTparams, (unapplyParam :: Nil) :: Nil, clsTypeRef, This(EmptyTypeName))
+ val unapplyParam = makeSyntheticParameter(tpt = classTypeRef(cdef))
+ DefDef(synthetic, nme.unapply, methTypeParams(cdef), (unapplyParam :: Nil) :: Nil, EmptyTree, 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 _ =>
+ updateCompanion(cname.toTermName, applyMeths ::: unapplyMeth :: Nil)
+ addToClass(cdef, copyMeths ::: isDefinedMeth :: productArityMeth :: productElemMeths.toList)
+ }
- }
- if (companion.isEmpty)
- else {
+ def addToTemplate(templ: Template, stats: List[Tree]): Template =
+ templ.derivedTemplate(templ.constr, templ.parents, templ.self, templ.body ++ stats)
- }
+ def addToClass(cdef: ClassDef, stats: List[Tree]): ClassDef =
+ cdef.derivedClassDef(cdef.mods, cdef.name, cdef.tparams, addToTemplate(cdef.impl, stats))
- val applyMeth = {
- val applyVparamss =
- DefDef(Modifiers(Synthetic), nme.apply, methTparams, applyVparamss, EmptyTree, )
- }
+ def addToModule(mdef: ModuleDef, stats: List[Tree]): ModuleDef =
+ mdef.derivedModuleDef(mdef.mods, mdef.name, addToTemplate(mdef.impl, stats))
+ def updateCompanion(name: TermName, newDefs: List[Tree]) =
+ for (companion @ ModuleDef(_, `name`, _) <- enclosingStats) {
+ expandedTrees(companion) = expandedTrees get companion match {
+ case Some(Thicket(vdef :: (cdef: ClassDef) :: Nil)) =>
+ Thicket(vdef, addToClass(cdef, newDefs))
+ case none =>
+ addToModule(companion, newDefs)
+ }
}
- }
-
+ def implicitWrapper(cdef: ClassDef) =
+ DefDef(Modifiers(Synthetic | Implicit), cdef.name.toTermName,
+ methTypeParams(cdef), methParamss(cdef), EmptyTree, creator(cdef))
- 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)
+ val tree1 = tree match {
+ case ValDef(mods, name, tpt, rhs) =>
+ if (!ctx.owner.isClass || (mods is Private)) tree
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)
+ 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)
+ case mdef: ModuleDef =>
+ desugarModuleDef {
+ expandedTrees get mdef match {
+ case Some(mdef1: ModuleDef) => mdef
+ case _ => mdef
+ }
+ }
+ case cdef: ClassDef =>
+ val result = if (cdef.mods is Case) expandCaseClass(cdef) else cdef
+ if (cdef.mods is Implicit) {
+ if (ctx.owner is Package)
+ ctx.error("implicit classes may not be toplevel", cdef.pos)
+ Thicket(result :: implicitWrapper(cdef) :: Nil)
+ }
+ else result
+ case _ =>
+ tree
+ }
+ if (tree1 ne tree) expandedTrees(tree) = tree1
+ tree1
}
- 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 enterSyms(stats: List[Tree])(implicit ctx: Context): Unit = stats match {
+ case (imp @ Import(expr, selectors)) :: rest =>
+ val sym = createSymbol(imp, imp)
+ enterSyms(rest)(ctx.fresh.withImport(ImportInfo(sym, selectors, ctx.scopeNestingLevel)))
+ case stat :: rest =>
+ for (expanded <- expansion(stat).toList) createSymbol(expanded, stat)
+ enterSyms(rest)
+ case Nil =>
}
- def enter(tree: Tree)(implicit ctx: Context) = tree match {
- case Import(expr, selectors) =>
- ???
- case DefDef
- }
+ class Completer(tree: Tree)(implicit ctx: Context) extends LazyType {
+ def complete(sym: SymDenotation): Unit = {
+ for (defn <- expandedTrees.getOrElse(tree, tree).toList if symOfTree(defn) == sym)
+ defn match {
+ case ValDef(mods, name, tpt, rhs) =>
+ val (tpt1, rhs1) =
+ if (tpt.isEmpty) {
+ val rhs1 = typer.typedExpr(rhs)
+ (TypeTree().withType(rhs1.tpe), TypedSplice(rhs1))
+ }
+ else (typer.typedType(tpt), rhs)
+ defn.derivedValDef(mods, name, TypedSplice(tpt1), rhs1)
+
+ }
+
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
new file mode 100644
index 000000000..c9405af86
--- /dev/null
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -0,0 +1,21 @@
+package dotty.tools
+package dotc
+package typer
+
+import core._
+import ast._
+import Trees._, Constants._, StdNames._, Scopes._
+import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Flags._, Decorators._
+import util.Positions._
+import util.SourcePosition
+import collection.mutable
+import language.implicitConversions
+
+trait TyperContextOps { ctx: Context => }
+
+
+class Typer {
+ def typed(tree: untpd.Tree, pt: Type)(implicit ctx: Context): tpd.Tree = ???
+ def typedExpr(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree = ???
+ def typedType(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree = ???
+} \ 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 cc39008ed..ff9f68290 100644
--- a/src/dotty/tools/dotc/util/FreshNameCreator.scala
+++ b/src/dotty/tools/dotc/util/FreshNameCreator.scala
@@ -5,8 +5,7 @@ package util
import scala.collection.mutable
trait FreshNameCreator {
- def newName(): String
- def newName(prefix: String): String
+ def newName(prefix: String = ""): String
@deprecated("use newName(prefix)", "2.9.0")
def newName(pos: scala.reflect.internal.util.Position, prefix: String): String = newName(prefix)
@@ -24,7 +23,7 @@ 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
val counter = counters(safePrefix)