@@ -968,19 +968,31 @@ object Parsers {
968
968
* i.e. an identifier followed by type and value parameters, followed by `:`?
969
969
* @pre The current token is an identifier
970
970
*/
971
- def followingIsGivenSig () =
971
+ def followingIsOldStyleGivenSig () =
972
972
val lookahead = in.LookaheadScanner ()
973
973
if lookahead.isIdent then
974
974
lookahead.nextToken()
975
+ var paramsSeen = false
975
976
def skipParams (): Unit =
976
977
if lookahead.token == LPAREN || lookahead.token == LBRACKET then
978
+ paramsSeen = true
977
979
lookahead.skipParens()
978
980
skipParams()
979
981
else if lookahead.isNewLine then
980
982
lookahead.nextToken()
981
983
skipParams()
982
984
skipParams()
983
985
lookahead.isColon
986
+ && {
987
+ ! in.featureEnabled(Feature .modularity)
988
+ || { // with modularity language import, a `:` at EOL after an identifier represents a single identifier given
989
+ // Example:
990
+ // given C:
991
+ // def f = ...
992
+ lookahead.nextToken()
993
+ ! lookahead.isAfterLineEnd
994
+ }
995
+ }
984
996
985
997
def followingIsExtension () =
986
998
val next = in.lookahead.token
@@ -1793,7 +1805,9 @@ object Parsers {
1793
1805
1794
1806
def infixTypeRest (t : Tree , operand : Location => Tree = refinedTypeFn): Tree =
1795
1807
infixOps(t, canStartInfixTypeTokens, operand, Location .ElseWhere , ParseKind .Type ,
1796
- isOperator = ! followingIsVararg() && ! isPureArrow
1808
+ isOperator = ! followingIsVararg()
1809
+ && ! isPureArrow
1810
+ && ! (isIdent(nme.as) && in.featureEnabled(Feature .modularity))
1797
1811
&& nextCanFollowOperator(canStartInfixTypeTokens))
1798
1812
1799
1813
/** RefinedType ::= WithType {[nl] Refinement} [`^` CaptureSet]
@@ -4079,15 +4093,30 @@ object Parsers {
4079
4093
syntaxError(em " extension clause can only define methods " , stat.span)
4080
4094
}
4081
4095
4082
- /** GivenDef ::= [GivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
4083
- * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4084
- * GivenType ::= AnnotType1 {id [nl] AnnotType1}
4096
+ /** GivenDef ::= OldGivenDef | NewGivenDef
4097
+ * OldGivenDef ::= [OldGivenSig] (GivenType [‘=’ Expr] | StructuralInstance)
4098
+ * OldGivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘:’
4085
4099
* StructuralInstance ::= ConstrApp {‘with’ ConstrApp} [‘with’ WithTemplateBody]
4100
+ *
4101
+ * NewGivenDef ::= [GivenConditional '=>'] NewGivenSig
4102
+ * GivenConditional ::= [DefTypeParamClause | UsingParamClause] {UsingParamClause}
4103
+ * NewGivenSig ::= GivenType ['as' id] ([‘=’ Expr] | TemplateBody)
4104
+ * | ConstrApps ['as' id] TemplateBody
4105
+ *
4106
+ * GivenType ::= AnnotType1 {id [nl] AnnotType1}
4086
4107
*/
4087
4108
def givenDef (start : Offset , mods : Modifiers , givenMod : Mod ) = atSpan(start, nameStart) {
4088
4109
var mods1 = addMod(mods, givenMod)
4089
4110
val nameStart = in.offset
4090
- val name = if isIdent && followingIsGivenSig() then ident() else EmptyTermName
4111
+ var name = if isIdent && followingIsOldStyleGivenSig() then ident() else EmptyTermName
4112
+ var newSyntaxAllowed = in.featureEnabled(Feature .modularity)
4113
+
4114
+ def moreConstrApps () =
4115
+ if newSyntaxAllowed && in.token == COMMA then
4116
+ in.nextToken()
4117
+ constrApps()
4118
+ else // need to be careful with last `with`
4119
+ withConstrApps()
4091
4120
4092
4121
// TODO Change syntax description
4093
4122
def adjustDefParams (paramss : List [ParamClause ]): List [ParamClause ] =
@@ -4106,14 +4135,24 @@ object Parsers {
4106
4135
else Nil
4107
4136
newLinesOpt()
4108
4137
val noParams = tparams.isEmpty && vparamss.isEmpty
4109
- if ! (name.isEmpty && noParams) then acceptColon()
4138
+ if ! (name.isEmpty && noParams) then
4139
+ if in.isColon then
4140
+ newSyntaxAllowed = false
4141
+ in.nextToken()
4142
+ else if newSyntaxAllowed then accept(ARROW )
4143
+ else acceptColon()
4110
4144
val parents =
4111
4145
if isSimpleLiteral then
4112
4146
rejectWildcardType(annotType()) :: Nil
4113
4147
else constrApp() match
4114
- case parent : Apply => parent :: withConstrApps()
4115
- case parent if in.isIdent => infixTypeRest(parent, _ => annotType1()) :: Nil
4116
- case parent => parent :: withConstrApps()
4148
+ case parent : Apply => parent :: moreConstrApps()
4149
+ case parent if in.isIdent =>
4150
+ infixTypeRest(parent, _ => annotType1()) :: Nil
4151
+ case parent => parent :: moreConstrApps()
4152
+ if newSyntaxAllowed && in.isIdent(nme.as) then
4153
+ in.nextToken()
4154
+ name = ident()
4155
+
4117
4156
val parentsIsType = parents.length == 1 && parents.head.isType
4118
4157
if in.token == EQUALS && parentsIsType then
4119
4158
accept(EQUALS )
@@ -4123,7 +4162,7 @@ object Parsers {
4123
4162
ValDef (name, parents.head, subExpr())
4124
4163
else
4125
4164
DefDef (name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, subExpr())
4126
- else if (isStatSep || isStatSeqEnd) && parentsIsType then
4165
+ else if (isStatSep || isStatSeqEnd) && parentsIsType && ! newSyntaxAllowed then
4127
4166
if name.isEmpty then
4128
4167
syntaxError(em " anonymous given cannot be abstract " )
4129
4168
DefDef (name, adjustDefParams(joinParams(tparams, vparamss)), parents.head, EmptyTree )
@@ -4134,8 +4173,13 @@ object Parsers {
4134
4173
else vparam
4135
4174
val constr = makeConstructor(tparams, vparamss1)
4136
4175
val templ =
4137
- if isStatSep || isStatSeqEnd then Template (constr, parents, Nil , EmptyValDef , Nil )
4138
- else withTemplate(constr, parents)
4176
+ if isStatSep || isStatSeqEnd then
4177
+ Template (constr, parents, Nil , EmptyValDef , Nil )
4178
+ else if ! newSyntaxAllowed || in.token == WITH then
4179
+ withTemplate(constr, parents)
4180
+ else
4181
+ possibleTemplateStart()
4182
+ templateBodyOpt(constr, parents, Nil )
4139
4183
if noParams && ! mods.is(Inline ) then ModuleDef (name, templ)
4140
4184
else TypeDef (name.toTypeName, templ)
4141
4185
end gdef
0 commit comments