'operator' checks

This commit is contained in:
Yan Zhulanow
2015-10-12 02:55:45 +03:00
parent dc8e796e49
commit 275f3f8954
30 changed files with 589 additions and 94 deletions
@@ -564,8 +564,8 @@ public interface Errors {
DiagnosticFactory0<PsiElement> UNDERSCORE_IS_DEPRECATED = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> INAPPLICABLE_INFIX_MODIFIER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<PsiElement> INAPPLICABLE_INFIX_MODIFIER = DiagnosticFactory0.create(WARNING);
DiagnosticFactory2<PsiElement, FunctionDescriptor, String> OPERATOR_MODIFIER_REQUIRED = DiagnosticFactory2.create(WARNING);
DiagnosticFactory2<JetOperationReferenceExpression, FunctionDescriptor, String> INFIX_MODIFIER_REQUIRED = DiagnosticFactory2.create(WARNING);
@@ -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
}
}
@@ -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))
}
}
+1 -1
View File
@@ -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
}
+5 -5
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() {
@@ -43,4 +43,4 @@ fun testUnitIncDec() {
x = <!UNUSED_CHANGED_VALUE!>x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>--<!><!>
x = <!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>x
<!UNUSED_VALUE!>x =<!> <!INC_DEC_SHOULD_NOT_RETURN_UNIT!>--<!>x
}
}
+2 -2
View File
@@ -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, <!UNUSED_PARAMETER!>blah<!>: Int = 0) = Pair(this, other)
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun Example.toExtWithExtraParams(other: Example, <!UNUSED_PARAMETER!>blah<!>: Int = 0) = Pair(this, other)
fun Example.toExtNonInfixWithExtraParams(other: Example, <!UNUSED_PARAMETER!>blah<!>: Int = 0) = Pair(this, other)
infix fun Example.toExtDefaultValues(other: Example? = null, <!UNUSED_PARAMETER!>blah<!>: Int = 0) = Pair(this, other)
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun Example.toExtDefaultValues(other: Example? = null, <!UNUSED_PARAMETER!>blah<!>: Int = 0) = Pair(this, other)
fun Example.toExtNonInfixDefaultValues(other: Example? = null, <!UNUSED_PARAMETER!>blah<!>: Int = 0) = Pair(this, other)
fun Example.withLambda(f: () -> Unit) = Pair(this, f)
@@ -4,8 +4,8 @@ class Pair<A, B>(val a: A, val b: B)
infix fun <A, B> A.to(that: B): Pair<A, B> = 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
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun String.o2(o: String, o2: String? = null) = o
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun String.o3(o: String = "", o2: String? = null) = o
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun w1() {}
<!INAPPLICABLE_INFIX_MODIFIER!>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) {}
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun c2(s: String, a: Int = 0) {}
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun cw1(s: String, a: Int) {}
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun sw2() {}
+211
View File
@@ -0,0 +1,211 @@
interface Example {
operator fun plus(o: Example): Example
operator fun div(o: Example): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(o: Example, s: String = ""): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(vararg o: Example): Example
operator fun unaryPlus(): Example
operator fun unaryMinus(): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(s: String = ""): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(o: Example)
operator fun inc(): Example
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): Example?
operator fun plusAssign(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
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(a: String): Boolean
operator fun contains(n: Int): 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)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get()
operator fun set(n: Int, v: Int)
operator fun set(n: Int, n2: Int, v: Int)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(v: Int)
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
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(n: Int): Int
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun componentN(): Int
operator fun iterator(): String
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun iterator(n: Int): String
operator fun next(): String
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun next(n: Int): String
operator fun hasNext(): Boolean
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun hasNext(n: Int): String
infix fun i1(n: Int)
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun i1(n: Int, n2: Int)
<!INAPPLICABLE_INFIX_MODIFIER!>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 {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun getValue(thisRef: Any?, prop: String): String = ""
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: String, value: String) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: PropertyMetadata, vararg n: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(thisRef: Any?, prop: PropertyMetadata, f: Float = 0.0f) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun getValue(prop: PropertyMetadata): String = ""
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun setValue(prop: PropertyMetadata, value: String) {}
}
interface Example2 {
<!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 {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(other: Example, s: String = ""): Int
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(n: Int)
}
operator fun Example.plus(<!UNUSED_PARAMETER!>o<!>: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.div(<!UNUSED_PARAMETER!>o<!>: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.plus(<!UNUSED_PARAMETER!>o<!>: Example, <!UNUSED_PARAMETER!>s<!>: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minus(vararg <!UNUSED_PARAMETER!>o<!>: Example): 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!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.unaryPlus(<!UNUSED_PARAMETER!>s<!>: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.unaryMinus(<!UNUSED_PARAMETER!>o<!>: Example) {}
operator fun Example.inc(): 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(<!UNUSED_PARAMETER!>n<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.minusAssign(<!UNUSED_PARAMETER!>n<!>: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.divAssign(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>a<!>: String = "") {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.modAssign(vararg <!UNUSED_PARAMETER!>n<!>: Int) {}
operator fun Example.compareTo(<!UNUSED_PARAMETER!>other<!>: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.equals(<!UNUSED_PARAMETER!>a<!>: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.contains(<!UNUSED_PARAMETER!>n<!>: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.contains(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>s<!>: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.invoke() {}
operator fun Example.get(<!UNUSED_PARAMETER!>n<!>: Int) {}
operator fun Example.get(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>n2<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.get() {}
operator fun Example.set(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>v<!>: Int) {}
operator fun Example.set(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>n2<!>: Int, <!UNUSED_PARAMETER!>v<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.set(<!UNUSED_PARAMETER!>v<!>: Int) {}
operator fun Example.rangeTo(<!UNUSED_PARAMETER!>o<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.rangeTo(<!UNUSED_PARAMETER!>o<!>: Int, <!UNUSED_PARAMETER!>o2<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.rangeTo(vararg <!UNUSED_PARAMETER!>o<!>: String) {}
operator fun Example.component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.component1(<!UNUSED_PARAMETER!>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!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.iterator(<!UNUSED_PARAMETER!>n<!>: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.next(): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.next(<!UNUSED_PARAMETER!>n<!>: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun Example.hasNext(): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun Example.hasNext(<!UNUSED_PARAMETER!>n<!>: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
infix fun Example.i1(<!UNUSED_PARAMETER!>n<!>: Int) {}
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun Example.i1(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>n2<!>: Int) {}
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun Example.i1(vararg <!UNUSED_PARAMETER!>n<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(<!UNUSED_PARAMETER!>o<!>: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun div(<!UNUSED_PARAMETER!>o<!>: Example): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plus(<!UNUSED_PARAMETER!>o<!>: Example, <!UNUSED_PARAMETER!>s<!>: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minus(vararg <!UNUSED_PARAMETER!>o<!>: Example): 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!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryPlus(<!UNUSED_PARAMETER!>s<!>: String = ""): Example {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun unaryMinus(<!UNUSED_PARAMETER!>o<!>: Example) {}
<!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!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plusAssign(<!UNUSED_PARAMETER!>n<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minusAssign(<!UNUSED_PARAMETER!>n<!>: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun divAssign(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>a<!>: String = "") {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun modAssign(vararg <!UNUSED_PARAMETER!>n<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun compareTo(<!UNUSED_PARAMETER!>other<!>: Example): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun equals(<!UNUSED_PARAMETER!>a<!>: String): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(<!UNUSED_PARAMETER!>n<!>: Int): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun contains(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>s<!>: String = ""): Boolean {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun invoke() {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get(<!UNUSED_PARAMETER!>n<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>n2<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun get() {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>v<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>n2<!>: Int, <!UNUSED_PARAMETER!>v<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun set(<!UNUSED_PARAMETER!>v<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(<!UNUSED_PARAMETER!>o<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(<!UNUSED_PARAMETER!>o<!>: Int, <!UNUSED_PARAMETER!>o2<!>: Int) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun rangeTo(vararg <!UNUSED_PARAMETER!>o<!>: String) {}
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun component1(<!UNUSED_PARAMETER!>n<!>: Int): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun componentN(): Int {<!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(<!UNUSED_PARAMETER!>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(<!UNUSED_PARAMETER!>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(<!UNUSED_PARAMETER!>n<!>: Int): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun i1(<!UNUSED_PARAMETER!>n<!>: Int) {}
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun i1(<!UNUSED_PARAMETER!>n<!>: Int, <!UNUSED_PARAMETER!>n2<!>: Int) {}
<!INAPPLICABLE_INFIX_MODIFIER!>infix<!> fun i1(vararg <!UNUSED_PARAMETER!>n<!>: Int) {}
+171
View File
@@ -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<out Example>*/): 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<out kotlin.String>*/): 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<out Example>*/): 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<out kotlin.String>*/): 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<out Example>*/): 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<out kotlin.String>*/): 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<out Example>*/): 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
}
@@ -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> @Extension Function2<T, U, V>.minusAssign(ext : @Extension Function2<T, U, V>) {}
inline operator fun <T, U, V> @Extension Function2<T, U, V>.modAssign(ext : @Extension Function2<T, U, V>) = {
inline <!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T, U, V> @Extension Function2<T, U, V>.modAssign(ext : @Extension Function2<T, U, V>) = {
this += ext
ext += this
}
@@ -27,4 +27,4 @@ inline operator fun <T, U, V> @Extension Function2<T, U, V>.plusAssign(ext : @Ex
inline fun <T, U, V> inlineFunWithInvoke(s: (p: T) -> U, ext: T.(p: U) -> V) {
s += s
ext += ext
}
}
@@ -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) {
@@ -7,8 +7,8 @@ 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)
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plusAssign(f : (T) -> Unit) = callbacks.add(f)
<!INAPPLICABLE_OPERATOR_MODIFIER!>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 <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>+=<!> { it.X } // here
control.MouseMoved.plusAssign( { it.X } ) // ok
}
}
}
+6 -6
View File
@@ -1,19 +1,19 @@
package lol
class B() {
operator fun plusAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun plusAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
return "s"
}
operator fun minusAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun minusAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
return "s"
}
operator fun modAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun modAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
return "s"
}
operator fun divAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun divAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
return "s"
}
operator fun timesAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun timesAssign(<!UNUSED_PARAMETER!>other<!> : B) : String {
return "s"
}
}
@@ -25,4 +25,4 @@ fun main(args : Array<String>) {
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>/=<!> B()
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>-=<!> B()
c <!ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT!>%=<!> B()
}
}
@@ -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 { <!UNREACHABLE_CODE!>return<!> null!! }
public fun box() : MyClass? {
var i : MyClass?
var i : MyClass?
i = MyClass()
// type of j can be inferred as MyClass()
var j = <!DEBUG_INFO_SMARTCAST!>i<!>++
<!DEBUG_INFO_SMARTCAST!>j<!>.hashCode()
return i
}
}
@@ -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()
@@ -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 { <!UNREACHABLE_CODE!>return<!> null!! }
public fun box() {
var i : MyClass?
var i : MyClass?
i = MyClass()
// Type of j should be inferred as MyClass?
var j = ++<!DEBUG_INFO_SMARTCAST!>i<!>
// j is null so call is unsafe
j<!UNSAFE_CALL!>.<!>hashCode()
}
j.hashCode()
}
@@ -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()
@@ -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<A!>!
public/*package*/ open fun get(): test.ReturnInnerSubclassOfSupersInner.Super<A!>!
}
}
}
@@ -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<A!>!
public/*package*/ open fun get(): test.ReturnInnerSubclassOfSupersInner.Super<A!>!
}
}
}
@@ -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)
@@ -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;
}
@@ -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 }
}
@@ -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)
}
+1 -1
View File
@@ -46,7 +46,7 @@ fun Int.foo() = this
val foo : Int = 0
}
operator fun Any.equals(<warning>other</warning> : Any?) : Boolean = true
<warning>operator</warning> fun Any.equals(<warning>other</warning> : Any?) : Boolean = true
fun Any?.equals1(<warning>other</warning> : Any?) : Boolean = true
fun Any.equals2(<warning>other</warning> : Any?) : Boolean = true
+1 -1
View File
@@ -27,7 +27,7 @@ abstract class NotRange4() {
}
abstract class ImproperIterator3 {
abstract operator fun hasNext() : Int
abstract <warning>operator</warning> 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
<warning>operator</warning> fun inc() : Int = 1
<warning>operator</warning> fun dec() : Int = 1
}
fun testWrongIncDec() {
@@ -29,8 +29,8 @@ fun testWrongIncDec() {
}
class UnitIncDec() {
operator fun inc() : Unit {}
operator fun dec() : Unit {}
<warning>operator</warning> fun inc() : Unit {}
<warning>operator</warning> fun dec() : Unit {}
}
fun testUnitIncDec() {
+1 -1
View File
@@ -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)
}
@@ -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){}
@@ -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.<caret>foo(1) { it * 2 }
@@ -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