Fix for KT-13557: VerifyError with delegated local variable used in object expression

#KT-13557 Fixed
This commit is contained in:
Mikhael Bogdanov
2016-11-09 13:40:20 +01:00
parent e68dcdcc1e
commit 21f2febf82
6 changed files with 44 additions and 5 deletions
@@ -1937,10 +1937,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return asmType(varType);
}
private static boolean isDelegatedLocalVariable(@NotNull DeclarationDescriptor descriptor) {
return descriptor instanceof LocalVariableDescriptor && ((LocalVariableDescriptor) descriptor).isDelegated();
}
private static boolean isSharedVarType(@NotNull Type type) {
return type.getSort() == Type.OBJECT && type.getInternalName().startsWith(REF_TYPE_PREFIX);
}
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.codegen.context.RootContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
import org.jetbrains.kotlin.load.kotlin.*;
import org.jetbrains.kotlin.psi.Call;
@@ -303,4 +304,8 @@ public class JvmCodegenUtil {
}
return null;
}
public static boolean isDelegatedLocalVariable(@NotNull DeclarationDescriptor descriptor) {
return descriptor instanceof LocalVariableDescriptor && ((LocalVariableDescriptor) descriptor).isDelegated();
}
}
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
@@ -80,6 +81,7 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
@@ -1303,7 +1305,16 @@ public class KotlinTypeMapper {
if (variableDescriptor instanceof VariableDescriptor && !(variableDescriptor instanceof PropertyDescriptor)) {
Type sharedVarType = getSharedVarType(variableDescriptor);
if (sharedVarType == null) {
sharedVarType = mapType(((VariableDescriptor) variableDescriptor).getType());
if (isDelegatedLocalVariable(variableDescriptor)) {
VariableDescriptor delegateVariableDescriptor = bindingContext.get(LOCAL_VARIABLE_DELEGATE,
(VariableDescriptor) variableDescriptor);
assert delegateVariableDescriptor != null :
"Local delegated property " + variableDescriptor + " delegate descriptor should be not null";
sharedVarType = mapType(delegateVariableDescriptor.getType());
}
else {
sharedVarType = mapType(((VariableDescriptor) variableDescriptor).getType());
}
}
type = sharedVarType;
}
@@ -0,0 +1,15 @@
//WITH_REFLECT
import java.util.*
import kotlin.properties.Delegates
fun box(): String {
var foo: String by Delegates.notNull();
object {
fun baz() {
foo = "OK"
}
}.baz()
return foo
}
@@ -5728,6 +5728,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("kt13557.kt")
public void testKt13557() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt");
doTest(fileName);
}
@TestMetadata("localVal.kt")
public void testLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");
@@ -5728,6 +5728,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("kt13557.kt")
public void testKt13557() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/kt13557.kt");
doTest(fileName);
}
@TestMetadata("localVal.kt")
public void testLocalVal() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/delegatedProperty/local/localVal.kt");