== turned into a safe-call

This commit is contained in:
Andrey Breslav
2015-02-03 18:25:19 +03:00
parent 560b2346a6
commit 0e972acf8c
50 changed files with 149 additions and 142 deletions
@@ -118,7 +118,6 @@ public class IntrinsicMethods {
declareIntrinsicFunction("Cloneable", "clone", 0, CLONE);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "toString", 0, TO_STRING);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "equals", 1, EQUALS);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_ANY_FQ_NAME, "identityEquals", 1, IDENTITY_EQUALS);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, KOTLIN_STRING_FQ_NAME, "plus", 1, STRING_PLUS);
intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "arrayOfNulls", 1, new NewArray());
@@ -54,6 +54,10 @@ public class JetPsiFactory(private val project: Project) {
return createParameterList("($text int x)").getParameters().first().getValOrVarNode()!!
}
public fun createSafeCallNode(): ASTNode {
return (createExpression("a?.b") as JetSafeQualifiedExpression).getOperationTokenNode()
}
public fun createExpression(text: String): JetExpression {
return createProperty("val x = $text").getInitializer()!!
}
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.context.LazinessToken
import org.jetbrains.kotlin.resolve.lazy.LazyEntity
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.psi.debugText.getDebugText
public class TypeResolver(
private val annotationResolver: AnnotationResolver,
@@ -237,7 +238,7 @@ public class TypeResolver(
c.trace.report(UNSUPPORTED.on(element, "Self-types are not supported yet"))
}
})
return result ?: type(ErrorUtils.createErrorType(typeElement?.getText() ?: "No type element"))
return result ?: type(ErrorUtils.createErrorType(typeElement?.getDebugText() ?: "No type element"))
}
private fun getScopeForTypeParameter(c: TypeResolutionContext, typeParameterDescriptor: TypeParameterDescriptor): JetScope {
@@ -932,7 +932,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ExpressionTypingUtils.getTypeInfoOrNullType(left, context, facade);
return JetTypeInfo.create(components.builtIns.getBooleanType(), dataFlowInfo);
}
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context);
JetTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context, facade);
@@ -946,16 +945,30 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
context.trace, "trace to resolve 'equals(Any?)' interpreting as of type Any? an expression:", right);
traceInterpretingRightAsNullableAny.record(EXPRESSION_TYPE, right, components.builtIns.getNullableAnyType());
Call call = CallMaker.makeCallWithExpressions(expression, receiver, null, operationSign, Collections.singletonList(right));
// Nothing? has no members, and `equals()` would be unresolved on it
JetType leftType = leftTypeInfo.getType();
if (leftType != null && KotlinBuiltIns.isNothingOrNullableNothing(leftType)) {
traceInterpretingRightAsNullableAny.record(EXPRESSION_TYPE, left, components.builtIns.getNullableAnyType());
}
ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, newContext);
Call call = CallMaker.makeCallWithExpressions(
expression,
receiver,
// semantically, a call to `==` is a safe call
new JetPsiFactory(expression.getProject()).createSafeCallNode(),
operationSign,
Collections.singletonList(right)
);
OverloadResolutionResults<FunctionDescriptor> resolutionResults =
components.callResolver.resolveCallWithGivenName(newContext, call, operationSign, OperatorConventions.EQUALS);
traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {
@Override
public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
// the type of the right expression isn't 'Any?' actually
if (key == right && slice == EXPRESSION_TYPE) return false;
// the type of the right (and sometimes left) expression isn't 'Any?' actually
if ((key == right || key == left) && slice == EXPRESSION_TYPE) return false;
// a hack due to KT-678
// without this line an smartcast is reported on the receiver (if it was previously checked for not-null)
@@ -1154,6 +1167,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
else if (nullability == Nullability.NOT_NULL) {
expressionIsAlways = !equality;
}
else if (nullability == Nullability.IMPOSSIBLE) {
expressionIsAlways = false;
}
else return;
context.trace.report(SENSELESS_COMPARISON.on(expression, expression, expressionIsAlways));
-1
View File
@@ -1,7 +1,6 @@
package-fragment kotlin
public fun </*0*/ reified T> arrayOfNulls(/*0*/ size: kotlin.Int): kotlin.Array<T?>
public fun kotlin.Any?.equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public fun kotlin.Any?.identityEquals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public fun kotlin.String?.plus(/*0*/ other: kotlin.Any?): kotlin.String
public fun kotlin.Any?.toString(): kotlin.String
@@ -4,12 +4,12 @@ fun foo(a: Int, b: Int) {
}
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{{<: Any}, {<: Any}} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a == b <v4>: Boolean NEW: call(a == b, equals|<v2>, <v3>) -> <v4>
{ } !<v5>: *
if (a == b) { } <v6>: * NEW: merge(if (a == b) { }|!<v5>) -> <v6>
{ if (a == b) { } } <v6>: * COPY
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{*, *} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a == b <v4>: Boolean NEW: call(a == b, equals|<v2>, <v3>) -> <v4>
{ } !<v5>: *
if (a == b) { } <v6>: * NEW: merge(if (a == b) { }|!<v5>) -> <v6>
{ if (a == b) { } } <v6>: * COPY
=====================
@@ -3,12 +3,12 @@ fun neq(a: Int, b: Int) {
if (a != b) {}
}
---------------------
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{{<: Any}, {<: Any}} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a != b <v4>: Boolean NEW: call(a != b, equals|<v2>, <v3>) -> <v4>
{} !<v5>: *
if (a != b) {} <v6>: * NEW: merge(if (a != b) {}|!<v5>) -> <v6>
{ if (a != b) {} } <v6>: * COPY
<v0>: Int NEW: magic[FAKE_INITIALIZER](a: Int) -> <v0>
<v1>: Int NEW: magic[FAKE_INITIALIZER](b: Int) -> <v1>
a <v2>: OR{*, *} NEW: r(a) -> <v2>
b <v3>: * NEW: r(b) -> <v3>
a != b <v4>: Boolean NEW: call(a != b, equals|<v2>, <v3>) -> <v4>
{} !<v5>: *
if (a != b) {} <v6>: * NEW: merge(if (a != b) {}|!<v5>) -> <v6>
{ if (a != b) {} } <v6>: * COPY
=====================
+19 -19
View File
@@ -4,23 +4,23 @@ tailRecursive fun sum(x: Long, sum: Long): Long {
return sum(x - 1, sum + x)
}
---------------------
<v0>: Long NEW: magic[FAKE_INITIALIZER](x: Long) -> <v0>
<v1>: Long NEW: magic[FAKE_INITIALIZER](sum: Long) -> <v1>
x <v2>: OR{{<: Any}, {<: Any}} NEW: r(x) -> <v2>
0 <v3>: {<: Number} NEW: r(0) -> <v3>
toLong() <v4>: * NEW: call(toLong(), toLong|<v3>) -> <v4>
0.toLong() <v4>: * COPY
x == 0.toLong() <v5>: Boolean NEW: call(x == 0.toLong(), equals|<v2>, <v4>) -> <v5>
sum <v6>: Long NEW: r(sum) -> <v6>
return sum !<v7>: *
if (x == 0.toLong()) return sum <v8>: * NEW: merge(if (x == 0.toLong()) return sum|!<v7>) -> <v8>
x <v9>: Long NEW: r(x) -> <v9>
1 <v10>: Int NEW: r(1) -> <v10>
x - 1 <v11>: Long NEW: call(x - 1, minus|<v9>, <v10>) -> <v11>
sum <v12>: Long NEW: r(sum) -> <v12>
x <v13>: Long NEW: r(x) -> <v13>
sum + x <v14>: Long NEW: call(sum + x, plus|<v12>, <v13>) -> <v14>
sum(x - 1, sum + x) <v15>: Long NEW: call(sum(x - 1, sum + x), sum|<v11>, <v14>) -> <v15>
return sum(x - 1, sum + x) !<v16>: *
{ if (x == 0.toLong()) return sum return sum(x - 1, sum + x) } !<v16>: * COPY
<v0>: Long NEW: magic[FAKE_INITIALIZER](x: Long) -> <v0>
<v1>: Long NEW: magic[FAKE_INITIALIZER](sum: Long) -> <v1>
x <v2>: OR{*, *} NEW: r(x) -> <v2>
0 <v3>: {<: Number} NEW: r(0) -> <v3>
toLong() <v4>: * NEW: call(toLong(), toLong|<v3>) -> <v4>
0.toLong() <v4>: * COPY
x == 0.toLong() <v5>: Boolean NEW: call(x == 0.toLong(), equals|<v2>, <v4>) -> <v5>
sum <v6>: Long NEW: r(sum) -> <v6>
return sum !<v7>: *
if (x == 0.toLong()) return sum <v8>: * NEW: merge(if (x == 0.toLong()) return sum|!<v7>) -> <v8>
x <v9>: Long NEW: r(x) -> <v9>
1 <v10>: Int NEW: r(1) -> <v10>
x - 1 <v11>: Long NEW: call(x - 1, minus|<v9>, <v10>) -> <v11>
sum <v12>: Long NEW: r(sum) -> <v12>
x <v13>: Long NEW: r(x) -> <v13>
sum + x <v14>: Long NEW: call(sum + x, plus|<v12>, <v13>) -> <v14>
sum(x - 1, sum + x) <v15>: Long NEW: call(sum(x - 1, sum + x), sum|<v11>, <v14>) -> <v15>
return sum(x - 1, sum + x) !<v16>: *
{ if (x == 0.toLong()) return sum return sum(x - 1, sum + x) } !<v16>: * COPY
=====================
@@ -1,8 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by Delegate()
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,8 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a by Delegate()
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,10 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
abstract class A {
abstract val a: Int <!ABSTRACT_DELEGATED_PROPERTY!>by Delegate()<!>
}
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class B {
val a: Int by Delegate()
@@ -6,7 +8,6 @@ class B {
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
trait A {
val prop: Int
}
@@ -12,7 +14,6 @@ fun foo() {
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
trait A {
val prop: Int
}
@@ -12,7 +14,6 @@ fun foo() {
class Delegate {
fun get(t: Any?, p: PropertyMetadata): String {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return ""
}
}
@@ -1,8 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by A(1)
class A<T: Any>(<!UNUSED_PARAMETER!>i<!>: T) {
class A<T: Any>(i: T) {
fun get(t: Any?, p: PropertyMetadata): T {
t.equals(p) // to avoid UNUSED_PARAMETER warning
throw Exception()
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
open class Base
class Derived: Base()
@@ -5,7 +7,6 @@ val a: Base by A()
class A {
fun get(t: Any?, p: PropertyMetadata): Derived {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return Derived()
}
}
@@ -1,10 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
trait T {
val a: Int <!DELEGATED_PROPERTY_IN_TRAIT!>by Delegate()<!>
}
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A
class D {
@@ -8,7 +10,6 @@ val cTopLevel: Int by <!DELEGATE_SPECIAL_FUNCTION_MISSING!>IncorrectThis<A>()<!>
class IncorrectThis<T> {
fun get<R>(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,12 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
class Local {
fun foo() {
val <!UNUSED_VARIABLE!>a<!>: Int <!LOCAL_VARIABLE_WITH_DELEGATE!>by Delegate()<!>
val a: Int <!LOCAL_VARIABLE_WITH_DELEGATE!>by Delegate()<!>
}
}
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,8 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
var a: Int by <!DELEGATE_SPECIAL_FUNCTION_MISSING!>A()<!>
class A {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,10 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class B {
val c by Delegate(<!UNRESOLVED_REFERENCE!>ag<!>)
}
class Delegate<T: Any>(val init: T) {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
throw Exception()
}
fun get(t: Any?, p: PropertyMetadata): Int = null!!
}
@@ -1,16 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by <!DELEGATE_SPECIAL_FUNCTION_AMBIGUITY!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun propertyDelegated(p: PropertyMetadata) {
p.equals(p)
}
fun propertyDelegated(p: PropertyMetadata) {}
fun propertyDelegated(p: PropertyMetadata, s: String = "") {
p.equals(s)
}
fun propertyDelegated(p: PropertyMetadata, s: String = "") {}
}
@@ -1,12 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by <!DELEGATE_PD_METHOD_NONE_APPLICABLE!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun propertyDelegated<T>(p: PropertyMetadata) {
p.equals(p)
}
fun propertyDelegated<T>(p: PropertyMetadata) {}
}
@@ -1,8 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by Delegate()
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,12 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by <!DELEGATE_PD_METHOD_NONE_APPLICABLE!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
private fun propertyDelegated(p: PropertyMetadata) {
p.equals(p)
}
private fun propertyDelegated(p: PropertyMetadata) {}
}
@@ -1,22 +1,17 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by <!DELEGATE_PD_METHOD_NONE_APPLICABLE!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun propertyDelegated() {}
fun propertyDelegated(a: Int) {
a.equals(a)
}
fun propertyDelegated(a: Int) {}
fun propertyDelegated(a: String) {
a.equals(a)
}
fun propertyDelegated(a: String) {}
fun propertyDelegated(p: PropertyMetadata, a: Int) {
p.equals(a)
}
fun propertyDelegated(p: PropertyMetadata, a: Int) {}
}
@@ -1,8 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
<!PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE!>public val a<!> by Delegate()
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a by <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>a<!>
val b by Delegate(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>b<!>)
@@ -5,9 +7,8 @@ val b by Delegate(<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>b<!>)
val c by <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>d<!>
val d by <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>c<!>
class Delegate(<!UNUSED_PARAMETER!>i<!>: Int) {
class Delegate(i: Int) {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,9 +1,10 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val a: Int by Delegate()
<!ACCESSOR_FOR_DELEGATED_PROPERTY!>get() = 1<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,14 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
var a: Int by Delegate()
<!ACCESSOR_FOR_DELEGATED_PROPERTY!>get() = 1<!>
<!ACCESSOR_FOR_DELEGATED_PROPERTY!>set(i) {}<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun set(t: Any?, p: PropertyMetadata, i: Int) {
t.equals(p) || i.equals(null) // to avoid UNUSED_PARAMETER warning
}
fun set(t: Any?, p: PropertyMetadata, i: Int) {}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class D {
var c: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!>
}
@@ -8,11 +10,7 @@ class A
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun set(t: A, p: PropertyMetadata, i: Int) {
t.equals(p) // to avoid UNUSED_PARAMETER warning
i.equals(null)
}
fun set(t: A, p: PropertyMetadata, i: Int) {}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
open class Base
class Derived: Base()
@@ -5,13 +7,9 @@ var a: Derived by A()
class A {
fun get(t: Any?, p: PropertyMetadata): Derived {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return Derived()
}
fun set(t: Any?, p: PropertyMetadata, i: Base) {
t.equals(p) // to avoid UNUSED_PARAMETER warning
i.equals(null) // to avoid UNUSED_PARAMETER warning
}
fun set(t: Any?, p: PropertyMetadata, i: Base) {}
}
@@ -1,12 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val Int.a by Delegate(<!NO_THIS!>this<!>)
class A {
val Int.a by Delegate(<!TYPE_MISMATCH!>this<!>)
}
class Delegate(<!UNUSED_PARAMETER!>i<!>: Int) {
class Delegate(i: Int) {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A {
var a: Int by Delegate()
}
@@ -6,11 +8,7 @@ var aTopLevel: Int by Delegate()
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun set(t: Any?, p: PropertyMetadata, a: Int) {
t.equals(p) // to avoid UNUSED_PARAMETER warning
a.equals(null)
}
fun set(t: Any?, p: PropertyMetadata, a: Int) {}
}
@@ -1,8 +1,9 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
val c: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): String {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return ""
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A {
var a: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!>
}
@@ -6,11 +8,7 @@ var aTopLevel: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun set(t: Any?, p: PropertyMetadata, i: String) {
t.equals(p) // to avoid UNUSED_PARAMETER warning
i.equals(null)
}
fun set(t: Any?, p: PropertyMetadata, i: String) {}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A {
val a: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!>
}
@@ -6,7 +8,6 @@ val aTopLevel: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata, a: Int): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return a
}
}
@@ -1,3 +1,5 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A {
var a: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!>
}
@@ -6,12 +8,8 @@ var aTopLevel: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE!>Delegate()<!>
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun set(t: Any?, p: PropertyMetadata, a: Int, c: Int) {
t.equals(p) // to avoid UNUSED_PARAMETER warning
c.equals(a)
}
fun set(t: Any?, p: PropertyMetadata, a: Int, c: Int) {}
}
@@ -1,13 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
var b: Int by Delegate()
class Delegate {
fun get(t: Any?, p: PropertyMetadata): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return 1
}
fun set(t: Any?, p: PropertyMetadata, i: Int): Int {
t.equals(p) // to avoid UNUSED_PARAMETER warning
return i
}
}
@@ -63,7 +63,7 @@ import outer.*
command.foo
command.equals(null)
command<!UNSAFE_CALL!>.<!>equals(null)
command?.equals(null)
command.equals1(null)
command?.equals1(null)
@@ -12,7 +12,6 @@ internal final class C : kotlin.MutableIterator<kotlin.Int> {
package kotlin {
public fun </*0*/ reified T> arrayOfNulls(/*0*/ size: kotlin.Int): kotlin.Array<T?>
public fun kotlin.Any?.equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public fun kotlin.Any?.identityEquals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public fun kotlin.String?.plus(/*0*/ other: kotlin.Any?): kotlin.String
public fun kotlin.Any?.toString(): kotlin.String
@@ -2,7 +2,6 @@
class Foo() {}
fun Any.equals(<!UNUSED_PARAMETER!>other<!> : Any?) : Boolean = true
fun Any?.equals1(<!UNUSED_PARAMETER!>other<!> : Any?) : Boolean = true
fun main(args: Array<String>) {
@@ -14,5 +13,6 @@ fun main(args: Array<String>) {
// .equals(null) => 1; // must be resolved
// ?.equals(null) => 1 // same here
// }
command.equals(null)
command.equals1(null)
command?.equals(null)
}
@@ -1,7 +1,6 @@
package
internal fun main(/*0*/ args: kotlin.Array<kotlin.String>): kotlin.Unit
internal fun kotlin.Any.equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal fun kotlin.Any?.equals1(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final class Foo {
@@ -2,7 +2,6 @@ package
package kotlin {
public fun </*0*/ reified T> arrayOfNulls(/*0*/ size: kotlin.Int): kotlin.Array<T?>
public fun kotlin.Any?.equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public fun kotlin.Any?.identityEquals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public fun kotlin.String?.plus(/*0*/ other: kotlin.Any?): kotlin.String
public fun kotlin.Any?.toString(): kotlin.String
@@ -30,7 +30,7 @@ public class FunctionGenTest extends CodegenTestCase {
}
public void testAnyEqualsNullable() throws InvocationTargetException, IllegalAccessException {
loadText("fun foo(x: Any?) = x.equals(\"lala\")");
loadText("fun foo(x: Any?) = x?.equals(\"lala\")");
Method foo = generateFunction();
assertTrue((Boolean) foo.invoke(null, "lala"));
assertFalse((Boolean) foo.invoke(null, "mama"));
-7
View File
@@ -22,13 +22,6 @@ package kotlin
*/
public fun Any?.identityEquals(other: Any?): Boolean // = this === other
/**
* Returns true if the receiver and the [other] object are "equal" to each other, or if they are
* both null.
* @see Any.equals
*/
public fun Any?.equals(other: Any?): Boolean
/**
* Returns a string representation of the object. Can be called with a null receiver, in which case
* it returns the string "null".
+1 -1
View File
@@ -58,7 +58,7 @@ fun Int.foo() = this
command.foo
command.equals(null)
command<error descr="[UNSAFE_CALL] Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Command?">.</error>equals(null)
command?.equals(null)
command.equals1(null)
command?.equals1(null)
@@ -1,5 +1,6 @@
val a = <selection>1 == 2</selection>
val b = 1.equals(2)
val b1 = 1?.equals(2)
val c = 2.equals(1)
val d = 1 === 2
val e = 1 != 2
@@ -1,3 +1,3 @@
1 == 2
1.equals(2)
1?.equals(2)
@@ -7,7 +7,7 @@ fun box(): Boolean {
if (!(a equals 2.0)) return false
val c = "a"
if (!("a" equals c)) return false
if (!(null equals null)) return false
if (!((null : Any?)?.equals(null) ?: true)) return false
val d = 5.6
if (!(d.toShort() equals 5.toShort())) return false
if (!(d.toByte() equals 5.toByte())) return false