summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala20
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala16
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala8
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala9
-rw-r--r--test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala2
6 files changed, 34 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 61ea9230a7..d122a1a207 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -623,15 +623,6 @@ self =>
syntaxError(tpt.pos, "no * parameter type allowed here", skipIt = false)
}
- /** Check that tree is a legal clause of a forSome. */
- def checkLegalExistential(t: Tree) = t match {
- case TypeDef(_, _, _, TypeBoundsTree(_, _)) |
- ValDef(_, _, _, EmptyTree) | EmptyTree =>
- ;
- case _ =>
- syntaxError(t.pos, "not a legal existential clause", skipIt = false)
- }
-
/* -------------- TOKEN CLASSES ------------------------------------------- */
def isModifier: Boolean = in.token match {
@@ -885,9 +876,14 @@ self =>
}
}
private def makeExistentialTypeTree(t: Tree) = {
- val whereClauses = refinement()
- whereClauses foreach checkLegalExistential
- ExistentialTypeTree(t, whereClauses)
+ // EmptyTrees in the result of refinement() stand for parse errors
+ // so it's okay for us to filter them out here
+ ExistentialTypeTree(t, refinement() flatMap {
+ case t @ TypeDef(_, _, _, TypeBoundsTree(_, _)) => Some(t)
+ case t @ ValDef(_, _, _, EmptyTree) => Some(t)
+ case EmptyTree => None
+ case _ => syntaxError(t.pos, "not a legal existential clause", skipIt = false); None
+ })
}
/** {{{
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 241747e6d8..83da5141b9 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -2058,8 +2058,8 @@ trait Trees { self: Universe =>
* @group Extractors
*/
abstract class ExistentialTypeTreeExtractor {
- def apply(tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
- def unapply(existentialTypeTree: ExistentialTypeTree): Option[(Tree, List[Tree])]
+ def apply(tpt: Tree, whereClauses: List[MemberDef]): ExistentialTypeTree
+ def unapply(existentialTypeTree: ExistentialTypeTree): Option[(Tree, List[MemberDef])]
}
/** The API that all existential type trees support
@@ -2069,8 +2069,12 @@ trait Trees { self: Universe =>
/** The underlying type of the existential type. */
def tpt: Tree
- /** The clauses of the definition of the existential type. */
- def whereClauses: List[Tree]
+ /** The clauses of the definition of the existential type.
+ * Elements are one of the following:
+ * 1) TypeDef with TypeBoundsTree right-hand side
+ * 2) ValDef with empty right-hand side
+ */
+ def whereClauses: List[MemberDef]
}
/** A synthetic tree holding an arbitrary type. Not to be confused with
@@ -2533,7 +2537,7 @@ trait Trees { self: Universe =>
/** Creates a `ExistentialTypeTree` node from the given components, having a given `tree` as a prototype.
* Having a tree as a prototype means that the tree's attachments, type and symbol will be copied into the result.
*/
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[MemberDef]): ExistentialTypeTree
}
// ---------------------- traversing and transforming ------------------------------
@@ -2654,6 +2658,8 @@ trait Trees { self: Universe =>
def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] =
treess mapConserve (transformValDefs(_))
/** Transforms a list of `CaseDef` nodes. */
+ def transformMemberDefs(trees: List[MemberDef]): List[MemberDef] =
+ trees mapConserve (tree => transform(tree).asInstanceOf[MemberDef])
def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] =
trees mapConserve (tree => transform(tree).asInstanceOf[CaseDef])
/** Transforms a list of `Ident` nodes. */
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index cc6e55192f..91ba552012 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -409,7 +409,7 @@ trait Importers extends api.Importers { to: SymbolTable =>
case from.TypeBoundsTree(lo, hi) =>
new TypeBoundsTree(importTree(lo), importTree(hi))
case from.ExistentialTypeTree(tpt, whereClauses) =>
- new ExistentialTypeTree(importTree(tpt), whereClauses map importTree)
+ new ExistentialTypeTree(importTree(tpt), whereClauses map importMemberDef)
case from.EmptyTree =>
EmptyTree
case null =>
@@ -475,6 +475,7 @@ trait Importers extends api.Importers { to: SymbolTable =>
new ImportSelector(importName(sel.name), sel.namePos, if (sel.rename != null) importName(sel.rename) else null, sel.renamePos)
def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef]
def importTypeDef(tree: from.TypeDef): TypeDef = importTree(tree).asInstanceOf[TypeDef]
+ def importMemberDef(tree: from.MemberDef): MemberDef = importTree(tree).asInstanceOf[MemberDef]
def importTemplate(tree: from.Template): Template = importTree(tree).asInstanceOf[Template]
def importRefTree(tree: from.RefTree): RefTree = importTree(tree).asInstanceOf[RefTree]
def importIdent(tree: from.Ident): Ident = importTree(tree).asInstanceOf[Ident]
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index d191fbd38f..4a518f6c56 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -541,7 +541,7 @@ trait Trees extends api.Trees {
extends TypTree with TypeBoundsTreeApi
object TypeBoundsTree extends TypeBoundsTreeExtractor
- case class ExistentialTypeTree(tpt: Tree, whereClauses: List[Tree])
+ case class ExistentialTypeTree(tpt: Tree, whereClauses: List[MemberDef])
extends TypTree with ExistentialTypeTreeApi
object ExistentialTypeTree extends ExistentialTypeTreeExtractor
@@ -694,7 +694,7 @@ trait Trees extends api.Trees {
new AppliedTypeTree(tpt, args).copyAttrs(tree)
def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) =
new TypeBoundsTree(lo, hi).copyAttrs(tree)
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) =
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[MemberDef]) =
new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree)
}
@@ -910,7 +910,7 @@ trait Trees extends api.Trees {
if (lo0 == lo) && (hi0 == hi) => t
case _ => treeCopy.TypeBoundsTree(tree, lo, hi)
}
- def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match {
+ def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[MemberDef]) = tree match {
case t @ ExistentialTypeTree(tpt0, whereClauses0)
if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t
case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses)
@@ -1421,7 +1421,7 @@ trait Trees extends api.Trees {
case CompoundTypeTree(templ) =>
treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
case ExistentialTypeTree(tpt, whereClauses) =>
- treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
+ treeCopy.ExistentialTypeTree(tree, transform(tpt), transformMemberDefs(whereClauses))
case Return(expr) =>
treeCopy.Return(tree, transform(expr))
case Alternative(trees) =>
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index a6c34935ad..3d222fce10 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -487,6 +487,7 @@ abstract class UnPickler {
def nameRef() = readNameRef()
def tparamRef() = readTypeDefRef()
def vparamRef() = readValDefRef()
+ def memberRef() = readMemberDefRef()
def constRef() = readConstantRef()
def idRef() = readIdentRef()
def termNameRef() = readNameRef().toTermName
@@ -520,7 +521,7 @@ abstract class UnPickler {
case CLASStree => ClassDef(modsRef, typeNameRef, rep(tparamRef), implRef)
case COMPOUNDTYPEtree => CompoundTypeTree(implRef)
case DEFDEFtree => DefDef(modsRef, termNameRef, rep(tparamRef), rep(rep(vparamRef)), ref, ref)
- case EXISTENTIALTYPEtree => ExistentialTypeTree(ref, all(ref))
+ case EXISTENTIALTYPEtree => ExistentialTypeTree(ref, all(memberRef))
case FUNCTIONtree => Function(rep(vparamRef), ref)
case IMPORTtree => Import(ref, selectorsRef)
case LABELtree => LabelDef(termNameRef, rep(idRef), ref)
@@ -634,6 +635,12 @@ abstract class UnPickler {
case other =>
errorBadSignature("expected an TypeDef (" + other + ")")
}
+ protected def readMemberDefRef(): MemberDef =
+ readTreeRef() match {
+ case tree:MemberDef => tree
+ case other =>
+ errorBadSignature("expected an MemberDef (" + other + ")")
+ }
protected def errorBadSignature(msg: String) =
throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
diff --git a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala
index c5cac3ea45..fe90d7222f 100644
--- a/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala
+++ b/test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala
@@ -92,7 +92,7 @@ trait ArbitraryTreesAndNames {
yield DefDef(mods, name, tparams, vparamss, tpt, rhs)
def genExistentialTypeTree(size: Int) =
- for(tpt <- genTree(size - 1); where <- smallList(size, genTree(size - 1)))
+ for(tpt <- genTree(size - 1); where <- smallList(size, oneOf(genValDef(size - 1), genTypeDef(size - 1))))
yield ExistentialTypeTree(tpt, where)
def genFunction(size: Int) =