diff --git a/js/js.libraries/src/core/javalang.kt b/js/js.libraries/src/core/javalang.kt index be57e90250f..4ac67125812 100644 --- a/js/js.libraries/src/core/javalang.kt +++ b/js/js.libraries/src/core/javalang.kt @@ -30,7 +30,8 @@ class StringBuilder(content: String = "") : Appendable, CharSequence { private var string: String = content - override val length: Int = string.length + override val length: Int + get() = string.asDynamic().length override fun get(index: Int): Char = string[index] @@ -57,8 +58,7 @@ class StringBuilder(content: String = "") : Appendable, CharSequence { } fun reverse(): StringBuilder { - val nativeString: dynamic = string - string = nativeString.split("").reverse().join("") + string = string.asDynamic().split("").reverse().join("") return this } 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 2d154c5896f..778b1726062 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 @@ -53,7 +53,6 @@ import static org.jetbrains.kotlin.js.config.LibrarySourcesConfig.UNKNOWN_EXTERN import static org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isLibraryObject; import static org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject; import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn; -import static org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getContainingDeclaration; import static org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSuperclass; /** @@ -366,7 +365,7 @@ public final class StaticContext { } @NotNull - public JsName getNameForPackage(@NotNull final FqName packageFqName) { + private JsName getNameForPackage(@NotNull final FqName packageFqName) { return ContainerUtil.getOrCreate(packageNames, packageFqName, new Factory() { @Override public JsName create() { @@ -409,11 +408,26 @@ public final class StaticContext { @NotNull public JsName importDeclaration(@NotNull String suggestedName, @NotNull JsExpression declaration) { - JsName result = rootFunction.getScope().declareFreshName(suggestedName); + // Adding prefix is a workaround for a problem with scopes. + // Consider we declare name `foo` in functions's local scope, then call top-level function `foo` + // from another module. It's imported into global scope under name `foo`. If we could somehow + // declare all names in global scope before running translator, we would have got `foo_1` for local variable, + // since local scope inherited from global scope. + // TODO: remove prefix when problem with scopes is solved + + JsName result = rootFunction.getScope().declareFreshName("imported$" + suggestedName); importStatements.add(JsAstUtils.newVar(result, declaration)); return result; } + @NotNull + private JsName localOrImportedName(@NotNull DeclarationDescriptor descriptor, @NotNull String suggestedName) { + ModuleDescriptor module = DescriptorUtilsKt.getModule(descriptor); + return module != currentModule ? + importDeclaration(suggestedName, getQualifiedReference(descriptor)) : + rootFunction.getScope().declareFreshName(suggestedName); + } + private final class InnerNameGenerator extends Generator { public InnerNameGenerator() { addRule(new Rule() { @@ -431,12 +445,7 @@ public final class StaticContext { return getInnerNameForDescriptor(((ConstructorDescriptor) descriptor).getConstructedClass()); } } - JsName result = rootFunction.getScope().declareFreshName(getSuggestedName(descriptor)); - ModuleDescriptor module = DescriptorUtilsKt.getModule(descriptor); - if (module != currentModule) { - importStatements.add(JsAstUtils.newVar(result, getQualifiedReference(descriptor))); - } - return result; + return localOrImportedName(descriptor, getSuggestedName(descriptor)); } }); } @@ -449,12 +458,7 @@ public final class StaticContext { @Override public JsName apply(@NotNull DeclarationDescriptor descriptor) { String suggested = getSuggestedName(descriptor) + Namer.OBJECT_INSTANCE_FUNCTION_SUFFIX; - JsName result = rootFunction.getScope().declareFreshName(suggested); - ModuleDescriptor module = DescriptorUtilsKt.getModule(descriptor); - if (module != currentModule) { - importStatements.add(JsAstUtils.newVar(result, getQualifiedReference(descriptor))); - } - return result; + return localOrImportedName(descriptor, suggested); } }); } @@ -508,18 +512,6 @@ public final class StaticContext { return suggestedName; } - @NotNull - public JsName declarePropertyOrPropertyAccessorName(@NotNull DeclarationDescriptor descriptor, @NotNull String name, boolean fresh) { - JsScope scope = getEnclosingScope(descriptor); - return fresh ? scope.declareFreshName(name) : scope.declareName(name); - } - - @NotNull - private JsScope getEnclosingScope(@NotNull DeclarationDescriptor descriptor) { - DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor); - return getScopeForDescriptor(containingDeclaration.getOriginal()); - } - private final class ScopeGenerator extends Generator { public ScopeGenerator() { 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 d8396097622..e6bc169d6ed 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 @@ -229,11 +229,6 @@ public class TranslationContext { return staticContext.getNameForObjectInstance(descriptor); } - @NotNull - public JsName declarePropertyOrPropertyAccessorName(@NotNull DeclarationDescriptor descriptor, @NotNull String name) { - return staticContext.declarePropertyOrPropertyAccessorName(descriptor, name, false); - } - @NotNull public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof MemberDescriptor && isFromCurrentModule(descriptor) && isPublicInlineFunction()) { @@ -620,9 +615,15 @@ public class TranslationContext { } public boolean isPublicInlineFunction() { - if (!(declarationDescriptor instanceof FunctionDescriptor)) return false; - FunctionDescriptor function = (FunctionDescriptor) declarationDescriptor; - return function.isInline() && DescriptorUtilsKt.isEffectivelyPublicApi(function); + DeclarationDescriptor descriptor = declarationDescriptor; + while (descriptor instanceof FunctionDescriptor) { + FunctionDescriptor function = (FunctionDescriptor) descriptor; + if (function.isInline() && DescriptorUtilsKt.isEffectivelyPublicApi(function)) { + return true; + } + descriptor = descriptor.getContainingDeclaration(); + } + return false; } @NotNull 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 77932f35f7d..20307c9eb85 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 @@ -17,15 +17,14 @@ package org.jetbrains.kotlin.js.translate.utils; import com.google.dart.compiler.backend.js.ast.*; +import com.google.dart.compiler.backend.js.ast.JsBinaryOperator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; -import org.jetbrains.kotlin.js.translate.context.Namer; -import org.jetbrains.kotlin.js.translate.context.StaticContext; import org.jetbrains.kotlin.descriptors.impl.LocalVariableAccessorDescriptor; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; +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.general.Translation; @@ -41,7 +40,6 @@ import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*; import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getCallableDescriptorForOperationExpression; import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.assignment; import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.createDataDescriptor; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.isAnonymousObject; public final class TranslationUtils { @@ -84,8 +82,9 @@ public final class TranslationUtils { @NotNull public static JsExpression translateExclForBinaryEqualLikeExpr(@NotNull JsBinaryOperation baseBinaryExpression) { - return new JsBinaryOperation(notOperator(baseBinaryExpression.getOperator()), baseBinaryExpression.getArg1(), - baseBinaryExpression.getArg2()); + JsBinaryOperator negatedOperator = notOperator(baseBinaryExpression.getOperator()); + assert negatedOperator != null : "Can't negate operator: " + baseBinaryExpression.getOperator(); + return new JsBinaryOperation(negatedOperator, baseBinaryExpression.getArg1(), baseBinaryExpression.getArg2()); } public static boolean isEqualLikeOperator(@NotNull JsBinaryOperator operator) { @@ -153,8 +152,7 @@ public final class TranslationUtils { context.getNameForDescriptor(descriptor); if (!JsDescriptorUtils.isSimpleFinalProperty(descriptor) && !(containingDescriptor instanceof PackageFragmentDescriptor)) { - JsName backingFieldMangledName = context.getNameForBackingField(descriptor); - backingFieldName = context.declarePropertyOrPropertyAccessorName(descriptor, backingFieldMangledName.getIdent()); + backingFieldName = context.getNameForBackingField(descriptor); } JsExpression receiver; @@ -264,31 +262,6 @@ public final class TranslationUtils { return ensureNotNull; } - @NotNull - public static String getSuggestedNameForInnerDeclaration(StaticContext context, DeclarationDescriptor descriptor) { - String suggestedName = ""; - DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); - //noinspection ConstantConditions - if (containingDeclaration != null && - !(containingDeclaration instanceof ClassOrPackageFragmentDescriptor) && - !(containingDeclaration instanceof AnonymousFunctionDescriptor) && - !(containingDeclaration instanceof ConstructorDescriptor && isAnonymousObject(containingDeclaration.getContainingDeclaration()))) { - suggestedName = context.getNameForDescriptor(containingDeclaration).getIdent(); - } - - if (!suggestedName.isEmpty() && !suggestedName.endsWith("$")) { - suggestedName += "$"; - } - - if (descriptor.getName().isSpecial()) { - suggestedName += "f"; - } - else { - suggestedName += context.getNameForDescriptor(descriptor).getIdent(); - } - return suggestedName; - } - public static boolean isSimpleNameExpressionNotDelegatedLocalVar(@Nullable KtExpression expression, @NotNull TranslationContext context) { if (!(expression instanceof KtSimpleNameExpression)) { return false;