summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-02-03 22:06:42 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-02-04 09:19:19 +1000
commitda46355a90442636ee7634c31a69eae8e8b9cd42 (patch)
treeeec9abbf057e3c5fd4566df6628f9693835cc536 /src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
parent74e53cb4930fc3e02222d8be0f065ce8aaa71230 (diff)
parentcc6fea6d30609b8879db1ecdbc288e4cdaa5b8d4 (diff)
downloadscala-da46355a90442636ee7634c31a69eae8e8b9cd42.tar.gz
scala-da46355a90442636ee7634c31a69eae8e8b9cd42.tar.bz2
scala-da46355a90442636ee7634c31a69eae8e8b9cd42.zip
Merge commit 'cc6fea6' into merge/2.11.x-to-2.12.x-20160203
Conflicts: build.sbt scripts/jobs/integrate/bootstrap
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser/Parsers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala57
1 files changed, 54 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 1d96b940ae..831a0412cd 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -774,7 +774,58 @@ self =>
@inline final def caseSeparated[T](part: => T): List[T] = tokenSeparated(CASE, sepFirst = true, part)
def readAnnots(part: => Tree): List[Tree] = tokenSeparated(AT, sepFirst = true, part)
-/* --------- OPERAND/OPERATOR STACK --------------------------------------- */
+ /** Create a tuple type Tree. If the arity is not supported, a syntax error is emitted. */
+ def makeSafeTupleType(elems: List[Tree], offset: Offset) = {
+ if (checkTupleSize(elems, offset)) makeTupleType(elems)
+ else makeTupleType(Nil) // create a dummy node; makeTupleType(elems) would fail
+ }
+
+ /** Create a tuple term Tree. If the arity is not supported, a syntax error is emitted. */
+ def makeSafeTupleTerm(elems: List[Tree], offset: Offset) = {
+ checkTupleSize(elems, offset)
+ makeTupleTerm(elems)
+ }
+
+ private[this] def checkTupleSize(elems: List[Tree], offset: Offset): Boolean =
+ if (elems.lengthCompare(definitions.MaxTupleArity) > 0) {
+ syntaxError(offset, "too many elements for tuple: "+elems.length+", allowed: "+definitions.MaxTupleArity, skipIt = false)
+ false
+ } else true
+
+ /** Strip the artifitial `Parens` node to create a tuple term Tree. */
+ def stripParens(t: Tree) = t match {
+ case Parens(ts) => atPos(t.pos) { makeSafeTupleTerm(ts, t.pos.point) }
+ case _ => t
+ }
+
+ /** Create tree representing (unencoded) binary operation expression or pattern. */
+ def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position, targs: List[Tree] = Nil): Tree = {
+ require(isExpr || targs.isEmpty || targs.exists(_.isErroneous), s"Incompatible args to makeBinop: !isExpr but targs=$targs")
+
+ def mkSelection(t: Tree) = {
+ def sel = atPos(opPos union t.pos)(Select(stripParens(t), op.encode))
+ if (targs.isEmpty) sel else atPos(left.pos)(TypeApply(sel, targs))
+ }
+ def mkNamed(args: List[Tree]) = if (isExpr) args map treeInfo.assignmentToMaybeNamedArg else args
+ val arguments = right match {
+ case Parens(args) => mkNamed(args)
+ case _ => List(right)
+ }
+ if (isExpr) {
+ if (treeInfo.isLeftAssoc(op)) {
+ Apply(mkSelection(left), arguments)
+ } else {
+ val x = freshTermName()
+ Block(
+ List(ValDef(Modifiers(symtab.Flags.SYNTHETIC | symtab.Flags.ARTIFACT), x, TypeTree(), stripParens(left))),
+ Apply(mkSelection(right), List(Ident(x))))
+ }
+ } else {
+ Apply(Ident(op.encode), stripParens(left) :: arguments)
+ }
+ }
+
+ /* --------- OPERAND/OPERATOR STACK --------------------------------------- */
/** Modes for infix types. */
object InfixMode extends Enumeration {
@@ -878,7 +929,7 @@ self =>
atPos(start, in.skipToken()) { makeFunctionTypeTree(ts, typ()) }
else {
ts foreach checkNotByNameOrVarargs
- val tuple = atPos(start) { makeTupleType(ts) }
+ val tuple = atPos(start) { makeSafeTupleType(ts, start) }
infixTypeRest(
compoundTypeRest(
annotTypeRest(
@@ -945,7 +996,7 @@ self =>
def simpleType(): Tree = {
val start = in.offset
simpleTypeRest(in.token match {
- case LPAREN => atPos(start)(makeTupleType(inParens(types())))
+ case LPAREN => atPos(start)(makeSafeTupleType(inParens(types()), start))
case USCORE => wildcardType(in.skipToken())
case _ =>
path(thisOK = false, typeOK = true) match {