JS backend: Fix aliasing in CallTranslator for cases noReceiver & receiverObject & add hack for thisObject

This commit is contained in:
Erokhin Stanislav
2014-01-31 19:02:19 +04:00
parent 5d4cb1e065
commit a7eb143cff
5 changed files with 44 additions and 18 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils
import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.* import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.*
import com.google.dart.compiler.backend.js.ast.JsLiteral import com.google.dart.compiler.backend.js.ast.JsLiteral
import org.jetbrains.k2js.translate.utils.TranslationUtils import org.jetbrains.k2js.translate.utils.TranslationUtils
import org.jetbrains.k2js.translate.context.TranslationContext
val CallInfo.callableDescriptor: CallableDescriptor val CallInfo.callableDescriptor: CallableDescriptor
@@ -54,7 +55,7 @@ fun VariableAccessInfo.isGetAccess(): Boolean = value == null
fun VariableAccessInfo.getAccessFunctionName(): String = Namer.getNameForAccessor(variableName.getIdent()!!, isGetAccess(), false) fun VariableAccessInfo.getAccessFunctionName(): String = Namer.getNameForAccessor(variableName.getIdent()!!, isGetAccess(), false)
fun VariableAccessInfo.constructAccessExpression(ref: JsNameRef): JsExpression { fun VariableAccessInfo.constructAccessExpression(ref: JsExpression): JsExpression {
if (isGetAccess()) { if (isGetAccess()) {
return ref return ref
} else { } else {
@@ -66,3 +67,12 @@ val FunctionCallInfo.functionName: JsName
get() = context.getNameForDescriptor(callableDescriptor) get() = context.getNameForDescriptor(callableDescriptor)
fun FunctionCallInfo.hasSpreadOperator(): Boolean = argumentsInfo.isHasSpreadOperator() fun FunctionCallInfo.hasSpreadOperator(): Boolean = argumentsInfo.isHasSpreadOperator()
fun TranslationContext.aliasOrValue(callableDescriptor: CallableDescriptor, value: (CallableDescriptor) -> JsExpression): JsExpression {
val alias = getAliasForDescriptor(callableDescriptor)
if (alias != null) {
return alias
} else {
return value(callableDescriptor)
}
}
@@ -123,9 +123,13 @@ trait CallCase<I : CallInfo> {
else else
callInfo.receiverArgument() callInfo.receiverArgument()
} else { } else {
if (callInfo.receiverObject == null) if (callInfo.receiverObject == null) {
// TODO remake UsageTracker and drop this hack
// this call need for usage tracker -- without it, capture this not worked
val alias = callInfo.context.getAliasForDescriptor(callInfo.callableDescriptor)
assert(alias == null, "Failed hack for usageTracker")
callInfo.thisObject() callInfo.thisObject()
else } else
callInfo.bothReceivers() callInfo.bothReceivers()
} }
@@ -82,9 +82,12 @@ object DefaultFunctionCallCase : FunctionCallCase {
if (isNative) { if (isNative) {
return JsInvocation(JsNameRef(functionName), argumentsInfo.getTranslateArguments()) return JsInvocation(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
} }
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
val functionCall = JsNameRef(functionName, qualifierForFunction) val functionRef = context.aliasOrValue(callableDescriptor) {
return JsInvocation(functionCall, argumentsInfo.getTranslateArguments()) val qualifierForFunction = context.getQualifierForDescriptor(it)
JsNameRef(functionName, qualifierForFunction)
}
return JsInvocation(functionRef, argumentsInfo.getTranslateArguments())
} }
override fun FunctionCallInfo.noReceivers(): JsExpression { override fun FunctionCallInfo.noReceivers(): JsExpression {
@@ -102,9 +105,12 @@ object DefaultFunctionCallCase : FunctionCallCase {
if (isNative()) { if (isNative()) {
return JsInvocation(JsNameRef(functionName, receiverObject), argumentsInfo.getTranslateArguments()) return JsInvocation(JsNameRef(functionName, receiverObject), argumentsInfo.getTranslateArguments())
} }
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
val functionCall = JsNameRef(functionName, qualifierForFunction) // TODO: remake to call val functionRef = context.aliasOrValue(callableDescriptor) {
return JsInvocation(functionCall, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments())) val qualifierForFunction = context.getQualifierForDescriptor(it)
JsNameRef(functionName, qualifierForFunction) // TODO: remake to call
}
return JsInvocation(functionRef, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments()))
} }
override fun FunctionCallInfo.bothReceivers(): JsExpression { // TODO: think about crazy case: spreadOperator + native override fun FunctionCallInfo.bothReceivers(): JsExpression { // TODO: think about crazy case: spreadOperator + native
@@ -152,7 +158,11 @@ object ConstructorCallCase : FunctionCallCase {
if (isNative()) { if (isNative()) {
return JsNew(JsNameRef(functionName), argumentsInfo.getTranslateArguments()) return JsNew(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
} }
return JsNew(context.getQualifiedReference(callableDescriptor), argumentsInfo.getTranslateArguments())
val functionRef = context.aliasOrValue(callableDescriptor) {
context.getQualifiedReference(it)
}
return JsNew(functionRef, argumentsInfo.getTranslateArguments())
} }
} }
@@ -167,7 +177,6 @@ object ExpressionAsFunctionDescriptorIntrinsic : FunctionCallCase {
} }
val funRef = Translation.translateAsExpression((callableDescriptor as ExpressionAsFunctionDescriptor).getExpression()!!, context) val funRef = Translation.translateAsExpression((callableDescriptor as ExpressionAsFunctionDescriptor).getExpression()!!, context)
return JsInvocation(funRef, argumentsInfo.getTranslateArguments()) return JsInvocation(funRef, argumentsInfo.getTranslateArguments())
} }
} }
@@ -45,7 +45,10 @@ object NativeVariableAccessCase : VariableAccessCase {
object DefaultVariableAccessCase : VariableAccessCase { object DefaultVariableAccessCase : VariableAccessCase {
override fun VariableAccessInfo.noReceivers(): JsExpression { override fun VariableAccessInfo.noReceivers(): JsExpression {
return constructAccessExpression(context.getQualifiedReference(variableDescriptor)) val functionRef = context.aliasOrValue(callableDescriptor) {
context.getQualifiedReference(variableDescriptor)
}
return constructAccessExpression(functionRef)
} }
override fun VariableAccessInfo.thisObject(): JsExpression { override fun VariableAccessInfo.thisObject(): JsExpression {
@@ -53,11 +56,13 @@ object DefaultVariableAccessCase : VariableAccessCase {
} }
override fun VariableAccessInfo.receiverArgument(): JsExpression { override fun VariableAccessInfo.receiverArgument(): JsExpression {
val funRef = JsNameRef(getAccessFunctionName(), context.getQualifierForDescriptor(variableDescriptor)) val functionRef = context.aliasOrValue(callableDescriptor) {
JsNameRef(getAccessFunctionName(), context.getQualifierForDescriptor(variableDescriptor))
}
return if (isGetAccess()) { return if (isGetAccess()) {
JsInvocation(funRef, receiverObject!!) JsInvocation(functionRef, receiverObject!!)
} else { } else {
JsInvocation(funRef, receiverObject!!, value!!) JsInvocation(functionRef, receiverObject!!, value!!)
} }
} }
@@ -171,7 +171,6 @@ public class TranslationContext {
@NotNull @NotNull
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) { public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
descriptorUsedInThisContext(descriptor); // TODO drop this
return staticContext.getNameForDescriptor(descriptor); return staticContext.getNameForDescriptor(descriptor);
} }
@@ -187,7 +186,6 @@ public class TranslationContext {
@NotNull @NotNull
public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) { public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) {
descriptorUsedInThisContext(descriptor); // TODO drop this
return staticContext.getQualifiedReference(descriptor); return staticContext.getQualifiedReference(descriptor);
} }