diff options
author | Denys Shabalin <denys.shabalin@typesafe.com> | 2014-02-06 19:51:43 +0100 |
---|---|---|
committer | Denys Shabalin <denys.shabalin@typesafe.com> | 2014-02-07 12:47:45 +0100 |
commit | 1e5654c8bd10a3649ccc97c42a7949b179480073 (patch) | |
tree | 62bb8d1c833099d858209affc49b152eaf5e2a58 /src | |
parent | d60b8323dda884653f31410806c269d15140e5e6 (diff) | |
download | scala-1e5654c8bd10a3649ccc97c42a7949b179480073.tar.gz scala-1e5654c8bd10a3649ccc97c42a7949b179480073.tar.bz2 scala-1e5654c8bd10a3649ccc97c42a7949b179480073.zip |
Represent tq"" as SyntacticEmptyTypeTree rather than TypeTree()
Such representation codifies the fact that type tree that doesn't have
embedded syntactic equivalent must have been inferred or otherwise
provided by the compiler rather than specified by the end user.
Additionally it also ensures that we can still match trees without
explicit types (e.g. vals without type) after typechecking. Otherwise
the same quote couldn't be used in situations like:
val q"val x = 42" = typecheck(q"val x = 42")
Diffstat (limited to 'src')
4 files changed, 15 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index 0c73214745..2eb50d5993 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -190,6 +190,8 @@ trait Reifiers { self: Quasiquotes => reifyBuildCall(nme.SyntacticFunction, args, body) case SyntacticIdent(name, isBackquoted) => reifyBuildCall(nme.SyntacticIdent, name, isBackquoted) + case SyntacticEmptyTypeTree() => + reifyBuildCall(nme.SyntacticEmptyTypeTree) case Q(Placeholder(Hole(tree, DotDot))) => mirrorBuildCall(nme.SyntacticBlock, tree) case Q(other) => diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala index 3bcf751ace..7aaa3973b3 100644 --- a/src/reflect/scala/reflect/api/BuildUtils.scala +++ b/src/reflect/scala/reflect/api/BuildUtils.scala @@ -248,6 +248,13 @@ private[reflect] trait BuildUtils { self: Universe => def unapply(tree: Tree): Option[(Tree)] } + val SyntacticEmptyTypeTree: SyntacticEmptyTypeTreeExtractor + + trait SyntacticEmptyTypeTreeExtractor { + def apply(): TypeTree + def unapply(tt: TypeTree): Boolean + } + val SyntacticFor: SyntacticForExtractor val SyntacticForYield: SyntacticForExtractor diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index b586297fcb..4f4d7df793 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -537,8 +537,11 @@ trait BuildUtils { self: SymbolTable => def unapply(tree: Tree): Option[Tree] = gen.Filter.unapply(tree) } - // a type tree which wasn't specified by the user but might have been inferred by compiler - object SyntacticEmptyTypeTree { + // TypeTree without original is used to signal that no type was provided + // by the user and compiler should infer it instead. (Note: EmptyTree is + // not appropriate in such role, it's only used for terms, not types.) + object SyntacticEmptyTypeTree extends SyntacticEmptyTypeTreeExtractor { + def apply(): TypeTree = self.TypeTree() def unapply(tt: TypeTree): Boolean = tt.original == null || tt.original.isEmpty } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 53475be479..7c979e7bdc 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -602,6 +602,7 @@ trait StdNames { 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" |