@@ -948,19 +948,31 @@ object Parsers {
948
948
* i.e. an identifier followed by type and value parameters, followed by `:`?
949
949
* @pre The current token is an identifier
950
950
*/
951
- def followingIsGivenSig () =
951
+ def followingIsOldStyleGivenSig () =
952
952
val lookahead = in.LookaheadScanner ()
953
953
if lookahead.isIdent then
954
954
lookahead.nextToken()
955
+ var paramsSeen = false
955
956
def skipParams (): Unit =
956
957
if lookahead.token == LPAREN || lookahead.token == LBRACKET then
958
+ paramsSeen = true
957
959
lookahead.skipParens()
958
960
skipParams()
959
961
else if lookahead.isNewLine then
960
962
lookahead.nextToken()
961
963
skipParams()
962
964
skipParams()
963
965
lookahead.isColon
966
+ && {
967
+ ! in.featureEnabled(Feature .modularity)
968
+ || { // with modularity language import, a `:` at EOL after an identifier represents a single identifier given
969
+ // Example:
970
+ // given C:
971
+ // def f = ...
972
+ lookahead.nextToken()
973
+ ! lookahead.isAfterLineEnd
974
+ }
975
+ }
964
976
965
977
def followingIsExtension () =
966
978
val next = in.lookahead.token
@@ -1773,7 +1785,9 @@ object Parsers {
1773
1785
1774
1786
def infixTypeRest (t : Tree , operand : Location => Tree = refinedTypeFn): Tree =
1775
1787
infixOps(t, canStartInfixTypeTokens, operand, Location .ElseWhere , ParseKind .Type ,
1776
- isOperator = ! followingIsVararg() && ! isPureArrow
1788
+ isOperator = ! followingIsVararg()
1789
+ && ! isPureArrow
1790
+ && ! (isIdent(nme.as) && in.featureEnabled(Feature .modularity))
1777
1791
&& nextCanFollowOperator(canStartInfixTypeTokens))
1778
1792
1779
1793
/** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet]
@@ -4059,15 +4073,30 @@ object Parsers {
4059
4073
syntaxError(em " extension clause can only define methods " , stat.span)
4060
4074
}
4061
4075
4062
- /** GivenDef ::= [GivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
4063
- * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4064
- * GivenType ::= AnnotType1 {id [nl] AnnotType1}
4076
+ /** GivenDef ::= OldGivenDef | NewGivenDef
4077
+ * OldGivenDef ::= [OldGivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
4078
+ * OldGivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4065
4079
* StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ WithTemplateBody]
4080
+ *
4081
+ * NewGivenDef ::= [GivenConditional '=>'] NewGivenSig
4082
+ * GivenConditional ::= [DefTypeParamClause | UsingParamClause] {UsingParamClause}
4083
+ * NewGivenSig ::= GivenType ['as' id] ([‘=’ Expr] | TemplateBody)
4084
+ * | ConstrApps ['as' id] TemplateBody
4085
+ *
4086
+ * GivenType ::= AnnotType1 {id [nl] AnnotType1}
4066
4087
*/
4067
4088
def givenDef (start : Offset , mods : Modifiers , givenMod : Mod ) = atSpan(start, nameStart) {
4068
4089
var mods1 = addMod(mods, givenMod)
4069
4090
val nameStart = in.offset
4070
- val name = if isIdent && followingIsGivenSig() then ident() else EmptyTermName
4091
+ var name = if isIdent && followingIsOldStyleGivenSig() then ident() else EmptyTermName
4092
+ var newSyntaxAllowed = in.featureEnabled(Feature .modularity)
4093
+
4094
+ def moreConstrApps () =
4095
+ if newSyntaxAllowed && in.token == COMMA then
4096
+ in.nextToken()
4097
+ constrApps()
4098
+ else // need to be careful with last `with`
4099
+ withConstrApps()
4071
4100
4072
4101
// TODO Change syntax description
4073
4102
def adjustDefParams (paramss : List [ParamClause ]): List [ParamClause ] =
@@ -4086,14 +4115,24 @@ object Parsers {
4086
4115
else Nil
4087
4116
newLinesOpt()
4088
4117
val noParams = tparams.isEmpty && vparamss.isEmpty
4089
- if ! (name.isEmpty && noParams) then acceptColon()
4118
+ if ! (name.isEmpty && noParams) then
4119
+ if in.isColon then
4120
+ newSyntaxAllowed = false
4121
+ in.nextToken()
4122
+ else if newSyntaxAllowed then accept(ARROW )
4123
+ else acceptColon()
4090
4124
val parents =
4091
4125
if isSimpleLiteral then
4092
4126
rejectWildcardType(annotType()) :: Nil
4093
4127
else constrApp() match
4094
- case parent : Apply => parent :: withConstrApps()
4095
- case parent if in.isIdent => infixTypeRest(parent, _ => annotType1()) :: Nil
4096
- case parent => parent :: withConstrApps()
4128
+ case parent : Apply => parent :: moreConstrApps()
4129
+ case parent if in.isIdent =>
4130
+ infixTypeRest(parent, _ => annotType1()) :: Nil
4131
+ case parent => parent :: moreConstrApps()
4132
+ if newSyntaxAllowed && in.isIdent(nme.as) then
4133
+ in.nextToken()
4134
+ name = ident()
4135
+
4097
4136
val parentsIsType = parents.length == 1 && parents.head.isType
4098
4137
if in.token == EQUALS && parentsIsType then
4099
4138
accept(EQUALS )
@@ -4103,7 +4142,7 @@ object Parsers {
4103
4142
ValDef (name, parents.head, subExpr())
4104
4143
else
4105
4144
DefDef (name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, subExpr())
4106
- else if (isStatSep || isStatSeqEnd) && parentsIsType then
4145
+ else if (isStatSep || isStatSeqEnd) && parentsIsType && ! newSyntaxAllowed then
4107
4146
if name.isEmpty then
4108
4147
syntaxError(em " anonymous given cannot be abstract " )
4109
4148
DefDef (name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, EmptyTree )
@@ -4114,8 +4153,13 @@ object Parsers {
4114
4153
else vparam
4115
4154
val constr = makeConstructor(tparams, vparamss1)
4116
4155
val templ =
4117
- if isStatSep || isStatSeqEnd then Template (constr, parents, Nil , EmptyValDef , Nil )
4118
- else withTemplate(constr, parents)
4156
+ if isStatSep || isStatSeqEnd then
4157
+ Template (constr, parents, Nil , EmptyValDef , Nil )
4158
+ else if ! newSyntaxAllowed || in.token == WITH then
4159
+ withTemplate(constr, parents)
4160
+ else
4161
+ possibleTemplateStart()
4162
+ templateBodyOpt(constr, parents, Nil )
4119
4163
if noParams && ! mods.is(Inline ) then ModuleDef (name, templ)
4120
4164
else TypeDef (name.toTypeName, templ)
4121
4165
end gdef
0 commit comments