JS: refactor translation of callable references to top-level properties

This commit is contained in:
Alexey Andreev
2016-10-26 19:14:24 +03:00
parent 0252fe57af
commit ac4bfc645e
3 changed files with 57 additions and 16 deletions
@@ -16,20 +16,14 @@
package org.jetbrains.kotlin.js.translate.reference
import com.google.dart.compiler.backend.js.ast.JsExpression
import com.google.dart.compiler.backend.js.ast.JsInvocation
import com.google.dart.compiler.backend.js.ast.JsLiteral
import com.google.dart.compiler.backend.js.ast.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
import org.jetbrains.kotlin.js.translate.utils.*
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import java.util.*
object CallableReferenceTranslator {
@@ -93,13 +87,54 @@ object CallableReferenceTranslator {
val packageDescriptor = JsDescriptorUtils.getContainingDeclaration(descriptor)
assert(packageDescriptor is PackageFragmentDescriptor) { "Expected PackageFragmentDescriptor: $packageDescriptor" }
// TODO: revisit
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))
val getter = createTopLevelGetterFunction(descriptor, context)
val setter = if (descriptor.isVar) createTopLevelSetterFunction(descriptor, context) else JsLiteral.NULL
return JsInvocation(context.namer().callableRefForTopLevelPropertyReference(), getter, setter, jsPropertyNameAsString)
}
private fun createTopLevelGetterFunction(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
val getter = descriptor.getter!!
if (!JsDescriptorUtils.isSimpleFinalProperty(descriptor) && context.isFromCurrentModule(descriptor)) {
return context.getInnerReference(getter)
}
val expression = if (TranslationUtils.shouldAccessViaFunctions(descriptor)) {
JsInvocation(ReferenceTranslator.translateAsValueReference(getter, context))
}
else {
ReferenceTranslator.translateAsValueReference(descriptor, context)
}
val function = context.createTopLevelFunction(getter)
function.body.statements += JsReturn(expression)
return function
}
private fun createTopLevelSetterFunction(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
val setter = descriptor.setter!!
if (!JsDescriptorUtils.isSimpleFinalProperty(descriptor) && context.isFromCurrentModule(descriptor)) {
return context.getInnerReference(setter)
}
val function = context.createTopLevelFunction(setter)
val valueParam = function.scope.declareFreshName("value")
function.parameters += JsParameter(valueParam)
val expression = if (TranslationUtils.shouldAccessViaFunctions(descriptor)) {
JsInvocation(ReferenceTranslator.translateAsValueReference(setter, context), valueParam.makeRef())
}
else {
JsAstUtils.assignment(ReferenceTranslator.translateAsValueReference(descriptor, context), valueParam.makeRef())
}
function.body.statements += expression.makeStmt()
return function
}
private fun translateForMemberProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
@@ -4,6 +4,9 @@ var x = 1
val y = 2
val z: Int
get() = 3
fun box(): String {
var refX = ::x
assertEquals(1, refX.get())
@@ -16,5 +19,9 @@ fun box(): String {
assertEquals(2, refY.get())
assertEquals("y", refY.name)
var refZ = ::z
assertEquals(3, refZ.get())
assertEquals("z", refZ.name)
return "OK"
}
+3 -4
View File
@@ -470,10 +470,9 @@
};
};
Kotlin.getCallableRefForTopLevelProperty = function(packageName, name, isVar) {
var getFun = Function("p", "return function " + name + "() { return p['" + name + "']; }")(packageName);
var setFun = isVar ? function(value) { packageName[name] = value; } : null;
return getPropertyRefClass(getFun, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.zeroArg);
Kotlin.getCallableRefForTopLevelProperty = function(getter, setter, name) {
var getFun = Function("getter", "return function " + name + "() { return getter(); }")(getter, setter);
return getPropertyRefClass(getFun, "get", setter, "set_za3rmp$", propertyRefClassMetadataCache.zeroArg);
};
Kotlin.getCallableRefForMemberProperty = function(name, isVar) {