From 0ebf72b9498108e67c2133c6522c436af50a18e8 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 25 Nov 2012 22:00:11 +0100 Subject: introduces global.pendingSuperCall Similarly to global.emptyValDef, which is a dummy that stands for an empty self-type, this commit introduces global.pendingSuperCall, which stands for a yet-to-be-filled-in call to a superclass constructor. pendingSuperCall is emitted by Parsers.template, treated specially by Typers.typedParentType and replaced with a real superclass ctor call by Typers.typedTemplate. To avoid copy/paste, this commit also factors out and unifies dumminess of EmptyTree, emptyValDef and pendingSuperCall - they all don't have a position and actively refuse to gain one, same story for tpe. --- src/reflect/scala/reflect/api/BuildUtils.scala | 2 -- src/reflect/scala/reflect/api/Trees.scala | 9 +++++++++ src/reflect/scala/reflect/internal/BuildUtils.scala | 2 -- src/reflect/scala/reflect/internal/Importers.scala | 2 ++ src/reflect/scala/reflect/internal/Positions.scala | 2 +- src/reflect/scala/reflect/internal/Printers.scala | 4 +++- src/reflect/scala/reflect/internal/StdNames.scala | 1 + src/reflect/scala/reflect/internal/Trees.scala | 20 +++++++++++--------- 8 files changed, 27 insertions(+), 15 deletions(-) (limited to 'src/reflect') diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala index 0c8e81a220..8f256aa1f5 100644 --- a/src/reflect/scala/reflect/api/BuildUtils.scala +++ b/src/reflect/scala/reflect/api/BuildUtils.scala @@ -59,8 +59,6 @@ private[reflect] trait BuildUtils { self: Universe => def flagsFromBits(bits: Long): FlagSet - def emptyValDef: ValDef - def This(sym: Symbol): Tree def Select(qualifier: Tree, sym: Symbol): Select diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index c98107f9b5..9a65ddaa96 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -2366,6 +2366,15 @@ trait Trees { self: Universe => */ val emptyValDef: ValDef + /** An empty superclass constructor call corresponding to: + * super.() + * This is used as a placeholder in the primary constructor body in class templates + * to denote the insertion point of a call to superclass constructor after the typechecker + * figures out the superclass of a given template. + * @group Trees + */ + val pendingSuperCall: Apply + // ---------------------- factories ---------------------------------------------- /** A factory method for `ClassDef` nodes. diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index 9f41f0336e..b1b0c5b60b 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -47,8 +47,6 @@ trait BuildUtils { self: SymbolTable => def flagsFromBits(bits: Long): FlagSet = bits - def emptyValDef: ValDef = self.emptyValDef - def This(sym: Symbol): Tree = self.This(sym) def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym) diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index 43902c1930..2f2b02975c 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -334,6 +334,8 @@ trait Importers extends api.Importers { self: SymbolTable => new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl)) case from.emptyValDef => emptyValDef + case from.pendingSuperCall => + pendingSuperCall case from.ValDef(mods, name, tpt, rhs) => new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs)) case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) => diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala index faa161d6b1..b65df0e70b 100644 --- a/src/reflect/scala/reflect/internal/Positions.scala +++ b/src/reflect/scala/reflect/internal/Positions.scala @@ -38,7 +38,7 @@ trait Positions extends api.Positions { self: SymbolTable => protected class DefaultPosAssigner extends PosAssigner { var pos: Position = _ override def traverse(t: Tree) { - if (t eq EmptyTree) () + if (t.isDummy) () else if (t.pos == NoPosition) { t.setPos(pos) super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if? diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 80d247c0ea..6f834803c4 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -542,8 +542,10 @@ trait Printers extends api.Printers { self: SymbolTable => print(")") case EmptyTree => print("EmptyTree") - case emptyValDef: AnyRef if emptyValDef eq self.emptyValDef => + case self.emptyValDef => print("emptyValDef") + case self.pendingSuperCall => + print("pendingSuperCall") case tree: Tree => val hasSymbol = tree.hasSymbol && tree.symbol != NoSymbol val isError = hasSymbol && tree.symbol.name.toString == nme.ERROR.toString diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 5e7f5777b2..c870d8972d 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -730,6 +730,7 @@ trait StdNames { val null_ : NameType = "null" val ofDim: NameType = "ofDim" val origin: NameType = "origin" + val pendingSuperCall: NameType = "pendingSuperCall" val prefix : NameType = "prefix" val productArity: NameType = "productArity" val productElement: NameType = "productElement" diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 0087bb93e7..047298cf82 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -36,6 +36,7 @@ trait Trees extends api.Trees { self: SymbolTable => def isDef = false def isEmpty = false + def isDummy = false /** The canonical way to test if a Tree represents a term. */ @@ -228,14 +229,6 @@ trait Trees extends api.Trees { self: SymbolTable => override def isDef = true } - case object EmptyTree extends TermTree { - val asList = List(this) - super.tpe_=(NoType) - override def tpe_=(t: Type) = - if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for ") - override def isEmpty = true - } - abstract class MemberDef extends DefTree with MemberDefApi { def mods: Modifiers def keyword: String = this match { @@ -599,6 +592,7 @@ trait Trees extends api.Trees { self: SymbolTable => case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args) case _: ApplyImplicitView => new ApplyImplicitView(fun, args) // TODO: ApplyConstructor ??? + case self.pendingSuperCall => self.pendingSuperCall case _ => new Apply(fun, args) }).copyAttrs(tree) def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = @@ -961,12 +955,20 @@ trait Trees extends api.Trees { self: SymbolTable => def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree) - object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) { + trait DummyTree extends Tree { override def isEmpty = true + override def isDummy = true super.setPos(NoPosition) override def setPos(pos: Position) = { assert(false); this } + super.setType(NoType) + override def tpe_=(t: Type) = + if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for "+self.toString) } + case object EmptyTree extends TermTree with DummyTree { val asList = List(this) } + object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with DummyTree + object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with DummyTree + def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = atPos(sym.pos) { assert(sym != NoSymbol) -- cgit v1.2.3