@@ -43,6 +43,7 @@ object Parsers {
43
43
case InParens extends Location (true , false , false )
44
44
case InArgs extends Location (true , false , true )
45
45
case InPattern extends Location (false , true , false )
46
+ case InGuard extends Location (false , false , false )
46
47
case InPatternArgs extends Location (false , true , true ) // InParens not true, since it might be an alternative
47
48
case InBlock extends Location (false , false , false )
48
49
case ElseWhere extends Location (false , false , false )
@@ -403,22 +404,23 @@ object Parsers {
403
404
404
405
/** Convert tree to formal parameter list
405
406
*/
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
422
424
423
425
/** Convert tree to formal parameter
424
426
*/
@@ -920,7 +922,8 @@ object Parsers {
920
922
* @param maybePostfix postfix operators are allowed.
921
923
*/
922
924
def infixOps (
923
- first : Tree , canStartOperand : Token => Boolean , operand : () => Tree ,
925
+ first : Tree , canStartOperand : Token => Boolean , operand : Location => Tree ,
926
+ location : Location ,
924
927
isType : Boolean ,
925
928
isOperator : => Boolean ,
926
929
maybePostfix : Boolean = false ): Tree = {
@@ -941,7 +944,7 @@ object Parsers {
941
944
PostfixOp (od, topInfo.operator)
942
945
}
943
946
}
944
- else recur(operand())
947
+ else recur(operand(location ))
945
948
}
946
949
else
947
950
val t = reduceStack(base, top, minPrec, leftAssoc = true , in.name, isType)
@@ -1488,12 +1491,15 @@ object Parsers {
1488
1491
def infixType (): Tree = infixTypeRest(refinedType())
1489
1492
1490
1493
def infixTypeRest (t : Tree ): Tree =
1491
- infixOps(t, canStartTypeTokens, refinedType, isType = true ,
1494
+ infixOps(t, canStartTypeTokens, refinedTypeFn, Location .ElseWhere ,
1495
+ isType = true ,
1492
1496
isOperator = ! followingIsVararg())
1493
1497
1494
1498
/** RefinedType ::= WithType {[nl] Refinement}
1495
1499
*/
1496
- val refinedType : () => Tree = () => refinedTypeRest(withType())
1500
+ val refinedTypeFn : Location => Tree = _ => refinedType()
1501
+
1502
+ def refinedType () = refinedTypeRest(withType())
1497
1503
1498
1504
def refinedTypeRest (t : Tree ): Tree = {
1499
1505
argumentStart()
@@ -1811,7 +1817,11 @@ object Parsers {
1811
1817
if in.token != altToken then
1812
1818
if toBeContinued(altToken) then
1813
1819
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 )
1815
1825
}
1816
1826
else
1817
1827
if rewriteToNewSyntax(t.span) then
@@ -1882,8 +1892,7 @@ object Parsers {
1882
1892
val t = expr1(location)
1883
1893
if in.isArrow then
1884
1894
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)))
1887
1896
else if isWildcard(t) then
1888
1897
placeholderParams = placeholderParams ::: saved
1889
1898
t
@@ -2155,30 +2164,30 @@ object Parsers {
2155
2164
* | InfixExpr MatchClause
2156
2165
*/
2157
2166
def postfixExpr (location : Location = Location .ElseWhere ): Tree =
2158
- val t = postfixExprRest(prefixExpr(), location)
2167
+ val t = postfixExprRest(prefixExpr(location ), location)
2159
2168
if location.inArgs && followingIsVararg() then
2160
2169
Typed (t, atSpan(in.skipToken()) { Ident (tpnme.WILDCARD_STAR ) })
2161
2170
else
2162
2171
t
2163
2172
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,
2166
2175
isType = false ,
2167
2176
isOperator = ! (location.inArgs && followingIsVararg()),
2168
2177
maybePostfix = true )
2169
2178
2170
2179
/** PrefixExpr ::= [`-' | `+' | `~' | `!'] SimpleExpr
2171
2180
*/
2172
- val prefixExpr : () => Tree = () =>
2181
+ val prefixExpr : Location => Tree = location =>
2173
2182
if (isIdent && nme.raw.isUnary(in.name)) {
2174
2183
val start = in.offset
2175
2184
val op = termIdent()
2176
2185
if (op.name == nme.raw.MINUS && isNumericLit)
2177
- simpleExprRest(literal(start), canApply = true )
2186
+ simpleExprRest(literal(start), location, canApply = true )
2178
2187
else
2179
- atSpan(start) { PrefixOp (op, simpleExpr()) }
2188
+ atSpan(start) { PrefixOp (op, simpleExpr(location )) }
2180
2189
}
2181
- else simpleExpr()
2190
+ else simpleExpr(location )
2182
2191
2183
2192
/** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [TemplateBody]
2184
2193
* | ‘new’ TemplateBody
@@ -2195,11 +2204,12 @@ object Parsers {
2195
2204
* | SimpleExpr `.` MatchClause
2196
2205
* | SimpleExpr (TypeArgs | NamedTypeArgs)
2197
2206
* | SimpleExpr1 ArgumentExprs
2198
- * | SimpleExpr1 `:` nl ArgumentExprs
2207
+ * | SimpleExpr1 :<<< BlockExpr >>> -- under language.experimental.fewerBraces
2208
+ * | SimpleExpr1 FunParams (‘=>’ | ‘?=>’) indent Block outdent -- under language.experimental.fewerBraces
2199
2209
* Quoted ::= ‘'’ ‘{’ Block ‘}’
2200
2210
* | ‘'’ ‘[’ Type ‘]’
2201
2211
*/
2202
- def simpleExpr (): Tree = {
2212
+ def simpleExpr (location : Location ): Tree = {
2203
2213
var canApply = true
2204
2214
val t = in.token match {
2205
2215
case XMLSTART =>
@@ -2235,37 +2245,65 @@ object Parsers {
2235
2245
newExpr()
2236
2246
case MACRO =>
2237
2247
val start = in.skipToken()
2238
- MacroTree (simpleExpr())
2248
+ MacroTree (simpleExpr(Location . ElseWhere ))
2239
2249
case _ =>
2240
2250
if (isLiteral) literal()
2241
2251
else {
2242
2252
syntaxErrorOrIncomplete(IllegalStartSimpleExpr (tokenString(in.token)), expectedOffset)
2243
2253
errorTermTree
2244
2254
}
2245
2255
}
2246
- simpleExprRest(t, canApply)
2256
+ simpleExprRest(t, location, canApply)
2247
2257
}
2248
2258
2249
- def simpleExprRest (t : Tree , canApply : Boolean = true ): Tree = {
2259
+ def simpleExprRest (t : Tree , location : Location , canApply : Boolean = true ): Tree = {
2250
2260
if (canApply) argumentStart()
2251
2261
in.token match {
2252
2262
case DOT =>
2253
2263
in.nextToken()
2254
- simpleExprRest(selectorOrMatch(t), canApply = true )
2264
+ simpleExprRest(selectorOrMatch(t), location, canApply = true )
2255
2265
case LBRACKET =>
2256
2266
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 )
2258
2268
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 )
2261
2282
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 )
2264
2291
case _ =>
2265
2292
t
2266
2293
}
2267
2294
}
2268
2295
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
+
2269
2307
/** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [TemplateBody]
2270
2308
* | ‘new’ TemplateBody
2271
2309
*/
@@ -2382,7 +2420,7 @@ object Parsers {
2382
2420
/** Guard ::= if PostfixExpr
2383
2421
*/
2384
2422
def guard (): Tree =
2385
- if (in.token == IF ) { in.nextToken(); postfixExpr() }
2423
+ if (in.token == IF ) { in.nextToken(); postfixExpr(Location . InGuard ) }
2386
2424
else EmptyTree
2387
2425
2388
2426
/** Enumerators ::= Generator {semi Enumerator | Guard}
@@ -2607,7 +2645,7 @@ object Parsers {
2607
2645
/** InfixPattern ::= SimplePattern {id [nl] SimplePattern}
2608
2646
*/
2609
2647
def infixPattern (): Tree =
2610
- infixOps(simplePattern(), in.canStartExprTokens, simplePattern ,
2648
+ infixOps(simplePattern(), in.canStartExprTokens, simplePatternFn, Location . InPattern ,
2611
2649
isType = false ,
2612
2650
isOperator = in.name != nme.raw.BAR && ! followingIsVararg())
2613
2651
@@ -2622,7 +2660,7 @@ object Parsers {
2622
2660
* PatVar ::= id
2623
2661
* | `_'
2624
2662
*/
2625
- val simplePattern : () => Tree = () => in.token match {
2663
+ def simplePattern () : Tree = in.token match {
2626
2664
case IDENTIFIER | BACKQUOTED_IDENT | THIS | SUPER =>
2627
2665
simpleRef() match
2628
2666
case id @ Ident (nme.raw.MINUS ) if isNumericLit => literal(startOffset(id))
@@ -2632,7 +2670,7 @@ object Parsers {
2632
2670
case LPAREN =>
2633
2671
atSpan(in.offset) { makeTupleOrParens(inParens(patternsOpt())) }
2634
2672
case QUOTE =>
2635
- simpleExpr()
2673
+ simpleExpr(Location . ElseWhere )
2636
2674
case XMLSTART =>
2637
2675
xmlLiteralPattern()
2638
2676
case GIVEN =>
@@ -2649,6 +2687,8 @@ object Parsers {
2649
2687
}
2650
2688
}
2651
2689
2690
+ val simplePatternFn : Location => Tree = _ => simplePattern()
2691
+
2652
2692
def simplePatternRest (t : Tree ): Tree =
2653
2693
if in.token == DOT then
2654
2694
in.nextToken()
0 commit comments