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 com.google.dart.compiler.backend.js.ast.JsLiteral
import org.jetbrains.k2js.translate.utils.TranslationUtils
import org.jetbrains.k2js.translate.context.TranslationContext
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.constructAccessExpression(ref: JsNameRef): JsExpression {
fun VariableAccessInfo.constructAccessExpression(ref: JsExpression): JsExpression {
if (isGetAccess()) {
return ref
} else {
@@ -65,4 +66,13 @@ fun VariableAccessInfo.constructAccessExpression(ref: JsNameRef): JsExpression {
val FunctionCallInfo.functionName: JsName
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
callInfo.receiverArgument()
} 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()
else
} else
callInfo.bothReceivers()
}
@@ -82,9 +82,12 @@ object DefaultFunctionCallCase : FunctionCallCase {
if (isNative) {
return JsInvocation(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
}
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
val functionCall = JsNameRef(functionName, qualifierForFunction)
return JsInvocation(functionCall, argumentsInfo.getTranslateArguments())
val functionRef = context.aliasOrValue(callableDescriptor) {
val qualifierForFunction = context.getQualifierForDescriptor(it)
JsNameRef(functionName, qualifierForFunction)
}
return JsInvocation(functionRef, argumentsInfo.getTranslateArguments())
}
override fun FunctionCallInfo.noReceivers(): JsExpression {
@@ -102,9 +105,12 @@ object DefaultFunctionCallCase : FunctionCallCase {
if (isNative()) {
return JsInvocation(JsNameRef(functionName, receiverObject), argumentsInfo.getTranslateArguments())
}
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
val functionCall = JsNameRef(functionName, qualifierForFunction) // TODO: remake to call
return JsInvocation(functionCall, addReceiverToArgs(receiverObject!!, argumentsInfo.getTranslateArguments()))
val functionRef = context.aliasOrValue(callableDescriptor) {
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
@@ -152,7 +158,11 @@ object ConstructorCallCase : FunctionCallCase {
if (isNative()) {
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)
return JsInvocation(funRef, argumentsInfo.getTranslateArguments())
}
}
@@ -45,7 +45,10 @@ object NativeVariableAccessCase : VariableAccessCase {
object DefaultVariableAccessCase : VariableAccessCase {
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 {
@@ -53,11 +56,13 @@ object DefaultVariableAccessCase : VariableAccessCase {
}
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()) {
JsInvocation(funRef, receiverObject!!)
JsInvocation(functionRef, receiverObject!!)
} else {
JsInvocation(funRef, receiverObject!!, value!!)
JsInvocation(functionRef, receiverObject!!, value!!)
}
}
@@ -171,7 +171,6 @@ public class TranslationContext {
@NotNull
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
descriptorUsedInThisContext(descriptor); // TODO drop this
return staticContext.getNameForDescriptor(descriptor);
}
@@ -187,7 +186,6 @@ public class TranslationContext {
@NotNull
public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) {
descriptorUsedInThisContext(descriptor); // TODO drop this
return staticContext.getQualifiedReference(descriptor);
}