From 8867c7a33fed8d5d2e2b8da8b983f1163292b2df Mon Sep 17 00:00:00 2001 From: develar Date: Thu, 8 Aug 2013 19:51:49 +0400 Subject: [PATCH] JS backend: fixed Map set/get -- should work with jet Map/MutableMap. Added to PatternBuilder the ability to check that method has been overridden. --- js/js.libraries/src/core/core.kt | 6 +- js/js.libraries/src/core/javautil.kt | 6 -- .../functions/factories/TopLevelFIF.java | 7 +-- .../functions/patterns/PatternBuilder.java | 62 ++++++++++++++++++- .../testFiles/native/cases/kt2323.kt | 4 +- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/js/js.libraries/src/core/core.kt b/js/js.libraries/src/core/core.kt index 8555b1499ea..440e143e366 100644 --- a/js/js.libraries/src/core/core.kt +++ b/js/js.libraries/src/core/core.kt @@ -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 MutableMap.set(key: K, value: V): Unit = noImpl library("println") public fun println() {} diff --git a/js/js.libraries/src/core/javautil.kt b/js/js.libraries/src/core/javautil.kt index 31adf1747dd..57b37d6e47c 100644 --- a/js/js.libraries/src/core/javautil.kt +++ b/js/js.libraries/src/core/javautil.kt @@ -1,11 +1,5 @@ package java.util -import java.lang.* - -/** Provides [] access to maps */ -native -public fun MutableMap.set(key: K, value: V): Unit = noImpl - library("collectionsMax") public fun max(col: Collection, comp: Comparator): T = js.noImpl diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java index 44344d6a3df..0557dcfc710 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/TopLevelFIF.java @@ -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", ""), new MapSelectImplementationIntrinsic(false)); add(pattern(javaUtil, "HashSet", ""), new MapSelectImplementationIntrinsic(true)); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java index 7f0da2dd43a..7c5895e03ae 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/PatternBuilder.java @@ -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 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; diff --git a/js/js.translator/testFiles/native/cases/kt2323.kt b/js/js.translator/testFiles/native/cases/kt2323.kt index cb120f4b580..1482ffaffab 100644 --- a/js/js.translator/testFiles/native/cases/kt2323.kt +++ b/js/js.translator/testFiles/native/cases/kt2323.kt @@ -1,6 +1,6 @@ package foo -import java.util.* +import java.util.HashMap native val classes: Map = noImpl @@ -10,4 +10,4 @@ val classesMutable: HashMap = noImpl fun box(): Boolean { classesMutable["why"] = "?" return classes["answer"] == 42 && classesMutable["why"] == "?" -} +} \ No newline at end of file