[FIR] Implement deprecation for accessing private operators from public inline function
This only affects delegation operators as well as the for-loop-related next and hasNext operators. All the other operators worked correctly before. In K2, the previously mentioned operator calls will be flagged with a deprecation error and will become and error in 2.1. #KT-59782 Fixed
This commit is contained in:
committed by
Space Team
parent
58c03e021b
commit
376a9b8ace
+5
@@ -1651,6 +1651,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<Symbol>("referencedDeclaration")
|
||||
}
|
||||
|
||||
val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION by warning<KtElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||
parameter<Symbol>("inlineDeclaration")
|
||||
parameter<Symbol>("referencedDeclaration")
|
||||
}
|
||||
|
||||
val PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE by error<KtElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
|
||||
parameter<Symbol>("inlineDeclaration")
|
||||
parameter<Symbol>("referencedDeclaration")
|
||||
|
||||
@@ -833,6 +833,7 @@ object FirErrors {
|
||||
val NULLABLE_INLINE_PARAMETER: KtDiagnosticFactory2<FirValueParameterSymbol, FirBasedSymbol<*>> by error2<KtDeclaration, FirValueParameterSymbol, FirBasedSymbol<*>>()
|
||||
val RECURSION_IN_INLINE: KtDiagnosticFactory1<FirBasedSymbol<*>> by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE: KtDiagnosticFactory2<FirBasedSymbol<*>, FirBasedSymbol<*>> by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION: KtDiagnosticFactory2<FirBasedSymbol<*>, FirBasedSymbol<*>> by warning2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE: KtDiagnosticFactory2<FirBasedSymbol<*>, FirBasedSymbol<*>> by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR: KtDiagnosticFactory2<FirBasedSymbol<*>, FirBasedSymbol<*>> by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
val PROTECTED_CALL_FROM_PUBLIC_INLINE: KtDiagnosticFactory2<FirBasedSymbol<*>, FirBasedSymbol<*>> by warning2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+21
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.references.symbol
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.publishedApiEffectiveVisibility
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
@@ -91,7 +93,7 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
) {
|
||||
reporter.reportOn(
|
||||
source,
|
||||
FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE,
|
||||
getNonPublicCallFromPublicInlineFactory(accessExpression, source, context),
|
||||
inlineFunction.symbol,
|
||||
accessedSymbol,
|
||||
context
|
||||
@@ -106,6 +108,24 @@ object FirInlineDeclarationChecker : FirFunctionChecker(MppCheckerKind.Common) {
|
||||
)
|
||||
}
|
||||
|
||||
private fun getNonPublicCallFromPublicInlineFactory(
|
||||
accessExpression: FirStatement,
|
||||
source: KtSourceElement,
|
||||
context: CheckerContext,
|
||||
): KtDiagnosticFactory2<FirBasedSymbol<*>, FirBasedSymbol<*>> {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitPrivateOperatorCallInInline)) {
|
||||
val isDelegatedPropertyAccessor = source.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor
|
||||
val isForLoopButNotIteratorCall = source.kind == KtFakeSourceElementKind.DesugaredForLoop &&
|
||||
accessExpression.toReference(context.session)?.symbol?.memberDeclarationNameOrNull != OperatorNameConventions.ITERATOR
|
||||
|
||||
if (isDelegatedPropertyAccessor || isForLoopButNotIteratorCall) {
|
||||
return FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION
|
||||
}
|
||||
}
|
||||
|
||||
return FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE
|
||||
}
|
||||
|
||||
private fun EffectiveVisibility.isReachableDueToLocalDispatchReceiver(access: FirStatement, context: CheckerContext): Boolean {
|
||||
val receiverType = access.localDispatchReceiver(context) ?: return false
|
||||
val receiverProtected = EffectiveVisibility.Protected(receiverType.typeConstructor(context.session.typeContext))
|
||||
|
||||
+9
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticRenderers.CLASS_ID
|
||||
import org.jetbrains.kotlin.diagnostics.KtDiagnosticRenderers.COLLECTION
|
||||
@@ -504,6 +505,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PLATFORM_CLASS_MA
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPILER_REQUIRED_ANNOTATION_AMBIGUITY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_LABELS_ARE_FORBIDDEN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.POTENTIALLY_NON_REPORTED_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRE_RELEASE_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED
|
||||
@@ -2427,6 +2429,13 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
)
|
||||
map.put(RECURSION_IN_INLINE, "Inline function ''{0}'' cannot be recursive.", SYMBOL)
|
||||
map.put(NON_PUBLIC_CALL_FROM_PUBLIC_INLINE, "Public-API inline function cannot access non-public-API ''{0}''.", SYMBOL, SYMBOL)
|
||||
map.put(
|
||||
NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION,
|
||||
"Public-API inline function cannot access non-public-API ''{0}''. " +
|
||||
"This will become an error in Kotlin ${LanguageFeature.ProhibitPrivateOperatorCallInInline.sinceVersion?.versionString}.",
|
||||
SYMBOL,
|
||||
SYMBOL
|
||||
)
|
||||
map.put(
|
||||
PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE,
|
||||
"Protected constructor call from public-API inline function is deprecated.",
|
||||
|
||||
Reference in New Issue
Block a user