Weaken PRIVATE_CLASS_MEMBER_FROM_INLINE diagnostic
This commit is contained in:
+3
-2
@@ -52,12 +52,13 @@ class InlineChecker implements CallChecker {
|
|||||||
private final SimpleFunctionDescriptor descriptor;
|
private final SimpleFunctionDescriptor descriptor;
|
||||||
private final Set<CallableDescriptor> inlinableParameters = new LinkedHashSet<CallableDescriptor>();
|
private final Set<CallableDescriptor> inlinableParameters = new LinkedHashSet<CallableDescriptor>();
|
||||||
private final boolean isEffectivelyPublicApiFunction;
|
private final boolean isEffectivelyPublicApiFunction;
|
||||||
|
private final boolean isEffectivelyPrivateApiFunction;
|
||||||
|
|
||||||
public InlineChecker(@NotNull SimpleFunctionDescriptor descriptor) {
|
public InlineChecker(@NotNull SimpleFunctionDescriptor descriptor) {
|
||||||
assert InlineUtil.isInline(descriptor) : "This extension should be created only for inline functions: " + descriptor;
|
assert InlineUtil.isInline(descriptor) : "This extension should be created only for inline functions: " + descriptor;
|
||||||
this.descriptor = descriptor;
|
this.descriptor = descriptor;
|
||||||
this.isEffectivelyPublicApiFunction = DescriptorUtilsKt.isEffectivelyPublicApi(descriptor);
|
this.isEffectivelyPublicApiFunction = DescriptorUtilsKt.isEffectivelyPublicApi(descriptor);
|
||||||
|
this.isEffectivelyPrivateApiFunction = DescriptorUtilsKt.isEffectivelyPrivateApi(descriptor);
|
||||||
for (ValueParameterDescriptor param : descriptor.getValueParameters()) {
|
for (ValueParameterDescriptor param : descriptor.getValueParameters()) {
|
||||||
if (isInlinableParameter(param)) {
|
if (isInlinableParameter(param)) {
|
||||||
inlinableParameters.add(param);
|
inlinableParameters.add(param);
|
||||||
@@ -253,7 +254,7 @@ class InlineChecker implements CallChecker {
|
|||||||
@NotNull KtElement expression,
|
@NotNull KtElement expression,
|
||||||
@NotNull BasicCallResolutionContext context
|
@NotNull BasicCallResolutionContext context
|
||||||
) {
|
) {
|
||||||
if (!Visibilities.isPrivate(descriptor.getVisibility())) {
|
if (!isEffectivelyPrivateApiFunction) {
|
||||||
if (DescriptorUtilsKt.isInsidePrivateClass(declarationDescriptor)) {
|
if (DescriptorUtilsKt.isInsidePrivateClass(declarationDescriptor)) {
|
||||||
context.trace.report(Errors.PRIVATE_CLASS_MEMBER_FROM_INLINE.on(expression, declarationDescriptor, descriptor));
|
context.trace.report(Errors.PRIVATE_CLASS_MEMBER_FROM_INLINE.on(expression, declarationDescriptor, descriptor));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import test.*
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
return Test().run()
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
private abstract class Base {
|
||||||
|
protected fun duplicate(s: String) = s + "K"
|
||||||
|
|
||||||
|
protected inline fun doInline(block: () -> String): String {
|
||||||
|
return duplicate(block())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Extender: Base() {
|
||||||
|
fun doSomething(): String {
|
||||||
|
return doInline { "O" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun run(): String {
|
||||||
|
return Extender().doSomething();
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -1381,6 +1381,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/private"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/private"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("effectivePrivate.1.kt")
|
||||||
|
public void testEffectivePrivate() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/effectivePrivate.1.kt");
|
||||||
|
doTestMultiFileWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt6453.1.kt")
|
@TestMetadata("kt6453.1.kt")
|
||||||
public void testKt6453() throws Exception {
|
public void testKt6453() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/kt6453.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/kt6453.1.kt");
|
||||||
|
|||||||
+6
@@ -1381,6 +1381,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/private"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/private"), Pattern.compile("^(.+)\\.1.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("effectivePrivate.1.kt")
|
||||||
|
public void testEffectivePrivate() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/effectivePrivate.1.kt");
|
||||||
|
doBoxTestWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt6453.1.kt")
|
@TestMetadata("kt6453.1.kt")
|
||||||
public void testKt6453() throws Exception {
|
public void testKt6453() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/kt6453.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/kt6453.1.kt");
|
||||||
|
|||||||
@@ -106,6 +106,20 @@ val DeclarationDescriptorWithVisibility.isEffectivelyPublicApi: Boolean
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val DeclarationDescriptorWithVisibility.isEffectivelyPrivateApi: Boolean
|
||||||
|
get() {
|
||||||
|
var parent: DeclarationDescriptorWithVisibility? = this
|
||||||
|
|
||||||
|
while (parent != null) {
|
||||||
|
if (Visibilities.isPrivate(parent.visibility)) return true
|
||||||
|
|
||||||
|
parent = DescriptorUtils.getParentOfType(parent, DeclarationDescriptorWithVisibility::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val DeclarationDescriptor.isInsidePrivateClass: Boolean
|
val DeclarationDescriptor.isInsidePrivateClass: Boolean
|
||||||
get() {
|
get() {
|
||||||
var parent = containingDeclaration as? ClassDescriptor
|
var parent = containingDeclaration as? ClassDescriptor
|
||||||
|
|||||||
@@ -1066,7 +1066,7 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestGroup(val testsRoot: String, val testDataRoot: String) {
|
private class TestGroup(val testsRoot: String, val testDataRoot: String) {
|
||||||
inline fun <reified T: TestCase> testClass(
|
inline fun <reified T: TestCase> testClass(
|
||||||
suiteTestClass: String = getDefaultSuiteTestClass(T::class.java),
|
suiteTestClass: String = getDefaultSuiteTestClass(T::class.java),
|
||||||
noinline init: TestClass.() -> Unit
|
noinline init: TestClass.() -> Unit
|
||||||
|
|||||||
Reference in New Issue
Block a user