[FIR] Add INAPPLICABLE_OPERATOR_MODIFIER diagnostic

This commit is contained in:
Andrey Zinovyev
2021-08-16 14:59:20 +03:00
committed by TeamCityServer
parent 16f41bd80c
commit 1cd321a90f
37 changed files with 388 additions and 238 deletions
@@ -13,13 +13,13 @@ interface B {
}
interface C {
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override operator fun toString(): String = "Rest"<!>
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun toString(): String = "Rest"<!>
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override operator fun equals(other: Any?): Boolean = false<!>
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override operator fun hashCode(): Int = 2<!>
<!METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE!>override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hashCode(): Int = 2<!>
}
interface D {
override operator fun toString(): String
override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun toString(): String
override operator fun equals(other: Any?): Boolean
override operator fun hashCode(): Int
override <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hashCode(): Int
}
@@ -25,7 +25,7 @@ abstract class NotRange4() {
}
abstract class ImproperIterator3 {
abstract operator fun hasNext() : Int
abstract <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext() : Int
abstract operator fun next() : Int
}
@@ -347,6 +347,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<KtModifierKeywordToken>("modifier")
parameter<String>("target")
}
val INAPPLICABLE_OPERATOR_MODIFIER by error<PsiElement>(PositioningStrategy.OPERATOR_MODIFIER) {
parameter<String>("message")
}
}
val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") {
@@ -103,6 +103,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
ABSTRACT_MODIFIER,
LABEL,
COMMAS,
OPERATOR_MODIFIER,
;
@@ -268,6 +268,7 @@ object FirErrors {
val INFIX_MODIFIER_REQUIRED by error1<PsiElement, FirNamedFunctionSymbol>()
val WRONG_MODIFIER_CONTAINING_DECLARATION by error2<PsiElement, KtModifierKeywordToken, String>()
val DEPRECATED_MODIFIER_CONTAINING_DECLARATION by warning2<PsiElement, KtModifierKeywordToken, String>()
val INAPPLICABLE_OPERATOR_MODIFIER by error1<PsiElement, String>(SourceElementPositioningStrategies.OPERATOR_MODIFIER)
// Inline classes
val INLINE_CLASS_NOT_TOP_LEVEL by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
@@ -45,6 +45,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
get() = setOf(
FirFunctionNameChecker,
FirFunctionTypeParametersSyntaxChecker,
FirOperatorModifierChecker,
)
override val propertyCheckers: Set<FirPropertyChecker>
@@ -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<CheckerContext, FirSimpleFunction, String?> {
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<Name, List<Check>> = buildMap<Name, List<Check>> {
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<Pair<Regex, List<Check>>> = buildList {
checkFor(COMPONENT_REGEX, memberOrExtension, ValueParametersCount.none)
}
private fun MutableMap<Name, List<Check>>.checkFor(name: Name, vararg checks: Check) {
put(name, checks.asList())
}
private fun MutableMap<Name, List<Check>>.checkFor(names: Set<Name>, vararg checks: Check) {
names.forEach { put(it, checks.asList()) }
}
private fun MutableList<Pair<Regex, List<Check>>>.checkFor(regex: Regex, vararg checks: Check) {
add(regex to checks.asList())
}
}
@@ -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")
@@ -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))
@@ -304,4 +304,9 @@ object SourceElementPositioningStrategies {
LightTreePositioningStrategies.INLINE_PARAMETER_MODIFIER,
PositioningStrategies.INLINE_PARAMETER_MODIFIER
)
val OPERATOR_MODIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.OPERATOR_MODIFIER,
PositioningStrategies.OPERATOR_MODIFIER
)
}
@@ -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() =
@@ -377,6 +377,9 @@ object PositioningStrategies {
@JvmField
val DATA_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.DATA_KEYWORD)
@JvmField
val OPERATOR_MODIFIER: PositioningStrategy<KtModifierListOwner> = modifierSetPosition(KtTokens.OPERATOR_KEYWORD)
@JvmField
val FOR_REDECLARATION: PositioningStrategy<PsiElement> = object : PositioningStrategy<PsiElement>() {
override fun mark(element: PsiElement): List<TextRange> {
@@ -1,15 +1,15 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class Example {
operator fun plus(): String = ""
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(): String = ""
operator fun unaryPlus(): Int = 0
}
class ExampleDeprecated {
operator fun plus(): String = ""
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(): String = ""
}
operator fun String.plus(): String = this
<!INAPPLICABLE_OPERATOR_MODIFIER!>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
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus() = this
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus() = this
fun test() {
<!INAPPLICABLE_CANDIDATE!>+<!>this
@@ -27,7 +27,7 @@ abstract class NotRange4() {
}
abstract class ImproperIterator3 {
abstract operator fun hasNext() : Int
abstract <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext() : Int
abstract operator fun next() : Int
}
+4 -4
View File
@@ -16,8 +16,8 @@ fun testIncDec() {
}
class WrongIncDec() {
operator fun inc() : Int = 1
operator fun dec() : Int = 1
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc() : Int = 1
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec() : Int = 1
}
fun testWrongIncDec() {
@@ -29,8 +29,8 @@ fun testWrongIncDec() {
}
class UnitIncDec() {
operator fun inc() : Unit {}
operator fun dec() : Unit {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc() : Unit {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec() : Unit {}
}
fun testUnitIncDec() {
+92 -92
View File
@@ -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
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(o: Example, s: String = ""): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(vararg o: Example): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(): Example
operator fun unaryPlus(): Example
operator fun unaryMinus(): Example
operator fun unaryPlus(s: String = ""): Example
operator fun unaryMinus(o: Example)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(s: String = ""): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(o: Example)
operator fun inc(): Example
operator fun dec(): Example?
<!INAPPLICABLE_OPERATOR_MODIFIER!>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)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minusAssign(n: Int): String
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun divAssign(n: Int, a: String = "")
<!INAPPLICABLE_OPERATOR_MODIFIER!>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
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(a: String): Boolean
operator fun contains(n: Int): Boolean
operator fun contains(n: Int, s: String = ""): Boolean
<!INAPPLICABLE_OPERATOR_MODIFIER!>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()
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get()
operator fun set(n: Int, v: Int)
operator fun set(n: Int, n2: Int, v: Int)
operator fun set(v: Int)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(v: Int)
operator fun rangeTo(o: Int)
operator fun rangeTo(o: Int, o2: Int)
operator fun rangeTo(vararg o: String)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(o: Int, o2: Int)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(vararg o: String)
operator fun component1(): Int
operator fun component1(n: Int): Int
operator fun componentN(): Int
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(n: Int): Int
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun componentN(): Int
operator fun iterator(): String
operator fun iterator(n: Int): String
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun iterator(n: Int): String
operator fun next(): String
operator fun next(n: Int): String
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun next(n: Int): String
operator fun hasNext(): Boolean
operator fun hasNext(n: Int): String
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(n: Int): String
infix fun i1(n: Int)
<!INAPPLICABLE_INFIX_MODIFIER!>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) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun getValue(thisRef: Any?, prop: String): String = ""
<!INAPPLICABLE_OPERATOR_MODIFIER!>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) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: KProperty<*>, vararg n: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: KProperty<*>, f: Float = 0.0f) {}
operator fun getValue(prop: KProperty<*>): String = ""
operator fun setValue(prop: KProperty<*>, value: String) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun getValue(prop: KProperty<*>): String = ""
<!INAPPLICABLE_OPERATOR_MODIFIER!>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
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(s: String): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec()
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(vararg other: Example): Int
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(vararg n: Int): Boolean
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(): Int
}
interface Example3 {
operator fun compareTo(other: Example, s: String = ""): Int
operator fun contains(n: Int)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(other: Example, s: String = ""): Int
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int)
}
@@ -100,58 +100,58 @@ interface Example3 {
operator fun Example.plus(o: Any): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.div(o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.plus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.minus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.plus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.unaryPlus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.unaryMinus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.unaryMinus(o: Example) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.unaryMinus(o: Example) {}
operator fun Example.inc(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.plusAssign(n: Int) {}
operator fun Example.minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.divAssign(n: Int, a: String = "") {}
operator fun Example.modAssign(vararg n: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.divAssign(n: Int, a: String = "") {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.modAssign(vararg n: Int) {}
operator fun Example.compareTo(other: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.contains(n: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.invoke() {}
operator fun Example.get(n: Int) {}
operator fun Example.get(n: Int, n2: Int) {}
operator fun Example.get() {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>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) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>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) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.rangeTo(o: Int, o2: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.rangeTo(vararg o: String) {}
operator fun Example.component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.iterator(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.next(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.hasNext(): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
infix fun Example.i1(n: Int) {}
<!INAPPLICABLE_INFIX_MODIFIER!>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 {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun div(o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(o: String): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun div(o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(o: Example, s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(vararg o: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun unaryPlus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun unaryMinus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun unaryMinus(o: Example) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(s: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(o: Example) {}
operator fun inc(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): Example? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun plusAssign(n: Int) {}
operator fun minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun divAssign(n: Int, a: String = "") {}
operator fun modAssign(vararg n: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plusAssign(n: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minusAssign(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun divAssign(n: Int, a: String = "") {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun modAssign(vararg n: Int) {}
operator fun compareTo(other: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(other: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(a: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun contains(n: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int, s: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun invoke() {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun invoke() {}
operator fun get(n: Int) {}
operator fun get(n: Int, n2: Int) {}
operator fun get() {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get(n: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get(n: Int, n2: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get() {}
operator fun set(n: Int, v: Int) {}
operator fun set(n: Int, n2: Int, v: Int) {}
operator fun set(v: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(n: Int, v: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(n: Int, n2: Int, v: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(v: Int) {}
operator fun rangeTo(o: Int) {}
operator fun rangeTo(o: Int, o2: Int) {}
operator fun rangeTo(vararg o: String) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(o: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(o: Int, o2: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(vararg o: String) {}
operator fun component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(n: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun componentN(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun iterator(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun iterator(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun iterator(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun next(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun next(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun next(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun hasNext(): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(n: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_INFIX_MODIFIER!>infix fun i1(n: Int) {}<!>
<!INAPPLICABLE_INFIX_MODIFIER!>infix fun i1(n: Int, n2: Int) {}<!>
@@ -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
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class A {
operator fun A.minus(o: A) = o
@@ -16,7 +16,7 @@ object D {
}
object Z {
operator fun set() {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set() {
}
}
@@ -35,7 +35,7 @@ class MyProperty2<T, R> {
throw Exception()
}
operator fun setValue(i: Int) {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(i: Int) {
println("set")
}
}
@@ -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) {}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
import kotlin.reflect.KProperty
@@ -2,7 +2,7 @@
operator fun <T, U> Function1<T, U>.minusAssign(p: Function1<T, U>) {}
inline operator fun <T, U> Function1<T, U>.modAssign(p: Function1<T, U>) = {
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U> Function1<T, U>.modAssign(p: Function1<T, U>) = {
this += p
p += this
}
@@ -14,7 +14,7 @@ inline operator fun <T, U> Function1<T, U>.plusAssign(p: Function1<T, U>) {
operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.minusAssign(ext : @ExtensionFunctionType Function2<T, U, V>) {}
inline operator fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.modAssign(ext : @ExtensionFunctionType Function2<T, U, V>) = {
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U, V> @ExtensionFunctionType Function2<T, U, V>.modAssign(ext : @ExtensionFunctionType Function2<T, U, V>) = {
this += ext
ext += this
}
@@ -1,7 +1,7 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class C {
operator fun compareTo(c: C): Int? = null
<!INAPPLICABLE_OPERATOR_MODIFIER!>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
}
}
@@ -1,35 +0,0 @@
//KT-1028 Wrong type checking for plusAssign
package kt1028
import java.util.*
class event<T>()
{
val callbacks = ArrayList< Function1<T, Unit> >() // 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<MouseMovedEventArgs> = event<MouseMovedEventArgs>()
fun MoveMouse() = MouseMoved.call(MouseMovedEventArgs())
}
class Test()
{
fun test()
{
val control = Control()
control.MouseMoved <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>+=<!> { it.X } // here
control.MouseMoved.plusAssign( { it.X } ) // ok
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
//KT-1028 Wrong type checking for plusAssign
package kt1028
@@ -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 <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>+=<!> B()
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>*=<!> B()
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>/=<!> B()
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>-=<!> B()
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>%=<!> B()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package lol
class B() {
@@ -1,10 +0,0 @@
class IncDec {
operator fun inc(): Unit {}
}
fun foo(): IncDec {
var x = IncDec()
x = x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>
x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>
return x
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class IncDec {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): Unit {}
}
@@ -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 <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(a: A) = a === this
suspend operator fun set(a: A, b: A) {}
suspend operator fun provideDelegate(a: A, p: KProperty<*>) = a
@@ -5,7 +5,7 @@
// TESTCASE NUMBER: 1
class Case1(val a: Int) {
var isCompared = false
operator fun compareTo(other: Case1):Any = run{
<!INAPPLICABLE_OPERATOR_MODIFIER!>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 {
<!INAPPLICABLE_OPERATOR_MODIFIER!>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{
<!INAPPLICABLE_OPERATOR_MODIFIER!>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{
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(other: Case4):Int? = run{
TODO()
}
}
@@ -12,7 +12,7 @@ fun case1() {
class Case1() {
operator fun inc(): B {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): B {
TODO()
}
}
@@ -29,7 +29,7 @@ fun case2() {
class Case2() : C() {
var i = 0
operator fun inc(): C {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun inc(): C {
TODO()
}
@@ -12,7 +12,7 @@ fun case1() {
class Case1() {
operator fun dec(): B {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): B {
TODO()
}
}
@@ -29,7 +29,7 @@ fun case2() {
class Case2() : C() {
var i = 0
operator fun dec(): C {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): C {
TODO()
}
@@ -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,
@@ -796,6 +796,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
abstract val target: String
}
abstract class InapplicableOperatorModifier : KtFirDiagnostic<PsiElement>() {
override val diagnosticClass get() = InapplicableOperatorModifier::class
abstract val message: String
}
abstract class InlineClassNotTopLevel : KtFirDiagnostic<KtDeclaration>() {
override val diagnosticClass get() = InlineClassNotTopLevel::class
}
@@ -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<PsiElement> {
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
}
internal class InlineClassNotTopLevelImpl(
firDiagnostic: FirPsiDiagnostic,
override val token: ValidityToken,