@@ -938,10 +938,13 @@ object Parsers {
938938 lookahead.nextToken()
939939 while lookahead.token == LPAREN || lookahead.token == LBRACKET do
940940 lookahead.skipParens()
941- if lookahead.token == COLON then
941+ if lookahead.token == COLON then // TODO: remove
942942 lookahead.nextToken()
943943 ! lookahead.isAfterLineEnd
944- else lookahead.token == SUBTYPE || lookahead.isIdent(nme.as)
944+ else
945+ lookahead.token == SUBTYPE // TODO: remove
946+ || lookahead.isIdent(nme.as)
947+ || lookahead.token == WITH && lookahead.ch != Chars .LF // TODO: remove LF test
945948
946949 def followingIsExtension () =
947950 val lookahead = in.LookaheadScanner ()
@@ -2106,6 +2109,7 @@ object Parsers {
21062109 * | SimpleExpr `.' MatchClause
21072110 * | SimpleExpr (TypeArgs | NamedTypeArgs)
21082111 * | SimpleExpr1 ArgumentExprs
2112+ * | SimpleExpr ContextArguments
21092113 * Quoted ::= ‘'’ ‘{’ Block ‘}’
21102114 * | ‘'’ ‘[’ Type ‘]’
21112115 */
@@ -2174,6 +2178,8 @@ object Parsers {
21742178 case DOT =>
21752179 in.nextToken()
21762180 simpleExprRest(selector(t), canApply = true )
2181+ case DOTWITH =>
2182+ simpleExprRest(contextArguments(t), canApply = true )
21772183 case LBRACKET =>
21782184 val tapp = atSpan(startOffset(t), in.offset) { TypeApply (t, typeArgs(namedOK = true , wildOK = false )) }
21792185 simpleExprRest(tapp, canApply = true )
@@ -2250,7 +2256,7 @@ object Parsers {
22502256 else fn
22512257 }
22522258
2253- /** ParArgumentExprss ::= {ParArgumentExprs}
2259+ /** ParArgumentExprss ::= {ParArgumentExprs | ContextArguments }
22542260 *
22552261 * Special treatment for arguments to primary constructor annotations.
22562262 * (...) is considered an argument only if it does not look like a formal
@@ -2275,6 +2281,8 @@ object Parsers {
22752281 parArgumentExprss(
22762282 atSpan(startOffset(fn)) { mkApply(fn, parArgumentExprs()) }
22772283 )
2284+ else if in.token == DOTWITH then
2285+ parArgumentExprss(contextArguments(fn))
22782286 else fn
22792287 }
22802288
@@ -2304,6 +2312,14 @@ object Parsers {
23042312 else Block (stats, EmptyTree )
23052313 }
23062314
2315+ /** ContextArguments ::= ‘.’ ‘with’ ArgumentExprs */
2316+ def contextArguments (t : Tree ): Tree =
2317+ if in.token == DOTWITH then
2318+ atSpan(t.span.start, in.skipToken()) {
2319+ Apply (t, argumentExprs()._1).setGivenApply()
2320+ }
2321+ else t
2322+
23072323 /** Guard ::= if PostfixExpr
23082324 */
23092325 def guard (): Tree =
@@ -2786,23 +2802,23 @@ object Parsers {
27862802 def typeParamClauseOpt (ownerKind : ParamOwner .Value ): List [TypeDef ] =
27872803 if (in.token == LBRACKET ) typeParamClause(ownerKind) else Nil
27882804
2789- /** OLD: GivenTypes ::= AnnotType {‘,’ AnnotType}
2790- * NEW: GivenTypes ::= Type {‘,’ Type}
2805+ /** AnnotTypes ::= AnnotType {‘,’ AnnotType}
2806+ * Types ::= Type {‘,’ Type}
27912807 */
2792- def givenTypes (nparams : Int , ofClass : Boolean ): List [ValDef ] =
2793- val tps = commaSeparated(typ )
2808+ def givenTypes (parseType : () => Tree , nparams : Int , ofClass : Boolean ): List [ValDef ] =
2809+ val tps = commaSeparated(parseType )
27942810 var counter = nparams
27952811 def nextIdx = { counter += 1 ; counter }
27962812 val paramFlags = if ofClass then Private | Local | ParamAccessor else Param
27972813 tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given ))
27982814
27992815 /** ClsParamClause ::= ‘(’ [‘erased’] ClsParams ‘)’
2800- * GivenClsParamClause::= 'with' ‘(’ (ClsParams | GivenTypes ) ‘)’
2816+ * GivenClsParamClause::= 'with' ( ‘(’ (ClsParams | Types ) ‘)’ | AnnotTypes)
28012817 * ClsParams ::= ClsParam {‘,’ ClsParam}
28022818 * ClsParam ::= {Annotation}
28032819 *
28042820 * DefParamClause ::= ‘(’ [‘erased’] DefParams ‘)’
2805- * GivenParamClause ::= ‘with’ ‘(’ (DefParams | GivenTypes ) ‘)’
2821+ * GivenParamClause ::= ‘with’ ( ‘(’ (DefParams | Types ) ‘)’ | AnnotTypes)
28062822 * DefParams ::= DefParam {‘,’ DefParam}
28072823 * DefParam ::= {Annotation} [‘inline’] Param
28082824 *
@@ -2888,34 +2904,33 @@ object Parsers {
28882904 impliedModOpt(GIVEN , () => Mod .Given ())
28892905 impliedModOpt(ERASED , () => Mod .Erased ())
28902906 if givenOnly && ! impliedMods.is(Given ) then
2891- syntaxError(ExpectedTokenButFound ( GIVEN , in.token) )
2907+ syntaxError(" Normal parameter clause cannot follow context parameter clause " )
28922908 val isParams =
28932909 ! impliedMods.is(Given )
28942910 || startParamTokens.contains(in.token)
28952911 || isIdent && (in.name == nme.inline || in.lookaheadIn(BitSet (COLON )))
28962912 if isParams then commaSeparated(() => param())
2897- else givenTypes(nparams, ofClass)
2913+ else givenTypes(typ, nparams, ofClass)
28982914 checkVarArgsRules(clause)
28992915 clause
29002916 }
29012917 }
29022918
29032919 /** ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’]
2904- * | {ClsParamClause | GivenClsParamClause} [‘with’ GivenTypes]
2920+ * | {ClsParamClause} { GivenClsParamClause}
29052921 * DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’]
2906- * | {DefParamClause | GivenParamClause} [‘with’ GivenTypes]
2907- * GivenParamClauses ::= {GivenParamClause} [‘with’ GivenTypes]
2922+ * | {DefParamClause} {GivenParamClause}
29082923 *
29092924 * @return The parameter definitions
29102925 */
29112926 def paramClauses (ofClass : Boolean = false ,
29122927 ofCaseClass : Boolean = false ,
29132928 givenOnly : Boolean = false ): List [List [ValDef ]] =
29142929
2915- def recur (firstClause : Boolean , nparams : Int ): List [List [ValDef ]] =
2930+ def recur (firstClause : Boolean , nparams : Int , givenOnly : Boolean ): List [List [ValDef ]] =
29162931 newLineOptWhenFollowedBy(LPAREN )
29172932 val prefixMods =
2918- if in.token == WITH then
2933+ if in.token == WITH && in.ch != Chars . LF then // TODO: remove LF test
29192934 in.nextToken()
29202935 Modifiers (Given )
29212936 else
@@ -2930,15 +2945,18 @@ object Parsers {
29302945 firstClause = firstClause,
29312946 prefixMods = prefixMods)
29322947 val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
2948+ val isGivenClause = prefixMods.is(Given )
2949+ || params.nonEmpty && params.head.mods.flags.is(Given )
29332950 params :: (
29342951 if lastClause then Nil
2935- else recur(firstClause = false , nparams + params.length))
2952+ else recur(firstClause = false , nparams + params.length, givenOnly | isGivenClause ))
29362953 else if prefixMods.is(Given ) then
2937- givenTypes(nparams, ofClass) :: Nil
2954+ val params = givenTypes(annotType, nparams, ofClass)
2955+ params :: recur(firstClause = false , nparams + params.length, true )
29382956 else Nil
29392957 end recur
29402958
2941- recur(firstClause = true , 0 )
2959+ recur(firstClause = true , 0 , givenOnly )
29422960 end paramClauses
29432961
29442962/* -------- DEFS ------------------------------------------- */
@@ -3464,7 +3482,8 @@ object Parsers {
34643482 val tparams = typeParamClauseOpt(ParamOwner .Def )
34653483 val paramsStart = in.offset
34663484 val vparamss =
3467- if in.token == WITH || in.token == LPAREN && followingIsParamOrGivenType()
3485+ if in.token == WITH && in.ch != Chars .LF // TODO: remove LF test
3486+ || in.token == LPAREN && followingIsParamOrGivenType()
34683487 then paramClauses()
34693488 else Nil
34703489 def checkAllGivens (vparamss : List [List [ValDef ]], what : String ) =
@@ -3531,7 +3550,8 @@ object Parsers {
35313550 val constrApp : () => Tree = () => {
35323551 val t = rejectWildcardType(annotType(), fallbackTree = Ident (nme.ERROR ))
35333552 // Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code
3534- if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t
3553+ if in.token == LPAREN || in.token == DOTWITH then parArgumentExprss(wrapNew(t))
3554+ else t
35353555 }
35363556
35373557 /** ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp}
0 commit comments