JS: generate aliases for intrinsics.
This makes generated code more friendly to UglifyJS. For example, uglified circlet loses 15 kb.
This commit is contained in:
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.js.resolve.JsPlatform;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
@@ -87,16 +86,16 @@ public final class Namer {
|
||||
private static final String RECEIVER_PARAMETER_NAME = "$receiver";
|
||||
public static final String ANOTHER_THIS_PARAMETER_NAME = "$this";
|
||||
|
||||
private static final String THROW_NPE_FUN_NAME = "throwNPE";
|
||||
private static final String THROW_CLASS_CAST_EXCEPTION_FUN_NAME = "throwCCE";
|
||||
private static final String THROW_ILLEGAL_STATE_EXCEPTION_FUN_NAME = "throwISE";
|
||||
private static final String THROW_UNINITIALIZED_PROPERTY_ACCESS_EXCEPTION = "throwUPAE";
|
||||
public static final String THROW_NPE_FUN_NAME = "throwNPE";
|
||||
public static final String THROW_CLASS_CAST_EXCEPTION_FUN_NAME = "throwCCE";
|
||||
public static final String THROW_ILLEGAL_STATE_EXCEPTION_FUN_NAME = "throwISE";
|
||||
public static final String THROW_UNINITIALIZED_PROPERTY_ACCESS_EXCEPTION = "throwUPAE";
|
||||
private static final String PROTOTYPE_NAME = "prototype";
|
||||
private static final String CAPTURED_VAR_FIELD = "v";
|
||||
|
||||
public static final JsNameRef IS_ARRAY_FUN_REF = new JsNameRef("isArray", "Array");
|
||||
public static final String DEFINE_INLINE_FUNCTION = "defineInlineFunction";
|
||||
public static final String WRAP_FUNCTION = "wrapFunction";
|
||||
private static final String WRAP_FUNCTION = "wrapFunction";
|
||||
public static final String DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX = "$default";
|
||||
|
||||
private static final JsNameRef JS_OBJECT = new JsNameRef("Object");
|
||||
@@ -221,26 +220,6 @@ public final class Namer {
|
||||
return suggested.getNames().get(0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression throwNPEFunctionRef() {
|
||||
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression throwClassCastExceptionFunRef() {
|
||||
return new JsNameRef(THROW_CLASS_CAST_EXCEPTION_FUN_NAME, kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression throwIllegalStateExceptionFunRef() {
|
||||
return new JsNameRef(THROW_ILLEGAL_STATE_EXCEPTION_FUN_NAME, kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression throwUninitializedPropertyAccessExceptionFunRef() {
|
||||
return new JsNameRef(THROW_UNINITIALIZED_PROPERTY_ACCESS_EXCEPTION, kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsNameRef kotlin(@NotNull JsName name) {
|
||||
return pureFqn(name, kotlinObject());
|
||||
@@ -326,11 +305,6 @@ public final class Namer {
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static String generatePackageName(@NotNull FqName packageFqName) {
|
||||
return packageFqName.isRoot() ? getRootPackageName() : packageFqName.shortName().asString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression getUndefinedExpression() {
|
||||
return new JsPrefixOperation(JsUnaryOperator.VOID, new JsIntLiteral(0));
|
||||
|
||||
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.js.translate.context;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.LinkedHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -85,8 +83,6 @@ public final class StaticContext {
|
||||
@NotNull
|
||||
private final Generator<JsName> innerNames = new InnerNameGenerator();
|
||||
@NotNull
|
||||
private final Map<FqName, JsName> packageNames = Maps.newHashMap();
|
||||
@NotNull
|
||||
private final Generator<JsScope> scopes = new ScopeGenerator();
|
||||
@NotNull
|
||||
private final Generator<JsName> objectInstanceNames = new ObjectInstanceNameGenerator();
|
||||
@@ -123,9 +119,6 @@ public final class StaticContext {
|
||||
@NotNull
|
||||
private final Map<JsImportedModuleKey, JsImportedModule> importedModules = new LinkedHashMap<>();
|
||||
|
||||
@NotNull
|
||||
private final JsScope rootPackageScope;
|
||||
|
||||
@NotNull
|
||||
private final DeclarationExporter exporter = new DeclarationExporter(this);
|
||||
|
||||
@@ -142,6 +135,8 @@ public final class StaticContext {
|
||||
|
||||
private final Map<SpecialFunction, JsName> specialFunctions = new EnumMap<>(SpecialFunction.class);
|
||||
|
||||
private final Map<String, JsName> intrinsicNames = new HashMap<>();
|
||||
|
||||
public StaticContext(
|
||||
@NotNull BindingTrace bindingTrace,
|
||||
@NotNull JsConfig config,
|
||||
@@ -153,11 +148,10 @@ public final class StaticContext {
|
||||
|
||||
this.bindingTrace = bindingTrace;
|
||||
this.namer = Namer.newInstance(program.getRootScope());
|
||||
this.intrinsics = new Intrinsics(this);
|
||||
this.intrinsics = new Intrinsics();
|
||||
this.rootScope = fragment.getScope();
|
||||
this.config = config;
|
||||
this.currentModule = moduleDescriptor;
|
||||
rootPackageScope = new JsObjectScope(rootScope, "<root package>");
|
||||
|
||||
JsName kotlinName = rootScope.declareName(Namer.KOTLIN_NAME);
|
||||
createImportedModule(new JsImportedModuleKey(Namer.KOTLIN_LOWER_NAME, null), Namer.KOTLIN_LOWER_NAME, kotlinName, null);
|
||||
@@ -329,12 +323,6 @@ public final class StaticContext {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsNameRef getQualifiedReference(@NotNull FqName packageFqName) {
|
||||
JsName packageName = getNameForPackage(packageFqName);
|
||||
return pureFqn(packageName, packageFqName.isRoot() ? null : getQualifierForParentPackage(packageFqName.parent()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsName getNameForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof ClassDescriptor && KotlinBuiltIns.isAny((ClassDescriptor) descriptor)) {
|
||||
@@ -438,47 +426,13 @@ public final class StaticContext {
|
||||
return names;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsName getNameForPackage(@NotNull FqName packageFqName) {
|
||||
return ContainerUtil.getOrCreate(packageNames, packageFqName, (Factory<JsName>) () -> {
|
||||
String name = Namer.generatePackageName(packageFqName);
|
||||
return rootPackageScope.declareName(name);
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNameRef getQualifierForParentPackage(@NotNull FqName packageFqName) {
|
||||
JsNameRef result = null;
|
||||
JsNameRef qualifier = null;
|
||||
|
||||
FqName fqName = packageFqName;
|
||||
|
||||
while (true) {
|
||||
JsNameRef ref = pureFqn(getNameForPackage(fqName), null);
|
||||
|
||||
if (qualifier == null) {
|
||||
result = ref;
|
||||
}
|
||||
else {
|
||||
qualifier.setQualifier(ref);
|
||||
}
|
||||
|
||||
qualifier = ref;
|
||||
|
||||
if (fqName.isRoot()) break;
|
||||
fqName = fqName.parent();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsName importDeclaration(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression declaration) {
|
||||
private JsName importDeclaration(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression declaration) {
|
||||
JsName result = importDeclarationImpl(suggestedName, tag, declaration);
|
||||
fragment.getNameBindings().add(new JsNameBinding(tag, result));
|
||||
return result;
|
||||
@@ -871,4 +825,13 @@ public final class StaticContext {
|
||||
return name;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public JsExpression getReferenceToIntrinsic(@NotNull String name) {
|
||||
JsName resultName = intrinsicNames.computeIfAbsent(name, k ->
|
||||
importDeclaration(NameSuggestion.sanitizeName(name), "intrinsic:" + name, TranslationUtils.getIntrinsicFqn(name)));
|
||||
|
||||
return pureFqn(resultName, null);
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.js.backend.ast.*;
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.MetadataProperties;
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SpecialFunction;
|
||||
import org.jetbrains.kotlin.js.config.JsConfig;
|
||||
import org.jetbrains.kotlin.js.naming.NameSuggestion;
|
||||
import org.jetbrains.kotlin.js.naming.SuggestedName;
|
||||
import org.jetbrains.kotlin.js.translate.declaration.ClassModelGenerator;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.Intrinsics;
|
||||
@@ -317,6 +318,27 @@ public class TranslationContext {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression getReferenceToIntrinsic(@NotNull String intrinsicName) {
|
||||
JsExpression result;
|
||||
if (inlineFunctionContext == null || !isPublicInlineFunction()) {
|
||||
result = staticContext.getReferenceToIntrinsic(intrinsicName);
|
||||
}
|
||||
else {
|
||||
String tag = "intrinsic:" + intrinsicName;
|
||||
result = pureFqn(inlineFunctionContext.getImports().computeIfAbsent(tag, t -> {
|
||||
JsExpression imported = TranslationUtils.getIntrinsicFqn(intrinsicName);
|
||||
|
||||
JsName name = JsScope.declareTemporaryName(NameSuggestion.sanitizeName(intrinsicName));
|
||||
MetadataProperties.setImported(name, true);
|
||||
inlineFunctionContext.getImportBlock().getStatements().add(JsAstUtils.newVar(name, imported));
|
||||
return name;
|
||||
}), null);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsName getNameForObjectInstance(@NotNull ClassDescriptor descriptor) {
|
||||
return staticContext.getNameForObjectInstance(descriptor);
|
||||
|
||||
+7
-6
@@ -208,13 +208,14 @@ class ClassTranslator private constructor(
|
||||
private fun createMetadataRef() = JsNameRef(Namer.METADATA, context().getInnerReference(descriptor))
|
||||
|
||||
private fun addMetadataType() {
|
||||
val kotlinType = JsNameRef(Namer.CLASS_KIND_ENUM, Namer.KOTLIN_NAME)
|
||||
val typeRef = when {
|
||||
DescriptorUtils.isInterface(descriptor) -> JsNameRef(Namer.CLASS_KIND_INTERFACE, kotlinType)
|
||||
DescriptorUtils.isObject(descriptor) -> JsNameRef(Namer.CLASS_KIND_OBJECT, kotlinType)
|
||||
else -> JsNameRef(Namer.CLASS_KIND_CLASS, kotlinType)
|
||||
}
|
||||
val kindBuilder = StringBuilder(Namer.CLASS_KIND_ENUM + ".")
|
||||
kindBuilder.append(when {
|
||||
DescriptorUtils.isInterface(descriptor) -> Namer.CLASS_KIND_INTERFACE
|
||||
DescriptorUtils.isObject(descriptor) -> Namer.CLASS_KIND_OBJECT
|
||||
else -> Namer.CLASS_KIND_CLASS
|
||||
})
|
||||
|
||||
val typeRef = context().getReferenceToIntrinsic(kindBuilder.toString())
|
||||
metadataLiteral.propertyInitializers += JsPropertyInitializer(JsNameRef(Namer.METADATA_CLASS_KIND), typeRef)
|
||||
|
||||
val simpleName = descriptor.name
|
||||
|
||||
+2
-1
@@ -65,7 +65,8 @@ class EnumTranslator(
|
||||
val message = JsBinaryOperation(JsBinaryOperator.ADD,
|
||||
JsStringLiteral("No enum constant ${descriptor.fqNameSafe}."),
|
||||
nameParam.makeRef())
|
||||
val throwStatement = JsExpressionStatement(JsInvocation(Namer.throwIllegalStateExceptionFunRef(), message).source(psi))
|
||||
val throwFunction = context().getReferenceToIntrinsic(Namer.THROW_ILLEGAL_STATE_EXCEPTION_FUN_NAME)
|
||||
val throwStatement = JsExpressionStatement(JsInvocation(throwFunction, message).source(psi))
|
||||
|
||||
if (clauses.isNotEmpty()) {
|
||||
val defaultCase = JsDefault().apply {
|
||||
|
||||
+3
-3
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.js.translate.expression.translateFunction
|
||||
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
|
||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.*
|
||||
@@ -95,8 +94,9 @@ class DefaultPropertyTranslator(
|
||||
assert(descriptor is PropertyDescriptor) { "Property descriptor expected: $descriptor" }
|
||||
val result = backingFieldReference(context(), descriptor as PropertyDescriptor)
|
||||
if (getterDescriptor is PropertyAccessorDescriptor && getterDescriptor.correspondingProperty.isLateInit) {
|
||||
val throwFunction = context().getReferenceToIntrinsic(Namer.THROW_UNINITIALIZED_PROPERTY_ACCESS_EXCEPTION)
|
||||
function.body.statements += JsIf(JsBinaryOperation(JsBinaryOperator.EQ, result, JsNullLiteral()),
|
||||
JsReturn(JsInvocation(Namer.throwUninitializedPropertyAccessExceptionFunRef(),
|
||||
JsReturn(JsInvocation(throwFunction,
|
||||
JsStringLiteral(getterDescriptor.correspondingProperty.name.asString()))))
|
||||
}
|
||||
function.body.statements += JsReturn(result).apply { source = descriptor.source.getPsi() }
|
||||
@@ -195,7 +195,7 @@ fun TranslationContext.contextWithPropertyMetadataCreationIntrinsified(
|
||||
(delegatedCall.valueArgumentsByIndex!![1] as ExpressionValueArgument).valueArgument!!.getArgumentExpression()
|
||||
return innerContextWithAliasesForExpressions(mapOf(
|
||||
hostExpression to host,
|
||||
fakeArgumentExpression to JsNew(pureFqn("PropertyMetadata", Namer.kotlinObject()), listOf(propertyNameLiteral))
|
||||
fakeArgumentExpression to JsNew(getReferenceToIntrinsic("PropertyMetadata"), listOf(propertyNameLiteral))
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
return new JsInvocation(context.namer().kotlin(GET_KCLASS_FROM_EXPRESSION), receiver);
|
||||
}
|
||||
|
||||
return new JsInvocation(context.namer().kotlin(GET_KCLASS), UtilsKt.getReferenceToJsClass(lhs.getType(), context));
|
||||
return new JsInvocation(context.getReferenceToIntrinsic(GET_KCLASS), UtilsKt.getReferenceToJsClass(lhs.getType(), context));
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
onFail = new JsNullLiteral();
|
||||
}
|
||||
else {
|
||||
JsExpression throwCCEFunRef = Namer.throwClassCastExceptionFunRef();
|
||||
JsExpression throwCCEFunRef = context().getReferenceToIntrinsic(Namer.THROW_CLASS_CAST_EXCEPTION_FUN_NAME);
|
||||
onFail = new JsInvocation(throwCCEFunRef);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.js.translate.intrinsic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.js.translate.context.StaticContext;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.FunctionIntrinsics;
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
@@ -37,8 +36,8 @@ public final class Intrinsics {
|
||||
private final BinaryOperationIntrinsics binaryOperationIntrinsics = new BinaryOperationIntrinsics();
|
||||
private final ObjectIntrinsics objectIntrinsics;
|
||||
|
||||
public Intrinsics(@NotNull StaticContext staticContext) {
|
||||
objectIntrinsics = new ObjectIntrinsics(staticContext);
|
||||
public Intrinsics() {
|
||||
objectIntrinsics = new ObjectIntrinsics();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2010-2017 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.kotlin.js.backend.ast.JsExpression
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsInvocation
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsicWithReceiverComputed
|
||||
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
||||
|
||||
open class KotlinAliasedFunctionIntrinsic(private val functionName: String) : FunctionIntrinsicWithReceiverComputed() {
|
||||
override fun apply(
|
||||
receiver: JsExpression?,
|
||||
arguments: List<JsExpression>,
|
||||
context: TranslationContext
|
||||
): JsExpression {
|
||||
val function = context.getReferenceToIntrinsic(functionName)
|
||||
return JsInvocation(function, if (receiver == null) arguments else TranslationUtils.generateInvocationArguments(receiver, arguments))
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -47,7 +47,7 @@ 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") {
|
||||
private static final KotlinAliasedFunctionIntrinsic KOTLIN_ANY_EQUALS = new KotlinAliasedFunctionIntrinsic("equals") {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(
|
||||
@@ -65,7 +65,7 @@ public final class TopLevelFIF extends CompositeFIF {
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static final KotlinFunctionIntrinsic KOTLIN_EQUALS = new KotlinFunctionIntrinsic("equals");
|
||||
public static final KotlinAliasedFunctionIntrinsic KOTLIN_EQUALS = new KotlinAliasedFunctionIntrinsic("equals");
|
||||
|
||||
@NotNull
|
||||
private static final KotlinFunctionIntrinsic KOTLIN_SUBSEQUENCE = new KotlinFunctionIntrinsic("subSequence");
|
||||
@@ -73,7 +73,7 @@ public final class TopLevelFIF extends CompositeFIF {
|
||||
@NotNull
|
||||
private static final DescriptorPredicate HASH_CODE_IN_ANY = pattern("kotlin", "Any", "hashCode");
|
||||
@NotNull
|
||||
private static final KotlinFunctionIntrinsic KOTLIN_HASH_CODE = new KotlinFunctionIntrinsic("hashCode");
|
||||
private static final KotlinAliasedFunctionIntrinsic KOTLIN_HASH_CODE = new KotlinAliasedFunctionIntrinsic("hashCode");
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic RETURN_RECEIVER_INTRINSIC = new FunctionIntrinsicWithReceiverComputed() {
|
||||
@@ -164,7 +164,7 @@ public final class TopLevelFIF extends CompositeFIF {
|
||||
|
||||
|
||||
@NotNull
|
||||
public static final KotlinFunctionIntrinsic TO_STRING = new KotlinFunctionIntrinsic("toString");
|
||||
public static final KotlinAliasedFunctionIntrinsic TO_STRING = new KotlinAliasedFunctionIntrinsic("toString");
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic CHAR_TO_STRING = new FunctionIntrinsicWithReceiverComputed() {
|
||||
|
||||
+4
-14
@@ -20,25 +20,16 @@ import org.jetbrains.kotlin.builtins.CompanionObjectMapping
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsExpression
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.StaticContext
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
|
||||
class DefaultClassObjectIntrinsic(val staticContext: StaticContext, val tag: String, val fqName: FqName): ObjectIntrinsic {
|
||||
private val innerName: JsName by lazy {
|
||||
val declaration = JsAstUtils.replaceRootReference(staticContext.getQualifiedReference(fqName), Namer.kotlinObject())
|
||||
staticContext.importDeclaration(fqName.shortName().asString(), tag, declaration)
|
||||
}
|
||||
|
||||
override fun apply(context: TranslationContext) = JsAstUtils.pureFqn(innerName, null)
|
||||
class DefaultClassObjectIntrinsic( val fqName: FqName): ObjectIntrinsic {
|
||||
override fun apply(context: TranslationContext) = context.getReferenceToIntrinsic(fqName.asString())
|
||||
}
|
||||
|
||||
class ObjectIntrinsics(private val staticContext: StaticContext) {
|
||||
class ObjectIntrinsics {
|
||||
private val cache = mutableMapOf<ClassDescriptor, ObjectIntrinsic>()
|
||||
|
||||
fun getIntrinsic(classDescriptor: ClassDescriptor) = cache.getOrPut(classDescriptor) { createIntrinsic(classDescriptor) }
|
||||
@@ -53,8 +44,7 @@ class ObjectIntrinsics(private val staticContext: StaticContext) {
|
||||
val containingDeclaration = classDescriptor.containingDeclaration
|
||||
val name = Name.identifier(containingDeclaration.name.asString() + "CompanionObject")
|
||||
|
||||
return DefaultClassObjectIntrinsic(
|
||||
staticContext, "intrinsic:kotlin.js.internal.${name.asString()}", FqName("kotlin.js.internal").child(name))
|
||||
return DefaultClassObjectIntrinsic(FqName("kotlin.js.internal").child(name))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -135,7 +135,7 @@ object CallableReferenceTranslator {
|
||||
function.body.statements += JsReturn(TranslationUtils.coerce(context, invocation, context.currentModule.builtIns.anyType))
|
||||
|
||||
val rawCallableRef = bindIfNecessary(function, receiver)
|
||||
return wrapFunctionCallableRef(expression.callableReference.getReferencedName(), rawCallableRef)
|
||||
return context.wrapFunctionCallableRef(expression.callableReference.getReferencedName(), rawCallableRef)
|
||||
}
|
||||
|
||||
private fun translateForProperty(
|
||||
@@ -168,7 +168,7 @@ object CallableReferenceTranslator {
|
||||
null
|
||||
}
|
||||
|
||||
return wrapPropertyCallableRef(receiver, descriptor, expression.callableReference.getReferencedName(), getter, setter)
|
||||
return context.wrapPropertyCallableRef(receiver, descriptor, expression.callableReference.getReferencedName(), getter, setter)
|
||||
}
|
||||
|
||||
private fun isSetterVisible(descriptor: PropertyDescriptor, context: TranslationContext): Boolean {
|
||||
@@ -225,7 +225,7 @@ object CallableReferenceTranslator {
|
||||
}
|
||||
}
|
||||
|
||||
private fun wrapPropertyCallableRef(
|
||||
private fun TranslationContext.wrapPropertyCallableRef(
|
||||
receiver: JsExpression?,
|
||||
descriptor: PropertyDescriptor,
|
||||
name: String,
|
||||
@@ -238,7 +238,7 @@ object CallableReferenceTranslator {
|
||||
}
|
||||
val nameLiteral = JsStringLiteral(name)
|
||||
val argCountLiteral = JsIntLiteral(argCount)
|
||||
val invokeFun = JsNameRef(Namer.PROPERTY_CALLABLE_REF, Namer.kotlinObject())
|
||||
val invokeFun = getReferenceToIntrinsic(Namer.PROPERTY_CALLABLE_REF)
|
||||
val invocation = JsInvocation(invokeFun, nameLiteral, argCountLiteral, getter)
|
||||
if (setter != null) {
|
||||
invocation.arguments += setter
|
||||
@@ -246,13 +246,12 @@ object CallableReferenceTranslator {
|
||||
return invocation
|
||||
}
|
||||
|
||||
private fun wrapFunctionCallableRef(
|
||||
private fun TranslationContext.wrapFunctionCallableRef(
|
||||
name: String,
|
||||
function: JsExpression
|
||||
): JsExpression {
|
||||
val nameLiteral = JsStringLiteral(name)
|
||||
val invokeName = Namer.FUNCTION_CALLABLE_REF
|
||||
val invokeFun = JsNameRef(invokeName, Namer.kotlinObject())
|
||||
val invokeFun = getReferenceToIntrinsic(Namer.FUNCTION_CALLABLE_REF)
|
||||
invokeFun.sideEffects = SideEffectKind.PURE
|
||||
val invocation = JsInvocation(invokeFun, nameLiteral, function)
|
||||
invocation.isCallableReference = true
|
||||
|
||||
+2
-2
@@ -83,8 +83,8 @@ public class VariableAccessTranslator extends AbstractTranslator implements Acce
|
||||
else if (original instanceof LocalVariableDescriptor) {
|
||||
LocalVariableDescriptor originalLocal = (LocalVariableDescriptor) original;
|
||||
if (originalLocal.isLateInit()) {
|
||||
JsInvocation throwInvocation = new JsInvocation(Namer.throwUninitializedPropertyAccessExceptionFunRef(),
|
||||
new JsStringLiteral(originalLocal.getName().asString()));
|
||||
JsExpression throwFunction = context().getReferenceToIntrinsic(Namer.THROW_UNINITIALIZED_PROPERTY_ACCESS_EXCEPTION);
|
||||
JsInvocation throwInvocation = new JsInvocation(throwFunction, new JsStringLiteral(originalLocal.getName().asString()));
|
||||
return new JsConditional(new JsBinaryOperation(JsBinaryOperator.EQ, e, new JsNullLiteral()), throwInvocation, e);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-12
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.utils;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -226,17 +227,6 @@ public final class TranslationUtils {
|
||||
return Translation.translateAsExpression(baseExpression, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateLeftExpression(
|
||||
@NotNull TranslationContext context,
|
||||
@NotNull KtBinaryExpression expression,
|
||||
@NotNull JsBlock block
|
||||
) {
|
||||
KtExpression left = expression.getLeft();
|
||||
assert left != null : "Binary expression should have a left expression: " + expression.getText();
|
||||
return Translation.translateAsExpression(left, context, block);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateRightExpression(
|
||||
@NotNull TranslationContext context,
|
||||
@@ -305,7 +295,7 @@ public final class TranslationUtils {
|
||||
|
||||
@NotNull
|
||||
public static JsConditional sure(@NotNull JsExpression expression, @NotNull TranslationContext context) {
|
||||
JsInvocation throwNPE = new JsInvocation(Namer.throwNPEFunctionRef());
|
||||
JsInvocation throwNPE = new JsInvocation(context.getReferenceToIntrinsic(Namer.THROW_NPE_FUN_NAME));
|
||||
JsConditional ensureNotNull = notNullConditional(expression, throwNPE, context);
|
||||
|
||||
JsExpression thenExpression = ensureNotNull.getThenExpression();
|
||||
@@ -548,4 +538,13 @@ public final class TranslationUtils {
|
||||
public static String getTagForSpecialFunction(@NotNull SpecialFunction specialFunction) {
|
||||
return "special:" + specialFunction.name();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression getIntrinsicFqn(@NotNull String name) {
|
||||
JsExpression fqn = pureFqn(Namer.KOTLIN_NAME, null);
|
||||
for (String part : StringUtil.split(name, ".")) {
|
||||
fqn = pureFqn(part, fqn);
|
||||
}
|
||||
return fqn;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
// EXPECTED_REACHABLE_NODES: 995
|
||||
// HAS_NO_CAPTURED_VARS: function=A_init except=Kotlin;A
|
||||
// HAS_NO_CAPTURED_VARS: function=A_init except=Kotlin;A;equals
|
||||
|
||||
class A() {
|
||||
var y: String? = null
|
||||
|
||||
+1
-1
@@ -21,4 +21,4 @@ fun bar(x: Int) {
|
||||
println("%")
|
||||
}
|
||||
|
||||
// LINES: 1 1 1 1 1 1 1 17 2 2 3 3 4 7 7 9 9 10 10 11 14 14 16 16 1 1 22 20 20 20 20 2 2 3 3 4 3 7 7 9 9 10 10 11 10 14 14 16 16 * 20 21 21
|
||||
// LINES: 1 1 1 1 1 1 1 1 1 17 2 2 3 3 4 7 7 9 9 10 10 11 14 14 16 16 1 1 1 1 22 20 20 20 20 2 2 3 3 4 3 7 7 9 9 10 10 11 10 14 14 16 16 * 20 21 21
|
||||
Reference in New Issue
Block a user