@@ -62,7 +62,8 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
62
62
if (myValueSymbols.isEmpty) {
63
63
myValueSymbols = List (defn.Any_hashCode , defn.Any_equals )
64
64
myCaseSymbols = myValueSymbols ++ List (defn.Any_toString , defn.Product_canEqual ,
65
- defn.Product_productArity , defn.Product_productPrefix , defn.Product_productElement )
65
+ defn.Product_productArity , defn.Product_productPrefix , defn.Product_productElement ,
66
+ defn.Product_productElementName )
66
67
myCaseModuleSymbols = myCaseSymbols.filter(_ ne defn.Any_equals )
67
68
myEnumCaseSymbols = List (defn.Enum_ordinal )
68
69
}
@@ -126,6 +127,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
126
127
case nme.productArity => Literal (Constant (accessors.length))
127
128
case nme.productPrefix => ownName
128
129
case nme.productElement => productElementBody(accessors.length, vrefss.head.head)
130
+ case nme.productElementName => productElementNameBody(accessors.length, vrefss.head.head)
129
131
case nme.ordinal => Select (This (clazz), nme.ordinalDollar)
130
132
}
131
133
ctx.log(s " adding $synthetic to $clazz at ${ctx.phase}" )
@@ -149,6 +151,40 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
149
151
* ```
150
152
*/
151
153
def productElementBody (arity : Int , index : Tree )(implicit ctx : Context ): Tree = {
154
+ // case N => _${N + 1}
155
+ val cases = 0 .until(arity).map { i =>
156
+ CaseDef (Literal (Constant (i)), EmptyTree , Select (This (clazz), nme.selectorName(i)))
157
+ }
158
+
159
+ Match (index, (cases :+ generateIOBECase(index)).toList)
160
+ }
161
+
162
+ /** The class
163
+ *
164
+ * ```
165
+ * case class C(x: T, y: T)
166
+ * ```
167
+ *
168
+ * gets the `productElementName` method:
169
+ *
170
+ * ```
171
+ * def productElementName(index: Int): String = index match {
172
+ * case 0 => "x"
173
+ * case 1 => "y"
174
+ * case _ => throw new IndexOutOfBoundsException(index.toString)
175
+ * }
176
+ * ```
177
+ */
178
+ def productElementNameBody (arity : Int , index : Tree )(implicit ctx : Context ): Tree = {
179
+ // case N => // name for case arg N
180
+ val cases = 0 .until(arity).map { i =>
181
+ CaseDef (Literal (Constant (i)), EmptyTree , Literal (Constant (accessors(i).name.toString)))
182
+ }
183
+
184
+ Match (index, (cases :+ generateIOBECase(index)).toList)
185
+ }
186
+
187
+ def generateIOBECase (index : Tree ): CaseDef = {
152
188
val ioob = defn.IndexOutOfBoundsException .typeRef
153
189
// Second constructor of ioob that takes a String argument
154
190
def filterStringConstructor (s : Symbol ): Boolean = s.info match {
@@ -160,14 +196,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
160
196
val error = Throw (New (ioob, constructor, List (stringIndex)))
161
197
162
198
// case _ => throw new IndexOutOfBoundsException(i.toString)
163
- val defaultCase = CaseDef (Underscore (defn.IntType ), EmptyTree , error)
164
-
165
- // case N => _${N + 1}
166
- val cases = 0 .until(arity).map { i =>
167
- CaseDef (Literal (Constant (i)), EmptyTree , Select (This (clazz), nme.selectorName(i)))
168
- }
169
-
170
- Match (index, (cases :+ defaultCase).toList)
199
+ CaseDef (Underscore (defn.IntType ), EmptyTree , error)
171
200
}
172
201
173
202
/** The class
0 commit comments