From c1c26519882ae3a0306afa6ca323f430a90d0088 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 13 Apr 2016 14:53:47 +0300 Subject: [PATCH] J2K backend-common classes: convert Also merge CodegenUtilKt into CodegenUtil --- .../kotlin/backend/common/CodegenUtil.kt | 285 ++++++++++-------- .../kotlin/backend/common/CodegenUtilKt.kt | 74 ----- .../common/DataClassMethodGenerator.kt | 171 ++++------- .../codegen/ImplementationBodyCodegen.java | 17 +- .../kotlin/codegen/JvmStaticGenerator.kt | 5 +- .../declaration/DelegationTranslator.kt | 5 +- .../declaration/JsDataClassGenerator.java | 8 +- 7 files changed, 234 insertions(+), 331 deletions(-) delete mode 100644 compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtilKt.kt diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt index 0ae486ce0fe..b199d206432 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt @@ -14,183 +14,200 @@ * limitations under the License. */ -package org.jetbrains.kotlin.backend.common; +package org.jetbrains.kotlin.backend.common -import com.intellij.openapi.editor.Document; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.backend.common.bridges.ImplKt; -import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.incremental.components.NoLookupLocation; -import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.resolve.BindingContext; -import org.jetbrains.kotlin.resolve.DescriptorUtils; -import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt; -import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; -import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; -import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.kotlin.types.TypeUtils; -import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.backend.common.bridges.findTraitImplementation +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.MemberComparator +import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.checker.KotlinTypeChecker +import org.jetbrains.kotlin.types.isDynamic +import org.jetbrains.kotlin.utils.keysToMapExceptNulls -import java.util.*; +object CodegenUtil { + // class Foo : Bar by baz + // descriptor = Foo + // toInterface = Bar + // delegateExpressionType = typeof(baz) + // return Map + @JvmStatic + fun getDelegates( + descriptor: ClassDescriptor, + toInterface: ClassDescriptor, + delegateExpressionType: KotlinType? = null + ): Map { + if (delegateExpressionType?.isDynamic() ?: false) return emptyMap() -public class CodegenUtil { + return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence() + .filterIsInstance() + .filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION } + .asIterable() + .sortedWith(MemberComparator.INSTANCE) + .keysToMapExceptNulls { delegatingMember -> + val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember) + .mapNotNull { overriddenDescriptor -> + if (overriddenDescriptor.containingDeclaration == toInterface) { + val scope = (delegateExpressionType ?: toInterface.defaultType).memberScope + val name = overriddenDescriptor.name - private CodegenUtil() { - } + // this is the actual member of delegateExpressionType that we are delegating to + (scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + + scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)) + .firstOrNull { + (listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it)) + .map(CallableMemberDescriptor::getOriginal) + .contains(overriddenDescriptor.original) + } + } + else null + } - @Nullable - public static FunctionDescriptor getDeclaredFunctionByRawSignature( - @NotNull ClassDescriptor owner, - @NotNull Name name, - @NotNull ClassifierDescriptor returnedClassifier, - @NotNull ClassifierDescriptor... valueParameterClassifiers - ) { - Collection functions = owner.getDefaultType().getMemberScope().getContributedFunctions(name, NoLookupLocation.FROM_BACKEND); - for (FunctionDescriptor function : functions) { - if (!CallResolverUtilKt.isOrOverridesSynthesized(function) - && function.getTypeParameters().isEmpty() - && valueParameterClassesMatch(function.getValueParameters(), Arrays.asList(valueParameterClassifiers)) - && rawTypeMatches(function.getReturnType(), returnedClassifier)) { - return function; - } - } - return null; - } + assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" } - @Nullable - public static PropertyDescriptor getDelegatePropertyIfAny(KtExpression expression, ClassDescriptor classDescriptor, BindingContext bindingContext) { - PropertyDescriptor propertyDescriptor = null; - if (expression instanceof KtSimpleNameExpression) { - ResolvedCall call = CallUtilKt.getResolvedCall(expression, bindingContext); - if (call != null) { - CallableDescriptor callResultingDescriptor = call.getResultingDescriptor(); - if (callResultingDescriptor instanceof ValueParameterDescriptor) { - ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) callResultingDescriptor; - // constructor parameter - if (valueParameterDescriptor.getContainingDeclaration() instanceof ConstructorDescriptor) { - // constructor of my class - if (valueParameterDescriptor.getContainingDeclaration().getContainingDeclaration() == classDescriptor) { - propertyDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameterDescriptor); - } - } + actualDelegates.firstOrNull() } + } - // todo: when and if frontend will allow properties defined not as constructor parameters to be used in delegation specifier + @JvmStatic + fun getDeclaredFunctionByRawSignature( + owner: ClassDescriptor, + name: Name, + returnedClassifier: ClassifierDescriptor, + vararg valueParameterClassifiers: ClassifierDescriptor + ): FunctionDescriptor? { + return owner.defaultType.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).firstOrNull { function -> + !isOrOverridesSynthesized(function) && + function.typeParameters.isEmpty() && + valueParameterClassesMatch(function.valueParameters, valueParameterClassifiers.toList()) && + rawTypeMatches(function.returnType!!, returnedClassifier) + } + } + + @JvmStatic + fun getDelegatePropertyIfAny( + expression: KtExpression, classDescriptor: ClassDescriptor, bindingContext: BindingContext + ): PropertyDescriptor? { + val call = (expression as? KtSimpleNameExpression)?.getResolvedCall(bindingContext) ?: return null + val callResultingDescriptor = call.resultingDescriptor as? ValueParameterDescriptor ?: return null + // constructor parameter + if (callResultingDescriptor.containingDeclaration is ConstructorDescriptor) { + // constructor of my class + if (callResultingDescriptor.containingDeclaration.containingDeclaration === classDescriptor) { + return bindingContext.get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, callResultingDescriptor) } } - return propertyDescriptor; + return null } - public static boolean isFinalPropertyWithBackingField(PropertyDescriptor propertyDescriptor, BindingContext bindingContext) { + @JvmStatic + fun isFinalPropertyWithBackingField(propertyDescriptor: PropertyDescriptor?, bindingContext: BindingContext): Boolean { return propertyDescriptor != null && - !propertyDescriptor.isVar() && - Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)); + !propertyDescriptor.isVar && + (bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor) ?: false) } - @NotNull - public static Map getNonPrivateTraitMethods(ClassDescriptor descriptor) { - Map result = new LinkedHashMap(); - for (DeclarationDescriptor declaration : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) { - if (!(declaration instanceof CallableMemberDescriptor)) continue; + @JvmStatic + fun getNonPrivateTraitMethods(descriptor: ClassDescriptor): Map { + val result = linkedMapOf() + for (declaration in DescriptorUtils.getAllDescriptors(descriptor.defaultType.memberScope)) { + if (declaration !is CallableMemberDescriptor) continue - CallableMemberDescriptor inheritedMember = (CallableMemberDescriptor) declaration; - CallableMemberDescriptor traitMember = ImplKt.findTraitImplementation(inheritedMember); - if (traitMember == null || Visibilities.isPrivate(traitMember.getVisibility())) continue; + val traitMember = findTraitImplementation(declaration) + if (traitMember == null || Visibilities.isPrivate(traitMember.visibility)) continue - assert traitMember.getModality() != Modality.ABSTRACT : "Cannot delegate to abstract trait method: " + inheritedMember; + assert(traitMember.modality !== Modality.ABSTRACT) { "Cannot delegate to abstract trait method: $declaration" } // inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here // with traitMember's modality - result.putAll(copyFunctions(inheritedMember, traitMember, inheritedMember.getContainingDeclaration(), traitMember.getModality(), Visibilities.PUBLIC, - CallableMemberDescriptor.Kind.DECLARATION, true)); + result.putAll(copyFunctions(declaration, traitMember, declaration.containingDeclaration, traitMember.modality, + Visibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, true)) } - return result; + return result } - @NotNull - public static Map copyFunctions( - @NotNull CallableMemberDescriptor inheritedMember, - @NotNull CallableMemberDescriptor traitMember, - DeclarationDescriptor newOwner, - Modality modality, - Visibility visibility, - CallableMemberDescriptor.Kind kind, - boolean copyOverrides - ) { - CallableMemberDescriptor copy = inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides); - Map result = new LinkedHashMap(0); - if (traitMember instanceof SimpleFunctionDescriptor) { - result.put((FunctionDescriptor) traitMember, (FunctionDescriptor) copy); + fun copyFunctions( + inheritedMember: CallableMemberDescriptor, + traitMember: CallableMemberDescriptor, + newOwner: DeclarationDescriptor, + modality: Modality, + visibility: Visibility, + kind: CallableMemberDescriptor.Kind, + copyOverrides: Boolean + ): Map { + val copy = inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides) + val result = linkedMapOf() + if (traitMember is SimpleFunctionDescriptor) { + result[traitMember] = copy as FunctionDescriptor } - else if (traitMember instanceof PropertyDescriptor) { - for (PropertyAccessorDescriptor traitAccessor : ((PropertyDescriptor) traitMember).getAccessors()) { - for (PropertyAccessorDescriptor inheritedAccessor : ((PropertyDescriptor) copy).getAccessors()) { - if (inheritedAccessor.getClass() == traitAccessor.getClass()) { // same accessor kind - result.put(traitAccessor, inheritedAccessor); + else if (traitMember is PropertyDescriptor) { + for (traitAccessor in traitMember.accessors) { + for (inheritedAccessor in (copy as PropertyDescriptor).accessors) { + if (inheritedAccessor.javaClass == traitAccessor.javaClass) { // same accessor kind + result.put(traitAccessor, inheritedAccessor) } } } } - return result; + return result } - @NotNull - public static ClassDescriptor getSuperClassBySuperTypeListEntry(@NotNull KtSuperTypeListEntry specifier, @NotNull BindingContext bindingContext) { - KotlinType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference()); - assert superType != null : "superType should not be null: " + specifier.getText(); + @JvmStatic + fun getSuperClassBySuperTypeListEntry(specifier: KtSuperTypeListEntry, bindingContext: BindingContext): ClassDescriptor { + val superType = bindingContext.get(BindingContext.TYPE, specifier.typeReference!!) + ?: error("superType should not be null: ${specifier.text}") - ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); - assert superClassDescriptor != null : "superClassDescriptor should not be null: " + specifier.getText(); - return superClassDescriptor; + return superType.constructor.declarationDescriptor as? ClassDescriptor + ?: error("ClassDescriptor of superType should not be null: ${specifier.text}") } - private static boolean valueParameterClassesMatch( - @NotNull List parameters, - @NotNull List classifiers - ) { - if (parameters.size() != classifiers.size()) return false; - for (int i = 0; i < parameters.size(); i++) { - ValueParameterDescriptor parameterDescriptor = parameters.get(i); - ClassifierDescriptor classDescriptor = classifiers.get(i); - if (!rawTypeMatches(parameterDescriptor.getType(), classDescriptor)) { - return false; + private fun valueParameterClassesMatch( + parameters: List, + classifiers: List + ): Boolean { + if (parameters.size != classifiers.size) return false + for ((parameterDescriptor, classDescriptor) in parameters.zip(classifiers)) { + if (!rawTypeMatches(parameterDescriptor.type, classDescriptor)) { + return false } } - return true; + return true } - private static boolean rawTypeMatches(KotlinType type, ClassifierDescriptor classifier) { - return type.getConstructor().equals(classifier.getTypeConstructor()); + private fun rawTypeMatches(type: KotlinType, classifier: ClassifierDescriptor): Boolean = + type.constructor == classifier.typeConstructor + + @JvmStatic + fun isEnumValueOfMethod(functionDescriptor: FunctionDescriptor): Boolean { + val methodTypeParameters = functionDescriptor.valueParameters + val nullableString = TypeUtils.makeNullable(functionDescriptor.builtIns.stringType) + return DescriptorUtils.ENUM_VALUE_OF == functionDescriptor.name + && methodTypeParameters.size == 1 + && KotlinTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters[0].type, nullableString) } - public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) { - List methodTypeParameters = functionDescriptor.getValueParameters(); - KotlinType nullableString = TypeUtils.makeNullable(DescriptorUtilsKt.getBuiltIns(functionDescriptor).getStringType()); - return DescriptorUtils.ENUM_VALUE_OF.equals(functionDescriptor.getName()) - && methodTypeParameters.size() == 1 - && KotlinTypeChecker.DEFAULT.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString); - } - - @Nullable - public static Integer getLineNumberForElement(@NotNull PsiElement statement, boolean markEndOffset) { - PsiFile file = statement.getContainingFile(); - if (file instanceof KtFile) { - if (KtPsiFactoryKt.getDoNotAnalyze((KtFile) file) != null) { - return null; - } + @JvmStatic + fun getLineNumberForElement(statement: PsiElement, markEndOffset: Boolean): Int? { + val file = statement.containingFile + if (file is KtFile && file.doNotAnalyze != null) { + return null } - if (statement instanceof KtConstructorDelegationReferenceExpression && statement.getTextLength() == 0) { + if (statement is KtConstructorDelegationReferenceExpression && statement.textLength == 0) { // PsiElement for constructor delegation reference is always generated, so we shouldn't mark it's line number if it's empty - return null; + return null } - Document document = file.getViewProvider().getDocument(); - return document != null ? document.getLineNumber(markEndOffset ? statement.getTextRange().getEndOffset() : statement.getTextOffset()) + 1 : null; + val document = file.viewProvider.document + return document?.getLineNumber(if (markEndOffset) statement.textRange.endOffset else statement.textOffset)?.plus(1) } } diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtilKt.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtilKt.kt deleted file mode 100644 index 02914f3e739..00000000000 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtilKt.kt +++ /dev/null @@ -1,74 +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.backend.common - -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.MemberComparator -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.isDynamic -import org.jetbrains.kotlin.utils.keysToMapExceptNulls -import java.util.Comparator - -object CodegenUtilKt { - - // class Foo : Bar by baz - // descriptor = Foo - // toInterface = Bar - // delegateExpressionType = typeof(baz) - // return Map - @JvmStatic fun getDelegates( - descriptor: ClassDescriptor, - toInterface: ClassDescriptor, - delegateExpressionType: KotlinType? = null - ): Map { - if (delegateExpressionType?.isDynamic() ?: false) return mapOf() - - return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence() - .filterIsInstance() - .filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION } - .asIterable() - .sortedWith(MemberComparator.INSTANCE) - .keysToMapExceptNulls { - delegatingMember -> - - val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember) - .mapNotNull { - overriddenDescriptor -> - if (overriddenDescriptor.containingDeclaration == toInterface) { - val scope = (delegateExpressionType ?: toInterface.defaultType).memberScope - val name = overriddenDescriptor.name - - // this is the actual member of delegateExpressionType that we are delegating to - (scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND)) - .firstOrNull { - (listOf(it) + DescriptorUtils.getAllOverriddenDescriptors(it)) - .map { it.original } - .contains(overriddenDescriptor.original) - } - } - else null - } - assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" } - - actualDelegates.firstOrNull() - } - } -} diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/DataClassMethodGenerator.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/DataClassMethodGenerator.kt index 5b9c978b44f..5d345f52951 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/DataClassMethodGenerator.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/DataClassMethodGenerator.kt @@ -14,158 +14,115 @@ * limitations under the License. */ -package org.jetbrains.kotlin.backend.common; +package org.jetbrains.kotlin.backend.common -import com.google.common.collect.Lists; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; -import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.psi.KtClass; -import org.jetbrains.kotlin.psi.KtClassOrObject; -import org.jetbrains.kotlin.psi.KtParameter; -import org.jetbrains.kotlin.resolve.BindingContext; -import org.jetbrains.kotlin.resolve.BindingContextUtils; -import org.jetbrains.kotlin.resolve.OverrideResolver; -import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; - -import java.util.Collections; -import java.util.List; +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingContextUtils +import org.jetbrains.kotlin.resolve.OverrideResolver +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns /** * A platform-independent logic for generating data class synthetic methods. * TODO: data class with zero components gets no toString/equals/hashCode methods. This is inconsistent and should be - * changed here with the platform backends adopted. + * changed here with the platform backends adopted. */ -public abstract class DataClassMethodGenerator { - private final KtClassOrObject declaration; - private final BindingContext bindingContext; - private final ClassDescriptor classDescriptor; - private final KotlinBuiltIns builtIns; +abstract class DataClassMethodGenerator(private val declaration: KtClassOrObject, private val bindingContext: BindingContext) { + protected val classDescriptor: ClassDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration) - public DataClassMethodGenerator(KtClassOrObject declaration, BindingContext bindingContext) { - this.declaration = declaration; - this.bindingContext = bindingContext; - this.classDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration); - this.builtIns = DescriptorUtilsKt.getBuiltIns(classDescriptor); - } + private val builtIns = classDescriptor.builtIns - public void generate() { - generateComponentFunctionsForDataClasses(); + fun generate() { + generateComponentFunctionsForDataClasses() - generateCopyFunctionForDataClasses(getPrimaryConstructorParameters()); + generateCopyFunctionForDataClasses(primaryConstructorParameters) - List properties = getDataProperties(); - if (!properties.isEmpty()) { - generateDataClassToStringIfNeeded(properties); - generateDataClassHashCodeIfNeeded(properties); - generateDataClassEqualsIfNeeded(properties); + val properties = dataProperties + if (properties.isNotEmpty()) { + generateDataClassToStringIfNeeded(properties) + generateDataClassHashCodeIfNeeded(properties) + generateDataClassEqualsIfNeeded(properties) } } - protected abstract void generateComponentFunction(@NotNull FunctionDescriptor function, @NotNull ValueParameterDescriptor parameter); + protected abstract fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) - protected abstract void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List constructorParameters); + protected abstract fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List) - protected abstract void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List properties); + protected abstract fun generateToStringMethod(function: FunctionDescriptor, properties: List) - protected abstract void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List properties); + protected abstract fun generateHashCodeMethod(function: FunctionDescriptor, properties: List) - protected abstract void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List properties); + protected abstract fun generateEqualsMethod(function: FunctionDescriptor, properties: List) - @NotNull - protected ClassDescriptor getClassDescriptor() { - return classDescriptor; - } - - private void generateComponentFunctionsForDataClasses() { - ConstructorDescriptor constructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); + private fun generateComponentFunctionsForDataClasses() { // primary constructor should exist for data classes // but when generating light-classes still need to check we have one - if (constructor == null) return; + val constructor = classDescriptor.unsubstitutedPrimaryConstructor ?: return - for (ValueParameterDescriptor parameter : constructor.getValueParameters()) { - FunctionDescriptor function = bindingContext.get(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter); + for (parameter in constructor.valueParameters) { + val function = bindingContext.get(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter) if (function != null) { - generateComponentFunction(function, parameter); + generateComponentFunction(function, parameter) } } } - private void generateCopyFunctionForDataClasses(List constructorParameters) { - FunctionDescriptor copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor); - if (copyFunction != null) { - generateCopyFunction(copyFunction, constructorParameters); - } + private fun generateCopyFunctionForDataClasses(constructorParameters: List) { + val copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor) ?: return + generateCopyFunction(copyFunction, constructorParameters) } - private void generateDataClassToStringIfNeeded(@NotNull List properties) { - FunctionDescriptor function = getDeclaredMember("toString", builtIns.getString()); + private fun generateDataClassToStringIfNeeded(properties: List) { + val function = getDeclaredMember("toString", builtIns.string) if (function != null && isTrivial(function)) { - generateToStringMethod(function, properties); + generateToStringMethod(function, properties) } } - private void generateDataClassHashCodeIfNeeded(@NotNull List properties) { - FunctionDescriptor function = getDeclaredMember("hashCode", builtIns.getInt()); + private fun generateDataClassHashCodeIfNeeded(properties: List) { + val function = getDeclaredMember("hashCode", builtIns.int) if (function != null && isTrivial(function)) { - generateHashCodeMethod(function, properties); + generateHashCodeMethod(function, properties) } } - private void generateDataClassEqualsIfNeeded(@NotNull List properties) { - FunctionDescriptor function = getDeclaredMember("equals", builtIns.getBoolean(), builtIns.getAny()); + private fun generateDataClassEqualsIfNeeded(properties: List) { + val function = getDeclaredMember("equals", builtIns.boolean, builtIns.any) if (function != null && isTrivial(function)) { - generateEqualsMethod(function, properties); + generateEqualsMethod(function, properties) } } - private List getDataProperties() { - List result = Lists.newArrayList(); - for (KtParameter parameter : getPrimaryConstructorParameters()) { - if (parameter.hasValOrVar()) { - result.add(bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter)); - } - } - return result; - } + private val dataProperties: List + get() = primaryConstructorParameters + .filter { it.hasValOrVar() } + .map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! } - @NotNull - private List getPrimaryConstructorParameters() { - if (declaration instanceof KtClass) { - return declaration.getPrimaryConstructorParameters(); - } - return Collections.emptyList(); - } + private val primaryConstructorParameters: List + get() = (declaration as? KtClass)?.getPrimaryConstructorParameters().orEmpty() - @Nullable - private FunctionDescriptor getDeclaredMember( - @NotNull String name, - @NotNull ClassDescriptor returnedClassifier, - @NotNull ClassDescriptor... valueParameterClassifiers - ) { - return CodegenUtil.getDeclaredFunctionByRawSignature( - classDescriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers - ); - } + private fun getDeclaredMember( + name: String, + returnedClassifier: ClassDescriptor, + vararg valueParameterClassifiers: ClassDescriptor + ): FunctionDescriptor? = CodegenUtil.getDeclaredFunctionByRawSignature( + classDescriptor, Name.identifier(name), returnedClassifier, *valueParameterClassifiers + ) /** * @return true if the member is an inherited implementation of a method from Any */ - private boolean isTrivial(@NotNull FunctionDescriptor function) { - if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) { - return false; - } - - for (CallableDescriptor overridden : OverrideResolver.getOverriddenDeclarations(function)) { - if (overridden instanceof CallableMemberDescriptor - && ((CallableMemberDescriptor) overridden).getKind() == CallableMemberDescriptor.Kind.DECLARATION - && !overridden.getContainingDeclaration().equals(builtIns.getAny())) { - return false; - } - } - - return true; + private fun isTrivial(function: FunctionDescriptor): Boolean { + return function.kind != CallableMemberDescriptor.Kind.DECLARATION && + OverrideResolver.getOverriddenDeclarations(function).none { overridden -> + overridden is CallableMemberDescriptor && + overridden.kind == CallableMemberDescriptor.Kind.DECLARATION && + overridden.containingDeclaration != builtIns.any + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 79e6cf823ab..cbe6ccf8ecd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -27,7 +27,6 @@ import kotlin.jvm.functions.Function2; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.CodegenUtil; -import org.jetbrains.kotlin.backend.common.CodegenUtilKt; import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.codegen.binding.MutableClosure; @@ -496,7 +495,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } @Override - public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List properties) { + public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List properties) { MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function); MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null); InstructionAdapter iv = new InstructionAdapter(mv); @@ -553,7 +552,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } @Override - public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List properties) { + public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List properties) { MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function); MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "hashCode", "()I", null, null); InstructionAdapter iv = new InstructionAdapter(mv); @@ -602,7 +601,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } @Override - public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List properties) { + public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List properties) { MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function); MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); InstructionAdapter iv = new InstructionAdapter(mv); @@ -692,7 +691,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } @Override - public void generateCopyFunction(@NotNull final FunctionDescriptor function, @NotNull List constructorParameters) { + public void generateCopyFunction( + @NotNull final FunctionDescriptor function, + @NotNull List constructorParameters + ) { final Type thisDescriptorType = typeMapper.mapType(descriptor); functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(myClass, function), function, new FunctionGenerationStrategy() { @@ -1640,8 +1642,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { fieldInfo.name, fieldInfo.type.getDescriptor(), /*TODO*/null, null); } - protected void generateDelegates(ClassDescriptor toTrait, KotlinType delegateExpressionType, DelegationFieldsInfo.Field field) { - for (Map.Entry entry : CodegenUtilKt.getDelegates(descriptor, toTrait, delegateExpressionType).entrySet()) { + private void generateDelegates(ClassDescriptor toTrait, KotlinType delegateExpressionType, DelegationFieldsInfo.Field field) { + for (Map.Entry entry : + CodegenUtil.getDelegates(descriptor, toTrait, delegateExpressionType).entrySet()) { CallableMemberDescriptor callableMemberDescriptor = entry.getKey(); CallableDescriptor delegateTo = entry.getValue(); if (callableMemberDescriptor instanceof PropertyDescriptor) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt index 4dc2ab4347f..02849909cce 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt @@ -82,12 +82,13 @@ class JvmStaticGenerator( } companion object { - @JvmStatic fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor { + @JvmStatic + fun createStaticFunctionDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor { val memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.correspondingProperty else descriptor val copies = CodegenUtil.copyFunctions( memberDescriptor, memberDescriptor, - descriptor.containingDeclaration.containingDeclaration, + descriptor.containingDeclaration.containingDeclaration!!, descriptor.modality, descriptor.visibility, CallableMemberDescriptor.Kind.SYNTHESIZED, diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DelegationTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DelegationTranslator.kt index c3c4a4a3b67..22fc9b97c06 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DelegationTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DelegationTranslator.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.js.translate.declaration import com.google.dart.compiler.backend.js.ast.* import org.jetbrains.kotlin.backend.common.CodegenUtil -import org.jetbrains.kotlin.backend.common.CodegenUtilKt import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.TranslationContext @@ -32,8 +31,8 @@ import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.simpleReturnFunc import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.translateFunctionAsEcma5PropertyDescriptor import org.jetbrains.kotlin.js.translate.utils.generateDelegateCall import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtSuperTypeListEntry import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry +import org.jetbrains.kotlin.psi.KtSuperTypeListEntry import org.jetbrains.kotlin.resolve.DescriptorUtils class DelegationTranslator( @@ -90,7 +89,7 @@ class DelegationTranslator( CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext()) private fun generateDelegates(toClass: ClassDescriptor, field: Field, properties: MutableList) { - for ((descriptor, overriddenDescriptor) in CodegenUtilKt.getDelegates(classDescriptor, toClass)) { + for ((descriptor, overriddenDescriptor) in CodegenUtil.getDelegates(classDescriptor, toClass)) { when (descriptor) { is PropertyDescriptor -> generateDelegateCallForPropertyMember(descriptor, field.name, properties) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java index a6667a9d70e..9fddfc97885 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java @@ -61,7 +61,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { } @Override - public void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List constructorParameters) { + public void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List constructorParameters) { JsFunction functionObj = generateJsMethod(function); assert function.getValueParameters().size() == constructorParameters.size(); @@ -110,7 +110,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { } @Override - public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List classProperties) { + public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List classProperties) { // TODO: relax this limitation, with the data generation logic fixed. assert !classProperties.isEmpty(); JsFunction functionObj = generateJsMethod(function); @@ -136,7 +136,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { } @Override - public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List classProperties) { + public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List classProperties) { JsFunction functionObj = generateJsMethod(function); JsProgram jsProgram = context.program(); @@ -161,7 +161,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { } @Override - public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List classProperties) { + public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List classProperties) { assert !classProperties.isEmpty(); JsFunction functionObj = generateJsMethod(function); JsFunctionScope funScope = functionObj.getScope();