JS backend: support for bridge methods

This commit is contained in:
Michael Nedzelsky
2014-10-02 15:26:02 +04:00
parent 541786a4db
commit 6d1b89bba3
@@ -19,13 +19,13 @@ package org.jetbrains.k2js.translate.declaration;
import com.google.dart.compiler.backend.js.ast.*;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.jet.codegen.bridges.Bridge;
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -37,6 +37,7 @@ import org.jetbrains.k2js.translate.expression.ExpressionPackage;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
import org.jetbrains.k2js.translate.utils.JsAstUtils;
import org.jetbrains.k2js.translate.utils.UtilsPackage;
import java.util.*;
@@ -48,6 +49,7 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescrip
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getPrimaryConstructorParameters;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.simpleReturnFunction;
import static org.jetbrains.k2js.translate.utils.UtilsPackage.*;
/**
* Generates a definition of a single class.
@@ -145,6 +147,14 @@ public final class ClassTranslator extends AbstractTranslator {
invocationArguments.add(function);
}
if (!DescriptorUtils.isTrait(descriptor)) {
for (DeclarationDescriptor memberDescriptor : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
if (memberDescriptor instanceof FunctionDescriptor) {
generateBridges((FunctionDescriptor) memberDescriptor, properties);
}
}
}
boolean hasStaticProperties = !staticProperties.isEmpty();
if (!properties.isEmpty() || hasStaticProperties) {
if (properties.isEmpty()) {
@@ -248,4 +258,37 @@ public final class ClassTranslator extends AbstractTranslator {
return ExpressionPackage.withCapturedParameters(fun, funContext, outerClassContext, descriptor);
}
private void generateBridges(
@NotNull FunctionDescriptor descriptor,
@NotNull List<JsPropertyInitializer> properties
) {
Set<Bridge<FunctionDescriptor>> bridgesToGenerate =
BridgesPackage.generateBridgesForFunctionDescriptor(descriptor, UtilsPackage.<FunctionDescriptor>getID());
for (Bridge<FunctionDescriptor> bridge : bridgesToGenerate) {
generateBridge(bridge, properties);
}
}
private void generateBridge(
@NotNull Bridge<FunctionDescriptor> bridge,
@NotNull List<JsPropertyInitializer> properties
) {
FunctionDescriptor fromDescriptor = bridge.getFrom();
FunctionDescriptor toDescriptor = bridge.getTo();
if (areNamesEqual(fromDescriptor, toDescriptor)) return;
if (fromDescriptor.getKind().isReal() &&
fromDescriptor.getModality() != Modality.ABSTRACT &&
!toDescriptor.getKind().isReal()) return;
properties.add(generateDelegateCall(fromDescriptor, toDescriptor, JsLiteral.THIS, context()));
}
private boolean areNamesEqual(@NotNull FunctionDescriptor first, @NotNull FunctionDescriptor second) {
JsName firstName = context().getNameForDescriptor(first);
JsName secondName = context().getNameForDescriptor(second);
return firstName.getIdent().equals(secondName.getIdent());
}
}