summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-backward.whitelist.conf37
-rw-r--r--bincompat-forward.whitelist.conf62
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala16
-rw-r--r--src/reflect/scala/reflect/api/Internals.scala44
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala84
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala80
-rw-r--r--test/files/scalacheck/quasiquotes/TypecheckedProps.scala96
7 files changed, 349 insertions, 70 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index b799b17c21..703c5add42 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -144,6 +144,43 @@ filter {
{
matchName="scala.reflect.api.Mirror.weakTypeOf"
problemName=MissingMethodProblem
+ },
+ // see SI-8388
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticIdentExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSingletonType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTermIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTypeIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticCompoundType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticAnnotatedType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTypeProjection"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticExistentialType"
+ problemName=MissingMethodProblem
}
]
}
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 58bf98a173..5e869e3215 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -149,6 +149,7 @@ filter {
matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticPartialFunction"
problemName=MissingMethodProblem
},
+ // see SI-8428
{
matchName="scala.collection.Iterator#ConcatIterator.this"
problemName=MissingMethodProblem
@@ -164,6 +165,67 @@ filter {
{
matchName="scala.reflect.api.Mirror.weakTypeOf"
problemName=MissingMethodProblem
+ },
+ // see SI-8388
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticSingletonType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTermIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTypeIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticCompoundType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticAnnotatedType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticTypeProjection"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticExistentialType"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticIdent"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticAnnotatedTypeExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticTermIdentExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacitcSingletonTypeExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticTypeIdentExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticCompoundTypeExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticExistentialTypeExtractor"
+ problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticTypeProjectionExtractor"
+ problemName=MissingClassProblem
}
]
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 1b8b0686e8..95113d5b00 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -193,8 +193,6 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticAppliedType, tpt, targs)
case SyntacticFunction(args, body) =>
reifyBuildCall(nme.SyntacticFunction, args, body)
- case SyntacticIdent(name, isBackquoted) =>
- reifyBuildCall(nme.SyntacticIdent, name, isBackquoted)
case SyntacticEmptyTypeTree() =>
reifyBuildCall(nme.SyntacticEmptyTypeTree)
case SyntacticImport(expr, selectors) =>
@@ -203,6 +201,20 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticPartialFunction, cases)
case SyntacticMatch(scrutinee, cases) =>
reifyBuildCall(nme.SyntacticMatch, scrutinee, cases)
+ case SyntacticTermIdent(name, isBackquoted) =>
+ reifyBuildCall(nme.SyntacticTermIdent, name, isBackquoted)
+ case SyntacticTypeIdent(name) =>
+ reifyBuildCall(nme.SyntacticTypeIdent, name)
+ case SyntacticCompoundType(parents, defns) =>
+ reifyBuildCall(nme.SyntacticCompoundType, parents, defns)
+ case SyntacticSingletonType(ref) =>
+ reifyBuildCall(nme.SyntacticSingletonType, ref)
+ case SyntacticTypeProjection(qual, name) =>
+ reifyBuildCall(nme.SyntacticTypeProjection, qual, name)
+ case SyntacticAnnotatedType(tpt, annot) =>
+ reifyBuildCall(nme.SyntacticAnnotatedType, tpt, annot)
+ case SyntacticExistentialType(tpt, where) =>
+ reifyBuildCall(nme.SyntacticExistentialType, tpt, where)
case Q(tree) if fillListHole.isDefinedAt(tree) =>
mirrorBuildCall(nme.SyntacticBlock, fillListHole(tree))
case Q(other) =>
diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala
index 7788dba63e..577cd09295 100644
--- a/src/reflect/scala/reflect/api/Internals.scala
+++ b/src/reflect/scala/reflect/api/Internals.scala
@@ -780,10 +780,16 @@ trait Internals { self: Universe =>
def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)]
}
- val SyntacticIdent: SyntacticIdentExtractor
- trait SyntacticIdentExtractor {
- def apply(name: Name, isBackquoted: Boolean = false): Ident
- def unapply(tree: Ident): Option[(Name, Boolean)]
+ val SyntacticTermIdent: SyntacticTermIdentExtractor
+ trait SyntacticTermIdentExtractor {
+ def apply(name: TermName, isBackquoted: Boolean = false): Ident
+ def unapply(id: Ident): Option[(TermName, Boolean)]
+ }
+
+ val SyntacticTypeIdent: SyntacticTypeIdentExtractor
+ trait SyntacticTypeIdentExtractor {
+ def apply(name: TypeName): Ident
+ def unapply(tree: Tree): Option[TypeName]
}
val SyntacticImport: SyntacticImportExtractor
@@ -803,6 +809,36 @@ trait Internals { self: Universe =>
def apply(qual: Tree, name: TermName): Select
def unapply(tree: Tree): Option[(Tree, TermName)]
}
+
+ val SyntacticCompoundType: SyntacticCompoundTypeExtractor
+ trait SyntacticCompoundTypeExtractor {
+ def apply(parents: List[Tree], defns: List[Tree]): CompoundTypeTree
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree])]
+ }
+
+ val SyntacticSingletonType: SyntacitcSingletonTypeExtractor
+ trait SyntacitcSingletonTypeExtractor {
+ def apply(tree: Tree): SingletonTypeTree
+ def unapply(tree: Tree): Option[Tree]
+ }
+
+ val SyntacticTypeProjection: SyntacticTypeProjectionExtractor
+ trait SyntacticTypeProjectionExtractor {
+ def apply(qual: Tree, name: TypeName): SelectFromTypeTree
+ def unapply(tree: Tree): Option[(Tree, TypeName)]
+ }
+
+ val SyntacticAnnotatedType: SyntacticAnnotatedTypeExtractor
+ trait SyntacticAnnotatedTypeExtractor {
+ def apply(tpt: Tree, annot: Tree): Annotated
+ def unapply(tree: Tree): Option[(Tree, Tree)]
+ }
+
+ val SyntacticExistentialType: SyntacticExistentialTypeExtractor
+ trait SyntacticExistentialTypeExtractor {
+ def apply(tpt: Tree, where: List[Tree]): ExistentialTypeTree
+ def unapply(tree: Tree): Option[(Tree, List[MemberDef])]
+ }
}
@deprecated("Use `internal.reificationSupport` instead", "2.11.0")
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index f9f93fbff0..035fa7177c 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -227,9 +227,9 @@ trait ReificationSupport { self: SymbolTable =>
else throw new IllegalArgumentException(s"can't create applied type from non-type $tree")
def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match {
- case AppliedTypeTree(tpe, targs) => Some((tpe, targs))
- case _ if tree.isType => Some((tree, Nil))
- case _ => None
+ case MaybeTypeTreeOriginal(AppliedTypeTree(tpe, targs)) => Some((tpe, targs))
+ case _ if tree.isType => Some((tree, Nil))
+ case _ => None
}
}
@@ -891,13 +891,24 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] = Try.unapply(tree)
}
- object SyntacticIdent extends SyntacticIdentExtractor {
- def apply(name: Name, isBackquoted: Boolean) = {
+ object SyntacticTermIdent extends SyntacticTermIdentExtractor {
+ def apply(name: TermName, isBackquoted: Boolean): Ident = {
val id = self.Ident(name)
if (isBackquoted) id updateAttachment BackquotedIdentifierAttachment
id
}
- def unapply(tree: Ident): Some[(Name, Boolean)] = Some((tree.name, tree.hasAttachment[BackquotedIdentifierAttachment.type]))
+ def unapply(id: Ident): Option[(TermName, Boolean)] = id.name match {
+ case name: TermName => Some((name, id.hasAttachment[BackquotedIdentifierAttachment.type]))
+ case _ => None
+ }
+ }
+
+ object SyntacticTypeIdent extends SyntacticTypeIdentExtractor {
+ def apply(name: TypeName): Ident = self.Ident(name)
+ def unapply(tree: Tree): Option[TypeName] = tree match {
+ case MaybeTypeTreeOriginal(Ident(name: TypeName)) => Some(name)
+ case _ => None
+ }
}
/** Facade over Imports and ImportSelectors that lets to structurally
@@ -1043,8 +1054,8 @@ trait ReificationSupport { self: SymbolTable =>
object SyntacticSelectType extends SyntacticSelectTypeExtractor {
def apply(qual: Tree, name: TypeName): Select = Select(qual, name)
def unapply(tree: Tree): Option[(Tree, TypeName)] = tree match {
- case Select(qual, name: TypeName) => Some((qual, name))
- case _ => None
+ case MaybeTypeTreeOriginal(Select(qual, name: TypeName)) => Some((qual, name))
+ case _ => None
}
}
@@ -1055,6 +1066,63 @@ trait ReificationSupport { self: SymbolTable =>
case _ => None
}
}
+
+ object SyntacticCompoundType extends SyntacticCompoundTypeExtractor {
+ def apply(parents: List[Tree], defns: List[Tree]) =
+ CompoundTypeTree(Template(gen.mkParents(NoMods, parents), noSelfType, defns))
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree])] = tree match {
+ case MaybeTypeTreeOriginal(CompoundTypeTree(Template(parents, _, defns))) =>
+ Some((parents, defns))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticSingletonType extends SyntacitcSingletonTypeExtractor {
+ def apply(ref: Tree): SingletonTypeTree = SingletonTypeTree(ref)
+ def unapply(tree: Tree): Option[Tree] = tree match {
+ case MaybeTypeTreeOriginal(SingletonTypeTree(ref)) =>
+ Some(ref)
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticTypeProjection extends SyntacticTypeProjectionExtractor {
+ def apply(qual: Tree, name: TypeName): SelectFromTypeTree =
+ SelectFromTypeTree(qual, name)
+ def unapply(tree: Tree): Option[(Tree, TypeName)] = tree match {
+ case MaybeTypeTreeOriginal(SelectFromTypeTree(qual, name)) =>
+ Some((qual, name))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticAnnotatedType extends SyntacticAnnotatedTypeExtractor {
+ def apply(tpt: Tree, annot: Tree): Annotated =
+ Annotated(annot, tpt)
+ def unapply(tree: Tree): Option[(Tree, Tree)] = tree match {
+ case MaybeTypeTreeOriginal(Annotated(annot, tpt)) =>
+ Some((tpt, annot))
+ case _ =>
+ None
+ }
+ }
+
+ object SyntacticExistentialType extends SyntacticExistentialTypeExtractor {
+ def apply(tpt: Tree, where: List[Tree]): ExistentialTypeTree =
+ ExistentialTypeTree(tpt, where.map {
+ case md: MemberDef => md
+ case tree => throw new IllegalArgumentException("$tree is not legal forSome definition")
+ })
+ def unapply(tree: Tree): Option[(Tree, List[MemberDef])] = tree match {
+ case MaybeTypeTreeOriginal(ExistentialTypeTree(tpt, where)) =>
+ Some((tpt, where))
+ case _ =>
+ None
+ }
+ }
}
val build = new ReificationSupportImpl
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 10959ff41f..6848c357c5 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -612,37 +612,6 @@ trait StdNames {
val SelectFromTypeTree: NameType = "SelectFromTypeTree"
val SingleType: NameType = "SingleType"
val SuperType: NameType = "SuperType"
- val SyntacticApplied: NameType = "SyntacticApplied"
- val SyntacticAppliedType: NameType = "SyntacticAppliedType"
- val SyntacticAssign: NameType = "SyntacticAssign"
- val SyntacticBlock: NameType = "SyntacticBlock"
- val SyntacticClassDef: NameType = "SyntacticClassDef"
- val SyntacticDefDef: NameType = "SyntacticDefDef"
- val SyntacticEmptyTypeTree: NameType = "SyntacticEmptyTypeTree"
- val SyntacticFilter: NameType = "SyntacticFilter"
- val SyntacticFor: NameType = "SyntacticFor"
- val SyntacticForYield: NameType = "SyntacticForYield"
- val SyntacticFunction: NameType = "SyntacticFunction"
- val SyntacticFunctionType: NameType = "SyntacticFunctionType"
- val SyntacticIdent: NameType = "SyntacticIdent"
- val SyntacticImport: NameType = "SyntacticImport"
- val SyntacticMatch: NameType = "SyntacticMatch"
- val SyntacticNew: NameType = "SyntacticNew"
- val SyntacticObjectDef: NameType = "SyntacticObjectDef"
- val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
- val SyntacticPartialFunction: NameType = "SyntacticPartialFunction"
- val SyntacticPatDef: NameType = "SyntacticPatDef"
- val SyntacticSelectType: NameType = "SyntacticSelectType"
- val SyntacticSelectTerm: NameType = "SyntacticSelectTerm"
- val SyntacticTraitDef: NameType = "SyntacticTraitDef"
- val SyntacticTry: NameType = "SyntacticTry"
- val SyntacticTuple: NameType = "SyntacticTuple"
- val SyntacticTupleType: NameType = "SyntacticTupleType"
- val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
- val SyntacticValDef: NameType = "SyntacticValDef"
- val SyntacticValEq: NameType = "SyntacticValEq"
- val SyntacticValFrom: NameType = "SyntacticValFrom"
- val SyntacticVarDef: NameType = "SyntacticVarDef"
val This: NameType = "This"
val ThisType: NameType = "ThisType"
val Tuple2: NameType = "Tuple2"
@@ -810,11 +779,50 @@ trait StdNames {
val zero: NameType = "zero"
// quasiquote interpolators:
- val q: NameType = "q"
- val tq: NameType = "tq"
- val cq: NameType = "cq"
- val pq: NameType = "pq"
- val fq: NameType = "fq"
+ val q: NameType = "q"
+ val tq: NameType = "tq"
+ val cq: NameType = "cq"
+ val pq: NameType = "pq"
+ val fq: NameType = "fq"
+
+ // quasiquote's syntactic combinators
+ val SyntacticAnnotatedType: NameType = "SyntacticAnnotatedType"
+ val SyntacticApplied: NameType = "SyntacticApplied"
+ val SyntacticAppliedType: NameType = "SyntacticAppliedType"
+ val SyntacticAssign: NameType = "SyntacticAssign"
+ val SyntacticBlock: NameType = "SyntacticBlock"
+ val SyntacticClassDef: NameType = "SyntacticClassDef"
+ val SyntacticCompoundType: NameType = "SyntacticCompoundType"
+ val SyntacticDefDef: NameType = "SyntacticDefDef"
+ val SyntacticEmptyTypeTree: NameType = "SyntacticEmptyTypeTree"
+ val SyntacticExistentialType: NameType = "SyntacticExistentialType"
+ val SyntacticFilter: NameType = "SyntacticFilter"
+ val SyntacticFor: NameType = "SyntacticFor"
+ val SyntacticForYield: NameType = "SyntacticForYield"
+ val SyntacticFunction: NameType = "SyntacticFunction"
+ val SyntacticFunctionType: NameType = "SyntacticFunctionType"
+ val SyntacticImport: NameType = "SyntacticImport"
+ val SyntacticMatch: NameType = "SyntacticMatch"
+ val SyntacticNew: NameType = "SyntacticNew"
+ val SyntacticObjectDef: NameType = "SyntacticObjectDef"
+ val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
+ val SyntacticPartialFunction: NameType = "SyntacticPartialFunction"
+ val SyntacticPatDef: NameType = "SyntacticPatDef"
+ val SyntacticSelectTerm: NameType = "SyntacticSelectTerm"
+ val SyntacticSelectType: NameType = "SyntacticSelectType"
+ val SyntacticSingletonType: NameType = "SyntacticSingletonType"
+ val SyntacticTermIdent: NameType = "SyntacticTermIdent"
+ val SyntacticTraitDef: NameType = "SyntacticTraitDef"
+ val SyntacticTry: NameType = "SyntacticTry"
+ val SyntacticTuple: NameType = "SyntacticTuple"
+ val SyntacticTupleType: NameType = "SyntacticTupleType"
+ val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
+ val SyntacticTypeIdent: NameType = "SyntacticTypeIdent"
+ val SyntacticTypeProjection: NameType = "SyntacticTypeProjection"
+ val SyntacticValDef: NameType = "SyntacticValDef"
+ val SyntacticValEq: NameType = "SyntacticValEq"
+ val SyntacticValFrom: NameType = "SyntacticValFrom"
+ val SyntacticVarDef: NameType = "SyntacticVarDef"
// unencoded operators
object raw {
diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
index fb2eb69321..a5d526191f 100644
--- a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
+++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala
@@ -2,32 +2,13 @@ import org.scalacheck._, Prop._, Gen._, Arbitrary._
import scala.reflect.runtime.universe._, Flag._, internal.reificationSupport._
object TypecheckedProps extends QuasiquoteProperties("typechecked") {
- def original(tree: Tree) = tree match {
- case tt: TypeTree => Some(tt.original)
- case _ => None
- }
- def originals(trees: List[Tree]) = trees.flatMap(original)
- val int = ScalaDot(TypeName("Int"))
- val intint = List(int, int)
+
property("tuple term") = test {
val q"(..$elements)" = typecheck(q"(1, 2)")
assert(elements ≈ List(q"1", q"2"))
}
- property("tuple type") = test {
- val tq"(..$els0)" = typecheckTyp(tq"Unit")
- assert(els0.isEmpty)
- val tq"(..$els1)" = typecheckTyp(tq"(Int, Int)")
- assert(originals(els1) ≈ intint)
- }
-
- property("function type") = test {
- val tq"(..$argtpes) => $restpe" = typecheckTyp(tq"(Int, Int) => Int")
- assert(originals(argtpes) ≈ intint)
- assert(original(restpe).get ≈ int)
- }
-
property("for/for-yield") = test {
val enums = fq"x <- xs" :: fq"x1 = x + 1" :: fq"if x1 % 2 == 0" :: Nil
val body = q"x1"
@@ -158,3 +139,78 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") {
assert(cases ≈ q"{ case 1 => () }".cases)
}
}
+
+trait TypecheckedTypes { self: QuasiquoteProperties =>
+ property("type ident") = test {
+ val q"$_; type $_ = $tpt" = typecheck(q"class C; type T = C")
+ val tq"C" = tpt
+ }
+
+ property("type select") = test {
+ val tq"scala.Int" = typecheckTyp(tq"Int")
+ }
+
+ property("this type select") = test {
+ val q"class $_ { $_; type $_ = $tpt }" = typecheck(q"class C { type A = Int; type B = this.A }")
+ val tq"this.$name" = tpt
+ val TypeName("A") = name
+ }
+
+ property("super type select") = test {
+ val q"$_; class $_ extends $_ { type $_ = $tpt }" =
+ typecheck(q"class C1 { type A = Int }; class C2 extends C1 { type B = super[C1].A }")
+ val tq"$empty.super[$c1].$a" = tpt
+ val TypeName("") = empty
+ val TypeName("C1") = c1
+ val TypeName("A") = a
+ }
+
+ property("applied type") = test {
+ val tt = typecheckTyp(q"Map[Int, Int]")
+ val tq"$tpt[..$tpts]" = tt
+ val tq"scala.this.Predef.Map" = tpt
+ val List(tq"scala.Int", tq"scala.Int") = tpts
+ }
+
+ property("tuple type") = test {
+ val tq"(..$els0)" = typecheckTyp(tq"Unit")
+ assert(els0.isEmpty)
+ val tq"(..$els1)" = typecheckTyp(tq"(Int, Int)")
+ val List(tq"scala.Int", tq"scala.Int") = els1
+ }
+
+ property("function type") = test {
+ val tq"(..$argtpes) => $restpe" = typecheckTyp(tq"(Int, Int) => Int")
+ val List(tq"scala.Int", tq"scala.Int") = argtpes
+ val tq"scala.Int" = restpe
+ }
+
+ property("compound type") = test {
+ val tq"..$parents { ..$defns }" = typecheckTyp(tq"Int { def x: Int }")
+ val List(tq"Int") = parents
+ val List(q"def x: Int") = defns
+ }
+
+ property("singleton type") = test {
+ val tq"$ref.type" = typecheckTyp(tq"scala.Predef.type")
+ val q"scala.Predef" = ref
+ }
+
+ property("type projection") = test {
+ val tq"$tpt#$name" = typecheckTyp(tq"({ type T = Int })#T")
+ val TypeName("T") = name
+ val tq"{ type T = Int }" = tpt
+ }
+
+ property("annotated type") = test {
+ val tq"$tpt @$annot" = typecheckTyp(tq"Int @unchecked")
+ val tq"scala.Int" = tpt
+ val q"new unchecked" = annot
+ }
+
+ property("existential type") = test {
+ val tq"$tpt forSome { ..$defns }" = typecheckTyp(tq"T forSome { type T }")
+ val tq"T" = tpt
+ val q"type T" :: Nil = defns
+ }
+}