JS backend: cosmetic changes & class for cases remake to object
This commit is contained in:
@@ -31,6 +31,9 @@ import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
|
||||
import com.google.dart.compiler.backend.js.ast.JsName
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.k2js.translate.context.Namer
|
||||
|
||||
|
||||
trait CallInfo {
|
||||
@@ -48,7 +51,7 @@ trait CallInfo {
|
||||
}
|
||||
|
||||
// if value == null, it is get access
|
||||
class VariableAccessInfo(callInfo: CallInfo, val value: JsExpression? = null): CallInfo by callInfo
|
||||
class VariableAccessInfo(callInfo: CallInfo, val value: JsExpression? = null) : CallInfo by callInfo
|
||||
|
||||
class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : CallInfo by callInfo
|
||||
|
||||
@@ -60,12 +63,12 @@ class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTransl
|
||||
*/
|
||||
class ExplicitReceivers(val receiverOrThisObject: JsExpression?, val receiverObject: JsExpression? = null)
|
||||
|
||||
fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall<out CallableDescriptor>, receiver: JsExpression?): CallInfo {
|
||||
return createCallInfo(resolvedCall, ExplicitReceivers(receiver))
|
||||
fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall<out CallableDescriptor>, receiverOrThisObject: JsExpression?): CallInfo {
|
||||
return createCallInfo(resolvedCall, ExplicitReceivers(receiverOrThisObject))
|
||||
}
|
||||
|
||||
fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall<out FunctionDescriptor>, receiver: JsExpression?): FunctionCallInfo {
|
||||
return getCallInfo(resolvedCall, ExplicitReceivers(receiver));
|
||||
fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall<out FunctionDescriptor>, receiverOrThisObject: JsExpression?): FunctionCallInfo {
|
||||
return getCallInfo(resolvedCall, ExplicitReceivers(receiverOrThisObject));
|
||||
}
|
||||
|
||||
// two receiver need only for FunctionCall in VariableAsFunctionResolvedCall
|
||||
@@ -75,24 +78,20 @@ fun TranslationContext.getCallInfo(resolvedCall: ResolvedCall<out FunctionDescri
|
||||
return FunctionCallInfo(callInfo, argumentsInfo)
|
||||
}
|
||||
|
||||
|
||||
val CallInfo.callableDescriptor: CallableDescriptor
|
||||
get() {
|
||||
return resolvedCall.getResultingDescriptor().getOriginal()
|
||||
}
|
||||
fun CallInfo.isExtension(): Boolean {
|
||||
return receiverObject != null
|
||||
}
|
||||
fun CallInfo.isMemberCall(): Boolean {
|
||||
return thisObject != null
|
||||
}
|
||||
fun CallInfo.isNative(): Boolean {
|
||||
return AnnotationsUtils.isNativeObject(callableDescriptor)
|
||||
}
|
||||
fun CallInfo.isSuperInvocation() : Boolean {
|
||||
get() = resolvedCall.getResultingDescriptor().getOriginal()
|
||||
|
||||
fun CallInfo.isExtension(): Boolean = receiverObject != null
|
||||
|
||||
fun CallInfo.isMemberCall(): Boolean = thisObject != null
|
||||
|
||||
fun CallInfo.isNative(): Boolean = AnnotationsUtils.isNativeObject(callableDescriptor)
|
||||
|
||||
fun CallInfo.isSuperInvocation(): Boolean {
|
||||
val thisObject = resolvedCall.getThisObject()
|
||||
return thisObject is ExpressionReceiver && ((thisObject as ExpressionReceiver)).getExpression() is JetSuperExpression
|
||||
}
|
||||
|
||||
fun CallInfo.constructSafeCallIsNeeded(result: JsExpression): JsExpression {
|
||||
if (!resolvedCall.isSafeCall())
|
||||
return result
|
||||
@@ -109,25 +108,27 @@ fun CallInfo.constructSafeCallIsNeeded(result: JsExpression): JsExpression {
|
||||
}
|
||||
|
||||
val VariableAccessInfo.variableDescriptor: VariableDescriptor
|
||||
get() {
|
||||
return callableDescriptor as VariableDescriptor
|
||||
get() = callableDescriptor as VariableDescriptor
|
||||
|
||||
val VariableAccessInfo.variableName: JsName
|
||||
get() = context.getNameForDescriptor(variableDescriptor)
|
||||
|
||||
fun VariableAccessInfo.isGetAccess(): Boolean = value == null
|
||||
|
||||
fun VariableAccessInfo.getAccessFunctionName(): String = Namer.getNameForAccessor(variableName.getIdent()!!, isGetAccess(), false)
|
||||
|
||||
fun VariableAccessInfo.constructAccessExpression(ref: JsNameRef): JsExpression {
|
||||
if (isGetAccess()) {
|
||||
return ref
|
||||
} else {
|
||||
return JsAstUtils.assignment(ref, value!!)
|
||||
}
|
||||
val VariableAccessInfo.variableName : JsName
|
||||
get() {
|
||||
return context.getNameForDescriptor(variableDescriptor)
|
||||
}
|
||||
fun VariableAccessInfo.isGetAccess(): Boolean {
|
||||
return value == null
|
||||
}
|
||||
|
||||
val FunctionCallInfo.functionName : JsName
|
||||
get() {
|
||||
return context.getNameForDescriptor(callableDescriptor)
|
||||
}
|
||||
fun FunctionCallInfo.hasSpreadOperator() : Boolean {
|
||||
return argumentsInfo.isHasSpreadOperator()
|
||||
}
|
||||
val FunctionCallInfo.functionName: JsName
|
||||
get() = context.getNameForDescriptor(callableDescriptor)
|
||||
|
||||
fun FunctionCallInfo.hasSpreadOperator(): Boolean = argumentsInfo.isHasSpreadOperator()
|
||||
|
||||
private fun TranslationContext.getThisObject(receiverValue: ReceiverValue): JsExpression {
|
||||
assert(receiverValue.exists(), "receiverValue must be exist here")
|
||||
@@ -160,15 +161,6 @@ private fun TranslationContext.createCallInfo(resolvedCall: ResolvedCall<out Cal
|
||||
}
|
||||
}
|
||||
|
||||
fun getNullableReceiverForSafeCall(): JsExpression? {
|
||||
if (!resolvedCall.isSafeCall()) {
|
||||
return null
|
||||
}
|
||||
return when (receiverKind) {
|
||||
BOTH_RECEIVERS -> explicitReceivers.receiverObject
|
||||
else -> explicitReceivers.receiverOrThisObject
|
||||
}
|
||||
}
|
||||
return object : CallInfo {
|
||||
override val context: TranslationContext = this@createCallInfo
|
||||
override val resolvedCall: ResolvedCall<out CallableDescriptor> = resolvedCall
|
||||
|
||||
@@ -34,21 +34,18 @@ import org.jetbrains.k2js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils
|
||||
|
||||
|
||||
val functionCallCases: CallCaseDispatcher<FunctionCallCase, FunctionCallInfo> = createFunctionCases()
|
||||
val variableAccessCases: CallCaseDispatcher<VariableAccessCase, VariableAccessInfo> = createVariableAccessCases()
|
||||
|
||||
fun TranslationContext.buildCall(resolvedCall: ResolvedCall<out FunctionDescriptor>, receiverOrThisObject: JsExpression? = null): JsExpression {
|
||||
return buildCall(resolvedCall, ExplicitReceivers(receiverOrThisObject))
|
||||
}
|
||||
|
||||
fun TranslationContext.buildGet(resolvedCall: ResolvedCall<out VariableDescriptor>, receiverOrThisObject: JsExpression? = null): JsExpression {
|
||||
val variableAccessInfo = VariableAccessInfo(getCallInfo(resolvedCall, receiverOrThisObject), null);
|
||||
return variableAccessCases.translate(variableAccessInfo)
|
||||
return variableAccessInfo.translateVariableAccess()
|
||||
}
|
||||
|
||||
fun TranslationContext.buildSet(resolvedCall: ResolvedCall<out VariableDescriptor>, value: JsExpression, receiverOrThisObject: JsExpression? = null): JsExpression {
|
||||
val variableAccessInfo = VariableAccessInfo(getCallInfo(resolvedCall, receiverOrThisObject), value);
|
||||
return variableAccessCases.translate(variableAccessInfo)
|
||||
return variableAccessInfo.translateVariableAccess()
|
||||
}
|
||||
|
||||
fun TranslationContext.buildFakeCall(functionDescriptor: FunctionDescriptor, args: List<JsExpression>, thisObject: JsExpression?): JsExpression {
|
||||
@@ -57,13 +54,13 @@ fun TranslationContext.buildFakeCall(functionDescriptor: FunctionDescriptor, arg
|
||||
val isNative = AnnotationsUtils.isNativeObject(functionDescriptor)
|
||||
val hasSpreadOperator = false
|
||||
if (thisObject != null) {
|
||||
return DefaultCallCase.buildDefaultCallWithThisObject(argumentsInfo, thisObject, functionName, isNative, hasSpreadOperator)
|
||||
return DefaultFunctionCallCase.buildDefaultCallWithThisObject(argumentsInfo, thisObject, functionName, isNative, hasSpreadOperator)
|
||||
} else {
|
||||
return DefaultCallCase.buildDefaultCallWithoutReceiver(this, argumentsInfo, functionDescriptor, functionName, isNative, hasSpreadOperator)
|
||||
return DefaultFunctionCallCase.buildDefaultCallWithoutReceiver(this, argumentsInfo, functionDescriptor, functionName, isNative, hasSpreadOperator)
|
||||
}
|
||||
}
|
||||
|
||||
fun ResolvedCall<out CallableDescriptor>.expectedReceivers(): Boolean {
|
||||
private fun ResolvedCall<out CallableDescriptor>.expectedReceivers(): Boolean {
|
||||
return this.getExplicitReceiverKind() != NO_EXPLICIT_RECEIVER
|
||||
}
|
||||
|
||||
@@ -84,34 +81,23 @@ private fun TranslationContext.buildCall(resolvedCall: ResolvedCall<out Function
|
||||
}
|
||||
|
||||
val functionCallInfo = getCallInfo(resolvedCall, explicitReceivers)
|
||||
return functionCallCases.translate(functionCallInfo)
|
||||
return functionCallInfo.translateFunctionCall()
|
||||
}
|
||||
|
||||
|
||||
trait CallCase<I : CallInfo> {
|
||||
val callInfo: I
|
||||
|
||||
protected fun unsupported(message: String = "") : Nothing {
|
||||
throw UnsupportedOperationException("this case unsopported. $callInfo")
|
||||
}
|
||||
protected fun I.unsupported(message: String = "") : Nothing = throw UnsupportedOperationException("this case unsopported. $this")
|
||||
|
||||
protected fun I.noReceivers(): JsExpression {
|
||||
unsupported()
|
||||
}
|
||||
protected fun I.noReceivers(): JsExpression = unsupported()
|
||||
|
||||
protected fun I.thisObject(): JsExpression {
|
||||
unsupported()
|
||||
}
|
||||
protected fun I.thisObject(): JsExpression = unsupported()
|
||||
|
||||
protected fun I.receiverArgument(): JsExpression {
|
||||
unsupported()
|
||||
}
|
||||
protected fun I.receiverArgument(): JsExpression = unsupported()
|
||||
|
||||
protected fun I.bothReceivers(): JsExpression {
|
||||
unsupported()
|
||||
}
|
||||
protected fun I.bothReceivers(): JsExpression = unsupported()
|
||||
|
||||
final fun translate(): JsExpression {
|
||||
final fun translate(callInfo: I): JsExpression {
|
||||
val result = if (callInfo.thisObject == null) {
|
||||
if (callInfo.receiverObject == null)
|
||||
callInfo.noReceivers()
|
||||
@@ -128,62 +114,23 @@ trait CallCase<I : CallInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
open class FunctionCallCase(override val callInfo: FunctionCallInfo) : CallCase<FunctionCallInfo>
|
||||
trait FunctionCallCase : CallCase<FunctionCallInfo>
|
||||
|
||||
open class VariableAccessCase(override val callInfo: VariableAccessInfo) : CallCase<VariableAccessInfo> {
|
||||
protected fun VariableAccessInfo.getAccessFunctionName(): String {
|
||||
return Namer.getNameForAccessor(variableName.getIdent()!!, isGetAccess(), false)
|
||||
}
|
||||
trait VariableAccessCase : CallCase<VariableAccessInfo>
|
||||
|
||||
protected fun VariableAccessInfo.constructAccessExpression(ref: JsNameRef): JsExpression {
|
||||
if (isGetAccess()) {
|
||||
return ref
|
||||
} else {
|
||||
return JsAstUtils.assignment(ref, value!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CallCaseDispatcher<C : CallCase<I>, I : CallInfo> {
|
||||
private val cases: MutableList<(I) -> JsExpression?> = ArrayList()
|
||||
|
||||
fun addCase(canBeApplyCase: (I) -> JsExpression?) {
|
||||
cases.add(canBeApplyCase)
|
||||
}
|
||||
|
||||
fun addCase(caseConstructor: (I) -> C, canApply: (I) -> Boolean) {
|
||||
cases.add({
|
||||
if (canApply(it))
|
||||
caseConstructor(it).translate()
|
||||
else
|
||||
null
|
||||
})
|
||||
}
|
||||
|
||||
fun translate(callInfo: I): JsExpression {
|
||||
for (case in cases) {
|
||||
val result = case(callInfo)
|
||||
if (result != null)
|
||||
return result
|
||||
}
|
||||
throw UnsupportedOperationException("This case of call unsopported. CallInfo: $callInfo")
|
||||
}
|
||||
}
|
||||
|
||||
trait DelegateIntrinsic<I : CallInfo> : CallCase<I> {
|
||||
trait DelegateIntrinsic<I : CallInfo> {
|
||||
fun I.canBeApply(): Boolean = true
|
||||
fun I.getReceiver(): JsExpression? {
|
||||
return when (resolvedCall.getExplicitReceiverKind()) {
|
||||
THIS_OBJECT -> thisObject
|
||||
RECEIVER_ARGUMENT, BOTH_RECEIVERS -> receiverObject
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun I.getDescriptor(): CallableDescriptor
|
||||
fun I.getArgs(): List<JsExpression>
|
||||
|
||||
fun I.intrinsic(): JsExpression? {
|
||||
fun intrinsic(callInfo: I): JsExpression? {
|
||||
return if (callInfo.canBeApply())
|
||||
callInfo.getIntrinsic()
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
private fun I.getIntrinsic(): JsExpression? {
|
||||
val descriptor = getDescriptor();
|
||||
|
||||
// Now intrinsic support only FunctionDescriptor. See DelegatePropertyAccessIntrinsic.getDescriptor()
|
||||
@@ -195,11 +142,4 @@ trait DelegateIntrinsic<I : CallInfo> : CallCase<I> {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun intrinsic(): JsExpression? {
|
||||
return if (callInfo.canBeApply())
|
||||
callInfo.intrinsic()
|
||||
else
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,44 +48,42 @@ public fun addReceiverToArgs(receiver: JsExpression, arguments: List<JsExpressio
|
||||
|
||||
|
||||
// call may be native and|or with spreadOperator
|
||||
class DefaultCallCase(callInfo: FunctionCallInfo): FunctionCallCase(callInfo) {
|
||||
class object {
|
||||
// TODO: refactor after fix ArgumentsInfo - duplicate code
|
||||
private fun nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo: CallArgumentTranslator.ArgumentsInfo, functionName: JsName): JsExpression {
|
||||
val cachedReceiver = argumentsInfo.getCachedReceiver()!!
|
||||
val functionCallRef = Namer.getFunctionApplyRef(JsNameRef(functionName, cachedReceiver.assignmentExpression()))
|
||||
object DefaultFunctionCallCase : FunctionCallCase {
|
||||
// TODO: refactor after fix ArgumentsInfo - duplicate code
|
||||
private fun nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo: CallArgumentTranslator.ArgumentsInfo, functionName: JsName): JsExpression {
|
||||
val cachedReceiver = argumentsInfo.getCachedReceiver()!!
|
||||
val functionCallRef = Namer.getFunctionApplyRef(JsNameRef(functionName, cachedReceiver.assignmentExpression()))
|
||||
return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
|
||||
fun buildDefaultCallWithThisObject(argumentsInfo: CallArgumentTranslator.ArgumentsInfo,
|
||||
thisObject: JsExpression,
|
||||
functionName: JsName,
|
||||
isNative: Boolean,
|
||||
hasSpreadOperator: Boolean): JsExpression {
|
||||
if (isNative && hasSpreadOperator) {
|
||||
return nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo, functionName)
|
||||
}
|
||||
val functionRef = JsNameRef(functionName, thisObject)
|
||||
return JsInvocation(functionRef, argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
|
||||
fun buildDefaultCallWithoutReceiver(context: TranslationContext,
|
||||
argumentsInfo: CallArgumentTranslator.ArgumentsInfo,
|
||||
callableDescriptor: CallableDescriptor,
|
||||
functionName: JsName,
|
||||
isNative: Boolean,
|
||||
hasSpreadOperator: Boolean): JsExpression {
|
||||
if (isNative && hasSpreadOperator) {
|
||||
val functionCallRef = Namer.getFunctionApplyRef(JsNameRef(functionName))
|
||||
return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
|
||||
fun buildDefaultCallWithThisObject(argumentsInfo: CallArgumentTranslator.ArgumentsInfo,
|
||||
thisObject: JsExpression,
|
||||
functionName: JsName,
|
||||
isNative: Boolean,
|
||||
hasSpreadOperator: Boolean): JsExpression {
|
||||
if (isNative && hasSpreadOperator) {
|
||||
return nativeSpreadFunWithThisObjectOrReceiver(argumentsInfo, functionName)
|
||||
}
|
||||
val functionRef = JsNameRef(functionName, thisObject)
|
||||
return JsInvocation(functionRef, argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
|
||||
fun buildDefaultCallWithoutReceiver(context: TranslationContext,
|
||||
argumentsInfo: CallArgumentTranslator.ArgumentsInfo,
|
||||
callableDescriptor: CallableDescriptor,
|
||||
functionName: JsName,
|
||||
isNative: Boolean,
|
||||
hasSpreadOperator: Boolean): JsExpression {
|
||||
if (isNative && hasSpreadOperator) {
|
||||
val functionCallRef = Namer.getFunctionApplyRef(JsNameRef(functionName))
|
||||
return JsInvocation(functionCallRef, argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
if (isNative) {
|
||||
return JsInvocation(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
|
||||
val functionCall = JsNameRef(functionName, qualifierForFunction)
|
||||
return JsInvocation(functionCall, argumentsInfo.getTranslateArguments())
|
||||
if (isNative) {
|
||||
return JsInvocation(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
val qualifierForFunction = context.getQualifierForDescriptor(callableDescriptor)
|
||||
val functionCall = JsNameRef(functionName, qualifierForFunction)
|
||||
return JsInvocation(functionCall, argumentsInfo.getTranslateArguments())
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
||||
@@ -115,7 +113,7 @@ class DefaultCallCase(callInfo: FunctionCallInfo): FunctionCallCase(callInfo) {
|
||||
}
|
||||
|
||||
|
||||
class DelegateFunctionIntrinsic(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo), DelegateIntrinsic<FunctionCallInfo> {
|
||||
object DelegateFunctionIntrinsic : DelegateIntrinsic<FunctionCallInfo> {
|
||||
override fun FunctionCallInfo.getArgs(): List<JsExpression> {
|
||||
return argumentsInfo.getTranslateArguments()
|
||||
}
|
||||
@@ -124,18 +122,16 @@ class DelegateFunctionIntrinsic(callInfo: FunctionCallInfo) : FunctionCallCase(c
|
||||
}
|
||||
}
|
||||
|
||||
class InvokeIntrinsic(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
||||
class object {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
if (!callInfo.callableDescriptor.getName().asString().equals("invoke"))
|
||||
return false
|
||||
val parameterCount = callInfo.callableDescriptor.getValueParameters().size()
|
||||
val funDeclaration = callInfo.callableDescriptor.getContainingDeclaration()
|
||||
return funDeclaration == ((if (callInfo.callableDescriptor.getReceiverParameter() == null)
|
||||
KotlinBuiltIns.getInstance().getFunction(parameterCount)
|
||||
else
|
||||
KotlinBuiltIns.getInstance().getExtensionFunction(parameterCount)))
|
||||
}
|
||||
object InvokeIntrinsic : FunctionCallCase {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
if (!callInfo.callableDescriptor.getName().asString().equals("invoke"))
|
||||
return false
|
||||
val parameterCount = callInfo.callableDescriptor.getValueParameters().size()
|
||||
val funDeclaration = callInfo.callableDescriptor.getContainingDeclaration()
|
||||
return funDeclaration == ((if (callInfo.callableDescriptor.getReceiverParameter() == null)
|
||||
KotlinBuiltIns.getInstance().getFunction(parameterCount)
|
||||
else
|
||||
KotlinBuiltIns.getInstance().getExtensionFunction(parameterCount)))
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.thisObject(): JsExpression {
|
||||
@@ -146,7 +142,11 @@ class InvokeIntrinsic(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
class ConstructorCallCase(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
||||
object ConstructorCallCase : FunctionCallCase {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
return callInfo.callableDescriptor is ConstructorDescriptor
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
||||
if (isNative()) {
|
||||
return JsNew(JsNameRef(functionName), argumentsInfo.getTranslateArguments())
|
||||
@@ -155,16 +155,14 @@ class ConstructorCallCase(callInfo: FunctionCallInfo) : FunctionCallCase(callInf
|
||||
}
|
||||
}
|
||||
|
||||
class ExpressionAsFunctionDescriptorIntrinsic(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
||||
class object {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
return callInfo.callableDescriptor is ExpressionAsFunctionDescriptor
|
||||
}
|
||||
object ExpressionAsFunctionDescriptorIntrinsic : FunctionCallCase {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
return callInfo.callableDescriptor is ExpressionAsFunctionDescriptor
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.noReceivers(): JsExpression {
|
||||
if (callableDescriptor !is ExpressionAsFunctionDescriptor) {
|
||||
throw IllegalStateException("callableDescriptor must be ExpressionAsFunctionDescriptor $callInfo")
|
||||
throw IllegalStateException("callableDescriptor must be ExpressionAsFunctionDescriptor $this")
|
||||
}
|
||||
val funRef = Translation.translateAsExpression((callableDescriptor as ExpressionAsFunctionDescriptor).getExpression()!!, context)
|
||||
return JsInvocation(funRef, argumentsInfo.getTranslateArguments())
|
||||
@@ -172,11 +170,9 @@ class ExpressionAsFunctionDescriptorIntrinsic(callInfo: FunctionCallInfo) : Func
|
||||
}
|
||||
}
|
||||
|
||||
class SuperCallCase(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
||||
class object {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
return callInfo.isSuperInvocation()
|
||||
}
|
||||
object SuperCallCase : FunctionCallCase {
|
||||
fun canApply(callInfo: FunctionCallInfo): Boolean {
|
||||
return callInfo.isSuperInvocation()
|
||||
}
|
||||
|
||||
override fun FunctionCallInfo.thisObject(): JsExpression { // TODO: spread operator
|
||||
@@ -186,17 +182,21 @@ class SuperCallCase(callInfo: FunctionCallInfo) : FunctionCallCase(callInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
fun createFunctionCases(): CallCaseDispatcher<FunctionCallCase, FunctionCallInfo> {
|
||||
val caseDispatcher = CallCaseDispatcher<FunctionCallCase, FunctionCallInfo>()
|
||||
fun FunctionCallInfo.translateFunctionCall(): JsExpression {
|
||||
val intrinsic = DelegateFunctionIntrinsic.intrinsic(this)
|
||||
|
||||
caseDispatcher.addCase(::ExpressionAsFunctionDescriptorIntrinsic) {ExpressionAsFunctionDescriptorIntrinsic.canApply(it)}
|
||||
caseDispatcher.addCase(::InvokeIntrinsic) {InvokeIntrinsic.canApply(it)}
|
||||
|
||||
caseDispatcher.addCase { DelegateFunctionIntrinsic(it).intrinsic() }
|
||||
|
||||
caseDispatcher.addCase(::ConstructorCallCase) {it.callableDescriptor is ConstructorDescriptor}
|
||||
caseDispatcher.addCase(::SuperCallCase) {SuperCallCase.canApply(it)}
|
||||
|
||||
caseDispatcher.addCase(::DefaultCallCase) { true } // TODO: fix this
|
||||
return caseDispatcher
|
||||
return when {
|
||||
intrinsic != null ->
|
||||
intrinsic
|
||||
ExpressionAsFunctionDescriptorIntrinsic.canApply(this) ->
|
||||
ExpressionAsFunctionDescriptorIntrinsic.translate(this)
|
||||
InvokeIntrinsic.canApply(this) ->
|
||||
InvokeIntrinsic.translate(this)
|
||||
ConstructorCallCase.canApply(this) ->
|
||||
ConstructorCallCase.translate(this)
|
||||
SuperCallCase.canApply(this) ->
|
||||
SuperCallCase.translate(this)
|
||||
else ->
|
||||
DefaultFunctionCallCase.translate(this)
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorFactory
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
|
||||
|
||||
|
||||
class NativeVariableAccessCase(callInfo: VariableAccessInfo) : VariableAccessCase(callInfo) {
|
||||
|
||||
object NativeVariableAccessCase : VariableAccessCase {
|
||||
override fun VariableAccessInfo.receiverArgument(): JsExpression {
|
||||
return constructAccessExpression(JsNameRef(variableName, receiverObject!!))
|
||||
}
|
||||
@@ -44,8 +43,7 @@ class NativeVariableAccessCase(callInfo: VariableAccessInfo) : VariableAccessCas
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultVariableAccessCase(callInfo: VariableAccessInfo) : VariableAccessCase(callInfo) {
|
||||
|
||||
object DefaultVariableAccessCase : VariableAccessCase {
|
||||
override fun VariableAccessInfo.noReceivers(): JsExpression {
|
||||
return constructAccessExpression(context.getQualifiedReference(variableDescriptor))
|
||||
}
|
||||
@@ -73,7 +71,7 @@ class DefaultVariableAccessCase(callInfo: VariableAccessInfo) : VariableAccessCa
|
||||
}
|
||||
}
|
||||
|
||||
class DelegatePropertyAccessIntrinsic(callInfo: VariableAccessInfo) : VariableAccessCase(callInfo), DelegateIntrinsic<VariableAccessInfo> {
|
||||
object DelegatePropertyAccessIntrinsic : DelegateIntrinsic<VariableAccessInfo> {
|
||||
override fun VariableAccessInfo.canBeApply(): Boolean {
|
||||
if(variableDescriptor is PropertyDescriptor) {
|
||||
return isGetAccess() || (variableDescriptor as PropertyDescriptor).isVar()
|
||||
@@ -98,7 +96,7 @@ class DelegatePropertyAccessIntrinsic(callInfo: VariableAccessInfo) : VariableAc
|
||||
}
|
||||
}
|
||||
|
||||
class SuperPropertyAccessCase(callInfo: VariableAccessInfo) : VariableAccessCase(callInfo) {
|
||||
object SuperPropertyAccessCase : VariableAccessCase {
|
||||
override fun VariableAccessInfo.thisObject(): JsExpression {
|
||||
val variableName = context.program().getStringLiteral(this.variableName.getIdent())
|
||||
return if (isGetAccess())
|
||||
@@ -108,12 +106,17 @@ class SuperPropertyAccessCase(callInfo: VariableAccessInfo) : VariableAccessCase
|
||||
}
|
||||
}
|
||||
|
||||
fun createVariableAccessCases(): CallCaseDispatcher<VariableAccessCase, VariableAccessInfo> {
|
||||
val caseDispatcher = CallCaseDispatcher<VariableAccessCase, VariableAccessInfo>()
|
||||
fun VariableAccessInfo.translateVariableAccess(): JsExpression {
|
||||
val intrinsic = DelegatePropertyAccessIntrinsic.intrinsic(this)
|
||||
|
||||
caseDispatcher.addCase { DelegatePropertyAccessIntrinsic(it).intrinsic() }
|
||||
caseDispatcher.addCase(::SuperPropertyAccessCase) { it.isSuperInvocation() }
|
||||
caseDispatcher.addCase(::NativeVariableAccessCase) { it.isNative() }
|
||||
caseDispatcher.addCase(::DefaultVariableAccessCase) { true } // TODO: fix this
|
||||
return caseDispatcher
|
||||
return when {
|
||||
intrinsic != null ->
|
||||
intrinsic
|
||||
isSuperInvocation() ->
|
||||
SuperPropertyAccessCase.translate(this)
|
||||
isNative() ->
|
||||
NativeVariableAccessCase.translate(this)
|
||||
else ->
|
||||
DefaultVariableAccessCase.translate(this)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user