From 7ba0f0eb33c4ebc843a4c5242bdfd0261cb66b99 Mon Sep 17 00:00:00 2001 From: develar Date: Thu, 8 Aug 2013 19:51:49 +0400 Subject: [PATCH] JS backend: refactoring - add KotlinFunctionIntrinsic; - remove CallStandardMethodIntrinsic - rename TranslationUtils#generateCallArgumentList to TranslationUtils#generateInvocationArguments; - add to PatternBuilder#pattern with root(prefix) parameter. --- .../basic/CallStandardMethodIntrinsic.java | 71 ------------------- .../functions/factories/ArrayFIF.java | 14 ++-- .../factories/KotlinFunctionIntrinsic.java | 32 +++++++++ .../functions/factories/TopLevelFIF.java | 18 ++--- .../functions/patterns/PatternBuilder.java | 52 ++++++++++++-- .../translate/reference/CallTranslator.java | 2 +- .../translate/utils/TranslationUtils.java | 2 +- 7 files changed, 94 insertions(+), 97 deletions(-) delete mode 100644 js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java create mode 100644 js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java deleted file mode 100644 index 17365062675..00000000000 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.k2js.translate.intrinsic.functions.basic; - -import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.intellij.util.SmartList; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.k2js.translate.context.TranslationContext; - -import java.util.List; - -import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.atLocation; - -public final class CallStandardMethodIntrinsic extends FunctionIntrinsic { - @NotNull - private final JsNameRef methodName; - - private final boolean receiverShouldBeNotNull; - private final int expectedParamsNumber; - - public CallStandardMethodIntrinsic(@NotNull JsNameRef methodName, boolean receiverShouldBeNotNull, int expectedParamsNumber) { - this.methodName = methodName; - this.receiverShouldBeNotNull = receiverShouldBeNotNull; - this.expectedParamsNumber = expectedParamsNumber; - } - - @NotNull - @Override - public JsExpression apply(@Nullable JsExpression receiver, - @NotNull List arguments, - @NotNull TranslationContext context) { - assert (receiver != null == receiverShouldBeNotNull); - assert arguments.size() == expectedParamsNumber : errorMessage(receiver, arguments); - return new JsInvocation(methodName, composeArguments(receiver, arguments)); - } - - @NotNull - private String errorMessage(@Nullable JsExpression receiver, @NotNull List arguments) { - return "Incorrect number of arguments " + arguments.size() + " when expected " + expectedParamsNumber + " on method " + methodName + " " + - atLocation(receiver, arguments); - } - - @NotNull - private static List composeArguments(@Nullable JsExpression receiver, @NotNull List arguments) { - if (receiver != null) { - List args = new SmartList(receiver); - args.addAll(arguments); - return args; - } - else { - return arguments; - } - } -} diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/ArrayFIF.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/ArrayFIF.java index 601683c9475..bcb55267b69 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/ArrayFIF.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/ArrayFIF.java @@ -19,7 +19,6 @@ package org.jetbrains.k2js.translate.intrinsic.functions.factories; import com.google.common.collect.Lists; import com.google.dart.compiler.backend.js.ast.JsArrayAccess; import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsNameRef; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.resolve.name.Name; @@ -27,7 +26,6 @@ import org.jetbrains.jet.lang.types.lang.PrimitiveType; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.intrinsic.functions.basic.BuiltInPropertyIntrinsic; -import org.jetbrains.k2js.translate.intrinsic.functions.basic.CallStandardMethodIntrinsic; import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic; import org.jetbrains.k2js.translate.intrinsic.functions.patterns.DescriptorPredicate; import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate; @@ -138,12 +136,12 @@ public final class ArrayFIF extends CompositeFIF { add(pattern(ARRAYS, "get"), GET_INTRINSIC); add(pattern(ARRAYS, "set"), SET_INTRINSIC); add(pattern(ARRAYS, ""), ARRAY_LENGTH_INTRINSIC); - add(pattern(ARRAYS, ""), new CallStandardMethodIntrinsic(new JsNameRef("arrayIndices", "Kotlin"), true, 0)); - add(pattern(ARRAYS, "iterator"), new CallStandardMethodIntrinsic(new JsNameRef("arrayIterator", "Kotlin"), true, 0)); - add(pattern(ARRAY, ""), new CallStandardMethodIntrinsic(new JsNameRef("arrayFromFun", "Kotlin"), false, 2)); - add(pattern(NUMBER_ARRAY, ""), new CallStandardMethodIntrinsic(new JsNameRef("numberArrayOfSize", "Kotlin"), false, 1)); - add(pattern(CHAR_ARRAY, ""), new CallStandardMethodIntrinsic(new JsNameRef("charArrayOfSize", "Kotlin"), false, 1)); - add(pattern(BOOLEAN_ARRAY, ""), new CallStandardMethodIntrinsic(new JsNameRef("booleanArrayOfSize", "Kotlin"), false, 1)); + add(pattern(ARRAYS, ""), new KotlinFunctionIntrinsic("arrayIndices")); + add(pattern(ARRAYS, "iterator"), new KotlinFunctionIntrinsic("arrayIterator")); + add(pattern(ARRAY, ""), new KotlinFunctionIntrinsic("arrayFromFun")); + add(pattern(NUMBER_ARRAY, ""),new KotlinFunctionIntrinsic("numberArrayOfSize")); + add(pattern(CHAR_ARRAY, ""), new KotlinFunctionIntrinsic("charArrayOfSize")); + add(pattern(BOOLEAN_ARRAY, ""), new KotlinFunctionIntrinsic("booleanArrayOfSize")); add(ARRAY_FACTORY_METHODS, ARRAY_INTRINSIC); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java new file mode 100644 index 00000000000..63d988f3517 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/KotlinFunctionIntrinsic.java @@ -0,0 +1,32 @@ +package org.jetbrains.k2js.translate.intrinsic.functions.factories; + +import com.google.dart.compiler.backend.js.ast.JsExpression; +import com.google.dart.compiler.backend.js.ast.JsInvocation; +import com.google.dart.compiler.backend.js.ast.JsNameRef; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.k2js.translate.context.Namer; +import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic; +import org.jetbrains.k2js.translate.utils.TranslationUtils; + +import java.util.List; + +public final class KotlinFunctionIntrinsic extends FunctionIntrinsic { + @NotNull + private final JsNameRef function; + + public KotlinFunctionIntrinsic(@NotNull String functionName) { + function = new JsNameRef(functionName, Namer.KOTLIN_NAME); + } + + @NotNull + @Override + public JsExpression apply( + @Nullable JsExpression receiver, + @NotNull List arguments, + @NotNull TranslationContext context + ) { + return new JsInvocation(function, receiver == null ? arguments : TranslationUtils.generateInvocationArguments(receiver, arguments)); + } +} 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 1ecdc259866..5715631d03c 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 @@ -36,7 +36,6 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.PrimitiveType; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.intrinsic.functions.basic.BuiltInFunctionIntrinsic; -import org.jetbrains.k2js.translate.intrinsic.functions.basic.CallStandardMethodIntrinsic; import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic; import org.jetbrains.k2js.translate.intrinsic.functions.patterns.DescriptorPredicate; import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate; @@ -49,11 +48,11 @@ import java.util.List; import static org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic.CallParametersAwareFunctionIntrinsic; import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern; -import static org.jetbrains.k2js.translate.utils.TranslationUtils.generateCallArgumentList; +import static org.jetbrains.k2js.translate.utils.TranslationUtils.generateInvocationArguments; public final class TopLevelFIF extends CompositeFIF { @NotNull - public static final CallStandardMethodIntrinsic EQUALS = new CallStandardMethodIntrinsic(new JsNameRef("equals", "Kotlin"), true, 1); + public static final KotlinFunctionIntrinsic EQUALS = new KotlinFunctionIntrinsic("equals"); @NotNull private static final FunctionIntrinsic RETURN_RECEIVER_INTRINSIC = new FunctionIntrinsic() { @NotNull @@ -124,7 +123,7 @@ public final class TopLevelFIF extends CompositeFIF { add(pattern("jet", "equals").receiverExists(true), EQUALS); add(pattern(NamePredicate.PRIMITIVE_NUMBERS, "equals"), EQUALS); add(pattern("String|Boolean|Char|Number.equals"), EQUALS); - add(pattern("jet", "arrayOfNulls"), new CallStandardMethodIntrinsic(new JsNameRef("nullArray", "Kotlin"), false, 1)); + add(pattern("jet", "arrayOfNulls"), new KotlinFunctionIntrinsic("nullArray")); add(pattern("jet", "iterator").receiverExists(true), RETURN_RECEIVER_INTRINSIC); add(new DescriptorPredicate() { @Override @@ -155,18 +154,19 @@ public final class TopLevelFIF extends CompositeFIF { } else { return new JsInvocation(new JsNameRef("call", callTranslator.getCallParameters().getFunctionReference()), - generateCallArgumentList(thisExpression, arguments)); + generateInvocationArguments(thisExpression, arguments)); } } } ); - add(pattern("java", "util", "set").receiverExists(true), NATIVE_MAP_SET); + String[] javaUtil = {"java", "util"}; + add(pattern(javaUtil, "set").receiverExists(true), NATIVE_MAP_SET); add(pattern("jet", "Map", "get"), NATIVE_MAP_GET); - add(pattern("java", "util", "HashMap", "get"), NATIVE_MAP_GET); + add(pattern(javaUtil, "HashMap", "get"), NATIVE_MAP_GET); - add(pattern("java", "util", "HashMap", ""), new MapSelectImplementationIntrinsic(false)); - add(pattern("java", "util", "HashSet", ""), new MapSelectImplementationIntrinsic(true)); + add(pattern(javaUtil, "HashMap", ""), new MapSelectImplementationIntrinsic(false)); + add(pattern(javaUtil, "HashSet", ""), new MapSelectImplementationIntrinsic(true)); } private abstract static class NativeMapGetSet extends CallParametersAwareFunctionIntrinsic { 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 f336a2aba35..7119c24d85d 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,6 +18,7 @@ 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.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; @@ -125,6 +126,11 @@ 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); } @@ -134,6 +140,8 @@ public final class PatternBuilder { private boolean receiverParameterExists; + private String[] root; + public DescriptorPredicateImpl(String... names) { this.names = names; } @@ -143,24 +151,54 @@ public final class PatternBuilder { return this; } + public DescriptorPredicateImpl root(String... root) { + this.root = root; + return this; + } + @Override public boolean apply(@NotNull FunctionDescriptor functionDescriptor) { if ((functionDescriptor.getReceiverParameter() == null) == receiverParameterExists) { return false; } - DeclarationDescriptor descriptor = functionDescriptor; + // avoid unwrap FAKE_OVERRIDE int nameIndex = names.length - 1; - do { - if (!descriptor.getName().asString().equals(names[nameIndex--])) { + if (!functionDescriptor.getName().asString().equals(names[nameIndex--])) { + return false; + } + + 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; } - descriptor = descriptor.getContainingDeclaration(); - if (nameIndex == -1) { - return isRootNamespace(descriptor); + + if (!descriptor.getName().asString().equals(list[nameIndex--])) { + return false; } } - while (descriptor != null && !isRootNamespace(descriptor)); return false; } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index be555c31ba5..8d9d5a3bc50 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -156,7 +156,7 @@ public final class CallTranslator extends AbstractTranslator { @NotNull private List generateCallArgumentList(@NotNull JsExpression receiver) { - return TranslationUtils.generateCallArgumentList(receiver, arguments); + return TranslationUtils.generateInvocationArguments(receiver, arguments); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index add8f9ee7d3..7810b588f68 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -195,7 +195,7 @@ public final class TranslationUtils { } @NotNull - public static List generateCallArgumentList(@NotNull JsExpression receiver, @NotNull List arguments) { + public static List generateInvocationArguments(@NotNull JsExpression receiver, @NotNull List arguments) { if (arguments.isEmpty()) { return Collections.singletonList(receiver); }