@@ -766,7 +766,58 @@ self =>
766
766
@ inline final def caseSeparated [T ](part : => T ): List [T ] = tokenSeparated(CASE , sepFirst = true , part)
767
767
def readAnnots (part : => Tree ): List [Tree ] = tokenSeparated(AT , sepFirst = true , part)
768
768
769
- /* --------- OPERAND/OPERATOR STACK --------------------------------------- */
769
+ /** Create a tuple type Tree. If the arity is not supported, a syntax error is emitted. */
770
+ def makeSafeTupleType (elems : List [Tree ], offset : Offset ) = {
771
+ if (checkTupleSize(elems, offset)) makeTupleType(elems)
772
+ else makeTupleType(Nil ) // create a dummy node; makeTupleType(elems) would fail
773
+ }
774
+
775
+ /** Create a tuple term Tree. If the arity is not supported, a syntax error is emitted. */
776
+ def makeSafeTupleTerm (elems : List [Tree ], offset : Offset ) = {
777
+ checkTupleSize(elems, offset)
778
+ makeTupleTerm(elems)
779
+ }
780
+
781
+ private [this ] def checkTupleSize (elems : List [Tree ], offset : Offset ): Boolean =
782
+ if (elems.lengthCompare(definitions.MaxTupleArity ) > 0 ) {
783
+ syntaxError(offset, " too many elements for tuple: " + elems.length+ " , allowed: " + definitions.MaxTupleArity , skipIt = false )
784
+ false
785
+ } else true
786
+
787
+ /** Strip the artifitial `Parens` node to create a tuple term Tree. */
788
+ def stripParens (t : Tree ) = t match {
789
+ case Parens (ts) => atPos(t.pos) { makeSafeTupleTerm(ts, t.pos.point) }
790
+ case _ => t
791
+ }
792
+
793
+ /** Create tree representing (unencoded) binary operation expression or pattern. */
794
+ def makeBinop (isExpr : Boolean , left : Tree , op : TermName , right : Tree , opPos : Position , targs : List [Tree ] = Nil ): Tree = {
795
+ require(isExpr || targs.isEmpty || targs.exists(_.isErroneous), s " Incompatible args to makeBinop: !isExpr but targs= $targs" )
796
+
797
+ def mkSelection (t : Tree ) = {
798
+ def sel = atPos(opPos union t.pos)(Select (stripParens(t), op.encode))
799
+ if (targs.isEmpty) sel else atPos(left.pos)(TypeApply (sel, targs))
800
+ }
801
+ def mkNamed (args : List [Tree ]) = if (isExpr) args map treeInfo.assignmentToMaybeNamedArg else args
802
+ val arguments = right match {
803
+ case Parens (args) => mkNamed(args)
804
+ case _ => List (right)
805
+ }
806
+ if (isExpr) {
807
+ if (treeInfo.isLeftAssoc(op)) {
808
+ Apply (mkSelection(left), arguments)
809
+ } else {
810
+ val x = freshTermName()
811
+ Block (
812
+ List (ValDef (Modifiers (symtab.Flags .SYNTHETIC | symtab.Flags .ARTIFACT ), x, TypeTree (), stripParens(left))),
813
+ Apply (mkSelection(right), List (Ident (x))))
814
+ }
815
+ } else {
816
+ Apply (Ident (op.encode), stripParens(left) :: arguments)
817
+ }
818
+ }
819
+
820
+ /* --------- OPERAND/OPERATOR STACK --------------------------------------- */
770
821
771
822
/** Modes for infix types. */
772
823
object InfixMode extends Enumeration {
@@ -870,7 +921,7 @@ self =>
870
921
atPos(start, in.skipToken()) { makeFunctionTypeTree(ts, typ()) }
871
922
else {
872
923
ts foreach checkNotByNameOrVarargs
873
- val tuple = atPos(start) { makeTupleType (ts) }
924
+ val tuple = atPos(start) { makeSafeTupleType (ts, start ) }
874
925
infixTypeRest(
875
926
compoundTypeRest(
876
927
annotTypeRest(
@@ -937,7 +988,7 @@ self =>
937
988
def simpleType (): Tree = {
938
989
val start = in.offset
939
990
simpleTypeRest(in.token match {
940
- case LPAREN => atPos(start)(makeTupleType (inParens(types())))
991
+ case LPAREN => atPos(start)(makeSafeTupleType (inParens(types()), start ))
941
992
case USCORE => wildcardType(in.skipToken())
942
993
case _ =>
943
994
path(thisOK = false , typeOK = true ) match {
0 commit comments