diff options
author | Denys Shabalin <denys.shabalin@typesafe.com> | 2014-02-25 12:36:27 +0100 |
---|---|---|
committer | Denys Shabalin <denys.shabalin@typesafe.com> | 2014-03-09 15:47:21 +0200 |
commit | 67d175f06db62e8af18851fc5694cfff2158d73b (patch) | |
tree | be0ddf941355a07ee0a92cfb687260149a5c2c30 /src | |
parent | 973f2255481c0ee3c9954d361ef3941186495c8f (diff) | |
download | scala-67d175f06db62e8af18851fc5694cfff2158d73b.tar.gz scala-67d175f06db62e8af18851fc5694cfff2158d73b.tar.bz2 scala-67d175f06db62e8af18851fc5694cfff2158d73b.zip |
SI-8331 make sure type select & applied type doesn't match terms
Due to tree re-use it used to be the fact that type quasiquotes could
match term trees. This commit makes sure selections and applied type and
type applied are all non-overlapping between q and tq.
Diffstat (limited to 'src')
4 files changed, 63 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index 5eae3b6e6f..ebb59f98fd 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -185,6 +185,8 @@ trait Reifiers { self: Quasiquotes => reifyBuildCall(nme.SyntacticApplied, fun, argss) case SyntacticTypeApplied(fun, targs) if targs.nonEmpty => reifyBuildCall(nme.SyntacticTypeApplied, fun, targs) + case SyntacticAppliedType(tpt, targs) if targs.nonEmpty => + reifyBuildCall(nme.SyntacticAppliedType, tpt, targs) case SyntacticFunction(args, body) => reifyBuildCall(nme.SyntacticFunction, args, body) case SyntacticIdent(name, isBackquoted) => @@ -215,6 +217,11 @@ trait Reifiers { self: Quasiquotes => // correctness of the trees produced by quasiquotes case Select(id @ Ident(nme.scala_), name) if id.symbol == ScalaPackage => reifyBuildCall(nme.ScalaDot, name) + case Select(qual, name) => + if (name.isTypeName) + reifyBuildCall(nme.SyntacticSelectType, qual, name) + else + reifyBuildCall(nme.SyntacticSelectTerm, qual, name) case _ => super.reifyTreeSyntactically(tree) } diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala index 01f928ed61..d2e742726d 100644 --- a/src/reflect/scala/reflect/api/Internals.scala +++ b/src/reflect/scala/reflect/api/Internals.scala @@ -600,10 +600,11 @@ trait Internals { self: Universe => } val SyntacticTypeApplied: SyntacticTypeAppliedExtractor + val SyntacticAppliedType: SyntacticTypeAppliedExtractor trait SyntacticTypeAppliedExtractor { def apply(tree: Tree, targs: List[Tree]): Tree - def unapply(tree: Tree): Some[(Tree, List[Tree])] + def unapply(tree: Tree): Option[(Tree, List[Tree])] } val SyntacticApplied: SyntacticAppliedExtractor @@ -784,6 +785,18 @@ trait Internals { self: Universe => def apply(expr: Tree, selectors: List[Tree]): Import def unapply(imp: Import): Some[(Tree, List[Tree])] } + + val SyntacticSelectType: SyntacticSelectTypeExtractor + trait SyntacticSelectTypeExtractor { + def apply(qual: Tree, name: TypeName): Select + def unapply(tree: Tree): Option[(Tree, TypeName)] + } + + val SyntacticSelectTerm: SyntacticSelectTermExtractor + trait SyntacticSelectTermExtractor { + def apply(qual: Tree, name: TermName): Select + def unapply(tree: Tree): Option[(Tree, TermName)] + } } @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 66ac4bc751..9a47bab37c 100644 --- a/src/reflect/scala/reflect/internal/ReificationSupport.scala +++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala @@ -101,7 +101,7 @@ trait ReificationSupport { self: SymbolTable => } def mkAnnotation(tree: Tree): Tree = tree match { - case SyntacticNew(Nil, SyntacticApplied(SyntacticTypeApplied(_, _), _) :: Nil, noSelfType, Nil) => + case SyntacticNew(Nil, SyntacticApplied(SyntacticAppliedType(_, _), _) :: Nil, noSelfType, Nil) => tree case _ => throw new IllegalArgumentException(s"Tree ${showRaw(tree)} isn't a correct representation of annotation." + @@ -205,13 +205,25 @@ trait ReificationSupport { self: SymbolTable => def apply(tree: Tree, targs: List[Tree]): Tree = if (targs.isEmpty) tree else if (tree.isTerm) TypeApply(tree, targs) - else if (tree.isType) AppliedTypeTree(tree, targs) - else throw new IllegalArgumentException(s"can't apply types to $tree") + else throw new IllegalArgumentException(s"can't apply type arguments to $tree") - def unapply(tree: Tree): Some[(Tree, List[Tree])] = tree match { + def unapply(tree: Tree): Option[(Tree, List[Tree])] = tree match { case TypeApply(fun, targs) => Some((fun, targs)) + case _ if tree.isTerm => Some((tree, Nil)) + case _ => None + } + } + + object SyntacticAppliedType extends SyntacticTypeAppliedExtractor { + def apply(tree: Tree, targs: List[Tree]): Tree = + if (targs.isEmpty) tree + else if (tree.isType) AppliedTypeTree(tree, targs) + 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 _ => Some((tree, Nil)) + case _ if tree.isType => Some((tree, Nil)) + case _ => None } } @@ -223,7 +235,10 @@ trait ReificationSupport { self: SymbolTable => case UnApply(treeInfo.Unapplied(Select(fun, nme.unapply)), pats) => Some((fun, pats :: Nil)) case treeInfo.Applied(fun, targs, argss) => - Some((SyntacticTypeApplied(fun, targs), argss)) + if (fun.isTerm) + Some((SyntacticTypeApplied(fun, targs), argss)) + else + Some((SyntacticAppliedType(fun, targs), argss)) } } @@ -489,8 +504,8 @@ trait ReificationSupport { self: SymbolTable => gen.mkNew(parents, mkSelfType(selfType), earlyDefs ::: body, NoPosition, NoPosition) def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match { - case SyntacticApplied(Select(New(SyntacticTypeApplied(ident, targs)), nme.CONSTRUCTOR), argss) => - Some((Nil, SyntacticApplied(SyntacticTypeApplied(ident, targs), argss) :: Nil, noSelfType, Nil)) + case SyntacticApplied(Select(New(SyntacticAppliedType(ident, targs)), nme.CONSTRUCTOR), argss) => + Some((Nil, SyntacticApplied(SyntacticAppliedType(ident, targs), argss) :: Nil, noSelfType, Nil)) case SyntacticBlock(SyntacticClassDef(_, tpnme.ANON_CLASS_NAME, Nil, _, ListOfNil, earlyDefs, parents, selfType, body) :: Apply(Select(New(Ident(tpnme.ANON_CLASS_NAME)), nme.CONSTRUCTOR), Nil) :: Nil) => Some((earlyDefs, parents, selfType, body)) @@ -987,6 +1002,22 @@ trait ReificationSupport { self: SymbolTable => Some((imp.expr, selectors)) } } + + 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 + } + } + + object SyntacticSelectTerm extends SyntacticSelectTermExtractor { + def apply(qual: Tree, name: TermName): Select = Select(qual, name) + def unapply(tree: Tree): Option[(Tree, TermName)] = tree match { + case Select(qual, name: TermName) => Some((qual, name)) + 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 339923a061..640e0606c7 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -613,6 +613,7 @@ trait StdNames { 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" @@ -630,6 +631,8 @@ trait StdNames { val SyntacticObjectDef: NameType = "SyntacticObjectDef" val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef" val SyntacticPatDef: NameType = "SyntacticPatDef" + val SyntacticSelectType: NameType = "SyntacticSelectType" + val SyntacticSelectTerm: NameType = "SyntacticSelectTerm" val SyntacticTraitDef: NameType = "SyntacticTraitDef" val SyntacticTry: NameType = "SyntacticTry" val SyntacticTuple: NameType = "SyntacticTuple" |