JS: refactor translation of callable references to top-level properties
This commit is contained in:
+47
-12
@@ -16,20 +16,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.translate.reference
|
package org.jetbrains.kotlin.js.translate.reference
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
import com.google.dart.compiler.backend.js.ast.*
|
||||||
import com.google.dart.compiler.backend.js.ast.JsInvocation
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
import org.jetbrains.kotlin.js.translate.utils.*
|
||||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object CallableReferenceTranslator {
|
object CallableReferenceTranslator {
|
||||||
@@ -93,13 +87,54 @@ object CallableReferenceTranslator {
|
|||||||
val packageDescriptor = JsDescriptorUtils.getContainingDeclaration(descriptor)
|
val packageDescriptor = JsDescriptorUtils.getContainingDeclaration(descriptor)
|
||||||
assert(packageDescriptor is PackageFragmentDescriptor) { "Expected PackageFragmentDescriptor: $packageDescriptor" }
|
assert(packageDescriptor is PackageFragmentDescriptor) { "Expected PackageFragmentDescriptor: $packageDescriptor" }
|
||||||
|
|
||||||
// TODO: revisit
|
|
||||||
val jsPackageNameRef = context.getQualifiedReference(packageDescriptor)
|
|
||||||
val jsPropertyName = context.getNameForDescriptor(descriptor)
|
val jsPropertyName = context.getNameForDescriptor(descriptor)
|
||||||
val jsPropertyNameAsString = context.program().getStringLiteral(jsPropertyName.toString())
|
val jsPropertyNameAsString = context.program().getStringLiteral(jsPropertyName.toString())
|
||||||
|
|
||||||
return JsInvocation(context.namer().callableRefForTopLevelPropertyReference(), jsPackageNameRef, jsPropertyNameAsString,
|
val getter = createTopLevelGetterFunction(descriptor, context)
|
||||||
isVar(descriptor))
|
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 {
|
private fun translateForMemberProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ var x = 1
|
|||||||
|
|
||||||
val y = 2
|
val y = 2
|
||||||
|
|
||||||
|
val z: Int
|
||||||
|
get() = 3
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var refX = ::x
|
var refX = ::x
|
||||||
assertEquals(1, refX.get())
|
assertEquals(1, refX.get())
|
||||||
@@ -16,5 +19,9 @@ fun box(): String {
|
|||||||
assertEquals(2, refY.get())
|
assertEquals(2, refY.get())
|
||||||
assertEquals("y", refY.name)
|
assertEquals("y", refY.name)
|
||||||
|
|
||||||
|
var refZ = ::z
|
||||||
|
assertEquals(3, refZ.get())
|
||||||
|
assertEquals("z", refZ.name)
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -470,10 +470,9 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.getCallableRefForTopLevelProperty = function(packageName, name, isVar) {
|
Kotlin.getCallableRefForTopLevelProperty = function(getter, setter, name) {
|
||||||
var getFun = Function("p", "return function " + name + "() { return p['" + name + "']; }")(packageName);
|
var getFun = Function("getter", "return function " + name + "() { return getter(); }")(getter, setter);
|
||||||
var setFun = isVar ? function(value) { packageName[name] = value; } : null;
|
return getPropertyRefClass(getFun, "get", setter, "set_za3rmp$", propertyRefClassMetadataCache.zeroArg);
|
||||||
return getPropertyRefClass(getFun, "get", setFun, "set_za3rmp$", propertyRefClassMetadataCache.zeroArg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.getCallableRefForMemberProperty = function(name, isVar) {
|
Kotlin.getCallableRefForMemberProperty = function(name, isVar) {
|
||||||
|
|||||||
Reference in New Issue
Block a user