You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/11/22 15:11:28 UTC
[groovy] 12/18: GROOVY-9238: look again for collector annotations
when anno list changes
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 3a581dcd3c5c1e129ab8f579ac53779aae5e1f12
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Nov 18 16:47:43 2019 -0600
GROOVY-9238: look again for collector annotations when anno list changes
(cherry picked from commit 2af190780bd33c7c12806297e8f548f52f1b7c2c)
---
.../ASTTransformationCollectorCodeVisitor.java | 40 ++++++++--------
src/test/groovy/bugs/Groovy9238.groovy | 53 ++++++++++++++++++++++
2 files changed, 75 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java b/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java
index 5fb0418..8e38896 100644
--- a/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/ASTTransformationCollectorCodeVisitor.java
@@ -83,25 +83,29 @@ public class ASTTransformationCollectorCodeVisitor extends ClassCodeVisitorSuppo
if (nodeAnnotations.isEmpty()) return;
super.visitAnnotations(node);
- Map<Integer, AnnotationCollectorMode> modes = new LinkedHashMap<>();
- Map<Integer, List<AnnotationNode>> existing = new LinkedHashMap<>();
- Map<Integer, List<AnnotationNode>> replacements = new LinkedHashMap<>();
- int index = 0;
- for (AnnotationNode annotation : nodeAnnotations) {
- findCollectedAnnotations(annotation, node, index, modes, existing, replacements);
- index += 1;
- }
- for (Map.Entry<Integer, List<AnnotationNode>> entry : replacements.entrySet()) {
- Integer replacementIndex = entry.getKey();
- List<AnnotationNode> annotationNodeList = entry.getValue();
- mergeCollectedAnnotations(modes.get(replacementIndex), existing, annotationNodeList);
- existing.put(replacementIndex, annotationNodeList);
- }
- List<AnnotationNode> mergedList = new ArrayList<>();
- existing.values().forEach(mergedList::addAll);
+ for (;;) {
+ Map<Integer, AnnotationCollectorMode> modes = new LinkedHashMap<>();
+ Map<Integer, List<AnnotationNode>> existing = new LinkedHashMap<>();
+ Map<Integer, List<AnnotationNode>> replacements = new LinkedHashMap<>();
+ int index = 0;
+ for (AnnotationNode annotation : nodeAnnotations) {
+ findCollectedAnnotations(annotation, node, index, modes, existing, replacements);
+ index += 1;
+ }
+ for (Map.Entry<Integer, List<AnnotationNode>> entry : replacements.entrySet()) {
+ Integer replacementIndex = entry.getKey();
+ List<AnnotationNode> annotationNodeList = entry.getValue();
+ mergeCollectedAnnotations(modes.get(replacementIndex), existing, annotationNodeList);
+ existing.put(replacementIndex, annotationNodeList);
+ }
+ List<AnnotationNode> mergedList = new ArrayList<>();
+ existing.values().forEach(mergedList::addAll);
+ if (mergedList.equals(nodeAnnotations)) break;
- nodeAnnotations.clear();
- nodeAnnotations.addAll(mergedList);
+ nodeAnnotations.clear();
+ nodeAnnotations.addAll(mergedList);
+ // GROOVY-9238: look again for collector annotations
+ }
for (AnnotationNode annotation : nodeAnnotations) {
addTransformsToClassNode(annotation);
diff --git a/src/test/groovy/bugs/Groovy9238.groovy b/src/test/groovy/bugs/Groovy9238.groovy
new file mode 100644
index 0000000..6730e3a
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9238.groovy
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.bugs
+
+import groovy.transform.AnnotationCollector
+import groovy.transform.CompileStatic
+import groovy.transform.Immutable
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+@CompileStatic
+final class Groovy9238 {
+
+ @Test
+ void testAnnotationCollectorOfCollectedAnnotations() {
+ assertScript '''
+ import groovy.bugs.Groovy9238.Collector
+
+ @Collector
+ class Pogo9238 {
+ String string
+ }
+
+ def pogo = new Pogo9238('old')
+ pogo = pogo.copyWith(string: 'new')
+
+ assert pogo.string == 'new'
+ '''
+ }
+
+ @CompileStatic
+ @Immutable(copyWith=true) // this uses AnnotationCollector
+ @AnnotationCollector
+ @interface Collector {
+ }
+}