diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java index 1e5ae3c551b..b932ba79101 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java @@ -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)); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index a1f7b629ae1..570e89791cc 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -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 innerNames = new InnerNameGenerator(); @NotNull - private final Map packageNames = Maps.newHashMap(); - @NotNull private final Generator scopes = new ScopeGenerator(); @NotNull private final Generator objectInstanceNames = new ObjectInstanceNameGenerator(); @@ -123,9 +119,6 @@ public final class StaticContext { @NotNull private final Map 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 specialFunctions = new EnumMap<>(SpecialFunction.class); + private final Map 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, ""); 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) () -> { - 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); + } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java index e3e1a583fbf..7e79141058c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java @@ -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); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt index 458f664f813..45d06d93a54 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt @@ -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 diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/EnumTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/EnumTranslator.kt index 43784f00225..c547f9bb68b 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/EnumTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/EnumTranslator.kt @@ -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 { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/PropertyTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/PropertyTranslator.kt index 2ffe76ee9c7..b2cfb84a5c9 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/PropertyTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/PropertyTranslator.kt @@ -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)) )) } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java index 6b2f6fd7da5..9cc0169bad2 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java @@ -263,7 +263,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { 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)); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java index 30c29147da2..08926c5b3c1 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java @@ -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); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java index a010936b3d2..6528ab3bf79 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/Intrinsics.java @@ -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 diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/KotlinAliasedFunctionIntrinsic.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/KotlinAliasedFunctionIntrinsic.kt new file mode 100644 index 00000000000..eef982c3522 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/KotlinAliasedFunctionIntrinsic.kt @@ -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, + context: TranslationContext + ): JsExpression { + val function = context.getReferenceToIntrinsic(functionName) + return JsInvocation(function, if (receiver == null) arguments else TranslationUtils.generateInvocationArguments(receiver, arguments)) + } +} \ No newline at end of file diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java index af13c6949ff..487763c4dd8 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/TopLevelFIF.java @@ -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() { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt index 41910d9149c..877ccd61147 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/objects/objectsIntrinsics.kt @@ -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() 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)) } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt index 82d2e1fd4d3..33477cdd581 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallableReferenceTranslator.kt @@ -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 diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/VariableAccessTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/VariableAccessTranslator.java index eaba7744093..1511324bad2 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/VariableAccessTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/VariableAccessTranslator.java @@ -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); } } 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 9aec9041bab..35d98c35268 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 @@ -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; + } } diff --git a/js/js.translator/testData/box/expression/evaluationOrder/secondaryConstructorTemporaryVars.kt b/js/js.translator/testData/box/expression/evaluationOrder/secondaryConstructorTemporaryVars.kt index ab19a3ea3bb..c532bd5e70b 100644 --- a/js/js.translator/testData/box/expression/evaluationOrder/secondaryConstructorTemporaryVars.kt +++ b/js/js.translator/testData/box/expression/evaluationOrder/secondaryConstructorTemporaryVars.kt @@ -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 diff --git a/js/js.translator/testData/lineNumbers/inlineReturn.kt b/js/js.translator/testData/lineNumbers/inlineReturn.kt index 46c862ad3b3..89b2acc48d4 100644 --- a/js/js.translator/testData/lineNumbers/inlineReturn.kt +++ b/js/js.translator/testData/lineNumbers/inlineReturn.kt @@ -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 \ No newline at end of file +// 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 \ No newline at end of file