blob: 1adf1812e272313865bc5c4b662c1fd36bb4c569 [file] [log] [blame]
/*
* Copyright (C) 2020 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 ApiAnalyzerTest : DriverTest() {
@Test
fun `Hidden abstract method with show @SystemApi`() {
check(
showAnnotations = arrayOf("android.annotation.SystemApi"),
expectedIssues = """
src/test/pkg/SystemApiClass.java:7: error: badAbstractHiddenMethod cannot be hidden and abstract when SystemApiClass has a visible constructor, in case a third-party attempts to subclass it. [HiddenAbstractMethod]
src/test/pkg/PublicClass.java:5: error: badAbstractHiddenMethod cannot be hidden and abstract when PublicClass has a visible constructor, in case a third-party attempts to subclass it. [HiddenAbstractMethod]
src/test/pkg/PublicClass.java:6: error: badPackagePrivateMethod cannot be hidden and abstract when PublicClass has a visible constructor, in case a third-party attempts to subclass it. [HiddenAbstractMethod]
""",
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.SystemApi;
public abstract class PublicClass {
/** @hide */
public abstract boolean badAbstractHiddenMethod() { return true; }
abstract void badPackagePrivateMethod() { }
/**
* This method does not fail because it is visible due to showAnnotations,
* instead it will fail when running analysis on public API. See test below.
* @hide
*/
@SystemApi
public abstract boolean goodAbstractSystemHiddenMethod() { return true; }
}
"""
),
java(
"""
package test.pkg;
import android.annotation.SystemApi;
public abstract class PublicClassWithHiddenConstructor {
private PublicClassWithHiddenConstructor() { }
/** @hide */
public abstract boolean goodAbstractHiddenMethod() { return true; }
}
"""
),
java(
"""
package test.pkg;
import android.annotation.SystemApi;
/** @hide */
@SystemApi
public abstract class SystemApiClass {
/** @hide */
public abstract boolean badAbstractHiddenMethod() { return true; }
/**
* This method is OK, because it matches visibility of the class
* @hide
*/
@SystemApi
public abstract boolean goodAbstractSystemHiddenMethod() { return true; }
public abstract boolean goodAbstractPublicMethod() { return true; }
}
"""
),
java(
"""
package test.pkg;
import android.annotation.SystemApi;
/** This class is OK because it is all hidden @hide */
public abstract class HiddenClass {
public abstract boolean goodAbstractHiddenMethod() { return true; }
}
"""
),
systemApiSource
)
)
}
@Test
fun `Hidden abstract method for public API`() {
check(
expectedIssues = """
src/test/pkg/PublicClass.java:5: error: badAbstractHiddenMethod cannot be hidden and abstract when PublicClass has a visible constructor, in case a third-party attempts to subclass it. [HiddenAbstractMethod]
src/test/pkg/PublicClass.java:6: error: badPackagePrivateMethod cannot be hidden and abstract when PublicClass has a visible constructor, in case a third-party attempts to subclass it. [HiddenAbstractMethod]
src/test/pkg/PublicClass.java:9: error: badAbstractSystemHiddenMethod cannot be hidden and abstract when PublicClass has a visible constructor, in case a third-party attempts to subclass it. [HiddenAbstractMethod]
""",
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.SystemApi;
public abstract class PublicClass {
/** @hide */
public abstract boolean badAbstractHiddenMethod() { return true; }
abstract void badPackagePrivateMethod() { }
/** @hide */
@SystemApi
public abstract boolean badAbstractSystemHiddenMethod() { return true; }
}
"""
),
systemApiSource
)
)
}
}