• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.tools.metalava
18 
19 import com.android.tools.lint.checks.infrastructure.TestFiles.base64gzip
20 import com.android.tools.lint.checks.infrastructure.TestFiles.jar
21 import com.android.tools.lint.checks.infrastructure.TestFiles.xml
22 import org.junit.Assert.assertEquals
23 import org.junit.Assert.assertFalse
24 import org.junit.Assert.assertTrue
25 import org.junit.Test
26 import java.io.File
27 import java.lang.reflect.Modifier
28 import java.net.URLClassLoader
29 import kotlin.text.Charsets.UTF_8
30 
31 class RewriteAnnotationsTest : DriverTest() {
32     @Test
Test copying private annotations from one of the stubsnull33     fun `Test copying private annotations from one of the stubs`() {
34         val source = File("stub-annotations".replace('/', File.separatorChar))
35         assertTrue(source.path, source.isDirectory)
36         val target = temporaryFolder.newFolder()
37         runDriver(
38             ARG_NO_COLOR,
39             ARG_NO_BANNER,
40 
41             ARG_COPY_ANNOTATIONS,
42             source.path,
43             target.path
44         )
45 
46         // Source retention: Shouldn't exist
47         val nonNull = File(target, "androidx/annotation/NonNull.java")
48         assertFalse("${nonNull.path} exists", nonNull.isFile)
49 
50         // Class retention: Should be converted
51 
52         val recentlyNull = File(target, "androidx/annotation/RecentlyNullable.java")
53         assertTrue("${recentlyNull.path} doesn't exist", recentlyNull.isFile)
54         assertEquals(
55             """
56             /*
57              * Copyright (C) 2018 The Android Open Source Project
58              *
59              * Licensed under the Apache License, Version 2.0 (the "License");
60              * you may not use this file except in compliance with the License.
61              * You may obtain a copy of the License at
62              *
63              *      http://www.apache.org/licenses/LICENSE-2.0
64              *
65              * Unless required by applicable law or agreed to in writing, software
66              * distributed under the License is distributed on an "AS IS" BASIS,
67              * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68              * See the License for the specific language governing permissions and
69              * limitations under the License.
70              */
71             package androidx.annotation;
72 
73             import static java.lang.annotation.ElementType.FIELD;
74             import static java.lang.annotation.ElementType.METHOD;
75             import static java.lang.annotation.ElementType.PARAMETER;
76             import static java.lang.annotation.ElementType.TYPE_USE;
77             import static java.lang.annotation.RetentionPolicy.CLASS;
78 
79             import java.lang.annotation.Retention;
80             import java.lang.annotation.Target;
81 
82             /** Stub only annotation. Do not use directly. */
83             @Retention(CLASS)
84             @Target({METHOD, PARAMETER, FIELD})
85             @interface RecentlyNullable {}
86         """.trimIndent().trim(), recentlyNull.readText(UTF_8).trim().replace("\r\n", "\n")
87         )
88     }
89 
90     @Test
Test rewriting the bytecode for one of the public annotationsnull91     fun `Test rewriting the bytecode for one of the public annotations`() {
92         val bytecode = base64gzip(
93             "androidx/annotation/CallSuper.class", "" +
94                 "H4sIAAAAAAAAAIWPsU4CQRRF70NhEQWxJMZoLCjdxs6KIMYCA2E3NlbD8kKG" +
95                 "DDNkmSXwaxZ+gB9FfGMBFps4yczc5J53kve9//wC8IirCK0IlxHahEbiijzj" +
96                 "F22Y0OorY5JixfnDQm0UoTMprNdLftdrPTXcs9Z55bWza8LdMDCxUXYeq0MR" +
97                 "T9izDemJUN0oU4i3+w86dkZnuzDQH/aShHBTPpCqfM5euPvyfmB4KcZ0t2KB" +
98                 "am+D9HX0LDZlZ7nTs+1f9rAqoX2UjaYLzjzhttR/3L9LIFTkniCcCk5/3ypq" +
99                 "8l9LiqSrM87QwHmIHyDGBZo/ObYRQoUBAAA="
100         )
101 
102         val compiledStubs = temporaryFolder.newFolder("compiled-stubs")
103         bytecode.createFile(compiledStubs)
104 
105         runDriver(
106             ARG_NO_COLOR,
107             ARG_NO_BANNER,
108 
109             ARG_REWRITE_ANNOTATIONS,
110             compiledStubs.path
111         )
112 
113         // Load the class to make sure it's legit
114         val url = compiledStubs.toURI().toURL()
115         val loader = URLClassLoader(arrayOf(url), null)
116         val annotationClass = loader.loadClass("androidx.annotation.CallSuper")
117         val modifiers = annotationClass.modifiers
118         assertEquals(0, modifiers and Modifier.PUBLIC)
119         assertTrue(annotationClass.isAnnotation)
120     }
121 
122     @Test
Test rewriting the bytecode for one of the public annotations in a jar filenull123     fun `Test rewriting the bytecode for one of the public annotations in a jar file`() {
124         val bytecode = base64gzip(
125             "androidx/annotation/CallSuper.class", "" +
126                 "H4sIAAAAAAAAAIWPsU4CQRRF70NhEQWxJMZoLCjdxs6KIMYCA2E3NlbD8kKG" +
127                 "DDNkmSXwaxZ+gB9FfGMBFps4yczc5J53kve9//wC8IirCK0IlxHahEbiijzj" +
128                 "F22Y0OorY5JixfnDQm0UoTMprNdLftdrPTXcs9Z55bWza8LdMDCxUXYeq0MR" +
129                 "T9izDemJUN0oU4i3+w86dkZnuzDQH/aShHBTPpCqfM5euPvyfmB4KcZ0t2KB" +
130                 "am+D9HX0LDZlZ7nTs+1f9rAqoX2UjaYLzjzhttR/3L9LIFTkniCcCk5/3ypq" +
131                 "8l9LiqSrM87QwHmIHyDGBZo/ObYRQoUBAAA="
132         )
133 
134         val jarDesc = jar(
135             "myjar.jar",
136             bytecode,
137             xml("foo/bar/baz.xml", "<hello-world/>")
138         )
139 
140         val jarFile = jarDesc.createFile(temporaryFolder.root)
141 
142         runDriver(
143             ARG_NO_COLOR,
144             ARG_NO_BANNER,
145 
146             ARG_REWRITE_ANNOTATIONS,
147             jarFile.path
148         )
149 
150         // Load the class to make sure it's legit
151         val url = jarFile.toURI().toURL()
152         val loader = URLClassLoader(arrayOf(url), null)
153         val annotationClass = loader.loadClass("androidx.annotation.CallSuper")
154         val modifiers = annotationClass.modifiers
155         assertEquals(0, modifiers and Modifier.PUBLIC)
156         assertTrue(annotationClass.isAnnotation)
157     }
158 }