@@ -976,19 +976,31 @@ object Parsers {
976
976
* i.e. an identifier followed by type and value parameters, followed by `:`?
977
977
* @pre The current token is an identifier
978
978
*/
979
- def followingIsGivenSig () =
979
+ def followingIsOldStyleGivenSig () =
980
980
val lookahead = in.LookaheadScanner ()
981
981
if lookahead.isIdent then
982
982
lookahead.nextToken()
983
+ var paramsSeen = false
983
984
def skipParams (): Unit =
984
985
if lookahead.token == LPAREN || lookahead.token == LBRACKET then
986
+ paramsSeen = true
985
987
lookahead.skipParens()
986
988
skipParams()
987
989
else if lookahead.isNewLine then
988
990
lookahead.nextToken()
989
991
skipParams()
990
992
skipParams()
991
993
lookahead.isColon
994
+ && {
995
+ ! in.featureEnabled(Feature .modularity)
996
+ || { // with modularity language import, a `:` at EOL after an identifier represents a single identifier given
997
+ // Example:
998
+ // given C:
999
+ // def f = ...
1000
+ lookahead.nextToken()
1001
+ ! lookahead.isAfterLineEnd
1002
+ }
1003
+ }
992
1004
993
1005
def followingIsExtension () =
994
1006
val next = in.lookahead.token
@@ -1808,7 +1820,9 @@ object Parsers {
1808
1820
1809
1821
def infixTypeRest (t : Tree , operand : Location => Tree = refinedTypeFn): Tree =
1810
1822
infixOps(t, canStartInfixTypeTokens, operand, Location .ElseWhere , ParseKind .Type ,
1811
- isOperator = ! followingIsVararg() && ! isPureArrow
1823
+ isOperator = ! followingIsVararg()
1824
+ && ! isPureArrow
1825
+ && ! (isIdent(nme.as) && in.featureEnabled(Feature .modularity))
1812
1826
&& nextCanFollowOperator(canStartInfixTypeTokens))
1813
1827
1814
1828
/** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet]
@@ -4101,15 +4115,30 @@ object Parsers {
4101
4115
syntaxError(em " extension clause can only define methods " , stat.span)
4102
4116
}
4103
4117
4104
- /** GivenDef ::= [GivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
4105
- * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4106
- * GivenType ::= AnnotType1 {id [nl] AnnotType1}
4118
+ /** GivenDef ::= OldGivenDef | NewGivenDef
4119
+ * OldGivenDef ::= [OldGivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
4120
+ * OldGivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4107
4121
* StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ WithTemplateBody]
4122
+ *
4123
+ * NewGivenDef ::= [GivenConditional '=>'] NewGivenSig
4124
+ * GivenConditional ::= [DefTypeParamClause | UsingParamClause] {UsingParamClause}
4125
+ * NewGivenSig ::= GivenType ['as' id] ([‘=’ Expr] | TemplateBody)
4126
+ * | ConstrApps ['as' id] TemplateBody
4127
+ *
4128
+ * GivenType ::= AnnotType1 {id [nl] AnnotType1}
4108
4129
*/
4109
4130
def givenDef (start : Offset , mods : Modifiers , givenMod : Mod ) = atSpan(start, nameStart) {
4110
4131
var mods1 = addMod(mods, givenMod)
4111
4132
val nameStart = in.offset
4112
- val name = if isIdent && followingIsGivenSig() then ident() else EmptyTermName
4133
+ var name = if isIdent && followingIsOldStyleGivenSig() then ident() else EmptyTermName
4134
+ var newSyntaxAllowed = in.featureEnabled(Feature .modularity)
4135
+
4136
+ def moreConstrApps () =
4137
+ if newSyntaxAllowed && in.token == COMMA then
4138
+ in.nextToken()
4139
+ constrApps()
4140
+ else // need to be careful with last `with`
4141
+ withConstrApps()
4113
4142
4114
4143
// TODO Change syntax description
4115
4144
def adjustDefParams (paramss : List [ParamClause ]): List [ParamClause ] =
@@ -4128,14 +4157,24 @@ object Parsers {
4128
4157
else Nil
4129
4158
newLinesOpt()
4130
4159
val noParams = tparams.isEmpty && vparamss.isEmpty
4131
- if ! (name.isEmpty && noParams) then acceptColon()
4160
+ if ! (name.isEmpty && noParams) then
4161
+ if in.isColon then
4162
+ newSyntaxAllowed = false
4163
+ in.nextToken()
4164
+ else if newSyntaxAllowed then accept(ARROW )
4165
+ else acceptColon()
4132
4166
val parents =
4133
4167
if isSimpleLiteral then
4134
4168
rejectWildcardType(annotType()) :: Nil
4135
4169
else constrApp() match
4136
- case parent : Apply => parent :: withConstrApps()
4137
- case parent if in.isIdent => infixTypeRest(parent, _ => annotType1()) :: Nil
4138
- case parent => parent :: withConstrApps()
4170
+ case parent : Apply => parent :: moreConstrApps()
4171
+ case parent if in.isIdent =>
4172
+ infixTypeRest(parent, _ => annotType1()) :: Nil
4173
+ case parent => parent :: moreConstrApps()
4174
+ if newSyntaxAllowed && in.isIdent(nme.as) then
4175
+ in.nextToken()
4176
+ name = ident()
4177
+
4139
4178
val parentsIsType = parents.length == 1 && parents.head.isType
4140
4179
if in.token == EQUALS && parentsIsType then
4141
4180
accept(EQUALS )
@@ -4145,7 +4184,7 @@ object Parsers {
4145
4184
ValDef (name, parents.head, subExpr())
4146
4185
else
4147
4186
DefDef (name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, subExpr())
4148
- else if (isStatSep || isStatSeqEnd) && parentsIsType then
4187
+ else if (isStatSep || isStatSeqEnd) && parentsIsType && ! newSyntaxAllowed then
4149
4188
if name.isEmpty then
4150
4189
syntaxError(em " anonymous given cannot be abstract " )
4151
4190
DefDef (name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, EmptyTree )
@@ -4156,8 +4195,13 @@ object Parsers {
4156
4195
else vparam
4157
4196
val constr = makeConstructor(tparams, vparamss1)
4158
4197
val templ =
4159
- if isStatSep || isStatSeqEnd then Template (constr, parents, Nil , EmptyValDef , Nil )
4160
- else withTemplate(constr, parents)
4198
+ if isStatSep || isStatSeqEnd then
4199
+ Template (constr, parents, Nil , EmptyValDef , Nil )
4200
+ else if ! newSyntaxAllowed || in.token == WITH then
4201
+ withTemplate(constr, parents)
4202
+ else
4203
+ possibleTemplateStart()
4204
+ templateBodyOpt(constr, parents, Nil )
4161
4205
if noParams && ! mods.is(Inline ) then ModuleDef (name, templ)
4162
4206
else TypeDef (name.toTypeName, templ)
4163
4207
end gdef
0 commit comments