Skip to content

Commit 7303278

Browse files
committed
match on string for valueOf
1 parent cc5c208 commit 7303278

File tree

2 files changed

+18
-33
lines changed

2 files changed

+18
-33
lines changed

compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,19 @@ object DesugarEnums {
101101
/** The following lists of definitions for an enum type E and known value cases e_0, ..., e_n:
102102
*
103103
* private val $values = Array[E](e_0,...,e_n)(ClassTag[E](classOf[E]))
104-
* @annotation.threadUnsafe private lazy val $valuesReverse =
105-
* scala.runtime.ScalaRuntime.wrapRefArray($values).map((x_0: E) => (x_0.enumLabel, x_0)).toMap
106104
* def values = $values.clone
107-
* def valueOf($name: String) =
108-
* try $valuesReverse($name) catch
109-
* {
110-
* case ex$: NoSuchElementException =>
111-
* throw new IllegalArgumentException("enum case not found: " + $name)
112-
* }
105+
* def valueOf($name: String) = $name match {
106+
* case "e_0" => e_0
107+
* ...
108+
* case "e_n" => e_n
109+
* case _ => throw new IllegalArgumentException("case not found: " + $name)
110+
* }
113111
*/
114112
private def enumScaffolding(enumCases: List[(Int, TermName)])(using Context): List[Tree] = {
115113
import dotty.tools.dotc.transform.SymUtils.rawTypeRef
114+
115+
def const(arg: String | Int | Null | Unit) = Literal(Constant(arg))
116+
116117
val rawEnumClassRef = rawRef(enumClass.typeRef)
117118
extension (tpe: NamedType) def ofRawEnum = AppliedTypeTree(ref(tpe), rawEnumClassRef)
118119

@@ -121,39 +122,24 @@ object DesugarEnums {
121122
ArrayLiteral(enumCases.map((_, name) => Ident(name)), rawEnumClassRef))
122123
.withFlags(Private | Synthetic)
123124

124-
val privateReverseValuesDef =
125-
val wrapped = Apply(Select(ref(defn.ScalaRuntimeModule.termRef), nme.wrapRefArray), Ident(nme.DOLLAR_VALUES))
126-
val mapper =
127-
val paramName = nme.syntheticParamName(0)
128-
val paramDef = param(paramName, rawEnumClassRef)
129-
Function(paramDef :: Nil, Tuple(Select(Ident(paramName), nme.enumLabel) :: Ident(paramName) :: Nil))
130-
val mapBody = Select(Apply(Select(wrapped, nme.map), mapper), nme.toMap)
131-
val annot = New(ref(defn.ThreadUnsafeAnnot.typeRef), Nil).withSpan(ctx.tree.span)
132-
ValDef(nme.DOLLAR_VALUES_REVERSE, TypeTree(), mapBody)
133-
.withFlags(Private | Synthetic | Lazy).withAnnotations(annot :: Nil)
134-
135125
val valuesDef =
136126
DefDef(nme.values, Nil, Nil, defn.ArrayType.ofRawEnum, valuesDot(nme.clone_))
137127
.withFlags(Synthetic)
138128

139-
val valuesOfExnMessage = Apply(
140-
Select(Literal(Constant("enum case not found: ")), nme.PLUS), Ident(nme.nameDollar))
141-
142-
val valuesOfBody = Try(
143-
expr = Apply(Ident(nme.DOLLAR_VALUES_REVERSE), Ident(nme.nameDollar) :: Nil),
144-
cases = CaseDef(
145-
pat = Typed(Ident(nme.DEFAULT_EXCEPTION_NAME), TypeTree(defn.NoSuchElementExceptionType)),
146-
guard = EmptyTree,
147-
body = Throw(New(TypeTree(defn.IllegalArgumentExceptionType), List(valuesOfExnMessage :: Nil)))
148-
) :: Nil,
149-
finalizer = EmptyTree
150-
)
129+
val valuesOfBody: Tree =
130+
val defaultCase =
131+
val msg = Apply(Select(const("enum case not found: "), nme.PLUS), Ident(nme.nameDollar))
132+
CaseDef(Ident(nme.WILDCARD), EmptyTree,
133+
Throw(New(TypeTree(defn.IllegalArgumentExceptionType), List(msg :: Nil))))
134+
val stringCases = enumCases.map((_, name) =>
135+
CaseDef(const(name.toString), EmptyTree, Ident(name))
136+
) ::: defaultCase :: Nil
137+
Match(Ident(nme.nameDollar), stringCases)
151138
val valueOfDef = DefDef(nme.valueOf, Nil, List(param(nme.nameDollar, defn.StringType) :: Nil),
152139
TypeTree(), valuesOfBody)
153140
.withFlags(Synthetic)
154141

155142
privateValuesDef ::
156-
privateReverseValuesDef ::
157143
valuesDef ::
158144
valueOfDef :: Nil
159145
}

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ object StdNames {
123123
val DEFAULT_GETTER_INIT: N = "$lessinit$greater"
124124
val DO_WHILE_PREFIX: N = "doWhile$"
125125
val DOLLAR_VALUES: N = "$values"
126-
val DOLLAR_VALUES_REVERSE: N = "$valuesReverse"
127126
val DOLLAR_NEW: N = "$new"
128127
val EMPTY: N = ""
129128
val EMPTY_PACKAGE: N = "<empty>"

0 commit comments

Comments
 (0)