@@ -43,6 +43,7 @@ object Parsers {
4343 enum Location (val inParens : Boolean , val inPattern : Boolean , val inArgs : Boolean ):
4444 case InParens extends Location (true , false , false )
4545 case InArgs extends Location (true , false , true )
46+ case InColonArg extends Location (false , false , true )
4647 case InPattern extends Location (false , true , false )
4748 case InGuard extends Location (false , false , false )
4849 case InPatternArgs extends Location (false , true , true ) // InParens not true, since it might be an alternative
@@ -893,7 +894,6 @@ object Parsers {
893894 val next = in.lookahead.token
894895 next == LBRACKET || next == LPAREN
895896
896-
897897 def followingIsSelfType () =
898898 val lookahead = in.LookaheadScanner ()
899899 lookahead.nextToken()
@@ -917,10 +917,10 @@ object Parsers {
917917 }
918918 }
919919
920- /** When encountering a `:`, is that in the first binding of a lambda?
921- * @pre location of the enclosing expression is `InParens`, so there is am open `(`.
920+ /** When encountering a `:`, is that in the binding of a lambda?
921+ * @pre location of the enclosing expression is `InParens`, so there is an open `(`.
922922 */
923- def followingisLambdaParams () =
923+ def followingIsLambdaParams () =
924924 val lookahead = in.LookaheadScanner ()
925925 lookahead.nextToken()
926926 while lookahead.token != RPAREN && lookahead.token != EOF do
@@ -932,6 +932,21 @@ object Parsers {
932932 lookahead.isArrow
933933 }
934934
935+ /** Is the token sequence following the current `:` token classified as a lambda?
936+ * This is the case if the input starts with an identifier, a wildcard, or
937+ * something enclosed in (...) or [...], and this is followed by a `=>` or `?=>`.
938+ */
939+ def followingIsLambdaAfterColon (): Boolean =
940+ val lookahead = in.LookaheadScanner ()
941+ lookahead.nextToken()
942+ if lookahead.isIdent || lookahead.token == USCORE then
943+ lookahead.nextToken()
944+ lookahead.isArrow
945+ else if lookahead.token == LPAREN || lookahead.token == LBRACKET then
946+ lookahead.skipParens()
947+ lookahead.isArrow
948+ else false
949+
935950 /* --------- OPERAND/OPERATOR STACK --------------------------------------- */
936951
937952 var opStack : List [OpInfo ] = Nil
@@ -2229,7 +2244,17 @@ object Parsers {
22292244 in.nextToken()
22302245 else
22312246 accept(ARROW )
2232- Function (params, if (location == Location .InBlock ) block() else expr())
2247+ val body =
2248+ if location == Location .InBlock then block()
2249+ else if location == Location .InColonArg then
2250+ if in.token == INDENT then
2251+ blockExpr()
2252+ else
2253+ in.insertMaxIndent()
2254+ try casesOrBlock(simplify = true )
2255+ finally accept(OUTDENT )
2256+ else expr()
2257+ Function (params, body)
22332258 }
22342259
22352260 /** PostfixExpr ::= InfixExpr [id [nl]]
@@ -2279,9 +2304,12 @@ object Parsers {
22792304 * | SimpleExpr `.` MatchClause
22802305 * | SimpleExpr (TypeArgs | NamedTypeArgs)
22812306 * | SimpleExpr1 ArgumentExprs
2282- * | SimpleExpr1 `:` IndentedExpr -- under language.experimental.fewerBraces
2283- * | SimpleExpr1 FunParams (‘=>’ | ‘?=>’) IndentedExpr -- under language.experimental.fewerBraces
2284- * IndentedExpr ::= indent (CaseClauses | Block) outdent
2307+ * | SimpleExpr1 `:` ColonArgument -- under language.experimental.fewerBraces
2308+ * ColonArgument ::= indent (CaseClauses | Block) outdent
2309+ * | FunParams (‘=>’ | ‘?=>’) ColonArgBody
2310+ * | HkTypeParamClause ‘=>’ ColonArgBody
2311+ * ColonArgBody ::= indent (CaseClauses | Block) outdent
2312+ * | <silent-indent> (CaseClauses | Block) outdent -- silent-indent is inserted by Scanner if no real indent is found
22852313 * Quoted ::= ‘'’ ‘{’ Block ‘}’
22862314 * | ‘'’ ‘[’ Type ‘]’
22872315 */
@@ -2337,65 +2365,38 @@ object Parsers {
23372365 simpleExprRest(t, location, canApply)
23382366 }
23392367
2340- def simpleExprRest (t : Tree , location : Location , canApply : Boolean = true ): Tree = {
2368+ def simpleExprRest (t : Tree , location : Location , canApply : Boolean = true ): Tree =
23412369 if (canApply) argumentStart()
2342- in.token match {
2370+ in.token match
23432371 case DOT =>
23442372 in.nextToken()
23452373 simpleExprRest(selectorOrMatch(t), location, canApply = true )
23462374 case LBRACKET =>
23472375 val tapp = atSpan(startOffset(t), in.offset) { TypeApply (t, typeArgs(namedOK = true , wildOK = false )) }
23482376 simpleExprRest(tapp, location, canApply = true )
2349- case LPAREN if canApply =>
2350- val app = atSpan(startOffset(t), in.offset) {
2351- val argExprs @ (args, isUsing) = argumentExprs()
2352- if ! isUsing && in.isArrow && location != Location .InGuard && in.fewerBracesEnabled then
2353- val params = convertToParams(Tuple (args))
2354- if params.forall(_.name != nme.ERROR ) then
2355- applyToClosure(t, in.offset, params)
2356- else
2357- mkApply(t, argExprs)
2358- else
2359- mkApply(t, argExprs)
2360- }
2361- simpleExprRest(app, location, canApply = true )
2362- case LBRACE | INDENT if canApply =>
2377+ case LPAREN | LBRACE | INDENT if canApply =>
23632378 val app = atSpan(startOffset(t), in.offset) { mkApply(t, argumentExprs()) }
23642379 simpleExprRest(app, location, canApply = true )
23652380 case USCORE =>
2366- if in.lookahead.isArrow && location != Location .InGuard && in.fewerBracesEnabled then
2367- val app = applyToClosure(t, in.offset, convertToParams(wildcardIdent()))
2368- simpleExprRest(app, location, canApply = true )
2369- else
2370- atSpan(startOffset(t), in.skipToken()) { PostfixOp (t, Ident (nme.WILDCARD )) }
2371- case IDENTIFIER
2372- if ! in.isOperator && in.lookahead.isArrow && location != Location .InGuard && in.fewerBracesEnabled =>
2373- val app = applyToClosure(t, in.offset, convertToParams(termIdent()))
2374- simpleExprRest(app, location, canApply = true )
2381+ atSpan(startOffset(t), in.skipToken()) { PostfixOp (t, Ident (nme.WILDCARD )) }
23752382 case _ =>
2376- t match
2377- case id @ Ident (name)
2378- if in.isColon() && location == Location .InParens && followingisLambdaParams() =>
2379- if name.is(WildcardParamName ) then
2380- assert(name == placeholderParams.head.name)
2381- placeholderParams = placeholderParams.tail
2382- atSpan(startOffset(id)) {
2383- makeParameter(name.asTermName, typedOpt(), Modifiers (), isBackquoted = isBackquoted(id))
2384- }
2385- case _ =>
2386- t
2387- }
2388- }
2389-
2390- def applyToClosure (t : Tree , start : Offset , params : List [ValDef ]): Tree =
2391- atSpan(startOffset(t), in.offset) {
2392- val arg = atSpan(start, in.skipToken()) {
2393- if in.token != INDENT then
2394- syntaxErrorOrIncomplete(i " indented expression expected, ${in} found " )
2395- Function (params, blockExpr())
2396- }
2397- Apply (t, arg)
2398- }
2383+ if in.isColon() && location == Location .InParens && followingIsLambdaParams() then
2384+ t match
2385+ case id @ Ident (name) =>
2386+ if name.is(WildcardParamName ) then
2387+ assert(name == placeholderParams.head.name)
2388+ placeholderParams = placeholderParams.tail
2389+ atSpan(startOffset(id)) {
2390+ makeParameter(name.asTermName, typedOpt(), Modifiers (), isBackquoted = isBackquoted(id))
2391+ }
2392+ case _ => t
2393+ else if in.fewerBracesEnabled && in.token == COLON && followingIsLambdaAfterColon() then
2394+ val app = atSpan(startOffset(t), in.skipToken()) {
2395+ Apply (t, expr(Location .InColonArg ) :: Nil )
2396+ }
2397+ simpleExprRest(app, location, canApply = true )
2398+ else t
2399+ end simpleExprRest
23992400
24002401 /** SimpleExpr ::= ‘new’ ConstrApp {`with` ConstrApp} [TemplateBody]
24012402 * | ‘new’ TemplateBody
@@ -2499,12 +2500,13 @@ object Parsers {
24992500 */
25002501 def blockExpr (): Tree = atSpan(in.offset) {
25012502 val simplify = in.token == INDENT
2502- inDefScopeBraces {
2503- if (in.token == CASE ) Match (EmptyTree , caseClauses(() => caseClause()))
2504- else block(simplify)
2505- }
2503+ inDefScopeBraces { casesOrBlock(simplify) }
25062504 }
25072505
2506+ def casesOrBlock (simplify : Boolean ): Tree =
2507+ if (in.token == CASE ) Match (EmptyTree , caseClauses(() => caseClause()))
2508+ else block(simplify)
2509+
25082510 /** Block ::= BlockStatSeq
25092511 * @note Return tree does not have a defined span.
25102512 */
0 commit comments