Skip to content

Commit c5f9b2a

Browse files
committed
move productElementName generation to SyntheticMethods
1 parent f82d9a3 commit c5f9b2a

File tree

3 files changed

+44
-30
lines changed

3 files changed

+44
-30
lines changed

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

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -610,24 +610,8 @@ object desugar {
610610
}
611611
}
612612

613-
def productElemNameMeth = {
614-
val methodParam = makeSyntheticParameter(tpt = scalaDot(tpnme.Int))
615-
val paramRef = Ident(methodParam.name)
616-
617-
val indexAsString = Apply(Select(javaDotLangDot(nme.String), nme.valueOf), paramRef)
618-
val throwOutOfBound = Throw(New(javaDotLangDot(tpnme.IOOBException), List(List(indexAsString))))
619-
val defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, throwOutOfBound)
620-
621-
val patternMatchCases = derivedVparamss.head.zipWithIndex.map { case (param, idx) =>
622-
CaseDef(Literal(Constant(idx)), EmptyTree, Literal(Constant(param.name.decode.toString)))
623-
} :+ defaultCase
624-
val body = Match(paramRef, patternMatchCases)
625-
DefDef(nme.productElementName, Nil, List(List(methodParam)), javaDotLangDot(tpnme.String), body)
626-
.withFlags(Override | Synthetic)
627-
}
628-
629613
if (isCaseClass)
630-
productElemNameMeth :: copyMeths ::: ordinalMeths ::: productElemMeths
614+
copyMeths ::: ordinalMeths ::: productElemMeths
631615
else Nil
632616
}
633617

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -596,10 +596,11 @@ class Definitions {
596596

597597
@tu lazy val EnumValuesClass: ClassSymbol = ctx.requiredClass("scala.runtime.EnumValues")
598598
@tu lazy val ProductClass: ClassSymbol = ctx.requiredClass("scala.Product")
599-
@tu lazy val Product_canEqual : Symbol = ProductClass.requiredMethod(nme.canEqual_)
600-
@tu lazy val Product_productArity : Symbol = ProductClass.requiredMethod(nme.productArity)
601-
@tu lazy val Product_productElement: Symbol = ProductClass.requiredMethod(nme.productElement)
602-
@tu lazy val Product_productPrefix : Symbol = ProductClass.requiredMethod(nme.productPrefix)
599+
@tu lazy val Product_canEqual : Symbol = ProductClass.requiredMethod(nme.canEqual_)
600+
@tu lazy val Product_productArity : Symbol = ProductClass.requiredMethod(nme.productArity)
601+
@tu lazy val Product_productElement : Symbol = ProductClass.requiredMethod(nme.productElement)
602+
@tu lazy val Product_productElementName: Symbol = ProductClass.requiredMethod(nme.productElementName)
603+
@tu lazy val Product_productPrefix : Symbol = ProductClass.requiredMethod(nme.productPrefix)
603604

604605
@tu lazy val IteratorClass: ClassSymbol = ctx.requiredClass("scala.collection.Iterator")
605606
def IteratorModule(implicit ctx: Context): Symbol = IteratorClass.companionModule

compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
6262
if (myValueSymbols.isEmpty) {
6363
myValueSymbols = List(defn.Any_hashCode, defn.Any_equals)
6464
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)
6667
myCaseModuleSymbols = myCaseSymbols.filter(_ ne defn.Any_equals)
6768
myEnumCaseSymbols = List(defn.Enum_ordinal)
6869
}
@@ -126,6 +127,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
126127
case nme.productArity => Literal(Constant(accessors.length))
127128
case nme.productPrefix => ownName
128129
case nme.productElement => productElementBody(accessors.length, vrefss.head.head)
130+
case nme.productElementName => productElementNameBody(accessors.length, vrefss.head.head)
129131
case nme.ordinal => Select(This(clazz), nme.ordinalDollar)
130132
}
131133
ctx.log(s"adding $synthetic to $clazz at ${ctx.phase}")
@@ -149,6 +151,40 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
149151
* ```
150152
*/
151153
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 = {
152188
val ioob = defn.IndexOutOfBoundsException.typeRef
153189
// Second constructor of ioob that takes a String argument
154190
def filterStringConstructor(s: Symbol): Boolean = s.info match {
@@ -160,14 +196,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
160196
val error = Throw(New(ioob, constructor, List(stringIndex)))
161197

162198
// 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)
171200
}
172201

173202
/** The class

0 commit comments

Comments
 (0)