Report of UNINITIALIZED_ENUM_COMPANION also for implicit receivers #KT-11769 Fixed
This commit is contained in:
@@ -39,10 +39,7 @@ import org.jetbrains.kotlin.lexer.KtTokens.*
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
|
||||||
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -1481,6 +1478,16 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
|||||||
|
|
||||||
when (receiver) {
|
when (receiver) {
|
||||||
is ImplicitReceiver -> {
|
is ImplicitReceiver -> {
|
||||||
|
if (callElement is KtCallExpression) {
|
||||||
|
val declaration = receiver.declarationDescriptor
|
||||||
|
if (declaration is ClassDescriptor) {
|
||||||
|
val fakeDescriptor = getFakeDescriptorForObject(declaration)
|
||||||
|
val calleeExpression = callElement.calleeExpression
|
||||||
|
if (fakeDescriptor != null && calleeExpression != null) {
|
||||||
|
builder.read(calleeExpression, AccessTarget.Declaration(fakeDescriptor), emptyMap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
receiverValues = receiverValues.plus(createSyntheticValue(callElement, MagicKind.IMPLICIT_RECEIVER), receiver)
|
receiverValues = receiverValues.plus(createSyntheticValue(callElement, MagicKind.IMPLICIT_RECEIVER), receiver)
|
||||||
}
|
}
|
||||||
is ExpressionReceiver -> {
|
is ExpressionReceiver -> {
|
||||||
|
|||||||
@@ -91,7 +91,12 @@ public class PseudocodeUtil {
|
|||||||
public static VariableDescriptor extractVariableDescriptorIfAny(@NotNull Instruction instruction, boolean onlyReference, @NotNull BindingContext bindingContext) {
|
public static VariableDescriptor extractVariableDescriptorIfAny(@NotNull Instruction instruction, boolean onlyReference, @NotNull BindingContext bindingContext) {
|
||||||
KtElement element = null;
|
KtElement element = null;
|
||||||
if (instruction instanceof ReadValueInstruction) {
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
element = ((ReadValueInstruction) instruction).getElement();
|
ReadValueInstruction readValueInstruction = (ReadValueInstruction) instruction;
|
||||||
|
AccessTarget target = readValueInstruction.getTarget();
|
||||||
|
if (target instanceof AccessTarget.Declaration) {
|
||||||
|
return ((AccessTarget.Declaration) target).getDescriptor();
|
||||||
|
}
|
||||||
|
element = readValueInstruction.getElement();
|
||||||
}
|
}
|
||||||
else if (instruction instanceof WriteValueInstruction) {
|
else if (instruction instanceof WriteValueInstruction) {
|
||||||
element = ((WriteValueInstruction) instruction).getLValue();
|
element = ((WriteValueInstruction) instruction).getLValue();
|
||||||
|
|||||||
+9
-8
@@ -26,18 +26,19 @@ L0:
|
|||||||
v(ANOTHER(foo());)
|
v(ANOTHER(foo());)
|
||||||
magic[FAKE_INITIALIZER](ANOTHER(foo());) -> <v5>
|
magic[FAKE_INITIALIZER](ANOTHER(foo());) -> <v5>
|
||||||
w(ANOTHER|<v5>)
|
w(ANOTHER|<v5>)
|
||||||
magic[IMPLICIT_RECEIVER](foo()) -> <v6>
|
r(foo, Companion) -> <v6>
|
||||||
|
magic[IMPLICIT_RECEIVER](foo()) -> <v7>
|
||||||
mark(foo())
|
mark(foo())
|
||||||
call(foo(), foo|<v6>) -> <v7>
|
call(foo(), foo|<v7>) -> <v8>
|
||||||
mark((foo()))
|
mark((foo()))
|
||||||
call((foo()), <init>|<v7>) -> <v8>
|
call((foo()), <init>|<v8>) -> <v9>
|
||||||
v(companion object { fun foo() = 42 })
|
v(companion object { fun foo() = 42 })
|
||||||
magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v9>
|
magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v10>
|
||||||
w(Companion|<v9>)
|
w(Companion|<v10>)
|
||||||
L1:
|
L1:
|
||||||
<END> NEXT:[<SINK>]
|
<END> NEXT:[<SINK>]
|
||||||
error:
|
error:
|
||||||
<ERROR> PREV:[]
|
<ERROR> PREV:[]
|
||||||
sink:
|
sink:
|
||||||
<SINK> PREV:[<ERROR>, <END>]
|
<SINK> PREV:[<ERROR>, <END>]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
+12
-11
@@ -8,15 +8,16 @@ enum class EE(val x: Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
---------------------
|
---------------------
|
||||||
<v0>: Int NEW: magic[FAKE_INITIALIZER](val x: Int) -> <v0>
|
<v0>: Int NEW: magic[FAKE_INITIALIZER](val x: Int) -> <v0>
|
||||||
<v1>: EE NEW: magic[FAKE_INITIALIZER](INSTANCE(Companion.foo()),) -> <v1>
|
<v10>: EE.Companion NEW: magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v10>
|
||||||
<v5>: EE NEW: magic[FAKE_INITIALIZER](ANOTHER(foo());) -> <v5>
|
<v1>: EE NEW: magic[FAKE_INITIALIZER](INSTANCE(Companion.foo()),) -> <v1>
|
||||||
<v6>: EE.Companion NEW: magic[IMPLICIT_RECEIVER](foo()) -> <v6>
|
<v5>: EE NEW: magic[FAKE_INITIALIZER](ANOTHER(foo());) -> <v5>
|
||||||
<v9>: EE.Companion NEW: magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v9>
|
<v7>: EE.Companion NEW: magic[IMPLICIT_RECEIVER](foo()) -> <v7>
|
||||||
Companion <v2>: EE.Companion NEW: r(Companion) -> <v2>
|
Companion <v2>: EE.Companion NEW: r(Companion) -> <v2>
|
||||||
foo() <v3>: Int NEW: call(foo(), foo|<v2>) -> <v3>
|
foo() <v3>: Int NEW: call(foo(), foo|<v2>) -> <v3>
|
||||||
Companion.foo() <v3>: Int COPY
|
Companion.foo() <v3>: Int COPY
|
||||||
(Companion.foo()) <v4>: * NEW: call((Companion.foo()), <init>|<v3>) -> <v4>
|
(Companion.foo()) <v4>: * NEW: call((Companion.foo()), <init>|<v3>) -> <v4>
|
||||||
foo() <v7>: Int NEW: call(foo(), foo|<v6>) -> <v7>
|
foo <v6>: * NEW: r(foo, Companion) -> <v6>
|
||||||
(foo()) <v8>: * NEW: call((foo()), <init>|<v7>) -> <v8>
|
foo() <v8>: Int NEW: call(foo(), foo|<v7>) -> <v8>
|
||||||
|
(foo()) <v9>: * NEW: call((foo()), <init>|<v8>) -> <v9>
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ enum class EnumCompanion1(val x: Int) {
|
|||||||
}
|
}
|
||||||
// Also should be reported for implicit receiver
|
// Also should be reported for implicit receiver
|
||||||
enum class EnumCompanion2(val x: Int) {
|
enum class EnumCompanion2(val x: Int) {
|
||||||
INSTANCE(foo()); // TODO
|
INSTANCE(<!UNINITIALIZED_ENUM_COMPANION!>foo<!>());
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun foo() = 42
|
fun foo() = 42
|
||||||
|
|||||||
Reference in New Issue
Block a user