Skip to content

Commit 35b1084

Browse files
authored
Merge pull request #15063 from raboof/keep-annotation-order-fixing-14743
Keep annotation order
2 parents f29eea7 + 414091f commit 35b1084

File tree

10 files changed

+55
-1
lines changed

10 files changed

+55
-1
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import Constants._
1111
import Types._
1212
import Decorators._
1313

14+
import scala.collection.mutable
15+
1416
class RepeatableAnnotations extends MiniPhase:
1517

1618
override def phaseName: String = RepeatableAnnotations.name
@@ -28,7 +30,7 @@ class RepeatableAnnotations extends MiniPhase:
2830
tree
2931

3032
private def aggregateAnnotations(annotations: Seq[Annotation])(using Context): List[Annotation] =
31-
val annsByType = annotations.groupBy(_.symbol)
33+
val annsByType = stableGroupBy(annotations, _.symbol)
3234
annsByType.flatMap {
3335
case (_, a :: Nil) => a :: Nil
3436
case (sym, anns) if sym.derivesFrom(defn.ClassfileAnnotationClass) =>
@@ -50,6 +52,14 @@ class RepeatableAnnotations extends MiniPhase:
5052
case (_, anns) => anns
5153
}.toList
5254

55+
private def stableGroupBy[A, K](ins: Seq[A], f: A => K): scala.collection.MapView[K, List[A]] =
56+
val out = new mutable.LinkedHashMap[K, mutable.ListBuffer[A]]()
57+
for (in <- ins) {
58+
val buffer = out.getOrElseUpdate(f(in), new mutable.ListBuffer)
59+
buffer += in
60+
}
61+
out.view.mapValues(_.toList)
62+
5363
object RepeatableAnnotations:
5464
val name: String = "repeatableAnnotations"
5565
val description: String = "aggregate repeatable annotations"

tests/pos/Annotations.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package foo.bar
2+
3+
import jdk.jfr.Enabled
4+
5+
@Enabled
6+
@Deprecated
7+
final class Annotations {
8+
}

tests/pos/annotations1/a.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Annot1(s: String) extends scala.annotation.StaticAnnotation
2+
class Annot2(s: Class[_]) extends scala.annotation.StaticAnnotation

tests/pos/annotations1/b.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@Annot1("foo")
2+
@Annot2(classOf[AnyRef])
3+
class Test

tests/pos/annotationsJava/Annot1.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import java.lang.annotation.*;
2+
@Retention(RetentionPolicy.RUNTIME)
3+
@Target(ElementType.TYPE)
4+
@Inherited
5+
@interface Annot1 { String value() default ""; }

tests/pos/annotationsJava/Annot2.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import java.lang.annotation.*;
2+
@Retention(RetentionPolicy.RUNTIME)
3+
@Target(ElementType.TYPE)
4+
@Inherited
5+
@interface Annot2 { Class value(); }

tests/pos/annotationsJava/b.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@Annot1("foo") @Annot2(classOf[AnyRef]) class Test
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import java.lang.annotation.*;
2+
3+
@Repeatable(Annot1.Container.class)
4+
@Retention(RetentionPolicy.RUNTIME)
5+
@Target(ElementType.TYPE)
6+
@interface Annot1 { String value() default "";
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.TYPE)
10+
public static @interface Container {
11+
Annot1[] value();
12+
}
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import java.lang.annotation.*;
2+
3+
@Retention(RetentionPolicy.RUNTIME)
4+
@Target(ElementType.TYPE)
5+
@Inherited
6+
@interface Annot2 { Class value(); }
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@Annot1("foo") @Annot2(classOf[String]) @Annot1("bar") class Test

0 commit comments

Comments
 (0)