Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF Maven / Gradle / Ivy
/*
* Copyright 2010-2016 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.factories;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
import org.jetbrains.kotlin.js.backend.ast.JsExpression;
import org.jetbrains.kotlin.js.backend.ast.JsInvocation;
import org.jetbrains.kotlin.js.backend.ast.JsNameRef;
import org.jetbrains.kotlin.js.patterns.DescriptorPredicate;
import org.jetbrains.kotlin.js.patterns.NamePredicate;
import org.jetbrains.kotlin.js.translate.callTranslator.CallInfo;
import org.jetbrains.kotlin.js.translate.callTranslator.CallInfoExtensionsKt;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsicWithReceiverComputed;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.js.translate.utils.UtilsKt;
import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.types.KotlinType;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES;
import static org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern;
public final class TopLevelFIF extends CompositeFIF {
public static final DescriptorPredicate EQUALS_IN_ANY = pattern("kotlin", "Any", "equals");
@NotNull
private static final KotlinFunctionIntrinsic KOTLIN_ANY_EQUALS = new KotlinFunctionIntrinsic("equals") {
@NotNull
@Override
public JsExpression apply(
@NotNull CallInfo callInfo,
@NotNull List arguments, @NotNull TranslationContext context
) {
if (CallInfoExtensionsKt.isSuperInvocation(callInfo)) {
JsExpression dispatchReceiver = callInfo.getDispatchReceiver();
assert arguments.size() == 1 && dispatchReceiver != null;
return JsAstUtils.equality(dispatchReceiver, arguments.get(0));
}
return super.apply(callInfo, arguments, context);
}
};
@NotNull
public static final KotlinFunctionIntrinsic KOTLIN_EQUALS = new KotlinFunctionIntrinsic("equals");
@NotNull
private static final KotlinFunctionIntrinsic KOTLIN_SUBSEQUENCE = new KotlinFunctionIntrinsic("subSequence");
@NotNull
private static final DescriptorPredicate HASH_CODE_IN_ANY = pattern("kotlin", "Any", "hashCode");
@NotNull
private static final KotlinFunctionIntrinsic KOTLIN_HASH_CODE = new KotlinFunctionIntrinsic("hashCode");
@NotNull
private static final FunctionIntrinsic RETURN_RECEIVER_INTRINSIC = new FunctionIntrinsicWithReceiverComputed() {
@NotNull
@Override
public JsExpression apply(
@Nullable JsExpression receiver,
@NotNull List arguments,
@NotNull TranslationContext context
) {
assert receiver != null;
return receiver;
}
};
private static JsExpression getReferenceToOnlyTypeParameter(
@NotNull CallInfo callInfo, @NotNull TranslationContext context
) {
ResolvedCall resolvedCall = callInfo.getResolvedCall();
Map typeArguments = resolvedCall.getTypeArguments();
assert typeArguments.size() == 1;
KotlinType type = typeArguments.values().iterator().next();
return UtilsKt.getReferenceToJsClass(type, context);
}
private static final FunctionIntrinsic JS_CLASS_FUN_INTRINSIC = new FunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(
@NotNull CallInfo callInfo,
@NotNull List arguments,
@NotNull TranslationContext context
) {
return getReferenceToOnlyTypeParameter(callInfo, context);
}
};
private static final FunctionIntrinsic ENUM_VALUES_INTRINSIC = new FunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(
@NotNull CallInfo callInfo,
@NotNull List arguments,
@NotNull TranslationContext context
) {
JsExpression enumClassRef = getReferenceToOnlyTypeParameter(callInfo, context);
FunctionDescriptor fd = DescriptorFactory.createEnumValuesMethod(context.getCurrentModule().getBuiltIns().getEnum());
return new JsInvocation(new JsNameRef(context.getNameForDescriptor(fd), enumClassRef));
}
};
private static final FunctionIntrinsic ENUM_VALUE_OF_INTRINSIC = new FunctionIntrinsic() {
@NotNull
@Override
public JsExpression apply(
@NotNull CallInfo callInfo,
@NotNull List arguments,
@NotNull TranslationContext context
) {
JsExpression arg = arguments.get(2); // The first two are reified parameters
JsExpression enumClassRef = getReferenceToOnlyTypeParameter(callInfo, context);
FunctionDescriptor fd = DescriptorFactory.createEnumValueOfMethod(context.getCurrentModule().getBuiltIns().getEnum());
return new JsInvocation(new JsNameRef(context.getNameForDescriptor(fd), enumClassRef), arg);
}
};
private static final FunctionIntrinsic STRING_SUBSTRING = new FunctionIntrinsicWithReceiverComputed() {
@NotNull
@Override
public JsExpression apply(
@Nullable JsExpression receiver,
@NotNull List arguments,
@NotNull TranslationContext context
) {
return new JsInvocation(new JsNameRef("substring", receiver), arguments);
}
};
@NotNull
public static final KotlinFunctionIntrinsic TO_STRING = new KotlinFunctionIntrinsic("toString");
@NotNull
public static final FunctionIntrinsic CHAR_TO_STRING = new FunctionIntrinsicWithReceiverComputed() {
@NotNull
@Override
public JsExpression apply(
@Nullable JsExpression receiver, @NotNull List arguments, @NotNull TranslationContext context
) {
assert receiver != null;
return JsAstUtils.charToString(receiver);
}
};
@NotNull
public static final FunctionIntrinsicFactory INSTANCE = new TopLevelFIF();
private TopLevelFIF() {
add(EQUALS_IN_ANY, KOTLIN_ANY_EQUALS);
add(pattern("Char.toString"), CHAR_TO_STRING);
add(pattern("kotlin", "toString").isExtensionOf(FQ_NAMES.any.asString()), TO_STRING);
add(pattern("kotlin", "equals").isExtensionOf(FQ_NAMES.any.asString()), KOTLIN_EQUALS);
add(HASH_CODE_IN_ANY, KOTLIN_HASH_CODE);
add(pattern(NamePredicate.PRIMITIVE_NUMBERS, "equals"), KOTLIN_EQUALS);
add(pattern("String|Boolean|Char|Number.equals"), KOTLIN_EQUALS);
add(pattern("String.subSequence"), STRING_SUBSTRING);
add(pattern("CharSequence.subSequence"), KOTLIN_SUBSEQUENCE);
add(pattern("kotlin", "iterator").isExtensionOf(FQ_NAMES.iterator.asString()), RETURN_RECEIVER_INTRINSIC);
add(pattern("kotlin.js", "Json", "get"), ArrayFIF.GET_INTRINSIC);
add(pattern("kotlin.js", "Json", "set"), ArrayFIF.SET_INTRINSIC);
add(pattern("kotlin.js", "jsClass"), JS_CLASS_FUN_INTRINSIC);
add(pattern("kotlin", "enumValues"), ENUM_VALUES_INTRINSIC);
add(pattern("kotlin", "enumValueOf"), ENUM_VALUE_OF_INTRINSIC);
}
}