JS backend: remake NameGenerator in case Property & PropertyAccessor. Fix overload extension property.
This commit is contained in:
@@ -84,6 +84,10 @@ public class RegressionMergeEcmaTest extends SingleFileTranslationTest {
|
|||||||
checkFooBoxIsOk();
|
checkFooBoxIsOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBackendField() throws Exception {
|
||||||
|
checkFooBoxIsOk();
|
||||||
|
}
|
||||||
|
|
||||||
public void testExtensionClass() throws Exception {
|
public void testExtensionClass() throws Exception {
|
||||||
checkFooBoxIsOk();
|
checkFooBoxIsOk();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator;
|
|||||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
|
||||||
import org.jetbrains.k2js.translate.utils.PredefinedAnnotation;
|
import org.jetbrains.k2js.translate.utils.PredefinedAnnotation;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -44,7 +43,6 @@ import java.util.Comparator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*;
|
import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.isObjectDeclaration;
|
|
||||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
|
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -199,13 +197,6 @@ public final class StaticContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class NameGenerator extends Generator<JsName> {
|
private final class NameGenerator extends Generator<JsName> {
|
||||||
private JsName declareName(DeclarationDescriptor descriptor, String name) {
|
|
||||||
JsScope scope = getEnclosingScope(descriptor);
|
|
||||||
// ecma 5 property name never declares as obfuscatable:
|
|
||||||
// 1) property cannot be overloaded, so, name collision is not possible
|
|
||||||
// 2) main reason: if property doesn't have any custom accessor, value holder will have the same name as accessor, so, the same name will be declared more than once
|
|
||||||
return isEcma5() ? scope.declareName(name) : scope.declareFreshName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NameGenerator() {
|
public NameGenerator() {
|
||||||
Rule<JsName> namesForStandardClasses = new Rule<JsName>() {
|
Rule<JsName> namesForStandardClasses = new Rule<JsName>() {
|
||||||
@@ -286,23 +277,40 @@ public final class StaticContext {
|
|||||||
return getNameForDescriptor(containingClass);
|
return getNameForDescriptor(containingClass);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Rule<JsName> accessorsHasNamesWithSpecialPrefixes = new Rule<JsName>() {
|
|
||||||
|
// ecma 5 property name never declares as obfuscatable:
|
||||||
|
// 1) property cannot be overloaded, so, name collision is not possible
|
||||||
|
// 2) main reason: if property doesn't have any custom accessor, value holder will have the same name as accessor, so, the same name will be declared more than once
|
||||||
|
//
|
||||||
|
// But extension property may obfuscatable, because transform into function. Example: String.foo = 1, Int.foo = 2
|
||||||
|
Rule<JsName> propertyOrPropertyAccessor = new Rule<JsName>() {
|
||||||
@Override
|
@Override
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
if (!(descriptor instanceof PropertyAccessorDescriptor)) {
|
PropertyDescriptor propertyDescriptor;
|
||||||
|
if (descriptor instanceof PropertyAccessorDescriptor) {
|
||||||
|
propertyDescriptor = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
|
||||||
|
}
|
||||||
|
else if (descriptor instanceof PropertyDescriptor) {
|
||||||
|
propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
|
}
|
||||||
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor;
|
String propertyName = propertyDescriptor.getName().asString();
|
||||||
String propertyName = accessorDescriptor.getCorrespondingProperty().getName().asString();
|
|
||||||
if (isObjectDeclaration(accessorDescriptor.getCorrespondingProperty())) {
|
|
||||||
return declareName(descriptor, propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
|
if (!isExtension(propertyDescriptor)) {
|
||||||
String accessorName = Namer.getNameForAccessor(propertyName, isGetter,
|
return declarePropertyOrPropertyAccessorName(descriptor, propertyName, false);
|
||||||
accessorDescriptor.getReceiverParameter() == null && isEcma5());
|
} else {
|
||||||
return declareName(descriptor, accessorName);
|
if (descriptor instanceof PropertyDescriptor) {
|
||||||
|
return declarePropertyOrPropertyAccessorName(descriptor, propertyName, true);
|
||||||
|
} else {
|
||||||
|
String propertyJsName = getNameForDescriptor(propertyDescriptor).getIdent();
|
||||||
|
boolean isGetter = descriptor instanceof PropertyGetterDescriptor;
|
||||||
|
String accessorName = Namer.getNameForAccessor(propertyJsName, isGetter, false);
|
||||||
|
return declarePropertyOrPropertyAccessorName(descriptor, accessorName, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -320,21 +328,6 @@ public final class StaticContext {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Rule<JsName> propertiesCorrespondToSpeciallyTreatedBackingFieldNames = new Rule<JsName>() {
|
|
||||||
@Override
|
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (!(descriptor instanceof PropertyDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = descriptor.getName().asString();
|
|
||||||
if (!isEcma5() || !JsDescriptorUtils.isSimpleProperty((PropertyDescriptor) descriptor)) {
|
|
||||||
name = Namer.getKotlinBackingFieldName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return declareName(descriptor, name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Rule<JsName> overridingDescriptorsReferToOriginalName = new Rule<JsName>() {
|
Rule<JsName> overridingDescriptorsReferToOriginalName = new Rule<JsName>() {
|
||||||
@Override
|
@Override
|
||||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||||
@@ -355,15 +348,20 @@ public final class StaticContext {
|
|||||||
};
|
};
|
||||||
addRule(namesForStandardClasses);
|
addRule(namesForStandardClasses);
|
||||||
addRule(constructorHasTheSameNameAsTheClass);
|
addRule(constructorHasTheSameNameAsTheClass);
|
||||||
|
addRule(propertyOrPropertyAccessor);
|
||||||
addRule(predefinedObjectsHasUnobfuscatableNames);
|
addRule(predefinedObjectsHasUnobfuscatableNames);
|
||||||
addRule(propertiesCorrespondToSpeciallyTreatedBackingFieldNames);
|
|
||||||
addRule(namespacesShouldBeDefinedInRootScope);
|
addRule(namespacesShouldBeDefinedInRootScope);
|
||||||
addRule(overridingDescriptorsReferToOriginalName);
|
addRule(overridingDescriptorsReferToOriginalName);
|
||||||
addRule(accessorsHasNamesWithSpecialPrefixes);
|
|
||||||
addRule(memberDeclarationsInsideParentsScope);
|
addRule(memberDeclarationsInsideParentsScope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@NotNull
|
||||||
private JsScope getEnclosingScope(@NotNull DeclarationDescriptor descriptor) {
|
private JsScope getEnclosingScope(@NotNull DeclarationDescriptor descriptor) {
|
||||||
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
DeclarationDescriptor containingDeclaration = getContainingDeclaration(descriptor);
|
||||||
|
|||||||
@@ -172,6 +172,11 @@ public class TranslationContext {
|
|||||||
return staticContext.getNameForDescriptor(descriptor);
|
return staticContext.getNameForDescriptor(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsName declarePropertyOrPropertyAccessorName(@NotNull DeclarationDescriptor descriptor, @NotNull String name, boolean fresh) {
|
||||||
|
return staticContext.declarePropertyOrPropertyAccessorName(descriptor, name, fresh);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsStringLiteral nameToLiteral(@NotNull Named named) {
|
public JsStringLiteral nameToLiteral(@NotNull Named named) {
|
||||||
return program().getStringLiteral(named.getName().asString());
|
return program().getStringLiteral(named.getName().asString());
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*;
|
import static com.google.dart.compiler.backend.js.ast.JsBinaryOperator.*;
|
||||||
|
import static org.jetbrains.k2js.translate.context.Namer.getKotlinBackingFieldName;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
|
||||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.createDataDescriptor;
|
import static org.jetbrains.k2js.translate.utils.JsAstUtils.createDataDescriptor;
|
||||||
@@ -154,6 +155,11 @@ public final class TranslationUtils {
|
|||||||
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
|
public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
|
||||||
@NotNull PropertyDescriptor descriptor) {
|
@NotNull PropertyDescriptor descriptor) {
|
||||||
JsName backingFieldName = context.getNameForDescriptor(descriptor);
|
JsName backingFieldName = context.getNameForDescriptor(descriptor);
|
||||||
|
if(!JsDescriptorUtils.isSimpleProperty(descriptor)) {
|
||||||
|
backingFieldName = context.declarePropertyOrPropertyAccessorName(descriptor,
|
||||||
|
getKotlinBackingFieldName(backingFieldName.getIdent()),
|
||||||
|
false);
|
||||||
|
}
|
||||||
return new JsNameRef(backingFieldName, JsLiteral.THIS);
|
return new JsNameRef(backingFieldName, JsLiteral.THIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
val a: Int = 1
|
||||||
|
get() = $a + 1
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (a != 2) return "a != 2, it: $a"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user