Fix accessibility check for experimental declarations from default scope
#KT-40919 Fixed
This commit is contained in:
+1
@@ -80,6 +80,7 @@ class KotlinResolutionStatelessCallbacksImpl(
|
|||||||
kotlinCallArgument.psiCallArgument.psiExpression,
|
kotlinCallArgument.psiCallArgument.psiExpression,
|
||||||
(resolutionCallbacks as? KotlinResolutionCallbacksImpl)?.trace?.bindingContext,
|
(resolutionCallbacks as? KotlinResolutionCallbacksImpl)?.trace?.bindingContext,
|
||||||
isSuperCall = false,
|
isSuperCall = false,
|
||||||
|
fromImportingScope = false
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean =
|
override fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean =
|
||||||
|
|||||||
+11
-6
@@ -64,15 +64,17 @@ class DeprecationResolver(
|
|||||||
descriptor: DeclarationDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
call: Call? = null,
|
call: Call? = null,
|
||||||
bindingContext: BindingContext? = null,
|
bindingContext: BindingContext? = null,
|
||||||
isSuperCall: Boolean = false
|
isSuperCall: Boolean = false,
|
||||||
|
fromImportingScope: Boolean = false
|
||||||
): Boolean =
|
): Boolean =
|
||||||
isHiddenInResolution(descriptor, call?.callElement, bindingContext, isSuperCall)
|
isHiddenInResolution(descriptor, call?.callElement, bindingContext, isSuperCall, fromImportingScope)
|
||||||
|
|
||||||
fun isHiddenInResolution(
|
fun isHiddenInResolution(
|
||||||
descriptor: DeclarationDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
callElement: KtElement?,
|
callElement: KtElement?,
|
||||||
bindingContext: BindingContext?,
|
bindingContext: BindingContext?,
|
||||||
isSuperCall: Boolean
|
isSuperCall: Boolean,
|
||||||
|
fromImportingScope: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (descriptor is FunctionDescriptor) {
|
if (descriptor is FunctionDescriptor) {
|
||||||
if (descriptor.isHiddenToOvercomeSignatureClash) return true
|
if (descriptor.isHiddenToOvercomeSignatureClash) return true
|
||||||
@@ -83,14 +85,17 @@ class DeprecationResolver(
|
|||||||
if (sinceKotlinAccessibility is SinceKotlinAccessibility.NotAccessible) return true
|
if (sinceKotlinAccessibility is SinceKotlinAccessibility.NotAccessible) return true
|
||||||
|
|
||||||
if (sinceKotlinAccessibility is SinceKotlinAccessibility.NotAccessibleButWasExperimental) {
|
if (sinceKotlinAccessibility is SinceKotlinAccessibility.NotAccessibleButWasExperimental) {
|
||||||
if (callElement != null && bindingContext != null) {
|
return if (callElement != null && bindingContext != null) {
|
||||||
return with(ExperimentalUsageChecker) {
|
with(ExperimentalUsageChecker) {
|
||||||
sinceKotlinAccessibility.markerClasses.any { classDescriptor ->
|
sinceKotlinAccessibility.markerClasses.any { classDescriptor ->
|
||||||
!callElement.isExperimentalityAccepted(classDescriptor.fqNameSafe, languageVersionSettings, bindingContext)
|
!callElement.isExperimentalityAccepted(classDescriptor.fqNameSafe, languageVersionSettings, bindingContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// We need a softer check for descriptors from importing scope as there is no access to PSI elements
|
||||||
|
// It's fine to return false here as there will be additional checks for accessibility later
|
||||||
|
!fromImportingScope
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return isDeprecatedHidden(descriptor)
|
return isDeprecatedHidden(descriptor)
|
||||||
|
|||||||
@@ -235,7 +235,8 @@ class LazyImportScope(
|
|||||||
private fun LazyImportResolver<*>.isClassifierVisible(descriptor: ClassifierDescriptor): Boolean {
|
private fun LazyImportResolver<*>.isClassifierVisible(descriptor: ClassifierDescriptor): Boolean {
|
||||||
if (filteringKind == FilteringKind.ALL) return true
|
if (filteringKind == FilteringKind.ALL) return true
|
||||||
|
|
||||||
if (components.deprecationResolver.isHiddenInResolution(descriptor)) return false
|
// TODO: do not perform this check here because for correct work it requires corresponding PSI element
|
||||||
|
if (components.deprecationResolver.isHiddenInResolution(descriptor, fromImportingScope = true)) return false
|
||||||
|
|
||||||
val visibility = (descriptor as DeclarationDescriptorWithVisibility).visibility
|
val visibility = (descriptor as DeclarationDescriptorWithVisibility).visibility
|
||||||
val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES
|
val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
$TESTDATA_DIR$/useDeclarationThatWasExperimentalWithoutExplicitImport.kt
|
||||||
|
-d
|
||||||
|
$TEMP_DIR$
|
||||||
|
-language-version
|
||||||
|
1.3
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
@ExperimentalStdlibApi
|
||||||
|
fun test(s: ArrayDeque<Int>): ArrayDeque<Int>? {
|
||||||
|
ArrayDeque<Int>(42)
|
||||||
|
|
||||||
|
val x: ArrayDeque<Int>? = null
|
||||||
|
return x ?: s
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
OK
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
$TESTDATA_DIR$/useDeclarationThatWasExperimentalWithoutMarker.kt
|
||||||
|
-d
|
||||||
|
$TEMP_DIR$
|
||||||
|
-language-version
|
||||||
|
1.3
|
||||||
|
-Xopt-in=kotlin.ExperimentalStdlibApi
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
OK
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
$TESTDATA_DIR$/useDeclarationThatWasExperimentalWithoutMarker.kt
|
||||||
|
-d
|
||||||
|
$TEMP_DIR$
|
||||||
|
-language-version
|
||||||
|
1.3
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun test(s: ArrayDeque<Int>): ArrayDeque<Int>? {
|
||||||
|
ArrayDeque<Int>(42)
|
||||||
|
|
||||||
|
val x: ArrayDeque<Int>? = null
|
||||||
|
return x ?: s
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:1:13: error: this declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)'
|
||||||
|
fun test(s: ArrayDeque<Int>): ArrayDeque<Int>? {
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:1:31: error: this declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)'
|
||||||
|
fun test(s: ArrayDeque<Int>): ArrayDeque<Int>? {
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:2:5: error: unresolved reference: ArrayDeque
|
||||||
|
ArrayDeque<Int>(42)
|
||||||
|
^
|
||||||
|
compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:4:12: error: this declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)'
|
||||||
|
val x: ArrayDeque<Int>? = null
|
||||||
|
^
|
||||||
|
COMPILATION_ERROR
|
||||||
@@ -720,6 +720,21 @@ public class CliTestGenerated extends AbstractCliTest {
|
|||||||
runTest("compiler/testData/cli/jvm/unknownExtraFlags.args");
|
runTest("compiler/testData/cli/jvm/unknownExtraFlags.args");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("useDeclarationThatWasExperimentalWithoutExplicitImport.args")
|
||||||
|
public void testUseDeclarationThatWasExperimentalWithoutExplicitImport() throws Exception {
|
||||||
|
runTest("compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutExplicitImport.args");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("useDeclarationThatWasExperimentalWithoutExplicitImportCommandLine.args")
|
||||||
|
public void testUseDeclarationThatWasExperimentalWithoutExplicitImportCommandLine() throws Exception {
|
||||||
|
runTest("compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutExplicitImportCommandLine.args");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("useDeclarationThatWasExperimentalWithoutMarker.args")
|
||||||
|
public void testUseDeclarationThatWasExperimentalWithoutMarker() throws Exception {
|
||||||
|
runTest("compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.args");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("useMixedNamedArgumentsFlag.args")
|
@TestMetadata("useMixedNamedArgumentsFlag.args")
|
||||||
public void testUseMixedNamedArgumentsFlag() throws Exception {
|
public void testUseMixedNamedArgumentsFlag() throws Exception {
|
||||||
runTest("compiler/testData/cli/jvm/useMixedNamedArgumentsFlag.args");
|
runTest("compiler/testData/cli/jvm/useMixedNamedArgumentsFlag.args");
|
||||||
|
|||||||
Reference in New Issue
Block a user