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