From 376a9b8ace3a2952c99384743a8d558326532c43 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Fri, 2 Feb 2024 14:23:10 +0100 Subject: [PATCH] [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 --- .../diagnostics/KtFirDataClassConverters.kt | 8 +++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 6 ++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 7 +++ ...CompilerTestFE10TestdataTestGenerated.java | 12 ++++ ...sticCompilerFE10TestDataTestGenerated.java | 12 ++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 12 ++++ ...siOldFrontendDiagnosticsTestGenerated.java | 12 ++++ .../diagnostics/FirDiagnosticsList.kt | 5 ++ .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../FirInlineDeclarationChecker.kt | 22 ++++++- .../diagnostics/FirErrorsDefaultMessages.kt | 9 +++ .../privateOperatorsInInlineAfter.fir.kt | 63 +++++++++++++++++++ .../inline/privateOperatorsInInlineAfter.kt | 63 +++++++++++++++++++ .../privateOperatorsInInlineBefore.fir.kt | 63 +++++++++++++++++++ .../inline/privateOperatorsInInlineBefore.kt | 63 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 12 ++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + 17 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt create mode 100644 compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 336eb0ab3f7..ef175f93970 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -4721,6 +4721,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION) { firDiagnostic -> + NonPublicCallFromPublicInlineDeprecationImpl( + firSymbolBuilder.buildSymbol(firDiagnostic.a), + firSymbolBuilder.buildSymbol(firDiagnostic.b), + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE) { firDiagnostic -> ProtectedConstructorCallFromPublicInlineImpl( firSymbolBuilder.buildSymbol(firDiagnostic.a), diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 198b6d17649..f034afeb1ec 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -3288,6 +3288,12 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { val referencedDeclaration: KtSymbol } + interface NonPublicCallFromPublicInlineDeprecation : KtFirDiagnostic { + override val diagnosticClass get() = NonPublicCallFromPublicInlineDeprecation::class + val inlineDeclaration: KtSymbol + val referencedDeclaration: KtSymbol + } + interface ProtectedConstructorCallFromPublicInline : KtFirDiagnostic { override val diagnosticClass get() = ProtectedConstructorCallFromPublicInline::class val inlineDeclaration: KtSymbol diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index f8e678e429e..e3037c15386 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -3963,6 +3963,13 @@ internal class NonPublicCallFromPublicInlineImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.NonPublicCallFromPublicInline +internal class NonPublicCallFromPublicInlineDeprecationImpl( + override val inlineDeclaration: KtSymbol, + override val referencedDeclaration: KtSymbol, + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.NonPublicCallFromPublicInlineDeprecation + internal class ProtectedConstructorCallFromPublicInlineImpl( override val inlineDeclaration: KtSymbol, override val referencedDeclaration: KtSymbol, diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index d63ef5fea89..b3ecbc597fc 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -20734,6 +20734,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/inline/privateClass.kt"); } + @Test + @TestMetadata("privateOperatorsInInlineAfter.kt") + public void testPrivateOperatorsInInlineAfter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt"); + } + + @Test + @TestMetadata("privateOperatorsInInlineBefore.kt") + public void testPrivateOperatorsInInlineBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt"); + } + @Test @TestMetadata("propagation.kt") public void testPropagation() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index c973c133604..148bbdcdfd6 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -20734,6 +20734,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/inline/privateClass.kt"); } + @Test + @TestMetadata("privateOperatorsInInlineAfter.kt") + public void testPrivateOperatorsInInlineAfter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt"); + } + + @Test + @TestMetadata("privateOperatorsInInlineBefore.kt") + public void testPrivateOperatorsInInlineBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt"); + } + @Test @TestMetadata("propagation.kt") public void testPropagation() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index de2f1513392..5ef4ce9ddc3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -20728,6 +20728,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/inline/privateClass.kt"); } + @Test + @TestMetadata("privateOperatorsInInlineAfter.kt") + public void testPrivateOperatorsInInlineAfter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt"); + } + + @Test + @TestMetadata("privateOperatorsInInlineBefore.kt") + public void testPrivateOperatorsInInlineBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt"); + } + @Test @TestMetadata("propagation.kt") public void testPropagation() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index f74753088ba..a1933493da2 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -20734,6 +20734,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/inline/privateClass.kt"); } + @Test + @TestMetadata("privateOperatorsInInlineAfter.kt") + public void testPrivateOperatorsInInlineAfter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt"); + } + + @Test + @TestMetadata("privateOperatorsInInlineBefore.kt") + public void testPrivateOperatorsInInlineBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt"); + } + @Test @TestMetadata("propagation.kt") public void testPropagation() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index cf48bf9504f..fc567b4169f 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1651,6 +1651,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("referencedDeclaration") } + val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION by warning(PositioningStrategy.REFERENCE_BY_QUALIFIED) { + parameter("inlineDeclaration") + parameter("referencedDeclaration") + } + val PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE by error(PositioningStrategy.REFERENCE_BY_QUALIFIED) { parameter("inlineDeclaration") parameter("referencedDeclaration") diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 0619158ef48..03efd783a91 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -833,6 +833,7 @@ object FirErrors { val NULLABLE_INLINE_PARAMETER: KtDiagnosticFactory2> by error2>() val RECURSION_IN_INLINE: KtDiagnosticFactory1> by error1>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE: KtDiagnosticFactory2, FirBasedSymbol<*>> by error2, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) + val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE_DEPRECATION: KtDiagnosticFactory2, FirBasedSymbol<*>> by warning2, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE: KtDiagnosticFactory2, FirBasedSymbol<*>> by error2, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR: KtDiagnosticFactory2, FirBasedSymbol<*>> by error2, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val PROTECTED_CALL_FROM_PUBLIC_INLINE: KtDiagnosticFactory2, FirBasedSymbol<*>> by warning2, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt index cf12bd76403..cd1ef818e34 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt @@ -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<*>> { + 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)) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index abcdd298eca..81b412b4ba2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -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.", diff --git a/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.fir.kt b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.fir.kt new file mode 100644 index 00000000000..da7536113ad --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.fir.kt @@ -0,0 +1,63 @@ +// WITH_STDLIB +// DIAGNOSTICS: -NOTHING_TO_INLINE +// LANGUAGE: +ProhibitPrivateOperatorCallInInline + +import kotlin.reflect.KProperty +import kotlin.properties.ReadOnlyProperty + +private operator fun String.getValue(nothing: Any?, property: KProperty<*>) = "OK" +private operator fun String.setValue(nothing: Any?, property: KProperty<*>, s: String) {} +private operator fun Int.provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty = ReadOnlyProperty { _, _ -> this } + +private operator fun O.compareTo(other: O) = 1 +private operator fun O.contains(other: O) = true +private operator fun O.invoke() {} +private operator fun O.iterator() = O +private operator fun O.next() = O +private operator fun O.hasNext() = false +private operator fun O.get(i: Int) = O +private operator fun O.set(i: Int, o: O) {} +private operator fun O.component1() = O +private operator fun O.inc() = O +private operator fun O.not() = O +private operator fun O.plus(other: O) = O +private operator fun O.unaryPlus() = O +private operator fun O.rangeTo(other: O) = O +private operator fun O.rangeUntil(other: O) = O +private operator fun O.plusAssign(other: O) {} + +object O +object P + +operator fun P.iterator() = P +private operator fun P.next() = P +private operator fun P.hasNext() = false + +inline fun foo() { + var x by "" + x + x = "" + + val y by 1 + y + + var o = O + o < o + o in o + o() + for (o1 in o) { + } + o[1] + o[1] = o + val (o2) = o + o++ + !o + o + o + +o + o..o + o..<o + O += o + + for (p in P) { + } +} diff --git a/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt new file mode 100644 index 00000000000..772a7238476 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt @@ -0,0 +1,63 @@ +// WITH_STDLIB +// DIAGNOSTICS: -NOTHING_TO_INLINE +// LANGUAGE: +ProhibitPrivateOperatorCallInInline + +import kotlin.reflect.KProperty +import kotlin.properties.ReadOnlyProperty + +private operator fun String.getValue(nothing: Any?, property: KProperty<*>) = "OK" +private operator fun String.setValue(nothing: Any?, property: KProperty<*>, s: String) {} +private operator fun Int.provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty = ReadOnlyProperty { _, _ -> this } + +private operator fun O.compareTo(other: O) = 1 +private operator fun O.contains(other: O) = true +private operator fun O.invoke() {} +private operator fun O.iterator() = O +private operator fun O.next() = O +private operator fun O.hasNext() = false +private operator fun O.get(i: Int) = O +private operator fun O.set(i: Int, o: O) {} +private operator fun O.component1() = O +private operator fun O.inc() = O +private operator fun O.not() = O +private operator fun O.plus(other: O) = O +private operator fun O.unaryPlus() = O +private operator fun O.rangeTo(other: O) = O +private operator fun O.rangeUntil(other: O) = O +private operator fun O.plusAssign(other: O) {} + +object O +object P + +operator fun P.iterator() = P +private operator fun P.next() = P +private operator fun P.hasNext() = false + +inline fun foo() { + var x by "" + x + x = "" + + val y by 1 + y + + var o = O + o < o + o in o + o() + for (o1 in o) { + } + o[1] + o[1] = o + val (o2) = o + o++ + !o + o + o + +o + o..o + o..<o + O += o + + for (p in P) { + } +} diff --git a/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.fir.kt b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.fir.kt new file mode 100644 index 00000000000..919c2f71f19 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.fir.kt @@ -0,0 +1,63 @@ +// WITH_STDLIB +// DIAGNOSTICS: -NOTHING_TO_INLINE +// LANGUAGE: -ProhibitPrivateOperatorCallInInline + +import kotlin.reflect.KProperty +import kotlin.properties.ReadOnlyProperty + +private operator fun String.getValue(nothing: Any?, property: KProperty<*>) = "OK" +private operator fun String.setValue(nothing: Any?, property: KProperty<*>, s: String) {} +private operator fun Int.provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty = ReadOnlyProperty { _, _ -> this } + +private operator fun O.compareTo(other: O) = 1 +private operator fun O.contains(other: O) = true +private operator fun O.invoke() {} +private operator fun O.iterator() = O +private operator fun O.next() = O +private operator fun O.hasNext() = false +private operator fun O.get(i: Int) = O +private operator fun O.set(i: Int, o: O) {} +private operator fun O.component1() = O +private operator fun O.inc() = O +private operator fun O.not() = O +private operator fun O.plus(other: O) = O +private operator fun O.unaryPlus() = O +private operator fun O.rangeTo(other: O) = O +private operator fun O.rangeUntil(other: O) = O +private operator fun O.plusAssign(other: O) {} + +object O +object P + +operator fun P.iterator() = P +private operator fun P.next() = P +private operator fun P.hasNext() = false + +inline fun foo() { + var x by "" + x + x = "" + + val y by 1 + y + + var o = O + o < o + o in o + o() + for (o1 in o) { + } + o[1] + o[1] = o + val (o2) = o + o++ + !o + o + o + +o + o..o + o..<o + O += o + + for (p in P) { + } +} diff --git a/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt new file mode 100644 index 00000000000..e3e0d6b7f8c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt @@ -0,0 +1,63 @@ +// WITH_STDLIB +// DIAGNOSTICS: -NOTHING_TO_INLINE +// LANGUAGE: -ProhibitPrivateOperatorCallInInline + +import kotlin.reflect.KProperty +import kotlin.properties.ReadOnlyProperty + +private operator fun String.getValue(nothing: Any?, property: KProperty<*>) = "OK" +private operator fun String.setValue(nothing: Any?, property: KProperty<*>, s: String) {} +private operator fun Int.provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty = ReadOnlyProperty { _, _ -> this } + +private operator fun O.compareTo(other: O) = 1 +private operator fun O.contains(other: O) = true +private operator fun O.invoke() {} +private operator fun O.iterator() = O +private operator fun O.next() = O +private operator fun O.hasNext() = false +private operator fun O.get(i: Int) = O +private operator fun O.set(i: Int, o: O) {} +private operator fun O.component1() = O +private operator fun O.inc() = O +private operator fun O.not() = O +private operator fun O.plus(other: O) = O +private operator fun O.unaryPlus() = O +private operator fun O.rangeTo(other: O) = O +private operator fun O.rangeUntil(other: O) = O +private operator fun O.plusAssign(other: O) {} + +object O +object P + +operator fun P.iterator() = P +private operator fun P.next() = P +private operator fun P.hasNext() = false + +inline fun foo() { + var x by "" + x + x = "" + + val y by 1 + y + + var o = O + o < o + o in o + o() + for (o1 in o) { + } + o[1] + o[1] = o + val (o2) = o + o++ + !o + o + o + +o + o..o + o..<o + O += o + + for (p in P) { + } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 2a1c086c377..0dcd1fb5933 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -20734,6 +20734,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inline/privateClass.kt"); } + @Test + @TestMetadata("privateOperatorsInInlineAfter.kt") + public void testPrivateOperatorsInInlineAfter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineAfter.kt"); + } + + @Test + @TestMetadata("privateOperatorsInInlineBefore.kt") + public void testPrivateOperatorsInInlineBefore() throws Exception { + runTest("compiler/testData/diagnostics/tests/inline/privateOperatorsInInlineBefore.kt"); + } + @Test @TestMetadata("propagation.kt") public void testPropagation() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 25f63127879..85e73be0a37 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -320,6 +320,7 @@ enum class LanguageFeature( ForbidLambdaParameterWithMissingDependencyType(KOTLIN_2_1, kind = BUG_FIX), // KT-64266 JsAllowInvalidCharsIdentifiersEscaping(KOTLIN_2_1, kind = OTHER), // KT-31799 SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced(KOTLIN_2_1, kind = BUG_FIX), // KT-63209 + ProhibitPrivateOperatorCallInInline(KOTLIN_2_1, kind = BUG_FIX), // KT-65494 // End of 2.* language features --------------------------------------------------