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
This commit is contained in:
@@ -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)
|
||||||
+28
@@ -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)
|
||||||
+27
@@ -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)
|
||||||
-34
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2016,7 +2016,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
receiver = StackValue.receiverWithoutReceiverArgument(receiver);
|
receiver = StackValue.receiverWithoutReceiverArgument(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
return intermediateValueForProperty(propertyDescriptor, directToField, superExpression, receiver);
|
return intermediateValueForProperty(propertyDescriptor, directToField, directToField, superExpression, false, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
@@ -2140,12 +2140,27 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
@Nullable KtSuperExpression superExpression,
|
@Nullable KtSuperExpression superExpression,
|
||||||
@NotNull StackValue receiver
|
@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(
|
public StackValue.Property intermediateValueForProperty(
|
||||||
@NotNull PropertyDescriptor propertyDescriptor,
|
@NotNull PropertyDescriptor propertyDescriptor,
|
||||||
boolean forceField,
|
boolean forceField,
|
||||||
|
boolean syntheticBackingField,
|
||||||
@Nullable KtSuperExpression superExpression,
|
@Nullable KtSuperExpression superExpression,
|
||||||
boolean skipAccessorsForPrivateFieldInOuterClass,
|
boolean skipAccessorsForPrivateFieldInOuterClass,
|
||||||
StackValue receiver
|
StackValue receiver
|
||||||
@@ -2156,7 +2171,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
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) ||
|
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
|
||||||
AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor);
|
AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor);
|
||||||
boolean isSuper = superExpression != null;
|
boolean isSuper = superExpression != null;
|
||||||
@@ -2168,28 +2190,27 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
CallableMethod callableGetter = null;
|
CallableMethod callableGetter = null;
|
||||||
CallableMethod callableSetter = null;
|
CallableMethod callableSetter = null;
|
||||||
|
|
||||||
CodegenContext backingFieldContext;
|
CodegenContext backingFieldContext = getBackingFieldContext(fieldAccessorKind, containingDeclaration);
|
||||||
boolean changeOwnerOnTypeMapping;
|
DeclarationDescriptor ownerDescriptor = containingDeclaration;
|
||||||
boolean skipPropertyAccessors;
|
boolean skipPropertyAccessors;
|
||||||
|
|
||||||
if (isBackingFieldInAnotherClass && forceField) {
|
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
|
||||||
backingFieldContext = context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration());
|
|
||||||
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
|
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
|
||||||
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
|
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
|
||||||
if (!skipPropertyAccessors) {
|
if (!skipPropertyAccessors) {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(
|
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(
|
||||||
propertyDescriptor, true, delegateType, superExpression
|
propertyDescriptor, fieldAccessorKind, delegateType, superExpression
|
||||||
);
|
);
|
||||||
changeOwnerOnTypeMapping = !(propertyDescriptor instanceof AccessorForPropertyBackingFieldInOuterClass);
|
assert propertyDescriptor instanceof AccessorForPropertyBackingField :
|
||||||
}
|
"Unexpected accessor descriptor: " + propertyDescriptor;
|
||||||
else {
|
ownerDescriptor = propertyDescriptor;
|
||||||
changeOwnerOnTypeMapping = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
backingFieldContext = context.getParentContext();
|
if (!isBackingFieldInClassCompanion) {
|
||||||
changeOwnerOnTypeMapping = isBackingFieldInAnotherClass;
|
ownerDescriptor = propertyDescriptor;
|
||||||
|
}
|
||||||
skipPropertyAccessors = forceField;
|
skipPropertyAccessors = forceField;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2226,8 +2247,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type backingFieldOwner =
|
Type backingFieldOwner = typeMapper.mapOwner(ownerDescriptor);
|
||||||
typeMapper.mapOwner(changeOwnerOnTypeMapping ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor);
|
|
||||||
|
|
||||||
String fieldName;
|
String fieldName;
|
||||||
if (isExtensionProperty && !isDelegatedProperty) {
|
if (isExtensionProperty && !isDelegatedProperty) {
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
|||||||
KtExpression initializer = property.getDelegateExpressionOrInitializer();
|
KtExpression initializer = property.getDelegateExpressionOrInitializer();
|
||||||
assert initializer != null : "shouldInitializeProperty must return false if initializer is null";
|
assert initializer != null : "shouldInitializeProperty must return false if initializer is null";
|
||||||
|
|
||||||
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, true, StackValue.LOCAL_0);
|
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, false, null, true, StackValue.LOCAL_0);
|
||||||
|
|
||||||
propValue.store(codegen.gen(initializer), codegen.v);
|
propValue.store(codegen.gen(initializer), codegen.v);
|
||||||
}
|
}
|
||||||
@@ -613,10 +613,11 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
|
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
|
||||||
!isCompanionObject(accessor.getContainingDeclaration());
|
boolean forceField = (AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||||
|
!isCompanionObject(accessor.getContainingDeclaration())) || syntheticBackingField;
|
||||||
StackValue property = codegen.intermediateValueForProperty(
|
StackValue property = codegen.intermediateValueForProperty(
|
||||||
original, forceField, accessor.getSuperCallExpression(), true, StackValue.none()
|
original, forceField, syntheticBackingField, accessor.getSuperCallExpression(), true, StackValue.none()
|
||||||
);
|
);
|
||||||
|
|
||||||
InstructionAdapter iv = codegen.v;
|
InstructionAdapter iv = codegen.v;
|
||||||
|
|||||||
@@ -293,14 +293,14 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable KtSuperExpression superCallExpression) {
|
public <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable KtSuperExpression superCallExpression) {
|
||||||
return getAccessor(descriptor, false, null, superCallExpression);
|
return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@NotNull
|
@NotNull
|
||||||
public <D extends CallableMemberDescriptor> D getAccessor(
|
public <D extends CallableMemberDescriptor> D getAccessor(
|
||||||
@NotNull D possiblySubstitutedDescriptor,
|
@NotNull D possiblySubstitutedDescriptor,
|
||||||
boolean isForBackingFieldInOuterClass,
|
@NotNull FieldAccessorKind accessorKind,
|
||||||
@Nullable KotlinType delegateType,
|
@Nullable KotlinType delegateType,
|
||||||
@Nullable KtSuperExpression superCallExpression
|
@Nullable KtSuperExpression superCallExpression
|
||||||
) {
|
) {
|
||||||
@@ -315,11 +315,11 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
|
|
||||||
AccessorForCallableDescriptor<?> accessor = accessors.get(key);
|
AccessorForCallableDescriptor<?> accessor = accessors.get(key);
|
||||||
if (accessor != null) {
|
if (accessor != null) {
|
||||||
assert !isForBackingFieldInOuterClass ||
|
assert accessorKind == FieldAccessorKind.NORMAL ||
|
||||||
accessor instanceof AccessorForPropertyBackingFieldInOuterClass : "There is already exists accessor with isForBackingFieldInOuterClass = false in this context";
|
accessor instanceof AccessorForPropertyBackingField : "There is already exists accessor with isForBackingField = false in this context";
|
||||||
return (D) accessor;
|
return (D) accessor;
|
||||||
}
|
}
|
||||||
String nameSuffix = SyntheticAccessorUtilKt.getAccessorNameSuffix(descriptor, key.superCallLabelTarget, isForBackingFieldInOuterClass);
|
String nameSuffix = SyntheticAccessorUtilKt.getAccessorNameSuffix(descriptor, key.superCallLabelTarget, accessorKind);
|
||||||
if (descriptor instanceof SimpleFunctionDescriptor) {
|
if (descriptor instanceof SimpleFunctionDescriptor) {
|
||||||
accessor = new AccessorForFunctionDescriptor(
|
accessor = new AccessorForFunctionDescriptor(
|
||||||
(FunctionDescriptor) descriptor, contextDescriptor, superCallExpression, nameSuffix
|
(FunctionDescriptor) descriptor, contextDescriptor, superCallExpression, nameSuffix
|
||||||
@@ -329,13 +329,18 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
accessor = new AccessorForConstructorDescriptor((ConstructorDescriptor) descriptor, contextDescriptor, superCallExpression);
|
accessor = new AccessorForConstructorDescriptor((ConstructorDescriptor) descriptor, contextDescriptor, superCallExpression);
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof PropertyDescriptor) {
|
else if (descriptor instanceof PropertyDescriptor) {
|
||||||
if (isForBackingFieldInOuterClass) {
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
accessor = new AccessorForPropertyBackingFieldInOuterClass((PropertyDescriptor) descriptor, contextDescriptor,
|
switch (accessorKind) {
|
||||||
delegateType, nameSuffix);
|
case NORMAL:
|
||||||
}
|
accessor = new AccessorForPropertyDescriptor(propertyDescriptor, contextDescriptor, superCallExpression, nameSuffix);
|
||||||
else {
|
break;
|
||||||
accessor = new AccessorForPropertyDescriptor((PropertyDescriptor) descriptor, contextDescriptor,
|
case IN_CLASS_COMPANION:
|
||||||
superCallExpression, nameSuffix);
|
accessor = new AccessorForPropertyBackingFieldInClassCompanion(propertyDescriptor, contextDescriptor,
|
||||||
|
delegateType, nameSuffix);
|
||||||
|
break;
|
||||||
|
case FIELD_FROM_LOCAL:
|
||||||
|
accessor = new AccessorForPropertyBackingFieldFromLocal(propertyDescriptor, contextDescriptor, nameSuffix);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -18,14 +18,23 @@ package org.jetbrains.kotlin.codegen
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
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) {
|
val suffix = when (descriptor) {
|
||||||
is ConstructorDescriptor ->
|
is ConstructorDescriptor ->
|
||||||
return "will be ignored"
|
return "will be ignored"
|
||||||
is SimpleFunctionDescriptor ->
|
is SimpleFunctionDescriptor ->
|
||||||
descriptor.name.asString()
|
descriptor.name.asString()
|
||||||
is PropertyDescriptor ->
|
is PropertyDescriptor ->
|
||||||
descriptor.name.asString() + "$" + (if (isForBackingFieldInOuterClass) "cp" else "p")
|
descriptor.name.asString() + "$" + accessorKind
|
||||||
else ->
|
else ->
|
||||||
throw UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor)
|
throw UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ class A {
|
|||||||
fun `access$getFoo$cp`(): Int = 1
|
fun `access$getFoo$cp`(): Int = 1
|
||||||
fun `access$setFoo$cp`(d: Int) {}
|
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 {
|
companion object {
|
||||||
private var foo = 1;
|
private var foo = 1;
|
||||||
|
|
||||||
@@ -26,7 +32,7 @@ class A {
|
|||||||
fun test() {
|
fun test() {
|
||||||
{
|
{
|
||||||
foo = 2;
|
foo = 2;
|
||||||
foo
|
foo + bar
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+14
-4
@@ -18,6 +18,11 @@ compiler/testData/cli/jvm/syntheticAccessorForPropertiesSignatureClash.kt:1:7: e
|
|||||||
fun `access$setFoo$cp`(d: kotlin.Int): kotlin.Unit
|
fun `access$setFoo$cp`(d: kotlin.Int): kotlin.Unit
|
||||||
class A {
|
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 <get-bar>(): 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):
|
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 <get-foo>(): kotlin.Int
|
fun <get-foo>(): kotlin.Int
|
||||||
fun `access$getFoo$p`(a: A): 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: kotlin.Int): kotlin.Unit
|
||||||
fun `access$setFoo$cp`(d: Int) {}
|
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 <get-bar>(): 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 <get-foo>(): kotlin.Int
|
fun <get-foo>(): kotlin.Int
|
||||||
fun `access$getFoo$p`(p: A.Companion): kotlin.Int
|
fun `access$getFoo$p`(p: A.Companion): kotlin.Int
|
||||||
companion object {
|
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 <set-foo>(<set-?>: kotlin.Int): kotlin.Unit
|
fun <set-foo>(<set-?>: kotlin.Int): kotlin.Unit
|
||||||
fun `access$setFoo$p`(p: A.Companion, d: kotlin.Int): kotlin.Unit
|
fun `access$setFoo$p`(p: A.Companion, d: kotlin.Int): kotlin.Unit
|
||||||
companion object {
|
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 <get-foo>(): kotlin.Int
|
fun <get-foo>(): kotlin.Int
|
||||||
fun `access$getFoo$p`(p: A.Companion): kotlin.Int
|
fun `access$getFoo$p`(p: A.Companion): kotlin.Int
|
||||||
fun `access$getFoo$p`(p: A.Companion): Int = 1
|
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 <set-foo>(<set-?>: kotlin.Int): kotlin.Unit
|
fun <set-foo>(<set-?>: kotlin.Int): kotlin.Unit
|
||||||
fun `access$setFoo$p`(p: A.Companion, d: 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) {}
|
fun `access$setFoo$p`(p: A.Companion, d: Int) {}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class My {
|
||||||
|
val my: String = "O"
|
||||||
|
get() = { field }() + "K"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = My().my
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
+15
@@ -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
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class My {
|
||||||
|
companion object {
|
||||||
|
val my: String = "O"
|
||||||
|
get() = { field }() + "K"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = My.my
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
val my: String = "O"
|
||||||
|
get() = { field }() + "K"
|
||||||
|
|
||||||
|
fun box() = my
|
||||||
+42
@@ -6397,12 +6397,48 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties"), Pattern.compile("^(.+)\\.kt$"), true);
|
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")
|
@TestMetadata("classObjectProperties.kt")
|
||||||
public void testClassObjectProperties() throws Exception {
|
public void testClassObjectProperties() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classObjectProperties.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/classObjectProperties.kt");
|
||||||
doTest(fileName);
|
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")
|
@TestMetadata("field.kt")
|
||||||
public void testField() throws Exception {
|
public void testField() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/field.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/field.kt");
|
||||||
@@ -6421,6 +6457,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("fieldInsideNested.kt")
|
||||||
public void testFieldInsideNested() throws Exception {
|
public void testFieldInsideNested() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/fieldInsideNested.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/fieldInsideNested.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user