diff options
author | Martin Odersky <odersky@gmail.com> | 2013-05-30 10:09:48 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-05-30 10:09:48 +0200 |
commit | 17d0e7008f62882c10193ea0db09c9b90736c320 (patch) | |
tree | 44cf4d4f2675effabb2ba651f9399d7d6fce21a1 | |
parent | c53ac49cbe7c98c05a99fea3c8e1dcad75275a82 (diff) | |
download | dotty-17d0e7008f62882c10193ea0db09c9b90736c320.tar.gz dotty-17d0e7008f62882c10193ea0db09c9b90736c320.tar.bz2 dotty-17d0e7008f62882c10193ea0db09c9b90736c320.zip |
wip, because I have to get off this machine.
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/UntypedTrees.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 44 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/Parsers.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ImportInfo.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 207 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 21 | ||||
-rw-r--r-- | src/dotty/tools/dotc/util/FreshNameCreator.scala | 5 |
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) |