From 4b6cb3ebcecb8b1e835807c2af99989269c44300 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 21 Oct 2015 12:06:21 +0300 Subject: [PATCH] A new kind of synthetic accessors for backing fields, if accessed inside lambda / object literal / local class #KT-9657 Fixed A set of tests provided Also #KT-4867 Fixed Also #KT-8750 Fixed Slight codegen refactoring --- .../AccessorForPropertyBackingField.kt | 31 +++++++++++ ...ccessorForPropertyBackingFieldFromLocal.kt | 28 ++++++++++ ...ForPropertyBackingFieldInClassCompanion.kt | 27 ++++++++++ ...orForPropertyBackingFieldInOuterClass.java | 34 ------------ .../kotlin/codegen/ExpressionCodegen.java | 52 +++++++++++++------ .../kotlin/codegen/MemberCodegen.java | 9 ++-- .../codegen/context/CodegenContext.java | 29 ++++++----- .../kotlin/codegen/syntheticAccessorUtil.kt | 13 ++++- ...eticAccessorForPropertiesSignatureClash.kt | 8 ++- ...ticAccessorForPropertiesSignatureClash.out | 18 +++++-- .../classArtificialFieldInsideNested.kt | 15 ++++++ .../box/properties/classFieldInsideLambda.kt | 6 +++ .../classFieldInsideLocalInSetter.kt | 18 +++++++ .../box/properties/classFieldInsideNested.kt | 14 +++++ ...classPrivateArtificialFieldInsideNested.kt | 15 ++++++ .../properties/companionFieldInsideLambda.kt | 8 +++ .../box/properties/fieldInsideLambda.kt | 4 ++ .../BlackBoxCodegenTestGenerated.java | 42 +++++++++++++++ 18 files changed, 298 insertions(+), 73 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInClassCompanion.kt delete mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInOuterClass.java create mode 100644 compiler/testData/codegen/box/properties/classArtificialFieldInsideNested.kt create mode 100644 compiler/testData/codegen/box/properties/classFieldInsideLambda.kt create mode 100644 compiler/testData/codegen/box/properties/classFieldInsideLocalInSetter.kt create mode 100644 compiler/testData/codegen/box/properties/classFieldInsideNested.kt create mode 100644 compiler/testData/codegen/box/properties/classPrivateArtificialFieldInsideNested.kt create mode 100644 compiler/testData/codegen/box/properties/companionFieldInsideLambda.kt create mode 100644 compiler/testData/codegen/box/properties/fieldInsideLambda.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt new file mode 100644 index 00000000000..48bd75a4da3 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2015 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.kotlin.codegen + +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor +import org.jetbrains.kotlin.psi.KtSuperExpression +import org.jetbrains.kotlin.types.KotlinType + +abstract class AccessorForPropertyBackingField(property: PropertyDescriptor, + type: KotlinType, + receiverType: KotlinType?, + dispatchReceiver: ReceiverParameterDescriptor?, + containingDeclaration: DeclarationDescriptor, + suffix: String +) : AccessorForPropertyDescriptor(property, type, receiverType, dispatchReceiver, containingDeclaration, null, suffix) \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt new file mode 100644 index 00000000000..a11b1eefeb7 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2015 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.kotlin.codegen + +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.resolve.DescriptorUtils + +class AccessorForPropertyBackingFieldFromLocal(property: PropertyDescriptor, + containingDeclaration: DeclarationDescriptor, + nameSuffix: String +) : AccessorForPropertyBackingField(property, property.type, + DescriptorUtils.getReceiverParameterType(property.extensionReceiverParameter), + property.dispatchReceiverParameter, containingDeclaration, nameSuffix) \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInClassCompanion.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInClassCompanion.kt new file mode 100644 index 00000000000..e99fea586f2 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInClassCompanion.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2015 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.kotlin.codegen + +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.types.KotlinType + +class AccessorForPropertyBackingFieldInClassCompanion(property: PropertyDescriptor, + containingDeclaration: DeclarationDescriptor, + delegationType: KotlinType?, + nameSuffix: String +) : AccessorForPropertyBackingField(property, delegationType ?: property.type, null, null, containingDeclaration, nameSuffix) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInOuterClass.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInOuterClass.java deleted file mode 100644 index daf898032d4..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInOuterClass.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.codegen; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; -import org.jetbrains.kotlin.descriptors.PropertyDescriptor; -import org.jetbrains.kotlin.types.KotlinType; - -public class AccessorForPropertyBackingFieldInOuterClass extends AccessorForPropertyDescriptor { - public AccessorForPropertyBackingFieldInOuterClass( - @NotNull PropertyDescriptor property, - @NotNull DeclarationDescriptor containingDeclaration, - @Nullable KotlinType delegationType, - @NotNull String nameSuffix - ) { - super(property, delegationType != null ? delegationType : property.getType(), null, null, containingDeclaration, null, nameSuffix); - } -} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index ab32f294a91..13a3e8363fc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2016,7 +2016,7 @@ public class ExpressionCodegen extends KtVisitor impleme receiver = StackValue.receiverWithoutReceiverArgument(receiver); } - return intermediateValueForProperty(propertyDescriptor, directToField, superExpression, receiver); + return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superExpression, false, receiver); } if (descriptor instanceof ClassDescriptor) { @@ -2140,12 +2140,27 @@ public class ExpressionCodegen extends KtVisitor impleme @Nullable KtSuperExpression superExpression, @NotNull StackValue receiver ) { - return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, false, receiver); + return intermediateValueForProperty(propertyDescriptor, forceField, false, superExpression, false, receiver); + } + + private CodegenContext getBackingFieldContext( + @NotNull FieldAccessorKind accessorKind, + @NotNull DeclarationDescriptor containingDeclaration + ) { + switch (accessorKind) { + case NORMAL: return context.getParentContext(); + // For companion object property, backing field lives in object containing class + // Otherwise, it lives in its containing declaration + case IN_CLASS_COMPANION: return context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration()); + case FIELD_FROM_LOCAL: return context.findParentContextWithDescriptor(containingDeclaration); + default: throw new IllegalStateException(); + } } public StackValue.Property intermediateValueForProperty( @NotNull PropertyDescriptor propertyDescriptor, boolean forceField, + boolean syntheticBackingField, @Nullable KtSuperExpression superExpression, boolean skipAccessorsForPrivateFieldInOuterClass, StackValue receiver @@ -2156,7 +2171,14 @@ public class ExpressionCodegen extends KtVisitor impleme DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); - boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor); + FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL; + boolean isBackingFieldInClassCompanion = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor); + if (isBackingFieldInClassCompanion && forceField) { + fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION; + } + else if (syntheticBackingField && context.getParentContext().getContextDescriptor() != containingDeclaration) { + fieldAccessorKind = FieldAccessorKind.FIELD_FROM_LOCAL; + } boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) || AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor); boolean isSuper = superExpression != null; @@ -2168,28 +2190,27 @@ public class ExpressionCodegen extends KtVisitor impleme CallableMethod callableGetter = null; CallableMethod callableSetter = null; - CodegenContext backingFieldContext; - boolean changeOwnerOnTypeMapping; + CodegenContext backingFieldContext = getBackingFieldContext(fieldAccessorKind, containingDeclaration); + DeclarationDescriptor ownerDescriptor = containingDeclaration; boolean skipPropertyAccessors; - if (isBackingFieldInAnotherClass && forceField) { - backingFieldContext = context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration()); + if (fieldAccessorKind != FieldAccessorKind.NORMAL) { int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty); skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass; if (!skipPropertyAccessors) { //noinspection ConstantConditions propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor( - propertyDescriptor, true, delegateType, superExpression + propertyDescriptor, fieldAccessorKind, delegateType, superExpression ); - changeOwnerOnTypeMapping = !(propertyDescriptor instanceof AccessorForPropertyBackingFieldInOuterClass); - } - else { - changeOwnerOnTypeMapping = true; + assert propertyDescriptor instanceof AccessorForPropertyBackingField : + "Unexpected accessor descriptor: " + propertyDescriptor; + ownerDescriptor = propertyDescriptor; } } else { - backingFieldContext = context.getParentContext(); - changeOwnerOnTypeMapping = isBackingFieldInAnotherClass; + if (!isBackingFieldInClassCompanion) { + ownerDescriptor = propertyDescriptor; + } skipPropertyAccessors = forceField; } @@ -2226,8 +2247,7 @@ public class ExpressionCodegen extends KtVisitor impleme propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor); } - Type backingFieldOwner = - typeMapper.mapOwner(changeOwnerOnTypeMapping ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor); + Type backingFieldOwner = typeMapper.mapOwner(ownerDescriptor); String fieldName; if (isExtensionProperty && !isDelegatedProperty) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 3d2ddeb6c5c..b14f04b251a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -389,7 +389,7 @@ public abstract class MemberCodegen { @NotNull public D getAccessor(@NotNull D descriptor, @Nullable KtSuperExpression superCallExpression) { - return getAccessor(descriptor, false, null, superCallExpression); + return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallExpression); } @SuppressWarnings("unchecked") @NotNull public D getAccessor( @NotNull D possiblySubstitutedDescriptor, - boolean isForBackingFieldInOuterClass, + @NotNull FieldAccessorKind accessorKind, @Nullable KotlinType delegateType, @Nullable KtSuperExpression superCallExpression ) { @@ -315,11 +315,11 @@ public abstract class CodegenContext { AccessorForCallableDescriptor accessor = accessors.get(key); if (accessor != null) { - assert !isForBackingFieldInOuterClass || - accessor instanceof AccessorForPropertyBackingFieldInOuterClass : "There is already exists accessor with isForBackingFieldInOuterClass = false in this context"; + assert accessorKind == FieldAccessorKind.NORMAL || + accessor instanceof AccessorForPropertyBackingField : "There is already exists accessor with isForBackingField = false in this context"; return (D) accessor; } - String nameSuffix = SyntheticAccessorUtilKt.getAccessorNameSuffix(descriptor, key.superCallLabelTarget, isForBackingFieldInOuterClass); + String nameSuffix = SyntheticAccessorUtilKt.getAccessorNameSuffix(descriptor, key.superCallLabelTarget, accessorKind); if (descriptor instanceof SimpleFunctionDescriptor) { accessor = new AccessorForFunctionDescriptor( (FunctionDescriptor) descriptor, contextDescriptor, superCallExpression, nameSuffix @@ -329,13 +329,18 @@ public abstract class CodegenContext { accessor = new AccessorForConstructorDescriptor((ConstructorDescriptor) descriptor, contextDescriptor, superCallExpression); } else if (descriptor instanceof PropertyDescriptor) { - if (isForBackingFieldInOuterClass) { - accessor = new AccessorForPropertyBackingFieldInOuterClass((PropertyDescriptor) descriptor, contextDescriptor, - delegateType, nameSuffix); - } - else { - accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor, - superCallExpression, nameSuffix); + PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; + switch (accessorKind) { + case NORMAL: + accessor = new AccessorForPropertyDescriptor(propertyDescriptor, contextDescriptor, superCallExpression, nameSuffix); + break; + case IN_CLASS_COMPANION: + accessor = new AccessorForPropertyBackingFieldInClassCompanion(propertyDescriptor, contextDescriptor, + delegateType, nameSuffix); + break; + case FIELD_FROM_LOCAL: + accessor = new AccessorForPropertyBackingFieldFromLocal(propertyDescriptor, contextDescriptor, nameSuffix); + break; } } else { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt index a9c2dfa7d95..f86d44b8f27 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt @@ -18,14 +18,23 @@ package org.jetbrains.kotlin.codegen import org.jetbrains.kotlin.descriptors.* -fun getAccessorNameSuffix(descriptor: CallableMemberDescriptor, superCallDescriptor: ClassDescriptor?, isForBackingFieldInOuterClass: Boolean): String { +enum class FieldAccessorKind(val suffix: String) { + NORMAL("p"), + IN_CLASS_COMPANION("cp"), + FIELD_FROM_LOCAL("lp"); + + override fun toString() = suffix +} + +fun getAccessorNameSuffix(descriptor: CallableMemberDescriptor, superCallDescriptor: ClassDescriptor?, + accessorKind: FieldAccessorKind): String { val suffix = when (descriptor) { is ConstructorDescriptor -> return "will be ignored" is SimpleFunctionDescriptor -> descriptor.name.asString() is PropertyDescriptor -> - descriptor.name.asString() + "$" + (if (isForBackingFieldInOuterClass) "cp" else "p") + descriptor.name.asString() + "$" + accessorKind else -> throw UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor) } diff --git a/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt b/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt index 4c92d47bbc6..52f0cfe3f9a 100644 --- a/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt +++ b/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt @@ -9,6 +9,12 @@ class A { fun `access$getFoo$cp`(): Int = 1 fun `access$setFoo$cp`(d: Int) {} + val bar = 0 + get() = { field }() + + //synthetic field convention accessor + fun `access$getBar$lp`(a: A): Int = 7 + companion object { private var foo = 1; @@ -26,7 +32,7 @@ class A { fun test() { { foo = 2; - foo + foo + bar }() } } \ No newline at end of file diff --git a/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.out b/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.out index 1bcfee535a2..2ac05f8d22f 100644 --- a/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.out +++ b/compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.out @@ -18,6 +18,11 @@ compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:1:7: e fun `access$setFoo$cp`(d: kotlin.Int): kotlin.Unit class A { ^ +compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:1:7: error: platform declaration clash: The following declarations have the same JVM signature (access$getBar$lp(LA;)I): + fun (): kotlin.Int + fun `access$getBar$lp`(a: A): kotlin.Int +class A { + ^ compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:5:5: error: platform declaration clash: The following declarations have the same JVM signature (access$getFoo$p(LA;)I): fun (): kotlin.Int fun `access$getFoo$p`(a: A): kotlin.Int @@ -38,22 +43,27 @@ compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:10:5: fun `access$setFoo$cp`(d: kotlin.Int): kotlin.Unit fun `access$setFoo$cp`(d: Int) {} ^ -compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:12:15: error: platform declaration clash: The following declarations have the same JVM signature (access$getFoo$p(LA$Companion;)I): +compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:16:5: error: platform declaration clash: The following declarations have the same JVM signature (access$getBar$lp(LA;)I): + fun (): kotlin.Int + fun `access$getBar$lp`(a: A): kotlin.Int + fun `access$getBar$lp`(a: A): Int = 7 + ^ +compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:18:15: error: platform declaration clash: The following declarations have the same JVM signature (access$getFoo$p(LA$Companion;)I): fun (): kotlin.Int fun `access$getFoo$p`(p: A.Companion): kotlin.Int companion object { ^ -compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:12:15: error: platform declaration clash: The following declarations have the same JVM signature (access$setFoo$p(LA$Companion;I)V): +compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:18:15: error: platform declaration clash: The following declarations have the same JVM signature (access$setFoo$p(LA$Companion;I)V): fun (: kotlin.Int): kotlin.Unit fun `access$setFoo$p`(p: A.Companion, d: kotlin.Int): kotlin.Unit companion object { ^ -compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:22:9: error: platform declaration clash: The following declarations have the same JVM signature (access$getFoo$p(LA$Companion;)I): +compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:28:9: error: platform declaration clash: The following declarations have the same JVM signature (access$getFoo$p(LA$Companion;)I): fun (): kotlin.Int fun `access$getFoo$p`(p: A.Companion): kotlin.Int fun `access$getFoo$p`(p: A.Companion): Int = 1 ^ -compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:23:9: error: platform declaration clash: The following declarations have the same JVM signature (access$setFoo$p(LA$Companion;I)V): +compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:29:9: error: platform declaration clash: The following declarations have the same JVM signature (access$setFoo$p(LA$Companion;I)V): fun (: kotlin.Int): kotlin.Unit fun `access$setFoo$p`(p: A.Companion, d: kotlin.Int): kotlin.Unit fun `access$setFoo$p`(p: A.Companion, d: Int) {} diff --git a/compiler/testData/codegen/box/properties/classArtificialFieldInsideNested.kt b/compiler/testData/codegen/box/properties/classArtificialFieldInsideNested.kt new file mode 100644 index 00000000000..a33fcca3c74 --- /dev/null +++ b/compiler/testData/codegen/box/properties/classArtificialFieldInsideNested.kt @@ -0,0 +1,15 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +class My { + val back = "O" + val my: String + get() = object : Your() { + override val your = back + }.foo() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/classFieldInsideLambda.kt b/compiler/testData/codegen/box/properties/classFieldInsideLambda.kt new file mode 100644 index 00000000000..121ac3426b4 --- /dev/null +++ b/compiler/testData/codegen/box/properties/classFieldInsideLambda.kt @@ -0,0 +1,6 @@ +class My { + val my: String = "O" + get() = { field }() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/classFieldInsideLocalInSetter.kt b/compiler/testData/codegen/box/properties/classFieldInsideLocalInSetter.kt new file mode 100644 index 00000000000..e6e1c9f17f4 --- /dev/null +++ b/compiler/testData/codegen/box/properties/classFieldInsideLocalInSetter.kt @@ -0,0 +1,18 @@ +class My { + var my: String = "U" + get() = { field }() + set(arg) { + class Local { + fun foo() { + field = arg + "K" + } + } + Local().foo() + } +} + +fun box(): String { + val m = My() + m.my = "O" + return m.my +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/classFieldInsideNested.kt b/compiler/testData/codegen/box/properties/classFieldInsideNested.kt new file mode 100644 index 00000000000..0ac00ddb630 --- /dev/null +++ b/compiler/testData/codegen/box/properties/classFieldInsideNested.kt @@ -0,0 +1,14 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +class My { + val my: String = "O" + get() = object : Your() { + override val your = field + }.foo() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/classPrivateArtificialFieldInsideNested.kt b/compiler/testData/codegen/box/properties/classPrivateArtificialFieldInsideNested.kt new file mode 100644 index 00000000000..af1660a58da --- /dev/null +++ b/compiler/testData/codegen/box/properties/classPrivateArtificialFieldInsideNested.kt @@ -0,0 +1,15 @@ +abstract class Your { + abstract val your: String + + fun foo() = your +} + +class My { + private val back = "O" + val my: String + get() = object : Your() { + override val your = back + }.foo() + "K" +} + +fun box() = My().my \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/companionFieldInsideLambda.kt b/compiler/testData/codegen/box/properties/companionFieldInsideLambda.kt new file mode 100644 index 00000000000..4e4f60b9df7 --- /dev/null +++ b/compiler/testData/codegen/box/properties/companionFieldInsideLambda.kt @@ -0,0 +1,8 @@ +class My { + companion object { + val my: String = "O" + get() = { field }() + "K" + } +} + +fun box() = My.my \ No newline at end of file diff --git a/compiler/testData/codegen/box/properties/fieldInsideLambda.kt b/compiler/testData/codegen/box/properties/fieldInsideLambda.kt new file mode 100644 index 00000000000..ebf3cb6cfb7 --- /dev/null +++ b/compiler/testData/codegen/box/properties/fieldInsideLambda.kt @@ -0,0 +1,4 @@ +val my: String = "O" + get() = { field }() + "K" + +fun box() = my diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 057a1b85412..ef495e4a3ee 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -6397,12 +6397,48 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("classArtificialFieldInsideNested.kt") + public void testClassArtificialFieldInsideNested() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classArtificialFieldInsideNested.kt"); + doTest(fileName); + } + + @TestMetadata("classFieldInsideLambda.kt") + public void testClassFieldInsideLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classFieldInsideLambda.kt"); + doTest(fileName); + } + + @TestMetadata("classFieldInsideLocalInSetter.kt") + public void testClassFieldInsideLocalInSetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classFieldInsideLocalInSetter.kt"); + doTest(fileName); + } + + @TestMetadata("classFieldInsideNested.kt") + public void testClassFieldInsideNested() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classFieldInsideNested.kt"); + doTest(fileName); + } + @TestMetadata("classObjectProperties.kt") public void testClassObjectProperties() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classObjectProperties.kt"); doTest(fileName); } + @TestMetadata("classPrivateArtificialFieldInsideNested.kt") + public void testClassPrivateArtificialFieldInsideNested() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classPrivateArtificialFieldInsideNested.kt"); + doTest(fileName); + } + + @TestMetadata("companionFieldInsideLambda.kt") + public void testCompanionFieldInsideLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/companionFieldInsideLambda.kt"); + doTest(fileName); + } + @TestMetadata("field.kt") public void testField() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/field.kt"); @@ -6421,6 +6457,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("fieldInsideLambda.kt") + public void testFieldInsideLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/fieldInsideLambda.kt"); + doTest(fileName); + } + @TestMetadata("fieldInsideNested.kt") public void testFieldInsideNested() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/fieldInsideNested.kt");