diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index b9e9fa7319e..1558a9d3c05 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -564,8 +564,8 @@ public interface Errors { DiagnosticFactory0 UNDERSCORE_IS_DEPRECATED = DiagnosticFactory0.create(WARNING); - DiagnosticFactory0 INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory0.create(ERROR); - DiagnosticFactory0 INAPPLICABLE_INFIX_MODIFIER = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory0.create(WARNING); + DiagnosticFactory0 INAPPLICABLE_INFIX_MODIFIER = DiagnosticFactory0.create(WARNING); DiagnosticFactory2 OPERATOR_MODIFIER_REQUIRED = DiagnosticFactory2.create(WARNING); DiagnosticFactory2 INFIX_MODIFIER_REQUIRED = DiagnosticFactory2.create(WARNING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/InfixModifierChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/InfixModifierChecker.kt index f2309cef0fd..aa01f0ac0e7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/InfixModifierChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/InfixModifierChecker.kt @@ -43,20 +43,10 @@ public class InfixModifierChecker : DeclarationChecker { private fun isApplicable(descriptor: FunctionDescriptor): Boolean { if (descriptor.dispatchReceiverParameter == null && descriptor.extensionReceiverParameter == null) return false - val paramCount = descriptor.valueParameters.size() - return when (paramCount) { - 0 -> false - 1 -> true - else -> { - val params = descriptor.valueParameters - for (i in 1..params.lastIndex) { - if (!params[i].hasDefaultValue()) { - return false - } - } - true - } - } + if (descriptor.valueParameters.size != 1) return false + + val singleParameter = descriptor.valueParameters.first() + return !singleParameter.hasDefaultValue() && singleParameter.varargElementType == null } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt index 38364272c1a..b1ba6eba4e0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OperatorModifierChecker.kt @@ -38,7 +38,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.psi.JetDeclaration -import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.util.OperatorChecks public class OperatorModifierChecker : DeclarationChecker { override fun check( @@ -51,7 +51,7 @@ public class OperatorModifierChecker : DeclarationChecker { if (!functionDescriptor.isOperator) return val modifier = declaration.modifierList?.getModifier(JetTokens.OPERATOR_KEYWORD) ?: return - if (!OperatorNameConventions.canBeOperator(functionDescriptor)) { + if (!OperatorChecks.canBeOperator(functionDescriptor)) { diagnosticHolder.report(Errors.INAPPLICABLE_OPERATOR_MODIFIER.on(modifier)) } } diff --git a/compiler/testData/diagnostics/tests/ForRangeConventions.kt b/compiler/testData/diagnostics/tests/ForRangeConventions.kt index e920f5195b4..f475a8cae2a 100644 --- a/compiler/testData/diagnostics/tests/ForRangeConventions.kt +++ b/compiler/testData/diagnostics/tests/ForRangeConventions.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.kt b/compiler/testData/diagnostics/tests/IncDec.kt index 648100d67a3..adec0848762 100644 --- a/compiler/testData/diagnostics/tests/IncDec.kt +++ b/compiler/testData/diagnostics/tests/IncDec.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() { @@ -43,4 +43,4 @@ fun testUnitIncDec() { x = x-- x = ++x x = --x -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/Infix.kt b/compiler/testData/diagnostics/tests/Infix.kt index 1ca06d751c4..db5936351a5 100644 --- a/compiler/testData/diagnostics/tests/Infix.kt +++ b/compiler/testData/diagnostics/tests/Infix.kt @@ -8,10 +8,10 @@ class Example { infix fun Example.toExt(other: Example) = Pair(this, other) fun Example.toExtNonInfix(other: Example) = Pair(this, other) -infix fun Example.toExtWithExtraParams(other: Example, blah: Int = 0) = Pair(this, other) +infix fun Example.toExtWithExtraParams(other: Example, blah: Int = 0) = Pair(this, other) fun Example.toExtNonInfixWithExtraParams(other: Example, blah: Int = 0) = Pair(this, other) -infix fun Example.toExtDefaultValues(other: Example? = null, blah: Int = 0) = Pair(this, other) +infix fun Example.toExtDefaultValues(other: Example? = null, blah: Int = 0) = Pair(this, other) fun Example.toExtNonInfixDefaultValues(other: Example? = null, blah: Int = 0) = Pair(this, other) fun Example.withLambda(f: () -> Unit) = Pair(this, f) diff --git a/compiler/testData/diagnostics/tests/InfixModifierApplicability.kt b/compiler/testData/diagnostics/tests/InfixModifierApplicability.kt index f1fc4d6a720..387c35c4121 100644 --- a/compiler/testData/diagnostics/tests/InfixModifierApplicability.kt +++ b/compiler/testData/diagnostics/tests/InfixModifierApplicability.kt @@ -4,8 +4,8 @@ class Pair(val a: A, val b: B) infix fun A.to(that: B): Pair = Pair(this, that) infix fun String.o1(o: String) = o -infix fun String.o2(o: String, o2: String? = null) = o -infix fun String.o3(o: String = "", o2: String? = null) = o +infix fun String.o2(o: String, o2: String? = null) = o +infix fun String.o3(o: String = "", o2: String? = null) = o infix fun w1() {} infix fun w2(s: String) {} @@ -15,7 +15,7 @@ infix fun String.o3(o: String = "", o2: String? = null) = o class Example { infix fun c1(s: String) {} - infix fun c2(s: String, a: Int = 0) {} + infix fun c2(s: String, a: Int = 0) {} infix fun cw1(s: String, a: Int) {} infix fun sw2() {} diff --git a/compiler/testData/diagnostics/tests/OperatorChecks.kt b/compiler/testData/diagnostics/tests/OperatorChecks.kt new file mode 100644 index 00000000000..93c5e903b88 --- /dev/null +++ b/compiler/testData/diagnostics/tests/OperatorChecks.kt @@ -0,0 +1,211 @@ +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 unaryPlus(): Example + operator fun unaryMinus(): Example + + operator fun unaryPlus(s: String = ""): Example + operator fun unaryMinus(o: 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 compareTo(other: Example): Int + + override operator fun equals(other: Any?): Boolean + operator fun equals(a: String): Boolean + + operator fun contains(n: Int): 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 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 component1(): Int + operator fun component1(n: Int): Int + operator fun componentN(): Int + + operator fun iterator(): String + operator fun iterator(n: Int): String + + operator fun next(): String + operator fun next(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) + infix fun i1(vararg n: Int) +} + +class OkDelegates { + operator fun getValue(thisRef: Any?, prop: PropertyMetadata): String = "" + operator fun setValue(thisRef: Any?, prop: PropertyMetadata, s: String): String = "" + operator fun setValue(thisRef: Any?, prop: Any, n: Int) {} + operator fun setValue(thisRef: Any?, prop: Any?, s: String) {} +} + +class DelegatesWithErrors { + operator fun getValue(thisRef: Any?, prop: String): String = "" + operator fun setValue(thisRef: Any?, prop: String, value: String) {} + + operator fun setValue(thisRef: Any?, prop: PropertyMetadata, vararg n: Int) {} + operator fun setValue(thisRef: Any?, prop: PropertyMetadata, f: Float = 0.0f) {} + + operator fun getValue(prop: PropertyMetadata): String = "" + operator fun setValue(prop: PropertyMetadata, 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 +} + +interface Example3 { + operator fun compareTo(other: Example, s: String = ""): Int + operator fun contains(n: Int) +} + + + + +operator fun Example.plus(o: Example): 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.unaryPlus(): Example {} +operator fun Example.unaryMinus(): 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.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.compareTo(other: Example): Int {} + +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.invoke() {} + +operator fun Example.get(n: Int) {} +operator fun Example.get(n: Int, n2: Int) {} +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.rangeTo(o: Int) {} +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.iterator(): String {} +operator fun Example.iterator(n: Int): String {} + +operator fun Example.next(): String {} +operator fun Example.next(n: Int): String {} + +operator fun Example.hasNext(): Boolean {} +operator fun Example.hasNext(n: Int): String {} + +infix fun Example.i1(n: Int) {} +infix fun Example.i1(n: Int, n2: Int) {} +infix fun Example.i1(vararg n: Int) {} + + + + + +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 unaryPlus(): Example {} +operator fun unaryMinus(): Example {} + +operator fun unaryPlus(s: String = ""): Example {} +operator fun unaryMinus(o: 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 compareTo(other: Example): Int {} + +operator fun equals(a: String): Boolean {} + +operator fun contains(n: Int): 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 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 component1(): Int {} +operator fun component1(n: Int): Int {} +operator fun componentN(): Int {} + +operator fun iterator(): String {} +operator fun iterator(n: Int): String {} + +operator fun next(): String {} +operator fun next(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) {} +infix fun i1(vararg n: Int) {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/OperatorChecks.txt b/compiler/testData/diagnostics/tests/OperatorChecks.txt new file mode 100644 index 00000000000..47c2ba80ace --- /dev/null +++ b/compiler/testData/diagnostics/tests/OperatorChecks.txt @@ -0,0 +1,171 @@ +package + +public operator fun compareTo(/*0*/ other: Example): kotlin.Int +public operator fun component1(): kotlin.Int +public operator fun component1(/*0*/ n: kotlin.Int): kotlin.Int +public operator fun componentN(): kotlin.Int +public operator fun contains(/*0*/ n: kotlin.Int): kotlin.Boolean +public operator fun contains(/*0*/ n: kotlin.Int, /*1*/ s: kotlin.String = ...): kotlin.Boolean +public operator fun dec(): Example? +public operator fun div(/*0*/ o: Example): Example +public operator fun divAssign(/*0*/ n: kotlin.Int, /*1*/ a: kotlin.String = ...): kotlin.Unit +public operator fun equals(/*0*/ a: kotlin.String): kotlin.Boolean +public operator fun get(): kotlin.Unit +public operator fun get(/*0*/ n: kotlin.Int): kotlin.Unit +public operator fun get(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int): kotlin.Unit +public operator fun hasNext(): kotlin.Boolean +public operator fun hasNext(/*0*/ n: kotlin.Int): kotlin.String +public infix fun i1(/*0*/ n: kotlin.Int): kotlin.Unit +public infix fun i1(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int): kotlin.Unit +public infix fun i1(/*0*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit +public operator fun inc(): Example +public operator fun invoke(): kotlin.Unit +public operator fun iterator(): kotlin.String +public operator fun iterator(/*0*/ n: kotlin.Int): kotlin.String +public operator fun minus(/*0*/ vararg o: Example /*kotlin.Array*/): Example +public operator fun minusAssign(/*0*/ n: kotlin.Int): kotlin.String +public operator fun modAssign(/*0*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit +public operator fun next(): kotlin.String +public operator fun next(/*0*/ n: kotlin.Int): kotlin.String +public operator fun plus(/*0*/ o: Example): Example +public operator fun plus(/*0*/ o: Example, /*1*/ s: kotlin.String = ...): Example +public operator fun plusAssign(/*0*/ n: kotlin.Int): kotlin.Unit +public operator fun rangeTo(/*0*/ vararg o: kotlin.String /*kotlin.Array*/): kotlin.Unit +public operator fun rangeTo(/*0*/ o: kotlin.Int): kotlin.Unit +public operator fun rangeTo(/*0*/ o: kotlin.Int, /*1*/ o2: kotlin.Int): kotlin.Unit +public operator fun set(/*0*/ v: kotlin.Int): kotlin.Unit +public operator fun set(/*0*/ n: kotlin.Int, /*1*/ v: kotlin.Int): kotlin.Unit +public operator fun set(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int, /*2*/ v: kotlin.Int): kotlin.Unit +public operator fun unaryMinus(): Example +public operator fun unaryMinus(/*0*/ o: Example): kotlin.Unit +public operator fun unaryPlus(): Example +public operator fun unaryPlus(/*0*/ s: kotlin.String = ...): Example +public operator fun Example.compareTo(/*0*/ other: Example): kotlin.Int +public operator fun Example.component1(): kotlin.Int +public operator fun Example.component1(/*0*/ n: kotlin.Int): kotlin.Int +public operator fun Example.componentN(): kotlin.Int +public operator fun Example.contains(/*0*/ n: kotlin.Int): kotlin.Boolean +public operator fun Example.contains(/*0*/ n: kotlin.Int, /*1*/ s: kotlin.String = ...): kotlin.Boolean +public operator fun Example.dec(): Example? +public operator fun Example.div(/*0*/ o: Example): Example +public operator fun Example.divAssign(/*0*/ n: kotlin.Int, /*1*/ a: kotlin.String = ...): kotlin.Unit +public operator fun Example.equals(/*0*/ a: kotlin.String): kotlin.Boolean +public operator fun Example.get(): kotlin.Unit +public operator fun Example.get(/*0*/ n: kotlin.Int): kotlin.Unit +public operator fun Example.get(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int): kotlin.Unit +public operator fun Example.hasNext(): kotlin.Boolean +public operator fun Example.hasNext(/*0*/ n: kotlin.Int): kotlin.String +public infix fun Example.i1(/*0*/ n: kotlin.Int): kotlin.Unit +public infix fun Example.i1(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int): kotlin.Unit +public infix fun Example.i1(/*0*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit +public operator fun Example.inc(): Example +public operator fun Example.invoke(): kotlin.Unit +public operator fun Example.iterator(): kotlin.String +public operator fun Example.iterator(/*0*/ n: kotlin.Int): kotlin.String +public operator fun Example.minus(/*0*/ vararg o: Example /*kotlin.Array*/): Example +public operator fun Example.minusAssign(/*0*/ n: kotlin.Int): kotlin.String +public operator fun Example.modAssign(/*0*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit +public operator fun Example.next(): kotlin.String +public operator fun Example.next(/*0*/ n: kotlin.Int): kotlin.String +public operator fun Example.plus(/*0*/ o: Example): Example +public operator fun Example.plus(/*0*/ o: Example, /*1*/ s: kotlin.String = ...): Example +public operator fun Example.plusAssign(/*0*/ n: kotlin.Int): kotlin.Unit +public operator fun Example.rangeTo(/*0*/ vararg o: kotlin.String /*kotlin.Array*/): kotlin.Unit +public operator fun Example.rangeTo(/*0*/ o: kotlin.Int): kotlin.Unit +public operator fun Example.rangeTo(/*0*/ o: kotlin.Int, /*1*/ o2: kotlin.Int): kotlin.Unit +public operator fun Example.set(/*0*/ v: kotlin.Int): kotlin.Unit +public operator fun Example.set(/*0*/ n: kotlin.Int, /*1*/ v: kotlin.Int): kotlin.Unit +public operator fun Example.set(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int, /*2*/ v: kotlin.Int): kotlin.Unit +public operator fun Example.unaryMinus(): Example +public operator fun Example.unaryMinus(/*0*/ o: Example): kotlin.Unit +public operator fun Example.unaryPlus(): Example +public operator fun Example.unaryPlus(/*0*/ s: kotlin.String = ...): Example + +public final class DelegatesWithErrors { + public constructor DelegatesWithErrors() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.String): kotlin.String + public final operator fun getValue(/*0*/ prop: kotlin.PropertyMetadata): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.PropertyMetadata, /*2*/ f: kotlin.Float = ...): kotlin.Unit + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.PropertyMetadata, /*2*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.String, /*2*/ value: kotlin.String): kotlin.Unit + public final operator fun setValue(/*0*/ prop: kotlin.PropertyMetadata, /*1*/ value: kotlin.String): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Example { + public abstract operator fun compareTo(/*0*/ other: Example): kotlin.Int + public abstract operator fun component1(): kotlin.Int + public abstract operator fun component1(/*0*/ n: kotlin.Int): kotlin.Int + public abstract operator fun componentN(): kotlin.Int + public abstract operator fun contains(/*0*/ n: kotlin.Int): kotlin.Boolean + public abstract operator fun contains(/*0*/ n: kotlin.Int, /*1*/ s: kotlin.String = ...): kotlin.Boolean + public abstract operator fun dec(): Example? + public abstract operator fun div(/*0*/ o: Example): Example + public abstract operator fun divAssign(/*0*/ n: kotlin.Int, /*1*/ a: kotlin.String = ...): kotlin.Unit + public abstract override /*1*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract operator fun equals(/*0*/ a: kotlin.String): kotlin.Boolean + public abstract operator fun get(): kotlin.Unit + public abstract operator fun get(/*0*/ n: kotlin.Int): kotlin.Unit + public abstract operator fun get(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int): kotlin.Unit + public abstract operator fun hasNext(): kotlin.Boolean + public abstract operator fun hasNext(/*0*/ n: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract infix fun i1(/*0*/ n: kotlin.Int): kotlin.Unit + public abstract infix fun i1(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int): kotlin.Unit + public abstract infix fun i1(/*0*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit + public abstract operator fun inc(): Example + public abstract operator fun invoke(): kotlin.Unit + public abstract operator fun iterator(): kotlin.String + public abstract operator fun iterator(/*0*/ n: kotlin.Int): kotlin.String + public abstract operator fun minus(/*0*/ vararg o: Example /*kotlin.Array*/): Example + public abstract operator fun minusAssign(/*0*/ n: kotlin.Int): kotlin.String + public abstract operator fun modAssign(/*0*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit + public abstract operator fun next(): kotlin.String + public abstract operator fun next(/*0*/ n: kotlin.Int): kotlin.String + public abstract operator fun plus(/*0*/ o: Example): Example + public abstract operator fun plus(/*0*/ o: Example, /*1*/ s: kotlin.String = ...): Example + public abstract operator fun plusAssign(/*0*/ n: kotlin.Int): kotlin.Unit + public abstract operator fun rangeTo(/*0*/ vararg o: kotlin.String /*kotlin.Array*/): kotlin.Unit + public abstract operator fun rangeTo(/*0*/ o: kotlin.Int): kotlin.Unit + public abstract operator fun rangeTo(/*0*/ o: kotlin.Int, /*1*/ o2: kotlin.Int): kotlin.Unit + public abstract operator fun set(/*0*/ v: kotlin.Int): kotlin.Unit + public abstract operator fun set(/*0*/ n: kotlin.Int, /*1*/ v: kotlin.Int): kotlin.Unit + public abstract operator fun set(/*0*/ n: kotlin.Int, /*1*/ n2: kotlin.Int, /*2*/ v: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public abstract operator fun unaryMinus(): Example + public abstract operator fun unaryMinus(/*0*/ o: Example): kotlin.Unit + public abstract operator fun unaryPlus(): Example + public abstract operator fun unaryPlus(/*0*/ s: kotlin.String = ...): Example +} + +public interface Example2 { + public abstract operator fun compareTo(/*0*/ vararg other: Example /*kotlin.Array*/): kotlin.Int + public abstract operator fun contains(/*0*/ vararg n: kotlin.Int /*kotlin.IntArray*/): kotlin.Boolean + public abstract operator fun dec(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract operator fun hasNext(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract operator fun inc(/*0*/ s: kotlin.String): Example + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Example3 { + public abstract operator fun compareTo(/*0*/ other: Example, /*1*/ s: kotlin.String = ...): kotlin.Int + public abstract operator fun contains(/*0*/ n: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class OkDelegates { + public constructor OkDelegates() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.PropertyMetadata): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.Any, /*2*/ n: kotlin.Int): kotlin.Unit + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.Any?, /*2*/ s: kotlin.String): kotlin.Unit + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.PropertyMetadata, /*2*/ s: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.kt b/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.kt index 8767f9c00ee..438b43cc618 100644 --- a/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.kt +++ b/compiler/testData/diagnostics/tests/inline/binaryExpressions/assignment.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 @Extension Function2.minusAssign(ext : @Extension Function2) {} -inline operator fun @Extension Function2.modAssign(ext : @Extension Function2) = { +inline operator fun @Extension Function2.modAssign(ext : @Extension Function2) = { this += ext ext += this } @@ -27,4 +27,4 @@ inline operator fun @Extension Function2.plusAssign(ext : @Ex inline fun inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) { s += s ext += ext -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.kt index b447be3d803..d3815e9e89d 100644 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.kt +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/compareToNullable.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) { diff --git a/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt b/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt index e4f9c170868..18169a7e199 100644 --- a/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt +++ b/compiler/testData/diagnostics/tests/operatorsOverloading/kt1028.kt @@ -7,8 +7,8 @@ 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) + 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) } } @@ -32,4 +32,4 @@ class Test() control.MouseMoved += { it.X } // here control.MouseMoved.plusAssign( { it.X } ) // ok } -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/kt618.kt b/compiler/testData/diagnostics/tests/regressions/kt618.kt index 9ec89637b0e..cbdc7687f1f 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt618.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt618.kt @@ -1,19 +1,19 @@ package lol class B() { - operator fun plusAssign(other : B) : String { + operator fun plusAssign(other : B) : String { return "s" } - operator fun minusAssign(other : B) : String { + operator fun minusAssign(other : B) : String { return "s" } - operator fun modAssign(other : B) : String { + operator fun modAssign(other : B) : String { return "s" } - operator fun divAssign(other : B) : String { + operator fun divAssign(other : B) : String { return "s" } - operator fun timesAssign(other : B) : String { + operator fun timesAssign(other : B) : String { return "s" } } @@ -25,4 +25,4 @@ fun main(args : Array) { c /= B() c -= B() c %= B() -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.kt index 90aa70feef2..a06b9936a6e 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.kt @@ -1,13 +1,12 @@ class MyClass -// In principle it is not correct, MyClass? is not a subtype of MyClass -operator fun MyClass.inc(): MyClass? { return null } +operator fun MyClass.inc(): MyClass { return null!! } public fun box() : MyClass? { - var i : MyClass? + var i : MyClass? i = MyClass() // type of j can be inferred as MyClass() var j = i++ j.hashCode() return i -} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.txt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.txt index 93b1c9a20fe..80485e2dee8 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.txt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/postfixNotnullClassIncrement.txt @@ -1,7 +1,7 @@ package public fun box(): MyClass? -public operator fun MyClass.inc(): MyClass? +public operator fun MyClass.inc(): MyClass public final class MyClass { public constructor MyClass() diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.kt index 26e87880923..8608bce843e 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.kt @@ -1,13 +1,12 @@ class MyClass -// In principle it is not correct, MyClass? is not a subtype of MyClass -operator fun MyClass.inc(): MyClass? { return null } +operator fun MyClass.inc(): MyClass { return null!! } public fun box() { - var i : MyClass? + var i : MyClass? i = MyClass() // Type of j should be inferred as MyClass? var j = ++i // j is null so call is unsafe - j.hashCode() -} + j.hashCode() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.txt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.txt index 172966df78d..11ef3d26d6d 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.txt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/prefixNotnullClassIncrement.txt @@ -1,7 +1,7 @@ package public fun box(): kotlin.Unit -public operator fun MyClass.inc(): MyClass? +public operator fun MyClass.inc(): MyClass public final class MyClass { public constructor MyClass() diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/ReturnInnerSubclassOfSupersInner.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/ReturnInnerSubclassOfSupersInner.txt index 880ae8c0437..3aff37ed373 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/ReturnInnerSubclassOfSupersInner.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/ReturnInnerSubclassOfSupersInner.txt @@ -16,7 +16,7 @@ public interface ReturnInnerSubclassOfSupersInner { public/*package*/ open inner class Inner { public/*package*/ constructor Inner() - public/*package*/ open operator fun get(): test.ReturnInnerSubclassOfSupersInner.Super! + public/*package*/ open fun get(): test.ReturnInnerSubclassOfSupersInner.Super! } } } diff --git a/compiler/testData/loadJava/sourceJava/ReturnInnerSubclassOfSupersInner.txt b/compiler/testData/loadJava/sourceJava/ReturnInnerSubclassOfSupersInner.txt index 880ae8c0437..3aff37ed373 100644 --- a/compiler/testData/loadJava/sourceJava/ReturnInnerSubclassOfSupersInner.txt +++ b/compiler/testData/loadJava/sourceJava/ReturnInnerSubclassOfSupersInner.txt @@ -16,7 +16,7 @@ public interface ReturnInnerSubclassOfSupersInner { public/*package*/ open inner class Inner { public/*package*/ constructor Inner() - public/*package*/ open operator fun get(): test.ReturnInnerSubclassOfSupersInner.Super! + public/*package*/ open fun get(): test.ReturnInnerSubclassOfSupersInner.Super! } } } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 7158e4d96b2..a34cd30519a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -397,6 +397,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("OperatorChecks.kt") + public void testOperatorChecks() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/OperatorChecks.kt"); + doTest(fileName); + } + @TestMetadata("Operators.kt") public void testOperators() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/Operators.kt"); @@ -9286,6 +9292,16 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/jdk-annotations") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Jdk_annotations extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInJdk_annotations() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/jdk-annotations"), Pattern.compile("^(.+)\\.kt$"), true); + } + + } + @TestMetadata("compiler/testData/diagnostics/tests/labels") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java index 1123c8bfcee..0614d021d61 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.TypeSubstitutor; -import org.jetbrains.kotlin.util.OperatorNameConventions; +import org.jetbrains.kotlin.util.OperatorChecks; import java.util.List; @@ -88,7 +88,7 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement SimpleFunctionDescriptorImpl descriptor = super.initialize( receiverParameterType, dispatchReceiverParameter, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modality, visibility); - setOperator(OperatorNameConventions.INSTANCE$.canBeOperator(descriptor)); + setOperator(OperatorChecks.INSTANCE$.canBeOperator(descriptor)); return descriptor; } diff --git a/core/descriptors/src/org/jetbrains/kotlin/util/OperatorChecker.kt b/core/descriptors/src/org/jetbrains/kotlin/util/OperatorChecker.kt new file mode 100644 index 00000000000..96b9d45c2f7 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/util/OperatorChecker.kt @@ -0,0 +1,130 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.util + +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.name.FqNameUnsafe +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue +import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension +import org.jetbrains.kotlin.types.typeUtil.* +import org.jetbrains.kotlin.util.OperatorNameConventions.GET +import org.jetbrains.kotlin.util.OperatorNameConventions.SET +import org.jetbrains.kotlin.util.OperatorNameConventions.INVOKE +import org.jetbrains.kotlin.util.OperatorNameConventions.CONTAINS +import org.jetbrains.kotlin.util.OperatorNameConventions.ITERATOR +import org.jetbrains.kotlin.util.OperatorNameConventions.NEXT +import org.jetbrains.kotlin.util.OperatorNameConventions.HAS_NEXT +import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS +import org.jetbrains.kotlin.util.OperatorNameConventions.COMPARE_TO +import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_OPERATION_NAMES +import org.jetbrains.kotlin.util.OperatorNameConventions.BINARY_OPERATION_NAMES +import org.jetbrains.kotlin.util.OperatorNameConventions.ASSIGNMENT_OPERATIONS +import org.jetbrains.kotlin.util.OperatorNameConventions.COMPONENT_REGEX +import org.jetbrains.kotlin.util.OperatorNameConventions.PLUS +import org.jetbrains.kotlin.util.OperatorNameConventions.MINUS +import org.jetbrains.kotlin.util.OperatorNameConventions.RANGE_TO +import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_PLUS +import org.jetbrains.kotlin.util.OperatorNameConventions.UNARY_MINUS +import org.jetbrains.kotlin.util.OperatorNameConventions.NOT +import org.jetbrains.kotlin.util.OperatorNameConventions.INC +import org.jetbrains.kotlin.util.OperatorNameConventions.DEC +import org.jetbrains.kotlin.util.OperatorNameConventions.GET_VALUE +import org.jetbrains.kotlin.util.OperatorNameConventions.SET_VALUE + +object OperatorChecks { + fun canBeOperator(functionDescriptor: FunctionDescriptor): Boolean { + val name = functionDescriptor.name + + return with (functionDescriptor) { + if (!functionDescriptor.isMemberOrExtension) return false + + when { + GET == name -> valueParameters.size >= 1 + SET == name -> { + val lastIsOk = valueParameters.lastOrNull()?.let { !it.hasDefaultValue() && it.varargElementType == null } ?: false + valueParameters.size >= 2 && lastIsOk + } + + GET_VALUE == name -> noDefaultsAndVarargs && valueParameters.size >= 2 && valueParameters[1].isPropertyMetadata + SET_VALUE == name -> noDefaultsAndVarargs && valueParameters.size >= 3 && valueParameters[1].isPropertyMetadata + + INVOKE == name -> isMemberOrExtension + CONTAINS == name -> singleValueParameter && noDefaultsAndVarargs && returnsBoolean + + ITERATOR == name -> noValueParameters + NEXT == name -> noValueParameters + HAS_NEXT == name -> noValueParameters && returnsBoolean + + RANGE_TO == name -> singleValueParameter && noDefaultsAndVarargs + + EQUALS == name -> { + fun DeclarationDescriptor.isAny() = (this as? ClassDescriptor)?.let { KotlinBuiltIns.isAny(it) } ?: false + isMember && overriddenDescriptors.any { it.containingDeclaration.isAny() } + } + COMPARE_TO == name -> returnsInt && singleValueParameter && noDefaultsAndVarargs + + BINARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.size == 1 -> + singleValueParameter && noDefaultsAndVarargs + (PLUS == name) || (MINUS == name) || (UNARY_PLUS == name) || (UNARY_MINUS == name) || (NOT == name) -> + noValueParameters + (INC == name) || (DEC == name) -> { + val receiver = dispatchReceiverParameter ?: extensionReceiverParameter + isMemberOrExtension && (receiver != null) && (returnType?.let { it.isSubtypeOf(receiver.type) } ?: false) + } + + ASSIGNMENT_OPERATIONS.any { it == name } -> + returnsUnit && singleValueParameter && noDefaultsAndVarargs + + name.asString().matches(COMPONENT_REGEX) -> noValueParameters + else -> false + } + } + } + + private val ValueParameterDescriptor.isPropertyMetadata: Boolean + get() = builtIns.propertyMetadata.defaultType.isSubtypeOf(type.makeNotNullable()) + + private val FunctionDescriptor.isMember: Boolean + get() = containingDeclaration is ClassDescriptor + + private val FunctionDescriptor.isMemberOrExtension: Boolean + get() = isExtension || containingDeclaration is ClassDescriptor + + private val FunctionDescriptor.noValueParameters: Boolean + get() = valueParameters.isEmpty + + private val FunctionDescriptor.singleValueParameter: Boolean + get() = valueParameters.size == 1 + + private val FunctionDescriptor.returnsBoolean: Boolean + get() = returnType?.let { KotlinBuiltIns.isBoolean(it) } ?: false + + private val FunctionDescriptor.returnsInt: Boolean + get() = returnType?.let { builtIns.intType == it } ?: false //TODO + + private val FunctionDescriptor.returnsUnit: Boolean + get() = returnType?.let { builtIns.unitType == it } ?: false //TODO + + private val FunctionDescriptor.noDefaultsAndVarargs: Boolean + get() = valueParameters.all { !it.hasDefaultValue() && it.varargElementType == null } + +} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt b/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt index b69ec12f115..9d76263a313 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt @@ -16,13 +16,15 @@ package org.jetbrains.kotlin.util -import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.name.Name import java.util.* import kotlin.text.Regex object OperatorNameConventions { + val GET_VALUE = Name.identifier("getValue") + val SET_VALUE = Name.identifier("setValue") + val EQUALS = Name.identifier("equals") val IDENTITY_EQUALS = Name.identifier("identityEquals"); val COMPARE_TO = Name.identifier("compareTo") @@ -62,31 +64,8 @@ object OperatorNameConventions { // If you add new unary, binary or assignment operators, add it to OperatorConventions as well val UNARY_OPERATION_NAMES_WITH_DEPRECATED = Collections.unmodifiableSet(setOf(INC, DEC, UNARY_PLUS, PLUS, UNARY_MINUS, MINUS, NOT)) - private val UNARY_OPERATION_NAMES = setOf(INC, DEC, UNARY_PLUS, UNARY_MINUS, NOT) - private val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, RANGE_TO) - private val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN) - - fun canBeOperator(functionDescriptor: FunctionDescriptor): Boolean { - val name = functionDescriptor.name - - return when { - GET == name -> true - SET == name -> true - INVOKE == name -> true - CONTAINS == name -> true - ITERATOR == name -> true - NEXT == name -> true - HAS_NEXT == name -> true - EQUALS == name -> true - COMPARE_TO == name -> true - UNARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.isEmpty() -> true - BINARY_OPERATION_NAMES.any { it == name } && functionDescriptor.valueParameters.size() == 1 -> true - (PLUS == name) || (MINUS == name) -> true //temporary fix for deprecated unaryPlus()/unaryMinus() - ASSIGNMENT_OPERATIONS.any { it == name } -> true - name.asString().matches(COMPONENT_REGEX) -> true - else -> false - } - } - + internal val UNARY_OPERATION_NAMES = setOf(INC, DEC, UNARY_PLUS, UNARY_MINUS, NOT) + internal val BINARY_OPERATION_NAMES = setOf(TIMES, PLUS, MINUS, DIV, MOD, RANGE_TO) + internal val ASSIGNMENT_OPERATIONS = setOf(TIMES_ASSIGN, DIV_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN) } diff --git a/idea/testData/checker/ExtensionFunctions.kt b/idea/testData/checker/ExtensionFunctions.kt index b9f516263b0..76a4a3bf2e8 100644 --- a/idea/testData/checker/ExtensionFunctions.kt +++ b/idea/testData/checker/ExtensionFunctions.kt @@ -46,7 +46,7 @@ fun Int.foo() = this val foo : Int = 0 } - operator fun Any.equals(other : Any?) : Boolean = true + operator fun Any.equals(other : Any?) : Boolean = true fun Any?.equals1(other : Any?) : Boolean = true fun Any.equals2(other : Any?) : Boolean = true diff --git a/idea/testData/checker/ForRangeConventions.kt b/idea/testData/checker/ForRangeConventions.kt index 508d61767e0..b5523e94830 100644 --- a/idea/testData/checker/ForRangeConventions.kt +++ b/idea/testData/checker/ForRangeConventions.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/idea/testData/checker/IncDec.kt b/idea/testData/checker/IncDec.kt index 6e1589b445c..050954cab3e 100644 --- a/idea/testData/checker/IncDec.kt +++ b/idea/testData/checker/IncDec.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/idea/testData/intentions/toInfixCall/multipleArguments.kt b/idea/testData/intentions/toInfixCall/multipleArguments.kt index ca2d9cffa41..b69823341d3 100644 --- a/idea/testData/intentions/toInfixCall/multipleArguments.kt +++ b/idea/testData/intentions/toInfixCall/multipleArguments.kt @@ -1,5 +1,5 @@ // IS_APPLICABLE: false -// ERROR: 'infix' modifier is inapplicable on this function +// WARNING: 'infix' modifier is inapplicable on this function interface Foo { infix fun foo(a: Int, b: Int) } diff --git a/idea/testData/intentions/toInfixCall/packageFunctionCall.kt b/idea/testData/intentions/toInfixCall/packageFunctionCall.kt index 5a54d511c7b..0d17025cdc5 100644 --- a/idea/testData/intentions/toInfixCall/packageFunctionCall.kt +++ b/idea/testData/intentions/toInfixCall/packageFunctionCall.kt @@ -1,5 +1,5 @@ // IS_APPLICABLE: false -// ERROR: 'infix' modifier is inapplicable on this function +// WARNING: 'infix' modifier is inapplicable on this function package ppp infix fun foo(p: String){} diff --git a/idea/testData/intentions/toInfixCall/simpleArgumentAndFunctionLiteralArgument.kt b/idea/testData/intentions/toInfixCall/simpleArgumentAndFunctionLiteralArgument.kt index b653d66b18e..4d4d29adef3 100644 --- a/idea/testData/intentions/toInfixCall/simpleArgumentAndFunctionLiteralArgument.kt +++ b/idea/testData/intentions/toInfixCall/simpleArgumentAndFunctionLiteralArgument.kt @@ -1,5 +1,5 @@ // IS_APPLICABLE: false -// ERROR: 'infix' modifier is inapplicable on this function +// WARNING: 'infix' modifier is inapplicable on this function fun foo(x: Foo) { x.foo(1) { it * 2 } diff --git a/idea/testData/intentions/toInfixCall/singlePackageFunctionCall.kt b/idea/testData/intentions/toInfixCall/singlePackageFunctionCall.kt index c2575dec383..56a9aedef81 100644 --- a/idea/testData/intentions/toInfixCall/singlePackageFunctionCall.kt +++ b/idea/testData/intentions/toInfixCall/singlePackageFunctionCall.kt @@ -1,6 +1,6 @@ // WITH_RUNTIME // IS_APPLICABLE: false -// ERROR: 'infix' modifier is inapplicable on this function +// WARNING: 'infix' modifier is inapplicable on this function package demo