KT-12152 : constructor consistency analysis, base cases
This commit is contained in:
@@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* 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.cfg
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstruction
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicInstruction
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.ReadValueInstruction
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder
|
||||||
|
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.traverse
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
|
||||||
|
sealed class LeakingThisDescriptor(val classOrObject: KtClassOrObject) {
|
||||||
|
class PropertyIsNull(val property: PropertyDescriptor, classOrObject: KtClassOrObject) : LeakingThisDescriptor(classOrObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConstructorConsistencyChecker private constructor(
|
||||||
|
private val classOrObject: KtClassOrObject,
|
||||||
|
private val classDescriptor: ClassDescriptor,
|
||||||
|
private val trace: BindingTrace,
|
||||||
|
private val pseudocode: Pseudocode,
|
||||||
|
private val variablesData: PseudocodeVariablesData
|
||||||
|
) {
|
||||||
|
|
||||||
|
private fun safeThisUsage(expression: KtThisExpression): Boolean {
|
||||||
|
val referenceDescriptor = trace.get(BindingContext.REFERENCE_TARGET, expression.instanceReference)
|
||||||
|
if (referenceDescriptor != classDescriptor) return true
|
||||||
|
val parent = expression.parent
|
||||||
|
return when (parent) {
|
||||||
|
is KtQualifiedExpression -> parent.selectorExpression is KtSimpleNameExpression
|
||||||
|
is KtBinaryExpression -> OperatorConventions.IDENTITY_EQUALS_OPERATIONS.contains(parent.operationToken)
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun safeCallUsage(expression: KtCallExpression): Boolean {
|
||||||
|
val callee = expression.calleeExpression
|
||||||
|
if (callee is KtReferenceExpression) {
|
||||||
|
val descriptor = trace.get(BindingContext.REFERENCE_TARGET, callee)
|
||||||
|
if (descriptor is FunctionDescriptor) {
|
||||||
|
val containingDescriptor = descriptor.containingDeclaration
|
||||||
|
if (containingDescriptor != classDescriptor) return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun check() {
|
||||||
|
// List of properties to initialize
|
||||||
|
val propertyDescriptors = variablesData.getDeclaredVariables(pseudocode, false)
|
||||||
|
.filterIsInstance<PropertyDescriptor>()
|
||||||
|
.filter { trace.get(BindingContext.BACKING_FIELD_REQUIRED, it) == true }
|
||||||
|
pseudocode.traverse(
|
||||||
|
TraversalOrder.FORWARD, variablesData.variableInitializers, { instruction, enterData, exitData ->
|
||||||
|
|
||||||
|
fun firstUninitializedNotNullProperty() = propertyDescriptors.firstOrNull {
|
||||||
|
!it.type.isMarkedNullable && !KotlinBuiltIns.isPrimitiveType(it.type) &&
|
||||||
|
!it.isLateInit && !(enterData[it]?.definitelyInitialized() ?: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleLeakingThis(expression: KtExpression) {
|
||||||
|
val uninitializedProperty = firstUninitializedNotNullProperty()
|
||||||
|
if (uninitializedProperty != null) {
|
||||||
|
trace.record(BindingContext.LEAKING_THIS, target(expression),
|
||||||
|
LeakingThisDescriptor.PropertyIsNull(uninitializedProperty, classOrObject))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instruction.owner != pseudocode) {
|
||||||
|
return@traverse
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instruction is KtElementInstruction) {
|
||||||
|
val element = instruction.element
|
||||||
|
when (instruction) {
|
||||||
|
is ReadValueInstruction ->
|
||||||
|
if (element is KtThisExpression) {
|
||||||
|
if (!safeThisUsage(element)) {
|
||||||
|
handleLeakingThis(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is MagicInstruction ->
|
||||||
|
if (instruction.kind == MagicKind.IMPLICIT_RECEIVER && element is KtCallExpression) {
|
||||||
|
if (!safeCallUsage(element)) {
|
||||||
|
handleLeakingThis(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun check(
|
||||||
|
constructor: KtSecondaryConstructor,
|
||||||
|
trace: BindingTrace,
|
||||||
|
pseudocode: Pseudocode,
|
||||||
|
pseudocodeVariablesData: PseudocodeVariablesData
|
||||||
|
) = check(constructor.getContainingClassOrObject(), trace, pseudocode, pseudocodeVariablesData)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun check(
|
||||||
|
classOrObject: KtClassOrObject,
|
||||||
|
trace: BindingTrace,
|
||||||
|
pseudocode: Pseudocode,
|
||||||
|
pseudocodeVariablesData: PseudocodeVariablesData
|
||||||
|
) {
|
||||||
|
val classDescriptor = trace.get(BindingContext.CLASS, classOrObject) ?: return
|
||||||
|
ConstructorConsistencyChecker(classOrObject, classDescriptor, trace, pseudocode, pseudocodeVariablesData).check()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun target(expression: KtExpression): KtExpression = when (expression) {
|
||||||
|
is KtThisExpression -> {
|
||||||
|
val selectorOrThis = (expression.parent as? KtQualifiedExpression)?.let {
|
||||||
|
if (it.receiverExpression === expression) it.selectorExpression else null
|
||||||
|
} ?: expression
|
||||||
|
if (selectorOrThis === expression) selectorOrThis else target(selectorOrThis)
|
||||||
|
}
|
||||||
|
is KtCallExpression -> expression.let { it.calleeExpression ?: it }
|
||||||
|
else -> expression
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -125,6 +125,8 @@ public class ControlFlowInformationProvider {
|
|||||||
checkIfExpressions();
|
checkIfExpressions();
|
||||||
|
|
||||||
checkWhenExpressions();
|
checkWhenExpressions();
|
||||||
|
|
||||||
|
checkConstructorConsistency();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkFunction(@Nullable KotlinType expectedReturnType) {
|
public void checkFunction(@Nullable KotlinType expectedReturnType) {
|
||||||
@@ -923,6 +925,15 @@ public class ControlFlowInformationProvider {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkConstructorConsistency() {
|
||||||
|
if (subroutine instanceof KtClassOrObject) {
|
||||||
|
ConstructorConsistencyChecker.check((KtClassOrObject) subroutine, trace, pseudocode, pseudocodeVariablesData);
|
||||||
|
}
|
||||||
|
else if (subroutine instanceof KtSecondaryConstructor) {
|
||||||
|
ConstructorConsistencyChecker.check((KtSecondaryConstructor) subroutine, trace, pseudocode, pseudocodeVariablesData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Tail calls
|
// Tail calls
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,11 @@ public class CheckerTestUtil {
|
|||||||
debugAnnotations.add(new DebugInfoDiagnostic(expression, DebugInfoDiagnosticFactory.CONSTANT));
|
debugAnnotations.add(new DebugInfoDiagnostic(expression, DebugInfoDiagnosticFactory.CONSTANT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (KtExpression expression : bindingContext.getSliceContents(BindingContext.LEAKING_THIS).keySet()) {
|
||||||
|
if (PsiTreeUtil.isAncestor(root, expression, false)) {
|
||||||
|
debugAnnotations.add(new DebugInfoDiagnostic(expression, DebugInfoDiagnosticFactory.LEAKING_THIS));
|
||||||
|
}
|
||||||
|
}
|
||||||
for (KtWhenExpression expression : bindingContext.getSliceContents(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN).keySet()) {
|
for (KtWhenExpression expression : bindingContext.getSliceContents(BindingContext.IMPLICIT_EXHAUSTIVE_WHEN).keySet()) {
|
||||||
if (PsiTreeUtil.isAncestor(root, expression, false)) {
|
if (PsiTreeUtil.isAncestor(root, expression, false)) {
|
||||||
debugAnnotations.add(new DebugInfoDiagnostic(expression, DebugInfoDiagnosticFactory.IMPLICIT_EXHAUSTIVE));
|
debugAnnotations.add(new DebugInfoDiagnostic(expression, DebugInfoDiagnosticFactory.IMPLICIT_EXHAUSTIVE));
|
||||||
@@ -533,6 +538,7 @@ public class CheckerTestUtil {
|
|||||||
public static final DebugInfoDiagnosticFactory SMARTCAST = new DebugInfoDiagnosticFactory("SMARTCAST");
|
public static final DebugInfoDiagnosticFactory SMARTCAST = new DebugInfoDiagnosticFactory("SMARTCAST");
|
||||||
public static final DebugInfoDiagnosticFactory IMPLICIT_RECEIVER_SMARTCAST = new DebugInfoDiagnosticFactory("IMPLICIT_RECEIVER_SMARTCAST");
|
public static final DebugInfoDiagnosticFactory IMPLICIT_RECEIVER_SMARTCAST = new DebugInfoDiagnosticFactory("IMPLICIT_RECEIVER_SMARTCAST");
|
||||||
public static final DebugInfoDiagnosticFactory CONSTANT = new DebugInfoDiagnosticFactory("CONSTANT");
|
public static final DebugInfoDiagnosticFactory CONSTANT = new DebugInfoDiagnosticFactory("CONSTANT");
|
||||||
|
public static final DebugInfoDiagnosticFactory LEAKING_THIS = new DebugInfoDiagnosticFactory("LEAKING_THIS");
|
||||||
public static final DebugInfoDiagnosticFactory IMPLICIT_EXHAUSTIVE = new DebugInfoDiagnosticFactory("IMPLICIT_EXHAUSTIVE");
|
public static final DebugInfoDiagnosticFactory IMPLICIT_EXHAUSTIVE = new DebugInfoDiagnosticFactory("IMPLICIT_EXHAUSTIVE");
|
||||||
public static final DebugInfoDiagnosticFactory ELEMENT_WITH_ERROR_TYPE = new DebugInfoDiagnosticFactory("ELEMENT_WITH_ERROR_TYPE");
|
public static final DebugInfoDiagnosticFactory ELEMENT_WITH_ERROR_TYPE = new DebugInfoDiagnosticFactory("ELEMENT_WITH_ERROR_TYPE");
|
||||||
public static final DebugInfoDiagnosticFactory UNRESOLVED_WITH_TARGET = new DebugInfoDiagnosticFactory("UNRESOLVED_WITH_TARGET");
|
public static final DebugInfoDiagnosticFactory UNRESOLVED_WITH_TARGET = new DebugInfoDiagnosticFactory("UNRESOLVED_WITH_TARGET");
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.annotations.ReadOnly;
|
import org.jetbrains.annotations.ReadOnly;
|
||||||
import org.jetbrains.annotations.TestOnly;
|
import org.jetbrains.annotations.TestOnly;
|
||||||
|
import org.jetbrains.kotlin.cfg.LeakingThisDescriptor;
|
||||||
import org.jetbrains.kotlin.cfg.TailRecursionKind;
|
import org.jetbrains.kotlin.cfg.TailRecursionKind;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||||
@@ -97,6 +98,7 @@ public interface BindingContext {
|
|||||||
WritableSlice<KtExpression, KotlinType> EXPECTED_EXPRESSION_TYPE = new BasicWritableSlice<KtExpression, KotlinType>(DO_NOTHING);
|
WritableSlice<KtExpression, KotlinType> EXPECTED_EXPRESSION_TYPE = new BasicWritableSlice<KtExpression, KotlinType>(DO_NOTHING);
|
||||||
WritableSlice<KtFunction, KotlinType> EXPECTED_RETURN_TYPE = new BasicWritableSlice<KtFunction, KotlinType>(DO_NOTHING);
|
WritableSlice<KtFunction, KotlinType> EXPECTED_RETURN_TYPE = new BasicWritableSlice<KtFunction, KotlinType>(DO_NOTHING);
|
||||||
WritableSlice<KtExpression, DataFlowInfo> DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice();
|
WritableSlice<KtExpression, DataFlowInfo> DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice();
|
||||||
|
WritableSlice<KtExpression, LeakingThisDescriptor> LEAKING_THIS = Slices.createSimpleSlice();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A qualifier corresponds to a receiver expression (if any). For 'A.B' qualifier is recorded for 'A'.
|
* A qualifier corresponds to a receiver expression (if any). For 'A.B' qualifier is recorded for 'A'.
|
||||||
|
|||||||
+10
-10
@@ -1,6 +1,6 @@
|
|||||||
class Test(foo: Any?, bar: Any?) {
|
class Test(foo: Any?, bar: Any?) {
|
||||||
val foo = foo ?: this
|
val foo = foo ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bar = bar ?: this
|
private val bar = bar ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bas = bas()
|
private val bas = bas()
|
||||||
val bas2 = bas2()
|
val bas2 = bas2()
|
||||||
|
|
||||||
@@ -15,8 +15,8 @@ class Test(foo: Any?, bar: Any?) {
|
|||||||
|
|
||||||
// KT-6413 Typechecker recursive problem when class have non-invariant generic parameters
|
// KT-6413 Typechecker recursive problem when class have non-invariant generic parameters
|
||||||
class Test2<A, B, C>(foo: Any?, bar: Any?) {
|
class Test2<A, B, C>(foo: Any?, bar: Any?) {
|
||||||
val foo = foo ?: this
|
val foo = foo ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bar = bar ?: this
|
private val bar = bar ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bas = bas()
|
private val bas = bas()
|
||||||
val bas2 = bas2()
|
val bas2 = bas2()
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ class Test2<A, B, C>(foo: Any?, bar: Any?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Test3<in A, B, C>(foo: Any?, bar: Any?) {
|
class Test3<in A, B, C>(foo: Any?, bar: Any?) {
|
||||||
val foo = foo ?: this
|
val foo = foo ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bar = bar ?: this
|
private val bar = bar ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bas = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!DEBUG_INFO_MISSING_UNRESOLVED!>bas<!>()<!>
|
private val bas = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!DEBUG_INFO_MISSING_UNRESOLVED!>bas<!>()<!>
|
||||||
val bas2 = bas2()
|
val bas2 = bas2()
|
||||||
|
|
||||||
@@ -45,8 +45,8 @@ class Test3<in A, B, C>(foo: Any?, bar: Any?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Test4<A, out B, C>(foo: Any?, bar: Any?) {
|
class Test4<A, out B, C>(foo: Any?, bar: Any?) {
|
||||||
val foo = foo ?: this
|
val foo = foo ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bar = bar ?: this
|
private val bar = bar ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bas = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!DEBUG_INFO_MISSING_UNRESOLVED!>bas<!>()<!>
|
private val bas = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!><!DEBUG_INFO_MISSING_UNRESOLVED!>bas<!>()<!>
|
||||||
val bas2 = bas2()
|
val bas2 = bas2()
|
||||||
|
|
||||||
@@ -60,8 +60,8 @@ class Test4<A, out B, C>(foo: Any?, bar: Any?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Test5<A, out B, C>(foo: Any?, bar: Any?) {
|
class Test5<A, out B, C>(foo: Any?, bar: Any?) {
|
||||||
val foo = foo ?: this
|
val foo = foo ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bar = bar ?: this
|
private val bar = bar ?: <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
private val bas: Int = bas()
|
private val bas: Int = bas()
|
||||||
val bas2 = bas2()
|
val bas2 = bas2()
|
||||||
|
|
||||||
|
|||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
class My(val x: Int) {
|
||||||
|
val y: Int = x + 3
|
||||||
|
val z: Int? = foo()
|
||||||
|
|
||||||
|
fun foo() = if (x >= 0) x else if (y >= 0) y else null
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My(/*0*/ x: kotlin.Int)
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public final val y: kotlin.Int
|
||||||
|
public final val z: kotlin.Int?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
fun foo() = 42
|
||||||
|
|
||||||
|
class Your {
|
||||||
|
fun bar() = 13
|
||||||
|
}
|
||||||
|
|
||||||
|
class My {
|
||||||
|
val your = Your()
|
||||||
|
|
||||||
|
val x = foo()
|
||||||
|
|
||||||
|
val y = Your().bar()
|
||||||
|
|
||||||
|
val z = your.bar()
|
||||||
|
|
||||||
|
// This extension function also can use our properties,
|
||||||
|
// so the call is also dangerous
|
||||||
|
val w = your.<!DEBUG_INFO_LEAKING_THIS!>gav<!>()
|
||||||
|
|
||||||
|
val v = Your().<!DEBUG_INFO_LEAKING_THIS!>gav<!>()
|
||||||
|
|
||||||
|
val t = your.other()
|
||||||
|
|
||||||
|
val r = Your().other()
|
||||||
|
|
||||||
|
fun Your.gav() = if (your.bar() == 0) t else r
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Your.other() = "3"
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun foo(): kotlin.Int
|
||||||
|
public fun Your.other(): kotlin.String
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val r: kotlin.String
|
||||||
|
public final val t: kotlin.String
|
||||||
|
public final val v: kotlin.String
|
||||||
|
public final val w: kotlin.String
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public final val y: kotlin.Int
|
||||||
|
public final val your: Your
|
||||||
|
public final val z: 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 fun Your.gav(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Your {
|
||||||
|
public constructor Your()
|
||||||
|
public final fun bar(): 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
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class My {
|
||||||
|
val x: String
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
val temp = <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
|
x = bar(temp)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(arg: My) = arg.x
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ arg: My): kotlin.String
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val x: 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
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class My {
|
||||||
|
val x: String
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
val y = bar(<!DEBUG_INFO_LEAKING_THIS!>this<!>)
|
||||||
|
val z = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
|
||||||
|
x = "$y$z"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() = x
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(arg: My) = arg.x
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ arg: My): kotlin.String
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val x: kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class My {
|
||||||
|
|
||||||
|
val x = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
|
||||||
|
|
||||||
|
val w = bar()
|
||||||
|
|
||||||
|
fun foo() = 0
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val y = <!UNRESOLVED_REFERENCE!>foo<!>()
|
||||||
|
|
||||||
|
val u = <!DEBUG_INFO_LEAKING_THIS!>bar<!>()
|
||||||
|
|
||||||
|
val z: String? = bar()
|
||||||
|
|
||||||
|
fun bar() = "1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val w: kotlin.String
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val u: kotlin.String
|
||||||
|
public final val y: [ERROR : Type for foo()]
|
||||||
|
public final val z: kotlin.String?
|
||||||
|
public final fun bar(): 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
val instance = My()
|
||||||
|
|
||||||
|
class My {
|
||||||
|
val equalsInstance = (<!DEBUG_INFO_LEAKING_THIS!>this<!> == instance)
|
||||||
|
|
||||||
|
val isInstance = if (this === instance) "true" else "false"
|
||||||
|
|
||||||
|
override fun equals(other: Any?) =
|
||||||
|
other is My && isInstance.hashCode() == <!DEBUG_INFO_SMARTCAST!>other<!>.isInstance.hashCode()
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val instance: My
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val equalsInstance: kotlin.Boolean
|
||||||
|
public final val isInstance: kotlin.String
|
||||||
|
public open override /*1*/ 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
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
class Delegate(val x: Int) {
|
||||||
|
operator fun getValue(t: Any?, p: KProperty<*>): Int = x
|
||||||
|
}
|
||||||
|
|
||||||
|
class My {
|
||||||
|
val x: Int by Delegate(this.foo())
|
||||||
|
|
||||||
|
fun foo(): Int = x
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class Delegate {
|
||||||
|
public constructor Delegate(/*0*/ x: kotlin.Int)
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final operator fun getValue(/*0*/ t: kotlin.Any?, /*1*/ p: kotlin.reflect.KProperty<*>): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
open class Base(val x: String) {
|
||||||
|
fun foo() = bar()
|
||||||
|
|
||||||
|
open fun bar() = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived(x: String): Base(x) {
|
||||||
|
// It's still dangerous: we're not sure that foo() does not call some open function inside
|
||||||
|
val y = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
|
||||||
|
val z = x
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public open class Base {
|
||||||
|
public constructor Base(/*0*/ x: kotlin.String)
|
||||||
|
public final val x: kotlin.String
|
||||||
|
public open fun bar(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Derived : Base {
|
||||||
|
public constructor Derived(/*0*/ x: kotlin.String)
|
||||||
|
public final override /*1*/ /*fake_override*/ val x: kotlin.String
|
||||||
|
public final val y: kotlin.Int
|
||||||
|
public final val z: kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun bar(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final override /*1*/ /*fake_override*/ fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class My {
|
||||||
|
val x: String
|
||||||
|
|
||||||
|
init {
|
||||||
|
x = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(): String = x
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val x: kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
interface Wise {
|
||||||
|
fun doIt(): Int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Wise(f: () -> Int) = object: Wise {
|
||||||
|
override fun doIt() = f()
|
||||||
|
}
|
||||||
|
|
||||||
|
class My {
|
||||||
|
// Still dangerous (???), nobogy can guarantee what Wise() will do with this lambda
|
||||||
|
val x = Wise { foo() }
|
||||||
|
|
||||||
|
val y = 42
|
||||||
|
|
||||||
|
fun foo() = y
|
||||||
|
|
||||||
|
fun bar() = x.doIt()
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun Wise(/*0*/ f: () -> kotlin.Int): Wise
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val x: Wise
|
||||||
|
public final val y: kotlin.Int = 42
|
||||||
|
public final fun bar(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Wise {
|
||||||
|
public abstract fun doIt(): 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
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class WithLateInit {
|
||||||
|
lateinit var x: String
|
||||||
|
|
||||||
|
fun init(xx: String) {
|
||||||
|
x = xx
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
// This is obviously a bug,
|
||||||
|
// but with lateinit we explicitly want it to occur in runtime
|
||||||
|
use()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun use() = x
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class WithLateInit {
|
||||||
|
public constructor WithLateInit()
|
||||||
|
public final lateinit var x: 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 final fun init(/*0*/ xx: kotlin.String): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public final fun use(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
open class Wise {
|
||||||
|
|
||||||
|
val x = 1
|
||||||
|
|
||||||
|
open fun doIt(): Int = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
class My {
|
||||||
|
|
||||||
|
fun foo(): Int {
|
||||||
|
val wise = object: Wise() {
|
||||||
|
var xx = 1
|
||||||
|
override fun doIt() = super.doIt() + bar(this) + xx
|
||||||
|
}
|
||||||
|
return wise.doIt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(wise: Wise): Int = wise.x
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ wise: Wise): kotlin.Int
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class Wise {
|
||||||
|
public constructor Wise()
|
||||||
|
public final val x: kotlin.Int = 1
|
||||||
|
public open fun doIt(): 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
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class My {
|
||||||
|
|
||||||
|
val x: Int
|
||||||
|
get() = 1
|
||||||
|
|
||||||
|
init {
|
||||||
|
// x has no backing field, so the call is safe
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My()
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class Outer {
|
||||||
|
|
||||||
|
fun foo() = 1
|
||||||
|
|
||||||
|
inner class Inner {
|
||||||
|
|
||||||
|
val x = this@Outer.foo()
|
||||||
|
|
||||||
|
val y = foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class Outer {
|
||||||
|
public constructor Outer()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final inner class Inner {
|
||||||
|
public constructor Inner()
|
||||||
|
public final val x: 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class My(x: String) {
|
||||||
|
val y: String = <!DEBUG_INFO_LEAKING_THIS!>foo<!>(x)
|
||||||
|
|
||||||
|
fun foo(x: String) = "$x$y"
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My(/*0*/ x: kotlin.String)
|
||||||
|
public final val y: kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun foo(/*0*/ x: kotlin.String): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class My {
|
||||||
|
val x: Int
|
||||||
|
|
||||||
|
constructor(x: Int) {
|
||||||
|
this.x = x
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class My {
|
||||||
|
public constructor My(/*0*/ x: kotlin.Int)
|
||||||
|
public final val x: 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
|
||||||
|
}
|
||||||
+2
-2
@@ -2,12 +2,12 @@ class B {
|
|||||||
companion object <!REDECLARATION!>A<!> {
|
companion object <!REDECLARATION!>A<!> {
|
||||||
}
|
}
|
||||||
|
|
||||||
val <!REDECLARATION!>A<!> = this
|
val <!REDECLARATION!>A<!> = <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
class C {
|
class C {
|
||||||
companion <!CONFLICTING_JVM_DECLARATIONS!>object A<!> {
|
companion <!CONFLICTING_JVM_DECLARATIONS!>object A<!> {
|
||||||
<!CONFLICTING_JVM_DECLARATIONS!>val A<!> = this
|
<!CONFLICTING_JVM_DECLARATIONS!>val A<!> = <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -10,8 +10,8 @@ class Q {
|
|||||||
C()
|
C()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var x = foo<CharSequence>()()
|
private var x = <!DEBUG_INFO_LEAKING_THIS!>foo<!><CharSequence>()()
|
||||||
private var y = foo<String>()()
|
private var y = <!DEBUG_INFO_LEAKING_THIS!>foo<!><String>()()
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
x = <!TYPE_MISMATCH!>y<!>
|
x = <!TYPE_MISMATCH!>y<!>
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ class Q {
|
|||||||
C<F>()
|
C<F>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var x = foo<CharSequence, Number>()()
|
private var x = <!DEBUG_INFO_LEAKING_THIS!>foo<!><CharSequence, Number>()()
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
x.e.checkType { _<CharSequence>() }
|
x.e.checkType { _<CharSequence>() }
|
||||||
|
|||||||
+2
-2
@@ -8,8 +8,8 @@ class Q {
|
|||||||
val prop: E = magic()
|
val prop: E = magic()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var x = foo<CharSequence>()
|
private var x = <!DEBUG_INFO_LEAKING_THIS!>foo<!><CharSequence>()
|
||||||
private var y = foo<String>()
|
private var y = <!DEBUG_INFO_LEAKING_THIS!>foo<!><String>()
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
x = <!TYPE_MISMATCH!>y<!>
|
x = <!TYPE_MISMATCH!>y<!>
|
||||||
|
|||||||
+1
-1
@@ -6,6 +6,6 @@ enum class E {
|
|||||||
companion object {
|
companion object {
|
||||||
class FIRST
|
class FIRST
|
||||||
|
|
||||||
val SECOND = this
|
val SECOND = <!DEBUG_INFO_LEAKING_THIS!>this<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,5 +10,5 @@ class C() {
|
|||||||
return x(x(y))
|
return x(x(y))
|
||||||
}
|
}
|
||||||
|
|
||||||
val x: B = a({it.b()}, B())
|
val x: B = <!DEBUG_INFO_LEAKING_THIS!>a<!>({it.b()}, B())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ class A() {
|
|||||||
<!UNUSED_EXPRESSION!>this<!>
|
<!UNUSED_EXPRESSION!>this<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val x = this@A.foo()
|
val x = this@A.<!DEBUG_INFO_LEAKING_THIS!>foo<!>()
|
||||||
val y = this.foo()
|
val y = this.<!DEBUG_INFO_LEAKING_THIS!>foo<!>()
|
||||||
val z = foo()
|
val z = <!DEBUG_INFO_LEAKING_THIS!>foo<!>()
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
class A(val a:Int) {
|
class A(val a:Int) {
|
||||||
|
|
||||||
inner class B() {
|
inner class B() {
|
||||||
val x = checkSubtype<B>(this@B)
|
val x = checkSubtype<B>(<!DEBUG_INFO_LEAKING_THIS!>this@B<!>)
|
||||||
val y = checkSubtype<A>(this@A)
|
val y = checkSubtype<A>(this@A)
|
||||||
val z = checkSubtype<B>(this)
|
val z = checkSubtype<B>(<!DEBUG_INFO_LEAKING_THIS!>this<!>)
|
||||||
val Int.xx : Int get() = checkSubtype<Int>(this)
|
val Int.xx : Int get() = checkSubtype<Int>(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2887,6 +2887,111 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/constructorConsistency")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ConstructorConsistency extends AbstractDiagnosticsTest {
|
||||||
|
@TestMetadata("afterInitialization.kt")
|
||||||
|
public void testAfterInitialization() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/afterInitialization.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("aliencall.kt")
|
||||||
|
public void testAliencall() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/aliencall.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInConstructorConsistency() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/constructorConsistency"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("assignment.kt")
|
||||||
|
public void testAssignment() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/assignment.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("basic.kt")
|
||||||
|
public void testBasic() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/basic.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("companion.kt")
|
||||||
|
public void testCompanion() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/companion.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("comparison.kt")
|
||||||
|
public void testComparison() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/comparison.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("delegate.kt")
|
||||||
|
public void testDelegate() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/delegate.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("derived.kt")
|
||||||
|
public void testDerived() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/derived.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("init.kt")
|
||||||
|
public void testInit() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/init.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaInObject.kt")
|
||||||
|
public void testLambdaInObject() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/lambdaInObject.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lateInit.kt")
|
||||||
|
public void testLateInit() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/lateInit.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localObject.kt")
|
||||||
|
public void testLocalObject() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/localObject.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nobacking.kt")
|
||||||
|
public void testNobacking() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/nobacking.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("outer.kt")
|
||||||
|
public void testOuter() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/outer.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("property.kt")
|
||||||
|
public void testProperty() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/property.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyAccess.kt")
|
||||||
|
public void testPropertyAccess() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/constructorConsistency/propertyAccess.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis")
|
@TestMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user