Finishing refactoring intrinsic. Implemented most of FunctionIntrinsics and basic BinaryOperationIntrinsics.
All test pass, need to add tests for type conversion operation though.
This commit is contained in:
+6
@@ -98,6 +98,12 @@ public class OperatorConventions {
|
||||
.put(JetTokens.PLUSEQ, JetTokens.PLUS)
|
||||
.put(JetTokens.MINUSEQ, JetTokens.MINUS)
|
||||
.build();
|
||||
|
||||
//TODO: use these across frontend
|
||||
public static final ImmutableBiMap<JetToken, Name> BOOLEAN_OPERATIONS = ImmutableBiMap.<JetToken, Name>builder()
|
||||
.put(JetTokens.ANDAND, Name.identifier("and"))
|
||||
.put(JetTokens.OROR, Name.identifier("or"))
|
||||
.build();
|
||||
|
||||
@Nullable
|
||||
public static Name getNameForOperationSymbol(@NotNull JetToken token) {
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.k2js.config.EcmaVersion;
|
||||
import org.jetbrains.k2js.translate.context.generator.Generator;
|
||||
import org.jetbrains.k2js.translate.context.generator.Rule;
|
||||
@@ -45,14 +44,12 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
|
||||
*/
|
||||
public final class StaticContext {
|
||||
|
||||
public static StaticContext generateStaticContext(@NotNull JetStandardLibrary library,
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull EcmaVersion ecmaVersion) {
|
||||
public static StaticContext generateStaticContext(@NotNull BindingContext bindingContext, @NotNull EcmaVersion ecmaVersion) {
|
||||
JsProgram program = new JsProgram("main");
|
||||
JsRootScope jsRootScope = program.getRootScope();
|
||||
Namer namer = Namer.newInstance(jsRootScope);
|
||||
NamingScope scope = NamingScope.rootScope(jsRootScope);
|
||||
Intrinsics intrinsics = Intrinsics.standardLibraryIntrinsics(library);
|
||||
Intrinsics intrinsics = new Intrinsics();
|
||||
StandardClasses standardClasses = StandardClasses.bindImplementations(namer.getKotlinScope());
|
||||
return new StaticContext(program, bindingContext, namer, intrinsics, standardClasses, scope, ecmaVersion);
|
||||
}
|
||||
|
||||
+7
-7
@@ -26,7 +26,7 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.factories.ArrayFIF;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -44,12 +44,12 @@ public final class ArrayForTranslator extends ForTranslator {
|
||||
|
||||
@NotNull
|
||||
public static JsStatement doTranslate(@NotNull JetForExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull TranslationContext context) {
|
||||
return (new ArrayForTranslator(expression, context).translate());
|
||||
}
|
||||
|
||||
public static boolean isApplicable(@NotNull JetForExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull TranslationContext context) {
|
||||
JetExpression loopRange = getLoopRange(expression);
|
||||
JetType rangeType = BindingUtils.getTypeForExpression(context.bindingContext(), loopRange);
|
||||
//TODO: better check
|
||||
@@ -70,10 +70,10 @@ public final class ArrayForTranslator extends ForTranslator {
|
||||
private ArrayForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||
super(forExpression, context);
|
||||
loopRange = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
||||
FunctionIntrinsic lengthPropertyIntrinsic = context().intrinsics().getLengthPropertyIntrinsic();
|
||||
JsExpression length = lengthPropertyIntrinsic.apply(loopRange.reference(),
|
||||
Collections.<JsExpression>emptyList(),
|
||||
context());
|
||||
|
||||
JsExpression length = ArrayFIF.ARRAY_LENGTH_INTRINSIC.apply(loopRange.reference(),
|
||||
Collections.<JsExpression>emptyList(),
|
||||
context());
|
||||
end = context().declareTemporary(length);
|
||||
index = context().declareTemporary(program().getNumberLiteral(0));
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.k2js.config.Config;
|
||||
import org.jetbrains.k2js.facade.MainCallParameters;
|
||||
import org.jetbrains.k2js.facade.exceptions.MainFunctionNotFoundException;
|
||||
@@ -167,8 +166,7 @@ public final class Translation {
|
||||
@NotNull MainCallParameters mainCallParameters,
|
||||
@NotNull Config config) throws MainFunctionNotFoundException {
|
||||
//TODO: move some of the code somewhere
|
||||
JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance();
|
||||
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext, config.getTarget());
|
||||
StaticContext staticContext = StaticContext.generateStaticContext(bindingContext, config.getTarget());
|
||||
JsProgram program = staticContext.getProgram();
|
||||
JsBlock block = program.getGlobalBlock();
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public abstract class CompareToIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
private JetToken comparisonToken = null;
|
||||
|
||||
@NotNull
|
||||
protected JetToken getComparisonToken() {
|
||||
assert comparisonToken != null : "Should use set token first";
|
||||
return comparisonToken;
|
||||
}
|
||||
|
||||
public void setComparisonToken(@NotNull JetToken comparisonToken) {
|
||||
assert OperatorConventions.COMPARISON_OPERATIONS.contains(comparisonToken)
|
||||
: "Should be a comparison operation";
|
||||
this.comparisonToken = comparisonToken;
|
||||
}
|
||||
}
|
||||
@@ -16,36 +16,9 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.k2js.translate.intrinsic.array.ArrayGetIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.array.ArraySetIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.primitive.*;
|
||||
import org.jetbrains.k2js.translate.intrinsic.string.CharAtIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.tuple.TupleAccessIntrinsic;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getFunctionByName;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getPropertyByName;
|
||||
|
||||
//TODO: class is monstrous, should be refactored.
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.FunctionIntrinsics;
|
||||
import org.jetbrains.k2js.translate.intrinsic.operation.BinaryOperationIntrinsics;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -55,249 +28,18 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getPropertyBy
|
||||
public final class Intrinsics {
|
||||
|
||||
@NotNull
|
||||
private final Map<FunctionDescriptor, FunctionIntrinsic> functionIntrinsics =
|
||||
new HashMap<FunctionDescriptor, FunctionIntrinsic>();
|
||||
private final FunctionIntrinsics functionIntrinsics = new FunctionIntrinsics();
|
||||
|
||||
@NotNull
|
||||
private final Map<FunctionDescriptor, EqualsIntrinsic> equalsIntrinsics =
|
||||
new HashMap<FunctionDescriptor, EqualsIntrinsic>();
|
||||
|
||||
@NotNull
|
||||
private final Map<FunctionDescriptor, CompareToIntrinsic> compareToIntrinsics =
|
||||
new HashMap<FunctionDescriptor, CompareToIntrinsic>();
|
||||
|
||||
@NotNull
|
||||
private final FunctionIntrinsic lengthPropertyIntrinsic = new BuiltInPropertyIntrinsic("length");
|
||||
|
||||
public static Intrinsics standardLibraryIntrinsics(@NotNull JetStandardLibrary library) {
|
||||
return new Intrinsics(library);
|
||||
public BinaryOperationIntrinsics getBinaryOperationIntrinsics() {
|
||||
return binaryOperationIntrinsics;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final JetStandardLibrary library;
|
||||
|
||||
private Intrinsics(@NotNull JetStandardLibrary library) {
|
||||
this.library = library;
|
||||
declareOperatorIntrinsics();
|
||||
declareStringIntrinsics();
|
||||
declareTuplesIntrinsics();
|
||||
declareArrayIntrinsics();
|
||||
declareBooleanIntrinsics();
|
||||
FunctionDescriptor intToDouble = getFunctionByName(library.getInt().getDefaultType().getMemberScope(), Name.identifier("toDouble"));
|
||||
functionIntrinsics.put(intToDouble, ReturnReceiverIntrinsic.INSTANCE);
|
||||
FunctionDescriptor doubleToInt = getFunctionByName(library.getDouble().getDefaultType().getMemberScope(), Name.identifier("toInt"));
|
||||
functionIntrinsics.put(doubleToInt, new CallStandardMethodIntrinsic("Math.floor", true, 0));
|
||||
FunctionDescriptor toStringFunction = getFunctionByName(library.getLibraryScope(), Name.identifier("toString"));
|
||||
functionIntrinsics.put(toStringFunction, new BuiltInFunctionIntrinsic("toString"));
|
||||
}
|
||||
|
||||
private void declareBooleanIntrinsics() {
|
||||
FunctionDescriptor andFunction = getFunctionByName(library.getBoolean().getDefaultType().getMemberScope(), Name.identifier("and"));
|
||||
functionIntrinsics.put(andFunction, PrimitiveBinaryOperationIntrinsic.newInstance(JetTokens.ANDAND));
|
||||
|
||||
FunctionDescriptor orFunction = getFunctionByName(library.getBoolean().getDefaultType().getMemberScope(), Name.identifier("or"));
|
||||
functionIntrinsics.put(orFunction, PrimitiveBinaryOperationIntrinsic.newInstance(JetTokens.OROR));
|
||||
|
||||
FunctionDescriptor notFunction = getFunctionByName(library.getBoolean().getDefaultType().getMemberScope(), Name.identifier("not"));
|
||||
functionIntrinsics.put(notFunction, PrimitiveUnaryOperationIntrinsic.newInstance(JetTokens.EXCL));
|
||||
|
||||
FunctionDescriptor xorFunction = getFunctionByName(library.getBoolean().getDefaultType().getMemberScope(), Name.identifier("xor"));
|
||||
functionIntrinsics.put(xorFunction, PrimitiveBinaryOperationIntrinsic.newInstance(JsBinaryOperator.BIT_XOR));
|
||||
}
|
||||
private final BinaryOperationIntrinsics binaryOperationIntrinsics = new BinaryOperationIntrinsics();
|
||||
|
||||
@NotNull
|
||||
public FunctionIntrinsic getLengthPropertyIntrinsic() {
|
||||
return lengthPropertyIntrinsic;
|
||||
}
|
||||
|
||||
private void declareTuplesIntrinsics() {
|
||||
for (int tupleSize = 0; tupleSize <= JetStandardClasses.MAX_TUPLE_ORDER; ++tupleSize) {
|
||||
declareTupleIntrinsics(tupleSize);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: provide generic mechanism or refactor
|
||||
private void declareArrayIntrinsics() {
|
||||
|
||||
List<JetType> arrayTypes = getLibraryArrayTypes();
|
||||
|
||||
for (JetType arrayType : arrayTypes) {
|
||||
declareIntrinsicsForArrayType(arrayType);
|
||||
}
|
||||
declareNullConstructorIntrinsic();
|
||||
}
|
||||
|
||||
private void declareNullConstructorIntrinsic() {
|
||||
FunctionDescriptor nullArrayConstructor = library.getLibraryScope().getFunctions(Name.identifier("arrayOfNulls")).iterator().next();
|
||||
functionIntrinsics.put(nullArrayConstructor, new CallStandardMethodIntrinsic("Kotlin.nullArray", false, 1));
|
||||
}
|
||||
|
||||
//TODO: some dangerous operation unchecked here
|
||||
private void declareIntrinsicsForArrayType(@NotNull JetType arrayType) {
|
||||
JetScope arrayMemberScope = arrayType.getMemberScope();
|
||||
FunctionDescriptor setFunction = getFunctionByName(arrayMemberScope, Name.identifier("set"));
|
||||
functionIntrinsics.put(setFunction, ArraySetIntrinsic.INSTANCE);
|
||||
FunctionDescriptor getFunction = getFunctionByName(arrayMemberScope, Name.identifier("get"));
|
||||
functionIntrinsics.put(getFunction, ArrayGetIntrinsic.INSTANCE);
|
||||
PropertyDescriptor sizeProperty = getPropertyByName(arrayMemberScope, Name.identifier("size"));
|
||||
functionIntrinsics.put(sizeProperty.getGetter(), lengthPropertyIntrinsic);
|
||||
//TODO: excessive object creation
|
||||
PropertyDescriptor indicesProperty = getPropertyByName(arrayMemberScope, Name.identifier("indices"));
|
||||
functionIntrinsics.put(indicesProperty.getGetter(), new CallStandardMethodIntrinsic("Kotlin.arrayIndices", true, 0));
|
||||
FunctionDescriptor iteratorFunction = getFunctionByName(arrayMemberScope, Name.identifier("iterator"));
|
||||
functionIntrinsics.put(iteratorFunction, new CallStandardMethodIntrinsic("Kotlin.arrayIterator", true, 0));
|
||||
ConstructorDescriptor arrayConstructor =
|
||||
((ClassDescriptor) arrayMemberScope.getContainingDeclaration()).getConstructors().iterator().next();
|
||||
functionIntrinsics.put(arrayConstructor, new CallStandardMethodIntrinsic("Kotlin.arrayFromFun", false, 2));
|
||||
}
|
||||
|
||||
private List<JetType> getLibraryArrayTypes() {
|
||||
List<JetType> arrayTypes = Lists.newArrayList();
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
arrayTypes.add(library.getPrimitiveArrayJetType(type));
|
||||
}
|
||||
arrayTypes.add(library.getArray().getDefaultType());
|
||||
return arrayTypes;
|
||||
}
|
||||
|
||||
private void declareTupleIntrinsics(int tupleSize) {
|
||||
JetScope libraryScope = library.getLibraryScope();
|
||||
assert libraryScope != null;
|
||||
ClassifierDescriptor tupleDescriptor = libraryScope.getClassifier(Name.identifier("Tuple" + tupleSize));
|
||||
assert tupleDescriptor != null;
|
||||
declareTupleIntrinsicAccessors(tupleDescriptor, tupleSize);
|
||||
}
|
||||
|
||||
private void declareStringIntrinsics() {
|
||||
//TODO: same intrinsic for 2 different methods
|
||||
PropertyDescriptor stringLengthProperty =
|
||||
getPropertyByName(library.getString().getDefaultType().getMemberScope(), Name.identifier("length"));
|
||||
functionIntrinsics.put(stringLengthProperty.getGetter(), lengthPropertyIntrinsic);
|
||||
PropertyDescriptor charSequenceLengthProperty =
|
||||
getPropertyByName(library.getCharSequence().getDefaultType().getMemberScope(), Name.identifier("length"));
|
||||
functionIntrinsics.put(charSequenceLengthProperty.getGetter(), lengthPropertyIntrinsic);
|
||||
FunctionDescriptor getFunction =
|
||||
getFunctionByName(library.getString().getDefaultType().getMemberScope(), Name.identifier("get"));
|
||||
functionIntrinsics.put(getFunction, CharAtIntrinsic.INSTANCE);
|
||||
}
|
||||
|
||||
private void declareTupleIntrinsicAccessors(@NotNull ClassifierDescriptor tupleDescriptor,
|
||||
int tupleSize) {
|
||||
for (int elementIndex = 0; elementIndex < tupleSize; ++elementIndex) {
|
||||
Name accessorName = Name.identifier("_" + (elementIndex + 1));
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
getPropertyByName(tupleDescriptor.getDefaultType().getMemberScope(), accessorName);
|
||||
functionIntrinsics.put(propertyDescriptor.getGetter(), new TupleAccessIntrinsic(elementIndex));
|
||||
}
|
||||
}
|
||||
|
||||
private void declareOperatorIntrinsics() {
|
||||
IntrinsicDeclarationVisitor visitor = new IntrinsicDeclarationVisitor();
|
||||
for (DeclarationDescriptor descriptor : library.getLibraryScope().getAllDescriptors()) {
|
||||
//noinspection NullableProblems
|
||||
descriptor.accept(visitor, null);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIntrinsic(@NotNull DeclarationDescriptor descriptor) {
|
||||
//NOTE: that if we want to add other intrinsics we have to modify this method
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor.getOriginal();
|
||||
return (equalsIntrinsics.containsKey(functionDescriptor) ||
|
||||
compareToIntrinsics.containsKey(functionDescriptor) ||
|
||||
functionIntrinsics.containsKey(functionDescriptor));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//NOTE: that if we want to add other intrinsics we have to modify this method
|
||||
@NotNull
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
FunctionIntrinsic intrinsic = functionIntrinsics.get(descriptor.getOriginal());
|
||||
if (intrinsic == null) {
|
||||
intrinsic = equalsIntrinsics.get(descriptor.getOriginal());
|
||||
}
|
||||
if (intrinsic == null) {
|
||||
intrinsic = compareToIntrinsics.get(descriptor.getOriginal());
|
||||
}
|
||||
return intrinsic;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompareToIntrinsic getCompareToIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
return compareToIntrinsics.get(descriptor.getOriginal());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EqualsIntrinsic getEqualsIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
return equalsIntrinsics.get(descriptor.getOriginal());
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private final class IntrinsicDeclarationVisitor extends DeclarationDescriptorVisitorEmptyBodies<Void, Void> {
|
||||
|
||||
@Override
|
||||
public Void visitClassDescriptor(@NotNull ClassDescriptor descriptor, @Nullable Void nothing) {
|
||||
for (DeclarationDescriptor memberDescriptor :
|
||||
descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||
//noinspection NullableProblems
|
||||
memberDescriptor.accept(this, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitFunctionDescriptor(@NotNull FunctionDescriptor descriptor, @Nullable Void nothing) {
|
||||
if (!isIntrinsic(descriptor)) {
|
||||
declareOperatorIntrinsic(descriptor);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*package*/ void declareOperatorIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
tryResolveAsEqualsCompareToOrRangeToIntrinsic(descriptor);
|
||||
tryResolveAsUnaryIntrinsics(descriptor);
|
||||
tryResolveAsBinaryIntrinsics(descriptor);
|
||||
}
|
||||
|
||||
private void tryResolveAsEqualsCompareToOrRangeToIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
Name functionName = descriptor.getName();
|
||||
if (functionName.equals(COMPARE_TO)) {
|
||||
compareToIntrinsics.put(descriptor, PrimitiveCompareToIntrinsic.newInstance());
|
||||
}
|
||||
if (functionName.equals(EQUALS)) {
|
||||
equalsIntrinsics.put(descriptor, PrimitiveEqualsIntrinsic.newInstance());
|
||||
}
|
||||
if (functionName.equals(Name.identifier("rangeTo"))) {
|
||||
functionIntrinsics.put(descriptor, PrimitiveRangeToIntrinsic.newInstance());
|
||||
}
|
||||
}
|
||||
|
||||
private void tryResolveAsUnaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||
Name functionName = descriptor.getName();
|
||||
JetToken token = UNARY_OPERATION_NAMES.inverse().get(functionName);
|
||||
|
||||
if (token == null) return;
|
||||
if (!isUnaryOperation(descriptor)) return;
|
||||
|
||||
functionIntrinsics.put(descriptor, PrimitiveUnaryOperationIntrinsic.newInstance(token));
|
||||
}
|
||||
|
||||
private void tryResolveAsBinaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||
Name functionName = descriptor.getName();
|
||||
|
||||
if (isUnaryOperation(descriptor)) return;
|
||||
|
||||
JetToken token = BINARY_OPERATION_NAMES.inverse().get(functionName);
|
||||
if (token == null) return;
|
||||
|
||||
if (!OperatorTable.hasCorrespondingBinaryOperator(token)) return;
|
||||
functionIntrinsics.put(descriptor, PrimitiveBinaryOperationIntrinsic.newInstance(token));
|
||||
}
|
||||
|
||||
private boolean isUnaryOperation(@NotNull FunctionDescriptor descriptor) {
|
||||
return !JsDescriptorUtils.hasParameters(descriptor);
|
||||
}
|
||||
public FunctionIntrinsics getFunctionIntrinsics() {
|
||||
return functionIntrinsics;
|
||||
}
|
||||
}
|
||||
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.array;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsArrayAccess;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum ArrayGetIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 1 : "Array get expression must have one argument.";
|
||||
JsExpression indexExpression = arguments.get(0);
|
||||
return new JsArrayAccess(receiver, indexExpression);
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.array;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsArrayAccess;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum ArraySetIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 2 : "Array set expression must have two arguments.";
|
||||
JsExpression indexExpression = arguments.get(0);
|
||||
JsExpression value = arguments.get(1);
|
||||
JsArrayAccess arrayAccess = AstUtil.newArrayAccess(receiver, indexExpression);
|
||||
return AstUtil.newAssignment(arrayAccess, value);
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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;
|
||||
|
||||
import closurecompiler.internal.com.google.common.collect.Lists;
|
||||
import closurecompiler.internal.com.google.common.collect.Maps;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.factories.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class FunctionIntrinsics {
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic NO_INTRINSIC = new FunctionIntrinsic() {
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
throw new UnsupportedOperationException("FunctionIntrinsic#NO_INTRINSIC_#apply");
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private final Map<FunctionDescriptor, FunctionIntrinsic> intrinsicCache = Maps.newHashMap();
|
||||
|
||||
@NotNull
|
||||
private final List<FunctionIntrinsicFactory> factories = Lists.newArrayList();
|
||||
|
||||
public FunctionIntrinsics() {
|
||||
registerFactories();
|
||||
}
|
||||
|
||||
private void registerFactories() {
|
||||
register(PrimitiveUnaryOperationFIF.INSTANCE);
|
||||
register(PrimitiveBinaryOperationFIF.INSTANCE);
|
||||
register(TupleGetterFIF.INSTANCE);
|
||||
register(StringOperationFIF.INSTANCE);
|
||||
register(ArrayFIF.INSTANCE);
|
||||
register(TopLevelFIF.INSTANCE);
|
||||
}
|
||||
|
||||
private boolean register(@NotNull FunctionIntrinsicFactory instance) {
|
||||
return factories.add(instance);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
FunctionIntrinsic intrinsic = lookUpCache(descriptor);
|
||||
if (intrinsic != null) {
|
||||
return intrinsic;
|
||||
}
|
||||
intrinsic = computeAndCacheIntrinsic(descriptor);
|
||||
return intrinsic;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FunctionIntrinsic lookUpCache(@NotNull FunctionDescriptor descriptor) {
|
||||
return intrinsicCache.get(descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FunctionIntrinsic computeAndCacheIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
FunctionIntrinsic result = computeIntrinsic(descriptor);
|
||||
intrinsicCache.put(descriptor, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FunctionIntrinsic computeIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
for (FunctionIntrinsicFactory factory : factories) {
|
||||
if (factory.getPattern().apply(descriptor)) {
|
||||
return factory.getIntrinsic(descriptor);
|
||||
}
|
||||
}
|
||||
return NO_INTRINSIC;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
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.JsNameRef;
|
||||
@@ -31,7 +31,7 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class BuiltInFunctionIntrinsic implements FunctionIntrinsic {
|
||||
public final class BuiltInFunctionIntrinsic extends FunctionIntrinsic {
|
||||
|
||||
@NotNull
|
||||
private final String functionName;
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
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.JsNameRef;
|
||||
@@ -15,7 +15,7 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
//TODO: find should be usages
|
||||
public final class BuiltInPropertyIntrinsic implements FunctionIntrinsic {
|
||||
public final class BuiltInPropertyIntrinsic extends FunctionIntrinsic {
|
||||
|
||||
@NotNull
|
||||
private final String propertyName;
|
||||
+4
-4
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
package org.jetbrains.k2js.translate.intrinsic.functions.basic;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.Source;
|
||||
@@ -33,7 +33,7 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class CallStandardMethodIntrinsic implements FunctionIntrinsic {
|
||||
public final class CallStandardMethodIntrinsic extends FunctionIntrinsic {
|
||||
|
||||
@NotNull
|
||||
private final String methodName;
|
||||
@@ -50,8 +50,8 @@ public final class CallStandardMethodIntrinsic implements FunctionIntrinsic {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert (receiver != null == receiverShouldBeNotNull);
|
||||
assert arguments.size() == expectedParamsNumber : "Incorrect number of arguments " + arguments.size() + " when expected " + expectedParamsNumber + " on method " + methodName + " " + atLocation(receiver, arguments);
|
||||
JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef(methodName);
|
||||
+8
-4
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
package org.jetbrains.k2js.translate.intrinsic.functions.basic;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -28,9 +28,13 @@ import java.util.List;
|
||||
* <p/>
|
||||
* Base for intrinsics that substitute standard function calls like Int#plus, Float#minus ... etc
|
||||
*/
|
||||
public interface FunctionIntrinsic {
|
||||
public abstract class FunctionIntrinsic {
|
||||
|
||||
@NotNull
|
||||
JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context);
|
||||
public abstract JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context);
|
||||
|
||||
public boolean exists() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.factories;
|
||||
|
||||
import closurecompiler.internal.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.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.lang.PrimitiveType;
|
||||
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.NameChecker;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class ArrayFIF {
|
||||
|
||||
@NotNull
|
||||
private static final NameChecker ARRAYS;
|
||||
|
||||
static {
|
||||
List<Name> arrayTypeNames = Lists.newArrayList();
|
||||
for (PrimitiveType type : PrimitiveType.values()) {
|
||||
arrayTypeNames.add(type.getArrayTypeName());
|
||||
}
|
||||
arrayTypeNames.add(Name.identifier("Array"));
|
||||
ARRAYS = new NameChecker(arrayTypeNames);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic GET_INTRINSIC = new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 1 : "Array get expression must have one argument.";
|
||||
JsExpression indexExpression = arguments.get(0);
|
||||
return new JsArrayAccess(receiver, indexExpression);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic SET_INTRINSIC = new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 2 : "Array set expression must have two arguments.";
|
||||
JsExpression indexExpression = arguments.get(0);
|
||||
JsExpression value = arguments.get(1);
|
||||
JsArrayAccess arrayAccess = AstUtil.newArrayAccess(receiver, indexExpression);
|
||||
return AstUtil.newAssignment(arrayAccess, value);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static final BuiltInPropertyIntrinsic ARRAY_LENGTH_INTRINSIC = new BuiltInPropertyIntrinsic("length");
|
||||
|
||||
@NotNull
|
||||
public static final FunctionIntrinsicFactory INSTANCE = FIFBuilder.start()
|
||||
.add(pattern(ARRAYS, "get"), GET_INTRINSIC)
|
||||
.add(pattern(ARRAYS, "set"), SET_INTRINSIC)
|
||||
.add(pattern(ARRAYS, "<get-size>"), ARRAY_LENGTH_INTRINSIC)
|
||||
.add(pattern(ARRAYS, "<get-indices>"), new CallStandardMethodIntrinsic("Kotlin.arrayIndices", true, 0))
|
||||
.add(pattern(ARRAYS, "iterator"), new CallStandardMethodIntrinsic("Kotlin.arrayIterator", true, 0))
|
||||
.add(pattern(ARRAYS, "<init>"), new CallStandardMethodIntrinsic("Kotlin.arrayFromFun", false, 2))
|
||||
.build();
|
||||
|
||||
private ArrayFIF() {
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.factories;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.Pattern;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class FIFBuilder {
|
||||
|
||||
@NotNull final Map<Pattern, FunctionIntrinsic> patternToIntrinsic = Maps.newHashMap();
|
||||
|
||||
private FIFBuilder() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FIFBuilder start() {
|
||||
return new FIFBuilder();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FIFBuilder add(@NotNull Pattern pattern, @NotNull FunctionIntrinsic intrinsic) {
|
||||
patternToIntrinsic.put(pattern, intrinsic);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FunctionIntrinsicFactory build() {
|
||||
return new FunctionIntrinsicFactory() {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pattern getPattern() {
|
||||
Collection<Pattern> patterns = patternToIntrinsic.keySet();
|
||||
return PatternBuilder.any(patterns.toArray(new Pattern[patterns.size()]));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
for (Pattern pattern : patternToIntrinsic.keySet()) {
|
||||
if (pattern.apply(descriptor)) {
|
||||
return patternToIntrinsic.get(pattern);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Must have intrinsic for pattern.");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+8
-10
@@ -14,23 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
package org.jetbrains.k2js.translate.intrinsic.functions.factories;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.Pattern;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public abstract class EqualsIntrinsic implements FunctionIntrinsic {
|
||||
public interface FunctionIntrinsicFactory {
|
||||
|
||||
@NotNull
|
||||
private Boolean isNegated = false;
|
||||
Pattern getPattern();
|
||||
|
||||
public void setNegated(boolean isNegated) {
|
||||
this.isNegated = isNegated;
|
||||
}
|
||||
|
||||
protected boolean isNegated() {
|
||||
return isNegated;
|
||||
}
|
||||
@NotNull
|
||||
FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor);
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.factories;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NameChecker;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.Pattern;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
INSTANCE;
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic RANGE_TO_INTRINSIC = new FunctionIntrinsic() {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression rangeStart, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.size() == 1 : "RangeTo must have one argument.";
|
||||
assert rangeStart != null;
|
||||
JsExpression rangeEnd = arguments.get(0);
|
||||
JsBinaryOperation rangeSize = sum(subtract(rangeEnd, rangeStart),
|
||||
context.program().getNumberLiteral(1));
|
||||
JsNameRef expr = AstUtil.newQualifiedNameRef("Kotlin.NumberRange");
|
||||
HasArguments numberRangeConstructorInvocation = context.isEcma5() ? AstUtil.newInvocation(expr) : new JsNew(expr);
|
||||
//TODO: add tests and correct expression for reversed ranges.
|
||||
JsBooleanLiteral isRangeReversed = context.program().getFalseLiteral();
|
||||
setArguments(numberRangeConstructorInvocation, rangeStart, rangeSize, isRangeReversed);
|
||||
return (JsExpression) numberRangeConstructorInvocation;
|
||||
}
|
||||
};
|
||||
@NotNull
|
||||
private static final NameChecker BINARY_OPERATIONS = new NameChecker(OperatorConventions.BINARY_OPERATION_NAMES.values());
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pattern getPattern() {
|
||||
//TODO: check that it is binary operation
|
||||
return PatternBuilder.any(pattern(NameChecker.PRIMITIVE_NUMBERS, BINARY_OPERATIONS),
|
||||
pattern("Boolean.or|and|xor"),
|
||||
pattern("String.plus"));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
if (descriptor.getName().equals(Name.identifier("rangeTo"))) {
|
||||
return RANGE_TO_INTRINSIC;
|
||||
}
|
||||
final JsBinaryOperator operator = getOperator(descriptor);
|
||||
return new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.size() == 1 : "Binary operator should have a receiver and one argument";
|
||||
return new JsBinaryOperation(operator, receiver, arguments.get(0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsBinaryOperator getOperator(@NotNull FunctionDescriptor descriptor) {
|
||||
JetToken token = OperatorConventions.BINARY_OPERATION_NAMES.inverse().get(descriptor.getName());
|
||||
if (token == null) {
|
||||
token = OperatorConventions.BOOLEAN_OPERATIONS.inverse().get(descriptor.getName());
|
||||
}
|
||||
if (token == null) {
|
||||
assert descriptor.getName().getName().equals("xor");
|
||||
return JsBinaryOperator.BIT_XOR;
|
||||
}
|
||||
return OperatorTable.getBinaryOperator(token);
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.factories;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsPrefixOperation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsUnaryOperator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NameChecker;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.Pattern;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.NameChecker.PRIMITIVE_NUMBERS;
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.*;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
private static final NameChecker UNARY_OPERATIONS = new NameChecker(OperatorConventions.UNARY_OPERATION_NAMES.values());
|
||||
@NotNull
|
||||
private static final Pattern UNARY_OPERATION_FOR_PRIMITIVE_NUMBER =
|
||||
pattern(PRIMITIVE_NUMBERS, UNARY_OPERATIONS);
|
||||
@NotNull
|
||||
private static final Pattern NO_PARAMETERS = new Pattern() {
|
||||
@Override
|
||||
public boolean apply(@NotNull FunctionDescriptor descriptor) {
|
||||
return !JsDescriptorUtils.hasParameters(descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pattern getPattern() {
|
||||
Pattern primitiveUnaryOperationNames = any(UNARY_OPERATION_FOR_PRIMITIVE_NUMBER, pattern("Boolean.not"));
|
||||
return all(primitiveUnaryOperationNames, NO_PARAMETERS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@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);
|
||||
return new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.factories;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.BuiltInPropertyIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.Pattern;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class StringOperationFIF {
|
||||
|
||||
@NotNull
|
||||
private static final Pattern GET_PATTERN = pattern("String.get");
|
||||
|
||||
@NotNull
|
||||
private static final FunctionIntrinsic GET_INTRINSIC = new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 1 : "String#get expression must have 1 argument.";
|
||||
//TODO: provide better way
|
||||
JsNameRef charAtReference = AstUtil.newQualifiedNameRef("charAt");
|
||||
setQualifier(charAtReference, receiver);
|
||||
return newInvocation(charAtReference, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static final FunctionIntrinsicFactory INSTANCE = FIFBuilder.start()
|
||||
.add(GET_PATTERN, GET_INTRINSIC)
|
||||
.add(pattern("String.<get-length>"), new BuiltInPropertyIntrinsic("length"))
|
||||
.add(pattern("CharSequence.<get-length>"), new BuiltInPropertyIntrinsic("length"))
|
||||
.build();
|
||||
|
||||
private StringOperationFIF() {
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.factories;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
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.patterns.Pattern;
|
||||
|
||||
import static org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder.pattern;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class TopLevelFIF {
|
||||
|
||||
@NotNull
|
||||
private static final Pattern EXT_TO_STRING = pattern("toString");
|
||||
|
||||
@NotNull
|
||||
public static final FunctionIntrinsicFactory INSTANCE = FIFBuilder.start()
|
||||
.add(EXT_TO_STRING, new BuiltInFunctionIntrinsic("toString"))
|
||||
//TODO: add intrinsic for calling equals explicitly
|
||||
.add(pattern("arrayOfNulls"), new CallStandardMethodIntrinsic("Kotlin.nullArray", false, 1))
|
||||
.build();
|
||||
|
||||
private TopLevelFIF() {
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.factories;
|
||||
|
||||
import closurecompiler.internal.com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NameChecker;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.Pattern;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum TupleGetterFIF implements FunctionIntrinsicFactory {
|
||||
INSTANCE;
|
||||
|
||||
@NotNull
|
||||
private static final NameChecker TUPLES;
|
||||
|
||||
static {
|
||||
List<String> tupleNames = Lists.newArrayList();
|
||||
for (int tupleSize = 0; tupleSize <= JetStandardClasses.MAX_TUPLE_ORDER; ++tupleSize) {
|
||||
tupleNames.add("Tuple" + tupleSize);
|
||||
}
|
||||
TUPLES = new NameChecker(tupleNames);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static final NameChecker TUPLE_UNDERSCORE_ACCESSORS;
|
||||
|
||||
static {
|
||||
List<String> accessorNames = Lists.newArrayList();
|
||||
for (int tupleSize = 0; tupleSize <= JetStandardClasses.MAX_TUPLE_ORDER; ++tupleSize) {
|
||||
accessorNames.add("<get-_" + (tupleSize + 1) + ">");
|
||||
}
|
||||
TUPLE_UNDERSCORE_ACCESSORS = new NameChecker(accessorNames);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pattern getPattern() {
|
||||
return PatternBuilder.pattern(TUPLES, TUPLE_UNDERSCORE_ACCESSORS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||
String nameString = descriptor.getName().getName();
|
||||
String elementIndexSubString = nameString.substring(6, nameString.length() - 1);
|
||||
final int elementIndex = Integer.parseInt(elementIndexSubString) - 1;
|
||||
return new FunctionIntrinsic() {
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver,
|
||||
@NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.isEmpty() : "Tuple access expression should not have any arguments.";
|
||||
return AstUtil.newArrayAccess(receiver, context.program().getNumberLiteral(elementIndex));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.patterns;
|
||||
|
||||
import closurecompiler.internal.com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class NameChecker {
|
||||
|
||||
@NotNull
|
||||
public static final NameChecker PRIMITIVE_NUMBERS = new NameChecker("Int", "Double", "Float", "Long", "Short");
|
||||
|
||||
@NotNull
|
||||
private final List<Name> validNames = Lists.newArrayList();
|
||||
|
||||
public NameChecker(@NotNull String... validNames) {
|
||||
this(Arrays.asList(validNames));
|
||||
}
|
||||
|
||||
public NameChecker(@NotNull List<String> validNames) {
|
||||
for (String validName : validNames) {
|
||||
this.validNames.add(Name.guess(validName));
|
||||
}
|
||||
}
|
||||
|
||||
public NameChecker(@NotNull Collection<Name> validNames) {
|
||||
this.validNames.addAll(validNames);
|
||||
}
|
||||
|
||||
public boolean isValid(@NotNull Name name) {
|
||||
for (Name validName : validNames) {
|
||||
if (name.equals(validName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+3
-6
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
package org.jetbrains.k2js.translate.intrinsic.functions.patterns;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
@@ -22,10 +22,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public abstract class FunctionIntrinsicFactory {
|
||||
public interface Pattern {
|
||||
|
||||
public abstract boolean isApplicable(@NotNull FunctionDescriptor descriptor);
|
||||
|
||||
@NotNull
|
||||
public abstract FunctionIntrinsic createIntrinsic(@NotNull FunctionDescriptor descriptor);
|
||||
boolean apply(@NotNull FunctionDescriptor descriptor);
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.patterns;
|
||||
|
||||
import closurecompiler.internal.com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class PatternBuilder {
|
||||
|
||||
public static final NameChecker JET = new NameChecker("jet");
|
||||
|
||||
private PatternBuilder() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pattern pattern(@NotNull NameChecker checker, @NotNull String stringWithPattern) {
|
||||
List<NameChecker> checkers = Lists.newArrayList(checker);
|
||||
checkers.addAll(parseStringAsCheckerList(stringWithPattern));
|
||||
return pattern(checkers);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pattern pattern(@NotNull String string) {
|
||||
List<NameChecker> checkers = parseStringAsCheckerList(string);
|
||||
return pattern(checkers);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<NameChecker> parseStringAsCheckerList(@NotNull String stringWithPattern) {
|
||||
String[] subPatterns = stringWithPattern.split("\\.");
|
||||
List<NameChecker> checkers = Lists.newArrayList();
|
||||
for (String subPattern : subPatterns) {
|
||||
String[] validNames = subPattern.split("\\|");
|
||||
checkers.add(new NameChecker(validNames));
|
||||
}
|
||||
return checkers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Pattern pattern(@NotNull List<NameChecker> checkers) {
|
||||
final List<NameChecker> checkersWithPrefixChecker = Lists.newArrayList(JET);
|
||||
checkersWithPrefixChecker.addAll(checkers);
|
||||
return new Pattern() {
|
||||
@Override
|
||||
public boolean apply(@NotNull FunctionDescriptor descriptor) {
|
||||
//TODO: no need to wrap if we check beforehand
|
||||
try {
|
||||
return doApply(descriptor);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doApply(@NotNull FunctionDescriptor descriptor) {
|
||||
List<Name> nameParts = DescriptorUtils.getFQName(descriptor).pathSegments();
|
||||
if (nameParts.size() != checkersWithPrefixChecker.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!allNamePartsValid(nameParts)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean allNamePartsValid(@NotNull List<Name> nameParts) {
|
||||
for (int i = 0; i < nameParts.size(); ++i) {
|
||||
Name namePart = nameParts.get(i);
|
||||
NameChecker correspondingPredicate = checkersWithPrefixChecker.get(i);
|
||||
if (!correspondingPredicate.isValid(namePart)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pattern pattern(@NotNull final NameChecker... checkers) {
|
||||
return pattern(Arrays.asList(checkers));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pattern any(@NotNull final Pattern... patterns) {
|
||||
return new Pattern() {
|
||||
@Override
|
||||
public boolean apply(@NotNull FunctionDescriptor descriptor) {
|
||||
for (Pattern pattern : patterns) {
|
||||
if (pattern.apply(descriptor)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pattern all(@NotNull final Pattern... patterns) {
|
||||
return new Pattern() {
|
||||
@Override
|
||||
public boolean apply(@NotNull FunctionDescriptor descriptor) {
|
||||
for (Pattern pattern : patterns) {
|
||||
if (!pattern.apply(descriptor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+6
-13
@@ -14,27 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic;
|
||||
package org.jetbrains.k2js.translate.intrinsic.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum ReturnReceiverIntrinsic implements FunctionIntrinsic {
|
||||
public interface BinaryOperationIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
boolean isApplicable(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
return receiver;
|
||||
}
|
||||
JsExpression apply(@NotNull JetBinaryExpression expression, @NotNull JsExpression left,
|
||||
@NotNull JsExpression right, @NotNull TranslationContext context);
|
||||
}
|
||||
+22
-16
@@ -14,33 +14,39 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.intrinsic.tuple;
|
||||
package org.jetbrains.k2js.translate.intrinsic.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import closurecompiler.internal.com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class TupleAccessIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
private final int elementIndex;
|
||||
|
||||
public TupleAccessIntrinsic(int elementIndex) {
|
||||
this.elementIndex = elementIndex;
|
||||
}
|
||||
public final class BinaryOperationIntrinsics {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.isEmpty() : "Tuple access expression should not have any arguments.";
|
||||
return AstUtil.newArrayAccess(receiver, context.program().getNumberLiteral(elementIndex));
|
||||
private final List<BinaryOperationIntrinsic> intrinsics = Lists.newArrayList();
|
||||
|
||||
{
|
||||
intrinsics.add(new EqualsIntrinsic());
|
||||
intrinsics.add(new CompareToInstrinsic());
|
||||
}
|
||||
|
||||
public BinaryOperationIntrinsics() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BinaryOperationIntrinsic getIntrinsic(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
for (BinaryOperationIntrinsic intrinsic : intrinsics) {
|
||||
if (intrinsic.isApplicable(expression, context)) {
|
||||
return intrinsic;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class CompareToInstrinsic implements BinaryOperationIntrinsic {
|
||||
@Override
|
||||
public boolean isApplicable(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
if (!OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression))) {
|
||||
return false;
|
||||
}
|
||||
FunctionDescriptor functionDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
assert functionDescriptor != null;
|
||||
return JsDescriptorUtils.isStandardDeclaration(functionDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsExpression apply(@NotNull JetBinaryExpression expression,
|
||||
@NotNull JsExpression left,
|
||||
@NotNull JsExpression right,
|
||||
@NotNull TranslationContext context) {
|
||||
JsBinaryOperator operator = OperatorTable.getBinaryOperator(getOperationToken(expression));
|
||||
return new JsBinaryOperation(operator, left, right);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.utils.JsDescriptorUtils;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.equality;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.inequality;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNullLiteral;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.nullCheck;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class EqualsIntrinsic implements BinaryOperationIntrinsic {
|
||||
@Override
|
||||
public boolean isApplicable(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context) {
|
||||
if (!OperatorConventions.EQUALS_OPERATIONS.contains(getOperationToken(expression))) {
|
||||
return false;
|
||||
}
|
||||
FunctionDescriptor functionDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
assert functionDescriptor != null;
|
||||
return JsDescriptorUtils.isStandardDeclaration(functionDescriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsExpression apply(@NotNull JetBinaryExpression expression,
|
||||
@NotNull JsExpression left,
|
||||
@NotNull JsExpression right,
|
||||
@NotNull TranslationContext context) {
|
||||
boolean isNegated = getOperationToken(expression).equals(JetTokens.EXCLEQ);
|
||||
if (isNullLiteral(context, right)) {
|
||||
return nullCheck(context, left, !isNegated);
|
||||
}
|
||||
if (isNullLiteral(context, left)) {
|
||||
return nullCheck(context, right, !isNegated);
|
||||
}
|
||||
if (isNegated) {
|
||||
return inequality(left, right);
|
||||
}
|
||||
else {
|
||||
return equality(left, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.primitive;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class PrimitiveBinaryOperationIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
@NotNull
|
||||
public static PrimitiveBinaryOperationIntrinsic newInstance(@NotNull JetToken token) {
|
||||
JsBinaryOperator operator = OperatorTable.getBinaryOperator(token);
|
||||
return new PrimitiveBinaryOperationIntrinsic(operator);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PrimitiveBinaryOperationIntrinsic newInstance(@NotNull JsBinaryOperator operator) {
|
||||
return new PrimitiveBinaryOperationIntrinsic(operator);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private final JsBinaryOperator operator;
|
||||
|
||||
private PrimitiveBinaryOperationIntrinsic(@NotNull JsBinaryOperator operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.size() == 1 : "Binary operator should have a receiver and one argument";
|
||||
return new JsBinaryOperation(operator, receiver, arguments.get(0));
|
||||
}
|
||||
}
|
||||
-52
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.primitive;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class PrimitiveCompareToIntrinsic extends CompareToIntrinsic {
|
||||
|
||||
@NotNull
|
||||
public static PrimitiveCompareToIntrinsic newInstance() {
|
||||
return new PrimitiveCompareToIntrinsic();
|
||||
}
|
||||
|
||||
private PrimitiveCompareToIntrinsic() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.size() == 1 : "Equals operation should have one argument";
|
||||
JsBinaryOperator operator = OperatorTable.getBinaryOperator(getComparisonToken());
|
||||
JsExpression argument = arguments.get(0);
|
||||
return new JsBinaryOperation(operator, receiver, argument);
|
||||
}
|
||||
|
||||
}
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.primitive;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.equality;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.inequality;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNullLiteral;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.nullCheck;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class PrimitiveEqualsIntrinsic extends EqualsIntrinsic {
|
||||
|
||||
@NotNull
|
||||
public static PrimitiveEqualsIntrinsic newInstance() {
|
||||
return new PrimitiveEqualsIntrinsic();
|
||||
}
|
||||
|
||||
private PrimitiveEqualsIntrinsic() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.size() == 1 : "Equals operation should have one argument";
|
||||
assert receiver != null;
|
||||
JsExpression argument = arguments.get(0);
|
||||
if (isNullLiteral(context, argument)) {
|
||||
return nullCheck(context, receiver, !isNegated());
|
||||
}
|
||||
if (isNullLiteral(context, receiver)) {
|
||||
return nullCheck(context, argument, !isNegated());
|
||||
}
|
||||
if (isNegated()) {
|
||||
return inequality(receiver, argument);
|
||||
}
|
||||
else {
|
||||
return equality(receiver, argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.primitive;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class PrimitiveRangeToIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
@NotNull
|
||||
public static PrimitiveRangeToIntrinsic newInstance() {
|
||||
return new PrimitiveRangeToIntrinsic();
|
||||
}
|
||||
|
||||
private PrimitiveRangeToIntrinsic() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression rangeStart, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert arguments.size() == 1 : "RangeTo must have one argument.";
|
||||
assert rangeStart != null;
|
||||
JsExpression rangeEnd = arguments.get(0);
|
||||
JsBinaryOperation rangeSize = sum(subtract(rangeEnd, rangeStart),
|
||||
context.program().getNumberLiteral(1));
|
||||
//TODO: provide a way not to hard code this value
|
||||
JsNameRef expr = AstUtil.newQualifiedNameRef("Kotlin.NumberRange");
|
||||
HasArguments numberRangeConstructorInvocation = context.isEcma5() ? AstUtil.newInvocation(expr) : new JsNew(expr);
|
||||
//TODO: add tests and correct expression for reversed ranges.
|
||||
JsBooleanLiteral isRangeReversed = context.program().getFalseLiteral();
|
||||
setArguments(numberRangeConstructorInvocation, rangeStart, rangeSize, isRangeReversed);
|
||||
return (JsExpression) numberRangeConstructorInvocation;
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.primitive;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsPrefixOperation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsUnaryOperator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class PrimitiveUnaryOperationIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
@NotNull
|
||||
public static PrimitiveUnaryOperationIntrinsic newInstance(@NotNull JetToken token) {
|
||||
JsUnaryOperator operator = OperatorTable.getUnaryOperator(token);
|
||||
return new PrimitiveUnaryOperationIntrinsic(operator);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final JsUnaryOperator operator;
|
||||
|
||||
private PrimitiveUnaryOperationIntrinsic(@NotNull JsUnaryOperator operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 0 : "Unary operator should not have arguments.";
|
||||
//NOTE: cannot use this for increment/decrement
|
||||
return new JsPrefixOperation(operator, receiver);
|
||||
}
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.string;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum CharAtIntrinsic implements FunctionIntrinsic {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
assert arguments.size() == 1 : "get Char expression must have 1 arguments.";
|
||||
//TODO: provide better way
|
||||
JsNameRef charAtReference = AstUtil.newQualifiedNameRef("charAt");
|
||||
setQualifier(charAtReference, receiver);
|
||||
return newInvocation(charAtReference, arguments);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -29,7 +29,7 @@ import org.jetbrains.k2js.translate.reference.AccessTranslator;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.isAssignment;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.hasCorrespondingFunctionIntrinsic;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
if (isIntrinsicOperation(context, expression)) {
|
||||
if (hasCorrespondingFunctionIntrinsic(context, expression)) {
|
||||
return IntrinsicAssignmentTranslator.doTranslate(expression, context);
|
||||
}
|
||||
return OverloadedAssignmentTranslator.doTranslate(expression, context);
|
||||
|
||||
+20
-14
@@ -30,7 +30,7 @@ import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.operation.BinaryOperationIntrinsic;
|
||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||
import org.jetbrains.k2js.translate.reference.CallType;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
@@ -40,9 +40,9 @@ import static org.jetbrains.k2js.translate.operation.CompareToTranslator.isCompa
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.not;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isEquals;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
|
||||
|
||||
|
||||
/**
|
||||
@@ -78,6 +78,10 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression translate() {
|
||||
BinaryOperationIntrinsic intrinsic = getIntrinsicForExpression();
|
||||
if (intrinsic != null) {
|
||||
return applyIntrinsic(intrinsic);
|
||||
}
|
||||
if (isElvisOperator(expression)) {
|
||||
return translateAsElvisOperator(expression);
|
||||
}
|
||||
@@ -92,12 +96,22 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
|
||||
}
|
||||
assert operationDescriptor != null :
|
||||
"Overloadable operations must have not null descriptor";
|
||||
if (isEquals(operationDescriptor) && context().intrinsics().isIntrinsic(operationDescriptor)) {
|
||||
return translateAsEqualsIntrinsic();
|
||||
}
|
||||
return translateAsOverloadedBinaryOperation();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BinaryOperationIntrinsic getIntrinsicForExpression() {
|
||||
return context().intrinsics().getBinaryOperationIntrinsics().getIntrinsic(expression, context());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression applyIntrinsic(@NotNull BinaryOperationIntrinsic intrinsic) {
|
||||
return intrinsic.apply(expression,
|
||||
translateLeftExpression(context(), expression),
|
||||
translateRightExpression(context(), expression),
|
||||
context());
|
||||
}
|
||||
|
||||
private static boolean isElvisOperator(@NotNull JetBinaryExpression expression) {
|
||||
return getOperationToken(expression).equals(JetTokens.ELVIS);
|
||||
}
|
||||
@@ -115,14 +129,6 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
|
||||
return operationDescriptor == null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateAsEqualsIntrinsic() {
|
||||
assert operationDescriptor != null : "Equals operation must resolve to descriptor.";
|
||||
EqualsIntrinsic intrinsic = context().intrinsics().getEqualsIntrinsic(operationDescriptor);
|
||||
intrinsic.setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ));
|
||||
return applyIntrinsicToBinaryExpression(context(), intrinsic, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateAsUnOverloadableBinaryOperation() {
|
||||
JetToken token = getOperationToken(expression);
|
||||
|
||||
+3
-27
@@ -23,17 +23,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isCompareTo;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.applyIntrinsicToBinaryExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -41,7 +37,7 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOpe
|
||||
public final class CompareToTranslator extends AbstractTranslator {
|
||||
|
||||
public static boolean isCompareToCall(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull TranslationContext context) {
|
||||
FunctionDescriptor operationDescriptor =
|
||||
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
|
||||
@@ -52,47 +48,27 @@ public final class CompareToTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull TranslationContext context) {
|
||||
return (new CompareToTranslator(expression, context)).translate();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final JetBinaryExpression expression;
|
||||
|
||||
@NotNull
|
||||
private final FunctionDescriptor descriptor;
|
||||
|
||||
private CompareToTranslator(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.expression = expression;
|
||||
FunctionDescriptor functionDescriptor =
|
||||
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
assert functionDescriptor != null : "CompareTo should always have a descriptor";
|
||||
this.descriptor = functionDescriptor;
|
||||
assert (OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translate() {
|
||||
if (isIntrinsicOperation(context(), expression)) {
|
||||
return intrinsicCompareTo();
|
||||
}
|
||||
return overloadedCompareTo();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression overloadedCompareTo() {
|
||||
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(getOperationToken(expression));
|
||||
JsExpression methodCall = BinaryOperationTranslator.translateAsOverloadedCall(expression, context());
|
||||
return new JsBinaryOperation(correspondingOperator, methodCall, TranslationUtils.zeroLiteral(context()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression intrinsicCompareTo() {
|
||||
CompareToIntrinsic intrinsic = context().intrinsics().getCompareToIntrinsic(descriptor);
|
||||
intrinsic.setComparisonToken((JetToken) expression.getOperationToken());
|
||||
return applyIntrinsicToBinaryExpression(context(), intrinsic, expression);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -34,7 +34,7 @@ import static org.jetbrains.k2js.translate.reference.AccessTranslationUtils.getC
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.newSequence;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.hasCorrespondingFunctionIntrinsic;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -49,7 +49,7 @@ public abstract class IncrementTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
public static JsExpression translate(@NotNull JetUnaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
if (isIntrinsicOperation(context, expression)) {
|
||||
if (hasCorrespondingFunctionIntrinsic(context, expression)) {
|
||||
return IntrinsicIncrementTranslator.doTranslate(expression, context);
|
||||
}
|
||||
return (new OverloadedIncrementTranslator(expression, context)).translateIncrementExpression();
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.k2js.translate.utils.ErrorReportingUtils;
|
||||
|
||||
@@ -119,14 +119,19 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private boolean isIntrinsic() {
|
||||
return context().intrinsics().isIntrinsic(descriptor);
|
||||
if (descriptor instanceof FunctionDescriptor) {
|
||||
FunctionIntrinsic intrinsic = context().intrinsics().getFunctionIntrinsics().getIntrinsic((FunctionDescriptor) descriptor);
|
||||
return intrinsic.exists();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression intrinsicInvocation() {
|
||||
assert descriptor instanceof FunctionDescriptor;
|
||||
try {
|
||||
FunctionIntrinsic intrinsic = context().intrinsics().getIntrinsic((FunctionDescriptor) descriptor);
|
||||
FunctionIntrinsic intrinsic = context().intrinsics().getFunctionIntrinsics().getIntrinsic((FunctionDescriptor) descriptor);
|
||||
assert intrinsic.exists();
|
||||
return intrinsic.apply(callParameters.getThisOrReceiverOrNull(), arguments, context());
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
|
||||
@@ -25,17 +25,19 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.isNotAny;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -53,10 +55,6 @@ public final class JsDescriptorUtils {
|
||||
return (valueParametersCount(functionDescriptor) > 0);
|
||||
}
|
||||
|
||||
public static boolean isEquals(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
return (functionDescriptor.getName().equals(OperatorConventions.EQUALS));
|
||||
}
|
||||
|
||||
public static boolean isCompareTo(@NotNull FunctionDescriptor functionDescriptor) {
|
||||
return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO));
|
||||
}
|
||||
@@ -65,34 +63,6 @@ public final class JsDescriptorUtils {
|
||||
return (descriptor instanceof ConstructorDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FunctionDescriptor getFunctionByName(@NotNull JetScope scope,
|
||||
@NotNull Name name) {
|
||||
Collection<FunctionDescriptor> functionDescriptors = scope.getFunctions(name);
|
||||
assert functionDescriptors.size() == 1 :
|
||||
"In scope " + scope + " supposed to be exactly one " + name + " function.\n" +
|
||||
"Found: " + functionDescriptors.size();
|
||||
//noinspection LoopStatementThatDoesntLoop
|
||||
for (FunctionDescriptor descriptor : functionDescriptors) {
|
||||
return descriptor;
|
||||
}
|
||||
throw new AssertionError("In scope " + scope
|
||||
+ " supposed to be exactly one " + name + " function.");
|
||||
}
|
||||
|
||||
//TODO: some strange stuff happening to this method
|
||||
//TODO: inspect
|
||||
@NotNull
|
||||
public static PropertyDescriptor getPropertyByName(@NotNull JetScope scope,
|
||||
@NotNull Name name) {
|
||||
Collection<VariableDescriptor> variables = scope.getProperties(name);
|
||||
assert variables.size() == 1 : "Actual size: " + variables.size();
|
||||
VariableDescriptor variable = variables.iterator().next();
|
||||
PropertyDescriptor descriptor = (PropertyDescriptor)variable;
|
||||
assert descriptor != null : "Must have a descriptor.";
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
for (ClassDescriptor descriptor : superclassDescriptors) {
|
||||
@@ -103,9 +73,31 @@ public final class JsDescriptorUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
|
||||
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
|
||||
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
|
||||
for (JetType type : superclassTypes) {
|
||||
ClassDescriptor result = getClassDescriptorForType(type);
|
||||
if (isNotAny(result)) {
|
||||
superClassDescriptors.add(result);
|
||||
}
|
||||
}
|
||||
return superClassDescriptors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClassDescriptor getSuperclass(@NotNull ClassDescriptor classDescriptor) {
|
||||
return findAncestorClass(DescriptorUtils.getSuperclassDescriptors(classDescriptor));
|
||||
return findAncestorClass(getSuperclassDescriptors(classDescriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
|
||||
DeclarationDescriptor superClassDescriptor =
|
||||
type.getConstructor().getDeclarationDescriptor();
|
||||
assert superClassDescriptor instanceof ClassDescriptor
|
||||
: "Superclass descriptor of a type should be of type ClassDescriptor";
|
||||
return (ClassDescriptor) superClassDescriptor;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,9 +124,9 @@ public final class JsDescriptorUtils {
|
||||
|
||||
@NotNull
|
||||
public static DeclarationDescriptor getDeclarationDescriptorForReceiver
|
||||
(@NotNull ReceiverDescriptor receiverParameter) {
|
||||
(@NotNull ReceiverDescriptor receiverParameter) {
|
||||
DeclarationDescriptor declarationDescriptor =
|
||||
receiverParameter.getType().getConstructor().getDeclarationDescriptor();
|
||||
receiverParameter.getType().getConstructor().getDeclarationDescriptor();
|
||||
//TODO: WHY assert?
|
||||
assert declarationDescriptor != null;
|
||||
return declarationDescriptor.getOriginal();
|
||||
@@ -155,13 +147,26 @@ public final class JsDescriptorUtils {
|
||||
DeclarationDescriptor containing = descriptor.getContainingDeclaration();
|
||||
while (containing != null) {
|
||||
if (containing instanceof ClassDescriptor && !isClassObject(containing)) {
|
||||
return (ClassDescriptor)containing;
|
||||
return (ClassDescriptor) containing;
|
||||
}
|
||||
containing = containing.getContainingDeclaration();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static NamespaceDescriptor getContainingNamespace(@NotNull DeclarationDescriptor descriptor) {
|
||||
return DescriptorUtils.getParentOfType(descriptor, NamespaceDescriptor.class);
|
||||
}
|
||||
|
||||
public static boolean isStandardDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||
NamespaceDescriptor namespace = getContainingNamespace(descriptor);
|
||||
if (namespace == null) {
|
||||
return false;
|
||||
}
|
||||
return namespace.equals(JetStandardLibrary.getInstance().getLibraryScope().getContainingDeclaration());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor,
|
||||
@NotNull BindingContext context) {
|
||||
@@ -232,7 +237,7 @@ public final class JsDescriptorUtils {
|
||||
while (!(current.getContainingDeclaration() instanceof ModuleDescriptor)) {
|
||||
result.add(current);
|
||||
if (current.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||
current = (NamespaceDescriptor)current.getContainingDeclaration();
|
||||
current = (NamespaceDescriptor) current.getContainingDeclaration();
|
||||
assert current != null;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -26,10 +26,8 @@ import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.dart.compiler.util.AstUtil.newAssignment;
|
||||
@@ -205,13 +203,12 @@ public final class TranslationUtils {
|
||||
return Translation.translateAsExpression(rightExpression, context);
|
||||
}
|
||||
|
||||
public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
|
||||
public static boolean hasCorrespondingFunctionIntrinsic(@NotNull TranslationContext context,
|
||||
@NotNull JetOperationExpression expression) {
|
||||
FunctionDescriptor operationDescriptor =
|
||||
BindingUtils.getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
FunctionDescriptor operationDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||
|
||||
if (operationDescriptor == null) return true;
|
||||
if (context.intrinsics().isIntrinsic(operationDescriptor)) return true;
|
||||
if (context.intrinsics().getFunctionIntrinsics().getIntrinsic(operationDescriptor).exists()) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -232,15 +229,6 @@ public final class TranslationUtils {
|
||||
return context.program().getNumberLiteral(0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression applyIntrinsicToBinaryExpression(@NotNull TranslationContext context,
|
||||
@NotNull FunctionIntrinsic intrinsic,
|
||||
@NotNull JetBinaryExpression binaryExpression) {
|
||||
JsExpression left = translateLeftExpression(context, binaryExpression);
|
||||
JsExpression right = translateRightExpression(context, binaryExpression);
|
||||
return intrinsic.apply(left, Arrays.asList(right), context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JsExpression resolveThisObjectForResolvedCall(@NotNull ResolvedCall<?> call,
|
||||
@NotNull TranslationContext context) {
|
||||
|
||||
Reference in New Issue
Block a user