blob: 32872b459970fb002786eecc9b237c515cf3bdc8 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tools.metalava
import org.junit.Test
class KeepFileTest : DriverTest() {
@Test
fun `Generate Keep file`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
@SuppressWarnings("ALL")
public interface MyInterface<T extends Object>
extends MyBaseInterface {
}
"""
),
java(
"""
package a.b.c;
@SuppressWarnings("ALL")
public interface MyStream<T, S extends MyStream<T, S>> extends java.lang.AutoCloseable {
}
"""
),
java(
"""
package test.pkg;
@SuppressWarnings("ALL")
public interface MyInterface2<T extends Number>
extends MyBaseInterface {
class TtsSpan<C extends MyInterface<?>> { }
abstract class Range<T extends Comparable<? super T>> {
protected String myString;
}
}
"""
),
java(
"""
package test.pkg;
public interface MyBaseInterface {
void fun(int a, String b);
}
"""
)
),
proguard = """
-keep class a.b.c.MyStream {
}
-keep class test.pkg.MyBaseInterface {
public abstract void fun(int, java.lang.String);
}
-keep class test.pkg.MyInterface {
}
-keep class test.pkg.MyInterface2 {
}
-keep class test.pkg.MyInterface2${"$"}Range {
<init>();
protected java.lang.String myString;
}
-keep class test.pkg.MyInterface2${"$"}TtsSpan {
<init>();
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@Test
fun `Primitive types`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
public class MyClass {
public int testMethodA(int a) {}
public boolean testMethodB(boolean a) {}
public float testMethodC(float a) {}
public double testMethodD(double a) {}
public byte testMethodE(byte a) {}
}
"""
)
),
proguard = """
-keep class test.pkg.MyClass {
<init>();
public int testMethodA(int);
public boolean testMethodB(boolean);
public float testMethodC(float);
public double testMethodD(double);
public byte testMethodE(byte);
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@Test
fun `Primitive array types`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
public class MyClass {
public int[] testMethodA(int[] a) {}
public float[][] testMethodB(float[][] a) {}
public double[][][] testMethodC(double[][][] a) {}
public byte testMethodD(byte... a) {}
}
"""
)
),
proguard = """
-keep class test.pkg.MyClass {
<init>();
public int[] testMethodA(int[]);
public float[][] testMethodB(float[][]);
public double[][][] testMethodC(double[][][]);
public byte testMethodD(byte[]);
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@Test
fun `Object Array parameters`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
public class MyClass {
public void testMethodA(String a) {}
public void testMethodB(Boolean[] a) {}
public void testMethodC(Integer... a) {}
}
"""
)
),
proguard = """
-keep class test.pkg.MyClass {
<init>();
public void testMethodA(java.lang.String);
public void testMethodB(java.lang.Boolean[]);
public void testMethodC(java.lang.Integer[]);
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@Test
fun `Arrays with Inner class`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
public class MyClass {
public void testMethodA(InnerClass a) {}
public void testMethodB(InnerClass[] a) {}
public void testMethodC(InnerClass... a) {}
public class InnerClass {}
}
"""
)
),
proguard = """
-keep class test.pkg.MyClass {
<init>();
public void testMethodA(test.pkg.MyClass${"$"}InnerClass);
public void testMethodB(test.pkg.MyClass${"$"}InnerClass[]);
public void testMethodC(test.pkg.MyClass${"$"}InnerClass[]);
}
-keep class test.pkg.MyClass${"$"}InnerClass {
<init>();
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@Test
fun `Conflicting Class Names in parameters`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
public class String {}
"""
),
java(
"""
package test.pkg;
public class MyClass {
public void testMethodA(String a, String b) {}
public void testMethodB(String a, test.pkg.String b) {}
public void testMethodC(String a, java.lang.String b) {}
public void testMethodD(java.lang.String a, test.pkg.String b) {}
}
"""
),
java(
"""
package test.pkg;
public class MyClassArrays {
public void testMethodA(String[] a, String[] b) {}
public void testMethodB(String[] a, test.pkg.String[] b) {}
public void testMethodC(String[] a, java.lang.String[] b) {}
public void testMethodD(java.lang.String... a, test.pkg.String... b) {}
}
"""
)
),
proguard = """
-keep class test.pkg.MyClass {
<init>();
public void testMethodA(test.pkg.String, test.pkg.String);
public void testMethodB(test.pkg.String, test.pkg.String);
public void testMethodC(test.pkg.String, java.lang.String);
public void testMethodD(java.lang.String, test.pkg.String);
}
-keep class test.pkg.MyClassArrays {
<init>();
public void testMethodA(test.pkg.String[], test.pkg.String[]);
public void testMethodB(test.pkg.String[], test.pkg.String[]);
public void testMethodC(test.pkg.String[], java.lang.String[]);
public void testMethodD(java.lang.String[], test.pkg.String[]);
}
-keep class test.pkg.String {
<init>();
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@Test
fun `Multi dimensional arrays`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
public class String {}
"""
),
java(
"""
package test.pkg;
public class MyClassArrays {
public void testMethodA(String[][] a, String[][] b) {}
public void testMethodB(String[][][] a, test.pkg.String[][][] b) {}
public void testMethodC(String[][] a, java.lang.String[][] b) {}
public class InnerClass {}
public void testMethodD(InnerClass[][] a) {}
}
"""
)
),
proguard = """
-keep class test.pkg.MyClassArrays {
<init>();
public void testMethodA(test.pkg.String[][], test.pkg.String[][]);
public void testMethodB(test.pkg.String[][][], test.pkg.String[][][]);
public void testMethodC(test.pkg.String[][], java.lang.String[][]);
public void testMethodD(test.pkg.MyClassArrays${"$"}InnerClass[][]);
}
-keep class test.pkg.MyClassArrays${"$"}InnerClass {
<init>();
}
-keep class test.pkg.String {
<init>();
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
@Test
fun `Methods with arrays as the return type`() {
check(
sourceFiles = arrayOf(
java(
"""
package test.pkg;
public class MyClass {
public String[] testMethodA() {}
public String[][] testMethodB() {}
public String[][][] testMethodC() {}
}
"""
),
java(
"""
package test.pkg;
public class MyOtherClass {
public java.lang.String[] testMethodA() {}
public String[][] testMethodB() {}
public test.pkg.String[][][] testMethodC() {}
}
"""
),
java(
"""
package test.pkg;
public class String {}
"""
)
),
proguard = """
-keep class test.pkg.MyClass {
<init>();
public test.pkg.String[] testMethodA();
public test.pkg.String[][] testMethodB();
public test.pkg.String[][][] testMethodC();
}
-keep class test.pkg.MyOtherClass {
<init>();
public java.lang.String[] testMethodA();
public test.pkg.String[][] testMethodB();
public test.pkg.String[][][] testMethodC();
}
-keep class test.pkg.String {
<init>();
}
""",
extraArguments = arrayOf(ARG_HIDE, "KotlinKeyword")
)
}
}