@@ -1968,15 +1968,21 @@ object Parsers {
1968
1968
* DefParams ::= DefParam {`,' DefParam}
1969
1969
* DefParam ::= {Annotation} [`inline'] Param
1970
1970
* Param ::= id `:' ParamType [`=' Expr]
1971
- */
1972
- def paramClauses (owner : Name , ofCaseClass : Boolean = false ): List [List [ValDef ]] = {
1973
- var imods : Modifiers = EmptyModifiers
1971
+ *
1972
+ * @return the list of parameter definitions
1973
+ */
1974
+ def paramClause (ofClass : Boolean = false , // owner is a class
1975
+ ofCaseClass : Boolean = false , // owner is a case class
1976
+ ofMethod : Boolean = false , // owner is a method or constructor
1977
+ prefix : Boolean = false , // clause precedes name of an extension method
1978
+ firstClause : Boolean = false ) // clause is the first in regular list of clauses
1979
+ : List [ValDef ] = {
1974
1980
var implicitOffset = - 1 // use once
1975
- var firstClauseOfCaseClass = ofCaseClass
1976
- def param (): ValDef = {
1981
+
1982
+ def param (impliedMods : Modifiers ): ValDef = {
1977
1983
val start = in.offset
1978
- var mods = annotsAsMods( )
1979
- if (owner.isTypeName ) {
1984
+ var mods = impliedMods.withAnnotations(annotations() )
1985
+ if (ofClass ) {
1980
1986
mods = addFlag(modifiers(start = mods), ParamAccessor )
1981
1987
mods =
1982
1988
atPos(start, in.offset) {
@@ -1989,9 +1995,9 @@ object Parsers {
1989
1995
addMod(mods, mod)
1990
1996
}
1991
1997
else {
1992
- if (! (mods.flags &~ (ParamAccessor | Inline )).isEmpty)
1998
+ if (! (mods.flags &~ (ParamAccessor | Inline | impliedMods.flags )).isEmpty)
1993
1999
syntaxError(" `val' or `var' expected" )
1994
- if (firstClauseOfCaseClass ) mods
2000
+ if (firstClause && ofCaseClass ) mods
1995
2001
else mods | PrivateLocal
1996
2002
}
1997
2003
}
@@ -2004,7 +2010,7 @@ object Parsers {
2004
2010
atPos(start, nameStart) {
2005
2011
val name = ident()
2006
2012
accept(COLON )
2007
- if (in.token == ARROW && owner.isTypeName && ! (mods is Local ))
2013
+ if (in.token == ARROW && ofClass && ! (mods is Local ))
2008
2014
syntaxError(VarValParametersMayNotBeCallByName (name, mods is Mutable ))
2009
2015
val tpt = paramType()
2010
2016
val default =
@@ -2014,56 +2020,75 @@ object Parsers {
2014
2020
mods = mods.withPos(mods.pos.union(Position (implicitOffset, implicitOffset)))
2015
2021
implicitOffset = - 1
2016
2022
}
2017
- for (imod <- imods.mods) mods = addMod(mods, imod)
2018
2023
ValDef (name, tpt, default).withMods(mods)
2019
2024
}
2020
2025
}
2021
- def paramClause (): List [ValDef ] = inParens {
2022
- if (in.token == RPAREN ) Nil
2026
+
2027
+ def checkVarArgsRules (vparams : List [ValDef ]): Unit = vparams match {
2028
+ case Nil =>
2029
+ case _ :: Nil if ! prefix =>
2030
+ case vparam :: rest =>
2031
+ vparam.tpt match {
2032
+ case PostfixOp (_, op) if op.name == tpnme.raw.STAR =>
2033
+ syntaxError(VarArgsParamMustComeLast (), vparam.tpt.pos)
2034
+ case _ =>
2035
+ }
2036
+ checkVarArgsRules(rest)
2037
+ }
2038
+
2039
+ // begin paramClause
2040
+ inParens {
2041
+ if (in.token == RPAREN && ! prefix) Nil
2023
2042
else {
2024
- def funArgMods (): Unit = {
2043
+ def funArgMods (mods : Modifiers ): Modifiers =
2025
2044
if (in.token == IMPLICIT ) {
2026
2045
implicitOffset = in.offset
2027
- imods = addMod(imods, atPos(accept(IMPLICIT )) { Mod .Implicit () })
2028
- funArgMods()
2029
- } else if (in.token == ERASED ) {
2030
- imods = addMod(imods, atPos(accept(ERASED )) { Mod .Erased () })
2031
- funArgMods()
2046
+ funArgMods(addMod(mods, atPos(accept(IMPLICIT )) { Mod .Implicit () }))
2032
2047
}
2033
- }
2034
- funArgMods()
2035
-
2036
- commaSeparated(() => param())
2048
+ else if (in.token == ERASED )
2049
+ funArgMods(addMod(mods, atPos(accept(ERASED )) { Mod .Erased () }))
2050
+ else mods
2051
+
2052
+ val paramMods = funArgMods(EmptyModifiers )
2053
+ val clause =
2054
+ if (prefix) param(paramMods) :: Nil
2055
+ else commaSeparated(() => param(paramMods))
2056
+ checkVarArgsRules(clause)
2057
+ clause
2037
2058
}
2038
2059
}
2039
- def clauses (): List [List [ValDef ]] = {
2060
+ }
2061
+
2062
+ /** ClsParamClauses ::= {ClsParamClause}
2063
+ * DefParamClauses ::= {DefParamClause}
2064
+ *
2065
+ * @return The parameter definitions
2066
+ */
2067
+ def paramClauses (ofClass : Boolean = false ,
2068
+ ofCaseClass : Boolean = false ,
2069
+ ofMethod : Boolean = false ): (List [List [ValDef ]]) = {
2070
+ def recur (firstClause : Boolean ): List [List [ValDef ]] = {
2040
2071
newLineOptWhenFollowedBy(LPAREN )
2041
2072
if (in.token == LPAREN ) {
2042
- imods = EmptyModifiers
2043
- paramClause() :: {
2044
- firstClauseOfCaseClass = false
2045
- if (imods is Implicit ) Nil else clauses()
2046
- }
2047
- } else Nil
2048
- }
2049
- val start = in.offset
2050
- val result = clauses()
2051
- if (owner == nme.CONSTRUCTOR && (result.isEmpty || (result.head take 1 exists (_.mods is Implicit )))) {
2052
- in.token match {
2053
- case LBRACKET => syntaxError(" no type parameters allowed here" )
2054
- case EOF => incompleteInputError(AuxConstructorNeedsNonImplicitParameter ())
2055
- case _ => syntaxError(AuxConstructorNeedsNonImplicitParameter (), start)
2073
+ val params = paramClause(
2074
+ ofClass = ofClass,
2075
+ ofCaseClass = ofCaseClass,
2076
+ ofMethod = ofMethod,
2077
+ firstClause = firstClause)
2078
+ val lastClause =
2079
+ params.nonEmpty && params.head.mods.flags.is(Implicit )
2080
+ params :: (if (lastClause) Nil else recur(firstClause = false ))
2056
2081
}
2082
+ else Nil
2057
2083
}
2058
- val listOfErrors = checkVarArgsRules(result)
2059
- listOfErrors.foreach { vparam =>
2060
- syntaxError(VarArgsParamMustComeLast (), vparam.tpt.pos)
2061
- }
2062
- result
2084
+ recur(firstClause = true )
2063
2085
}
2064
2086
2065
2087
/* -------- DEFS ------------------------------------------- */
2066
2088
2089
+ def finalizeDef (md : MemberDef , mods : Modifiers , start : Int ): md.ThisTree [Untyped ] =
2090
+ md.withMods(mods).setComment(in.getDocComment(start))
2091
+
2067
2092
/** Import ::= import ImportExpr {`,' ImportExpr}
2068
2093
*/
2069
2094
def importClause (): List [Tree ] = {
@@ -2189,29 +2214,16 @@ object Parsers {
2189
2214
} else EmptyTree
2190
2215
lhs match {
2191
2216
case (id @ Ident (name : TermName )) :: Nil => {
2192
- ValDef (name, tpt, rhs).withMods( mods).setComment(in.getDocComment( start) )
2217
+ finalizeDef( ValDef (name, tpt, rhs), mods, start)
2193
2218
} case _ =>
2194
2219
PatDef (mods, lhs, tpt, rhs)
2195
2220
}
2196
2221
}
2197
2222
2198
- private def checkVarArgsRules (vparamss : List [List [ValDef ]]): List [ValDef ] = {
2199
- def isVarArgs (tpt : Trees .Tree [Untyped ]): Boolean = tpt match {
2200
- case PostfixOp (_, op) if op.name == tpnme.raw.STAR => true
2201
- case _ => false
2202
- }
2203
-
2204
- vparamss.flatMap { params =>
2205
- if (params.nonEmpty) {
2206
- params.init.filter(valDef => isVarArgs(valDef.tpt))
2207
- } else List ()
2208
- }
2209
- }
2210
-
2211
2223
/** DefDef ::= DefSig [(‘:’ | ‘<:’) Type] ‘=’ Expr
2212
2224
* | this ParamClause ParamClauses `=' ConstrExpr
2213
2225
* DefDcl ::= DefSig `:' Type
2214
- * DefSig ::= id [DefTypeParamClause] ParamClauses
2226
+ * DefSig ::= ‘(’ DefParam ‘)’ [nl] id [DefTypeParamClause] ParamClauses
2215
2227
*/
2216
2228
def defDefOrDcl (start : Offset , mods : Modifiers ): Tree = atPos(start, nameStart) {
2217
2229
def scala2ProcedureSyntax (resultTypeStr : String ) = {
@@ -2225,18 +2237,29 @@ object Parsers {
2225
2237
}
2226
2238
if (in.token == THIS ) {
2227
2239
in.nextToken()
2228
- val vparamss = paramClauses(nme.CONSTRUCTOR )
2240
+ val vparamss = paramClauses()
2241
+ if (vparamss.isEmpty || vparamss.head.take(1 ).exists(_.mods.is(Implicit )))
2242
+ in.token match {
2243
+ case LBRACKET => syntaxError(" no type parameters allowed here" )
2244
+ case EOF => incompleteInputError(AuxConstructorNeedsNonImplicitParameter ())
2245
+ case _ => syntaxError(AuxConstructorNeedsNonImplicitParameter (), nameStart)
2246
+ }
2229
2247
if (in.isScala2Mode) newLineOptWhenFollowedBy(LBRACE )
2230
2248
val rhs = {
2231
2249
if (! (in.token == LBRACE && scala2ProcedureSyntax(" " ))) accept(EQUALS )
2232
2250
atPos(in.offset) { constrExpr() }
2233
2251
}
2234
2252
makeConstructor(Nil , vparamss, rhs).withMods(mods).setComment(in.getDocComment(start))
2235
2253
} else {
2236
- val mods1 = addFlag(mods, Method )
2254
+ val (leadingParamss : List [List [ValDef ]], flags : FlagSet ) =
2255
+ if (in.token == LPAREN )
2256
+ (paramClause(ofMethod = true , prefix = true ) :: Nil , Method | Extension )
2257
+ else
2258
+ (Nil , Method )
2259
+ val mods1 = addFlag(mods, flags)
2237
2260
val name = ident()
2238
2261
val tparams = typeParamClauseOpt(ParamOwner .Def )
2239
- val vparamss = paramClauses(name )
2262
+ val vparamss = leadingParamss ::: paramClauses(ofMethod = true )
2240
2263
var tpt = fromWithinReturnType {
2241
2264
if (in.token == SUBTYPE && mods.is(Inline )) {
2242
2265
in.nextToken()
@@ -2262,7 +2285,7 @@ object Parsers {
2262
2285
accept(EQUALS )
2263
2286
expr()
2264
2287
}
2265
- DefDef (name, tparams, vparamss, tpt, rhs).withMods( mods1).setComment(in.getDocComment( start) )
2288
+ finalizeDef( DefDef (name, tparams, vparamss, tpt, rhs), mods1, start)
2266
2289
}
2267
2290
}
2268
2291
@@ -2302,7 +2325,7 @@ object Parsers {
2302
2325
val name = ident().toTypeName
2303
2326
val tparams = typeParamClauseOpt(ParamOwner .Type )
2304
2327
def makeTypeDef (rhs : Tree ): Tree =
2305
- TypeDef (name, lambdaAbstract(tparams, rhs)).withMods( mods).setComment(in.getDocComment( start) )
2328
+ finalizeDef( TypeDef (name, lambdaAbstract(tparams, rhs)), mods, start)
2306
2329
in.token match {
2307
2330
case EQUALS =>
2308
2331
in.nextToken()
@@ -2355,23 +2378,23 @@ object Parsers {
2355
2378
}
2356
2379
2357
2380
def classDefRest (start : Offset , mods : Modifiers , name : TypeName ): TypeDef = {
2358
- val constr = classConstr(name, isCaseClass = mods is Case )
2381
+ val constr = classConstr(isCaseClass = mods.is( Case ) )
2359
2382
val templ = templateOpt(constr)
2360
- TypeDef (name, templ).withMods( mods).setComment(in.getDocComment( start) )
2383
+ finalizeDef( TypeDef (name, templ), mods, start)
2361
2384
}
2362
2385
2363
2386
/** ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses
2364
2387
*/
2365
- def classConstr (owner : TypeName , isCaseClass : Boolean = false ): DefDef = atPos(in.lastOffset) {
2388
+ def classConstr (isCaseClass : Boolean = false ): DefDef = atPos(in.lastOffset) {
2366
2389
val tparams = typeParamClauseOpt(ParamOwner .Class )
2367
- val cmods = fromWithinClassConstr(constrModsOpt(owner ))
2368
- val vparamss = paramClauses(owner, isCaseClass)
2390
+ val cmods = fromWithinClassConstr(constrModsOpt())
2391
+ val vparamss = paramClauses(ofClass = true , ofCaseClass = isCaseClass)
2369
2392
makeConstructor(tparams, vparamss).withMods(cmods)
2370
2393
}
2371
2394
2372
2395
/** ConstrMods ::= {Annotation} [AccessModifier]
2373
2396
*/
2374
- def constrModsOpt (owner : Name ): Modifiers =
2397
+ def constrModsOpt (): Modifiers =
2375
2398
modifiers(accessModifierTokens, annotsAsMods())
2376
2399
2377
2400
/** ObjectDef ::= id TemplateOpt
@@ -2382,17 +2405,17 @@ object Parsers {
2382
2405
2383
2406
def objectDefRest (start : Offset , mods : Modifiers , name : TermName ): ModuleDef = {
2384
2407
val template = templateOpt(emptyConstructor)
2385
- ModuleDef (name, template).withMods( mods).setComment(in.getDocComment( start) )
2408
+ finalizeDef( ModuleDef (name, template), mods, start)
2386
2409
}
2387
2410
2388
2411
/** EnumDef ::= id ClassConstr [`extends' [ConstrApps]] EnumBody
2389
2412
*/
2390
2413
def enumDef (start : Offset , mods : Modifiers , enumMod : Mod ): TypeDef = atPos(start, nameStart) {
2391
2414
val modName = ident()
2392
2415
val clsName = modName.toTypeName
2393
- val constr = classConstr(clsName )
2416
+ val constr = classConstr()
2394
2417
val impl = templateOpt(constr, isEnum = true )
2395
- TypeDef (clsName, impl).withMods( addMod(mods, enumMod)).setComment(in.getDocComment( start) )
2418
+ finalizeDef( TypeDef (clsName, impl), addMod(mods, enumMod), start)
2396
2419
}
2397
2420
2398
2421
/** EnumCase = `case' (id ClassConstr [`extends' ConstrApps] | ids)
@@ -2416,12 +2439,12 @@ object Parsers {
2416
2439
val caseDef =
2417
2440
if (in.token == LBRACKET || in.token == LPAREN || in.token == AT || isModifier) {
2418
2441
val clsName = id.name.toTypeName
2419
- val constr = classConstr(clsName, isCaseClass = true )
2442
+ val constr = classConstr(isCaseClass = true )
2420
2443
TypeDef (clsName, caseTemplate(constr))
2421
2444
}
2422
2445
else
2423
2446
ModuleDef (id.name.toTermName, caseTemplate(emptyConstructor))
2424
- caseDef.withMods( mods1).setComment(in.getDocComment( start) )
2447
+ finalizeDef(caseDef, mods1, start)
2425
2448
}
2426
2449
}
2427
2450
}
@@ -2564,7 +2587,7 @@ object Parsers {
2564
2587
case Typed (tree @ This (EmptyTypeIdent ), tpt) =>
2565
2588
self = makeSelfDef(nme.WILDCARD , tpt).withPos(first.pos)
2566
2589
case _ =>
2567
- val ValDef (name, tpt, _) = convertToParam(first, expected = " self type clause" )
2590
+ val ValDef (name, tpt, _) = convertToParam(first, EmptyModifiers , " self type clause" )
2568
2591
if (name != nme.ERROR )
2569
2592
self = makeSelfDef(name, tpt).withPos(first.pos)
2570
2593
}
0 commit comments