diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt index a13c1084fb8..0c79a69827f 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/methodOfAnyImplementedInInterface.kt @@ -13,13 +13,13 @@ interface B { } interface C { - override operator fun toString(): String = "Rest" + override operator fun toString(): String = "Rest" override operator fun equals(other: Any?): Boolean = false - override operator fun hashCode(): Int = 2 + override operator fun hashCode(): Int = 2 } interface D { - override operator fun toString(): String + override operator fun toString(): String override operator fun equals(other: Any?): Boolean - override operator fun hashCode(): Int + override operator fun hashCode(): Int } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt index 658e51e708a..17e882268ef 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/diagnostics/forLoopChecker.kt @@ -25,7 +25,7 @@ abstract class NotRange4() { } abstract class ImproperIterator3 { - abstract operator fun hasNext() : Int + abstract operator fun hasNext() : Int abstract operator fun next() : Int } 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 ebb8637d3ee..fd82f8b4fe7 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 @@ -347,6 +347,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("modifier") parameter("target") } + val INAPPLICABLE_OPERATOR_MODIFIER by error(PositioningStrategy.OPERATOR_MODIFIER) { + parameter("message") + } } val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt index 533bf940dc2..38c55759ecd 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt @@ -103,6 +103,7 @@ enum class PositioningStrategy(private val strategy: String? = null) { ABSTRACT_MODIFIER, LABEL, COMMAS, + OPERATOR_MODIFIER, ; 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 12ac8e60291..c390c681338 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 @@ -268,6 +268,7 @@ object FirErrors { val INFIX_MODIFIER_REQUIRED by error1() val WRONG_MODIFIER_CONTAINING_DECLARATION by error2() val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning2() + val INAPPLICABLE_OPERATOR_MODIFIER by error1(SourceElementPositioningStrategies.OPERATOR_MODIFIER) // Inline classes val INLINE_CLASS_NOT_TOP_LEVEL by error0(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index c93fc419929..7dc3cbcc99c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -45,6 +45,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { get() = setOf( FirFunctionNameChecker, FirFunctionTypeParametersSyntaxChecker, + FirOperatorModifierChecker, ) override val propertyCheckers: Set 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 new file mode 100644 index 00000000000..50686eec512 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOperatorModifierChecker.kt @@ -0,0 +1,221 @@ +/* + * 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. + */ + +/* + * 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. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import javaslang.Function2 +import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.Returns +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.ValueParametersCount +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.isKProperty +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.member +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.memberOrExtension +import org.jetbrains.kotlin.fir.analysis.checkers.declaration.Checks.noDefaultAndVarargs +import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier +import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeOf +import org.jetbrains.kotlin.fir.analysis.checkers.isSupertypeOf +import org.jetbrains.kotlin.fir.analysis.checkers.overriddenFunctions +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.containingClass +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.utils.isOperator +import org.jetbrains.kotlin.fir.resolve.toFirRegularClass +import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl +import org.jetbrains.kotlin.fir.typeContext +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.util.OperatorNameConventions.ASSIGNMENT_OPERATIONS +import org.jetbrains.kotlin.util.OperatorNameConventions.BINARY_OPERATION_NAMES +import org.jetbrains.kotlin.util.OperatorNameConventions.COMPARE_TO +import org.jetbrains.kotlin.util.OperatorNameConventions.COMPONENT_REGEX +import org.jetbrains.kotlin.util.OperatorNameConventions.CONTAINS +import org.jetbrains.kotlin.util.OperatorNameConventions.DEC +import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS +import org.jetbrains.kotlin.util.OperatorNameConventions.GET +import org.jetbrains.kotlin.util.OperatorNameConventions.GET_VALUE +import org.jetbrains.kotlin.util.OperatorNameConventions.HAS_NEXT +import org.jetbrains.kotlin.util.OperatorNameConventions.INC +import org.jetbrains.kotlin.util.OperatorNameConventions.INVOKE +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.SET +import org.jetbrains.kotlin.util.OperatorNameConventions.SET_VALUE +import org.jetbrains.kotlin.util.OperatorNameConventions.SIMPLE_UNARY_OPERATION_NAMES + + +object FirOperatorModifierChecker : FirSimpleFunctionChecker() { + + override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) { + if (!declaration.isOperator) return + //we are not interested in implicit operators from override + if (!declaration.hasModifier(KtTokens.OPERATOR_KEYWORD)) return + + val checks = OperatorFunctionChecks.checksByName.getOrElse(declaration.name) { + OperatorFunctionChecks.regexChecks.find { it.first.matches(declaration.name.asString()) }?.second + } + + if (checks == null) { + reporter.reportOn(declaration.source, FirErrors.INAPPLICABLE_OPERATOR_MODIFIER, "illegal function name", context) + return + } + + for (check in checks) { + check.check(context, declaration)?.let { error -> + reporter.reportOn(declaration.source, FirErrors.INAPPLICABLE_OPERATOR_MODIFIER, error, context) + return + } + } + } + +} + +interface Check : Function2 { + override fun apply(t1: CheckerContext, t2: FirSimpleFunction): String? = check(t1, t2) + fun check(context: CheckerContext, function: FirSimpleFunction): String? +} + +object Checks { + fun simple(message: String, predicate: (FirSimpleFunction) -> Boolean) = object : Check { + override fun check(context: CheckerContext, function: FirSimpleFunction): String? = message.takeIf { !predicate(function) } + } + + fun full(message: String, predicate: (CheckerContext, FirSimpleFunction) -> Boolean) = object : Check { + override fun check(context: CheckerContext, function: FirSimpleFunction): String? = message.takeIf { !predicate(context, function) } + } + + val memberOrExtension = simple("must be a member or an extension function") { + it.dispatchReceiverType != null || it.receiverTypeRef != null + } + + val member = simple("must be a member function") { + it.dispatchReceiverType != null + } + + object ValueParametersCount { + fun atLeast(n: Int) = simple("must have at least $n value parameter" + (if (n > 1) "s" else "")) { + it.valueParameters.size >= n + } + + fun exactly(n: Int) = simple("must have exactly $n value parameters") { + it.valueParameters.size == n + } + + val single = simple("must have a single value parameter") { + it.valueParameters.size == 1 + } + val none = simple("must have no value parameters") { + it.valueParameters.isEmpty() + } + } + + object Returns { + val boolean = simple("must return Boolean") { + it.returnTypeRef.isBoolean + } + + val int = simple("must return Int") { + it.returnTypeRef.isInt + } + + val unit = simple("must return Unit") { + it.returnTypeRef.isUnit + } + } + + val noDefaultAndVarargs = simple("should not have varargs or parameters with default values") { + it.valueParameters.all { param -> + param.defaultValue == null && !param.isVararg + } + } + + private val kPropertyType = ConeClassLikeTypeImpl( + ConeClassLikeLookupTagImpl(StandardNames.FqNames.kProperty), + arrayOf(ConeStarProjection), + isNullable = false + ) + + val isKProperty = full("second parameter must be of type KProperty<*> or its supertype") { ctx, function -> + val paramType = function.valueParameters[1].returnTypeRef.coneType + paramType.isSupertypeOf(ctx.session.typeContext, kPropertyType) + } + +} + +@OptIn(ExperimentalStdlibApi::class) +object OperatorFunctionChecks { + + //reimplementation of org.jetbrains.kotlin.util.OperatorChecks for FIR + val checksByName: Map> = buildMap> { + checkFor(GET, memberOrExtension, ValueParametersCount.atLeast(1)) + checkFor( + SET, + memberOrExtension, ValueParametersCount.atLeast(2), + Checks.simple("last parameter should not have a default value or be a vararg") { + it.valueParameters.lastOrNull()?.let { param -> + param.defaultValue == null && !param.isVararg + } == true + } + ) + checkFor(GET_VALUE, memberOrExtension, noDefaultAndVarargs, ValueParametersCount.atLeast(2), isKProperty) + checkFor(SET_VALUE, memberOrExtension, noDefaultAndVarargs, ValueParametersCount.atLeast(3), isKProperty) + checkFor(PROVIDE_DELEGATE, memberOrExtension, noDefaultAndVarargs, ValueParametersCount.exactly(2), isKProperty) + checkFor(INVOKE, memberOrExtension) + checkFor(CONTAINS, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs, Returns.boolean) + checkFor(ITERATOR, memberOrExtension, ValueParametersCount.none) + checkFor(NEXT, memberOrExtension, ValueParametersCount.none) + checkFor(HAS_NEXT, memberOrExtension, ValueParametersCount.none, Returns.boolean) + checkFor(RANGE_TO, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs) + checkFor( + EQUALS, + member, + Checks.full("must override ''equals()'' in Any") { ctx, function -> + val containingClass = function.containingClass()?.toFirRegularClass(ctx.session) ?: return@full true + function.overriddenFunctions(containingClass, ctx).any { + it.containingClass()?.classId?.asSingleFqName() == StandardNames.FqNames.any.toSafe() + } + } + ) + checkFor(COMPARE_TO, memberOrExtension, Returns.int, ValueParametersCount.single, noDefaultAndVarargs) + checkFor(BINARY_OPERATION_NAMES, memberOrExtension, ValueParametersCount.single, noDefaultAndVarargs) + checkFor(SIMPLE_UNARY_OPERATION_NAMES, memberOrExtension, ValueParametersCount.none) + checkFor( + setOf(INC, DEC), + memberOrExtension, + Checks.full("receiver must be a supertype of the return type") { ctx, function -> + val receiver = function.dispatchReceiverType ?: function.receiverTypeRef?.coneType ?: return@full false + function.returnTypeRef.coneType.isSubtypeOf(ctx.session.typeContext, receiver) + } + ) + checkFor(ASSIGNMENT_OPERATIONS, memberOrExtension, Returns.unit, ValueParametersCount.single, noDefaultAndVarargs) + } + + val regexChecks: List>> = buildList { + checkFor(COMPONENT_REGEX, memberOrExtension, ValueParametersCount.none) + } + + private fun MutableMap>.checkFor(name: Name, vararg checks: Check) { + put(name, checks.asList()) + } + + private fun MutableMap>.checkFor(names: Set, vararg checks: Check) { + names.forEach { put(it, checks.asList()) } + } + + private fun MutableList>>.checkFor(regex: Regex, vararg checks: Check) { + add(regex to checks.asList()) + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 43356212e2c..e461c5dc848 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -211,6 +211,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CAND import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_FILE_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_INFIX_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_LATEINIT_MODIFIER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_OPERATOR_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_PARAM_TARGET import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_ON_PROPERTY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_TARGET_PROPERTY_HAS_NO_BACKING_FIELD @@ -744,6 +745,7 @@ class FirDefaultErrorMessages { map.put(INFIX_MODIFIER_REQUIRED, "''infix'' modifier is required on ''{0}''", TO_STRING) map.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, STRING) map.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", TO_STRING, STRING) + map.put(INAPPLICABLE_OPERATOR_MODIFIER, "''operator'' modifier is inapplicable on this function: {0}", STRING) // Classes and interfaces map.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt index 1a3728ab3d7..40d9afd0ed7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -373,6 +373,9 @@ object LightTreePositioningStrategies { val DATA_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.DATA_KEYWORD)) + val OPERATOR_MODIFIER: LightTreePositioningStrategy = + ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.OPERATOR_KEYWORD)) + val INLINE_PARAMETER_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD)) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt index 633eeab63ac..8dca98b8065 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt @@ -304,4 +304,9 @@ object SourceElementPositioningStrategies { LightTreePositioningStrategies.INLINE_PARAMETER_MODIFIER, PositioningStrategies.INLINE_PARAMETER_MODIFIER ) + + val OPERATOR_MODIFIER = SourceElementPositioningStrategy( + LightTreePositioningStrategies.OPERATOR_MODIFIER, + PositioningStrategies.OPERATOR_MODIFIER + ) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt index 8657e05dc19..f45d2aba5d7 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt @@ -40,6 +40,7 @@ val FirTypeRef.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing val FirTypeRef.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true) val FirTypeRef.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false) val FirTypeRef.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false) +val FirTypeRef.isInt: Boolean get() = isBuiltinType(StandardClassIds.Int, false) val FirTypeRef.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false) val FirTypeRef.isArrayType: Boolean get() = diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index c162c7d1518..798f208ff35 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -377,6 +377,9 @@ object PositioningStrategies { @JvmField val DATA_MODIFIER: PositioningStrategy = modifierSetPosition(KtTokens.DATA_KEYWORD) + @JvmField + val OPERATOR_MODIFIER: PositioningStrategy = modifierSetPosition(KtTokens.OPERATOR_KEYWORD) + @JvmField val FOR_REDECLARATION: PositioningStrategy = object : PositioningStrategy() { override fun mark(element: PsiElement): List { diff --git a/compiler/testData/diagnostics/tests/DeprecatedUnaryOperatorConventions.fir.kt b/compiler/testData/diagnostics/tests/DeprecatedUnaryOperatorConventions.fir.kt index eb8df0587ce..c7df06f542f 100644 --- a/compiler/testData/diagnostics/tests/DeprecatedUnaryOperatorConventions.fir.kt +++ b/compiler/testData/diagnostics/tests/DeprecatedUnaryOperatorConventions.fir.kt @@ -1,15 +1,15 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER class Example { - operator fun plus(): String = "" + operator fun plus(): String = "" operator fun unaryPlus(): Int = 0 } class ExampleDeprecated { - operator fun plus(): String = "" + operator fun plus(): String = "" } -operator fun String.plus(): String = this +operator fun String.plus(): String = this operator fun String.unaryPlus(): Int = 0 fun test() { @@ -22,8 +22,8 @@ fun requireInt(n: Int) {} fun requireString(s: String) {} class Example2 { - operator fun plus() = this - operator fun minus() = this + operator fun plus() = this + operator fun minus() = this fun test() { +this diff --git a/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt b/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt index 4ce159082d3..f7fb90cfb46 100644 --- a/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt +++ b/compiler/testData/diagnostics/tests/ForRangeConventions.fir.kt @@ -27,7 +27,7 @@ abstract class NotRange4() { } abstract class ImproperIterator3 { - abstract operator fun hasNext() : Int + abstract operator fun hasNext() : Int abstract operator fun next() : Int } diff --git a/compiler/testData/diagnostics/tests/IncDec.fir.kt b/compiler/testData/diagnostics/tests/IncDec.fir.kt index 00153790c68..fa8326da3a6 100644 --- a/compiler/testData/diagnostics/tests/IncDec.fir.kt +++ b/compiler/testData/diagnostics/tests/IncDec.fir.kt @@ -16,8 +16,8 @@ fun testIncDec() { } class WrongIncDec() { - operator fun inc() : Int = 1 - operator fun dec() : Int = 1 + operator fun inc() : Int = 1 + operator fun dec() : Int = 1 } fun testWrongIncDec() { @@ -29,8 +29,8 @@ fun testWrongIncDec() { } class UnitIncDec() { - operator fun inc() : Unit {} - operator fun dec() : Unit {} + operator fun inc() : Unit {} + operator fun dec() : Unit {} } fun testUnitIncDec() { diff --git a/compiler/testData/diagnostics/tests/OperatorChecks.fir.kt b/compiler/testData/diagnostics/tests/OperatorChecks.fir.kt index 740a20d4346..c344e2be272 100644 --- a/compiler/testData/diagnostics/tests/OperatorChecks.fir.kt +++ b/compiler/testData/diagnostics/tests/OperatorChecks.fir.kt @@ -5,59 +5,59 @@ import kotlin.reflect.KProperty interface Example { operator fun plus(o: Example): Example operator fun div(o: Example): Example - operator fun plus(o: Example, s: String = ""): Example - operator fun minus(vararg o: Example): Example - operator fun plus(): Example - operator fun minus(): Example + operator fun plus(o: Example, s: String = ""): Example + operator fun minus(vararg o: Example): Example + operator fun plus(): Example + operator fun minus(): Example operator fun unaryPlus(): Example operator fun unaryMinus(): Example - operator fun unaryPlus(s: String = ""): Example - operator fun unaryMinus(o: Example) + operator fun unaryPlus(s: String = ""): Example + operator fun unaryMinus(o: Example) operator fun inc(): Example - operator fun dec(): Example? + operator fun dec(): Example? operator fun plusAssign(n: Int) - operator fun minusAssign(n: Int): String - operator fun divAssign(n: Int, a: String = "") - operator fun modAssign(vararg n: Int) + operator fun minusAssign(n: Int): String + operator fun divAssign(n: Int, a: String = "") + operator fun modAssign(vararg n: Int) operator fun compareTo(other: Example): Int override operator fun equals(other: Any?): Boolean - operator fun equals(a: String): Boolean + operator fun equals(a: String): Boolean operator fun contains(n: Int): Boolean - operator fun contains(n: Int, s: String = ""): Boolean + operator fun contains(n: Int, s: String = ""): Boolean operator fun invoke() operator fun get(n: Int) operator fun get(n: Int, n2: Int) - operator fun get() + operator fun get() operator fun set(n: Int, v: Int) operator fun set(n: Int, n2: Int, v: Int) - operator fun set(v: Int) + operator fun set(v: Int) operator fun rangeTo(o: Int) - operator fun rangeTo(o: Int, o2: Int) - operator fun rangeTo(vararg o: String) + operator fun rangeTo(o: Int, o2: Int) + operator fun rangeTo(vararg o: String) operator fun component1(): Int - operator fun component1(n: Int): Int - operator fun componentN(): Int + operator fun component1(n: Int): Int + operator fun componentN(): Int operator fun iterator(): String - operator fun iterator(n: Int): String + operator fun iterator(n: Int): String operator fun next(): String - operator fun next(n: Int): String + operator fun next(n: Int): String operator fun hasNext(): Boolean - operator fun hasNext(n: Int): String + operator fun hasNext(n: Int): String infix fun i1(n: Int) infix fun i1(n: Int, n2: Int) @@ -72,27 +72,27 @@ class OkDelegates { } class DelegatesWithErrors { - operator fun getValue(thisRef: Any?, prop: String): String = "" - operator fun setValue(thisRef: Any?, prop: String, value: String) {} + operator fun getValue(thisRef: Any?, prop: String): String = "" + operator fun setValue(thisRef: Any?, prop: String, value: String) {} - operator fun setValue(thisRef: Any?, prop: KProperty<*>, vararg n: Int) {} - operator fun setValue(thisRef: Any?, prop: KProperty<*>, f: Float = 0.0f) {} + operator fun setValue(thisRef: Any?, prop: KProperty<*>, vararg n: Int) {} + operator fun setValue(thisRef: Any?, prop: KProperty<*>, f: Float = 0.0f) {} - operator fun getValue(prop: KProperty<*>): String = "" - operator fun setValue(prop: KProperty<*>, value: String) {} + operator fun getValue(prop: KProperty<*>): String = "" + operator fun setValue(prop: KProperty<*>, value: String) {} } interface Example2 { - operator fun inc(s: String): Example - operator fun dec() - operator fun compareTo(vararg other: Example): Int - operator fun contains(vararg n: Int): Boolean - operator fun hasNext(): Int + operator fun inc(s: String): Example + operator fun dec() + operator fun compareTo(vararg other: Example): Int + operator fun contains(vararg n: Int): Boolean + operator fun hasNext(): Int } interface Example3 { - operator fun compareTo(other: Example, s: String = ""): Int - operator fun contains(n: Int) + operator fun compareTo(other: Example, s: String = ""): Int + operator fun contains(n: Int) } @@ -100,58 +100,58 @@ interface Example3 { operator fun Example.plus(o: Any): Example {} operator fun Example.div(o: Example): Example {} -operator fun Example.plus(o: Example, s: String = ""): Example {} -operator fun Example.minus(vararg o: Example): Example {} -operator fun Example.plus(): Example {} -operator fun Example.minus(): Example {} +operator fun Example.plus(o: Example, s: String = ""): Example {} +operator fun Example.minus(vararg o: Example): Example {} +operator fun Example.plus(): Example {} +operator fun Example.minus(): Example {} operator fun Example.unaryPlus(): Example {} operator fun Example.unaryMinus(): Example {} -operator fun Example.unaryPlus(s: String = ""): Example {} -operator fun Example.unaryMinus(o: Example) {} +operator fun Example.unaryPlus(s: String = ""): Example {} +operator fun Example.unaryMinus(o: Example) {} operator fun Example.inc(): Example {} -operator fun Example.dec(): Example? {} +operator fun Example.dec(): Example? {} operator fun Example.plusAssign(n: Int) {} -operator fun Example.minusAssign(n: Int): String {} -operator fun Example.divAssign(n: Int, a: String = "") {} -operator fun Example.modAssign(vararg n: Int) {} +operator fun Example.minusAssign(n: Int): String {} +operator fun Example.divAssign(n: Int, a: String = "") {} +operator fun Example.modAssign(vararg n: Int) {} operator fun Example.compareTo(other: Example): Int {} -operator fun Example.equals(a: String): Boolean {} +operator fun Example.equals(a: String): Boolean {} operator fun Example.contains(n: Int): Boolean {} -operator fun Example.contains(n: Int, s: String = ""): Boolean {} +operator fun Example.contains(n: Int, s: String = ""): Boolean {} operator fun Example.invoke() {} operator fun Example.get(n: Int) {} operator fun Example.get(n: Int, n2: Int) {} -operator fun Example.get() {} +operator fun Example.get() {} operator fun Example.set(n: Int, v: Int) {} operator fun Example.set(n: Int, n2: Int, v: Int) {} -operator fun Example.set(v: Int) {} +operator fun Example.set(v: Int) {} operator fun Example.rangeTo(o: Int) {} -operator fun Example.rangeTo(o: Int, o2: Int) {} -operator fun Example.rangeTo(vararg o: String) {} +operator fun Example.rangeTo(o: Int, o2: Int) {} +operator fun Example.rangeTo(vararg o: String) {} operator fun Example.component1(): Int {} -operator fun Example.component1(n: Int): Int {} -operator fun Example.componentN(): Int {} +operator fun Example.component1(n: Int): Int {} +operator fun Example.componentN(): Int {} operator fun Example.iterator(): String {} -operator fun Example.iterator(n: Int): String {} +operator fun Example.iterator(n: Int): String {} operator fun Example.next(): String {} -operator fun Example.next(n: Int): String {} +operator fun Example.next(n: Int): String {} operator fun Example.hasNext(): Boolean {} -operator fun Example.hasNext(n: Int): String {} +operator fun Example.hasNext(n: Int): String {} infix fun Example.i1(n: Int) {} infix fun Example.i1(n: Int, n2: Int) {} @@ -161,58 +161,58 @@ infix fun Example.i1(vararg n: Int) {} -operator fun plus(o: String): Example {} -operator fun div(o: Example): Example {} -operator fun plus(o: Example, s: String = ""): Example {} -operator fun minus(vararg o: Example): Example {} +operator fun plus(o: String): Example {} +operator fun div(o: Example): Example {} +operator fun plus(o: Example, s: String = ""): Example {} +operator fun minus(vararg o: Example): Example {} -operator fun unaryPlus(): Example {} -operator fun unaryMinus(): Example {} +operator fun unaryPlus(): Example {} +operator fun unaryMinus(): Example {} -operator fun unaryPlus(s: String = ""): Example {} -operator fun unaryMinus(o: Example) {} +operator fun unaryPlus(s: String = ""): Example {} +operator fun unaryMinus(o: Example) {} -operator fun inc(): Example {} -operator fun dec(): Example? {} +operator fun inc(): Example {} +operator fun dec(): Example? {} -operator fun plusAssign(n: Int) {} -operator fun minusAssign(n: Int): String {} -operator fun divAssign(n: Int, a: String = "") {} -operator fun modAssign(vararg n: Int) {} +operator fun plusAssign(n: Int) {} +operator fun minusAssign(n: Int): String {} +operator fun divAssign(n: Int, a: String = "") {} +operator fun modAssign(vararg n: Int) {} -operator fun compareTo(other: Example): Int {} +operator fun compareTo(other: Example): Int {} -operator fun equals(a: String): Boolean {} +operator fun equals(a: String): Boolean {} -operator fun contains(n: Int): Boolean {} -operator fun contains(n: Int, s: String = ""): Boolean {} +operator fun contains(n: Int): Boolean {} +operator fun contains(n: Int, s: String = ""): Boolean {} -operator fun invoke() {} +operator fun invoke() {} -operator fun get(n: Int) {} -operator fun get(n: Int, n2: Int) {} -operator fun get() {} +operator fun get(n: Int) {} +operator fun get(n: Int, n2: Int) {} +operator fun get() {} -operator fun set(n: Int, v: Int) {} -operator fun set(n: Int, n2: Int, v: Int) {} -operator fun set(v: Int) {} +operator fun set(n: Int, v: Int) {} +operator fun set(n: Int, n2: Int, v: Int) {} +operator fun set(v: Int) {} -operator fun rangeTo(o: Int) {} -operator fun rangeTo(o: Int, o2: Int) {} -operator fun rangeTo(vararg o: String) {} +operator fun rangeTo(o: Int) {} +operator fun rangeTo(o: Int, o2: Int) {} +operator fun rangeTo(vararg o: String) {} -operator fun component1(): Int {} -operator fun component1(n: Int): Int {} -operator fun componentN(): Int {} +operator fun component1(): Int {} +operator fun component1(n: Int): Int {} +operator fun componentN(): Int {} -operator fun iterator(): String {} -operator fun iterator(n: Int): String {} +operator fun iterator(): String {} +operator fun iterator(n: Int): String {} -operator fun next(): String {} -operator fun next(n: Int): String {} +operator fun next(): String {} +operator fun next(n: Int): String {} -operator fun hasNext(): Boolean {} -operator fun hasNext(n: Int): String {} +operator fun hasNext(): Boolean {} +operator fun hasNext(n: Int): String {} infix fun i1(n: Int) {} infix fun i1(n: Int, n2: Int) {} diff --git a/compiler/testData/diagnostics/tests/OperatorsWithWrongNames.fir.kt b/compiler/testData/diagnostics/tests/OperatorsWithWrongNames.fir.kt deleted file mode 100644 index 16440292185..00000000000 --- a/compiler/testData/diagnostics/tests/OperatorsWithWrongNames.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -class A { - operator fun A.minus(o: A) = o - - operator fun A.add(o: A) = o - operator fun A.get(o: A) = o - operator fun A.invokee() {} -} - -operator fun A.plus(o: A) = o -operator fun A.component1() = 1 -operator fun A.componentN() = 1 \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/OperatorsWithWrongNames.kt b/compiler/testData/diagnostics/tests/OperatorsWithWrongNames.kt index 142d53068e8..47dc3cce0f0 100644 --- a/compiler/testData/diagnostics/tests/OperatorsWithWrongNames.kt +++ b/compiler/testData/diagnostics/tests/OperatorsWithWrongNames.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class A { operator fun A.minus(o: A) = o diff --git a/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt b/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt index 68cff469d7c..085af99f3d6 100644 --- a/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt +++ b/compiler/testData/diagnostics/tests/checkArguments/arrayAccessSet.fir.kt @@ -16,7 +16,7 @@ object D { } object Z { - operator fun set() { + operator fun set() { } } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.fir.kt index a9081d1a357..914e317e5d0 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.fir.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.fir.kt @@ -35,7 +35,7 @@ class MyProperty2 { throw Exception() } - operator fun setValue(i: Int) { + operator fun setValue(i: Int) { println("set") } } diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/provideDelegateOperatorDeclaration.fir.kt b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/provideDelegateOperatorDeclaration.fir.kt deleted file mode 100644 index 1bcc06edadb..00000000000 --- a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/provideDelegateOperatorDeclaration.fir.kt +++ /dev/null @@ -1,32 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER - -import kotlin.reflect.KProperty - -operator fun provideDelegate(x: Any?, p: KProperty<*>) {} - -operator fun Any.provideDelegate(x: Any?, p: KProperty<*>) {} - -operator fun Any.provideDelegate(x: Any?, p: Any) {} - -operator fun Any.provideDelegate(x: Any?, p: Int) {} - -class Host1 { - operator fun provideDelegate(x: Any?, p: KProperty<*>) {} -} - -class Host2 { - operator fun Any.provideDelegate(x: Any?, p: KProperty<*>) {} -} - -class Host3 { - operator fun provideDelegate(x: Any?, p: KProperty<*>, foo: Int) {} -} - -class Host4 { - operator fun provideDelegate(x: Any?, p: KProperty<*>, foo: Int = 0) {} -} - -class Host5 { - operator fun provideDelegate(x: Any?, p: KProperty<*>, vararg foo: Int) {} -} - diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/provideDelegateOperatorDeclaration.kt b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/provideDelegateOperatorDeclaration.kt index e620326a94b..ef980988ef3 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/provideDelegateOperatorDeclaration.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/provideDelegate/provideDelegateOperatorDeclaration.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER import kotlin.reflect.KProperty diff --git a/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.fir.kt b/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.fir.kt index 0324a66e8aa..7182ae34917 100644 --- a/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.fir.kt +++ b/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.fir.kt @@ -2,7 +2,7 @@ operator fun Function1.minusAssign(p: Function1) {} -inline operator fun Function1.modAssign(p: Function1) = { +inline operator fun Function1.modAssign(p: Function1) = { this += p p += this } @@ -14,7 +14,7 @@ inline operator fun Function1.plusAssign(p: Function1) { operator fun @ExtensionFunctionType Function2.minusAssign(ext : @ExtensionFunctionType Function2) {} -inline operator fun @ExtensionFunctionType Function2.modAssign(ext : @ExtensionFunctionType Function2) = { +inline operator fun @ExtensionFunctionType Function2.modAssign(ext : @ExtensionFunctionType Function2) = { this += ext ext += this } diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.fir.kt index a400f76638a..6ecf1d0f698 100644 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.fir.kt +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.fir.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER class C { - operator fun compareTo(c: C): Int? = null + operator fun compareTo(c: C): Int? = null } fun test(c: C) { @@ -9,4 +9,4 @@ fun test(c: C) { c <= c c >= c c > c -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.fir.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.fir.kt deleted file mode 100644 index e4f9c170868..00000000000 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.fir.kt +++ /dev/null @@ -1,35 +0,0 @@ -//KT-1028 Wrong type checking for plusAssign -package kt1028 - -import java.util.* - -class event() -{ - val callbacks = ArrayList< Function1 >() // Should be ArrayList<()->Unit>, bug posted - - operator fun plusAssign(f : (T) -> Unit) = callbacks.add(f) - operator fun minusAssign(f : (T) -> Unit) = callbacks.remove(f) - fun call(value : T) { for(c in callbacks) c(value) } -} - -class MouseMovedEventArgs() -{ - public val X : Int = 0 -} - -class Control() -{ - public val MouseMoved : event = event() - - fun MoveMouse() = MouseMoved.call(MouseMovedEventArgs()) -} - -class Test() -{ - fun test() - { - val control = Control() - control.MouseMoved += { it.X } // here - control.MouseMoved.plusAssign( { it.X } ) // ok - } -} diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt index 18169a7e199..28727f1d52c 100644 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL //KT-1028 Wrong type checking for plusAssign package kt1028 diff --git a/compiler/testData/diagnostics/tests/regressions/kt618.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt618.fir.kt deleted file mode 100644 index b631c9dee80..00000000000 --- a/compiler/testData/diagnostics/tests/regressions/kt618.fir.kt +++ /dev/null @@ -1,28 +0,0 @@ -package lol - -class B() { - operator fun plusAssign(other : B) : String { - return "s" - } - operator fun minusAssign(other : B) : String { - return "s" - } - operator fun remAssign(other : B) : String { - return "s" - } - operator fun divAssign(other : B) : String { - return "s" - } - operator fun timesAssign(other : B) : String { - return "s" - } -} - -fun main() { - var c = B() - c += B() - c *= B() - c /= B() - c -= B() - c %= B() -} diff --git a/compiler/testData/diagnostics/tests/regressions/kt618.kt b/compiler/testData/diagnostics/tests/regressions/kt618.kt index 02a2bd8cab8..9fb8d87371d 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt618.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt618.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL package lol class B() { diff --git a/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.fir.kt deleted file mode 100644 index d693218c103..00000000000 --- a/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.fir.kt +++ /dev/null @@ -1,10 +0,0 @@ -class IncDec { - operator fun inc(): Unit {} -} - -fun foo(): IncDec { - var x = IncDec() - x = x++ - x++ - return x -} diff --git a/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.kt b/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.kt index 598fd1580b3..67924d7ffc9 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/incDecToNull.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class IncDec { operator fun inc(): Unit {} } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/operators.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/operators.fir.kt index 9a9b4df845a..2f83974c558 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/operators.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/operators.fir.kt @@ -32,7 +32,7 @@ class A { suspend operator fun contains(b: A) = this == b suspend operator fun get(a: A) = a - suspend operator fun equals(a: A) = a === this + suspend operator fun equals(a: A) = a === this suspend operator fun set(a: A, b: A) {} suspend operator fun provideDelegate(a: A, p: KProperty<*>) = a diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/comparison-expressions/p-4/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/comparison-expressions/p-4/neg/1.1.fir.kt index 884ce5531ea..5bb5af05cdd 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/comparison-expressions/p-4/neg/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/comparison-expressions/p-4/neg/1.1.fir.kt @@ -5,7 +5,7 @@ // TESTCASE NUMBER: 1 class Case1(val a: Int) { var isCompared = false - operator fun compareTo(other: Case1):Any = run{ + operator fun compareTo(other: Case1):Any = run{ TODO() } } @@ -24,7 +24,7 @@ fun case1() { // TESTCASE NUMBER: 2 class Case2(val a: Int) { var isCompared = false - operator fun compareTo(other: Case2): Nothing = run { + operator fun compareTo(other: Case2): Nothing = run { TODO() } } @@ -43,7 +43,7 @@ fun case2() { // TESTCASE NUMBER: 3 class Case3(val a: Int) { var isCompared = false - operator fun compareTo(other: Case3):Long = run{ + operator fun compareTo(other: Case3):Long = run{ TODO() } } @@ -61,7 +61,7 @@ fun case3() { // TESTCASE NUMBER: 4 class Case4(val a: Int) { var isCompared = false - operator fun compareTo(other: Case4):Int? = run{ + operator fun compareTo(other: Case4):Int? = run{ TODO() } } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt index 512e8850fba..ef122218f1e 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-decrement-expression/p-5/neg/2.1.fir.kt @@ -12,7 +12,7 @@ fun case1() { class Case1() { - operator fun inc(): B { + operator fun inc(): B { TODO() } } @@ -29,7 +29,7 @@ fun case2() { class Case2() : C() { var i = 0 - operator fun inc(): C { + operator fun inc(): C { TODO() } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt index e0624495864..00791794406 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/prefix-expressions/prefix-increment-expression/p-5/neg/2.1.fir.kt @@ -12,7 +12,7 @@ fun case1() { class Case1() { - operator fun dec(): B { + operator fun dec(): B { TODO() } } @@ -29,7 +29,7 @@ fun case2() { class Case2() : C() { var i = 0 - operator fun dec(): C { + operator fun dec(): C { TODO() } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index c2edaa4c62e..96c7ac16452 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -1099,6 +1099,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.INAPPLICABLE_OPERATOR_MODIFIER) { firDiagnostic -> + InapplicableOperatorModifierImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.INLINE_CLASS_NOT_TOP_LEVEL) { firDiagnostic -> InlineClassNotTopLevelImpl( firDiagnostic as FirPsiDiagnostic, diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index f7e76520b25..1c7acec00a9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -796,6 +796,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val target: String } + abstract class InapplicableOperatorModifier : KtFirDiagnostic() { + override val diagnosticClass get() = InapplicableOperatorModifier::class + abstract val message: String + } + abstract class InlineClassNotTopLevel : KtFirDiagnostic() { override val diagnosticClass get() = InlineClassNotTopLevel::class } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 7baa7992ef6..a01ae61c23f 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -1262,6 +1262,14 @@ internal class DeprecatedModifierContainingDeclarationImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class InapplicableOperatorModifierImpl( + override val message: String, + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.InapplicableOperatorModifier(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class InlineClassNotTopLevelImpl( firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken,