From 4e9187779dcde226b9822d18e2902aba53a4e3ec Mon Sep 17 00:00:00 2001 From: Erokhin Stanislav Date: Thu, 26 Dec 2013 22:58:15 +0400 Subject: [PATCH] JS backend: Optimized CallInfo classes structure --- .../k2js/translate/reference/CallInfo.kt | 38 +++++++++++-------- .../reference/ClearCallTranslator.kt | 6 +-- .../translate/reference/FunctionCallCases.kt | 2 +- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallInfo.kt b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallInfo.kt index f4fec446bbf..7ffebcc4cee 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallInfo.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallInfo.kt @@ -32,15 +32,18 @@ import org.jetbrains.jet.lang.descriptors.VariableDescriptor import com.google.dart.compiler.backend.js.ast.JsName -open class BaseCallInfo( - val context: TranslationContext, - val resolvedCall: ResolvedCall, +trait CallInfo { + val context: TranslationContext + val resolvedCall: ResolvedCall - val thisObject: JsExpression?, - val receiverObject: JsExpression?, - val nullableReceiverForSafeCall: JsExpression? -) { - open val callableDescriptor = resolvedCall.getResultingDescriptor().getOriginal() + val thisObject: JsExpression? + val receiverObject: JsExpression? + val nullableReceiverForSafeCall: JsExpression? + + val callableDescriptor: CallableDescriptor + get() { + return resolvedCall.getResultingDescriptor().getOriginal() + } fun isExtension(): Boolean = receiverObject != null fun isMemberCall(): Boolean = thisObject != null @@ -55,11 +58,8 @@ open class BaseCallInfo( // TODO: toString for debug } -private open class CallInfoWrapper(callInfo: BaseCallInfo) : - BaseCallInfo(callInfo.context, callInfo.resolvedCall, callInfo.thisObject, callInfo.receiverObject, callInfo.nullableReceiverForSafeCall) - // if setTo == null, it is get access -class VariableAccessInfo(callInfo: BaseCallInfo, private val setTo: JsExpression? = null): CallInfoWrapper(callInfo) { +class VariableAccessInfo(callInfo: CallInfo, private val setTo: JsExpression? = null): CallInfo by callInfo { val variableDescriptor = super.callableDescriptor as VariableDescriptor val variableName : JsName get() { @@ -76,7 +76,7 @@ class VariableAccessInfo(callInfo: BaseCallInfo, private val setTo: JsExpression } } -class FunctionCallInfo(callInfo: BaseCallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : CallInfoWrapper(callInfo) { +class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : CallInfo by callInfo { val functionName : JsName get() { // getter, because for several descriptors name is undefined. Example: {(a) -> a+1}(3) return context.getNameForDescriptor(callableDescriptor) @@ -92,7 +92,7 @@ private fun TranslationContext.getThisObject(receiverValue: ReceiverValue): JsEx return getThisObject(getDeclarationDescriptorForReceiver(receiverValue)) } -private fun TranslationContext.mainGetCallInfo(resolvedCall: ResolvedCall, receiver1: JsExpression?, receiver2: JsExpression?): BaseCallInfo { +private fun TranslationContext.mainGetCallInfo(resolvedCall: ResolvedCall, receiver1: JsExpression?, receiver2: JsExpression?): CallInfo { val receiverKind = resolvedCall.getExplicitReceiverKind() fun getNotNullReceiver1(): JsExpression { assert(receiver1 != null, "ResolvedCall say, that receiver(1) must be not null") @@ -135,14 +135,20 @@ private fun TranslationContext.mainGetCallInfo(resolvedCall: ResolvedCall getNotNullReceiver1() } } - return BaseCallInfo(this, resolvedCall, getThisObject(), getReceiverObject(), getNullableReceiverForSafeCall()) + return object : CallInfo { + override val context: TranslationContext = this@mainGetCallInfo + override val resolvedCall: ResolvedCall = resolvedCall + override val thisObject: JsExpression? = getThisObject() + override val receiverObject: JsExpression? = getReceiverObject() + override val nullableReceiverForSafeCall: JsExpression? = getNullableReceiverForSafeCall() + }; } fun ResolvedCall.expectedReceivers(): Boolean { return this.getExplicitReceiverKind() != NO_EXPLICIT_RECEIVER } -fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall, receiver: JsExpression?): BaseCallInfo { +fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall, receiver: JsExpression?): CallInfo { return mainGetCallInfo(resolvedCall, receiver, null) } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/ClearCallTranslator.kt b/js/js.translator/src/org/jetbrains/k2js/translate/reference/ClearCallTranslator.kt index b7d2feb7f61..5ac4ba4dcf1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/ClearCallTranslator.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/ClearCallTranslator.kt @@ -69,7 +69,7 @@ private fun TranslationContext.buildCall(resolvedCall: ResolvedCall { +trait CallCase { val callInfo: I protected fun unsupported(message: String = "") : Exception { @@ -139,7 +139,7 @@ open class VariableAccessCase(override val callInfo: VariableAccessInfo) : CallC } } -class CallCaseDispatcher, I : BaseCallInfo> { +class CallCaseDispatcher, I : CallInfo> { private val cases: MutableList<(I) -> JsExpression?> = ArrayList() fun addCase(canBeApplyCase: (I) -> JsExpression?) { @@ -165,7 +165,7 @@ class CallCaseDispatcher, I : BaseCallInfo> { } } -trait DelegateIntrinsic : CallCase { +trait DelegateIntrinsic : CallCase { fun I.canBeApply(): Boolean = true fun I.getReceiver(): JsExpression? { return when (resolvedCall.getExplicitReceiverKind()) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt b/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt index 8027b2fa8a8..dfd73173b0e 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/FunctionCallCases.kt @@ -146,7 +146,7 @@ class ExpressionAsFunctionDescriptorIntrinsic(callInfo: FunctionCallInfo) : Func if (callableDescriptor !is ExpressionAsFunctionDescriptor) { throw IllegalStateException("callableDescriptor must be ExpressionAsFunctionDescriptor $callInfo") } - val funRef = Translation.translateAsExpression(callableDescriptor.getExpression()!!, context) + val funRef = Translation.translateAsExpression((callableDescriptor as ExpressionAsFunctionDescriptor).getExpression()!!, context) return JsInvocation(funRef, argumentsInfo.getTranslateArguments()) }