Add more hints about property access that is provable has no side effect. Refactor namer

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