JS: fix some bugs:
1. Fix translation of FQN in inline lambdas 2. Fix StringBuilder.length 3. Workaround order of declaration of names for imported declarations
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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<JsName>() {
|
||||
@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<JsName> {
|
||||
public InnerNameGenerator() {
|
||||
addRule(new Rule<JsName>() {
|
||||
@@ -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<JsScope> {
|
||||
|
||||
public ScopeGenerator() {
|
||||
|
||||
+9
-8
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user