Added support bitwise operations in js translator
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.test.semantics;
|
||||
|
||||
import junit.framework.Test;
|
||||
|
||||
//NOTE: well, it has tests
|
||||
@SuppressWarnings("JUnitTestCaseWithNoTests")
|
||||
public final class BitwiseOperationsTest extends JsUnitTestBase {
|
||||
public static Test suite() throws Exception {
|
||||
return createTestSuiteForFile("libraries/stdlib/test/language/BitwiseOperationsTest.kt");
|
||||
}
|
||||
}
|
||||
+20
-1
@@ -18,6 +18,7 @@ package org.jetbrains.k2js.translate.intrinsic.functions.factories;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
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;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
|
||||
@@ -79,12 +81,23 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
|
||||
@NotNull
|
||||
private static final NamePredicate BINARY_OPERATIONS = new NamePredicate(OperatorConventions.BINARY_OPERATION_NAMES.values());
|
||||
private static final DescriptorPredicate INT_WITH_BIT_OPERATIONS = pattern("Int.or|and|xor|shl|shr|ushr");
|
||||
|
||||
private static final ImmutableMap<String, JsBinaryOperator> BINARY_BITWISE_OPERATIONS = ImmutableMap.<String, JsBinaryOperator>builder()
|
||||
.put("or", JsBinaryOperator.BIT_OR)
|
||||
.put("and", JsBinaryOperator.BIT_AND)
|
||||
.put("xor", JsBinaryOperator.BIT_XOR)
|
||||
.put("shl", JsBinaryOperator.SHL)
|
||||
.put("shr", JsBinaryOperator.SHR)
|
||||
.put("ushr", JsBinaryOperator.SHRU)
|
||||
.build();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Predicate<FunctionDescriptor> getPredicate() {
|
||||
//TODO: check that it is binary operation
|
||||
return Predicates.or(pattern(NamePredicate.PRIMITIVE_NUMBERS, BINARY_OPERATIONS),
|
||||
return Predicates.or(INT_WITH_BIT_OPERATIONS,
|
||||
pattern(NamePredicate.PRIMITIVE_NUMBERS, BINARY_OPERATIONS),
|
||||
pattern("Boolean.or|and|xor"),
|
||||
pattern("String.plus"));
|
||||
}
|
||||
@@ -98,6 +111,12 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
if (descriptor.getName().equals(Name.identifier("rangeTo"))) {
|
||||
return RANGE_TO_INTRINSIC;
|
||||
}
|
||||
if (INT_WITH_BIT_OPERATIONS.apply(descriptor)) {
|
||||
JsBinaryOperator op = BINARY_BITWISE_OPERATIONS.get(descriptor.getName().getName());
|
||||
if (op != null) {
|
||||
return new PrimitiveBinaryOperationFunctionIntrinsic(op);
|
||||
}
|
||||
}
|
||||
JsBinaryOperator operator = getOperator(descriptor);
|
||||
return new PrimitiveBinaryOperationFunctionIntrinsic(operator);
|
||||
}
|
||||
|
||||
+13
-4
@@ -49,7 +49,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
pattern(PRIMITIVE_NUMBERS, UNARY_OPERATIONS);
|
||||
@NotNull
|
||||
private static final Predicate<FunctionDescriptor> PRIMITIVE_UNARY_OPERATION_NAMES =
|
||||
Predicates.or(UNARY_OPERATION_FOR_PRIMITIVE_NUMBER, pattern("Boolean.not"));
|
||||
Predicates.or(UNARY_OPERATION_FOR_PRIMITIVE_NUMBER, pattern("Boolean.not"), pattern("Int.inv"));
|
||||
@NotNull
|
||||
private static final DescriptorPredicate NO_PARAMETERS = new DescriptorPredicate() {
|
||||
@Override
|
||||
@@ -71,8 +71,17 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
@Override
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
Name name = descriptor.getName();
|
||||
JetToken jetToken = OperatorConventions.UNARY_OPERATION_NAMES.inverse().get(name);
|
||||
final JsUnaryOperator jsOperator = OperatorTable.getUnaryOperator(jetToken);
|
||||
|
||||
JsUnaryOperator jsOperator = null;
|
||||
if ("inv".equals(name.getName())) {
|
||||
jsOperator = JsUnaryOperator.BIT_NOT;
|
||||
}
|
||||
else {
|
||||
JetToken jetToken = OperatorConventions.UNARY_OPERATION_NAMES.inverse().get(name);
|
||||
jsOperator = OperatorTable.getUnaryOperator(jetToken);
|
||||
}
|
||||
|
||||
final JsUnaryOperator finalJsOperator = jsOperator;
|
||||
return new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -82,7 +91,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 0 : "Unary operator should not have arguments.";
|
||||
//NOTE: cannot use this for increment/decrement
|
||||
return new JsPrefixOperation(jsOperator, receiver);
|
||||
return new JsPrefixOperation(finalJsOperator, receiver);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package test
|
||||
|
||||
import kotlin.test.*
|
||||
import org.junit.Test as test
|
||||
|
||||
class BitwiseOperationsTest {
|
||||
test fun orForInt() {
|
||||
assertEquals(3, 2 or 1)
|
||||
}
|
||||
|
||||
test fun andForInt() {
|
||||
assertEquals(0, 1 and 0)
|
||||
}
|
||||
|
||||
test fun xorForInt() {
|
||||
assertEquals(1, 2 xor 3)
|
||||
}
|
||||
|
||||
test fun shlForInt() {
|
||||
assertEquals(4, 1 shl 2)
|
||||
}
|
||||
|
||||
test fun shrForInt() {
|
||||
assertEquals(1, 2 shr 1)
|
||||
}
|
||||
|
||||
test fun ushrForInt() {
|
||||
assertEquals(2147483647, -1 ushr 1)
|
||||
}
|
||||
|
||||
test fun invForInt() {
|
||||
assertEquals(0, (-1).inv())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user