From 27b8b209e3078675ff545ef914f459b76565dfc2 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 14 Jul 2017 13:46:27 +0300 Subject: [PATCH] Refactor accessors for backing fields in JVM back-end --- .../AccessorForPropertyBackingField.kt | 25 +++++++--- ...ccessorForPropertyBackingFieldFromLocal.kt | 28 ----------- ...ForPropertyBackingFieldInClassCompanion.kt | 27 ---------- .../kotlin/codegen/MemberCodegen.java | 5 +- .../codegen/context/CodegenContext.java | 49 +++++++++---------- .../kotlin/codegen/syntheticAccessorUtil.kt | 13 +++-- 6 files changed, 49 insertions(+), 98 deletions(-) delete mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt delete mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInClassCompanion.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt index 48bd75a4da3..1491ca4f951 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingField.kt @@ -19,13 +19,22 @@ 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 +class AccessorForPropertyBackingField( + property: PropertyDescriptor, + containingDeclaration: DeclarationDescriptor, + delegateType: KotlinType?, + extensionReceiverParameter: ReceiverParameterDescriptor?, + dispatchReceiverParameter: ReceiverParameterDescriptor?, + nameSuffix: String, + val fieldAccessorKind: FieldAccessorKind +) : AccessorForPropertyDescriptor( + property, + delegateType ?: property.type, + extensionReceiverParameter?.type, + dispatchReceiverParameter, + containingDeclaration, + null, + nameSuffix +) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt deleted file mode 100644 index a11b1eefeb7..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldFromLocal.kt +++ /dev/null @@ -1,28 +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.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 deleted file mode 100644 index e99fea586f2..00000000000 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForPropertyBackingFieldInClassCompanion.kt +++ /dev/null @@ -1,27 +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.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/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 7c0a3b0858a..57fa3647307 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -738,6 +738,7 @@ public abstract class MemberCodegen { AccessorKey key = new AccessorKey(descriptor, superCallTarget); // NB should check for property accessor factory first (or change property accessor tracking under propertyAccessorFactory creation) - AccessorForPropertyDescriptorFactory propertyAccessorFactory = propertyAccessorFactories.get(key); - if (propertyAccessorFactory != null) { - return (D) propertyAccessorFactory.getOrCreateAccessorIfNeeded(getterAccessorRequired, setterAccessorRequired); + if (propertyAccessorFactories.containsKey(key)) { + return (D) propertyAccessorFactories.get(key).getOrCreateAccessorIfNeeded(getterAccessorRequired, setterAccessorRequired); } - AccessorForCallableDescriptor accessor = accessors.get(key); - if (accessor != null) { + + if (accessors.containsKey(key)) { + AccessorForCallableDescriptor accessor = accessors.get(key); 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, accessorKind); + AccessorForCallableDescriptor accessor; if (descriptor instanceof SimpleFunctionDescriptor) { - accessor = new AccessorForFunctionDescriptor( - (FunctionDescriptor) descriptor, contextDescriptor, superCallTarget, nameSuffix - ); + accessor = new AccessorForFunctionDescriptor((FunctionDescriptor) descriptor, contextDescriptor, superCallTarget, nameSuffix); } else if (descriptor instanceof ClassConstructorDescriptor) { accessor = new AccessorForConstructorDescriptor((ClassConstructorDescriptor) descriptor, contextDescriptor, superCallTarget); } else if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - switch (accessorKind) { - case NORMAL: - propertyAccessorFactory = new AccessorForPropertyDescriptorFactory((PropertyDescriptor) descriptor, contextDescriptor, - superCallTarget, nameSuffix); - propertyAccessorFactories.put(key, propertyAccessorFactory); + if (accessorKind == FieldAccessorKind.NORMAL) { + AccessorForPropertyDescriptorFactory factory = + new AccessorForPropertyDescriptorFactory(propertyDescriptor, contextDescriptor, superCallTarget, nameSuffix); + propertyAccessorFactories.put(key, factory); - // Record worst case accessor for accessor methods generation. - AccessorForPropertyDescriptor accessorWithGetterAndSetter = - propertyAccessorFactory.getOrCreateAccessorWithSyntheticGetterAndSetter(); - accessors.put(key, accessorWithGetterAndSetter); + // Record worst case accessor for accessor methods generation. + accessors.put(key, factory.getOrCreateAccessorWithSyntheticGetterAndSetter()); - PropertyDescriptor accessorDescriptor = - propertyAccessorFactory.getOrCreateAccessorIfNeeded(getterAccessorRequired, setterAccessorRequired); - return (D) accessorDescriptor; - case IN_CLASS_COMPANION: - accessor = new AccessorForPropertyBackingFieldInClassCompanion(propertyDescriptor, contextDescriptor, - delegateType, nameSuffix); - break; - case FIELD_FROM_LOCAL: - accessor = new AccessorForPropertyBackingFieldFromLocal(propertyDescriptor, contextDescriptor, nameSuffix); - break; + return (D) factory.getOrCreateAccessorIfNeeded(getterAccessorRequired, setterAccessorRequired); } + + accessor = new AccessorForPropertyBackingField( + propertyDescriptor, contextDescriptor, delegateType, + accessorKind == FieldAccessorKind.IN_CLASS_COMPANION ? null : propertyDescriptor.getExtensionReceiverParameter(), + accessorKind == FieldAccessorKind.IN_CLASS_COMPANION ? null : propertyDescriptor.getDispatchReceiverParameter(), + nameSuffix, accessorKind + ); } else { throw new UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt index 4d7a8b1b30e..685bac7a3ff 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/syntheticAccessorUtil.kt @@ -22,26 +22,25 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils enum class FieldAccessorKind(val suffix: String) { NORMAL("p"), IN_CLASS_COMPANION("cp"), - FIELD_FROM_LOCAL("lp"); - - override fun toString() = suffix + FIELD_FROM_LOCAL("lp"), } private fun CallableMemberDescriptor.getJvmName() = DescriptorUtils.getJvmName(this) ?: name.asString() -fun getAccessorNameSuffix(descriptor: CallableMemberDescriptor, superCallDescriptor: ClassDescriptor?, - accessorKind: FieldAccessorKind): String { +fun getAccessorNameSuffix( + descriptor: CallableMemberDescriptor, superCallDescriptor: ClassDescriptor?, accessorKind: FieldAccessorKind +): String { val suffix = when (descriptor) { is ConstructorDescriptor -> return "will be ignored" is SimpleFunctionDescriptor -> descriptor.getJvmName() is PropertyDescriptor -> - descriptor.getJvmName() + "$" + accessorKind + descriptor.getJvmName() + "$" + accessorKind.suffix else -> throw UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor) } return if (superCallDescriptor == null) suffix else "$suffix\$s${superCallDescriptor.name.asString().hashCode()}" -} \ No newline at end of file +}