JS backend: added expected receiver type for intrinsics.

This commit is contained in:
Zalim Bashorov
2014-06-17 15:46:29 +04:00
parent 247808e17b
commit 516af6c908
4 changed files with 22 additions and 16 deletions
@@ -27,7 +27,7 @@ public final class StringOperationFIF extends CompositeFIF {
private StringOperationFIF() { private StringOperationFIF() {
add(pattern("kotlin", "String", "get"), new BuiltInFunctionIntrinsic("charAt")); add(pattern("kotlin", "String", "get"), new BuiltInFunctionIntrinsic("charAt"));
add(pattern("js", "length").receiverExists(), LENGTH_PROPERTY_INTRINSIC); add(pattern("js", "length").isExtensionOf("kotlin.CharSequence"), LENGTH_PROPERTY_INTRINSIC);
add(pattern("js", "isEmpty").receiverExists(), IS_EMPTY_INTRINSIC); add(pattern("js", "isEmpty").isExtensionOf("kotlin.CharSequence"), IS_EMPTY_INTRINSIC);
} }
} }
@@ -159,18 +159,18 @@ public final class TopLevelFIF extends CompositeFIF {
private TopLevelFIF() { private TopLevelFIF() {
add(EQUALS_IN_ANY, KOTLIN_EQUALS); add(EQUALS_IN_ANY, KOTLIN_EQUALS);
add(pattern("kotlin", "toString").receiverExists(), TO_STRING); add(pattern("kotlin", "toString").isExtensionOf("kotlin.Any"), TO_STRING);
add(pattern("kotlin", "equals").receiverExists(), KOTLIN_EQUALS); add(pattern("kotlin", "equals").isExtensionOf("kotlin.Any"), KOTLIN_EQUALS);
add(pattern("kotlin", "identityEquals").receiverExists(), IDENTITY_EQUALS); add(pattern("kotlin", "identityEquals").isExtensionOf("kotlin.Any"), IDENTITY_EQUALS);
add(HASH_CODE_IN_ANY, KOTLIN_HASH_CODE); add(HASH_CODE_IN_ANY, KOTLIN_HASH_CODE);
add(pattern(NamePredicate.PRIMITIVE_NUMBERS, "equals"), KOTLIN_EQUALS); add(pattern(NamePredicate.PRIMITIVE_NUMBERS, "equals"), KOTLIN_EQUALS);
add(pattern("String|Boolean|Char|Number.equals"), KOTLIN_EQUALS); add(pattern("String|Boolean|Char|Number.equals"), KOTLIN_EQUALS);
add(pattern("kotlin", "arrayOfNulls"), new KotlinFunctionIntrinsic("nullArray")); add(pattern("kotlin", "arrayOfNulls"), new KotlinFunctionIntrinsic("nullArray"));
add(pattern("kotlin", "PropertyMetadataImpl", "<init>"), PROPERTY_METADATA_IMPL); add(pattern("kotlin", "PropertyMetadataImpl", "<init>"), PROPERTY_METADATA_IMPL);
add(pattern("kotlin", "iterator").receiverExists(), RETURN_RECEIVER_INTRINSIC); add(pattern("kotlin", "iterator").isExtensionOf("kotlin.Iterator"), RETURN_RECEIVER_INTRINSIC);
add(pattern("kotlin", "Map", "get").checkOverridden(), NATIVE_MAP_GET); add(pattern("kotlin", "Map", "get").checkOverridden(), NATIVE_MAP_GET);
add(pattern("js", "set").receiverExists(), NATIVE_MAP_SET); add(pattern("js", "set").isExtensionOf("kotlin.MutableMap"), NATIVE_MAP_SET);
add(pattern("java.util", "HashMap", "<init>"), new MapSelectImplementationIntrinsic(false)); add(pattern("java.util", "HashMap", "<init>"), new MapSelectImplementationIntrinsic(false));
add(pattern("java.util", "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true)); add(pattern("java.util", "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true));
@@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverrideResolver; import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -127,7 +128,7 @@ public final class PatternBuilder {
public static class DescriptorPredicateImpl implements DescriptorPredicate { public static class DescriptorPredicateImpl implements DescriptorPredicate {
private final String[] names; private final String[] names;
private boolean receiverParameterExists; private String receiverFqName;
private boolean checkOverridden; private boolean checkOverridden;
@@ -135,8 +136,8 @@ public final class PatternBuilder {
this.names = names; this.names = names;
} }
public DescriptorPredicateImpl receiverExists() { public DescriptorPredicateImpl isExtensionOf(String receiverFqName) {
this.receiverParameterExists = true; this.receiverFqName = receiverFqName;
return this; return this;
} }
@@ -167,8 +168,13 @@ public final class PatternBuilder {
@Override @Override
public boolean apply(@NotNull FunctionDescriptor functionDescriptor) { public boolean apply(@NotNull FunctionDescriptor functionDescriptor) {
if ((functionDescriptor.getReceiverParameter() == null) == receiverParameterExists) { ReceiverParameterDescriptor actualReceiver = functionDescriptor.getReceiverParameter();
return false; if (actualReceiver != null) {
if (receiverFqName == null) return false;
String actualReceiverFqName = TranslationUtils.getJetTypeFqName(actualReceiver.getType());
if (!actualReceiverFqName.equals(receiverFqName)) return false;
} }
if (!(functionDescriptor.getContainingDeclaration() instanceof ClassDescriptor)) { if (!(functionDescriptor.getContainingDeclaration() instanceof ClassDescriptor)) {
@@ -267,13 +267,13 @@ public final class TranslationUtils {
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
if (receiverParameter != null) { if (receiverParameter != null) {
argTypes.append(getJetTypeName(receiverParameter.getType())).append("."); argTypes.append(getJetTypeFqName(receiverParameter.getType())).append(".");
} }
argTypes.append(StringUtil.join(descriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() { argTypes.append(StringUtil.join(descriptor.getValueParameters(), new Function<ValueParameterDescriptor, String>() {
@Override @Override
public String fun(ValueParameterDescriptor descriptor) { public String fun(ValueParameterDescriptor descriptor) {
return getJetTypeName(descriptor.getType()); return getJetTypeFqName(descriptor.getType());
} }
}, ",")); }, ","));
@@ -281,12 +281,12 @@ public final class TranslationUtils {
} }
@NotNull @NotNull
private static String getJetTypeName(@NotNull JetType jetType) { public static String getJetTypeFqName(@NotNull JetType jetType) {
ClassifierDescriptor declaration = jetType.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor declaration = jetType.getConstructor().getDeclarationDescriptor();
assert declaration != null; assert declaration != null;
if (declaration instanceof TypeParameterDescriptor) { if (declaration instanceof TypeParameterDescriptor) {
return getJetTypeName(((TypeParameterDescriptor) declaration).getUpperBoundsAsType()); return getJetTypeFqName(((TypeParameterDescriptor) declaration).getUpperBoundsAsType());
} }
return getFqName(declaration).asString(); return getFqName(declaration).asString();