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.psiUtil.getQualifiedElementSelector
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
@@ -1481,6 +1478,16 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
||||
|
||||
when (receiver) {
|
||||
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)
|
||||
}
|
||||
is ExpressionReceiver -> {
|
||||
|
||||
@@ -91,7 +91,12 @@ public class PseudocodeUtil {
|
||||
public static VariableDescriptor extractVariableDescriptorIfAny(@NotNull Instruction instruction, boolean onlyReference, @NotNull BindingContext bindingContext) {
|
||||
KtElement element = null;
|
||||
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) {
|
||||
element = ((WriteValueInstruction) instruction).getLValue();
|
||||
|
||||
+9
-8
@@ -26,18 +26,19 @@ L0:
|
||||
v(ANOTHER(foo());)
|
||||
magic[FAKE_INITIALIZER](ANOTHER(foo());) -> <v5>
|
||||
w(ANOTHER|<v5>)
|
||||
magic[IMPLICIT_RECEIVER](foo()) -> <v6>
|
||||
r(foo, Companion) -> <v6>
|
||||
magic[IMPLICIT_RECEIVER](foo()) -> <v7>
|
||||
mark(foo())
|
||||
call(foo(), foo|<v6>) -> <v7>
|
||||
call(foo(), foo|<v7>) -> <v8>
|
||||
mark((foo()))
|
||||
call((foo()), <init>|<v7>) -> <v8>
|
||||
call((foo()), <init>|<v8>) -> <v9>
|
||||
v(companion object { fun foo() = 42 })
|
||||
magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v9>
|
||||
w(Companion|<v9>)
|
||||
magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v10>
|
||||
w(Companion|<v10>)
|
||||
L1:
|
||||
<END> NEXT:[<SINK>]
|
||||
<END> NEXT:[<SINK>]
|
||||
error:
|
||||
<ERROR> PREV:[]
|
||||
<ERROR> PREV:[]
|
||||
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>
|
||||
<v1>: EE NEW: magic[FAKE_INITIALIZER](INSTANCE(Companion.foo()),) -> <v1>
|
||||
<v5>: EE NEW: magic[FAKE_INITIALIZER](ANOTHER(foo());) -> <v5>
|
||||
<v6>: EE.Companion NEW: magic[IMPLICIT_RECEIVER](foo()) -> <v6>
|
||||
<v9>: EE.Companion NEW: magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v9>
|
||||
Companion <v2>: EE.Companion NEW: r(Companion) -> <v2>
|
||||
foo() <v3>: Int NEW: call(foo(), foo|<v2>) -> <v3>
|
||||
Companion.foo() <v3>: Int COPY
|
||||
(Companion.foo()) <v4>: * NEW: call((Companion.foo()), <init>|<v3>) -> <v4>
|
||||
foo() <v7>: Int NEW: call(foo(), foo|<v6>) -> <v7>
|
||||
(foo()) <v8>: * NEW: call((foo()), <init>|<v7>) -> <v8>
|
||||
<v0>: Int NEW: magic[FAKE_INITIALIZER](val x: Int) -> <v0>
|
||||
<v10>: EE.Companion NEW: magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> <v10>
|
||||
<v1>: EE NEW: magic[FAKE_INITIALIZER](INSTANCE(Companion.foo()),) -> <v1>
|
||||
<v5>: EE NEW: magic[FAKE_INITIALIZER](ANOTHER(foo());) -> <v5>
|
||||
<v7>: EE.Companion NEW: magic[IMPLICIT_RECEIVER](foo()) -> <v7>
|
||||
Companion <v2>: EE.Companion NEW: r(Companion) -> <v2>
|
||||
foo() <v3>: Int NEW: call(foo(), foo|<v2>) -> <v3>
|
||||
Companion.foo() <v3>: Int COPY
|
||||
(Companion.foo()) <v4>: * NEW: call((Companion.foo()), <init>|<v3>) -> <v4>
|
||||
foo <v6>: * NEW: r(foo, Companion) -> <v6>
|
||||
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
|
||||
enum class EnumCompanion2(val x: Int) {
|
||||
INSTANCE(foo()); // TODO
|
||||
INSTANCE(<!UNINITIALIZED_ENUM_COMPANION!>foo<!>());
|
||||
|
||||
companion object {
|
||||
fun foo() = 42
|
||||
|
||||
Reference in New Issue
Block a user