J2K backend-common classes: convert
Also merge CodegenUtilKt into CodegenUtil
This commit is contained in:
@@ -14,183 +14,200 @@
|
|||||||
* limitations under the License.
|
* 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.PsiElement;
|
import org.jetbrains.kotlin.backend.common.bridges.findTraitImplementation
|
||||||
import com.intellij.psi.PsiFile;
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.types.isDynamic
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||||
import org.jetbrains.kotlin.types.TypeUtils;
|
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
|
||||||
|
|
||||||
import java.util.*;
|
object CodegenUtil {
|
||||||
|
// class Foo : Bar by baz
|
||||||
|
// descriptor = Foo
|
||||||
|
// toInterface = Bar
|
||||||
|
// delegateExpressionType = typeof(baz)
|
||||||
|
// return Map<member of Foo, corresponding member of typeOf(baz)>
|
||||||
|
@JvmStatic
|
||||||
|
fun getDelegates(
|
||||||
|
descriptor: ClassDescriptor,
|
||||||
|
toInterface: ClassDescriptor,
|
||||||
|
delegateExpressionType: KotlinType? = null
|
||||||
|
): Map<CallableMemberDescriptor, CallableDescriptor> {
|
||||||
|
if (delegateExpressionType?.isDynamic() ?: false) return emptyMap()
|
||||||
|
|
||||||
public class CodegenUtil {
|
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
|
||||||
|
.filterIsInstance<CallableMemberDescriptor>()
|
||||||
|
.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
|
assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
|
||||||
public static FunctionDescriptor getDeclaredFunctionByRawSignature(
|
|
||||||
@NotNull ClassDescriptor owner,
|
|
||||||
@NotNull Name name,
|
|
||||||
@NotNull ClassifierDescriptor returnedClassifier,
|
|
||||||
@NotNull ClassifierDescriptor... valueParameterClassifiers
|
|
||||||
) {
|
|
||||||
Collection<SimpleFunctionDescriptor> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
actualDelegates.firstOrNull()
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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 &&
|
return propertyDescriptor != null &&
|
||||||
!propertyDescriptor.isVar() &&
|
!propertyDescriptor.isVar &&
|
||||||
Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor));
|
(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor) ?: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@JvmStatic
|
||||||
public static Map<FunctionDescriptor, FunctionDescriptor> getNonPrivateTraitMethods(ClassDescriptor descriptor) {
|
fun getNonPrivateTraitMethods(descriptor: ClassDescriptor): Map<FunctionDescriptor, FunctionDescriptor> {
|
||||||
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>();
|
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||||
for (DeclarationDescriptor declaration : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
|
for (declaration in DescriptorUtils.getAllDescriptors(descriptor.defaultType.memberScope)) {
|
||||||
if (!(declaration instanceof CallableMemberDescriptor)) continue;
|
if (declaration !is CallableMemberDescriptor) continue
|
||||||
|
|
||||||
CallableMemberDescriptor inheritedMember = (CallableMemberDescriptor) declaration;
|
val traitMember = findTraitImplementation(declaration)
|
||||||
CallableMemberDescriptor traitMember = ImplKt.findTraitImplementation(inheritedMember);
|
if (traitMember == null || Visibilities.isPrivate(traitMember.visibility)) continue
|
||||||
if (traitMember == null || Visibilities.isPrivate(traitMember.getVisibility())) 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
|
// inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
|
||||||
// with traitMember's modality
|
// with traitMember's modality
|
||||||
result.putAll(copyFunctions(inheritedMember, traitMember, inheritedMember.getContainingDeclaration(), traitMember.getModality(), Visibilities.PUBLIC,
|
result.putAll(copyFunctions(declaration, traitMember, declaration.containingDeclaration, traitMember.modality,
|
||||||
CallableMemberDescriptor.Kind.DECLARATION, true));
|
Visibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, true))
|
||||||
}
|
}
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
fun copyFunctions(
|
||||||
public static Map<FunctionDescriptor, FunctionDescriptor> copyFunctions(
|
inheritedMember: CallableMemberDescriptor,
|
||||||
@NotNull CallableMemberDescriptor inheritedMember,
|
traitMember: CallableMemberDescriptor,
|
||||||
@NotNull CallableMemberDescriptor traitMember,
|
newOwner: DeclarationDescriptor,
|
||||||
DeclarationDescriptor newOwner,
|
modality: Modality,
|
||||||
Modality modality,
|
visibility: Visibility,
|
||||||
Visibility visibility,
|
kind: CallableMemberDescriptor.Kind,
|
||||||
CallableMemberDescriptor.Kind kind,
|
copyOverrides: Boolean
|
||||||
boolean copyOverrides
|
): Map<FunctionDescriptor, FunctionDescriptor> {
|
||||||
) {
|
val copy = inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides)
|
||||||
CallableMemberDescriptor copy = inheritedMember.copy(newOwner, modality, visibility, kind, copyOverrides);
|
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||||
Map<FunctionDescriptor, FunctionDescriptor> result = new LinkedHashMap<FunctionDescriptor, FunctionDescriptor>(0);
|
if (traitMember is SimpleFunctionDescriptor) {
|
||||||
if (traitMember instanceof SimpleFunctionDescriptor) {
|
result[traitMember] = copy as FunctionDescriptor
|
||||||
result.put((FunctionDescriptor) traitMember, (FunctionDescriptor) copy);
|
|
||||||
}
|
}
|
||||||
else if (traitMember instanceof PropertyDescriptor) {
|
else if (traitMember is PropertyDescriptor) {
|
||||||
for (PropertyAccessorDescriptor traitAccessor : ((PropertyDescriptor) traitMember).getAccessors()) {
|
for (traitAccessor in traitMember.accessors) {
|
||||||
for (PropertyAccessorDescriptor inheritedAccessor : ((PropertyDescriptor) copy).getAccessors()) {
|
for (inheritedAccessor in (copy as PropertyDescriptor).accessors) {
|
||||||
if (inheritedAccessor.getClass() == traitAccessor.getClass()) { // same accessor kind
|
if (inheritedAccessor.javaClass == traitAccessor.javaClass) { // same accessor kind
|
||||||
result.put(traitAccessor, inheritedAccessor);
|
result.put(traitAccessor, inheritedAccessor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@JvmStatic
|
||||||
public static ClassDescriptor getSuperClassBySuperTypeListEntry(@NotNull KtSuperTypeListEntry specifier, @NotNull BindingContext bindingContext) {
|
fun getSuperClassBySuperTypeListEntry(specifier: KtSuperTypeListEntry, bindingContext: BindingContext): ClassDescriptor {
|
||||||
KotlinType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
val superType = bindingContext.get(BindingContext.TYPE, specifier.typeReference!!)
|
||||||
assert superType != null : "superType should not be null: " + specifier.getText();
|
?: error("superType should not be null: ${specifier.text}")
|
||||||
|
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
return superType.constructor.declarationDescriptor as? ClassDescriptor
|
||||||
assert superClassDescriptor != null : "superClassDescriptor should not be null: " + specifier.getText();
|
?: error("ClassDescriptor of superType should not be null: ${specifier.text}")
|
||||||
return superClassDescriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean valueParameterClassesMatch(
|
private fun valueParameterClassesMatch(
|
||||||
@NotNull List<ValueParameterDescriptor> parameters,
|
parameters: List<ValueParameterDescriptor>,
|
||||||
@NotNull List<ClassifierDescriptor> classifiers
|
classifiers: List<ClassifierDescriptor>
|
||||||
) {
|
): Boolean {
|
||||||
if (parameters.size() != classifiers.size()) return false;
|
if (parameters.size != classifiers.size) return false
|
||||||
for (int i = 0; i < parameters.size(); i++) {
|
for ((parameterDescriptor, classDescriptor) in parameters.zip(classifiers)) {
|
||||||
ValueParameterDescriptor parameterDescriptor = parameters.get(i);
|
if (!rawTypeMatches(parameterDescriptor.type, classDescriptor)) {
|
||||||
ClassifierDescriptor classDescriptor = classifiers.get(i);
|
return false
|
||||||
if (!rawTypeMatches(parameterDescriptor.getType(), classDescriptor)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean rawTypeMatches(KotlinType type, ClassifierDescriptor classifier) {
|
private fun rawTypeMatches(type: KotlinType, classifier: ClassifierDescriptor): Boolean =
|
||||||
return type.getConstructor().equals(classifier.getTypeConstructor());
|
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) {
|
@JvmStatic
|
||||||
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
|
fun getLineNumberForElement(statement: PsiElement, markEndOffset: Boolean): Int? {
|
||||||
KotlinType nullableString = TypeUtils.makeNullable(DescriptorUtilsKt.getBuiltIns(functionDescriptor).getStringType());
|
val file = statement.containingFile
|
||||||
return DescriptorUtils.ENUM_VALUE_OF.equals(functionDescriptor.getName())
|
if (file is KtFile && file.doNotAnalyze != null) {
|
||||||
&& methodTypeParameters.size() == 1
|
return null
|
||||||
&& 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// 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();
|
val document = file.viewProvider.document
|
||||||
return document != null ? document.getLineNumber(markEndOffset ? statement.getTextRange().getEndOffset() : statement.getTextOffset()) + 1 : null;
|
return document?.getLineNumber(if (markEndOffset) statement.textRange.endOffset else statement.textOffset)?.plus(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<member of Foo, corresponding member of typeOf(baz)>
|
|
||||||
@JvmStatic fun getDelegates(
|
|
||||||
descriptor: ClassDescriptor,
|
|
||||||
toInterface: ClassDescriptor,
|
|
||||||
delegateExpressionType: KotlinType? = null
|
|
||||||
): Map<CallableMemberDescriptor, CallableDescriptor> {
|
|
||||||
if (delegateExpressionType?.isDynamic() ?: false) return mapOf()
|
|
||||||
|
|
||||||
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
|
|
||||||
.filterIsInstance<CallableMemberDescriptor>()
|
|
||||||
.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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+64
-107
@@ -14,158 +14,115 @@
|
|||||||
* limitations under the License.
|
* 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.kotlin.descriptors.*
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.psi.KtClass;
|
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||||
import org.jetbrains.kotlin.psi.KtParameter;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A platform-independent logic for generating data class synthetic methods.
|
* 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
|
* 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 {
|
abstract class DataClassMethodGenerator(private val declaration: KtClassOrObject, private val bindingContext: BindingContext) {
|
||||||
private final KtClassOrObject declaration;
|
protected val classDescriptor: ClassDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration)
|
||||||
private final BindingContext bindingContext;
|
|
||||||
private final ClassDescriptor classDescriptor;
|
|
||||||
private final KotlinBuiltIns builtIns;
|
|
||||||
|
|
||||||
public DataClassMethodGenerator(KtClassOrObject declaration, BindingContext bindingContext) {
|
private val builtIns = classDescriptor.builtIns
|
||||||
this.declaration = declaration;
|
|
||||||
this.bindingContext = bindingContext;
|
|
||||||
this.classDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration);
|
|
||||||
this.builtIns = DescriptorUtilsKt.getBuiltIns(classDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generate() {
|
fun generate() {
|
||||||
generateComponentFunctionsForDataClasses();
|
generateComponentFunctionsForDataClasses()
|
||||||
|
|
||||||
generateCopyFunctionForDataClasses(getPrimaryConstructorParameters());
|
generateCopyFunctionForDataClasses(primaryConstructorParameters)
|
||||||
|
|
||||||
List<PropertyDescriptor> properties = getDataProperties();
|
val properties = dataProperties
|
||||||
if (!properties.isEmpty()) {
|
if (properties.isNotEmpty()) {
|
||||||
generateDataClassToStringIfNeeded(properties);
|
generateDataClassToStringIfNeeded(properties)
|
||||||
generateDataClassHashCodeIfNeeded(properties);
|
generateDataClassHashCodeIfNeeded(properties)
|
||||||
generateDataClassEqualsIfNeeded(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<KtParameter> constructorParameters);
|
protected abstract fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>)
|
||||||
|
|
||||||
protected abstract void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
protected abstract fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||||
|
|
||||||
protected abstract void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
protected abstract fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||||
|
|
||||||
protected abstract void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties);
|
protected abstract fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>)
|
||||||
|
|
||||||
@NotNull
|
private fun generateComponentFunctionsForDataClasses() {
|
||||||
protected ClassDescriptor getClassDescriptor() {
|
|
||||||
return classDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateComponentFunctionsForDataClasses() {
|
|
||||||
ConstructorDescriptor constructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
|
|
||||||
// primary constructor should exist for data classes
|
// primary constructor should exist for data classes
|
||||||
// but when generating light-classes still need to check we have one
|
// 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()) {
|
for (parameter in constructor.valueParameters) {
|
||||||
FunctionDescriptor function = bindingContext.get(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter);
|
val function = bindingContext.get(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter)
|
||||||
if (function != null) {
|
if (function != null) {
|
||||||
generateComponentFunction(function, parameter);
|
generateComponentFunction(function, parameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateCopyFunctionForDataClasses(List<KtParameter> constructorParameters) {
|
private fun generateCopyFunctionForDataClasses(constructorParameters: List<KtParameter>) {
|
||||||
FunctionDescriptor copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor);
|
val copyFunction = bindingContext.get(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor) ?: return
|
||||||
if (copyFunction != null) {
|
generateCopyFunction(copyFunction, constructorParameters)
|
||||||
generateCopyFunction(copyFunction, constructorParameters);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateDataClassToStringIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
private fun generateDataClassToStringIfNeeded(properties: List<PropertyDescriptor>) {
|
||||||
FunctionDescriptor function = getDeclaredMember("toString", builtIns.getString());
|
val function = getDeclaredMember("toString", builtIns.string)
|
||||||
if (function != null && isTrivial(function)) {
|
if (function != null && isTrivial(function)) {
|
||||||
generateToStringMethod(function, properties);
|
generateToStringMethod(function, properties)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateDataClassHashCodeIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
private fun generateDataClassHashCodeIfNeeded(properties: List<PropertyDescriptor>) {
|
||||||
FunctionDescriptor function = getDeclaredMember("hashCode", builtIns.getInt());
|
val function = getDeclaredMember("hashCode", builtIns.int)
|
||||||
if (function != null && isTrivial(function)) {
|
if (function != null && isTrivial(function)) {
|
||||||
generateHashCodeMethod(function, properties);
|
generateHashCodeMethod(function, properties)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateDataClassEqualsIfNeeded(@NotNull List<PropertyDescriptor> properties) {
|
private fun generateDataClassEqualsIfNeeded(properties: List<PropertyDescriptor>) {
|
||||||
FunctionDescriptor function = getDeclaredMember("equals", builtIns.getBoolean(), builtIns.getAny());
|
val function = getDeclaredMember("equals", builtIns.boolean, builtIns.any)
|
||||||
if (function != null && isTrivial(function)) {
|
if (function != null && isTrivial(function)) {
|
||||||
generateEqualsMethod(function, properties);
|
generateEqualsMethod(function, properties)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PropertyDescriptor> getDataProperties() {
|
private val dataProperties: List<PropertyDescriptor>
|
||||||
List<PropertyDescriptor> result = Lists.newArrayList();
|
get() = primaryConstructorParameters
|
||||||
for (KtParameter parameter : getPrimaryConstructorParameters()) {
|
.filter { it.hasValOrVar() }
|
||||||
if (parameter.hasValOrVar()) {
|
.map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! }
|
||||||
result.add(bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
private val primaryConstructorParameters: List<KtParameter>
|
||||||
private List<KtParameter> getPrimaryConstructorParameters() {
|
get() = (declaration as? KtClass)?.getPrimaryConstructorParameters().orEmpty()
|
||||||
if (declaration instanceof KtClass) {
|
|
||||||
return declaration.getPrimaryConstructorParameters();
|
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
private fun getDeclaredMember(
|
||||||
private FunctionDescriptor getDeclaredMember(
|
name: String,
|
||||||
@NotNull String name,
|
returnedClassifier: ClassDescriptor,
|
||||||
@NotNull ClassDescriptor returnedClassifier,
|
vararg valueParameterClassifiers: ClassDescriptor
|
||||||
@NotNull ClassDescriptor... valueParameterClassifiers
|
): FunctionDescriptor? = CodegenUtil.getDeclaredFunctionByRawSignature(
|
||||||
) {
|
classDescriptor, Name.identifier(name), returnedClassifier, *valueParameterClassifiers
|
||||||
return CodegenUtil.getDeclaredFunctionByRawSignature(
|
)
|
||||||
classDescriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the member is an inherited implementation of a method from Any
|
* @return true if the member is an inherited implementation of a method from Any
|
||||||
*/
|
*/
|
||||||
private boolean isTrivial(@NotNull FunctionDescriptor function) {
|
private fun isTrivial(function: FunctionDescriptor): Boolean {
|
||||||
if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
|
return function.kind != CallableMemberDescriptor.Kind.DECLARATION &&
|
||||||
return false;
|
OverrideResolver.getOverriddenDeclarations(function).none { overridden ->
|
||||||
}
|
overridden is CallableMemberDescriptor &&
|
||||||
|
overridden.kind == CallableMemberDescriptor.Kind.DECLARATION &&
|
||||||
for (CallableDescriptor overridden : OverrideResolver.getOverriddenDeclarations(function)) {
|
overridden.containingDeclaration != builtIns.any
|
||||||
if (overridden instanceof CallableMemberDescriptor
|
}
|
||||||
&& ((CallableMemberDescriptor) overridden).getKind() == CallableMemberDescriptor.Kind.DECLARATION
|
|
||||||
&& !overridden.getContainingDeclaration().equals(builtIns.getAny())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import kotlin.jvm.functions.Function2;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
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.backend.common.DataClassMethodGenerator;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
||||||
@@ -496,7 +495,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> properties) {
|
||||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
|
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "equals", "(Ljava/lang/Object;)Z", null, null);
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
@@ -553,7 +552,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> properties) {
|
||||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "hashCode", "()I", null, null);
|
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "hashCode", "()I", null, null);
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
@@ -602,7 +601,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> properties) {
|
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> properties) {
|
||||||
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
MethodContext context = ImplementationBodyCodegen.this.context.intoFunction(function);
|
||||||
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
|
MethodVisitor mv = v.newMethod(JvmDeclarationOriginKt.OtherOrigin(function), ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
@@ -692,7 +691,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateCopyFunction(@NotNull final FunctionDescriptor function, @NotNull List<KtParameter> constructorParameters) {
|
public void generateCopyFunction(
|
||||||
|
@NotNull final FunctionDescriptor function,
|
||||||
|
@NotNull List<? extends KtParameter> constructorParameters
|
||||||
|
) {
|
||||||
final Type thisDescriptorType = typeMapper.mapType(descriptor);
|
final Type thisDescriptorType = typeMapper.mapType(descriptor);
|
||||||
|
|
||||||
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(myClass, function), function, new FunctionGenerationStrategy() {
|
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);
|
fieldInfo.name, fieldInfo.type.getDescriptor(), /*TODO*/null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateDelegates(ClassDescriptor toTrait, KotlinType delegateExpressionType, DelegationFieldsInfo.Field field) {
|
private void generateDelegates(ClassDescriptor toTrait, KotlinType delegateExpressionType, DelegationFieldsInfo.Field field) {
|
||||||
for (Map.Entry<CallableMemberDescriptor, CallableDescriptor> entry : CodegenUtilKt.getDelegates(descriptor, toTrait, delegateExpressionType).entrySet()) {
|
for (Map.Entry<CallableMemberDescriptor, CallableDescriptor> entry :
|
||||||
|
CodegenUtil.getDelegates(descriptor, toTrait, delegateExpressionType).entrySet()) {
|
||||||
CallableMemberDescriptor callableMemberDescriptor = entry.getKey();
|
CallableMemberDescriptor callableMemberDescriptor = entry.getKey();
|
||||||
CallableDescriptor delegateTo = entry.getValue();
|
CallableDescriptor delegateTo = entry.getValue();
|
||||||
if (callableMemberDescriptor instanceof PropertyDescriptor) {
|
if (callableMemberDescriptor instanceof PropertyDescriptor) {
|
||||||
|
|||||||
@@ -82,12 +82,13 @@ class JvmStaticGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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 memberDescriptor = if (descriptor is PropertyAccessorDescriptor) descriptor.correspondingProperty else descriptor
|
||||||
val copies = CodegenUtil.copyFunctions(
|
val copies = CodegenUtil.copyFunctions(
|
||||||
memberDescriptor,
|
memberDescriptor,
|
||||||
memberDescriptor,
|
memberDescriptor,
|
||||||
descriptor.containingDeclaration.containingDeclaration,
|
descriptor.containingDeclaration.containingDeclaration!!,
|
||||||
descriptor.modality,
|
descriptor.modality,
|
||||||
descriptor.visibility,
|
descriptor.visibility,
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
|||||||
+2
-3
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.js.translate.declaration
|
|||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*
|
import com.google.dart.compiler.backend.js.ast.*
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||||
import org.jetbrains.kotlin.backend.common.CodegenUtilKt
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
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.TranslationUtils.translateFunctionAsEcma5PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.js.translate.utils.generateDelegateCall
|
import org.jetbrains.kotlin.js.translate.utils.generateDelegateCall
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtSuperTypeListEntry
|
|
||||||
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
||||||
|
import org.jetbrains.kotlin.psi.KtSuperTypeListEntry
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
|
||||||
class DelegationTranslator(
|
class DelegationTranslator(
|
||||||
@@ -90,7 +89,7 @@ class DelegationTranslator(
|
|||||||
CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext())
|
CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext())
|
||||||
|
|
||||||
private fun generateDelegates(toClass: ClassDescriptor, field: Field, properties: MutableList<JsPropertyInitializer>) {
|
private fun generateDelegates(toClass: ClassDescriptor, field: Field, properties: MutableList<JsPropertyInitializer>) {
|
||||||
for ((descriptor, overriddenDescriptor) in CodegenUtilKt.getDelegates(classDescriptor, toClass)) {
|
for ((descriptor, overriddenDescriptor) in CodegenUtil.getDelegates(classDescriptor, toClass)) {
|
||||||
when (descriptor) {
|
when (descriptor) {
|
||||||
is PropertyDescriptor ->
|
is PropertyDescriptor ->
|
||||||
generateDelegateCallForPropertyMember(descriptor, field.name, properties)
|
generateDelegateCallForPropertyMember(descriptor, field.name, properties)
|
||||||
|
|||||||
+4
-4
@@ -61,7 +61,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List<KtParameter> constructorParameters) {
|
public void generateCopyFunction(@NotNull FunctionDescriptor function, @NotNull List<? extends KtParameter> constructorParameters) {
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
|
|
||||||
assert function.getValueParameters().size() == constructorParameters.size();
|
assert function.getValueParameters().size() == constructorParameters.size();
|
||||||
@@ -110,7 +110,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> classProperties) {
|
public void generateToStringMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
||||||
// TODO: relax this limitation, with the data generation logic fixed.
|
// TODO: relax this limitation, with the data generation logic fixed.
|
||||||
assert !classProperties.isEmpty();
|
assert !classProperties.isEmpty();
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
@@ -136,7 +136,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> classProperties) {
|
public void generateHashCodeMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
|
|
||||||
JsProgram jsProgram = context.program();
|
JsProgram jsProgram = context.program();
|
||||||
@@ -161,7 +161,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<PropertyDescriptor> classProperties) {
|
public void generateEqualsMethod(@NotNull FunctionDescriptor function, @NotNull List<? extends PropertyDescriptor> classProperties) {
|
||||||
assert !classProperties.isEmpty();
|
assert !classProperties.isEmpty();
|
||||||
JsFunction functionObj = generateJsMethod(function);
|
JsFunction functionObj = generateJsMethod(function);
|
||||||
JsFunctionScope funScope = functionObj.getScope();
|
JsFunctionScope funScope = functionObj.getScope();
|
||||||
|
|||||||
Reference in New Issue
Block a user