Skip to content

Commit

Permalink
[nomaster] Revert "refactors handling of parent types"
Browse files Browse the repository at this point in the history
This reverts commit 40063b0.

Conflicts:
	src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
	src/compiler/scala/tools/nsc/typechecker/Typers.scala
  • Loading branch information
xeno-by committed Feb 5, 2013
1 parent 570f4a4 commit c9a0e36
Show file tree
Hide file tree
Showing 21 changed files with 225 additions and 400 deletions.
18 changes: 6 additions & 12 deletions src/compiler/scala/tools/nsc/ast/Trees.scala
Expand Up @@ -82,7 +82,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* body
* }
*/
def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): Template = {
def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): Template = {
/* Add constructor to template */

// create parameters for <init> as synthetic trees.
Expand Down Expand Up @@ -117,16 +117,9 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos)(gen.mkSuperSelect)
val superCall = Apply(superRef, Nil) // we can't know in advance which of the parents will end up as a superclass
// this requires knowing which of the parents is a type macro and which is not
// and that's something that cannot be found out before typer
// (the type macros aren't in the trunk yet, but there is a plan for them to land there soon)
// this means that we don't know what will be the arguments of the super call
// therefore here we emit a dummy which gets populated when the template is named and typechecked
val superCall = (superRef /: argss) (Apply.apply)
List(
// TODO: previously this was `wrappingPos(superPos, lvdefs ::: argss.flatten)`
// is it going to be a problem that we can no longer include the `argss`?
atPos(wrappingPos(superPos, lvdefs)) (
atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
}
}
Expand All @@ -144,10 +137,11 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* @param constrMods the modifiers for the class constructor, i.e. as in `class C private (...)`
* @param vparamss the value parameters -- if they have symbols they
* should be owned by `sym`
* @param argss the supercall arguments
* @param body the template statements without primary constructor
* and value parameter fields.
*/
def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): ClassDef = {
def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = {
// "if they have symbols they should be owned by `sym`"
assert(
mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
Expand All @@ -157,7 +151,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
ClassDef(sym,
Template(sym.info.parents map TypeTree,
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
constrMods, vparamss, body, superPos))
constrMods, vparamss, argss, body, superPos))
}

// --- subcomponents --------------------------------------------------
Expand Down
62 changes: 32 additions & 30 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Expand Up @@ -1559,9 +1559,9 @@ self =>
val nstart = in.skipToken()
val npos = r2p(nstart, nstart, in.lastOffset)
val tstart = in.offset
val (parents, self, stats) = template()
val (parents, argss, self, stats) = template(isTrait = false)
val cpos = r2p(tstart, tstart, in.lastOffset max tstart)
makeNew(parents, self, stats, npos, cpos)
makeNew(parents, self, stats, argss, npos, cpos)
case _ =>
syntaxErrorOrIncomplete("illegal start of simple expression", true)
errorTermTree
Expand Down Expand Up @@ -2739,17 +2739,20 @@ self =>
* TraitParents ::= AnnotType {with AnnotType}
* }}}
*/
def templateParents(): List[Tree] = {
val parents = new ListBuffer[Tree]
def readAppliedParent() = {
val start = in.offset
val parent = startAnnotType()
val argss = if (in.token == LPAREN) multipleArgumentExprs() else Nil
parents += atPos(start)((parent /: argss)(Apply.apply))
def templateParents(isTrait: Boolean): (List[Tree], List[List[Tree]]) = {
val parents = new ListBuffer[Tree] += startAnnotType()
val argss = (
// TODO: the insertion of ListOfNil here is where "new Foo" becomes
// indistinguishable from "new Foo()".
if (in.token == LPAREN && !isTrait) multipleArgumentExprs()
else ListOfNil
)

while (in.token == WITH) {
in.nextToken()
parents += startAnnotType()
}
readAppliedParent()
while (in.token == WITH) { in.nextToken(); readAppliedParent() }
parents.toList
(parents.toList, argss)
}

/** {{{
Expand All @@ -2759,7 +2762,7 @@ self =>
* EarlyDef ::= Annotations Modifiers PatDef
* }}}
*/
def template(): (List[Tree], ValDef, List[Tree]) = {
def template(isTrait: Boolean): (List[Tree], List[List[Tree]], ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
// @S: pre template body cannot stub like post body can!
Expand All @@ -2776,16 +2779,16 @@ self =>
case _ => List()
}
in.nextToken()
val parents = templateParents()
val (self1, body1) = templateBodyOpt(parenMeansSyntaxError = false)
(parents, self1, earlyDefs ::: body1)
val (parents, argss) = templateParents(isTrait = isTrait)
val (self1, body1) = templateBodyOpt(traitParentSeen = isTrait)
(parents, argss, self1, earlyDefs ::: body1)
} else {
(List(), self, body)
(List(), ListOfNil, self, body)
}
} else {
val parents = templateParents()
val (self, body) = templateBodyOpt(parenMeansSyntaxError = false)
(parents, self, body)
val (parents, argss) = templateParents(isTrait = isTrait)
val (self, body) = templateBodyOpt(traitParentSeen = isTrait)
(parents, argss, self, body)
}
}

