diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-10 11:03:04 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-10 11:03:04 -0700 |
commit | 51a413e3327d9050f07377933eb1ca243d52c4ab (patch) | |
tree | 433351fea6467957114c8dd9143c6796c2f8b6a8 /src | |
parent | 1c7daf40bfe529969aa423ae0d2fd454adb20acb (diff) | |
parent | 1b5a34b402cb283db6029a1d54778390ba14ef6f (diff) | |
download | scala-51a413e3327d9050f07377933eb1ca243d52c4ab.tar.gz scala-51a413e3327d9050f07377933eb1ca243d52c4ab.tar.bz2 scala-51a413e3327d9050f07377933eb1ca243d52c4ab.zip |
Merge pull request #3594 from densh/si/8331
SI-8331 make sure type select & applied type doesn't match terms
Diffstat (limited to 'src')
4 files changed, 67 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..c37d5a3273 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,9 @@ 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) => + val ctor = if (name.isTypeName) nme.SyntacticSelectType else nme.SyntacticSelectTerm + reifyBuildCall(ctor, 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..dfe1811ff0 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." + @@ -201,17 +201,35 @@ trait ReificationSupport { self: SymbolTable => def unapply(flags: Long): Some[Long] = Some(flags) } + /** Construct/deconstruct type application term trees. + * Treats other term trees as zero-argument type applications. + */ object SyntacticTypeApplied extends SyntacticTypeAppliedExtractor { 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 + } + } + + /** Construct/deconstruct applied type trees. + * Treats other types as zero-arity applied types. + */ + 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 +241,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)) + val callee = + if (fun.isTerm) SyntacticTypeApplied(fun, targs) + else SyntacticAppliedType(fun, targs) + Some((callee, argss)) } } @@ -489,8 +510,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 +1008,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" |