@@ -911,11 +911,14 @@ object Parsers {
911
911
912
912
/** Are the next tokens a prefix of a formal parameter or given type?
913
913
* @pre: current token is LPAREN
914
+ * TODO: Drop once syntax has stabilized
914
915
*/
915
916
def followingIsParamOrGivenType () =
916
917
val lookahead = in.LookaheadScanner ()
917
918
lookahead.nextToken()
918
- if startParamOrGivenTypeTokens.contains(lookahead.token) then true
919
+ if startParamOrGivenTypeTokens.contains(lookahead.token)
920
+ || lookahead.isIdent(nme.using)
921
+ then true
919
922
else if lookahead.token == IDENTIFIER then
920
923
if lookahead.name == nme.inline then
921
924
lookahead.nextToken()
@@ -944,7 +947,6 @@ object Parsers {
944
947
else
945
948
lookahead.token == SUBTYPE // TODO: remove
946
949
|| lookahead.isIdent(nme.as)
947
- || lookahead.token == WITH && lookahead.ch != Chars .LF // TODO: remove LF test
948
950
949
951
def followingIsExtension () =
950
952
val lookahead = in.LookaheadScanner ()
@@ -1344,8 +1346,8 @@ object Parsers {
1344
1346
* MonoFunType ::= FunArgTypes (‘=>’ | ‘?=>’) Type
1345
1347
* PolyFunType ::= HKTypeParamClause '=>' Type
1346
1348
* FunArgTypes ::= InfixType
1347
- * | `(' [ [ ‘['erased'] FunArgType {`,' FunArgType } ] `)'
1348
- * | '(' [ ‘['erased'] TypedFunParam {',' TypedFunParam } ')'
1349
+ * | `(' [ [ ‘[using]’ ‘[ 'erased'] FunArgType {`,' FunArgType } ] `)'
1350
+ * | '(' [ ‘[using]’ ‘[ 'erased'] TypedFunParam {',' TypedFunParam } ')'
1349
1351
*/
1350
1352
def typ (): Tree = {
1351
1353
val start = in.offset
@@ -2184,7 +2186,6 @@ object Parsers {
2184
2186
* | SimpleExpr `.' MatchClause
2185
2187
* | SimpleExpr (TypeArgs | NamedTypeArgs)
2186
2188
* | SimpleExpr1 ArgumentExprs
2187
- * | SimpleExpr ContextArguments
2188
2189
* Quoted ::= ‘'’ ‘{’ Block ‘}’
2189
2190
* | ‘'’ ‘[’ Type ‘]’
2190
2191
*/
@@ -2253,8 +2254,6 @@ object Parsers {
2253
2254
case DOT =>
2254
2255
in.nextToken()
2255
2256
simpleExprRest(selector(t), canApply = true )
2256
- case DOTWITH =>
2257
- simpleExprRest(contextArguments(t), canApply = true )
2258
2257
case LBRACKET =>
2259
2258
val tapp = atSpan(startOffset(t), in.offset) { TypeApply (t, typeArgs(namedOK = true , wildOK = false )) }
2260
2259
simpleExprRest(tapp, canApply = true )
@@ -2294,13 +2293,13 @@ object Parsers {
2294
2293
def exprsInParensOpt (): List [Tree ] =
2295
2294
if (in.token == RPAREN ) Nil else commaSeparated(exprInParens)
2296
2295
2297
- /** ParArgumentExprs ::= `(' [‘given ’] [ExprsInParens] `)'
2296
+ /** ParArgumentExprs ::= `(' [‘using ’] [ExprsInParens] `)'
2298
2297
* | `(' [ExprsInParens `,'] PostfixExpr `:' `_' `*' ')'
2299
2298
*/
2300
2299
def parArgumentExprs (): (List [Tree ], Boolean ) = inParens {
2301
2300
if in.token == RPAREN then
2302
2301
(Nil , false )
2303
- else if in.token == GIVEN then
2302
+ else if in.token == GIVEN || isIdent(nme.using) then
2304
2303
in.nextToken()
2305
2304
(commaSeparated(argumentExpr), true )
2306
2305
else
@@ -2331,7 +2330,7 @@ object Parsers {
2331
2330
else fn
2332
2331
}
2333
2332
2334
- /** ParArgumentExprss ::= {ParArgumentExprs | ContextArguments }
2333
+ /** ParArgumentExprss ::= {ParArgumentExprs}
2335
2334
*
2336
2335
* Special treatment for arguments to primary constructor annotations.
2337
2336
* (...) is considered an argument only if it does not look like a formal
@@ -2356,8 +2355,6 @@ object Parsers {
2356
2355
parArgumentExprss(
2357
2356
atSpan(startOffset(fn)) { mkApply(fn, parArgumentExprs()) }
2358
2357
)
2359
- else if in.token == DOTWITH then
2360
- parArgumentExprss(contextArguments(fn))
2361
2358
else fn
2362
2359
}
2363
2360
@@ -2387,14 +2384,6 @@ object Parsers {
2387
2384
else Block (stats, EmptyTree )
2388
2385
}
2389
2386
2390
- /** ContextArguments ::= ‘.’ ‘with’ ArgumentExprs */
2391
- def contextArguments (t : Tree ): Tree =
2392
- if in.token == DOTWITH then
2393
- atSpan(t.span.start, in.skipToken()) {
2394
- Apply (t, argumentExprs()._1).setGivenApply()
2395
- }
2396
- else t
2397
-
2398
2387
/** Guard ::= if PostfixExpr
2399
2388
*/
2400
2389
def guard (): Tree =
@@ -2886,23 +2875,22 @@ object Parsers {
2886
2875
def typeParamClauseOpt (ownerKind : ParamOwner .Value ): List [TypeDef ] =
2887
2876
if (in.token == LBRACKET ) typeParamClause(ownerKind) else Nil
2888
2877
2889
- /** AnnotTypes ::= AnnotType {‘,’ AnnotType}
2890
- * Types ::= Type {‘,’ Type}
2878
+ /** ContextTypes ::= Type {‘,’ Type}
2891
2879
*/
2892
- def givenTypes ( parseType : () => Tree , nparams : Int , ofClass : Boolean ): List [ValDef ] =
2893
- val tps = commaSeparated(parseType )
2880
+ def contextTypes ( ofClass : Boolean , nparams : Int ): List [ValDef ] =
2881
+ val tps = commaSeparated(typ )
2894
2882
var counter = nparams
2895
2883
def nextIdx = { counter += 1 ; counter }
2896
2884
val paramFlags = if ofClass then Private | Local | ParamAccessor else Param
2897
2885
tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | Given ))
2898
2886
2899
- /** ClsParamClause ::= ‘(’ [‘erased’] ClsParams ‘)’
2900
- * GivenClsParamClause ::= 'with' ( ‘(’ (ClsParams | Types ) ‘)’ | AnnotTypes)
2887
+ /** ClsParamClause ::= ‘(’ [‘erased’] ClsParams ‘)’ | UsingClsParamClause
2888
+ * UsingClsParamClause ::= ‘(’ ‘using’ [‘erased’] (ClsParams | ContextTypes ) ‘)’
2901
2889
* ClsParams ::= ClsParam {‘,’ ClsParam}
2902
2890
* ClsParam ::= {Annotation}
2903
2891
*
2904
- * DefParamClause ::= ‘(’ [‘erased’] DefParams ‘)’
2905
- * GivenParamClause ::= ‘with’ (‘(’ (DefParams | Types ) ‘)’ | AnnotTypes)
2892
+ * DefParamClause ::= ‘(’ [‘erased’] DefParams ‘)’ | UsingParamClause
2893
+ * UsingParamClause ::= ‘(’ ‘using’ [‘erased’] (DefParams | ContextTypes ) ‘)’
2906
2894
* DefParams ::= DefParam {‘,’ DefParam}
2907
2895
* DefParam ::= {Annotation} [‘inline’] Param
2908
2896
*
@@ -2915,17 +2903,17 @@ object Parsers {
2915
2903
ofCaseClass : Boolean = false , // owner is a case class
2916
2904
prefix : Boolean = false , // clause precedes name of an extension method
2917
2905
givenOnly : Boolean = false , // only given parameters allowed
2918
- firstClause : Boolean = false , // clause is the first in regular list of clauses
2919
- prefixMods : Modifiers = EmptyModifiers // is `Given` if this is a with clause
2906
+ firstClause : Boolean = false // clause is the first in regular list of clauses
2920
2907
): List [ValDef ] = {
2921
- var impliedMods : Modifiers = prefixMods
2908
+ var impliedMods : Modifiers = EmptyModifiers
2922
2909
2923
- def impliedModOpt ( token : Token , mod : () => Mod ): Boolean =
2924
- if in.token == token then
2925
- impliedMods = addMod(impliedMods, atSpan(in.skipToken()) { mod() })
2926
- true
2910
+ def addParamMod ( mod : () => Mod ) = impliedMods = addMod(impliedMods, atSpan(in.skipToken()) { mod() })
2911
+
2912
+ def paramMods () =
2913
+ if in.token == IMPLICIT then addParamMod(() => Mod . Implicit ())
2927
2914
else
2928
- false
2915
+ if in.token == GIVEN || isIdent(nme.using) then addParamMod(() => Mod .Given ())
2916
+ if in.token == ERASED then addParamMod(() => Mod .Erased ())
2929
2917
2930
2918
def param (): ValDef = {
2931
2919
val start = in.offset
@@ -2984,32 +2972,22 @@ object Parsers {
2984
2972
val clause =
2985
2973
if prefix then param() :: Nil
2986
2974
else
2987
- if ! impliedModOpt(IMPLICIT , () => Mod .Implicit ()) then
2988
- impliedModOpt(GIVEN , () => Mod .Given ())
2989
- impliedModOpt(ERASED , () => Mod .Erased ())
2975
+ paramMods()
2990
2976
if givenOnly && ! impliedMods.is(Given ) then
2991
- syntaxError(" Normal parameter clause cannot follow context parameter clause " )
2977
+ syntaxError(" `using` expected " )
2992
2978
val isParams =
2993
2979
! impliedMods.is(Given )
2994
2980
|| startParamTokens.contains(in.token)
2995
2981
|| isIdent && (in.name == nme.inline || in.lookaheadIn(BitSet (COLON )))
2996
2982
if isParams then commaSeparated(() => param())
2997
- else givenTypes(typ , nparams, ofClass )
2983
+ else contextTypes(ofClass , nparams)
2998
2984
checkVarArgsRules(clause)
2999
2985
clause
3000
2986
}
3001
2987
}
3002
2988
3003
2989
/** ClsParamClauses ::= {ClsParamClause} [[nl] ‘(’ [‘implicit’] ClsParams ‘)’]
3004
- * | ClsParamClause ClsParamClauses
3005
- * | ClsParamClauses1
3006
- * ClsParamClauses1 ::= WithClsParamClause ClsParamClauses
3007
- * | AnnotTypes ClsParamClauses1ClsParamClauses
3008
2990
* DefParamClauses ::= {DefParamClause} [[nl] ‘(’ [‘implicit’] DefParams ‘)’]
3009
- * | DefParamClause DefParamClauses
3010
- * | DefParamClauses1
3011
- * DefParamClauses1 ::= WithCaramClause DefParamClauses
3012
- * | AnnotTypes DeParamClauses1
3013
2991
*
3014
2992
* @return The parameter definitions
3015
2993
*/
@@ -3019,33 +2997,18 @@ object Parsers {
3019
2997
3020
2998
def recur (firstClause : Boolean , nparams : Int ): List [List [ValDef ]] =
3021
2999
newLineOptWhenFollowedBy(LPAREN )
3022
- val prefixMods =
3023
- if in.token == WITH && in.ch != Chars .LF then // TODO: remove LF test
3024
- in.nextToken()
3025
- Modifiers (Given )
3026
- else
3027
- EmptyModifiers
3028
3000
if in.token == LPAREN then
3029
3001
val paramsStart = in.offset
3030
3002
val params = paramClause(
3031
3003
nparams,
3032
3004
ofClass = ofClass,
3033
3005
ofCaseClass = ofCaseClass,
3034
3006
givenOnly = givenOnly,
3035
- firstClause = firstClause,
3036
- prefixMods = prefixMods)
3007
+ firstClause = firstClause)
3037
3008
val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
3038
- val isGivenClause = prefixMods.is(Given )
3039
- || params.nonEmpty && params.head.mods.flags.is(Given )
3040
3009
params :: (
3041
3010
if lastClause then Nil
3042
3011
else recur(firstClause = false , nparams + params.length))
3043
- else if prefixMods.is(Given ) then
3044
- val params = givenTypes(annotType, nparams, ofClass)
3045
- params :: (
3046
- if in.token == WITH then recur(firstClause = false , nparams + params.length)
3047
- else Nil
3048
- )
3049
3012
else Nil
3050
3013
end recur
3051
3014
@@ -3090,8 +3053,8 @@ object Parsers {
3090
3053
3091
3054
/** ImportSelectors ::= id [‘=>’ id | ‘=>’ ‘_’] [‘,’ ImportSelectors]
3092
3055
* | WildCardSelector {‘,’ WildCardSelector}
3093
- * WildCardSelector ::= ‘given’ [ InfixType]
3094
- * | ‘_' [‘:’ InfixType]
3056
+ * WildCardSelector ::= ‘given’ (‘_' | InfixType)
3057
+ * | ‘_'
3095
3058
*/
3096
3059
def importSelectors (idOK : Boolean ): List [ImportSelector ] =
3097
3060
val selToken = in.token
@@ -3543,10 +3506,7 @@ object Parsers {
3543
3506
3544
3507
/** GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr
3545
3508
* | [GivenSig] ConstrApps [TemplateBody]
3546
- * GivenSig ::= [id] [DefTypeParamClause] {WithParamsOrTypes} ‘as’
3547
- * ExtParamClause ::= [DefTypeParamClause] DefParamClause
3548
- * ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
3549
- * WithParamsOrTypes ::= WithParamClause | AnnotTypes
3509
+ * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’
3550
3510
*/
3551
3511
def givenDef (start : Offset , mods : Modifiers , instanceMod : Mod ) = atSpan(start, nameStart) {
3552
3512
var mods1 = addMod(mods, instanceMod)
@@ -3571,18 +3531,17 @@ object Parsers {
3571
3531
templ.body.foreach(checkExtensionMethod(tparams, _))
3572
3532
ModuleDef (name, templ)
3573
3533
else
3574
- val hasLabel = ! name.isEmpty && in.token == COLON || in. isIdent(nme.as)
3534
+ val hasLabel = ! name.isEmpty && in.token == COLON || isIdent(nme.as)
3575
3535
if hasLabel then in.nextToken()
3576
3536
val tparams = typeParamClauseOpt(ParamOwner .Def )
3577
3537
val paramsStart = in.offset
3578
3538
val vparamss =
3579
- if in.token == WITH && in.ch != Chars .LF // TODO: remove LF test
3580
- || in.token == LPAREN && followingIsParamOrGivenType()
3539
+ if in.token == LPAREN && followingIsParamOrGivenType()
3581
3540
then paramClauses()
3582
3541
else Nil
3583
3542
def checkAllGivens (vparamss : List [List [ValDef ]], what : String ) =
3584
3543
vparamss.foreach(_.foreach(vparam =>
3585
- if ! vparam.mods.is(Given ) then syntaxError(em " $what must be `given ` " , vparam.span)))
3544
+ if ! vparam.mods.is(Given ) then syntaxError(em " $what must be preceded by `using ` " , vparam.span)))
3586
3545
checkAllGivens(vparamss, " parameter of given instance" )
3587
3546
val parents =
3588
3547
if in.token == SUBTYPE && ! hasLabel then
@@ -3620,7 +3579,7 @@ object Parsers {
3620
3579
finalizeDef(gdef, mods1, start)
3621
3580
}
3622
3581
3623
- /** ExtensionDef ::= [id] ‘on’ ExtParamClause GivenParamClauses ExtMethods
3582
+ /** ExtensionDef ::= [id] ‘on’ ExtParamClause {UsingParamClause} ExtMethods
3624
3583
*/
3625
3584
def extensionDef (start : Offset , mods : Modifiers ): ModuleDef =
3626
3585
in.nextToken()
@@ -3644,8 +3603,7 @@ object Parsers {
3644
3603
val constrApp : () => Tree = () => {
3645
3604
val t = rejectWildcardType(annotType(), fallbackTree = Ident (nme.ERROR ))
3646
3605
// Using Ident(nme.ERROR) to avoid causing cascade errors on non-user-written code
3647
- if in.token == LPAREN || in.token == DOTWITH then parArgumentExprss(wrapNew(t))
3648
- else t
3606
+ if in.token == LPAREN then parArgumentExprss(wrapNew(t)) else t
3649
3607
}
3650
3608
3651
3609
/** ConstrApps ::= ConstrApp {(‘,’ | ‘with’) ConstrApp}
0 commit comments