K1: add deprecation for implicit non-public calls #KT-54762 Fixed
This commit is contained in:
committed by
Space Team
parent
f4b5f5ff5d
commit
ac514849f4
+6
@@ -375,6 +375,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/initializedAfterRethrow.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineDeprecationsOnImplicitCalls.kt")
|
||||
public void testInlineDeprecationsOnImplicitCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inlineDeprecationsOnImplicitCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvokeAndRecursiveResolve.kt")
|
||||
public void testInvokeAndRecursiveResolve() throws Exception {
|
||||
|
||||
+6
@@ -375,6 +375,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/initializedAfterRethrow.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineDeprecationsOnImplicitCalls.kt")
|
||||
public void testInlineDeprecationsOnImplicitCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inlineDeprecationsOnImplicitCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvokeAndRecursiveResolve.kt")
|
||||
public void testInvokeAndRecursiveResolve() throws Exception {
|
||||
|
||||
+6
@@ -375,6 +375,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/initializedAfterRethrow.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineDeprecationsOnImplicitCalls.kt")
|
||||
public void testInlineDeprecationsOnImplicitCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inlineDeprecationsOnImplicitCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvokeAndRecursiveResolve.kt")
|
||||
public void testInvokeAndRecursiveResolve() throws Exception {
|
||||
|
||||
@@ -1272,6 +1272,7 @@ public interface Errors {
|
||||
//Inline and inlinable parameters
|
||||
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> NON_PUBLIC_CALL_FROM_PUBLIC_INLINE =
|
||||
DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
||||
DiagnosticFactory0<KtElement> DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS = DiagnosticFactory0.create(WARNING, CALL_ELEMENT);
|
||||
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> PRIVATE_CLASS_MEMBER_FROM_INLINE =
|
||||
DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
||||
DiagnosticFactory1<KtElement, KtElement> NON_LOCAL_RETURN_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, CALL_ELEMENT);
|
||||
|
||||
+1
@@ -1106,6 +1106,7 @@ public class DefaultErrorMessages {
|
||||
|
||||
//Inline
|
||||
MAP.put(NON_PUBLIC_CALL_FROM_PUBLIC_INLINE, "Public-API inline function cannot access non-public-API ''{0}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
MAP.put(DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS, "Deprecated implicit access of non-public-API from public-API inline function");
|
||||
MAP.put(PRIVATE_CLASS_MEMBER_FROM_INLINE, "Non-private inline function cannot access members of private classes: ''{0}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES);
|
||||
MAP.put(NOT_YET_SUPPORTED_IN_INLINE, "{0} are not yet supported in inline functions", STRING);
|
||||
MAP.put(DECLARATION_CANT_BE_INLINED, "'inline' modifier is not allowed on virtual members. Only private or final members can be inlined");
|
||||
|
||||
@@ -91,8 +91,9 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
}
|
||||
}
|
||||
|
||||
checkVisibilityAndAccess(targetDescriptor, expression, context, call)
|
||||
checkRecursion(context, targetDescriptor, expression)
|
||||
val replacementForReport = (call.dispatchReceiver as? ExpressionReceiver)?.expression
|
||||
checkVisibilityAndAccess(targetDescriptor, expression, replacementForReport, context, call)
|
||||
checkRecursion(context, targetDescriptor, expression, replacementForReport)
|
||||
}
|
||||
|
||||
private fun checkNotInDefaultParameter(context: CallCheckerContext, expression: KtExpression) =
|
||||
@@ -233,10 +234,12 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
private fun checkRecursion(
|
||||
context: CallCheckerContext,
|
||||
targetDescriptor: CallableDescriptor,
|
||||
expression: KtElement
|
||||
expression: KtElement,
|
||||
replacementForReport: KtElement?
|
||||
) {
|
||||
if (targetDescriptor.original === descriptor) {
|
||||
context.trace.report(RECURSION_IN_INLINE.on(expression, expression, descriptor))
|
||||
context.reportDeprecationOnReplacement(expression, replacementForReport)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +258,7 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
private fun checkVisibilityAndAccess(
|
||||
calledDescriptor: CallableDescriptor,
|
||||
expression: KtElement,
|
||||
replacementForReport: KtElement?,
|
||||
context: CallCheckerContext,
|
||||
call: Call
|
||||
) {
|
||||
@@ -267,10 +271,12 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
val isInlineFunPublicOrPublishedApi = inlineFunEffectiveVisibility.publicApi
|
||||
if (isInlineFunPublicOrPublishedApi &&
|
||||
!isCalledFunPublicOrPublishedApi &&
|
||||
calledDescriptor.visibility !== DescriptorVisibilities.LOCAL) {
|
||||
calledDescriptor.visibility !== DescriptorVisibilities.LOCAL
|
||||
) {
|
||||
context.trace.report(NON_PUBLIC_CALL_FROM_PUBLIC_INLINE.on(expression, calledDescriptor, descriptor))
|
||||
context.reportDeprecationOnReplacement(expression, replacementForReport)
|
||||
} else {
|
||||
checkPrivateClassMemberAccess(calledDescriptor, expression, context)
|
||||
checkPrivateClassMemberAccess(calledDescriptor, expression, replacementForReport, context)
|
||||
if (isInlineFunPublicOrPublishedApi) {
|
||||
checkSuperCalls(calledDescriptor, call, expression, context)
|
||||
}
|
||||
@@ -280,7 +286,8 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
if ((!isConstructorCall || expression !is KtConstructorCalleeExpression) &&
|
||||
isInlineFunPublicOrPublishedApi &&
|
||||
inlineFunEffectiveVisibility.toVisibility() !== Visibilities.Protected &&
|
||||
calledFunEffectiveVisibility.toVisibility() === Visibilities.Protected) {
|
||||
calledFunEffectiveVisibility.toVisibility() === Visibilities.Protected
|
||||
) {
|
||||
when {
|
||||
isConstructorCall -> {
|
||||
context.trace.report(
|
||||
@@ -293,17 +300,20 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
)
|
||||
}
|
||||
}
|
||||
context.reportDeprecationOnReplacement(expression, replacementForReport)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkPrivateClassMemberAccess(
|
||||
declarationDescriptor: DeclarationDescriptor,
|
||||
expression: KtElement,
|
||||
replacementForReport: KtElement?,
|
||||
context: CallCheckerContext
|
||||
) {
|
||||
if (!isEffectivelyPrivateApiFunction) {
|
||||
if (declarationDescriptor.isInsidePrivateClass) {
|
||||
context.trace.report(PRIVATE_CLASS_MEMBER_FROM_INLINE.on(expression, declarationDescriptor, descriptor))
|
||||
context.reportDeprecationOnReplacement(expression, replacementForReport)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -356,4 +366,13 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
|
||||
context.trace.report(NON_LOCAL_RETURN_NOT_ALLOWED.on(parameterUsage, parameterUsage))
|
||||
}
|
||||
}
|
||||
|
||||
private fun CallCheckerContext.reportDeprecationOnReplacement(
|
||||
expression: KtElement,
|
||||
replacementForReport: KtElement?
|
||||
) {
|
||||
if (!expression.isPhysical && replacementForReport != null) {
|
||||
trace.report(DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS.on(replacementForReport))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||
|
||||
@PublishedApi
|
||||
internal class InternalClassPrivateConstructor private constructor() {
|
||||
companion object {
|
||||
internal inline operator fun invoke(): InternalClassPrivateConstructor = InternalClassPrivateConstructor()
|
||||
|
||||
internal inline operator fun invoke(i: Int): InternalClassPrivateConstructor = <!RECURSION_IN_INLINE!>InternalClassPrivateConstructor<!>(i)
|
||||
}
|
||||
}
|
||||
|
||||
private class PrivateClass public constructor() {
|
||||
|
||||
operator fun invoke() = 42
|
||||
}
|
||||
|
||||
open class OpenClass {
|
||||
|
||||
protected operator fun invoke() = 42
|
||||
|
||||
inline fun foo() {
|
||||
<!PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR!>this<!>()
|
||||
}
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal open class InternalClassProtectedConstructor protected constructor() {
|
||||
companion object {
|
||||
internal inline operator fun invoke(): InternalClassProtectedConstructor = InternalClassProtectedConstructor()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun publicInline() {
|
||||
<!NON_PUBLIC_CALL_FROM_PUBLIC_INLINE!>InternalClassPrivateConstructor<!>()
|
||||
InternalClassPrivateConstructor.<!NON_PUBLIC_CALL_FROM_PUBLIC_INLINE!>invoke<!>()
|
||||
<!NON_PUBLIC_CALL_FROM_PUBLIC_INLINE!>InternalClassProtectedConstructor<!>()
|
||||
}
|
||||
|
||||
internal inline fun internalInline() {
|
||||
val pc = <!PRIVATE_CLASS_MEMBER_FROM_INLINE!>PrivateClass<!>()
|
||||
<!PRIVATE_CLASS_MEMBER_FROM_INLINE!>pc<!>()
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// !DIAGNOSTICS: -NOTHING_TO_INLINE
|
||||
|
||||
@PublishedApi
|
||||
internal class InternalClassPrivateConstructor private constructor() {
|
||||
companion object {
|
||||
internal inline operator fun invoke(): InternalClassPrivateConstructor = InternalClassPrivateConstructor()
|
||||
|
||||
internal inline operator fun invoke(i: Int): InternalClassPrivateConstructor = <!DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS!>InternalClassPrivateConstructor<!>(i)
|
||||
}
|
||||
}
|
||||
|
||||
private class PrivateClass public constructor() {
|
||||
|
||||
operator fun invoke() = 42
|
||||
}
|
||||
|
||||
open class OpenClass {
|
||||
|
||||
protected operator fun invoke() = 42
|
||||
|
||||
inline fun foo() {
|
||||
<!DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS!>this<!>()
|
||||
}
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal open class InternalClassProtectedConstructor protected constructor() {
|
||||
companion object {
|
||||
internal inline operator fun invoke(): InternalClassProtectedConstructor = InternalClassProtectedConstructor()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun publicInline() {
|
||||
<!DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS!>InternalClassPrivateConstructor<!>()
|
||||
InternalClassPrivateConstructor.<!NON_PUBLIC_CALL_FROM_PUBLIC_INLINE!>invoke<!>()
|
||||
<!DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS!>InternalClassProtectedConstructor<!>()
|
||||
}
|
||||
|
||||
internal inline fun internalInline() {
|
||||
val pc = <!PRIVATE_CLASS_MEMBER_FROM_INLINE!>PrivateClass<!>()
|
||||
<!DEPRECATED_IMPLICIT_NON_PUBLIC_API_ACCESS!>pc<!>()
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package
|
||||
|
||||
internal inline fun internalInline(): kotlin.Unit
|
||||
public inline fun publicInline(): kotlin.Unit
|
||||
|
||||
@kotlin.PublishedApi internal final class InternalClassPrivateConstructor {
|
||||
private constructor InternalClassPrivateConstructor()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public companion object Companion {
|
||||
private constructor Companion()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal final inline operator fun invoke(): InternalClassPrivateConstructor
|
||||
internal final inline operator fun invoke(/*0*/ i: kotlin.Int): InternalClassPrivateConstructor
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
@kotlin.PublishedApi internal open class InternalClassProtectedConstructor {
|
||||
protected constructor InternalClassProtectedConstructor()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public companion object Companion {
|
||||
private constructor Companion()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
internal final inline operator fun invoke(): InternalClassProtectedConstructor
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
public open class OpenClass {
|
||||
public constructor OpenClass()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final inline fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
protected final operator fun invoke(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private final class PrivateClass {
|
||||
public constructor PrivateClass()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun invoke(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Generated
+6
@@ -375,6 +375,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/initializedAfterRethrow.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineDeprecationsOnImplicitCalls.kt")
|
||||
public void testInlineDeprecationsOnImplicitCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inlineDeprecationsOnImplicitCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InvokeAndRecursiveResolve.kt")
|
||||
public void testInvokeAndRecursiveResolve() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user