SI-8944 A more resiliant naming scheme for case accessors#4125
SI-8944 A more resiliant naming scheme for case accessors#4125gkossakowski merged 1 commit intoscala:2.12.xfrom
Conversation
538ea95 to
556388a
Compare
Case class parameters that are less that public have an extra accessor method created to ensure universal pattern matchability. See scala#4081 for more background. Currently, this is given a fresh name based on the parameter name. However, this is fragile and the name can change based on unrelated edits higher up in the source file. This commit switches to a stable naming scheme for these methods. A non-public case field `foo` has a corresponding accessor `foo$access$N`, where `N` is the index of the parameter within the constructor parameter list. The enclosed tests show a case that used to trigger a linkage error under separate compilation that now works; shows that by choosing the `foo$access$1` rather than `foo$1` we don't clash with lambda lifted methods in the class; and shows the names of the accessor methods as seen via Java reflection.
556388a to
ff2cd80
Compare
|
@retronym, this looks fine to me. Would you like to merge? Also, would you consider deprecating private parameters to constructors of case classes? I think they make little sense. |
|
Let's get another opinion from @lrytz on the new scheme. It should be noted that |
|
We could make |
|
LGTM too |
|
I'm not sure I'm all for adding an abide check, though, for those who don't mean to be weird. |
SI-8944 A more resiliant naming scheme for case accessors
|
My heart sank when I learnt about this Scala feature but I give in to your reasons. :) |
Case class parameters may be declared as non-public. If this is the case, the case accessor method is still synthesized as public, but it has a mangled name of the form `origName$N`. See also SI-8944 / scala#4125. The compiler maps from case fields to the corresponding accessors with this naming convention in mind. However, it is too lenient, and assumes that only one accessor will be of the form "origName\$.*". If, however, a regular, public case parameter is named `a b`, it will have a name `a$u0020b`, which spurously matches that overly permissive pattern. This commit changes tightens up the logic to expect "origName\$\d+".
Case class parameters may be declared as non-public. If this is the case, the case accessor method is still synthesized as public, but it has a mangled name of the form `origName$N`. See also SI-8944 / scala#4125. The compiler maps from case fields to the corresponding accessors with this naming convention in mind. However, it is too lenient, and assumes that only one accessor will be of the form "origName\$.*". If, however, a regular, public case parameter is named `a b`, it will have a name `a$u0020b`, which spurously matches that overly permissive pattern. This commit changes tightens up the logic to expect "origName\$\d+".
Case class parameters that are less that public have an extra
accessor method created to ensure universal pattern matchability.
See #4081 for more background.
Currently, this is given a fresh name based on the parameter name.
However, this is fragile and the name can change based on unrelated
edits higher up in the source file.
This commit switches to a stable naming scheme for these methods.
A non-public case field
foohas a corresponding accessorfoo$access$N, whereNis the index of the parameter withinthe constructor parameter list.
The enclosed tests show a case that used to trigger a linkage
error under separate compilation that now works; shows that by
choosing the
foo$access$1rather thanfoo$1we don't clash withlambda lifted methods in the class; and shows the names of the
accessor methods as seen via Java reflection.
Just submitting for a test run for now.
/cc @gkossakowski who is usually has some good insights when it
comes to accessor naming schemes. This is one of the cross
compilation unit use cases that we have to deal with that Java
doesn't.