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