@@ -2307,9 +2307,59 @@ object Parsers {
23072307 def paramClauses (ofClass : Boolean = false ,
23082308 ofCaseClass : Boolean = false ,
23092309 ofInstance : Boolean = false ): List [List [ValDef ]] = {
2310+
2311+ def followingIsParamClause : Boolean = {
2312+ val lookahead = in.lookaheadScanner
2313+ lookahead.nextToken()
2314+ paramIntroTokens.contains(lookahead.token) && {
2315+ lookahead.token != IDENTIFIER ||
2316+ lookahead.name == nme.inline || {
2317+ lookahead.nextToken()
2318+ lookahead.token == COLON
2319+ }
2320+ }
2321+ }
2322+
2323+ /** For given instance definitions we have a disambiguation problem:
2324+ * given A as B
2325+ * given C ...
2326+ * Is the second line a parameter `given C` for the first `given` definition, or is it
2327+ * a second `given` definition? We only know if we find a `for` or `as` in `...`
2328+ * The same problem arises for
2329+ * class A
2330+ * given C ...
2331+ * For method definitions we do not have this problem since a parameter clause
2332+ * in a method definition is always followed by something else. So in
2333+ * def m(...)
2334+ * given C ...
2335+ * we know that `given` must start a parameter list. It cannot be a new given` definition.
2336+ */
2337+ def followingIsInstanceDef =
2338+ (ofClass || ofInstance) && {
2339+ val lookahead = in.lookaheadScanner // skips newline on startup
2340+ lookahead.nextToken() // skip the `given`
2341+ if (lookahead.token == IDENTIFIER || lookahead.token == BACKQUOTED_IDENT ) {
2342+ lookahead.nextToken()
2343+ if (lookahead.token == LBRACKET ) {
2344+ lookahead.nextToken()
2345+ var openBrackets = 1
2346+ while (openBrackets > 0 && lookahead.token != EOF ) {
2347+ if (lookahead.token == LBRACKET ) openBrackets += 1
2348+ else if (lookahead.token == RBRACKET ) openBrackets -= 1
2349+ lookahead.nextToken()
2350+ }
2351+ }
2352+ }
2353+ lookahead.token == FOR ||
2354+ lookahead.token == IDENTIFIER && lookahead.name == nme.as
2355+ }
2356+
23102357 def recur (firstClause : Boolean , nparams : Int , contextualOnly : Boolean ): List [List [ValDef ]] = {
23112358 var initialMods = EmptyModifiers
2359+ val isNewLine = in.token == NEWLINE
23122360 newLineOptWhenFollowedBy(LPAREN )
2361+ if (in.token == NEWLINE && in.next.token == GIVEN && ! followingIsInstanceDef)
2362+ in.nextToken()
23132363 if (in.token == GIVEN ) {
23142364 in.nextToken()
23152365 initialMods |= Given
@@ -2318,22 +2368,10 @@ object Parsers {
23182368 in.nextToken()
23192369 initialMods |= Erased
23202370 }
2321- val isContextual = initialMods.is(Given )
2371+ val isGiven = initialMods.is(Given )
23222372 newLineOptWhenFollowedBy(LPAREN )
2323- def isParamClause : Boolean =
2324- ! isContextual || {
2325- val lookahead = in.lookaheadScanner
2326- lookahead.nextToken()
2327- paramIntroTokens.contains(lookahead.token) && {
2328- lookahead.token != IDENTIFIER ||
2329- lookahead.name == nme.inline || {
2330- lookahead.nextToken()
2331- lookahead.token == COLON
2332- }
2333- }
2334- }
2335- if (in.token == LPAREN && isParamClause) {
2336- if (contextualOnly && ! isContextual)
2373+ if (in.token == LPAREN && (! isGiven || followingIsParamClause)) {
2374+ if (contextualOnly && ! isGiven)
23372375 if (ofInstance) syntaxError(em " parameters of instance definitions must come after `given' " )
23382376 else syntaxError(em " normal parameters cannot come after `given' clauses " )
23392377 val params = paramClause(
@@ -2342,15 +2380,15 @@ object Parsers {
23422380 firstClause = firstClause,
23432381 initialMods = initialMods)
23442382 val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
2345- params :: (if (lastClause) Nil else recur(firstClause = false , nparams + params.length, isContextual ))
2383+ params :: (if (lastClause) Nil else recur(firstClause = false , nparams + params.length, isGiven ))
23462384 }
2347- else if (isContextual ) {
2385+ else if (isGiven ) {
23482386 val tps = commaSeparated(() => annotType())
23492387 var counter = nparams
23502388 def nextIdx = { counter += 1 ; counter }
23512389 val paramFlags = if (ofClass) Private | Local | ParamAccessor else Param
23522390 val params = tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given ))
2353- params :: recur(firstClause = false , nparams + params.length, isContextual )
2391+ params :: recur(firstClause = false , nparams + params.length, isGiven )
23542392 }
23552393 else Nil
23562394 }
@@ -2819,7 +2857,7 @@ object Parsers {
28192857 val name = if (isIdent && (! newStyle || in.name != nme.as)) ident() else EmptyTermName
28202858 val tparams = typeParamClauseOpt(ParamOwner .Def )
28212859 val parents =
2822- if (! newStyle && in.token == FOR || newStyle && isIdent(nme.as)) {
2860+ if (! newStyle && in.token == FOR || isIdent(nme.as)) { // for the moment, accept both `given for` and `given as`
28232861 in.nextToken()
28242862 tokenSeparated(COMMA , constrApp)
28252863 }
0 commit comments