Skip to content

Commit 3e4f9e3

Browse files
committed
Enable suffix as in given defs
1 parent a185a9e commit 3e4f9e3

File tree

1 file changed

+46
-17
lines changed

1 file changed

+46
-17
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -958,8 +958,9 @@ object Parsers {
958958
val suffixIsUpper = Character.isUpperCase(suffixName.head)
959959
if prefixIsUpper && !suffixIsUpper then false
960960
else if !prefixIsUpper && suffixIsUpper then true
961-
else syntaxError(
962-
em"ambiguous syntax for given definition; make sure exactly one of $prefixName, $suffixName is capitalized")
961+
else
962+
syntaxError(
963+
em"ambiguous syntax for given definition; make sure exactly one of $prefixName, $suffixName is capitalized")
963964
true
964965
end followingIsGivenSig
965966

@@ -1440,7 +1441,7 @@ object Parsers {
14401441

14411442
val t =
14421443
if in.token == LPAREN then
1443-
typAfterParens(functionRest)
1444+
afterArguments(x => infixTypeRest(refinedTypeRest(withTypeRest(x))), functionRest)
14441445
else if (in.token == LBRACKET) {
14451446
val tparams = typeParamClause(ParamOwner.TypeParam)
14461447
if (in.token == TLARROW)
@@ -1480,14 +1481,14 @@ object Parsers {
14801481
buf += following()
14811482
buf.toList
14821483

1483-
def typAfterParens(parseRest: (List[Tree], Modifiers) => Tree) =
1484+
def afterArguments[T](parseSimple: Tree => T, parseFn: (List[Tree], Modifiers) => T): T =
14841485
val start = in.offset
14851486
in.nextToken()
14861487
var imods = Modifiers()
14871488
var isValParamList = false
14881489
if in.token == RPAREN then
14891490
in.nextToken()
1490-
parseRest(Nil, imods)
1491+
parseFn(Nil, imods)
14911492
else
14921493
openParens.change(LPAREN, 1)
14931494
imods = modifiers(funTypeArgMods)
@@ -1503,7 +1504,7 @@ object Parsers {
15031504
openParens.change(LPAREN, -1)
15041505
accept(RPAREN)
15051506
if isValParamList || in.token == ARROW || in.token == CTXARROW then
1506-
parseRest(ts, imods)
1507+
parseFn(ts, imods)
15071508
else
15081509
val ts1 =
15091510
for t <- ts yield
@@ -1514,12 +1515,8 @@ object Parsers {
15141515
case _ =>
15151516
t
15161517
val tuple = atSpan(start) { makeTupleOrParens(ts1) }
1517-
infixTypeRest(
1518-
refinedTypeRest(
1519-
withTypeRest(
1520-
annotTypeRest(
1521-
simpleTypeRest(tuple)))))
1522-
end typAfterParens
1518+
parseSimple(annotTypeRest(simpleTypeRest(tuple)))
1519+
end afterArguments
15231520

15241521
private def makeKindProjectorTypeDef(name: TypeName): TypeDef =
15251522
TypeDef(name, WildcardTypeBoundsTree()).withFlags(Param)
@@ -3562,13 +3559,13 @@ object Parsers {
35623559
syntaxError(i"extension clause can only define methods", stat.span)
35633560
}
35643561

3565-
/** GivenDef ::= [GivenSig] Type ‘=’ Expr
3566-
* | [GivenSig] ConstrApps [TemplateBody]
3567-
* GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’
3562+
/** GivenDef ::= [GivenParams] Type ['as' id] ‘=’ Expr
3563+
* | [GivenParams] ConstrApps ['as' id] [TemplateBody]
3564+
* GivenParams ::= [DefTypeParamClause '=>'] {FunArgTypes '=>'}
35683565
*/
35693566
def givenDef(start: Offset, mods: Modifiers, givenMod: Mod) = atSpan(start, nameStart) {
35703567
var mods1 = addMod(mods, givenMod)
3571-
val nameStart = in.offset
3568+
val start = in.offset
35723569
val (name, tparams, vparamss, parents) = if followingIsGivenSig() then
35733570
val name = if isIdent then ident() else EmptyTermName
35743571
val tparams = typeParamClauseOpt(ParamOwner.Def)
@@ -3581,6 +3578,36 @@ object Parsers {
35813578
accept(nme.as)
35823579
val parents = constrApps(commaOK = true)
35833580
(name, tparams, vparamss, parents)
3581+
else if true then
3582+
val tparams = typeParamClauseOpt(ParamOwner.Def)
3583+
if tparams.nonEmpty then accept(ARROW)
3584+
var counter = 0
3585+
def nextIdx = { counter += 1; counter }
3586+
def givenHeadRest(params: List[Tree], mods: Modifiers): (List[List[ValDef]], List[Tree]) =
3587+
accept(ARROW)
3588+
val vparams = params match
3589+
case (_: ValDef) :: _ =>
3590+
params.asInstanceOf[List[ValDef]].map(_.withFlags(Given))
3591+
case _ =>
3592+
params.map(makeSyntheticParameter(nextIdx, _, Param | Synthetic | Given))
3593+
val (vparamss1, parents) = givenHead()
3594+
(vparams :: vparamss1, parents)
3595+
def givenHeadFinish(t: Tree): (List[List[ValDef]], List[Tree]) =
3596+
(Nil, constrAppsRest(constrAppRest(t), commaOK = true))
3597+
def givenHead(): (List[List[ValDef]], List[Tree]) =
3598+
if in.token == LPAREN then
3599+
afterArguments(givenHeadFinish, givenHeadRest)
3600+
else
3601+
val constr = constrOrSimpleType()
3602+
if in.token == ARROW then givenHeadRest(constr :: Nil, EmptyModifiers)
3603+
else givenHeadFinish(constr)
3604+
val (vparamss, parents) = givenHead()
3605+
val name =
3606+
if in.isIdent(nme.as) then
3607+
in.nextToken()
3608+
ident()
3609+
else EmptyTermName
3610+
(name, tparams, vparamss, parents)
35843611
else
35853612
(EmptyTermName, Nil, Nil, constrApps(commaOK = true))
35863613
val gdef =
@@ -3662,7 +3689,9 @@ object Parsers {
36623689
/** ConstrApp ::= SimpleType1 {Annotation} {ParArgumentExprs}
36633690
*/
36643691
val constrApp: () => Tree = () =>
3665-
val t = constrOrSimpleType()
3692+
constrAppRest(constrOrSimpleType())
3693+
3694+
def constrAppRest(t: Tree): Tree =
36663695
if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t
36673696

36683697
/** ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp}

0 commit comments

Comments
 (0)