Create From Usage: Fix ClassCastException on local property with delegate
#EA-69707 Fixed
This commit is contained in:
@@ -1147,7 +1147,9 @@ public class JetControlFlowProcessor {
|
||||
JetExpression delegate = property.getDelegateExpression();
|
||||
if (delegate != null) {
|
||||
generateInstructions(delegate);
|
||||
generateDelegateConsumer(property, delegate);
|
||||
if (builder.getBoundValue(delegate) != null) {
|
||||
createSyntheticValue(property, MagicKind.VALUE_CONSUMER, delegate);
|
||||
}
|
||||
}
|
||||
|
||||
if (JetPsiUtil.isLocal(property)) {
|
||||
@@ -1157,15 +1159,6 @@ public class JetControlFlowProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDelegateConsumer(@NotNull JetProperty property, @NotNull JetExpression delegate) {
|
||||
DeclarationDescriptor descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, property);
|
||||
if (!(descriptor instanceof PropertyDescriptor)) return;
|
||||
|
||||
if (builder.getBoundValue(delegate) == null) return;
|
||||
|
||||
createSyntheticValue(property, MagicKind.VALUE_CONSUMER, delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMultiDeclaration(@NotNull JetMultiDeclaration declaration) {
|
||||
visitMultiDeclaration(declaration, true);
|
||||
|
||||
+5
-8
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder
|
||||
import com.intellij.refactoring.psi.SearchUtils
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.*
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -171,13 +168,13 @@ fun JetExpression.guessTypes(
|
||||
}
|
||||
}
|
||||
parent is JetPropertyDelegate -> {
|
||||
val property = context[BindingContext.DECLARATION_TO_DESCRIPTOR, parent.getParent() as JetProperty] as PropertyDescriptor
|
||||
val delegateClassName = if (property.isVar()) "ReadWriteProperty" else "ReadOnlyProperty"
|
||||
val variableDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, parent.getParent() as JetProperty] as VariableDescriptor
|
||||
val delegateClassName = if (variableDescriptor.isVar()) "ReadWriteProperty" else "ReadOnlyProperty"
|
||||
val delegateClass = module.resolveTopLevelClass(FqName("kotlin.properties.$delegateClassName"))
|
||||
?: return arrayOf(module.builtIns.getAnyType())
|
||||
val receiverType = (property.getExtensionReceiverParameter() ?: property.getDispatchReceiverParameter())?.getType()
|
||||
val receiverType = (variableDescriptor.getExtensionReceiverParameter() ?: variableDescriptor.getDispatchReceiverParameter())?.getType()
|
||||
?: module.builtIns.getNullableNothingType()
|
||||
val typeArguments = listOf(TypeProjectionImpl(receiverType), TypeProjectionImpl(property.getType()))
|
||||
val typeArguments = listOf(TypeProjectionImpl(receiverType), TypeProjectionImpl(variableDescriptor.getType()))
|
||||
arrayOf(TypeUtils.substituteProjectionsForParameters(delegateClass, typeArguments))
|
||||
}
|
||||
parent is JetStringTemplateEntryWithExpression && parent.getExpression() == this -> {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Create property 'foo'" "true"
|
||||
// ERROR: Local variables are not allowed to have delegates
|
||||
// ERROR: Property must be initialized
|
||||
|
||||
fun test() {
|
||||
val x: Int by <caret>foo
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
// "Create property 'foo'" "true"
|
||||
// ERROR: Local variables are not allowed to have delegates
|
||||
// ERROR: Property must be initialized
|
||||
|
||||
val foo: ReadOnlyProperty<Nothing?, Int>
|
||||
|
||||
fun test() {
|
||||
val x: Int by foo
|
||||
}
|
||||
@@ -2735,6 +2735,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localValDelegateRuntime.kt")
|
||||
public void testLocalValDelegateRuntime() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/localValDelegateRuntime.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localValNoReceiver.kt")
|
||||
public void testLocalValNoReceiver() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createVariable/property/localValNoReceiver.kt");
|
||||
|
||||
Reference in New Issue
Block a user