@@ -43,6 +43,7 @@ object Parsers {
4343 case InParens extends Location (true , false , false )
4444 case InArgs extends Location (true , false , true )
4545 case InPattern extends Location (false , true , false )
46+ case InGuard extends Location (false , false , false )
4647 case InPatternArgs extends Location (false , true , true ) // InParens not true, since it might be an alternative
4748 case InBlock extends Location (false , false , false )
4849 case ElseWhere extends Location (false , false , false )
@@ -403,22 +404,23 @@ object Parsers {
403404
404405 /** Convert tree to formal parameter list
405406 */
406- def convertToParams (tree : Tree , mods : Modifiers ): List [ValDef ] = tree match {
407- case Parens (t) =>
408- convertToParam(t, mods) :: Nil
409- case Tuple (ts) =>
410- ts.map(convertToParam(_, mods))
411- case t : Typed =>
412- report.errorOrMigrationWarning(
413- em " parentheses are required around the parameter of a lambda ${rewriteNotice()}" ,
414- in.sourcePos())
415- if migrateTo3 then
416- patch(source, t.span.startPos, " (" )
417- patch(source, t.span.endPos, " )" )
418- convertToParam(t, mods) :: Nil
419- case t =>
420- convertToParam(t, mods) :: Nil
421- }
407+ def convertToParams (tree : Tree ): List [ValDef ] =
408+ val mods = if in.token == CTXARROW then Modifiers (Given ) else EmptyModifiers
409+ tree match
410+ case Parens (t) =>
411+ convertToParam(t, mods) :: Nil
412+ case Tuple (ts) =>
413+ ts.map(convertToParam(_, mods))
414+ case t : Typed =>
415+ report.errorOrMigrationWarning(
416+ em " parentheses are required around the parameter of a lambda ${rewriteNotice()}" ,
417+ in.sourcePos())
418+ if migrateTo3 then
419+ patch(source, t.span.startPos, " (" )
420+ patch(source, t.span.endPos, " )" )
421+ convertToParam(t, mods) :: Nil
422+ case t =>
423+ convertToParam(t, mods) :: Nil
422424
423425 /** Convert tree to formal parameter
424426 */
@@ -920,7 +922,8 @@ object Parsers {
920922 * @param maybePostfix postfix operators are allowed.
921923 */
922924 def infixOps (
923- first : Tree , canStartOperand : Token => Boolean , operand : () => Tree ,
925+ first : Tree , canStartOperand : Token => Boolean , operand : Location => Tree ,
926+ location : Location ,
924927 isType : Boolean ,
925928 isOperator : => Boolean ,
926929 maybePostfix : Boolean = false ): Tree = {
@@ -941,7 +944,7 @@ object Parsers {
941944 PostfixOp (od, topInfo.operator)
942945 }
943946 }
944- else recur(operand())
947+ else recur(operand(location ))
945948 }
946949 else
947950 val t = reduceStack(base, top, minPrec, leftAssoc = true , in.name, isType)
@@ -1488,12 +1491,15 @@ object Parsers {
14881491 def infixType (): Tree = infixTypeRest(refinedType())
14891492
14901493 def infixTypeRest (t : Tree ): Tree =
1491- infixOps(t, canStartTypeTokens, refinedType, isType = true ,
1494+ infixOps(t, canStartTypeTokens, refinedTypeFn, Location .ElseWhere ,
1495+ isType = true ,
14921496 isOperator = ! followingIsVararg())
14931497
14941498 /** RefinedType ::= WithType {[nl] Refinement}
14951499 */
1496- val refinedType : () => Tree = () => refinedTypeRest(withType())
1500+ val refinedTypeFn : Location => Tree = _ => refinedType()
1501+
1502+ def refinedType () = refinedTypeRest(withType())
14971503
14981504 def refinedTypeRest (t : Tree ): Tree = {
14991505 argumentStart()
@@ -1811,7 +1817,11 @@ object Parsers {
18111817 if in.token != altToken then
18121818 if toBeContinued(altToken) then
18131819 t = inSepRegion(InCond ) {
1814- expr1Rest(postfixExprRest(simpleExprRest(t)), Location .ElseWhere )
1820+ expr1Rest(
1821+ postfixExprRest(
1822+ simpleExprRest(t, Location .ElseWhere ),
1823+ Location .ElseWhere ),
1824+ Location .ElseWhere )
18151825 }
18161826 else
18171827 if rewriteToNewSyntax(t.span) then
@@ -1882,8 +1892,7 @@ object Parsers {
18821892 val t = expr1(location)
18831893 if in.isArrow then
18841894 placeholderParams = Nil // don't interpret `_' to the left of `=>` as placeholder
1885- val paramMods = if in.token == CTXARROW then Modifiers (Given ) else EmptyModifiers
1886- wrapPlaceholders(closureRest(start, location, convertToParams(t, paramMods)))
1895+ wrapPlaceholders(closureRest(start, location, convertToParams(t)))
18871896 else if isWildcard(t) then
18881897 placeholderParams = placeholderParams ::: saved
18891898 t
@@ -2155,30 +2164,30 @@ object Parsers {
21552164 * | InfixExpr MatchClause
21562165 */
21572166 def postfixExpr (location : Location = Location .ElseWhere ): Tree =
2158- val t = postfixExprRest(prefixExpr(), location)
2167+ val t = postfixExprRest(prefixExpr(location ), location)
21592168 if location.inArgs && followingIsVararg() then
21602169 Typed (t, atSpan(in.skipToken()) { Ident (tpnme.WILDCARD_STAR ) })
21612170 else
21622171 t
21632172
2164- def postfixExprRest (t : Tree , location : Location = Location . ElseWhere ): Tree =
2165- infixOps(t, in.canStartExprTokens, prefixExpr,
2173+ def postfixExprRest (t : Tree , location : Location ): Tree =
2174+ infixOps(t, in.canStartExprTokens, prefixExpr, location,
21662175 isType = false ,
21672176 isOperator = ! (location.inArgs && followingIsVararg()),
21682177 maybePostfix = true )
21692178
21702179 /** PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr
21712180 */
2172- val prefixExpr : () => Tree = () =>
2181+ val prefixExpr : Location => Tree = location =>
21732182 if (isIdent && nme.raw.isUnary(in.name)) {
21742183 val start = in.offset
21752184 val op = termIdent()
21762185 if (op.name == nme.raw.MINUS && isNumericLit)
2177- simpleExprRest(literal(start), canApply = true )
2186+ simpleExprRest(literal(start), location, canApply = true )
21782187 else
2179- atSpan(start) { PrefixOp (op, simpleExpr()) }
2188+ atSpan(start) { PrefixOp (op, simpleExpr(location )) }
21802189 }
2181- else simpleExpr()
2190+ else simpleExpr(location )
21822191
21832192 /** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [TemplateBody]
21842193 * | ‘new’ TemplateBody
@@ -2195,11 +2204,12 @@ object Parsers {
21952204 * | SimpleExpr `.` MatchClause
21962205 * | SimpleExpr (TypeArgs | NamedTypeArgs)
21972206 * | SimpleExpr1 ArgumentExprs
2198- * | SimpleExpr1 `:` nl ArgumentExprs
2207+ * | SimpleExpr1 :<<< BlockExpr >>> -- under language.experimental.fewerBraces
2208+ * | SimpleExpr1 FunParams (‘=>’ | ‘?=>’) indent Block outdent -- under language.experimental.fewerBraces
21992209 * Quoted ::= ‘'’ ‘{’ Block ‘}’
22002210 * | ‘'’ ‘[’ Type ‘]’
22012211 */
2202- def simpleExpr (): Tree = {
2212+ def simpleExpr (location : Location ): Tree = {
22032213 var canApply = true
22042214 val t = in.token match {
22052215 case XMLSTART =>
@@ -2235,37 +2245,65 @@ object Parsers {
22352245 newExpr()
22362246 case MACRO =>
22372247 val start = in.skipToken()
2238- MacroTree (simpleExpr())
2248+ MacroTree (simpleExpr(Location . ElseWhere ))
22392249 case _ =>
22402250 if (isLiteral) literal()
22412251 else {
22422252 syntaxErrorOrIncomplete(IllegalStartSimpleExpr (tokenString(in.token)), expectedOffset)
22432253 errorTermTree
22442254 }
22452255 }
2246- simpleExprRest(t, canApply)
2256+ simpleExprRest(t, location, canApply)
22472257 }
22482258
2249- def simpleExprRest (t : Tree , canApply : Boolean = true ): Tree = {
2259+ def simpleExprRest (t : Tree , location : Location , canApply : Boolean = true ): Tree = {
22502260 if (canApply) argumentStart()
22512261 in.token match {
22522262 case DOT =>
22532263 in.nextToken()
2254- simpleExprRest(selectorOrMatch(t), canApply = true )
2264+ simpleExprRest(selectorOrMatch(t), location, canApply = true )
22552265 case LBRACKET =>
22562266 val tapp = atSpan(startOffset(t), in.offset) { TypeApply (t, typeArgs(namedOK = true , wildOK = false )) }
2257- simpleExprRest(tapp, canApply = true )
2267+ simpleExprRest(tapp, location, canApply = true )
22582268 case LPAREN | LBRACE | INDENT if canApply =>
2259- val app = atSpan(startOffset(t), in.offset) { mkApply(t, argumentExprs()) }
2260- simpleExprRest(app, canApply = true )
2269+ val inParents = in.token == LPAREN
2270+ val app = atSpan(startOffset(t), in.offset) {
2271+ val argExprs @ (args, isUsing) = argumentExprs()
2272+ if inParents && ! isUsing && in.isArrow && location != Location .InGuard then
2273+ val params = convertToParams(Tuple (args))
2274+ if params.forall(_.name != nme.ERROR ) then
2275+ applyToClosure(t, in.offset, params)
2276+ else
2277+ mkApply(t, argExprs)
2278+ else
2279+ mkApply(t, argExprs)
2280+ }
2281+ simpleExprRest(app, location, canApply = true )
22612282 case USCORE =>
2262- if in.lookahead.isArrow then ???
2263- else atSpan(startOffset(t), in.skipToken()) { PostfixOp (t, Ident (nme.WILDCARD )) }
2283+ if in.lookahead.isArrow && location != Location .InGuard then
2284+ val app = applyToClosure(t, in.offset, convertToParams(wildcardIdent()))
2285+ simpleExprRest(app, location, canApply = true )
2286+ else
2287+ atSpan(startOffset(t), in.skipToken()) { PostfixOp (t, Ident (nme.WILDCARD )) }
2288+ case IDENTIFIER if ! in.isOperator && in.lookahead.isArrow && location != Location .InGuard =>
2289+ val app = applyToClosure(t, in.offset, convertToParams(termIdent()))
2290+ simpleExprRest(app, location, canApply = true )
22642291 case _ =>
22652292 t
22662293 }
22672294 }
22682295
2296+ def applyToClosure (t : Tree , start : Offset , params : List [ValDef ]): Tree =
2297+ atSpan(startOffset(t), in.offset) {
2298+ val arg = atSpan(start, in.skipToken()) {
2299+ if in.token != INDENT then
2300+ syntaxErrorOrIncomplete(i " indented expression expected, ${in} found " )
2301+ val body = inDefScopeBraces(block(simplify = true ))
2302+ Function (params, body)
2303+ }
2304+ Apply (t, arg)
2305+ }
2306+
22692307 /** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [TemplateBody]
22702308 * | ‘new’ TemplateBody
22712309 */
@@ -2382,7 +2420,7 @@ object Parsers {
23822420 /** Guard ::= if PostfixExpr
23832421 */
23842422 def guard (): Tree =
2385- if (in.token == IF ) { in.nextToken(); postfixExpr() }
2423+ if (in.token == IF ) { in.nextToken(); postfixExpr(Location . InGuard ) }
23862424 else EmptyTree
23872425
23882426 /** Enumerators ::= Generator {semi Enumerator | Guard}
@@ -2607,7 +2645,7 @@ object Parsers {
26072645 /** InfixPattern ::= SimplePattern {id [nl] SimplePattern}
26082646 */
26092647 def infixPattern (): Tree =
2610- infixOps(simplePattern(), in.canStartExprTokens, simplePattern ,
2648+ infixOps(simplePattern(), in.canStartExprTokens, simplePatternFn, Location . InPattern ,
26112649 isType = false ,
26122650 isOperator = in.name != nme.raw.BAR && ! followingIsVararg())
26132651
@@ -2622,7 +2660,7 @@ object Parsers {
26222660 * PatVar ::= id
26232661 * | `_'
26242662 */
2625- val simplePattern : () => Tree = () => in.token match {
2663+ def simplePattern () : Tree = in.token match {
26262664 case IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER =>
26272665 simpleRef() match
26282666 case id @ Ident (nme.raw.MINUS ) if isNumericLit => literal(startOffset(id))
@@ -2632,7 +2670,7 @@ object Parsers {
26322670 case LPAREN =>
26332671 atSpan(in.offset) { makeTupleOrParens(inParens(patternsOpt())) }
26342672 case QUOTE =>
2635- simpleExpr()
2673+ simpleExpr(Location . ElseWhere )
26362674 case XMLSTART =>
26372675 xmlLiteralPattern()
26382676 case GIVEN =>
@@ -2649,6 +2687,8 @@ object Parsers {
26492687 }
26502688 }
26512689
2690+ val simplePatternFn : Location => Tree = _ => simplePattern()
2691+
26522692 def simplePatternRest (t : Tree ): Tree =
26532693 if in.token == DOT then
26542694 in.nextToken()
0 commit comments