From 60e487dcece83b1dcbaff9811049bdaa33e0c1d3 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Thu, 1 Mar 2018 15:38:36 +0300 Subject: [PATCH] Minor FunctionIntrinsics refactoring --- .../callTranslator/CallTranslator.kt | 2 +- .../js/translate/intrinsic/Intrinsics.kt | 2 +- .../functions/FunctionIntrinsics.java | 94 ------------------- .../intrinsic/functions/FunctionIntrinsics.kt | 51 ++++++++++ .../functions/basic/FunctionIntrinsic.kt | 17 ---- .../FunctionIntrinsicWithReceiverComputed.kt | 2 +- .../IntrinsicIncrementTranslator.java | 1 + .../js/translate/utils/TranslationUtils.java | 2 +- .../kotlin/js/translate/utils/utils.kt | 2 +- 9 files changed, 57 insertions(+), 116 deletions(-) delete mode 100644 js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java create mode 100644 js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt index 3c3d3b39f3a..f1e49fce2c4 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt @@ -276,7 +276,7 @@ interface DelegateIntrinsic { // Now intrinsic support only FunctionDescriptor. See DelegatePropertyAccessIntrinsic.getDescriptor() if (descriptor is FunctionDescriptor) { val intrinsic = context.intrinsics().getFunctionIntrinsic(descriptor) - if (intrinsic.exists()) { + if (intrinsic != null) { return intrinsic.apply(this, getArgs(), context) } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt index fc7a85f8d3a..3e33488cb33 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.kt @@ -39,7 +39,7 @@ class Intrinsics { return binaryOperationIntrinsics.getIntrinsic(expression, context) } - fun getFunctionIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic { + fun getFunctionIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { return functionIntrinsics.getIntrinsic(descriptor) } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java deleted file mode 100644 index f0b81ae8a46..00000000000 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.js.translate.intrinsic.functions; - -import com.google.common.collect.Lists; -import gnu.trove.THashMap; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.descriptors.FunctionDescriptor; -import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic; -import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.*; - -import java.util.List; -import java.util.Map; - -public final class FunctionIntrinsics { - - @NotNull - private final Map intrinsicCache = new THashMap<>(); - - @NotNull - private final List factories = Lists.newArrayList(); - - public FunctionIntrinsics() { - registerFactories(); - } - - private void registerFactories() { - register(LongOperationFIF.INSTANCE); - register(PrimitiveUnaryOperationFIF.INSTANCE); - register(StringPlusCharFIF.INSTANCE); - register(PrimitiveBinaryOperationFIF.INSTANCE); - register(ArrayFIF.INSTANCE); - register(TopLevelFIF.INSTANCE); - register(NumberAndCharConversionFIF.INSTANCE); - register(ThrowableConstructorIntrinsicFactory.INSTANCE); - register(ExceptionPropertyIntrinsicFactory.INSTANCE); - register(AsDynamicFIF.INSTANCE); - register(CoroutineContextFIF.INSTANCE); - register(SuspendCoroutineUninterceptedOrReturnFIF.INSTANCE); - register(InterceptedFIF.INSTANCE); - } - - private void register(@NotNull FunctionIntrinsicFactory instance) { - factories.add(instance); - } - - @NotNull - public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) { - FunctionIntrinsic intrinsic = lookUpCache(descriptor); - if (intrinsic != null) { - return intrinsic; - } - intrinsic = computeAndCacheIntrinsic(descriptor); - return intrinsic; - } - - @Nullable - private FunctionIntrinsic lookUpCache(@NotNull FunctionDescriptor descriptor) { - return intrinsicCache.get(descriptor); - } - - @NotNull - private FunctionIntrinsic computeAndCacheIntrinsic(@NotNull FunctionDescriptor descriptor) { - FunctionIntrinsic result = computeIntrinsic(descriptor); - intrinsicCache.put(descriptor, result); - return result; - } - - @NotNull - private FunctionIntrinsic computeIntrinsic(@NotNull FunctionDescriptor descriptor) { - for (FunctionIntrinsicFactory factory : factories) { - FunctionIntrinsic intrinsic = factory.getIntrinsic(descriptor); - if (intrinsic != null) { - return intrinsic; - } - } - return FunctionIntrinsic.NO_INTRINSIC; - } -} diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt new file mode 100644 index 00000000000..e2269a9f471 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/FunctionIntrinsics.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.translate.intrinsic.functions + +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic +import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.* +import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult + +class FunctionIntrinsics { + + private val intrinsicCache = mutableMapOf() + + private val factories = listOf( + LongOperationFIF, + PrimitiveUnaryOperationFIF.INSTANCE, + StringPlusCharFIF, + PrimitiveBinaryOperationFIF.INSTANCE, + ArrayFIF, + TopLevelFIF.INSTANCE, + NumberAndCharConversionFIF, + ThrowableConstructorIntrinsicFactory, + ExceptionPropertyIntrinsicFactory, + AsDynamicFIF, + CoroutineContextFIF, + SuspendCoroutineUninterceptedOrReturnFIF, + InterceptedFIF + ) + + fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? { + if (descriptor in intrinsicCache) return intrinsicCache[descriptor] + + return factories.firstNotNullResult { it.getIntrinsic(descriptor) }.also { + intrinsicCache[descriptor] = it + } + } +} diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsic.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsic.kt index b21384c948e..40c283a43da 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsic.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsic.kt @@ -25,21 +25,4 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext */ abstract class FunctionIntrinsic { abstract fun apply(callInfo: CallInfo, arguments: List, context: TranslationContext): JsExpression - - open fun exists(): Boolean = true - - companion object { - @JvmField - val NO_INTRINSIC: FunctionIntrinsic = object : FunctionIntrinsic() { - override fun exists() = false - - override fun apply(callInfo: CallInfo, arguments: List, context: TranslationContext) = - throw UnsupportedOperationException("FunctionIntrinsic#NO_INTRINSIC_#apply") - - } - - @JvmStatic - protected fun getThisOrReceiverOrNull(callInfo: CallInfo): JsExpression? = - callInfo.dispatchReceiver ?: callInfo.extensionReceiver - } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsicWithReceiverComputed.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsicWithReceiverComputed.kt index 32e729f18cf..d126da6aecf 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsicWithReceiverComputed.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/FunctionIntrinsicWithReceiverComputed.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext abstract class FunctionIntrinsicWithReceiverComputed : FunctionIntrinsic() { override fun apply(callInfo: CallInfo, arguments: List, context: TranslationContext): JsExpression { - return apply(getThisOrReceiverOrNull(callInfo), arguments, context) + return apply(callInfo.dispatchReceiver ?: callInfo.extensionReceiver, arguments, context) } abstract fun apply(receiver: JsExpression?, arguments: List, context: TranslationContext): JsExpression diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java index 729341eba83..bff0f711e26 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/operation/IntrinsicIncrementTranslator.java @@ -42,6 +42,7 @@ public final class IntrinsicIncrementTranslator extends IncrementTranslator { @NotNull protected JsExpression operationExpression(@NotNull TranslationContext context, @NotNull JsExpression receiver) { FunctionIntrinsic intrinsic = context.intrinsics().getFunctionIntrinsic(resolvedCall.getResultingDescriptor()); + assert intrinsic != null; CallInfo callInfo = CallInfoKt.getCallInfo(context, resolvedCall, receiver); return intrinsic.apply(callInfo, Collections.emptyList(), context); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java index f8492ed8daf..647346869be 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/TranslationUtils.java @@ -265,7 +265,7 @@ public final class TranslationUtils { return false; } - if (context.intrinsics().getFunctionIntrinsic((FunctionDescriptor) operationDescriptor).exists()) return true; + if (context.intrinsics().getFunctionIntrinsic((FunctionDescriptor) operationDescriptor) != null) return true; return false; } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt index a4941776cc1..dd820e2dc0d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/utils.kt @@ -79,7 +79,7 @@ fun generateDelegateCall( } val intrinsic = context.intrinsics().getFunctionIntrinsic(toDescriptor) - val invocation = if (intrinsic.exists() && intrinsic is FunctionIntrinsicWithReceiverComputed) { + val invocation = if (intrinsic is FunctionIntrinsicWithReceiverComputed) { intrinsic.apply(thisObject, args, context) } else { JsInvocation(overriddenMemberFunctionRef, args)