diff options
author | Martin Odersky <odersky@gmail.com> | 2013-05-28 14:56:22 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-05-28 14:56:22 +0200 |
commit | c53ac49cbe7c98c05a99fea3c8e1dcad75275a82 (patch) | |
tree | 0eef0f9b2cf63f025f70183846bb90ef7b83dabb /src/dotty/tools/dotc/typer/Namer.scala | |
parent | 41c54e9b3df245defd774cf06132880479128cb5 (diff) | |
download | dotty-c53ac49cbe7c98c05a99fea3c8e1dcad75275a82.tar.gz dotty-c53ac49cbe7c98c05a99fea3c8e1dcad75275a82.tar.bz2 dotty-c53ac49cbe7c98c05a99fea3c8e1dcad75275a82.zip |
wip namer.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 143 |
1 files changed, 143 insertions, 0 deletions
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 |