JS backend: fixed Map set/get -- should work with jet Map/MutableMap.

Added to PatternBuilder the ability to check that method has been overridden.
This commit is contained in:
develar
2013-08-08 19:51:49 +04:00
committed by Zalim Bashorov
parent 421c896416
commit 8867c7a33f
5 changed files with 70 additions and 15 deletions
+4 -2
View File
@@ -5,9 +5,11 @@ import js.native
import java.util.*;
import java.lang.*;
native
public val noImpl : Nothing = throw Exception();
public val noImpl : Nothing = throw Exception()
/** Provides [] access to maps */
native public fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit = noImpl
library("println")
public fun println() {}
-6
View File
@@ -1,11 +1,5 @@
package java.util
import java.lang.*
/** Provides [] access to maps */
native
public fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit = noImpl
library("collectionsMax")
public fun max<T>(col: Collection<T>, comp: Comparator<T>): T = js.noImpl
@@ -159,11 +159,10 @@ public final class TopLevelFIF extends CompositeFIF {
}
);
String[] javaUtil = {"java", "util"};
add(pattern(javaUtil, "set").receiverExists(), NATIVE_MAP_SET);
add(pattern("jet", "Map", "get"), NATIVE_MAP_GET);
add(pattern(javaUtil, "HashMap", "get"), NATIVE_MAP_GET);
add(pattern("jet", "Map", "get").checkOverridden(), NATIVE_MAP_GET);
add(pattern("js", "set").receiverExists(), NATIVE_MAP_SET);
String[] javaUtil = {"java", "util"};
add(pattern(javaUtil, "HashMap", "<init>"), new MapSelectImplementationIntrinsic(false));
add(pattern(javaUtil, "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true));
}
@@ -28,6 +28,7 @@ import org.jetbrains.k2js.translate.context.Namer;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public final class PatternBuilder {
@@ -141,6 +142,7 @@ public final class PatternBuilder {
private boolean receiverParameterExists;
private String[] root;
private boolean checkOverridden;
public DescriptorPredicateImpl(String... names) {
this.names = names;
@@ -156,6 +158,41 @@ public final class PatternBuilder {
return this;
}
public DescriptorPredicateImpl checkOverridden() {
this.checkOverridden = true;
return this;
}
private boolean check(FunctionDescriptor functionDescriptor) {
DeclarationDescriptor descriptor = functionDescriptor.getContainingDeclaration();
String[] list;
int nameIndex;
if (root == null) {
list = names;
nameIndex = list.length - 2;
}
else {
assert names.length == 1;
list = root;
nameIndex = list.length - 1;
}
do {
if (nameIndex == -1) {
return isRootNamespace(descriptor);
}
else if (isRootNamespace(descriptor)) {
return false;
}
if (!descriptor.getName().asString().equals(list[nameIndex--])) {
return false;
}
}
while ((descriptor = descriptor.getContainingDeclaration()) != null);
return false;
}
@Override
public boolean apply(@NotNull FunctionDescriptor functionDescriptor) {
if ((functionDescriptor.getReceiverParameter() == null) == receiverParameterExists) {
@@ -196,7 +233,30 @@ public final class PatternBuilder {
}
if (!descriptor.getName().asString().equals(list[nameIndex--])) {
return false;
// we check overridden on any mismatch - we can have classes with equal name from different packages
return checkOverridden && checkOverridden(functionDescriptor);
}
}
return false;
}
private boolean checkOverridden(FunctionDescriptor functionDescriptor) {
Set<? extends FunctionDescriptor> overriddenDescriptors = functionDescriptor.getOverriddenDescriptors();
if (overriddenDescriptors.isEmpty()) {
return false;
}
for (FunctionDescriptor overridden : overriddenDescriptors) {
if (overridden.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
for (FunctionDescriptor realOverridden : overridden.getOverriddenDescriptors()) {
if (check(realOverridden) || checkOverridden(realOverridden)) {
return true;
}
}
}
else if (check(overridden) || checkOverridden(overridden)) {
return true;
}
}
return false;
@@ -1,6 +1,6 @@
package foo
import java.util.*
import java.util.HashMap
native
val classes: Map<String, Any> = noImpl
@@ -10,4 +10,4 @@ val classesMutable: HashMap<String, String> = noImpl
fun box(): Boolean {
classesMutable["why"] = "?"
return classes["answer"] == 42 && classesMutable["why"] == "?"
}
}