From b053c549333907b7fc51b0414c08becce66ac692 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 30 Mar 2016 11:57:50 +0300 Subject: [PATCH] Add more hints about property access that is provable has no side effect. Refactor namer --- .../kotlin/js/inline/FunctionReader.kt | 2 +- .../clean/TemporaryVariableElimination.kt | 13 +++-- .../inline/clean/removeDefaultInitializers.kt | 2 +- .../callTranslator/FunctionCallCases.kt | 12 ++-- .../kotlin/js/translate/context/Namer.java | 58 +++++++++++-------- .../translate/context/TranslationContext.java | 5 +- .../declaration/JsDataClassGenerator.java | 9 ++- .../declaration/PropertyTranslator.kt | 3 +- .../js/translate/expression/InlineMetadata.kt | 5 +- .../expression/PatternTranslator.java | 2 +- .../ClassInitializerTranslator.java | 7 +-- .../basic/BuiltInFunctionIntrinsic.java | 4 +- .../basic/BuiltInPropertyIntrinsic.java | 4 +- .../functions/factories/ArrayFIF.java | 8 +-- .../factories/KotlinFunctionIntrinsic.java | 3 +- .../factories/ProgressionCompanionFIF.kt | 6 +- .../functions/factories/TopLevelFIF.java | 3 +- .../reference/CallArgumentTranslator.kt | 7 ++- .../utils/FunctionBodyTranslator.java | 3 +- .../kotlin/js/translate/utils/JsAstUtils.java | 50 +++++++++++----- 20 files changed, 119 insertions(+), 87 deletions(-) diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt index 0bd2faf7b98..ce6bebc932c 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt @@ -122,7 +122,7 @@ class FunctionReader(private val context: TranslationContext) { val moduleReference = context.namer().getModuleReference(moduleNameLiteral) val replacements = hashMapOf(moduleRootVariable[moduleName]!! to moduleReference, - moduleKotlinVariable[moduleName]!! to Namer.KOTLIN_OBJECT_REF) + moduleKotlinVariable[moduleName]!! to Namer.kotlinObject()) replaceExternalNames(function, replacements) return function } diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt index 2b253b25d3f..857d941cd4f 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/TemporaryVariableElimination.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.js.inline.clean import com.google.dart.compiler.backend.js.ast.* -import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata import com.google.dart.compiler.backend.js.ast.metadata.synthetic import com.google.dart.compiler.backend.js.ast.metadata.withoutSideEffects import org.jetbrains.kotlin.js.inline.util.collectDefinedNames @@ -179,15 +178,17 @@ internal class TemporaryVariableElimination(private val root: JsStatement) { return } - if (nameRef.qualifier != null && !(nameRef is HasMetadata && nameRef.withoutSideEffects)) { - super.visitNameRef(nameRef) + super.visitNameRef(nameRef) + if (nameRef.qualifier != null && !nameRef.withoutSideEffects) { sideEffectOccurred = true } } override fun visitInvocation(invocation: JsInvocation) { super.visitInvocation(invocation) - sideEffectOccurred = true + if (!invocation.withoutSideEffects) { + sideEffectOccurred = true + } } override fun visitNew(x: JsNew) { @@ -240,7 +241,9 @@ internal class TemporaryVariableElimination(private val root: JsStatement) { override fun visitArrayAccess(x: JsArrayAccess) { super.visitArrayAccess(x) - sideEffectOccurred = true + if (!x.withoutSideEffects) { + sideEffectOccurred = true + } } override fun visitArray(x: JsArrayLiteral) { diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeDefaultInitializers.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeDefaultInitializers.kt index 3bba49ea482..7d7ce07a382 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeDefaultInitializers.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeDefaultInitializers.kt @@ -112,7 +112,7 @@ private fun getDefaultParamsNames( initialized: Boolean ): Set { - val argsParams = args.zipWithDefault(params, Namer.UNDEFINED_EXPRESSION) + val argsParams = args.zipWithDefault(params, Namer.getUndefinedExpression()) val relevantParams = argsParams.asSequence() .filter { it.second.hasDefaultValue } .filter { initialized == !isUndefined(it.first) } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt index 62d4003d3dc..677c1a0f1ee 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.js.translate.callTranslator import com.google.dart.compiler.backend.js.ast.* -import com.google.dart.compiler.backend.js.ast.metadata.withoutSideEffects import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.Visibilities @@ -61,8 +60,7 @@ object DefaultFunctionCallCase : FunctionCallCase() { if (isNative && hasSpreadOperator) { return nativeSpreadFunWithDispatchOrExtensionReceiver(argumentsInfo, functionName) } - val functionRef = JsNameRef(functionName, dispatchReceiver) - return JsInvocation(functionRef, argumentsInfo.translateArguments) + return JsInvocation(JsAstUtils.fqn(functionName, dispatchReceiver), argumentsInfo.translateArguments) } fun buildDefaultCallWithoutReceiver(context: TranslationContext, @@ -81,9 +79,7 @@ object DefaultFunctionCallCase : FunctionCallCase() { val functionRef = context.aliasOrValue(callableDescriptor) { val qualifierForFunction = context.getQualifierForDescriptor(it) - val result = JsNameRef(functionName, qualifierForFunction) - result.withoutSideEffects = true - result + JsAstUtils.fqn(functionName, qualifierForFunction) } return JsInvocation(functionRef, argumentsInfo.translateArguments) } @@ -106,7 +102,7 @@ object DefaultFunctionCallCase : FunctionCallCase() { val functionRef = context.aliasOrValue(callableDescriptor) { val qualifierForFunction = context.getQualifierForDescriptor(it) - JsNameRef(functionName, qualifierForFunction) // TODO: remake to call + JsAstUtils.fqn(functionName, qualifierForFunction) // TODO: remake to call } val referenceToCall = @@ -231,7 +227,7 @@ object SuperCallCase : FunctionCallCase() { override fun FunctionCallInfo.dispatchReceiver(): JsExpression { // TODO: spread operator - val prototypeClass = JsNameRef(Namer.getPrototypeName(), calleeOwner) + val prototypeClass = JsAstUtils.fqn(Namer.getPrototypeName(), calleeOwner) val functionRef = Namer.getFunctionCallRef(JsNameRef(functionName, prototypeClass)) return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(dispatchReceiver!!)) } 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 9941dc347f8..c93f77828d2 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 @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.js.translate.context; import com.google.dart.compiler.backend.js.ast.*; +import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata; import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties; import com.google.dart.compiler.backend.js.ast.metadata.TypeCheck; import com.intellij.openapi.util.text.StringUtil; @@ -26,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import org.jetbrains.kotlin.idea.KotlinLanguage; import org.jetbrains.kotlin.js.resolve.JsPlatform; +import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.resolve.DescriptorUtils; @@ -43,8 +45,6 @@ import static org.jetbrains.kotlin.js.translate.utils.ManglingUtils.getSuggested public final class Namer { public static final String KOTLIN_NAME = KotlinLanguage.NAME; public static final String KOTLIN_LOWER_NAME = KOTLIN_NAME.toLowerCase(); - public static final JsNameRef KOTLIN_OBJECT_REF = new JsNameRef(KOTLIN_NAME); - public static final JsNameRef KOTLIN_LONG_NAME_REF = new JsNameRef("Long", KOTLIN_OBJECT_REF); public static final String EQUALS_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getAny(), "equals"); public static final String COMPARE_TO_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getComparable(), "compareTo"); @@ -96,11 +96,7 @@ public final class Namer { private static final String COMPANION_OBJECT_INITIALIZER = "object_initializer$"; private static final String PROTOTYPE_NAME = "prototype"; public static final String CAPTURED_VAR_FIELD = "v"; - - public static final JsNameRef CREATE_INLINE_FUNCTION = new JsNameRef("defineInlineFunction", KOTLIN_OBJECT_REF); - - @NotNull - public static final JsExpression UNDEFINED_EXPRESSION = new JsPrefixOperation(JsUnaryOperator.VOID, JsNumberLiteral.ZERO); + public static final String DEFINE_INLINE_FUNCTION = "defineInlineFunction"; private static final JsNameRef JS_OBJECT = new JsNameRef("Object"); private static final JsNameRef JS_OBJECT_CREATE_FUNCTION = new JsNameRef("create", JS_OBJECT); @@ -141,7 +137,7 @@ public final class Namer { @NotNull public static JsNameRef superMethodNameRef(@NotNull JsName superClassJsName) { - return new JsNameRef(SUPER_METHOD_NAME, superClassJsName.makeRef()); + return JsAstUtils.fqn(SUPER_METHOD_NAME, superClassJsName.makeRef()); } @NotNull @@ -175,7 +171,7 @@ public final class Namer { @NotNull public static JsExpression getCompanionObjectAccessor(@NotNull JsExpression referenceToClass) { - return new JsNameRef(COMPANION_OBJECT_GETTER, referenceToClass); + return JsAstUtils.fqn(COMPANION_OBJECT_GETTER, referenceToClass); } @NotNull @@ -190,7 +186,7 @@ public final class Namer { @NotNull public static JsNameRef getRefToPrototype(@NotNull JsExpression classOrTraitExpression) { - return new JsNameRef(getPrototypeName(), classOrTraitExpression); + return JsAstUtils.fqn(getPrototypeName(), classOrTraitExpression); } @NotNull @@ -215,12 +211,12 @@ public final class Namer { @NotNull public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) { - return new JsNameRef(CALL_FUNCTION, functionExpression); + return JsAstUtils.fqn(CALL_FUNCTION, functionExpression); } @NotNull public static JsNameRef getFunctionApplyRef(@NotNull JsExpression functionExpression) { - return new JsNameRef(APPLY_FUNCTION, functionExpression); + return JsAstUtils.fqn(APPLY_FUNCTION, functionExpression); } @NotNull @@ -230,7 +226,7 @@ public final class Namer { @NotNull public static JsNameRef getCapturedVarAccessor(@NotNull JsExpression ref) { - return new JsNameRef(CAPTURED_VAR_FIELD, ref); + return JsAstUtils.fqn(CAPTURED_VAR_FIELD, ref); } @NotNull @@ -308,6 +304,7 @@ public final class Namer { isTypeName = kotlinScope.declareName("isType"); modulesMap = kotlin("modules"); + MetadataProperties.setWithoutSideEffects((HasMetadata) modulesMap, true); } @NotNull @@ -376,29 +373,30 @@ public final class Namer { } @NotNull - public JsExpression throwNPEFunctionRef() { + public static JsExpression throwNPEFunctionRef() { return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject()); } @NotNull - private JsNameRef kotlin(@NotNull JsName name) { - return new JsNameRef(name, kotlinObject()); + public static JsNameRef kotlin(@NotNull JsName name) { + return JsAstUtils.fqn(name, kotlinObject()); } @NotNull - public JsExpression kotlin(@NotNull String name) { + public JsNameRef kotlin(@NotNull String name) { return kotlin(kotlinScope.declareName(name)); } @NotNull - public JsNameRef kotlinObject() { - return kotlinName.makeRef(); + public static JsNameRef kotlinObject() { + return JsAstUtils.fqn(KOTLIN_NAME, null); } @NotNull public JsExpression isTypeOf(@NotNull JsExpression type) { JsInvocation invocation = new JsInvocation(kotlin("isTypeOf"), type); MetadataProperties.setTypeCheck(invocation, TypeCheck.TYPEOF); + MetadataProperties.setWithoutSideEffects(invocation, true); return invocation; } @@ -406,12 +404,15 @@ public final class Namer { public JsExpression isInstanceOf(@NotNull JsExpression type) { JsInvocation invocation = new JsInvocation(kotlin("isInstanceOf"), type); MetadataProperties.setTypeCheck(invocation, TypeCheck.INSTANCEOF); + MetadataProperties.setWithoutSideEffects(invocation, true); return invocation; } @NotNull public JsExpression isInstanceOf(@NotNull JsExpression instance, @NotNull JsExpression type) { - return new JsInvocation(kotlin(isTypeName), instance, type); + JsInvocation result = new JsInvocation(kotlin(isTypeName), instance, type); + MetadataProperties.setWithoutSideEffects(result, true); + return result; } @NotNull @@ -445,8 +446,8 @@ public final class Namer { } @NotNull - public JsExpression getUndefinedExpression() { - return UNDEFINED_EXPRESSION; + public static JsExpression getUndefinedExpression() { + return new JsPrefixOperation(JsUnaryOperator.VOID, JsNumberLiteral.ZERO); } @NotNull @@ -461,6 +462,17 @@ public final class Namer { @NotNull public JsExpression getModuleReference(@NotNull JsStringLiteral moduleName) { - return new JsArrayAccess(modulesMap, moduleName); + JsArrayAccess result = new JsArrayAccess(modulesMap, moduleName); + MetadataProperties.setWithoutSideEffects(result, true); + return result; + } + + public static JsNameRef kotlinLong() { + return JsAstUtils.fqn("Long", kotlinObject()); + } + + @NotNull + public static JsNameRef createInlineFunction() { + return JsAstUtils.fqn(DEFINE_INLINE_FUNCTION, kotlinObject()); } } 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 8638d885f2c..090fe9e23aa 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 @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.js.translate.context; import com.google.dart.compiler.backend.js.ast.*; -import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -228,9 +227,7 @@ public class TranslationContext { @NotNull public JsNameRef getQualifiedReference(@NotNull FqName packageFqName) { - JsNameRef result = staticContext.getQualifiedReference(packageFqName); - MetadataProperties.setWithoutSideEffects(result, true); - return result; + return staticContext.getQualifiedReference(packageFqName); } @Nullable diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java index 7b1d553f8c9..512eb973d4c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/JsDataClassGenerator.java @@ -69,7 +69,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { argumentValue = parameterValue; } else { - JsExpression defaultCondition = JsAstUtils.equality(new JsNameRef(paramName), context.namer().getUndefinedExpression()); + JsExpression defaultCondition = JsAstUtils.equality(new JsNameRef(paramName), Namer.getUndefinedExpression()); argumentValue = new JsConditional(defaultCondition, propertyAccessor(JsLiteral.THIS, constructorParam.getName()), parameterValue); @@ -97,8 +97,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { for (int i = 0; i < classProperties.size(); i++) { String name = classProperties.get(i).getName().toString(); JsExpression literal = jsProgram.getStringLiteral((i == 0 ? (getClassDescriptor().getName() + "(") : ", ") + name + "="); - JsExpression expr = - new JsInvocation(new JsNameRef("toString", Namer.KOTLIN_OBJECT_REF), propertyAccessor(JsLiteral.THIS, name)); + JsExpression expr = new JsInvocation(context.namer().kotlin("toString"), propertyAccessor(JsLiteral.THIS, name)); JsExpression component = JsAstUtils.sum(literal, expr); if (result == null) { result = component; @@ -125,7 +124,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { for (PropertyDescriptor prop : classProperties) { // TODO: we should statically check that we can call hashCode method directly. - JsExpression component = new JsInvocation(new JsNameRef("hashCode", Namer.KOTLIN_OBJECT_REF), + JsExpression component = new JsInvocation(context.namer().kotlin("hashCode"), propertyAccessor(JsLiteral.THIS, prop.getName().toString())); JsExpression newHashValue = JsAstUtils.sum(JsAstUtils.mul(new JsNameRef(varName), jsProgram.getNumberLiteral(31)), component); JsExpression assignment = JsAstUtils.assignment(new JsNameRef(varName), @@ -156,7 +155,7 @@ class JsDataClassGenerator extends DataClassMethodGenerator { JsExpression fieldChain = null; for (PropertyDescriptor prop : classProperties) { String name = prop.getName().toString(); - JsExpression next = new JsInvocation(new JsNameRef("equals", Namer.KOTLIN_OBJECT_REF), + JsExpression next = new JsInvocation(context.namer().kotlin("equals"), propertyAccessor(JsLiteral.THIS, name), propertyAccessor(new JsNameRef(paramName), name)); if (fieldChain == null) { 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 474ad3de1b6..c78abdc1221 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 @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.translate.context.Namer.getReceiverParameterName import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.general.AbstractTranslator import org.jetbrains.kotlin.js.translate.general.Translation +import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.assignmentToBackingField import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.backingFieldReference @@ -164,7 +165,7 @@ private class PropertyTranslator( val fakeArgumentExpression = (delegatedCall.valueArgumentsByIndex!![1] as ExpressionValueArgument).valueArgument!!.getArgumentExpression() return context.innerContextWithAliasesForExpressions(mapOf( - fakeArgumentExpression to JsNew(JsNameRef("PropertyMetadata", Namer.KOTLIN_NAME), listOf(propertyNameLiteral)) + fakeArgumentExpression to JsNew(JsAstUtils.fqn("PropertyMetadata", Namer.kotlinObject()), listOf(propertyNameLiteral)) )) } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/InlineMetadata.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/InlineMetadata.kt index 83af9804bc9..295cf5ec67f 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/InlineMetadata.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/InlineMetadata.kt @@ -41,7 +41,8 @@ class InlineMetadata(val tag: JsStringLiteral, val function: JsFunction) { } private fun decomposeCreateFunctionCall(call: JsInvocation): InlineMetadata? { - if (Namer.CREATE_INLINE_FUNCTION != call.qualifier) return null + val qualifier = call.qualifier + if (qualifier !is JsNameRef || qualifier.ident != Namer.DEFINE_INLINE_FUNCTION) return null val arguments = call.arguments if (arguments.size != METADATA_PROPERTIES_COUNT) return null @@ -57,6 +58,6 @@ class InlineMetadata(val tag: JsStringLiteral, val function: JsFunction) { val functionWithMetadata: JsExpression get() { val propertiesList = listOf(tag, function) - return JsInvocation(Namer.CREATE_INLINE_FUNCTION, propertiesList) + return JsInvocation(Namer.createInlineFunction(), propertiesList) } } \ No newline at end of file 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 5eaf2e46144..83679c78eca 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 @@ -106,7 +106,7 @@ public final class PatternTranslator extends AbstractTranslator { } if (NamePredicate.LONG.apply(typeName)) { - return namer().isInstanceOf(Namer.KOTLIN_LONG_NAME_REF); + return namer().isInstanceOf(Namer.kotlinLong()); } if (NamePredicate.NUMBER.apply(typeName)) { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java index 10e9975bc15..e481f09e5d1 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/initializer/ClassInitializerTranslator.java @@ -127,9 +127,8 @@ public final class ClassInitializerTranslator extends AbstractTranslator { JsName outerName = initFunction.getScope().declareName(Namer.OUTER_FIELD_NAME); initFunction.getParameters().add(0, new JsParameter(outerName)); - JsExpression target = new JsNameRef(outerName, JsLiteral.THIS); - JsExpression paramRef = outerName.makeRef(); - JsExpression assignment = JsAstUtils.assignment(target, paramRef); + JsExpression paramRef = JsAstUtils.fqn(outerName, null); + JsExpression assignment = JsAstUtils.assignment(JsAstUtils.fqn(outerName, JsLiteral.THIS), paramRef); initFunction.getBody().getStatements().add(new JsExpressionStatement(assignment)); } @@ -166,7 +165,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator { assert superDescriptor != null : "This class is expected to have super class: " + PsiUtilsKt.getTextWithLocation(classDeclaration); if (superDescriptor.isInner() && descriptor.isInner()) { - arguments.add(0, new JsNameRef(Namer.OUTER_FIELD_NAME, JsLiteral.THIS)); + arguments.add(0, JsAstUtils.fqn(Namer.OUTER_FIELD_NAME, JsLiteral.THIS)); } addCallToSuperMethod(arguments, initializer); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInFunctionIntrinsic.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInFunctionIntrinsic.java index b489da0c452..425615828cc 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInFunctionIntrinsic.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInFunctionIntrinsic.java @@ -18,10 +18,10 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.basic; import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsNameRef; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.js.translate.context.TranslationContext; +import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; import java.util.List; @@ -42,6 +42,6 @@ public final class BuiltInFunctionIntrinsic extends FunctionIntrinsic { @NotNull TranslationContext context ) { assert receiver != null; - return new JsInvocation(new JsNameRef(functionName, receiver), arguments); + return new JsInvocation(JsAstUtils.fqn(functionName, receiver), arguments); } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInPropertyIntrinsic.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInPropertyIntrinsic.java index aeeafa40287..8264ffe258d 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInPropertyIntrinsic.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/basic/BuiltInPropertyIntrinsic.java @@ -17,10 +17,10 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.basic; import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsNameRef; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.js.translate.context.TranslationContext; +import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; import java.util.List; @@ -40,6 +40,6 @@ public final class BuiltInPropertyIntrinsic extends FunctionIntrinsic { @NotNull TranslationContext context) { assert receiver != null; assert arguments.isEmpty() : "Properties can't have arguments."; - return new JsNameRef(propertyName, receiver); + return JsAstUtils.fqn(propertyName, receiver); } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java index 5442d25f8c8..7e9e97e8fa2 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories; import com.google.common.collect.Lists; import com.google.dart.compiler.backend.js.ast.JsArrayAccess; import com.google.dart.compiler.backend.js.ast.JsExpression; +import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; @@ -30,7 +31,6 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic; import org.jetbrains.kotlin.name.Name; -import java.util.Arrays; import java.util.List; import static com.intellij.openapi.util.text.StringUtil.decapitalize; @@ -42,7 +42,6 @@ public final class ArrayFIF extends CompositeFIF { private static final NamePredicate CHAR_ARRAY; private static final NamePredicate BOOLEAN_ARRAY; private static final NamePredicate LONG_ARRAY; - private static final NamePredicate ARRAY; private static final NamePredicate ARRAYS; private static final DescriptorPredicate ARRAY_FACTORY_METHODS; @@ -66,7 +65,6 @@ public final class ArrayFIF extends CompositeFIF { CHAR_ARRAY = new NamePredicate(charArrayName); BOOLEAN_ARRAY = new NamePredicate(booleanArrayName); LONG_ARRAY = new NamePredicate(longArrayName); - ARRAY = new NamePredicate(arrayName); arrayTypeNames.add(charArrayName); arrayTypeNames.add(booleanArrayName); @@ -99,7 +97,9 @@ public final class ArrayFIF extends CompositeFIF { assert receiver != null; assert arguments.size() == 1 : "Array get expression must have one argument."; JsExpression indexExpression = arguments.get(0); - return new JsArrayAccess(receiver, indexExpression); + JsArrayAccess result = new JsArrayAccess(receiver, indexExpression); + MetadataProperties.setWithoutSideEffects(result, true); + return result; } }; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java index b279fe84bc4..fc31dd2f2ab 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.js.translate.context.Namer; import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic; +import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; import org.jetbrains.kotlin.js.translate.utils.TranslationUtils; import java.util.List; @@ -33,7 +34,7 @@ public class KotlinFunctionIntrinsic extends FunctionIntrinsic { private final JsNameRef function; public KotlinFunctionIntrinsic(@NotNull String functionName) { - function = new JsNameRef(functionName, Namer.KOTLIN_NAME); + function = JsAstUtils.fqn(functionName, Namer.kotlinObject()); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt index a17662a1ec3..d31a7707844 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ProgressionCompanionFIF.kt @@ -16,10 +16,10 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories -import com.google.dart.compiler.backend.js.ast.* +import com.google.dart.compiler.backend.js.ast.JsExpression +import com.google.dart.compiler.backend.js.ast.JsNew import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern -import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic @@ -38,7 +38,7 @@ object ProgressionCompanionFIF : CompositeFIF() { private class CallProgressionConstructorIntrinsic(val libraryProgressionName: String) : FunctionIntrinsic() { override fun apply(receiver: JsExpression?, arguments: MutableList, context: TranslationContext): JsExpression - = JsNew(JsNameRef(libraryProgressionName, Namer.KOTLIN_OBJECT_REF), arguments) + = JsNew(context.namer().kotlin(libraryProgressionName), 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 832a319e7b1..c348625843f 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 @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories; import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsNameRef; import com.google.dart.compiler.backend.js.ast.JsNew; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -213,7 +212,7 @@ public final class TopLevelFIF extends CompositeFIF { String mangledName = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getMutableMap(), operationName()); - return new JsInvocation(new JsNameRef(mangledName, thisOrReceiver), arguments); + return new JsInvocation(JsAstUtils.fqn(mangledName, thisOrReceiver), arguments); } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt index 1e0dfb835f6..64a912640bb 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/reference/CallArgumentTranslator.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.reference import com.google.dart.compiler.backend.js.ast.* import com.intellij.util.SmartList import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.TemporaryConstVariable import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.expression.PatternTranslator @@ -56,10 +57,10 @@ class CallArgumentTranslator private constructor( private val isNativeFunctionCall = AnnotationsUtils.isNativeObject(resolvedCall.candidateDescriptor) private fun removeLastUndefinedArguments(result: MutableList) { - var i = result.size - 1 + var i = result.lastIndex while (i >= 0) { - if (result.get(i) != context().namer().undefinedExpression) { + if (!JsAstUtils.isUndefinedExpression(result[i])) { break } i-- @@ -182,7 +183,7 @@ class CallArgumentTranslator private constructor( val valueArguments = actualArgument.arguments if (actualArgument is DefaultValueArgument) { - result.add(context.namer().undefinedExpression) + result += Namer.getUndefinedExpression() return ArgumentsKind.HAS_NOT_EMPTY_EXPRESSION_ARGUMENT } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java index f5dfa163a17..d15899e4eab 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/FunctionBodyTranslator.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; +import org.jetbrains.kotlin.js.translate.context.Namer; import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.general.AbstractTranslator; import org.jetbrains.kotlin.js.translate.general.Translation; @@ -61,7 +62,7 @@ public final class FunctionBodyTranslator extends AbstractTranslator { JsExpression defaultValue = Translation.translateAsExpression(defaultArgument, functionBodyContext, defaultArgBlock); JsStatement assignStatement = assignment(jsNameRef, defaultValue).makeStmt(); JsStatement thenStatement = JsAstUtils.mergeStatementInBlockIfNeeded(assignStatement, defaultArgBlock); - JsBinaryOperation checkArgIsUndefined = equality(jsNameRef, functionBodyContext.namer().getUndefinedExpression()); + JsBinaryOperation checkArgIsUndefined = equality(jsNameRef, Namer.getUndefinedExpression()); JsIf jsIf = JsAstUtils.newJsIf(checkArgIsUndefined, thenStatement); result.add(jsIf); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java index af68085048e..d1874d36097 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.js.translate.utils; import com.google.dart.compiler.backend.js.ast.*; +import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties; import com.intellij.util.SmartList; import kotlin.Pair; import org.jetbrains.annotations.NotNull; @@ -31,12 +32,12 @@ import java.util.Collections; import java.util.List; public final class JsAstUtils { - private static final JsNameRef DEFINE_PROPERTY = new JsNameRef("defineProperty"); - public static final JsNameRef CREATE_OBJECT = new JsNameRef("create"); + private static final JsNameRef DEFINE_PROPERTY = fqn("defineProperty", null); + public static final JsNameRef CREATE_OBJECT = fqn("create", null); private static final JsNameRef VALUE = new JsNameRef("value"); - private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(new JsNameRef("writable"), JsLiteral.TRUE); - private static final JsPropertyInitializer ENUMERABLE = new JsPropertyInitializer(new JsNameRef("enumerable"), JsLiteral.TRUE); + private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(fqn("writable", null), JsLiteral.TRUE); + private static final JsPropertyInitializer ENUMERABLE = new JsPropertyInitializer(fqn("enumerable", null), JsLiteral.TRUE); public static final String LENDS_JS_DOC_TAG = "lends"; @@ -122,12 +123,12 @@ public final class JsAstUtils { @NotNull public static JsInvocation invokeKotlinFunction(@NotNull String name, @NotNull JsExpression... argument) { - return new JsInvocation(new JsNameRef(name, Namer.KOTLIN_OBJECT_REF), argument); + return invokeMethod(Namer.kotlinObject(), name, argument); } @NotNull public static JsInvocation invokeMethod(@NotNull JsExpression thisObject, @NotNull String name, @NotNull JsExpression... arguments) { - return new JsInvocation(new JsNameRef(name, thisObject), arguments); + return new JsInvocation(fqn(name, thisObject), arguments); } @NotNull @@ -172,7 +173,7 @@ public final class JsAstUtils { @NotNull private static JsExpression rangeTo(@NotNull String rangeClassName, @NotNull JsExpression rangeStart, @NotNull JsExpression rangeEnd) { - JsNameRef expr = new JsNameRef(rangeClassName, Namer.KOTLIN_NAME); + JsNameRef expr = fqn(rangeClassName, Namer.kotlinObject()); JsNew numberRangeConstructorInvocation = new JsNew(expr); setArguments(numberRangeConstructorInvocation, rangeStart, rangeEnd); return numberRangeConstructorInvocation; @@ -195,17 +196,17 @@ public final class JsAstUtils { List args = new SmartList(); args.add(context.program().getNumberLiteral(low)); args.add(context.program().getNumberLiteral(high)); - return new JsNew(Namer.KOTLIN_LONG_NAME_REF, args); + return new JsNew(Namer.kotlinLong(), args); } else { if (value == 0) { - return new JsNameRef(Namer.LONG_ZERO, Namer.KOTLIN_LONG_NAME_REF); + return new JsNameRef(Namer.LONG_ZERO, Namer.kotlinLong()); } else if (value == 1) { - return new JsNameRef(Namer.LONG_ONE, Namer.KOTLIN_LONG_NAME_REF); + return new JsNameRef(Namer.LONG_ONE, Namer.kotlinLong()); } else if (value == -1) { - return new JsNameRef(Namer.LONG_NEG_ONE, Namer.KOTLIN_LONG_NAME_REF); + return new JsNameRef(Namer.LONG_NEG_ONE, Namer.kotlinLong()); } return longFromInt(context.program().getNumberLiteral((int) value)); } @@ -213,12 +214,12 @@ public final class JsAstUtils { @NotNull public static JsExpression longFromInt(@NotNull JsExpression expression) { - return invokeMethod(Namer.KOTLIN_LONG_NAME_REF, Namer.LONG_FROM_INT, expression); + return invokeMethod(Namer.kotlinLong(), Namer.LONG_FROM_INT, expression); } @NotNull public static JsExpression longFromNumber(@NotNull JsExpression expression) { - return invokeMethod(Namer.KOTLIN_LONG_NAME_REF, Namer.LONG_FROM_NUMBER, expression); + return invokeMethod(Namer.kotlinLong(), Namer.LONG_FROM_NUMBER, expression); } @NotNull @@ -447,7 +448,7 @@ public final class JsAstUtils { JsName kotlinObjectAsParameter = packageBlockFunction.getScope().declareNameUnsafe(Namer.KOTLIN_NAME); packageBlockFunction.getParameters().add(new JsParameter(kotlinObjectAsParameter)); - to.add(new JsInvocation(packageBlockFunction, Namer.KOTLIN_OBJECT_REF).makeStmt()); + to.add(new JsInvocation(packageBlockFunction, Namer.kotlinObject()).makeStmt()); return packageBlockFunction; } @@ -485,4 +486,25 @@ public final class JsAstUtils { return new SmartList(statement); } + + @NotNull + public static JsNameRef fqn(@NotNull String identifier, @Nullable JsExpression qualifier) { + JsNameRef result = new JsNameRef(identifier, qualifier); + MetadataProperties.setWithoutSideEffects(result, true); + return result; + } + + @NotNull + public static JsNameRef fqn(@NotNull JsName identifier, @Nullable JsExpression qualifier) { + JsNameRef result = new JsNameRef(identifier, qualifier); + MetadataProperties.setWithoutSideEffects(result, true); + return result; + } + + public static boolean isUndefinedExpression(JsExpression expression) { + if (!(expression instanceof JsUnaryOperation)) return false; + + JsUnaryOperation unary = (JsUnaryOperation) expression; + return unary.getOperator() == JsUnaryOperator.VOID; + } }