KT-4138: java.lang.VerifyError: (class: kotlin/sql/tests/h2/Foo, method: getA$b$0 signature: ()Lkotlin/sql/tests/h2/Foo;) Wrong return type in function

#KT-4138 Fixed
This commit is contained in:
Mikhael Bogdanov
2013-10-28 15:01:33 +04:00
parent 12d0da8146
commit 3ee918b084
6 changed files with 110 additions and 12 deletions
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2013 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.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.types.JetType;
public class AccessorForPropertyBackingFieldInOuterClass extends AccessorForPropertyDescriptor {
public AccessorForPropertyBackingFieldInOuterClass(
@NotNull PropertyDescriptor pd,
@NotNull DeclarationDescriptor containingDeclaration,
int index,
@Nullable JetType delegationType
) {
super(pd, delegationType != null ? delegationType : pd.getType(), null, null, containingDeclaration, index);
}
}
@@ -16,6 +16,8 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl;
@@ -29,17 +31,23 @@ import org.jetbrains.jet.lang.types.JetType;
import java.util.Collections;
public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl {
public AccessorForPropertyDescriptor(PropertyDescriptor pd, DeclarationDescriptor containingDeclaration, int index) {
public AccessorForPropertyDescriptor(@NotNull PropertyDescriptor pd, @NotNull DeclarationDescriptor containingDeclaration, int index) {
this(pd, pd.getType(), DescriptorUtils.getReceiverParameterType(pd.getReceiverParameter()), pd.getExpectedThisObject(), containingDeclaration, index);
}
protected AccessorForPropertyDescriptor(
@NotNull PropertyDescriptor original,
@NotNull JetType propertyType,
@Nullable JetType receiverType,
@Nullable ReceiverParameterDescriptor expectedThisObject,
@NotNull DeclarationDescriptor containingDeclaration,
int index
) {
super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.LOCAL,
pd.isVar(), Name.identifier(pd.getName() + "$b$" + index),
original.isVar(), Name.identifier(original.getName() + "$b$" + index),
Kind.DECLARATION);
boolean isStaticProperty = AsmUtil.isPropertyWithBackingFieldInOuterClass(pd)
&& !AsmUtil.isClassObjectWithBackingFieldsInOuter(containingDeclaration);
JetType receiverType = !isStaticProperty ? DescriptorUtils.getReceiverParameterType(pd.getReceiverParameter()) : null;
setType(pd.getType(), Collections.<TypeParameterDescriptorImpl>emptyList(), isStaticProperty ? null : pd.getExpectedThisObject(),
receiverType);
setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), expectedThisObject, receiverType);
initialize(new Getter(this), new Setter(this));
}
@@ -1811,7 +1811,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || methodKind == MethodKind.SYNTHETIC_ACCESSOR || methodKind == MethodKind.INITIALIZER;
if (!skipPropertyAccessors) {
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(propertyDescriptor);
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(propertyDescriptor, true, delegateType);
}
}
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collections;
import java.util.HashMap;
@@ -247,21 +248,35 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return c;
}
public DeclarationDescriptor getAccessor(DeclarationDescriptor descriptor) {
@NotNull
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor) {
return getAccessor(descriptor, false, null);
}
@NotNull
public DeclarationDescriptor getAccessor(@NotNull DeclarationDescriptor descriptor, boolean isForBackingFieldInOuterClass, @Nullable JetType delegateType) {
if (accessors == null) {
accessors = new HashMap<DeclarationDescriptor, DeclarationDescriptor>();
}
descriptor = descriptor.getOriginal();
DeclarationDescriptor accessor = accessors.get(descriptor);
if (accessor != null) {
assert !isForBackingFieldInOuterClass ||
accessor instanceof AccessorForPropertyBackingFieldInOuterClass : "There is already exists accessor with isForBackingFieldInOuterClass = false in this context";
return accessor;
}
int accessorIndex = accessors.size();
if (descriptor instanceof SimpleFunctionDescriptor || descriptor instanceof ConstructorDescriptor) {
accessor = new AccessorForFunctionDescriptor((FunctionDescriptor) descriptor, contextDescriptor, accessors.size());
accessor = new AccessorForFunctionDescriptor((FunctionDescriptor) descriptor, contextDescriptor, accessorIndex);
}
else if (descriptor instanceof PropertyDescriptor) {
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessors.size());
if (isForBackingFieldInOuterClass) {
accessor = new AccessorForPropertyBackingFieldInOuterClass((PropertyDescriptor) descriptor, contextDescriptor,
accessorIndex, delegateType);
} else {
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, accessorIndex);
}
}
else {
throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor);
@@ -0,0 +1,35 @@
class Delegate<T>(var inner: T) {
fun get(t: Any?, p: PropertyMetadata): T = inner
fun set(t: Any?, p: PropertyMetadata, i: T) { inner = i }
}
class Foo (val f: Int) {
class object {
val A: Foo by Delegate(Foo(11))
var B: Foo by Delegate(Foo(11))
}
}
trait FooTrait {
class object {
val A: Foo by Delegate(Foo(11))
var B: Foo by Delegate(Foo(11))
}
}
fun box() : String {
if (Foo.A.f != 11) return "fail 1"
if (Foo.B.f != 11) return "fail 2"
Foo.B = Foo(12)
if (Foo.B.f != 12) return "fail 3"
if (FooTrait.A.f != 11) return "fail 4"
if (FooTrait.B.f != 11) return "fail 5"
FooTrait.B = Foo(12)
if (FooTrait.B.f != 12) return "fail 6"
return "OK"
}
@@ -1877,6 +1877,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/delegatedProperty/inferredPropertyType.kt");
}
@TestMetadata("kt4138.kt")
public void testKt4138() throws Exception {
doTest("compiler/testData/codegen/box/delegatedProperty/kt4138.kt");
}
@TestMetadata("privateVar.kt")
public void testPrivateVar() throws Exception {
doTest("compiler/testData/codegen/box/delegatedProperty/privateVar.kt");