diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java index afeb84369eb..4bfdbbe58a0 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/OverridingUtil.java @@ -109,21 +109,28 @@ public class OverridingUtil { return candidates; } - public static boolean overrides(@NotNull Descriptor f, @NotNull Descriptor g) { - Set overriddenDescriptors = Sets.newHashSet(); - getAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors); + public static boolean overrides(@NotNull D f, @NotNull D g) { CallableDescriptor originalG = g.getOriginal(); - for (CallableDescriptor overriddenFunction : overriddenDescriptors) { + for (CallableDescriptor overriddenFunction : getAllOverriddenDescriptors(f)) { if (originalG.equals(overriddenFunction.getOriginal())) return true; } return false; } - private static void getAllOverriddenDescriptors(@NotNull CallableDescriptor current, @NotNull Set overriddenDescriptors) { - if (overriddenDescriptors.contains(current)) return; + public static Set getAllOverriddenDescriptors(CallableDescriptor f) { + Set overriddenDescriptors = Sets.newHashSet(); + collectAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors); + return overriddenDescriptors; + } + + private static void collectAllOverriddenDescriptors( + @NotNull CallableDescriptor current, + @NotNull Set result + ) { + if (result.contains(current)) return; for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) { - getAllOverriddenDescriptors(descriptor, overriddenDescriptors); - overriddenDescriptors.add(descriptor); + collectAllOverriddenDescriptors(descriptor, result); + result.add(descriptor); } } 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 66464c685d0..765da6737c2 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 @@ -179,9 +179,8 @@ public final class TopLevelFIF extends CompositeFIF { 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)); + add(pattern("java", "util", "HashMap", ""), new MapSelectImplementationIntrinsic(false)); + add(pattern("java", "util", "HashSet", ""), new MapSelectImplementationIntrinsic(true)); add(pattern("js", "Json", "get"), ArrayFIF.GET_INTRINSIC); add(pattern("js", "Json", "set"), ArrayFIF.SET_INTRINSIC); 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 7c5895e03ae..8f1dfa78a18 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 @@ -18,17 +18,17 @@ package org.jetbrains.k2js.translate.intrinsic.functions.patterns; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.OverridingUtil; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.k2js.translate.context.Namer; import java.util.Arrays; import java.util.List; -import java.util.Set; public final class PatternBuilder { @@ -127,13 +127,9 @@ public final class PatternBuilder { return new DescriptorPredicateImpl(names); } - @NotNull - public static DescriptorPredicateImpl pattern(@NotNull String[] root, @NotNull String... names) { - return new DescriptorPredicateImpl(names).root(root); - } - private static boolean isRootNamespace(DeclarationDescriptor declarationDescriptor) { - return declarationDescriptor instanceof NamespaceDescriptor && DescriptorUtils.isRootNamespace((NamespaceDescriptor) declarationDescriptor); + return declarationDescriptor instanceof NamespaceDescriptor && DescriptorUtils.isRootNamespace( + (NamespaceDescriptor) declarationDescriptor); } public static class DescriptorPredicateImpl implements DescriptorPredicate { @@ -141,7 +137,6 @@ public final class PatternBuilder { private boolean receiverParameterExists; - private String[] root; private boolean checkOverridden; public DescriptorPredicateImpl(String... names) { @@ -153,30 +148,14 @@ public final class PatternBuilder { return this; } - public DescriptorPredicateImpl root(String... root) { - this.root = root; - 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; - } - + private boolean matches(@NotNull CallableDescriptor callable) { + DeclarationDescriptor descriptor = callable; + int nameIndex = names.length - 1; do { if (nameIndex == -1) { return isRootNamespace(descriptor); @@ -185,12 +164,12 @@ public final class PatternBuilder { return false; } - if (!descriptor.getName().asString().equals(list[nameIndex--])) { + if (!descriptor.getName().asString().equals(names[nameIndex--])) { return false; } } while ((descriptor = descriptor.getContainingDeclaration()) != null); - return false; + return true; } @Override @@ -199,66 +178,24 @@ public final class PatternBuilder { return false; } - // avoid unwrap FAKE_OVERRIDE - int nameIndex = names.length - 1; - if (!functionDescriptor.getName().asString().equals(names[nameIndex--])) { - return false; + if (!(functionDescriptor.getContainingDeclaration() instanceof ClassDescriptor)) { + return matches(functionDescriptor); } - DeclarationDescriptor descriptor; - if (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { - assert functionDescriptor.getOverriddenDescriptors().size() > 0; - descriptor = functionDescriptor.getOverriddenDescriptors().iterator().next(); - } - else { - descriptor = functionDescriptor; - } - - String[] list = names; - while ((descriptor = descriptor.getContainingDeclaration()) != null) { - if (nameIndex == -1) { - if (isRootNamespace(descriptor)) { - return list == root || root == null; - } - else if (root == null) { - return false; - } - else { - nameIndex = root.length - 1; - list = root; - } - } - else if (isRootNamespace(descriptor)) { - return false; - } - - if (!descriptor.getName().asString().equals(list[nameIndex--])) { - // 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)) { + for (CallableMemberDescriptor real : OverridingUtil.getOverriddenDeclarations(functionDescriptor)) { + if (matches(real)) { return true; } } + + if (checkOverridden) { + for (CallableDescriptor overridden : OverridingUtil.getAllOverriddenDescriptors(functionDescriptor)) { + if (matches(overridden)) { + return true; + } + } + } + return false; } }