Expand All @@ -2799,15 +2802,15 @@ self =>
* }}}
*/
def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = {
val (parents0, self, body) = (
val (parents0, argss, self, body) = (
if (in.token == EXTENDS || in.token == SUBTYPE && mods.isTrait) {
in.nextToken()
template()
template(isTrait = mods.isTrait)
}
else {
newLineOptWhenFollowedBy(LBRACE)
val (self, body) = templateBodyOpt(parenMeansSyntaxError = mods.isTrait || name.isTermName)
(List(), self, body)
val (self, body) = templateBodyOpt(traitParentSeen = false)
(List(), ListOfNil, self, body)
}
)
def anyrefParents() = {
Expand All @@ -2829,7 +2832,7 @@ self =>
if (inScalaRootPackage && ScalaValueClassNames.contains(name))
Template(parents0, self, anyvalConstructor :: body)
else
Template(anyrefParents, self, constrMods, vparamss, body, o2p(tstart))
Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart))
}
}

Expand All @@ -2844,15 +2847,14 @@ self =>
case (self, Nil) => (self, EmptyTree.asList)
case result => result
}
def templateBodyOpt(parenMeansSyntaxError: Boolean): (ValDef, List[Tree]) = {
def templateBodyOpt(traitParentSeen: Boolean): (ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
templateBody(isPre = false)
} else {
if (in.token == LPAREN) {
if (parenMeansSyntaxError) syntaxError(s"traits or objects may not have parameters", true)
else abort("unexpected opening parenthesis")
}
if (in.token == LPAREN)
syntaxError((if (traitParentSeen) "parents of traits" else "traits or objects")+
" may not have parameters", true)
(emptyValDef, List())
}
}
Expand Down
20 changes: 7 additions & 13 deletions src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
Expand Up @@ -205,34 +205,28 @@ abstract class TreeBuilder {
*/
def makeAnonymousNew(stats: List[Tree]): Tree = {
val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats
makeNew(Nil, emptyValDef, stats1, NoPosition, NoPosition)
makeNew(Nil, emptyValDef, stats1, ListOfNil, NoPosition, NoPosition)
}

/** Create positioned tree representing an object creation <new parents { stats }
* @param npos the position of the new
* @param cpos the position of the anonymous class starting with parents
*/
def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree],
def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], argss: List[List[Tree]],
npos: Position, cpos: Position): Tree =
if (parents.isEmpty)
makeNew(List(scalaAnyRefConstr), self, stats, npos, cpos)
else if (parents.tail.isEmpty && stats.isEmpty) {
// `Parsers.template` no longer differentiates tpts and their argss
// e.g. `C()` will be represented as a single tree Apply(Ident(C), Nil)
// instead of parents = Ident(C), argss = Nil as before
// this change works great for things that are actually templates
// but in this degenerate case we need to perform postprocessing
val app = treeInfo.dissectApplied(parents.head)
atPos(npos union cpos) { New(app.callee, app.argss) }
} else {
makeNew(List(scalaAnyRefConstr), self, stats, argss, npos, cpos)
else if (parents.tail.isEmpty && stats.isEmpty)
atPos(npos union cpos) { New(parents.head, argss) }
else {
val x = tpnme.ANON_CLASS_NAME
atPos(npos union cpos) {
Block(
List(
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
Template(parents, self, NoMods, ListOfNil, stats, cpos.focus))
Template(parents, self, NoMods, ListOfNil, argss, stats, cpos.focus))
}),
atPos(npos) {
New(
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/transform/Constructors.scala
Expand Up @@ -511,6 +511,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
sym = closureClass,
constrMods = Modifiers(0),
vparamss = List(List(outerFieldDef)),
argss = ListOfNil,
body = List(applyMethodDef),
superPos = impl.pos)
}
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/transform/UnCurry.scala
Expand Up @@ -277,7 +277,7 @@ abstract class UnCurry extends InfoTransform

localTyper.typedPos(fun.pos) {
Block(
List(ClassDef(anonClass, NoMods, ListOfNil, List(applyMethodDef), fun.pos)),
List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}

Expand Down Expand Up @@ -403,7 +403,7 @@ abstract class UnCurry extends InfoTransform

localTyper.typedPos(fun.pos) {
Block(
List(ClassDef(anonClass, NoMods, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
}
Expand Down
13 changes: 6 additions & 7 deletions src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
Expand Up @@ -184,18 +184,14 @@ trait ContextErrors {
}

def ParentTypesError(templ: Template, ex: TypeError) = {
templ.tpe = null
issueNormalTypeError(templ, ex.getMessage())
setError(templ)
templ.tpe = null
issueNormalTypeError(templ, ex.getMessage())
}

// additional parentTypes errors
def ConstrArgsInParentWhichIsTraitError(arg: Tree, parent: Symbol) =
def ConstrArgsInTraitParentTpeError(arg: Tree, parent: Symbol) =
issueNormalTypeError(arg, parent + " is a trait; does not take constructor arguments")

def ConstrArgsInParentOfTraitError(arg: Tree, parent: Symbol) =
issueNormalTypeError(arg, "parents of traits may not have parameters")

def MissingTypeArgumentsParentTpeError(supertpt: Tree) =
issueNormalTypeError(supertpt, "missing type arguments")

Expand Down Expand Up @@ -1048,6 +1044,9 @@ trait ContextErrors {
def MaxParametersCaseClassError(tree: Tree) =
issueNormalTypeError(tree, "Implementation restriction: case classes cannot have more than " + definitions.MaxFunctionArity + " parameters.")

def InheritsItselfError(tree: Tree) =
issueNormalTypeError(tree, tree.tpe.typeSymbol+" inherits itself")

def MissingParameterOrValTypeError(vparam: Tree) =
issueNormalTypeError(vparam, "missing parameter type")

Expand Down
9 changes: 7 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Namers.scala
Expand Up @@ -857,8 +857,13 @@ trait Namers extends MethodSynthesis {
private def templateSig(templ: Template): Type = {
val clazz = context.owner
def checkParent(tpt: Tree): Type = {
if (tpt.tpe.isError) AnyRefClass.tpe
else tpt.tpe
val tp = tpt.tpe
val inheritsSelf = tp.typeSymbol == owner
if (inheritsSelf)
InheritsItselfError(tpt)

if (inheritsSelf || tp.isError) AnyRefClass.tpe
else tp
}

val parents = typer.parentTypes(templ) map checkParent
Expand Down
22 changes: 0 additions & 22 deletions src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
Expand Up @@ -4,29 +4,7 @@ package typechecker
trait StdAttachments {
self: Analyzer =>

import global._

/** Carries information necessary to expand the host tree.
* At times we need to store this info, because macro expansion can be delayed until its targs are inferred.
* After a macro application has been successfully expanded, this attachment is destroyed.
*/
type UnaffiliatedMacroContext = scala.reflect.macros.runtime.Context
type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type }
case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext])

/** After being synthesized by the parser, primary constructors aren't fully baked yet.
* A call to super in such constructors is just a fill-me-in-later dummy resolved later
* by `parentTypes`. This attachment coordinates `parentTypes` and `typedTemplate` and
* allows them to complete the synthesis.
*/
case class SuperCallArgsAttachment(argss: List[List[Tree]])

/** Extractor for `SuperCallArgsAttachment`.
* Compared with `MacroRuntimeAttachment` this attachment has different a usage pattern,
* so it really benefits from a dedicated extractor.
*/
object CarriesSuperCallArgs {
def unapply(tree: Tree): Option[List[List[Tree]]] =
tree.attachments.get[SuperCallArgsAttachment] collect { case SuperCallArgsAttachment(argss) => argss }
}
}

1 comment on commit c9a0e36

@scala-jenkins
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Job pr-checkin-per-commit failed for c9a0e36 (results):


Took 9 s.
sad kitty
to rebuild, comment "PLS REBUILD/pr-checkin-per-commit@c9a0e36224b6eb2807bad0df2d5aa11bb05c8a32"on PR #2112

Please sign in to comment.