diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-01-28 20:13:28 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-01-28 21:27:23 +0100 |
commit | 9afae59f0e46bed0acf40d043d3ee2a0e0ef432f (patch) | |
tree | eed2fd8fe79a873f84b3fea95c1e9d005e0b650c /src/reflect/scala/reflect/internal/Symbols.scala | |
parent | 02963d724c512251ce66502226408091686989ee (diff) | |
download | scala-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.scala | 23 |
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] = |