@@ -1876,15 +1876,16 @@ object Parsers {
1876
1876
mods1
1877
1877
}
1878
1878
1879
- /** Def ::= val PatDef
1880
- * | var VarDef
1881
- * | def DefDef
1882
- * | type {nl} TypeDcl
1883
- * | TmplDef
1884
- * Dcl ::= val ValDcl
1885
- * | var ValDcl
1886
- * | def DefDcl
1887
- * | type {nl} TypeDcl
1879
+ /** Def ::= val PatDef
1880
+ * | var VarDef
1881
+ * | def DefDef
1882
+ * | type {nl} TypeDcl
1883
+ * | TmplDef
1884
+ * Dcl ::= val ValDcl
1885
+ * | var ValDcl
1886
+ * | def DefDcl
1887
+ * | type {nl} TypeDcl
1888
+ * EnumCase ::= `case' (EnumClassDef | ObjectDef)
1888
1889
*/
1889
1890
def defOrDcl (start : Int , mods : Modifiers ): Tree = in.token match {
1890
1891
case VAL =>
@@ -1899,6 +1900,8 @@ object Parsers {
1899
1900
defDefOrDcl(start, posMods(start, mods), in.getDocComment(start))
1900
1901
case TYPE =>
1901
1902
typeDefOrDcl(start, posMods(start, mods), in.getDocComment(start))
1903
+ case CASE =>
1904
+ enumCase(start, mods, in.getDocComment(start))
1902
1905
case _ =>
1903
1906
tmplDef(start, mods)
1904
1907
}
@@ -2029,8 +2032,9 @@ object Parsers {
2029
2032
}
2030
2033
}
2031
2034
2032
- /** TmplDef ::= ([`case'] `class' | `trait') ClassDef
2033
- * | [`case'] `object' ObjectDef
2035
+ /** TmplDef ::= ([`case' | `enum]'] ‘class’ | [`enum'] trait’) ClassDef
2036
+ * | [`case' | `enum'] `object' ObjectDef
2037
+ * | `enum' EnumDef
2034
2038
*/
2035
2039
def tmplDef (start : Int , mods : Modifiers ): Tree = {
2036
2040
val docstring = in.getDocComment(start)
@@ -2045,29 +2049,39 @@ object Parsers {
2045
2049
objectDef(start, posMods(start, mods | Module ), docstring)
2046
2050
case CASEOBJECT =>
2047
2051
objectDef(start, posMods(start, mods | Case | Module ), docstring)
2052
+ case ENUM =>
2053
+ val mods1 = addMod(mods, atPos(in.skipToken()) { Mod .Enum () })
2054
+ in.token match {
2055
+ case CLASS | TRAIT | OBJECT => tmplDef(start, mods1)
2056
+ case _ => enumDef(start, mods, docstring)
2057
+ }
2048
2058
case _ =>
2049
2059
syntaxErrorOrIncomplete(" expected start of definition" )
2050
2060
EmptyTree
2051
2061
}
2052
2062
}
2053
2063
2054
- /** ClassDef ::= id [ClsTypeParamClause]
2055
- * [ConstrMods] ClsParamClauses TemplateOpt
2064
+ /** ClassDef ::= id ClassConstr TemplateOpt
2056
2065
*/
2057
2066
def classDef (start : Offset , mods : Modifiers , docstring : Option [Comment ]): TypeDef = atPos(start, nameStart) {
2058
- val name = ident().toTypeName
2059
- val constr = atPos(in.lastOffset) {
2060
- val tparams = typeParamClauseOpt(ParamOwner .Class )
2061
- val cmods = constrModsOpt()
2062
- val vparamss = paramClauses(name, mods is Case )
2067
+ classDefRest(start, mods, docstring, ident().toTypeName)
2068
+ }
2063
2069
2064
- makeConstructor(tparams, vparamss).withMods(cmods)
2065
- }
2070
+ def classDefRest ( start : Offset , mods : Modifiers , docstring : Option [ Comment ], name : TypeName ) : TypeDef = {
2071
+ val constr = classConstr(name, isCaseClass = mods is Case )
2066
2072
val templ = templateOpt(constr)
2067
-
2068
2073
TypeDef (name, templ).withMods(mods).setComment(docstring)
2069
2074
}
2070
2075
2076
+ /** ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsParamClauses
2077
+ */
2078
+ def classConstr (owner : Name , isCaseClass : Boolean = false ): DefDef = atPos(in.lastOffset) {
2079
+ val tparams = typeParamClauseOpt(ParamOwner .Class )
2080
+ val cmods = constrModsOpt()
2081
+ val vparamss = paramClauses(owner, isCaseClass)
2082
+ makeConstructor(tparams, vparamss).withMods(cmods)
2083
+ }
2084
+
2071
2085
/** ConstrMods ::= AccessModifier
2072
2086
* | Annotation {Annotation} (AccessModifier | `this')
2073
2087
*/
@@ -2082,12 +2096,64 @@ object Parsers {
2082
2096
/** ObjectDef ::= id TemplateOpt
2083
2097
*/
2084
2098
def objectDef (start : Offset , mods : Modifiers , docstring : Option [Comment ] = None ): ModuleDef = atPos(start, nameStart) {
2085
- val name = ident()
2086
- val template = templateOpt(emptyConstructor)
2099
+ objectDefRest(start, mods, docstring, ident() )
2100
+ }
2087
2101
2102
+ def objectDefRest (start : Offset , mods : Modifiers , docstring : Option [Comment ] = None , name : TermName ): ModuleDef = {
2103
+ val template = templateOpt(emptyConstructor)
2088
2104
ModuleDef (name, template).withMods(mods).setComment(docstring)
2089
2105
}
2090
2106
2107
+ /** id ClassConstr [`extends' [ConstrApps]]
2108
+ * [nl] ‘{’ EnumCaseStats ‘}’
2109
+ */
2110
+ def enumDef (start : Offset , mods : Modifiers , docstring : Option [Comment ] = None ): EnumDef = atPos(start, nameStart) {
2111
+ val name = ident().toTypeName
2112
+ val constr = classConstr(name)
2113
+ val parents =
2114
+ if (in.token == EXTENDS ) {
2115
+ in.nextToken();
2116
+ newLineOptWhenFollowedBy(LBRACE )
2117
+ if (in.token == LBRACE ) Nil else tokenSeparated(WITH , constrApp)
2118
+ }
2119
+ else Nil
2120
+ newLineOptWhenFollowedBy(LBRACE )
2121
+ val body = inBraces(enumCaseStats)
2122
+ EnumDef (name, Template (constr, Nil , EmptyValDef , body))
2123
+ .withMods(mods).setComment(in.getDocComment(start)).asInstanceOf [EnumDef ]
2124
+ }
2125
+
2126
+ /** EnumCaseStats = EnumCaseStat {semi EnumCaseStat */
2127
+ def enumCaseStats (): List [MemberDef ] = {
2128
+ val cases = new ListBuffer [MemberDef ] += enumCaseStat()
2129
+ while (in.token != RBRACE ) {
2130
+ acceptStatSep()
2131
+ cases += enumCaseStat()
2132
+ }
2133
+ cases.toList
2134
+ }
2135
+
2136
+ /** EnumCaseStat = {Annotation [nl]} {Modifier} EnumCase */
2137
+ def enumCaseStat (): MemberDef = {
2138
+ val start = in.offset
2139
+ val docstring = in.getDocComment(start)
2140
+ val mods = defAnnotsMods(modifierTokens)
2141
+ enumCase(start, mods, docstring)
2142
+ }
2143
+
2144
+ /** EnumCase = `case' (EnumClassDef | ObjectDef) */
2145
+ def enumCase (start : Offset , mods : Modifiers , docstring : Option [Comment ]): MemberDef = {
2146
+ val mods1 = mods.withAddedMod(atPos(in.offset)(Mod .EnumCase ())) | Case
2147
+ accept(CASE )
2148
+ atPos(start, nameStart) {
2149
+ val name = ident()
2150
+ if (in.token == LBRACKET || in.token == LPAREN )
2151
+ classDefRest(start, mods1, docstring, name.toTypeName)
2152
+ else
2153
+ objectDefRest(start, mods1, docstring, name)
2154
+ }
2155
+ }
2156
+
2091
2157
/* -------- TEMPLATES ------------------------------------------- */
2092
2158
2093
2159
/** ConstrApp ::= SimpleType {ParArgumentExprs}
@@ -2197,8 +2263,8 @@ object Parsers {
2197
2263
* TemplateStat ::= Import
2198
2264
* | Annotations Modifiers Def
2199
2265
* | Annotations Modifiers Dcl
2266
+ * | EnumCaseStat
2200
2267
* | Expr1
2201
- * | super ArgumentExprs {ArgumentExprs}
2202
2268
* |
2203
2269
*/
2204
2270
def templateStatSeq (): (ValDef , List [Tree ]) = checkNoEscapingPlaceholders {
@@ -2228,7 +2294,7 @@ object Parsers {
2228
2294
stats ++= importClause()
2229
2295
else if (isExprIntro)
2230
2296
stats += expr1()
2231
- else if (isDefIntro(modifierTokens ))
2297
+ else if (isDefIntro(modifierTokensOrCase ))
2232
2298
stats += defOrDcl(in.offset, defAnnotsMods(modifierTokens))
2233
2299
else if (! isStatSep) {
2234
2300
exitOnError = mustStartStat
0 commit comments