• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.annotationvisitor;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import com.google.common.base.Joiner;
22 import com.google.common.collect.ImmutableMap;
23 
24 import org.apache.bcel.classfile.AnnotationEntry;
25 import org.junit.Before;
26 import org.junit.Test;
27 
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Map;
32 
33 public class RepeatedAnnotationHandlerTest extends AnnotationHandlerTestBase {
34 
35     @Before
setup()36     public void setup() {
37         // To keep the test simpler and more concise, we don't use a real annotation here, but use
38         // our own @Annotation and @Annotation.Multi that have the same relationship.
39         mJavac.addSource("annotation.Annotation", Joiner.on('\n').join(
40                 "package annotation;",
41                 "import static java.lang.annotation.RetentionPolicy.CLASS;",
42                 "import java.lang.annotation.Repeatable;",
43                 "import java.lang.annotation.Retention;",
44                 "@Repeatable(Annotation.Multi.class)",
45                 "@Retention(CLASS)",
46                 "public @interface Annotation {",
47                 "  Class<?> clazz();",
48                 "  @Retention(CLASS)",
49                 "  @interface Multi {",
50                 "    Annotation[] value();",
51                 "  }",
52                 "}"));
53     }
54 
55     @Test
testRepeated()56     public void testRepeated() throws IOException {
57         mJavac.addSource("a.b.Class", Joiner.on('\n').join(
58                 "package a.b;",
59                 "import annotation.Annotation;",
60                 "public class Class {",
61                 "  @Annotation(clazz=Integer.class)",
62                 "  @Annotation(clazz=Long.class)",
63                 "  public String method() {return null;}",
64                 "}"));
65         mJavac.compile();
66 
67         TestAnnotationHandler handler = new TestAnnotationHandler();
68         Map<String, AnnotationHandler> handlerMap =
69             ImmutableMap.of("Lannotation/Annotation$Multi;",
70                 new RepeatedAnnotationHandler("Lannotation/Annotation;", handler));
71         new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus, handlerMap).visit();
72 
73         assertNoErrors();
74         assertThat(handler.getClasses()).containsExactly(
75                 "Ljava/lang/Integer;",
76                 "Ljava/lang/Long;");
77     }
78 
79     private static class TestAnnotationHandler extends AnnotationHandler {
80 
81         private final List<String> classes;
82 
TestAnnotationHandler()83         private TestAnnotationHandler() {
84             this.classes = new ArrayList<>();
85         }
86 
87         @Override
handleAnnotation(AnnotationEntry annotation, AnnotationContext context)88         protected void handleAnnotation(AnnotationEntry annotation,
89             AnnotationContext context) {
90             classes.add(annotation.getElementValuePairs()[0].getValue().stringifyValue());
91         }
92 
getClasses()93         private List<String> getClasses() {
94             return classes;
95         }
96     }
97 }
98