@@ -146,6 +146,7 @@ object Parsers {
146
146
def isNumericLit = numericLitTokens contains in.token
147
147
def isModifier = modifierTokens contains in.token
148
148
def isExprIntro = canStartExpressionTokens contains in.token
149
+ def isBindingIntro = canStartBindingTokens contains in.token
149
150
def isTemplateIntro = templateIntroTokens contains in.token
150
151
def isDclIntro = dclIntroTokens contains in.token
151
152
def isStatSeqEnd = in.token == RBRACE || in.token == EOF
@@ -947,14 +948,14 @@ object Parsers {
947
948
}
948
949
}
949
950
950
- /** Expr ::= FunParams `=>' Expr
951
+ /** Expr ::= [`implicit'] FunParams `=>' Expr
951
952
* | Expr1
952
953
* FunParams ::= Bindings
953
- * | [`implicit'] Id
954
+ * | Id
954
955
* | `_'
955
956
* ExprInParens ::= PostfixExpr `:' Type
956
957
* | Expr
957
- * BlockResult ::= (FunParams | [`implicit'] Id `:' InfixType) => Block
958
+ * BlockResult ::= [`implicit'] FunParams `=>' Block
958
959
* | Expr1
959
960
* Expr1 ::= `if' `(' Expr `)' {nl} Expr [[semi] else Expr]
960
961
* | `if' Expr `then' Expr [[semi] else Expr]
@@ -981,22 +982,27 @@ object Parsers {
981
982
def expr (): Tree = expr(Location .ElseWhere )
982
983
983
984
def expr (location : Location .Value ): Tree = {
984
- val saved = placeholderParams
985
- placeholderParams = Nil
986
- val t = expr1(location)
987
- if (in.token == ARROW ) {
988
- placeholderParams = saved
989
- closureRest(startOffset(t), location, convertToParams(t))
990
- }
991
- else if (isWildcard(t)) {
992
- placeholderParams = placeholderParams ::: saved
993
- t
985
+ val start = in.offset
986
+ if (in.token == IMPLICIT )
987
+ implicitClosure(start, location, implicitMods())
988
+ else {
989
+ val saved = placeholderParams
990
+ placeholderParams = Nil
991
+ val t = expr1(location)
992
+ if (in.token == ARROW ) {
993
+ placeholderParams = saved
994
+ closureRest(start, location, convertToParams(t))
995
+ }
996
+ else if (isWildcard(t)) {
997
+ placeholderParams = placeholderParams ::: saved
998
+ t
999
+ }
1000
+ else
1001
+ try
1002
+ if (placeholderParams.isEmpty) t
1003
+ else new WildcardFunction (placeholderParams.reverse, t)
1004
+ finally placeholderParams = saved
994
1005
}
995
- else
996
- try
997
- if (placeholderParams.isEmpty) t
998
- else new WildcardFunction (placeholderParams.reverse, t)
999
- finally placeholderParams = saved
1000
1006
}
1001
1007
1002
1008
def expr1 (location : Location .Value = Location .ElseWhere ): Tree = in.token match {
@@ -1062,8 +1068,6 @@ object Parsers {
1062
1068
atPos(in.skipToken()) { Return (if (isExprIntro) expr() else EmptyTree , EmptyTree ) }
1063
1069
case FOR =>
1064
1070
forExpr()
1065
- case IMPLICIT =>
1066
- implicitClosure(in.offset, location, atPos(in.skipToken()) { Mod .Implicit () })
1067
1071
case _ =>
1068
1072
expr1Rest(postfixExpr(), location)
1069
1073
}
@@ -1111,19 +1115,43 @@ object Parsers {
1111
1115
}
1112
1116
}
1113
1117
1118
+ /** FunParams ::= Bindings
1119
+ * | Id
1120
+ * | `_'
1121
+ * Bindings ::= `(' [Binding {`,' Binding}] `)'
1122
+ */
1123
+ def funParams (mods : Modifiers , location : Location .Value ): List [Tree ] =
1124
+ if (in.token == LPAREN )
1125
+ inParens(if (in.token == RPAREN ) Nil else commaSeparated(() => binding(mods)))
1126
+ else {
1127
+ val start = in.offset
1128
+ val name = bindingName()
1129
+ val t =
1130
+ if (in.token == COLON && location == Location .InBlock ) {
1131
+ in.nextToken()
1132
+ infixType()
1133
+ }
1134
+ else TypeTree ()
1135
+ (atPos(start) { makeParameter(name, t, mods) }) :: Nil
1136
+ }
1137
+
1138
+ /** Binding ::= (Id | `_') [`:' Type]
1139
+ */
1140
+ def binding (mods : Modifiers ): Tree =
1141
+ atPos(in.offset) { makeParameter(bindingName(), typedOpt(), mods) }
1142
+
1143
+ def bindingName (): TermName =
1144
+ if (in.token == USCORE ) {
1145
+ in.nextToken()
1146
+ ctx.freshName(nme.USCORE_PARAM_PREFIX ).toTermName
1147
+ }
1148
+ else ident()
1149
+
1114
1150
/** Expr ::= implicit Id `=>' Expr
1115
- * BlockResult ::= implicit Id [`:' InfixType] `=>' Block
1116
- */
1117
- def implicitClosure (start : Int , location : Location .Value , implicitMod : Mod ): Tree = {
1118
- val mods = Modifiers (Implicit ).withAddedMod(implicitMod)
1119
- val id = termIdent()
1120
- val paramExpr =
1121
- if (location == Location .InBlock && in.token == COLON )
1122
- atPos(startOffset(id), in.skipToken()) { Typed (id, infixType()) }
1123
- else
1124
- id
1125
- closureRest(start, location, convertToParam(paramExpr, mods) :: Nil )
1126
- }
1151
+ * BlockResult ::= implicit Id [`:' InfixType] `=>' Block // Scala2 only
1152
+ */
1153
+ def implicitClosure (start : Int , location : Location .Value , implicitMods : Modifiers ): Tree =
1154
+ closureRest(start, location, funParams(implicitMods, location))
1127
1155
1128
1156
def closureRest (start : Int , location : Location .Value , params : List [Tree ]): Tree =
1129
1157
atPos(start, in.offset) {
@@ -1577,6 +1605,9 @@ object Parsers {
1577
1605
normalize(loop(start))
1578
1606
}
1579
1607
1608
+ def implicitMods (): Modifiers =
1609
+ addMod(EmptyModifiers , atPos(accept(IMPLICIT )) { Mod .Implicit () })
1610
+
1580
1611
/** Wrap annotation or constructor in New(...).<init> */
1581
1612
def wrapNew (tpt : Tree ) = Select (New (tpt), nme.CONSTRUCTOR )
1582
1613
@@ -1682,9 +1713,9 @@ object Parsers {
1682
1713
* Param ::= id `:' ParamType [`=' Expr]
1683
1714
*/
1684
1715
def paramClauses (owner : Name , ofCaseClass : Boolean = false ): List [List [ValDef ]] = {
1685
- var implicitMod : Mod = null
1686
- var firstClauseOfCaseClass = ofCaseClass
1716
+ var imods : Modifiers = EmptyModifiers
1687
1717
var implicitOffset = - 1 // use once
1718
+ var firstClauseOfCaseClass = ofCaseClass
1688
1719
def param (): ValDef = {
1689
1720
val start = in.offset
1690
1721
var mods = annotsAsMods()
@@ -1719,7 +1750,7 @@ object Parsers {
1719
1750
if (in.token == ARROW ) {
1720
1751
if (owner.isTypeName && ! (mods is Local ))
1721
1752
syntaxError(s " ${if (mods is Mutable ) " `var'" else " `val'" } parameters may not be call-by-name " )
1722
- else if (implicitMod != null )
1753
+ else if (imods.hasFlags )
1723
1754
syntaxError(" implicit parameters may not be call-by-name" )
1724
1755
}
1725
1756
paramType()
@@ -1731,7 +1762,7 @@ object Parsers {
1731
1762
mods = mods.withPos(mods.pos.union(Position (implicitOffset, implicitOffset)))
1732
1763
implicitOffset = - 1
1733
1764
}
1734
- if (implicitMod != null ) mods = addMod(mods, implicitMod )
1765
+ for (imod <- imods.mods ) mods = addMod(mods, imod )
1735
1766
ValDef (name, tpt, default).withMods(mods)
1736
1767
}
1737
1768
}
@@ -1740,7 +1771,7 @@ object Parsers {
1740
1771
else {
1741
1772
if (in.token == IMPLICIT ) {
1742
1773
implicitOffset = in.offset
1743
- implicitMod = atPos(in.skipToken()) { Mod . Implicit () }
1774
+ imods = implicitMods()
1744
1775
}
1745
1776
commaSeparated(param)
1746
1777
}
@@ -1750,7 +1781,7 @@ object Parsers {
1750
1781
if (in.token == LPAREN )
1751
1782
paramClause() :: {
1752
1783
firstClauseOfCaseClass = false
1753
- if (implicitMod == null ) clauses() else Nil
1784
+ if (imods.hasFlags) Nil else clauses()
1754
1785
}
1755
1786
else Nil
1756
1787
}
@@ -2213,9 +2244,9 @@ object Parsers {
2213
2244
stats.toList
2214
2245
}
2215
2246
2216
- def localDef (start : Int , implicitMod : Option [ Mod ] = None ): Tree = {
2247
+ def localDef (start : Int , implicitMods : Modifiers = EmptyModifiers ): Tree = {
2217
2248
var mods = defAnnotsMods(localModifierTokens)
2218
- for (imod <- implicitMod ) mods = (mods | ImplicitCommon ).withAddedMod( imod)
2249
+ for (imod <- implicitMods.mods ) mods = addMod (mods, imod)
2219
2250
defOrDcl(start, mods)
2220
2251
}
2221
2252
@@ -2238,9 +2269,9 @@ object Parsers {
2238
2269
else if (isDefIntro(localModifierTokens))
2239
2270
if (in.token == IMPLICIT ) {
2240
2271
val start = in.offset
2241
- val mod = atPos(in.skipToken()) { Mod . Implicit () }
2242
- if (isIdent ) stats += implicitClosure(start, Location .InBlock , mod )
2243
- else stats += localDef(start, Some (mod) )
2272
+ val imods = implicitMods()
2273
+ if (isBindingIntro ) stats += implicitClosure(start, Location .InBlock , imods )
2274
+ else stats += localDef(start, imods )
2244
2275
} else {
2245
2276
stats += localDef(in.offset)
2246
2277
}
0 commit comments