• 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 @file:Suppress("ALL")
18 
19 package com.android.tools.metalava
20 
21 import org.junit.Test
22 
23 class Java9LanguageFeaturesTest : DriverTest() {
24     @Test
Private Interface Methodnull25     fun `Private Interface Method`() {
26         // Basic class; also checks that default constructor is made explicit
27         check(
28             format = FileFormat.V1,
29             checkCompilation = false, // Not compiling with JDK 9 yet
30             sourceFiles = arrayOf(
31                 java(
32                     """
33                     package test.pkg;
34 
35                     public interface Person {
36                         String name();
37                         private String reverse(String s) {
38                             return new StringBuilder(s).reverse().toString();
39                         }
40                     }
41                     """
42                 )
43             ),
44             api = """
45                 package test.pkg {
46                   public interface Person {
47                     method public String name();
48                   }
49                 }
50                 """,
51             extraArguments = arrayOf(ARG_JAVA_SOURCE, "1.9")
52         )
53     }
54 
55     @Test
Kotlin language levelnull56     fun `Kotlin language level`() {
57         // See https://kotlinlang.org/docs/reference/whatsnew13.html
58         check(
59             format = FileFormat.V1,
60             sourceFiles = arrayOf(
61                 kotlin(
62                     """
63                     package test.pkg
64                     interface Foo {
65                         companion object {
66                             @JvmField
67                             const val answer: Int = 42
68                             @JvmStatic
69                             fun sayHello() {
70                                 println("Hello, world!")
71                             }
72                         }
73                     }
74                     """
75                 )
76             ),
77             api =
78             """
79                 package test.pkg {
80                   public interface Foo {
81                     method public default static void sayHello();
82                     field @NonNull public static final test.pkg.Foo.Companion Companion;
83                     field public static final int answer = 42; // 0x2a
84                   }
85                   public static final class Foo.Companion {
86                     method public void sayHello();
87                   }
88                 }
89                 """,
90             // The above source uses 1.3 features, though UAST currently
91             // seems to still treat it as 1.3 despite being passed 1.2
92             extraArguments = arrayOf(ARG_KOTLIN_SOURCE, "1.2")
93         )
94     }
95 
96     @Test
Basic class signature extractionnull97     fun `Basic class signature extraction`() {
98         // Basic class; also checks that default constructor is made explicit
99         check(
100             format = FileFormat.V1,
101             checkCompilation = false, // Not compiling with JDK 9 yet
102             sourceFiles = arrayOf(
103                 java(
104                     """
105                     package libcore.internal;
106 
107                     import java.io.ByteArrayInputStream;
108                     import java.io.ByteArrayOutputStream;
109                     import java.io.IOException;
110                     import java.io.InputStream;
111                     import java.util.ArrayList;
112                     import java.util.Arrays;
113                     import java.util.List;
114                     import java.util.Objects;
115                     import java.util.concurrent.atomic.AtomicReference;
116 
117                     public class Java9LanguageFeatures {
118 
119                         public interface Person {
120                             String name();
121 
122                             default boolean isPalindrome() {
123                                 return name().equals(reverse(name()));
124                             }
125 
126                             default boolean isPalindromeIgnoreCase() {
127                                 return name().equalsIgnoreCase(reverse(name()));
128                             }
129 
130                             // Language feature: private interface method
131                             private String reverse(String s) {
132                                 return new StringBuilder(s).reverse().toString();
133                             }
134                         }
135 
136                         @SafeVarargs
137                         public static<T> String toListString(T... values) {
138                             return toString(values).toString();
139                         }
140 
141                         // Language feature: @SafeVarargs on private methods
142                         @SafeVarargs
143                         private static<T> List<String> toString(T... values) {
144                             List<String> result = new ArrayList<>();
145                             for (T value : values) {
146                                 result.add(value.toString());
147                             }
148                             return result;
149                         }
150 
151                         public <T> AtomicReference<T> createReference(T content) {
152                             // Language feature: <> on anonymous class
153                             //noinspection unchecked
154                             return new AtomicReference<>(content) { };
155                         }
156 
157                         public static byte[] copy(byte[] bytes) throws IOException {
158                             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
159                             InputStream inputStream = new ByteArrayInputStream(bytes);
160                             try (inputStream) { // Language feature: try on effectively-final variable
161                                 int value;
162                                 while ((value = inputStream.read()) != -1) {
163                                     byteArrayOutputStream.write(value);
164                                 }
165                             }
166                             return byteArrayOutputStream.toByteArray();
167                         }
168                     }
169                     """
170                 )
171             ),
172             api = """
173                 package libcore.internal {
174                   public class Java9LanguageFeatures {
175                     ctor public Java9LanguageFeatures();
176                     method public static byte[] copy(byte[]) throws java.io.IOException;
177                     method public <T> java.util.concurrent.atomic.AtomicReference<T> createReference(T);
178                     method @java.lang.SafeVarargs public static <T> String toListString(T...);
179                   }
180                   public static interface Java9LanguageFeatures.Person {
181                     method public default boolean isPalindrome();
182                     method public default boolean isPalindromeIgnoreCase();
183                     method public String name();
184                   }
185                 }
186                 """,
187             extraArguments = arrayOf(ARG_JAVA_SOURCE, "1.9")
188         )
189     }
190 
191     @Test
Using JDK APIsnull192     fun `Using JDK APIs`() {
193         // Non-Android example
194         val jdk = System.getProperty("java.home") ?: error("Expected java.home to be set")
195         check(
196             format = FileFormat.V2,
197             sourceFiles = arrayOf(
198                 java(
199                     """
200                     package test.pkg;
201                     import javax.swing.JButton;
202                     public class SwingTest extends JButton {
203                         public JButton button;
204                     }
205                     """
206                 )
207             ),
208             api =
209             """
210                 package test.pkg {
211                   public class SwingTest extends javax.swing.JButton {
212                     ctor public SwingTest();
213                     field public javax.swing.JButton button;
214                   }
215                 }
216                 """,
217             extraArguments = arrayOf(ARG_JDK_HOME, jdk)
218         )
219     }
220 }
221