Minor FunctionIntrinsics refactoring

This commit is contained in:
Anton Bannykh
2018-03-01 15:38:36 +03:00
committed by Anton Bannykh
parent 5b11ee251f
commit 60e487dcec
9 changed files with 57 additions and 116 deletions
@@ -276,7 +276,7 @@ interface DelegateIntrinsic<in I : CallInfo> {
// 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)
}
}
@@ -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)
}
@@ -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<FunctionDescriptor, FunctionIntrinsic> intrinsicCache = new THashMap<>();
@NotNull
private final List<FunctionIntrinsicFactory> 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;
}
}
@@ -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<FunctionDescriptor, FunctionIntrinsic?>()
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
}
}
}
@@ -25,21 +25,4 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
*/
abstract class FunctionIntrinsic {
abstract fun apply(callInfo: CallInfo, arguments: List<JsExpression>, 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<JsExpression>, context: TranslationContext) =
throw UnsupportedOperationException("FunctionIntrinsic#NO_INTRINSIC_#apply")
}
@JvmStatic
protected fun getThisOrReceiverOrNull(callInfo: CallInfo): JsExpression? =
callInfo.dispatchReceiver ?: callInfo.extensionReceiver
}
}
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext
abstract class FunctionIntrinsicWithReceiverComputed : FunctionIntrinsic() {
override fun apply(callInfo: CallInfo, arguments: List<JsExpression>, context: TranslationContext): JsExpression {
return apply(getThisOrReceiverOrNull(callInfo), arguments, context)
return apply(callInfo.dispatchReceiver ?: callInfo.extensionReceiver, arguments, context)
}
abstract fun apply(receiver: JsExpression?, arguments: List<JsExpression>, context: TranslationContext): JsExpression
@@ -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);
}
@@ -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;
}
@@ -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)