Exclude public API symbols in explicit mode from unused symbol inspection
#KT-41659 Fixed
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.ExplicitApiMode
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.project.implementingDescriptors
|
||||
@@ -75,7 +76,9 @@ import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.checkers.explicitApiEnabled
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
@@ -266,6 +269,10 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
||||
|
||||
// More expensive, resolve-based checks
|
||||
val descriptor = declaration.resolveToDescriptorIfAny() ?: return
|
||||
if (declaration.languageVersionSettings.explicitApiEnabled
|
||||
&& (descriptor as? DeclarationDescriptorWithVisibility)?.isEffectivelyPublicApi == true) {
|
||||
return
|
||||
}
|
||||
if (descriptor is FunctionDescriptor && descriptor.isOperator) return
|
||||
val isCheapEnough = lazy(LazyThreadSafetyMode.NONE) {
|
||||
isCheapEnoughToSearchUsages(declaration)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// PROBLEM: none
|
||||
// COMPILER_ARGUMENTS: -Xexplicit-api=strict
|
||||
|
||||
public class <caret>X {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// PROBLEM: none
|
||||
// COMPILER_ARGUMENTS: -Xexplicit-api=strict
|
||||
|
||||
public fun String.<caret>baz() {}
|
||||
@@ -0,0 +1,6 @@
|
||||
// PROBLEM: none
|
||||
// COMPILER_ARGUMENTS: -Xexplicit-api=strict
|
||||
|
||||
public class X {
|
||||
public fun <caret>foo() {}
|
||||
}
|
||||
+15
@@ -14529,11 +14529,26 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
runTest("idea/testData/inspectionsLocal/unusedSymbol/typeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unusedClassExplicitApi.kt")
|
||||
public void testUnusedClassExplicitApi() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedSymbol/unusedClassExplicitApi.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unusedEnumEntry.kt")
|
||||
public void testUnusedEnumEntry() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedSymbol/unusedEnumEntry.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unusedExtensionExplicitApi.kt")
|
||||
public void testUnusedExtensionExplicitApi() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedSymbol/unusedExtensionExplicitApi.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unusedFunctionExplicitApi.kt")
|
||||
public void testUnusedFunctionExplicitApi() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedSymbol/unusedFunctionExplicitApi.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("usedEnumFunction.kt")
|
||||
public void testUsedEnumFunction() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedSymbol/usedEnumFunction.kt");
|
||||
|
||||
Reference in New Issue
Block a user