x?.y != null and x?.call() != null provoke now x != null, a set of tests #KT-2127 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
9001b9bcc0
commit
11f50186fa
+22
-9
@@ -180,10 +180,11 @@ object DataFlowValueFactory {
|
|||||||
is KtQualifiedExpression -> {
|
is KtQualifiedExpression -> {
|
||||||
val receiverExpression = expression.receiverExpression
|
val receiverExpression = expression.receiverExpression
|
||||||
val selectorExpression = expression.selectorExpression
|
val selectorExpression = expression.selectorExpression
|
||||||
val receiverId = getIdForStableIdentifier(receiverExpression, bindingContext, containingDeclarationOrModule)
|
val receiverInfo = getIdForStableIdentifier(receiverExpression, bindingContext, containingDeclarationOrModule)
|
||||||
val selectorId = getIdForStableIdentifier(selectorExpression, bindingContext, containingDeclarationOrModule)
|
val selectorInfo = getIdForStableIdentifier(selectorExpression, bindingContext, containingDeclarationOrModule)
|
||||||
|
|
||||||
IdentifierInfo.qualified(receiverId, selectorId, expression.operationSign === KtTokens.SAFE_ACCESS)
|
IdentifierInfo.qualified(receiverInfo, bindingContext.getType(receiverExpression),
|
||||||
|
selectorInfo, expression.operationSign === KtTokens.SAFE_ACCESS)
|
||||||
}
|
}
|
||||||
is KtSimpleNameExpression ->
|
is KtSimpleNameExpression ->
|
||||||
getIdForSimpleNameExpression(expression, bindingContext, containingDeclarationOrModule)
|
getIdForSimpleNameExpression(expression, bindingContext, containingDeclarationOrModule)
|
||||||
@@ -219,13 +220,25 @@ object DataFlowValueFactory {
|
|||||||
// for now it fails for resolving 'invoke' convention, return it after 'invoke' algorithm changes
|
// for now it fails for resolving 'invoke' convention, return it after 'invoke' algorithm changes
|
||||||
// assert resolvedCall != null : "Cannot create right identifier info if the resolved call is not known yet for
|
// assert resolvedCall != null : "Cannot create right identifier info if the resolved call is not known yet for
|
||||||
val usageModuleDescriptor = DescriptorUtils.getContainingModuleOrNull(containingDeclarationOrModule)
|
val usageModuleDescriptor = DescriptorUtils.getContainingModuleOrNull(containingDeclarationOrModule)
|
||||||
val receiverInfo = resolvedCall?.let { getIdForImplicitReceiver(it.dispatchReceiver, simpleNameExpression) }
|
val selectorInfo = IdentifierInfo.Variable(declarationDescriptor,
|
||||||
|
variableKind(declarationDescriptor, usageModuleDescriptor,
|
||||||
|
bindingContext, simpleNameExpression))
|
||||||
|
|
||||||
IdentifierInfo.qualified(receiverInfo,
|
val implicitReceiver = resolvedCall?.dispatchReceiver
|
||||||
IdentifierInfo.Variable(declarationDescriptor,
|
if (implicitReceiver == null) {
|
||||||
variableKind(declarationDescriptor, usageModuleDescriptor,
|
selectorInfo
|
||||||
bindingContext, simpleNameExpression)),
|
}
|
||||||
resolvedCall?.call?.isSafeCall() ?: false)
|
else {
|
||||||
|
val receiverInfo = getIdForImplicitReceiver(implicitReceiver, simpleNameExpression)
|
||||||
|
|
||||||
|
if (receiverInfo == null) {
|
||||||
|
selectorInfo
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IdentifierInfo.qualified(receiverInfo, implicitReceiver.type,
|
||||||
|
selectorInfo, resolvedCall?.call?.isSafeCall() ?: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is PackageViewDescriptor, is ClassDescriptor -> IdentifierInfo.PackageOrClass(declarationDescriptor)
|
is PackageViewDescriptor, is ClassDescriptor -> IdentifierInfo.PackageOrClass(declarationDescriptor)
|
||||||
else -> IdentifierInfo.NO
|
else -> IdentifierInfo.NO
|
||||||
|
|||||||
+13
-3
@@ -90,8 +90,18 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun putNullability(map: MutableMap<DataFlowValue, Nullability>, value: DataFlowValue, nullability: Nullability): Boolean {
|
private fun putNullability(map: MutableMap<DataFlowValue, Nullability>, value: DataFlowValue,
|
||||||
|
nullability: Nullability, affectReceiver: Boolean = true): Boolean {
|
||||||
map.put(value, nullability)
|
map.put(value, nullability)
|
||||||
|
|
||||||
|
val identifierInfo = value.identifierInfo
|
||||||
|
if (affectReceiver && !nullability.canBeNull() && identifierInfo is IdentifierInfo.Qualified) {
|
||||||
|
val receiverType = identifierInfo.receiverType
|
||||||
|
if (identifierInfo.safe && receiverType != null) {
|
||||||
|
putNullability(map, DataFlowValue(identifierInfo.receiverInfo, receiverType), nullability)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nullability != getCollectedNullability(value)
|
return nullability != getCollectedNullability(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +145,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
override fun assign(a: DataFlowValue, b: DataFlowValue): DataFlowInfo {
|
override fun assign(a: DataFlowValue, b: DataFlowValue): DataFlowInfo {
|
||||||
val nullability = Maps.newHashMap<DataFlowValue, Nullability>()
|
val nullability = Maps.newHashMap<DataFlowValue, Nullability>()
|
||||||
val nullabilityOfB = getPredictableNullability(b)
|
val nullabilityOfB = getPredictableNullability(b)
|
||||||
putNullability(nullability, a, nullabilityOfB)
|
putNullability(nullability, a, nullabilityOfB, affectReceiver = false)
|
||||||
|
|
||||||
val newTypeInfo = newTypeInfo()
|
val newTypeInfo = newTypeInfo()
|
||||||
var typesForB = getPredictableTypes(b)
|
var typesForB = getPredictableTypes(b)
|
||||||
@@ -212,7 +222,7 @@ internal class DelegatingDataFlowInfo private constructor(
|
|||||||
val nullabilityOfA = getPredictableNullability(a)
|
val nullabilityOfA = getPredictableNullability(a)
|
||||||
val nullabilityOfB = getPredictableNullability(b)
|
val nullabilityOfB = getPredictableNullability(b)
|
||||||
|
|
||||||
var changed = putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert())) or
|
val changed = putNullability(builder, a, nullabilityOfA.refine(nullabilityOfB.invert())) or
|
||||||
putNullability(builder, b, nullabilityOfB.refine(nullabilityOfA.invert()))
|
putNullability(builder, b, nullabilityOfB.refine(nullabilityOfA.invert()))
|
||||||
return if (changed) create(this, ImmutableMap.copyOf(builder), EMPTY_TYPE_INFO) else this
|
return if (changed) create(this, ImmutableMap.copyOf(builder), EMPTY_TYPE_INFO) else this
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-11
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue.Kind.STABLE_V
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface IdentifierInfo {
|
interface IdentifierInfo {
|
||||||
|
|
||||||
@@ -72,7 +73,8 @@ interface IdentifierInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Qualified(
|
class Qualified(
|
||||||
val receiverInfo: IdentifierInfo, val selectorInfo: IdentifierInfo, val safe: Boolean
|
val receiverInfo: IdentifierInfo, val selectorInfo: IdentifierInfo,
|
||||||
|
val safe: Boolean, val receiverType: KotlinType?
|
||||||
) : IdentifierInfo {
|
) : IdentifierInfo {
|
||||||
override val kind: DataFlowValue.Kind get() = if (receiverInfo.kind.isStable()) selectorInfo.kind else OTHER
|
override val kind: DataFlowValue.Kind get() = if (receiverInfo.kind.isStable()) selectorInfo.kind else OTHER
|
||||||
|
|
||||||
@@ -89,16 +91,13 @@ interface IdentifierInfo {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun qualified(receiverInfo: IdentifierInfo?, selectorInfo: IdentifierInfo, safe: Boolean): IdentifierInfo {
|
fun qualified(
|
||||||
return if (selectorInfo == NO || receiverInfo === NO) {
|
receiverInfo: IdentifierInfo, receiverType: KotlinType?,
|
||||||
NO
|
selectorInfo: IdentifierInfo, safe: Boolean
|
||||||
}
|
) = when (receiverInfo) {
|
||||||
else if (receiverInfo == null || receiverInfo is PackageOrClass) {
|
NO -> NO
|
||||||
selectorInfo
|
is PackageOrClass -> selectorInfo
|
||||||
}
|
else -> Qualified(receiverInfo, selectorInfo, safe, receiverType)
|
||||||
else {
|
|
||||||
Qualified(receiverInfo, selectorInfo, safe)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-4
@@ -11,14 +11,16 @@ interface B {
|
|||||||
|
|
||||||
fun test(u: A?, x: A?, y: A?, z: A?, w: A, v: A?) {
|
fun test(u: A?, x: A?, y: A?, z: A?, w: A, v: A?) {
|
||||||
u?.b?.foo()!! // was UNNECESSARY_SAFE_CALL everywhere, because result type (of 'foo()') wasn't made nullable
|
u?.b?.foo()!! // was UNNECESSARY_SAFE_CALL everywhere, because result type (of 'foo()') wasn't made nullable
|
||||||
u!!.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
u<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
x?.b!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
x?.b!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
x!!.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
// x?.b is not null
|
||||||
|
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
|
|
||||||
y?.nb?.foo()!!
|
y?.nb?.foo()!!
|
||||||
y!!.nb?.foo()!!
|
y<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.nb?.foo()!!
|
||||||
z?.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
z?.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
z!!.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
// z?.nb is not null
|
||||||
|
z<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
|
|
||||||
w.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
w.b<!UNNECESSARY_SAFE_CALL!>?.<!>foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
w.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
w.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ public class Throwables() {
|
|||||||
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) : Unit {
|
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) : Unit {
|
||||||
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
|
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
|
||||||
{
|
{
|
||||||
throw declaredType?.cast(throwable)!!
|
throw declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public fun propagateIfPossible(throwable : Throwable?) : Unit {
|
public fun propagateIfPossible(throwable : Throwable?) : Unit {
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ val items: ArrayList<Item> = ArrayList<Item>()
|
|||||||
fun test(room : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>Object<!>) {
|
fun test(room : <!PLATFORM_CLASS_MAPPED_TO_KOTLIN!>Object<!>) {
|
||||||
for(item: Item? in items) {
|
for(item: Item? in items) {
|
||||||
if (item?.room === room) {
|
if (item?.room === room) {
|
||||||
System.out.println("You see " + item?.name)
|
// item?.room is not null
|
||||||
|
System.out.println("You see " + item<!UNNECESSARY_SAFE_CALL!>?.<!>name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ public class Throwables() {
|
|||||||
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) {
|
public fun <X : Throwable?> propagateIfInstanceOf(throwable : Throwable?, declaredType : Class<X?>?) {
|
||||||
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
|
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
|
||||||
{
|
{
|
||||||
throw declaredType?.cast(throwable)!!
|
throw declaredType<!UNNECESSARY_SAFE_CALL!>?.<!>cast(throwable)!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public fun propagateIfPossible(throwable : Throwable?) {
|
public fun propagateIfPossible(throwable : Throwable?) {
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ fun foo(y: MyClass?): Int {
|
|||||||
}
|
}
|
||||||
fun bar(y: MyClass?) {
|
fun bar(y: MyClass?) {
|
||||||
y?.x!!.length
|
y?.x!!.length
|
||||||
// !! is necessary here
|
// !! is NOT necessary here, because y?.x != null
|
||||||
y!!.x
|
y<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.x
|
||||||
}
|
}
|
||||||
+125
@@ -0,0 +1,125 @@
|
|||||||
|
// A set of examples for
|
||||||
|
// "If the result of a safe call is not null, understand that its receiver is not null"
|
||||||
|
// and some other improvements for nullability detection
|
||||||
|
|
||||||
|
fun kt6840_1(s: String?) {
|
||||||
|
val hash = s?.hashCode()
|
||||||
|
if (hash != null) {
|
||||||
|
// To be supported
|
||||||
|
s<!UNSAFE_CALL!>.<!>length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kt6840_2(s: String?) {
|
||||||
|
if (s?.hashCode() != null) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>s<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kt1635(s: String?) {
|
||||||
|
s?.hashCode()!!
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>s<!>.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kt2127() {
|
||||||
|
val s: String? = ""
|
||||||
|
if (s?.length != null) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>s<!>.hashCode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kt3356(s: String?): Int {
|
||||||
|
if (s?.length != 1) return 0
|
||||||
|
return <!DEBUG_INFO_SMARTCAST!>s<!>.length
|
||||||
|
}
|
||||||
|
|
||||||
|
open class SomeClass(val data: Any)
|
||||||
|
|
||||||
|
class SubClass(val extra: Any, data: Any) : SomeClass(data)
|
||||||
|
|
||||||
|
fun kt4565_1(a: SomeClass?) {
|
||||||
|
val data = a?.data
|
||||||
|
if (data != null) {
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>data<!>.hashCode()
|
||||||
|
// To be supported
|
||||||
|
a<!UNSAFE_CALL!>.<!>hashCode()
|
||||||
|
a<!UNSAFE_CALL!>.<!>data.hashCode()
|
||||||
|
}
|
||||||
|
if (a?.data != null) {
|
||||||
|
// To be supported
|
||||||
|
data<!UNSAFE_CALL!>.<!>hashCode()
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>a<!>.hashCode()
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>a<!>.data.hashCode()
|
||||||
|
}
|
||||||
|
if (a?.data is String) {
|
||||||
|
// To be supported
|
||||||
|
a<!UNSAFE_CALL!>.<!>data.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
data.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kt4565_2(a: SomeClass?) {
|
||||||
|
// To be supported
|
||||||
|
if (a as? SubClass != null) {
|
||||||
|
a.<!UNRESOLVED_REFERENCE!>extra<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>hashCode<!>()
|
||||||
|
}
|
||||||
|
val extra = (a as? SubClass)?.extra
|
||||||
|
if (extra != null) {
|
||||||
|
a.<!UNRESOLVED_REFERENCE!>extra<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>hashCode<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(val y: Int)
|
||||||
|
|
||||||
|
fun kt7491_1() {
|
||||||
|
val x: A? = A(42)
|
||||||
|
val <!UNUSED_VARIABLE!>z<!> = x?.y ?: return
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>x<!>.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getA(): A? = null
|
||||||
|
fun useA(a: A): Int = a.hashCode()
|
||||||
|
|
||||||
|
fun kt7491_2() {
|
||||||
|
val a = getA()
|
||||||
|
(a?.let { useA(<!DEBUG_INFO_SMARTCAST!>a<!>) } ?: a<!UNSAFE_CALL!>.<!>y ).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.correct() = true
|
||||||
|
|
||||||
|
fun kt8492(s: String?) {
|
||||||
|
if (s?.correct() ?: false) {
|
||||||
|
// To be supported
|
||||||
|
s<!UNSAFE_CALL!>.<!>length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kt11085(prop: String?) {
|
||||||
|
when (prop?.hashCode()) {
|
||||||
|
1 -> <!DEBUG_INFO_SMARTCAST!>prop<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HttpExchange(val code: String)
|
||||||
|
|
||||||
|
fun kt11313(arg: HttpExchange?) {
|
||||||
|
when (arg?.code) {
|
||||||
|
"GET" -> handleGet(<!DEBUG_INFO_SMARTCAST!>arg<!>)
|
||||||
|
"POST" -> handlePost(<!DEBUG_INFO_SMARTCAST!>arg<!>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleGet(arg: HttpExchange) = arg
|
||||||
|
|
||||||
|
fun handlePost(arg: HttpExchange) = arg
|
||||||
|
|
||||||
|
class Wrapper {
|
||||||
|
fun unwrap(): String? = "Something not consistent"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun falsePositive(w: Wrapper) {
|
||||||
|
if (w.unwrap() != null) {
|
||||||
|
// Here we should NOT have smart cast
|
||||||
|
<!SMARTCAST_IMPOSSIBLE!>w.unwrap()<!>.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun falsePositive(/*0*/ w: Wrapper): kotlin.Unit
|
||||||
|
public fun getA(): A?
|
||||||
|
public fun handleGet(/*0*/ arg: HttpExchange): HttpExchange
|
||||||
|
public fun handlePost(/*0*/ arg: HttpExchange): HttpExchange
|
||||||
|
public fun kt11085(/*0*/ prop: kotlin.String?): kotlin.Unit
|
||||||
|
public fun kt11313(/*0*/ arg: HttpExchange?): kotlin.Unit
|
||||||
|
public fun kt1635(/*0*/ s: kotlin.String?): kotlin.Unit
|
||||||
|
public fun kt2127(): kotlin.Unit
|
||||||
|
public fun kt3356(/*0*/ s: kotlin.String?): kotlin.Int
|
||||||
|
public fun kt4565_1(/*0*/ a: SomeClass?): kotlin.Unit
|
||||||
|
public fun kt4565_2(/*0*/ a: SomeClass?): kotlin.Unit
|
||||||
|
public fun kt6840_1(/*0*/ s: kotlin.String?): kotlin.Unit
|
||||||
|
public fun kt6840_2(/*0*/ s: kotlin.String?): kotlin.Unit
|
||||||
|
public fun kt7491_1(): kotlin.Unit
|
||||||
|
public fun kt7491_2(): kotlin.Unit
|
||||||
|
public fun kt8492(/*0*/ s: kotlin.String?): kotlin.Unit
|
||||||
|
public fun useA(/*0*/ a: A): kotlin.Int
|
||||||
|
public fun kotlin.String.correct(): kotlin.Boolean
|
||||||
|
|
||||||
|
public final class A {
|
||||||
|
public constructor A(/*0*/ y: kotlin.Int)
|
||||||
|
public final val y: kotlin.Int
|
||||||
|
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 HttpExchange {
|
||||||
|
public constructor HttpExchange(/*0*/ code: kotlin.String)
|
||||||
|
public final val code: kotlin.String
|
||||||
|
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 open class SomeClass {
|
||||||
|
public constructor SomeClass(/*0*/ data: kotlin.Any)
|
||||||
|
public final val data: kotlin.Any
|
||||||
|
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 SubClass : SomeClass {
|
||||||
|
public constructor SubClass(/*0*/ extra: kotlin.Any, /*1*/ data: kotlin.Any)
|
||||||
|
public final override /*1*/ /*fake_override*/ val data: kotlin.Any
|
||||||
|
public final val extra: kotlin.Any
|
||||||
|
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 Wrapper {
|
||||||
|
public constructor Wrapper()
|
||||||
|
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 fun unwrap(): kotlin.String?
|
||||||
|
}
|
||||||
@@ -18356,6 +18356,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeAccessReceiverNotNull.kt")
|
||||||
|
public void testSafeAccessReceiverNotNull() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/safecalls/safeAccessReceiverNotNull.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simple.kt")
|
@TestMetadata("simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/safecalls/simple.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/safecalls/simple.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user