diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 4da42e08250..4a5d848aa88 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -22343,6 +22343,28 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag public void testPlusAssignOnVarAndCollections() throws Exception { runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") + @TestDataPath("$PROJECT_ROOT") + public class Until { + @Test + public void testAllFilesPresentInUntil() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/operatorsOverloading/until"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("custom.kt") + public void testCustom() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/custom.kt"); + } + + @Test + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.kt"); + } + } } @Nested diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index cd8783fad4a..afe1fb2299f 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -22343,6 +22343,28 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti public void testPlusAssignOnVarAndCollections() throws Exception { runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") + @TestDataPath("$PROJECT_ROOT") + public class Until { + @Test + public void testAllFilesPresentInUntil() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/operatorsOverloading/until"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("custom.kt") + public void testCustom() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/custom.kt"); + } + + @Test + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.kt"); + } + } } @Nested diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index a23f3be3f7e..b93ff412c57 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -22343,6 +22343,28 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac public void testPlusAssignOnVarAndCollections() throws Exception { runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") + @TestDataPath("$PROJECT_ROOT") + public class Until { + @Test + public void testAllFilesPresentInUntil() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/operatorsOverloading/until"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("custom.kt") + public void testCustom() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/custom.kt"); + } + + @Test + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.kt"); + } + } } @Nested diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOperatorModifierChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOperatorModifierChecker.kt index 65e5360f479..27e09e06e7f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOperatorModifierChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOperatorModifierChecker.kt @@ -49,6 +49,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions.ITERATOR import org.jetbrains.kotlin.util.OperatorNameConventions.NEXT import org.jetbrains.kotlin.util.OperatorNameConventions.PROVIDE_DELEGATE import org.jetbrains.kotlin.util.OperatorNameConventions.RANGE_TO +import org.jetbrains.kotlin.util.OperatorNameConventions.RANGE_UNTIL import org.jetbrains.kotlin.util.OperatorNameConventions.SET import org.jetbrains.kotlin.util.OperatorNameConventions.SET_VALUE import org.jetbrains.kotlin.util.OperatorNameConventions.SIMPLE_UNARY_OPERATION_NAMES @@ -179,6 +180,7 @@ private object OperatorFunctionChecks { checkFor(NEXT, memberOrExtension, ValueParametersCount.none) checkFor(HAS_NEXT, memberOrExtension, ValueParametersCount.none, Returns.boolean) checkFor(RANGE_TO, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs) + checkFor(RANGE_UNTIL, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs) checkFor( EQUALS, member, diff --git a/compiler/psi/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java b/compiler/psi/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java index 687f6660444..bf463da1b72 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java +++ b/compiler/psi/src/org/jetbrains/kotlin/types/expressions/OperatorConventions.java @@ -62,6 +62,7 @@ public class OperatorConventions { .put(KtTokens.DIV, DIV) .put(KtTokens.PERC, REM) .put(KtTokens.RANGE, RANGE_TO) + .put(KtTokens.RANGE_UNTIL, RANGE_UNTIL) .build(); public static final ImmutableBiMap REM_TO_MOD_OPERATION_NAMES = ImmutableBiMap.builder() diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/until/custom.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/until/custom.fir.kt new file mode 100644 index 00000000000..f3c79b76768 --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/until/custom.fir.kt @@ -0,0 +1,9 @@ +class A { + operator fun rangeUntil(other: A): Iterable = TODO() +} + +fun main(n: A, f: A) { + for (i in f.. = TODO() +} + +fun main(n: A, f: A) { + for (i in f.. + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.fir.kt new file mode 100644 index 00000000000..21f9589e026 --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.fir.kt @@ -0,0 +1,5 @@ +fun main(n: Int) { + for (i in 0..<n) { + + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.kt new file mode 100644 index 00000000000..81e5f65dd37 --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.kt @@ -0,0 +1,5 @@ +fun main(n: Int) { + for (i in 0..<n) { + + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.txt b/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.txt new file mode 100644 index 00000000000..cc06aa73b51 --- /dev/null +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.txt @@ -0,0 +1,3 @@ +package + +public fun main(/*0*/ n: kotlin.Int): kotlin.Unit 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 d2e41408801..e006ee01b3a 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 @@ -22349,6 +22349,28 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { public void testPlusAssignOnVarAndCollections() throws Exception { runTest("compiler/testData/diagnostics/tests/operatorsOverloading/plusAssignOnVarAndCollections.kt"); } + + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/operatorsOverloading/until") + @TestDataPath("$PROJECT_ROOT") + public class Until { + @Test + public void testAllFilesPresentInUntil() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/operatorsOverloading/until"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("custom.kt") + public void testCustom() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/custom.kt"); + } + + @Test + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/operatorsOverloading/until/simple.kt"); + } + } } @Nested diff --git a/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt b/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt index ae38ec42394..728985a581f 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt @@ -61,6 +61,7 @@ object OperatorNameConventions { @JvmField val MOD = Name.identifier("mod") @JvmField val REM = Name.identifier("rem") @JvmField val RANGE_TO = Name.identifier("rangeTo") + @JvmField val RANGE_UNTIL = Name.identifier("rangeUntil") @JvmField val TIMES_ASSIGN = Name.identifier("timesAssign") @JvmField val DIV_ASSIGN = Name.identifier("divAssign") diff --git a/core/descriptors/src/org/jetbrains/kotlin/util/modifierChecks.kt b/core/descriptors/src/org/jetbrains/kotlin/util/modifierChecks.kt index 7695f8bbb9b..5fb6beb6da0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/util/modifierChecks.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/util/modifierChecks.kt @@ -46,6 +46,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions.ITERATOR import org.jetbrains.kotlin.util.OperatorNameConventions.NEXT import org.jetbrains.kotlin.util.OperatorNameConventions.PROVIDE_DELEGATE import org.jetbrains.kotlin.util.OperatorNameConventions.RANGE_TO +import org.jetbrains.kotlin.util.OperatorNameConventions.RANGE_UNTIL import org.jetbrains.kotlin.util.OperatorNameConventions.SET import org.jetbrains.kotlin.util.OperatorNameConventions.SET_VALUE import org.jetbrains.kotlin.util.OperatorNameConventions.SIMPLE_UNARY_OPERATION_NAMES @@ -194,6 +195,7 @@ object OperatorChecks : AbstractModifierChecks() { Checks(NEXT, MemberOrExtension, NoValueParameters), Checks(HAS_NEXT, MemberOrExtension, NoValueParameters, ReturnsBoolean), Checks(RANGE_TO, MemberOrExtension, SingleValueParameter, NoDefaultAndVarargsCheck), + Checks(RANGE_UNTIL, MemberOrExtension, SingleValueParameter, NoDefaultAndVarargsCheck), Checks(EQUALS, Member) { fun DeclarationDescriptor.isAny() = this is ClassDescriptor && KotlinBuiltIns.isAny(this) ensure(containingDeclaration.isAny() || overriddenDescriptors.any { it.containingDeclaration.isAny() }) {