Simplified intrinsics matching in JS backend.
This commit is contained in:
@@ -109,21 +109,28 @@ public class OverridingUtil {
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <Descriptor extends CallableDescriptor> boolean overrides(@NotNull Descriptor f, @NotNull Descriptor g) {
|
public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) {
|
||||||
Set<CallableDescriptor> overriddenDescriptors = Sets.newHashSet();
|
|
||||||
getAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors);
|
|
||||||
CallableDescriptor originalG = g.getOriginal();
|
CallableDescriptor originalG = g.getOriginal();
|
||||||
for (CallableDescriptor overriddenFunction : overriddenDescriptors) {
|
for (CallableDescriptor overriddenFunction : getAllOverriddenDescriptors(f)) {
|
||||||
if (originalG.equals(overriddenFunction.getOriginal())) return true;
|
if (originalG.equals(overriddenFunction.getOriginal())) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getAllOverriddenDescriptors(@NotNull CallableDescriptor current, @NotNull Set<CallableDescriptor> overriddenDescriptors) {
|
public static Set<CallableDescriptor> getAllOverriddenDescriptors(CallableDescriptor f) {
|
||||||
if (overriddenDescriptors.contains(current)) return;
|
Set<CallableDescriptor> overriddenDescriptors = Sets.newHashSet();
|
||||||
|
collectAllOverriddenDescriptors(f.getOriginal(), overriddenDescriptors);
|
||||||
|
return overriddenDescriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void collectAllOverriddenDescriptors(
|
||||||
|
@NotNull CallableDescriptor current,
|
||||||
|
@NotNull Set<CallableDescriptor> result
|
||||||
|
) {
|
||||||
|
if (result.contains(current)) return;
|
||||||
for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) {
|
for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) {
|
||||||
getAllOverriddenDescriptors(descriptor, overriddenDescriptors);
|
collectAllOverriddenDescriptors(descriptor, result);
|
||||||
overriddenDescriptors.add(descriptor);
|
result.add(descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -179,9 +179,8 @@ public final class TopLevelFIF extends CompositeFIF {
|
|||||||
add(pattern("jet", "Map", "get").checkOverridden(), NATIVE_MAP_GET);
|
add(pattern("jet", "Map", "get").checkOverridden(), NATIVE_MAP_GET);
|
||||||
add(pattern("js", "set").receiverExists(), NATIVE_MAP_SET);
|
add(pattern("js", "set").receiverExists(), NATIVE_MAP_SET);
|
||||||
|
|
||||||
String[] javaUtil = {"java", "util"};
|
add(pattern("java", "util", "HashMap", "<init>"), new MapSelectImplementationIntrinsic(false));
|
||||||
add(pattern(javaUtil, "HashMap", "<init>"), new MapSelectImplementationIntrinsic(false));
|
add(pattern("java", "util", "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true));
|
||||||
add(pattern(javaUtil, "HashSet", "<init>"), new MapSelectImplementationIntrinsic(true));
|
|
||||||
|
|
||||||
add(pattern("js", "Json", "get"), ArrayFIF.GET_INTRINSIC);
|
add(pattern("js", "Json", "get"), ArrayFIF.GET_INTRINSIC);
|
||||||
add(pattern("js", "Json", "set"), ArrayFIF.SET_INTRINSIC);
|
add(pattern("js", "Json", "set"), ArrayFIF.SET_INTRINSIC);
|
||||||
|
|||||||
+22
-85
@@ -18,17 +18,17 @@ package org.jetbrains.k2js.translate.intrinsic.functions.patterns;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
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.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.k2js.translate.context.Namer;
|
import org.jetbrains.k2js.translate.context.Namer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public final class PatternBuilder {
|
public final class PatternBuilder {
|
||||||
|
|
||||||
@@ -127,13 +127,9 @@ public final class PatternBuilder {
|
|||||||
return new DescriptorPredicateImpl(names);
|
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) {
|
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 {
|
public static class DescriptorPredicateImpl implements DescriptorPredicate {
|
||||||
@@ -141,7 +137,6 @@ public final class PatternBuilder {
|
|||||||
|
|
||||||
private boolean receiverParameterExists;
|
private boolean receiverParameterExists;
|
||||||
|
|
||||||
private String[] root;
|
|
||||||
private boolean checkOverridden;
|
private boolean checkOverridden;
|
||||||
|
|
||||||
public DescriptorPredicateImpl(String... names) {
|
public DescriptorPredicateImpl(String... names) {
|
||||||
@@ -153,30 +148,14 @@ public final class PatternBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DescriptorPredicateImpl root(String... root) {
|
|
||||||
this.root = root;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DescriptorPredicateImpl checkOverridden() {
|
public DescriptorPredicateImpl checkOverridden() {
|
||||||
this.checkOverridden = true;
|
this.checkOverridden = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean check(FunctionDescriptor functionDescriptor) {
|
private boolean matches(@NotNull CallableDescriptor callable) {
|
||||||
DeclarationDescriptor descriptor = functionDescriptor.getContainingDeclaration();
|
DeclarationDescriptor descriptor = callable;
|
||||||
String[] list;
|
int nameIndex = names.length - 1;
|
||||||
int nameIndex;
|
|
||||||
if (root == null) {
|
|
||||||
list = names;
|
|
||||||
nameIndex = list.length - 2;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert names.length == 1;
|
|
||||||
list = root;
|
|
||||||
nameIndex = list.length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (nameIndex == -1) {
|
if (nameIndex == -1) {
|
||||||
return isRootNamespace(descriptor);
|
return isRootNamespace(descriptor);
|
||||||
@@ -185,12 +164,12 @@ public final class PatternBuilder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!descriptor.getName().asString().equals(list[nameIndex--])) {
|
if (!descriptor.getName().asString().equals(names[nameIndex--])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ((descriptor = descriptor.getContainingDeclaration()) != null);
|
while ((descriptor = descriptor.getContainingDeclaration()) != null);
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -199,66 +178,24 @@ public final class PatternBuilder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// avoid unwrap FAKE_OVERRIDE
|
if (!(functionDescriptor.getContainingDeclaration() instanceof ClassDescriptor)) {
|
||||||
int nameIndex = names.length - 1;
|
return matches(functionDescriptor);
|
||||||
if (!functionDescriptor.getName().asString().equals(names[nameIndex--])) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationDescriptor descriptor;
|
for (CallableMemberDescriptor real : OverridingUtil.getOverriddenDeclarations(functionDescriptor)) {
|
||||||
if (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
if (matches(real)) {
|
||||||
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<? 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 true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (checkOverridden) {
|
||||||
|
for (CallableDescriptor overridden : OverridingUtil.getAllOverriddenDescriptors(functionDescriptor)) {
|
||||||
|
if (matches(overridden)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user