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.PLUSEQ, JetTokens.PLUS)
|
||||||
.put(JetTokens.MINUSEQ, JetTokens.MINUS)
|
.put(JetTokens.MINUSEQ, JetTokens.MINUS)
|
||||||
.build();
|
.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
|
@Nullable
|
||||||
public static Name getNameForOperationSymbol(@NotNull JetToken token) {
|
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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
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.config.EcmaVersion;
|
||||||
import org.jetbrains.k2js.translate.context.generator.Generator;
|
import org.jetbrains.k2js.translate.context.generator.Generator;
|
||||||
import org.jetbrains.k2js.translate.context.generator.Rule;
|
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 final class StaticContext {
|
||||||
|
|
||||||
public static StaticContext generateStaticContext(@NotNull JetStandardLibrary library,
|
public static StaticContext generateStaticContext(@NotNull BindingContext bindingContext, @NotNull EcmaVersion ecmaVersion) {
|
||||||
@NotNull BindingContext bindingContext,
|
|
||||||
@NotNull EcmaVersion ecmaVersion) {
|
|
||||||
JsProgram program = new JsProgram("main");
|
JsProgram program = new JsProgram("main");
|
||||||
JsRootScope jsRootScope = program.getRootScope();
|
JsRootScope jsRootScope = program.getRootScope();
|
||||||
Namer namer = Namer.newInstance(jsRootScope);
|
Namer namer = Namer.newInstance(jsRootScope);
|
||||||
NamingScope scope = NamingScope.rootScope(jsRootScope);
|
NamingScope scope = NamingScope.rootScope(jsRootScope);
|
||||||
Intrinsics intrinsics = Intrinsics.standardLibraryIntrinsics(library);
|
Intrinsics intrinsics = new Intrinsics();
|
||||||
StandardClasses standardClasses = StandardClasses.bindImplementations(namer.getKotlinScope());
|
StandardClasses standardClasses = StandardClasses.bindImplementations(namer.getKotlinScope());
|
||||||
return new StaticContext(program, bindingContext, namer, intrinsics, standardClasses, scope, ecmaVersion);
|
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.TemporaryVariable;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
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 org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -44,12 +44,12 @@ public final class ArrayForTranslator extends ForTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsStatement doTranslate(@NotNull JetForExpression expression,
|
public static JsStatement doTranslate(@NotNull JetForExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new ArrayForTranslator(expression, context).translate());
|
return (new ArrayForTranslator(expression, context).translate());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isApplicable(@NotNull JetForExpression expression,
|
public static boolean isApplicable(@NotNull JetForExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
JetExpression loopRange = getLoopRange(expression);
|
JetExpression loopRange = getLoopRange(expression);
|
||||||
JetType rangeType = BindingUtils.getTypeForExpression(context.bindingContext(), loopRange);
|
JetType rangeType = BindingUtils.getTypeForExpression(context.bindingContext(), loopRange);
|
||||||
//TODO: better check
|
//TODO: better check
|
||||||
@@ -70,10 +70,10 @@ public final class ArrayForTranslator extends ForTranslator {
|
|||||||
private ArrayForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
private ArrayForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||||
super(forExpression, context);
|
super(forExpression, context);
|
||||||
loopRange = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
loopRange = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
||||||
FunctionIntrinsic lengthPropertyIntrinsic = context().intrinsics().getLengthPropertyIntrinsic();
|
|
||||||
JsExpression length = lengthPropertyIntrinsic.apply(loopRange.reference(),
|
JsExpression length = ArrayFIF.ARRAY_LENGTH_INTRINSIC.apply(loopRange.reference(),
|
||||||
Collections.<JsExpression>emptyList(),
|
Collections.<JsExpression>emptyList(),
|
||||||
context());
|
context());
|
||||||
end = context().declareTemporary(length);
|
end = context().declareTemporary(length);
|
||||||
index = context().declareTemporary(program().getNumberLiteral(0));
|
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.descriptors.NamespaceDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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.config.Config;
|
||||||
import org.jetbrains.k2js.facade.MainCallParameters;
|
import org.jetbrains.k2js.facade.MainCallParameters;
|
||||||
import org.jetbrains.k2js.facade.exceptions.MainFunctionNotFoundException;
|
import org.jetbrains.k2js.facade.exceptions.MainFunctionNotFoundException;
|
||||||
@@ -167,8 +166,7 @@ public final class Translation {
|
|||||||
@NotNull MainCallParameters mainCallParameters,
|
@NotNull MainCallParameters mainCallParameters,
|
||||||
@NotNull Config config) throws MainFunctionNotFoundException {
|
@NotNull Config config) throws MainFunctionNotFoundException {
|
||||||
//TODO: move some of the code somewhere
|
//TODO: move some of the code somewhere
|
||||||
JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance();
|
StaticContext staticContext = StaticContext.generateStaticContext(bindingContext, config.getTarget());
|
||||||
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext, config.getTarget());
|
|
||||||
JsProgram program = staticContext.getProgram();
|
JsProgram program = staticContext.getProgram();
|
||||||
JsBlock block = program.getGlobalBlock();
|
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;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.k2js.translate.intrinsic.functions.FunctionIntrinsics;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.k2js.translate.intrinsic.operation.BinaryOperationIntrinsics;
|
||||||
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.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
@@ -55,249 +28,18 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getPropertyBy
|
|||||||
public final class Intrinsics {
|
public final class Intrinsics {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<FunctionDescriptor, FunctionIntrinsic> functionIntrinsics =
|
private final FunctionIntrinsics functionIntrinsics = new FunctionIntrinsics();
|
||||||
new HashMap<FunctionDescriptor, FunctionIntrinsic>();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<FunctionDescriptor, EqualsIntrinsic> equalsIntrinsics =
|
public BinaryOperationIntrinsics getBinaryOperationIntrinsics() {
|
||||||
new HashMap<FunctionDescriptor, EqualsIntrinsic>();
|
return binaryOperationIntrinsics;
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JetStandardLibrary library;
|
private final BinaryOperationIntrinsics binaryOperationIntrinsics = new BinaryOperationIntrinsics();
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public FunctionIntrinsic getLengthPropertyIntrinsic() {
|
public FunctionIntrinsics getFunctionIntrinsics() {
|
||||||
return lengthPropertyIntrinsic;
|
return functionIntrinsics;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-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.
|
* 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.JsExpression;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
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
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
public final class BuiltInFunctionIntrinsic implements FunctionIntrinsic {
|
public final class BuiltInFunctionIntrinsic extends FunctionIntrinsic {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final String functionName;
|
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.JsExpression;
|
||||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
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
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
//TODO: find should be usages
|
//TODO: find should be usages
|
||||||
public final class BuiltInPropertyIntrinsic implements FunctionIntrinsic {
|
public final class BuiltInPropertyIntrinsic extends FunctionIntrinsic {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final String propertyName;
|
private final String propertyName;
|
||||||
+4
-4
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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.common.collect.Lists;
|
||||||
import com.google.dart.compiler.Source;
|
import com.google.dart.compiler.Source;
|
||||||
@@ -33,7 +33,7 @@ import static org.jetbrains.k2js.translate.utils.JsAstUtils.newInvocation;
|
|||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
public final class CallStandardMethodIntrinsic implements FunctionIntrinsic {
|
public final class CallStandardMethodIntrinsic extends FunctionIntrinsic {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final String methodName;
|
private final String methodName;
|
||||||
@@ -50,8 +50,8 @@ public final class CallStandardMethodIntrinsic implements FunctionIntrinsic {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JsExpression apply(@Nullable JsExpression receiver,
|
public JsExpression apply(@Nullable JsExpression receiver,
|
||||||
@NotNull List<JsExpression> arguments,
|
@NotNull List<JsExpression> arguments,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
assert (receiver != null == receiverShouldBeNotNull);
|
assert (receiver != null == receiverShouldBeNotNull);
|
||||||
assert arguments.size() == expectedParamsNumber : "Incorrect number of arguments " + arguments.size() + " when expected " + expectedParamsNumber + " on method " + methodName + " " + atLocation(receiver, arguments);
|
assert arguments.size() == expectedParamsNumber : "Incorrect number of arguments " + arguments.size() + " when expected " + expectedParamsNumber + " on method " + methodName + " " + atLocation(receiver, arguments);
|
||||||
JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef(methodName);
|
JsNameRef iteratorFunName = AstUtil.newQualifiedNameRef(methodName);
|
||||||
+8
-4
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* 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.JsExpression;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -28,9 +28,13 @@ import java.util.List;
|
|||||||
* <p/>
|
* <p/>
|
||||||
* Base for intrinsics that substitute standard function calls like Int#plus, Float#minus ... etc
|
* Base for intrinsics that substitute standard function calls like Int#plus, Float#minus ... etc
|
||||||
*/
|
*/
|
||||||
public interface FunctionIntrinsic {
|
public abstract class FunctionIntrinsic {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
public abstract JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||||
@NotNull TranslationContext context);
|
@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.
|
* 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.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
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
public abstract class EqualsIntrinsic implements FunctionIntrinsic {
|
public interface FunctionIntrinsicFactory {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Boolean isNegated = false;
|
Pattern getPattern();
|
||||||
|
|
||||||
public void setNegated(boolean isNegated) {
|
@NotNull
|
||||||
this.isNegated = isNegated;
|
FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor);
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isNegated() {
|
|
||||||
return isNegated;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+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.
|
* 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.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
@@ -22,10 +22,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
public abstract class FunctionIntrinsicFactory {
|
public interface Pattern {
|
||||||
|
|
||||||
public abstract boolean isApplicable(@NotNull FunctionDescriptor descriptor);
|
boolean apply(@NotNull FunctionDescriptor descriptor);
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public abstract FunctionIntrinsic createIntrinsic(@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.
|
* 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 com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
import org.jetbrains.annotations.NotNull;
|
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.context.TranslationContext;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
public enum ReturnReceiverIntrinsic implements FunctionIntrinsic {
|
public interface BinaryOperationIntrinsic {
|
||||||
|
|
||||||
INSTANCE;
|
boolean isApplicable(@NotNull JetBinaryExpression expression, @NotNull TranslationContext context);
|
||||||
|
|
||||||
@NotNull
|
JsExpression apply(@NotNull JetBinaryExpression expression, @NotNull JsExpression left,
|
||||||
@Override
|
@NotNull JsExpression right, @NotNull TranslationContext context);
|
||||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
|
||||||
@NotNull TranslationContext context) {
|
|
||||||
assert receiver != null;
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+22
-16
@@ -14,33 +14,39 @@
|
|||||||
* limitations under the License.
|
* 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 closurecompiler.internal.com.google.common.collect.Lists;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
public final class TupleAccessIntrinsic implements FunctionIntrinsic {
|
public final class BinaryOperationIntrinsics {
|
||||||
|
|
||||||
private final int elementIndex;
|
|
||||||
|
|
||||||
public TupleAccessIntrinsic(int elementIndex) {
|
|
||||||
this.elementIndex = elementIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
private final List<BinaryOperationIntrinsic> intrinsics = Lists.newArrayList();
|
||||||
public JsExpression apply(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
|
||||||
@NotNull TranslationContext context) {
|
{
|
||||||
assert arguments.isEmpty() : "Tuple access expression should not have any arguments.";
|
intrinsics.add(new EqualsIntrinsic());
|
||||||
return AstUtil.newArrayAccess(receiver, context.program().getNumberLiteral(elementIndex));
|
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.BindingUtils.isVariableReassignment;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
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.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;
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +46,7 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
if (isIntrinsicOperation(context, expression)) {
|
if (hasCorrespondingFunctionIntrinsic(context, expression)) {
|
||||||
return IntrinsicAssignmentTranslator.doTranslate(expression, context);
|
return IntrinsicAssignmentTranslator.doTranslate(expression, context);
|
||||||
}
|
}
|
||||||
return OverloadedAssignmentTranslator.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.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
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.CallBuilder;
|
||||||
import org.jetbrains.k2js.translate.reference.CallType;
|
import org.jetbrains.k2js.translate.reference.CallType;
|
||||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
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.getFunctionDescriptorForOperationExpression;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
|
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.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.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
|
@NotNull
|
||||||
private JsExpression translate() {
|
private JsExpression translate() {
|
||||||
|
BinaryOperationIntrinsic intrinsic = getIntrinsicForExpression();
|
||||||
|
if (intrinsic != null) {
|
||||||
|
return applyIntrinsic(intrinsic);
|
||||||
|
}
|
||||||
if (isElvisOperator(expression)) {
|
if (isElvisOperator(expression)) {
|
||||||
return translateAsElvisOperator(expression);
|
return translateAsElvisOperator(expression);
|
||||||
}
|
}
|
||||||
@@ -92,12 +96,22 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
assert operationDescriptor != null :
|
assert operationDescriptor != null :
|
||||||
"Overloadable operations must have not null descriptor";
|
"Overloadable operations must have not null descriptor";
|
||||||
if (isEquals(operationDescriptor) && context().intrinsics().isIntrinsic(operationDescriptor)) {
|
|
||||||
return translateAsEqualsIntrinsic();
|
|
||||||
}
|
|
||||||
return translateAsOverloadedBinaryOperation();
|
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) {
|
private static boolean isElvisOperator(@NotNull JetBinaryExpression expression) {
|
||||||
return getOperationToken(expression).equals(JetTokens.ELVIS);
|
return getOperationToken(expression).equals(JetTokens.ELVIS);
|
||||||
}
|
}
|
||||||
@@ -115,14 +129,6 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
|
|||||||
return operationDescriptor == null;
|
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
|
@NotNull
|
||||||
private JsExpression translateAsUnOverloadableBinaryOperation() {
|
private JsExpression translateAsUnOverloadableBinaryOperation() {
|
||||||
JetToken token = getOperationToken(expression);
|
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.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
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.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
|
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
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.JsDescriptorUtils.isCompareTo;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
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
|
* @author Pavel Talanov
|
||||||
@@ -41,7 +37,7 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOpe
|
|||||||
public final class CompareToTranslator extends AbstractTranslator {
|
public final class CompareToTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
public static boolean isCompareToCall(@NotNull JetBinaryExpression expression,
|
public static boolean isCompareToCall(@NotNull JetBinaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
FunctionDescriptor operationDescriptor =
|
FunctionDescriptor operationDescriptor =
|
||||||
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||||
|
|
||||||
@@ -52,47 +48,27 @@ public final class CompareToTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
return (new CompareToTranslator(expression, context)).translate();
|
return (new CompareToTranslator(expression, context)).translate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JetBinaryExpression expression;
|
private final JetBinaryExpression expression;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final FunctionDescriptor descriptor;
|
|
||||||
|
|
||||||
private CompareToTranslator(@NotNull JetBinaryExpression expression,
|
private CompareToTranslator(@NotNull JetBinaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
FunctionDescriptor functionDescriptor =
|
FunctionDescriptor functionDescriptor =
|
||||||
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||||
assert functionDescriptor != null : "CompareTo should always have a descriptor";
|
assert functionDescriptor != null : "CompareTo should always have a descriptor";
|
||||||
this.descriptor = functionDescriptor;
|
|
||||||
assert (OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression)));
|
assert (OperatorConventions.COMPARISON_OPERATIONS.contains(getOperationToken(expression)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression translate() {
|
private JsExpression translate() {
|
||||||
if (isIntrinsicOperation(context(), expression)) {
|
|
||||||
return intrinsicCompareTo();
|
|
||||||
}
|
|
||||||
return overloadedCompareTo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsExpression overloadedCompareTo() {
|
|
||||||
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(getOperationToken(expression));
|
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(getOperationToken(expression));
|
||||||
JsExpression methodCall = BinaryOperationTranslator.translateAsOverloadedCall(expression, context());
|
JsExpression methodCall = BinaryOperationTranslator.translateAsOverloadedCall(expression, context());
|
||||||
return new JsBinaryOperation(correspondingOperator, methodCall, TranslationUtils.zeroLiteral(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.JsAstUtils.newSequence;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
|
||||||
import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization;
|
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
|
* @author Pavel Talanov
|
||||||
@@ -49,7 +49,7 @@ public abstract class IncrementTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public static JsExpression translate(@NotNull JetUnaryExpression expression,
|
public static JsExpression translate(@NotNull JetUnaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
if (isIntrinsicOperation(context, expression)) {
|
if (hasCorrespondingFunctionIntrinsic(context, expression)) {
|
||||||
return IntrinsicIncrementTranslator.doTranslate(expression, context);
|
return IntrinsicIncrementTranslator.doTranslate(expression, context);
|
||||||
}
|
}
|
||||||
return (new OverloadedIncrementTranslator(expression, context)).translateIncrementExpression();
|
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.jet.lang.resolve.calls.VariableAsFunctionResolvedCall;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
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.AnnotationsUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.ErrorReportingUtils;
|
import org.jetbrains.k2js.translate.utils.ErrorReportingUtils;
|
||||||
|
|
||||||
@@ -119,14 +119,19 @@ public final class CallTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isIntrinsic() {
|
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
|
@NotNull
|
||||||
private JsExpression intrinsicInvocation() {
|
private JsExpression intrinsicInvocation() {
|
||||||
assert descriptor instanceof FunctionDescriptor;
|
assert descriptor instanceof FunctionDescriptor;
|
||||||
try {
|
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());
|
return intrinsic.apply(callParameters.getThisOrReceiverOrNull(), arguments, context());
|
||||||
}
|
}
|
||||||
catch (RuntimeException e) {
|
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.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
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.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.expressions.OperatorConventions;
|
||||||
|
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||||
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
import org.jetbrains.k2js.config.LibrarySourcesConfig;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.isNotAny;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
@@ -53,10 +55,6 @@ public final class JsDescriptorUtils {
|
|||||||
return (valueParametersCount(functionDescriptor) > 0);
|
return (valueParametersCount(functionDescriptor) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isEquals(@NotNull FunctionDescriptor functionDescriptor) {
|
|
||||||
return (functionDescriptor.getName().equals(OperatorConventions.EQUALS));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isCompareTo(@NotNull FunctionDescriptor functionDescriptor) {
|
public static boolean isCompareTo(@NotNull FunctionDescriptor functionDescriptor) {
|
||||||
return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO));
|
return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO));
|
||||||
}
|
}
|
||||||
@@ -65,34 +63,6 @@ public final class JsDescriptorUtils {
|
|||||||
return (descriptor instanceof ConstructorDescriptor);
|
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
|
@Nullable
|
||||||
public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||||
for (ClassDescriptor descriptor : superclassDescriptors) {
|
for (ClassDescriptor descriptor : superclassDescriptors) {
|
||||||
@@ -103,9 +73,31 @@ public final class JsDescriptorUtils {
|
|||||||
return null;
|
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
|
@Nullable
|
||||||
public static ClassDescriptor getSuperclass(@NotNull ClassDescriptor classDescriptor) {
|
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
|
@NotNull
|
||||||
public static DeclarationDescriptor getDeclarationDescriptorForReceiver
|
public static DeclarationDescriptor getDeclarationDescriptorForReceiver
|
||||||
(@NotNull ReceiverDescriptor receiverParameter) {
|
(@NotNull ReceiverDescriptor receiverParameter) {
|
||||||
DeclarationDescriptor declarationDescriptor =
|
DeclarationDescriptor declarationDescriptor =
|
||||||
receiverParameter.getType().getConstructor().getDeclarationDescriptor();
|
receiverParameter.getType().getConstructor().getDeclarationDescriptor();
|
||||||
//TODO: WHY assert?
|
//TODO: WHY assert?
|
||||||
assert declarationDescriptor != null;
|
assert declarationDescriptor != null;
|
||||||
return declarationDescriptor.getOriginal();
|
return declarationDescriptor.getOriginal();
|
||||||
@@ -155,13 +147,26 @@ public final class JsDescriptorUtils {
|
|||||||
DeclarationDescriptor containing = descriptor.getContainingDeclaration();
|
DeclarationDescriptor containing = descriptor.getContainingDeclaration();
|
||||||
while (containing != null) {
|
while (containing != null) {
|
||||||
if (containing instanceof ClassDescriptor && !isClassObject(containing)) {
|
if (containing instanceof ClassDescriptor && !isClassObject(containing)) {
|
||||||
return (ClassDescriptor)containing;
|
return (ClassDescriptor) containing;
|
||||||
}
|
}
|
||||||
containing = containing.getContainingDeclaration();
|
containing = containing.getContainingDeclaration();
|
||||||
}
|
}
|
||||||
return null;
|
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
|
@NotNull
|
||||||
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor,
|
public static List<NamespaceDescriptor> getNestedNamespaces(@NotNull NamespaceDescriptor namespaceDescriptor,
|
||||||
@NotNull BindingContext context) {
|
@NotNull BindingContext context) {
|
||||||
@@ -232,7 +237,7 @@ public final class JsDescriptorUtils {
|
|||||||
while (!(current.getContainingDeclaration() instanceof ModuleDescriptor)) {
|
while (!(current.getContainingDeclaration() instanceof ModuleDescriptor)) {
|
||||||
result.add(current);
|
result.add(current);
|
||||||
if (current.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
if (current.getContainingDeclaration() instanceof NamespaceDescriptor) {
|
||||||
current = (NamespaceDescriptor)current.getContainingDeclaration();
|
current = (NamespaceDescriptor) current.getContainingDeclaration();
|
||||||
assert current != null;
|
assert current != null;
|
||||||
}
|
}
|
||||||
else {
|
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.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.dart.compiler.util.AstUtil.newAssignment;
|
import static com.google.dart.compiler.util.AstUtil.newAssignment;
|
||||||
@@ -205,13 +203,12 @@ public final class TranslationUtils {
|
|||||||
return Translation.translateAsExpression(rightExpression, context);
|
return Translation.translateAsExpression(rightExpression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
|
public static boolean hasCorrespondingFunctionIntrinsic(@NotNull TranslationContext context,
|
||||||
@NotNull JetOperationExpression expression) {
|
@NotNull JetOperationExpression expression) {
|
||||||
FunctionDescriptor operationDescriptor =
|
FunctionDescriptor operationDescriptor = getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
||||||
BindingUtils.getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
|
|
||||||
|
|
||||||
if (operationDescriptor == null) return true;
|
if (operationDescriptor == null) return true;
|
||||||
if (context.intrinsics().isIntrinsic(operationDescriptor)) return true;
|
if (context.intrinsics().getFunctionIntrinsics().getIntrinsic(operationDescriptor).exists()) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -232,15 +229,6 @@ public final class TranslationUtils {
|
|||||||
return context.program().getNumberLiteral(0);
|
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
|
@Nullable
|
||||||
public static JsExpression resolveThisObjectForResolvedCall(@NotNull ResolvedCall<?> call,
|
public static JsExpression resolveThisObjectForResolvedCall(@NotNull ResolvedCall<?> call,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
|
|||||||
Reference in New Issue
Block a user