JS backend: support for reflection
This commit is contained in:
@@ -7,6 +7,7 @@ package com.google.dart.compiler.backend.js.ast;
|
|||||||
import gnu.trove.TDoubleObjectHashMap;
|
import gnu.trove.TDoubleObjectHashMap;
|
||||||
import gnu.trove.THashMap;
|
import gnu.trove.THashMap;
|
||||||
import gnu.trove.TIntObjectHashMap;
|
import gnu.trove.TIntObjectHashMap;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -91,6 +92,7 @@ public final class JsProgram extends SourceInfoAwareJsNode {
|
|||||||
/**
|
/**
|
||||||
* Creates or retrieves a JsStringLiteral from an interned object pool.
|
* Creates or retrieves a JsStringLiteral from an interned object pool.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
public JsStringLiteral getStringLiteral(String value) {
|
public JsStringLiteral getStringLiteral(String value) {
|
||||||
JsStringLiteral literal = stringLiteralMap.get(value);
|
JsStringLiteral literal = stringLiteralMap.get(value);
|
||||||
if (literal == null) {
|
if (literal == null) {
|
||||||
|
|||||||
+10
-3
@@ -34,6 +34,8 @@ import org.jetbrains.k2js.translate.reference.CallArgumentTranslator
|
|||||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
|
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.jet.lang.descriptors.Visibilities
|
import org.jetbrains.jet.lang.descriptors.Visibilities
|
||||||
import org.jetbrains.jet.lang.psi.Call.CallType
|
import org.jetbrains.jet.lang.psi.Call.CallType
|
||||||
|
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||||
|
|
||||||
public fun addReceiverToArgs(receiver: JsExpression, arguments: List<JsExpression>): List<JsExpression> {
|
public fun addReceiverToArgs(receiver: JsExpression, arguments: List<JsExpression>): List<JsExpression> {
|
||||||
if (arguments.isEmpty())
|
if (arguments.isEmpty())
|
||||||
@@ -143,10 +145,15 @@ object InvokeIntrinsic : FunctionCallCase {
|
|||||||
return false
|
return false
|
||||||
val parameterCount = callInfo.callableDescriptor.getValueParameters().size()
|
val parameterCount = callInfo.callableDescriptor.getValueParameters().size()
|
||||||
val funDeclaration = callInfo.callableDescriptor.getContainingDeclaration()
|
val funDeclaration = callInfo.callableDescriptor.getContainingDeclaration()
|
||||||
return funDeclaration == ((if (callInfo.callableDescriptor.getReceiverParameter() == null)
|
|
||||||
KotlinBuiltIns.getInstance().getFunction(parameterCount)
|
val reflectionTypes = callInfo.context.getReflectionTypes()
|
||||||
|
return if (callInfo.callableDescriptor.getReceiverParameter() == null)
|
||||||
|
funDeclaration == KotlinBuiltIns.getInstance().getFunction(parameterCount) ||
|
||||||
|
funDeclaration == reflectionTypes.getKFunction(parameterCount)
|
||||||
else
|
else
|
||||||
KotlinBuiltIns.getInstance().getExtensionFunction(parameterCount)))
|
funDeclaration == KotlinBuiltIns.getInstance().getExtensionFunction(parameterCount) ||
|
||||||
|
funDeclaration == reflectionTypes.getKExtensionFunction(parameterCount) ||
|
||||||
|
funDeclaration == reflectionTypes.getKMemberFunction(parameterCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun FunctionCallInfo.thisObject(): JsExpression {
|
override fun FunctionCallInfo.thisObject(): JsExpression {
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ public final class Namer {
|
|||||||
private static final String TRAIT_OBJECT_NAME = "createTrait";
|
private static final String TRAIT_OBJECT_NAME = "createTrait";
|
||||||
private static final String OBJECT_OBJECT_NAME = "createObject";
|
private static final String OBJECT_OBJECT_NAME = "createObject";
|
||||||
private static final String ENUM_ENTRIES_NAME = "createEnumEntries";
|
private static final String ENUM_ENTRIES_NAME = "createEnumEntries";
|
||||||
|
private static final String CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME = "getCallableRefForMemberFunction";
|
||||||
|
private static final String CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME = "getCallableRefForExtensionFunction";
|
||||||
|
private static final String CALLABLE_REF_FOR_CONSTRUCTOR_NAME = "getCallableRefForConstructor";
|
||||||
|
private static final String CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY = "getCallableRefForTopLevelProperty";
|
||||||
|
private static final String CALLABLE_REF_FOR_MEMBER_PROPERTY = "getCallableRefForMemberProperty";
|
||||||
|
private static final String CALLABLE_REF_FOR_EXTENSION_PROPERTY = "getCallableRefForExtensionProperty";
|
||||||
|
|
||||||
private static final String SETTER_PREFIX = "set_";
|
private static final String SETTER_PREFIX = "set_";
|
||||||
private static final String GETTER_PREFIX = "get_";
|
private static final String GETTER_PREFIX = "get_";
|
||||||
@@ -177,6 +183,18 @@ public final class Namer {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final JsName enumEntriesName;
|
private final JsName enumEntriesName;
|
||||||
@NotNull
|
@NotNull
|
||||||
|
private final JsName callableRefForMemberFunctionName;
|
||||||
|
@NotNull
|
||||||
|
private final JsName callableRefForExtensionFunctionName;
|
||||||
|
@NotNull
|
||||||
|
private final JsName callableRefForConstructorName;
|
||||||
|
@NotNull
|
||||||
|
private final JsName callableRefForTopLevelProperty;
|
||||||
|
@NotNull
|
||||||
|
private final JsName callableRefForMemberProperty;
|
||||||
|
@NotNull
|
||||||
|
private final JsName callableRefForExtensionProperty;
|
||||||
|
@NotNull
|
||||||
private final JsExpression undefinedExpression;
|
private final JsExpression undefinedExpression;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsExpression callGetProperty;
|
private final JsExpression callGetProperty;
|
||||||
@@ -200,6 +218,12 @@ public final class Namer {
|
|||||||
className = kotlinScope.declareName(CLASS_OBJECT_NAME);
|
className = kotlinScope.declareName(CLASS_OBJECT_NAME);
|
||||||
enumEntriesName = kotlinScope.declareName(ENUM_ENTRIES_NAME);
|
enumEntriesName = kotlinScope.declareName(ENUM_ENTRIES_NAME);
|
||||||
objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
|
objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
|
||||||
|
callableRefForMemberFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME);
|
||||||
|
callableRefForExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME);
|
||||||
|
callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME);
|
||||||
|
callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY);
|
||||||
|
callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_PROPERTY);
|
||||||
|
callableRefForExtensionProperty = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_PROPERTY);
|
||||||
|
|
||||||
isTypeName = kotlinScope.declareName("isType");
|
isTypeName = kotlinScope.declareName("isType");
|
||||||
|
|
||||||
@@ -236,6 +260,36 @@ public final class Namer {
|
|||||||
return kotlin(objectName);
|
return kotlin(objectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression callableRefForMemberFunctionReference() {
|
||||||
|
return kotlin(callableRefForMemberFunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression callableRefForExtensionFunctionReference() {
|
||||||
|
return kotlin(callableRefForExtensionFunctionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression callableRefForConstructorReference() {
|
||||||
|
return kotlin(callableRefForConstructorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression callableRefForTopLevelPropertyReference() {
|
||||||
|
return kotlin(callableRefForTopLevelProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression callableRefForMemberPropertyReference() {
|
||||||
|
return kotlin(callableRefForMemberProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression callableRefForExtensionPropertyReference() {
|
||||||
|
return kotlin(callableRefForExtensionProperty);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression throwNPEFunctionRef() {
|
public JsExpression throwNPEFunctionRef() {
|
||||||
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ package org.jetbrains.k2js.translate.expression;
|
|||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
@@ -39,12 +37,8 @@ import org.jetbrains.k2js.translate.general.Translation;
|
|||||||
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
||||||
import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator;
|
import org.jetbrains.k2js.translate.operation.BinaryOperationTranslator;
|
||||||
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.AccessTranslationUtils;
|
import org.jetbrains.k2js.translate.reference.*;
|
||||||
import org.jetbrains.k2js.translate.reference.CallExpressionTranslator;
|
import org.jetbrains.k2js.translate.utils.*;
|
||||||
import org.jetbrains.k2js.translate.reference.QualifiedExpressionTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
|
||||||
import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator;
|
import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -168,6 +162,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
return newVar(name, initializer).source(expression);
|
return newVar(name, initializer).source(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JsNode visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, @NotNull TranslationContext context) {
|
||||||
|
return CallableReferenceTranslator.INSTANCE$.translate(expression, context);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsNode visitCallExpression(@NotNull JetCallExpression expression,
|
public JsNode visitCallExpression(@NotNull JetCallExpression expression,
|
||||||
|
|||||||
+158
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 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.k2js.translate.reference
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsExpression
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.k2js.translate.context.TranslationContext
|
||||||
|
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsInvocation
|
||||||
|
import org.jetbrains.jet.lang.descriptors.Visibilities
|
||||||
|
import org.jetbrains.k2js.translate.utils.AnnotationsUtils
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallableReferenceExpression
|
||||||
|
import org.jetbrains.k2js.translate.utils.BindingUtils
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
||||||
|
import java.util.ArrayList
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef
|
||||||
|
import org.jetbrains.k2js.translate.context.Namer
|
||||||
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||||
|
|
||||||
|
object CallableReferenceTranslator {
|
||||||
|
|
||||||
|
fun translate(expression: JetCallableReferenceExpression, context: TranslationContext): JsExpression {
|
||||||
|
val descriptor = BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression.getCallableReference())
|
||||||
|
return when (descriptor) {
|
||||||
|
is PropertyDescriptor ->
|
||||||
|
translateForProperty(descriptor as PropertyDescriptor, context)
|
||||||
|
is FunctionDescriptor ->
|
||||||
|
translateForFunction(descriptor as FunctionDescriptor, context)
|
||||||
|
else ->
|
||||||
|
throw IllegalArgumentException("Expected property or function: ${descriptor}, expression=${expression.getText()}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
return when {
|
||||||
|
// TODO Support for callable reference to builtin functions and members
|
||||||
|
JsDescriptorUtils.isBuiltin(descriptor) ->
|
||||||
|
throw UnsupportedOperationException("callable references for builtin functions are not supported yet")
|
||||||
|
isConstructor(descriptor) ->
|
||||||
|
translateForConstructor(descriptor, context)
|
||||||
|
isExtension(descriptor) ->
|
||||||
|
translateForExtensionFunction(descriptor, context)
|
||||||
|
isMember(descriptor) ->
|
||||||
|
translateForMemberFunction(descriptor, context)
|
||||||
|
else ->
|
||||||
|
ReferenceTranslator.translateAsFQReference(descriptor, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
return when {
|
||||||
|
// TODO Support for callable reference to builtin properties
|
||||||
|
JsDescriptorUtils.isBuiltin(descriptor) ->
|
||||||
|
throw UnsupportedOperationException("callable references for builtin properties are not supported yet")
|
||||||
|
isExtension(descriptor) ->
|
||||||
|
translateForExtensionProperty(descriptor, context)
|
||||||
|
isMember(descriptor) ->
|
||||||
|
translateForMemberProperty(descriptor, context)
|
||||||
|
else ->
|
||||||
|
translateForTopLevelProperty(descriptor, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isConstructor(descriptor: CallableDescriptor): Boolean = descriptor is ConstructorDescriptor
|
||||||
|
|
||||||
|
private fun isExtension(descriptor: CallableDescriptor): Boolean = JsDescriptorUtils.isExtension(descriptor)
|
||||||
|
|
||||||
|
private fun isMember(descriptor: CallableDescriptor): Boolean = JsDescriptorUtils.getContainingDeclaration(descriptor) is ClassDescriptor
|
||||||
|
|
||||||
|
private fun isVar(descriptor: PropertyDescriptor): JsExpression = if (descriptor.isVar()) JsLiteral.TRUE else JsLiteral.FALSE
|
||||||
|
|
||||||
|
private fun translateForTopLevelProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
val packageDescriptor = JsDescriptorUtils.getContainingDeclaration(descriptor)
|
||||||
|
assert(packageDescriptor is PackageFragmentDescriptor, "Expected PackageFragmentDescriptor: ${packageDescriptor}")
|
||||||
|
|
||||||
|
val jsPackageNameRef = context.getQualifiedReference(packageDescriptor)
|
||||||
|
val jsPropertyName = context.getNameForDescriptor(descriptor)
|
||||||
|
val jsPropertyNameAsString = context.program().getStringLiteral(jsPropertyName.toString())
|
||||||
|
|
||||||
|
return JsInvocation(context.namer().callableRefForTopLevelPropertyReference(), jsPackageNameRef, jsPropertyNameAsString, isVar(descriptor))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForMemberProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
val jsPropertyName = context.getNameForDescriptor(descriptor)
|
||||||
|
val jsPropertyNameAsString = context.program().getStringLiteral(jsPropertyName.toString())
|
||||||
|
return JsInvocation(context.namer().callableRefForMemberPropertyReference(), jsPropertyNameAsString, isVar(descriptor))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForExtensionProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
val jsGetterNameRef = context.getQualifiedReference(descriptor.getGetter()!!)
|
||||||
|
val propertyName = descriptor.getName()
|
||||||
|
val jsPropertyNameAsString = context.program().getStringLiteral(propertyName.asString())
|
||||||
|
val argumentList = ArrayList<JsExpression>(3)
|
||||||
|
argumentList.add(jsPropertyNameAsString)
|
||||||
|
argumentList.add(jsGetterNameRef)
|
||||||
|
if (descriptor.isVar()) {
|
||||||
|
val jsSetterNameRef = context.getQualifiedReference(descriptor.getSetter()!!)
|
||||||
|
argumentList.add(jsSetterNameRef)
|
||||||
|
}
|
||||||
|
if (AnnotationsUtils.isNativeObject(descriptor))
|
||||||
|
return translateForMemberProperty(descriptor, context)
|
||||||
|
else
|
||||||
|
return JsInvocation(context.namer().callableRefForExtensionPropertyReference(), argumentList)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForConstructor(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
val jsFunctionRef = ReferenceTranslator.translateAsFQReference(descriptor, context)
|
||||||
|
return JsInvocation(context.namer().callableRefForConstructorReference(), jsFunctionRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForExtensionFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
val receiverParameterDescriptor = descriptor.getReceiverParameter()
|
||||||
|
assert(receiverParameterDescriptor != null, "receiverParameter for extension should not be null")
|
||||||
|
|
||||||
|
val jsFunctionRef = ReferenceTranslator.translateAsFQReference(descriptor, context)
|
||||||
|
if (descriptor.getVisibility() == Visibilities.LOCAL)
|
||||||
|
return jsFunctionRef
|
||||||
|
else if (AnnotationsUtils.isNativeObject(descriptor)) {
|
||||||
|
val jetType = receiverParameterDescriptor!!.getType()
|
||||||
|
val receiverClassDescriptor = DescriptorUtils.getClassDescriptorForType(jetType)
|
||||||
|
return translateAsMemberFunctionReference(descriptor, receiverClassDescriptor, context)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return JsInvocation(context.namer().callableRefForExtensionFunctionReference(), jsFunctionRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForMemberFunction(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
val classDescriptor = JsDescriptorUtils.getContainingDeclaration(descriptor) as? ClassDescriptor ?: throw IllegalArgumentException("Expected ClassDescriptor: ${descriptor}")
|
||||||
|
return translateAsMemberFunctionReference(descriptor, classDescriptor, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateAsMemberFunctionReference(descriptor: CallableDescriptor, classDescriptor: ClassDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
val jsClassNameRef = context.getQualifiedReference(classDescriptor)
|
||||||
|
val funName = context.getNameForDescriptor(descriptor)
|
||||||
|
val funNameAsString = context.program().getStringLiteral(funName.toString())
|
||||||
|
return JsInvocation(context.namer().callableRefForMemberFunctionReference(), jsClassNameRef, funNameAsString)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -294,7 +294,60 @@ var Kotlin = {};
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO Store callable references for members in class
|
||||||
|
Kotlin.getCallableRefForMemberFunction = function (klass, memberName) {
|
||||||
|
return function () {
|
||||||
|
return this[memberName].apply(this, arguments);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO Store callable references for extension functions in class
|
||||||
|
// extFun expected receiver as the first argument
|
||||||
|
Kotlin.getCallableRefForExtensionFunction = function (extFun) {
|
||||||
|
return function () {
|
||||||
|
var args = [this];
|
||||||
|
Array.prototype.push.apply(args, arguments);
|
||||||
|
return extFun.apply(null, args);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Kotlin.getCallableRefForConstructor = function (klass) {
|
||||||
|
return function () {
|
||||||
|
var obj = Object.create(klass.prototype);
|
||||||
|
klass.apply(obj, arguments);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Kotlin.getCallableRefForTopLevelProperty = function(packageName, name, isVar) {
|
||||||
|
var obj = {};
|
||||||
|
obj.name = name;
|
||||||
|
obj.get = function() { return packageName[name]; };
|
||||||
|
if (isVar) {
|
||||||
|
obj.set_za3rmp$ = function(value) { packageName[name] = value; };
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kotlin.getCallableRefForMemberProperty = function(name, isVar) {
|
||||||
|
var obj = {};
|
||||||
|
obj.name = name;
|
||||||
|
obj.get_za3rmp$ = function(receiver) { return receiver[name]; };
|
||||||
|
if (isVar) {
|
||||||
|
obj.set_wn2jw4$ = function(receiver, value) { receiver[name] = value; };
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kotlin.getCallableRefForExtensionProperty = function(name, getFun, setFun) {
|
||||||
|
var obj = {};
|
||||||
|
obj.name = name;
|
||||||
|
obj.get_za3rmp$ = getFun;
|
||||||
|
if (setFun !== undefined) {
|
||||||
|
obj.set_wn2jw4$ = setFun;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
////////////////////////////////// packages & modules //////////////////////////////
|
////////////////////////////////// packages & modules //////////////////////////////
|
||||||
|
|
||||||
Kotlin.modules = {};
|
Kotlin.modules = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user