summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/internal/Symbols.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-01-28 20:13:28 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-01-28 21:27:23 +0100
commit9afae59f0e46bed0acf40d043d3ee2a0e0ef432f (patch)
treeeed2fd8fe79a873f84b3fea95c1e9d005e0b650c /src/reflect/scala/reflect/internal/Symbols.scala
parent02963d724c512251ce66502226408091686989ee (diff)
downloadscala-9afae59f0e46bed0acf40d043d3ee2a0e0ef432f.tar.gz
scala-9afae59f0e46bed0acf40d043d3ee2a0e0ef432f.tar.bz2
scala-9afae59f0e46bed0acf40d043d3ee2a0e0ef432f.zip
SI-7035 Centralize case field accessor sorting.
It is both burdensome and dangerous to expect callers to reorder these. This was seen in the field permutation in the unapply method; a regression in 2.10.0.
Diffstat (limited to 'src/reflect/scala/reflect/internal/Symbols.scala')
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index a4287fb181..8f7061433d 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -1728,8 +1728,27 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** For a case class, the symbols of the accessor methods, one for each
* argument in the first parameter list of the primary constructor.
* The empty list for all other classes.
- */
- final def caseFieldAccessors: List[Symbol] =
+ *
+ * This list will be sorted to correspond to the declaration order
+ * in the constructor parameter
+ */
+ final def caseFieldAccessors: List[Symbol] = {
+ // We can't rely on the ordering of the case field accessors within decls --
+ // handling of non-public parameters seems to change the order (see SI-7035.)
+ //
+ // Luckily, the constrParamAccessors are still sorted properly, so sort the field-accessors using them
+ // (need to undo name-mangling, including the sneaky trailing whitespace)
+ //
+ // The slightly more principled approach of using the paramss of the
+ // primary constructor leads to cycles in, for example, pos/t5084.scala.
+ val primaryNames = constrParamAccessors.map(acc => nme.dropLocalSuffix(acc.name))
+ caseFieldAccessorsUnsorted.sortBy { acc =>
+ primaryNames indexWhere { orig =>
+ (acc.name == orig) || (acc.name startsWith (orig append "$"))
+ }
+ }
+ }
+ private final def caseFieldAccessorsUnsorted: List[Symbol] =
(info.decls filter (_.isCaseAccessorMethod)).toList
final def constrParamAccessors: List[Symbol] =