diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000000..51c200ebf0d
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000000..3b312839bf2
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 905da820aa1..ccb5ce74db4 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,12 +5,36 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
@@ -108,7 +132,7 @@
-
+
@@ -121,20 +145,20 @@
-
+
-
+
-
-
+
+
-
+
@@ -204,76 +228,49 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -282,10 +279,17 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -299,23 +303,19 @@
-
-
-
-
-
-
+
+
-
+
-
-
+
+
-
+
@@ -323,46 +323,14 @@
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -371,25 +339,81 @@
-
+
-
-
+
+
-
+
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -416,22 +440,22 @@
@@ -521,6 +545,7 @@
+
@@ -535,7 +560,6 @@
-
@@ -582,7 +606,11 @@
-
+
+
+
+
+
@@ -600,7 +628,7 @@
-
+
@@ -636,139 +664,11 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -789,6 +689,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -883,13 +813,6 @@
-
-
-
-
-
-
-
@@ -1013,6 +936,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1128,17 +1086,23 @@
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
localhost
@@ -1196,6 +1160,7 @@
+
@@ -1206,14 +1171,14 @@
-
+
-
-
+
+
@@ -1256,7 +1221,7 @@
-
+
@@ -1269,7 +1234,6 @@
-
@@ -1294,6 +1258,7 @@
+
@@ -1303,120 +1268,122 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java b/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java
index 57e44a94e03..2b1077291a4 100644
--- a/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java
+++ b/translator/src/org/jetbrains/k2js/translate/context/Aliaser.java
@@ -5,18 +5,24 @@ import com.google.dart.compiler.backend.js.ast.JsNameRef;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
+import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import java.util.HashMap;
import java.util.Map;
+import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getFunctionByName;
+
//TODO: implement aliases stack for this
public class Aliaser {
static public Aliaser aliasesForStandardClasses(@NotNull JetStandardLibrary standardLibrary,
@NotNull Namer namer) {
- //TODO: decide if this aliases are needed
- return new Aliaser();
+ Aliaser aliaser = new Aliaser();
+ aliaser.setAliasForDescriptor(standardLibrary.getArray(), namer.libraryObject("Array"));
+ FunctionDescriptor nullConstructorFunction = getFunctionByName(standardLibrary.getLibraryScope(), "Array");
+ aliaser.setAliasForDescriptor(nullConstructorFunction, namer.libraryObject("array"));
+ return aliaser;
}
@NotNull
@@ -46,23 +52,23 @@ public class Aliaser {
}
public boolean hasAliasForDeclaration(@NotNull DeclarationDescriptor declaration) {
- return aliases.containsKey(declaration);
+ return aliases.containsKey(declaration.getOriginal());
}
@NotNull
public JsNameRef getAliasForDeclaration(@NotNull DeclarationDescriptor declaration) {
- JsName alias = aliases.get(declaration);
+ JsName alias = aliases.get(declaration.getOriginal());
assert alias != null : "Use has alias for declaration to check.";
return alias.makeRef();
}
public void setAliasForDescriptor(@NotNull DeclarationDescriptor declaration, @NotNull JsName alias) {
- assert (!hasAliasForDeclaration(declaration)) : "This declaration already has an alias!";
- aliases.put(declaration, alias);
+ assert (!hasAliasForDeclaration(declaration.getOriginal())) : "This declaration already has an alias!";
+ aliases.put(declaration.getOriginal(), alias);
}
public void removeAliasForDescriptor(@NotNull DeclarationDescriptor declaration) {
- assert (hasAliasForDeclaration(declaration)) : "This declaration does not has an alias!";
- aliases.remove(declaration);
+ assert (hasAliasForDeclaration(declaration.getOriginal())) : "This declaration does not has an alias!";
+ aliases.remove(declaration.getOriginal());
}
}
\ No newline at end of file
diff --git a/translator/src/org/jetbrains/k2js/translate/context/Namer.java b/translator/src/org/jetbrains/k2js/translate/context/Namer.java
index b93886d59c0..dcb1640d57d 100644
--- a/translator/src/org/jetbrains/k2js/translate/context/Namer.java
+++ b/translator/src/org/jetbrains/k2js/translate/context/Namer.java
@@ -124,6 +124,11 @@ public final class Namer {
return reference;
}
+ @NotNull
+ public JsName libraryObject(@NotNull String name) {
+ return kotlinScope.declareName(name);
+ }
+
@NotNull
public JsNameRef kotlinObject() {
return kotlinName.makeRef();
diff --git a/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java
index 2d1c6110a11..67c93fbf683 100644
--- a/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter;
+import static org.jetbrains.k2js.translate.utils.DescriptorUtils.findAncestorClass;
/**
* @author Talanov Pavel
@@ -108,7 +109,7 @@ public final class ClassTranslator extends AbstractTranslator {
@Nullable
private ClassDescriptor findAndRemoveAncestorClass(@NotNull List superclassDescriptors) {
- ClassDescriptor ancestorClass = BindingUtils.findAncestorClass(superclassDescriptors);
+ ClassDescriptor ancestorClass = findAncestorClass(superclassDescriptors);
superclassDescriptors.remove(ancestorClass);
return ancestorClass;
}
diff --git a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
index bd369bc33ce..020d0135f43 100644
--- a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
+++ b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java
@@ -238,6 +238,9 @@ public final class ExpressionVisitor extends TranslatorVisitor {
@NotNull
public JsNode visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression,
@NotNull TranslationContext context) {
+ if (expression.getSelectorExpression() instanceof JetCallExpression) {
+ return CallTranslator.translate(expression, context);
+ }
return translateQualifiedExpression(expression, context);
}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java
index 9380edbd67b..a1658dbee7f 100644
--- a/translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/FunctionIntrinsic.java
@@ -3,6 +3,6 @@ package org.jetbrains.k2js.translate.intrinsic;
/**
* @author Talanov Pavel
*/
-public abstract class FunctionIntrinsic implements Intrinsic {
+public interface FunctionIntrinsic extends Intrinsic {
}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java
index 08195efa500..03ba6e48517 100644
--- a/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/IntrinsicDeclarationVisitor.java
@@ -31,7 +31,7 @@ public final class IntrinsicDeclarationVisitor extends DeclarationDescriptorVisi
@Override
public Void visitFunctionDescriptor(@NotNull FunctionDescriptor descriptor, @Nullable Void nothing) {
if (!intrinsics.isIntrinsic(descriptor)) {
- intrinsics.declareIntrinsic(descriptor);
+ intrinsics.declareOperatorIntrinsic(descriptor);
}
return null;
}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java
index 1e003035f5a..049b8659619 100644
--- a/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/Intrinsics.java
@@ -6,16 +6,24 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken;
+import org.jetbrains.k2js.translate.intrinsic.array.ArrayGetIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.array.ArrayNullConstructorIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.array.ArraySetIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.primitive.PrimitiveBinaryOperationIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.primitive.PrimitiveCompareToIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.primitive.PrimitiveEqualsIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.primitive.PrimitiveUnaryOperationIntrinsic;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
import java.util.HashMap;
import java.util.Map;
+import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getFunctionByName;
+
/**
* @author Talanov Pavel
*/
-//TODO: different maps for different kinds of intrinsics
public final class Intrinsics {
@NotNull
@@ -26,7 +34,6 @@ public final class Intrinsics {
private final Map equalsIntrinsics =
new HashMap();
-
@NotNull
private final Map compareToIntrinsics =
new HashMap();
@@ -35,14 +42,35 @@ public final class Intrinsics {
return new Intrinsics(library);
}
+ @NotNull
+ private final JetStandardLibrary library;
+
private Intrinsics(@NotNull JetStandardLibrary library) {
+ this.library = library;
+ declareOperatorIntrinsics();
+ //TODO: array intrinsic are under consideration
+ //declareArrayIntrinsics();
+ }
+
+ private void declareOperatorIntrinsics() {
IntrinsicDeclarationVisitor visitor = new IntrinsicDeclarationVisitor(this);
for (DeclarationDescriptor descriptor : library.getLibraryScope().getAllDescriptors()) {
descriptor.accept(visitor, null);
}
}
- /*package*/ void declareIntrinsic(@NotNull FunctionDescriptor descriptor) {
+ private void declareArrayIntrinsics() {
+ FunctionDescriptor constructorFunction = getFunctionByName(library.getLibraryScope(), "Array");
+ functionIntrinsics.put(constructorFunction, ArrayNullConstructorIntrinsic.INSTANCE);
+
+ FunctionDescriptor getFunction = getFunctionByName(library.getArray(), "get");
+ functionIntrinsics.put(getFunction, ArrayGetIntrinsic.INSTANCE);
+
+ FunctionDescriptor setFunction = getFunctionByName(library.getArray(), "set");
+ functionIntrinsics.put(setFunction, ArraySetIntrinsic.INSTANCE);
+ }
+
+ /*package*/ void declareOperatorIntrinsic(@NotNull FunctionDescriptor descriptor) {
addCompareToIntrinsics(descriptor);
addEqualsIntrinsics(descriptor);
addUnaryIntrinsics(descriptor);
@@ -69,9 +97,10 @@ public final class Intrinsics {
if (token == null) return;
boolean isUnary = !DescriptorUtils.hasParameters(descriptor);
if (!isUnary) return;
- functionIntrinsics.put(descriptor, UnaryOperationIntrinsic.newInstance(token));
+ functionIntrinsics.put(descriptor, PrimitiveUnaryOperationIntrinsic.newInstance(token));
}
+ //TODO: refactor
private void addBinaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
String functionName = descriptor.getName();
boolean isUnary = !DescriptorUtils.hasParameters(descriptor);
@@ -80,7 +109,7 @@ public final class Intrinsics {
if (token == null) return;
//TODO: implement range and contains intrinsic
if (!OperatorTable.hasCorrespondingBinaryOperator(token)) return;
- functionIntrinsics.put(descriptor, BinaryOperationIntrinsic.newInstance(token));
+ functionIntrinsics.put(descriptor, PrimitiveBinaryOperationIntrinsic.newInstance(token));
}
public boolean isIntrinsic(@NotNull DeclarationDescriptor descriptor) {
@@ -96,16 +125,16 @@ public final class Intrinsics {
@NotNull
public FunctionIntrinsic getFunctionIntrinsic(@NotNull FunctionDescriptor descriptor) {
- return functionIntrinsics.get(descriptor);
+ return functionIntrinsics.get(descriptor.getOriginal());
}
@NotNull
public CompareToIntrinsic getCompareToIntrinsic(@NotNull FunctionDescriptor descriptor) {
- return compareToIntrinsics.get(descriptor);
+ return compareToIntrinsics.get(descriptor.getOriginal());
}
@NotNull
public EqualsIntrinsic getEqualsIntrinsic(@NotNull FunctionDescriptor descriptor) {
- return equalsIntrinsics.get(descriptor);
+ return equalsIntrinsics.get(descriptor.getOriginal());
}
}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayGetIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayGetIntrinsic.java
new file mode 100644
index 00000000000..488b0d6f3bc
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayGetIntrinsic.java
@@ -0,0 +1,31 @@
+package org.jetbrains.k2js.translate.intrinsic.array;
+
+import com.google.dart.compiler.backend.js.ast.JsConditional;
+import com.google.dart.compiler.backend.js.ast.JsExpression;
+import com.google.dart.compiler.util.AstUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.k2js.translate.context.TemporaryVariable;
+import org.jetbrains.k2js.translate.context.TranslationContext;
+import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+
+import java.util.List;
+
+/**
+ * @author Talanov Pavel
+ */
+public enum ArrayGetIntrinsic implements FunctionIntrinsic {
+
+ INSTANCE;
+
+ @NotNull
+ @Override
+ public JsExpression apply(@NotNull JsExpression receiver, @NotNull List arguments,
+ @NotNull TranslationContext context) {
+ assert arguments.size() == 1 : "Array get expression must have one argument.";
+ JsExpression indexExpression = arguments.get(0);
+ TemporaryVariable arrayExpression = context.declareTemporary(receiver);
+ JsConditional indexInBoundsCheck =
+ IntrinsicArrayUtils.indexInBoundsCheck(indexExpression, arrayExpression, context);
+ return AstUtil.newSequence(arrayExpression.assignmentExpression(), AstUtil.newArrayAccess(receiver, indexExpression));
+ }
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayNullConstructorIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayNullConstructorIntrinsic.java
new file mode 100644
index 00000000000..7a584a8af55
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArrayNullConstructorIntrinsic.java
@@ -0,0 +1,25 @@
+package org.jetbrains.k2js.translate.intrinsic.array;
+
+import com.google.dart.compiler.backend.js.ast.JsArrayLiteral;
+import com.google.dart.compiler.backend.js.ast.JsExpression;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.k2js.translate.context.TranslationContext;
+import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+
+import java.util.List;
+
+/**
+ * @author Talanov Pavel
+ */
+public enum ArrayNullConstructorIntrinsic implements FunctionIntrinsic {
+
+ INSTANCE;
+
+ //TODO: implement function passing to array constructor
+ @NotNull
+ @Override
+ public JsExpression apply(@NotNull JsExpression receiver, @NotNull List arguments,
+ @NotNull TranslationContext context) {
+ return new JsArrayLiteral();
+ }
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySetIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySetIntrinsic.java
new file mode 100644
index 00000000000..c4e20adfaa1
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/ArraySetIntrinsic.java
@@ -0,0 +1,29 @@
+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.k2js.translate.context.TranslationContext;
+import org.jetbrains.k2js.translate.intrinsic.FunctionIntrinsic;
+
+import java.util.List;
+
+/**
+ * @author Talanov Pavel
+ */
+public enum ArraySetIntrinsic implements FunctionIntrinsic {
+
+ INSTANCE;
+
+ @NotNull
+ @Override
+ public JsExpression apply(@NotNull JsExpression receiver, @NotNull List arguments,
+ @NotNull TranslationContext context) {
+ 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);
+ }
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/array/IntrinsicArrayUtils.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/IntrinsicArrayUtils.java
new file mode 100644
index 00000000000..de5b8bbb3ad
--- /dev/null
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/array/IntrinsicArrayUtils.java
@@ -0,0 +1,41 @@
+package org.jetbrains.k2js.translate.intrinsic.array;
+
+import com.google.dart.compiler.backend.js.ast.*;
+import com.google.dart.compiler.util.AstUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.k2js.translate.context.TemporaryVariable;
+import org.jetbrains.k2js.translate.context.TranslationContext;
+
+import static org.jetbrains.k2js.translate.utils.TranslationUtils.zeroLiteral;
+
+/**
+ * @author Talanov Pavel
+ */
+public final class IntrinsicArrayUtils {
+
+ private IntrinsicArrayUtils() {
+ }
+
+ @NotNull
+ public static JsConditional indexInBoundsCheck(@NotNull JsExpression indexExpression,
+ @NotNull TemporaryVariable arrayTemporary,
+ @NotNull TranslationContext context) {
+ JsExpression positiveOrZero = new JsBinaryOperation
+ (JsBinaryOperator.GTE, indexExpression, zeroLiteral(context));
+ JsNameRef lengthExpression = AstUtil.newQualifiedNameRef("length");
+ lengthExpression.setQualifier(arrayTemporary.nameReference());
+ JsExpression lessThanLength = new JsBinaryOperation
+ (JsBinaryOperator.LT, indexExpression, lengthExpression);
+ JsExpression indexInBounds = AstUtil.and(positiveOrZero, lessThanLength);
+ JsConditional indexCheck = new JsConditional();
+ indexCheck.setTestExpression(indexInBounds);
+ indexCheck.setElseExpression(throwOutOfBoundsException());
+ return indexCheck;
+ }
+
+ @NotNull
+ public static JsExpression throwOutOfBoundsException() {
+ //TODO: think about exception
+ return new JsThisRef();
+ }
+}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/BinaryOperationIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveBinaryOperationIntrinsic.java
similarity index 69%
rename from translator/src/org/jetbrains/k2js/translate/intrinsic/BinaryOperationIntrinsic.java
rename to translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveBinaryOperationIntrinsic.java
index 483acdd6d30..97e6265161f 100644
--- a/translator/src/org/jetbrains/k2js/translate/intrinsic/BinaryOperationIntrinsic.java
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveBinaryOperationIntrinsic.java
@@ -1,4 +1,4 @@
-package org.jetbrains.k2js.translate.intrinsic;
+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;
@@ -6,6 +6,7 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
import org.jetbrains.annotations.NotNull;
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;
@@ -13,18 +14,18 @@ import java.util.List;
/**
* @author Talanov Pavel
*/
-public class BinaryOperationIntrinsic extends FunctionIntrinsic {
+public final class PrimitiveBinaryOperationIntrinsic implements FunctionIntrinsic {
@NotNull
- /*package*/ static BinaryOperationIntrinsic newInstance(@NotNull JetToken token) {
+ public static PrimitiveBinaryOperationIntrinsic newInstance(@NotNull JetToken token) {
JsBinaryOperator operator = OperatorTable.getBinaryOperator(token);
- return new BinaryOperationIntrinsic(operator);
+ return new PrimitiveBinaryOperationIntrinsic(operator);
}
@NotNull
private final JsBinaryOperator operator;
- private BinaryOperationIntrinsic(@NotNull JsBinaryOperator operator) {
+ private PrimitiveBinaryOperationIntrinsic(@NotNull JsBinaryOperator operator) {
this.operator = operator;
}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/PrimitiveCompareToIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveCompareToIntrinsic.java
similarity index 84%
rename from translator/src/org/jetbrains/k2js/translate/intrinsic/PrimitiveCompareToIntrinsic.java
rename to translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveCompareToIntrinsic.java
index d4590486e56..0233c3bcf50 100644
--- a/translator/src/org/jetbrains/k2js/translate/intrinsic/PrimitiveCompareToIntrinsic.java
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveCompareToIntrinsic.java
@@ -1,10 +1,11 @@
-package org.jetbrains.k2js.translate.intrinsic;
+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.k2js.translate.context.TranslationContext;
+import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
import org.jetbrains.k2js.translate.operation.OperatorTable;
import java.util.List;
@@ -15,7 +16,7 @@ import java.util.List;
public final class PrimitiveCompareToIntrinsic extends CompareToIntrinsic {
@NotNull
- /*package*/ static PrimitiveCompareToIntrinsic newInstance() {
+ public static PrimitiveCompareToIntrinsic newInstance() {
return new PrimitiveCompareToIntrinsic();
}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/PrimitiveEqualsIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveEqualsIntrinsic.java
similarity index 82%
rename from translator/src/org/jetbrains/k2js/translate/intrinsic/PrimitiveEqualsIntrinsic.java
rename to translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveEqualsIntrinsic.java
index af550f8bce4..f49c74cfa48 100644
--- a/translator/src/org/jetbrains/k2js/translate/intrinsic/PrimitiveEqualsIntrinsic.java
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveEqualsIntrinsic.java
@@ -1,9 +1,10 @@
-package org.jetbrains.k2js.translate.intrinsic;
+package org.jetbrains.k2js.translate.intrinsic.primitive;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.k2js.translate.context.TranslationContext;
+import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
import java.util.List;
@@ -13,7 +14,7 @@ import java.util.List;
public final class PrimitiveEqualsIntrinsic extends EqualsIntrinsic {
@NotNull
- /*package*/ static PrimitiveEqualsIntrinsic newInstance() {
+ public static PrimitiveEqualsIntrinsic newInstance() {
return new PrimitiveEqualsIntrinsic();
}
diff --git a/translator/src/org/jetbrains/k2js/translate/intrinsic/UnaryOperationIntrinsic.java b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveUnaryOperationIntrinsic.java
similarity index 70%
rename from translator/src/org/jetbrains/k2js/translate/intrinsic/UnaryOperationIntrinsic.java
rename to translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveUnaryOperationIntrinsic.java
index ea73ee38794..dad8638b399 100644
--- a/translator/src/org/jetbrains/k2js/translate/intrinsic/UnaryOperationIntrinsic.java
+++ b/translator/src/org/jetbrains/k2js/translate/intrinsic/primitive/PrimitiveUnaryOperationIntrinsic.java
@@ -1,4 +1,4 @@
-package org.jetbrains.k2js.translate.intrinsic;
+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;
@@ -6,6 +6,7 @@ import com.google.dart.compiler.backend.js.ast.JsUnaryOperator;
import org.jetbrains.annotations.NotNull;
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;
@@ -13,18 +14,18 @@ import java.util.List;
/**
* @author Talanov Pavel
*/
-public class UnaryOperationIntrinsic extends FunctionIntrinsic {
+public final class PrimitiveUnaryOperationIntrinsic implements FunctionIntrinsic {
@NotNull
- /*package*/ static UnaryOperationIntrinsic newInstance(@NotNull JetToken token) {
+ public static PrimitiveUnaryOperationIntrinsic newInstance(@NotNull JetToken token) {
JsUnaryOperator operator = OperatorTable.getUnaryOperator(token);
- return new UnaryOperationIntrinsic(operator);
+ return new PrimitiveUnaryOperationIntrinsic(operator);
}
@NotNull
private final JsUnaryOperator operator;
- private UnaryOperationIntrinsic(@NotNull JsUnaryOperator operator) {
+ private PrimitiveUnaryOperationIntrinsic(@NotNull JsUnaryOperator operator) {
this.operator = operator;
}
diff --git a/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java b/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
index f82e7bd885c..43c7c102376 100644
--- a/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/operation/CompareToTranslator.java
@@ -3,7 +3,6 @@ package org.jetbrains.k2js.translate.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 com.google.dart.compiler.backend.js.ast.JsNumberLiteral;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
@@ -13,6 +12,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
import org.jetbrains.k2js.translate.reference.CallTranslator;
+import org.jetbrains.k2js.translate.utils.TranslationUtils;
import java.util.Arrays;
@@ -73,10 +73,9 @@ public final class CompareToTranslator extends AbstractTranslator {
@NotNull
private JsExpression overloadedCompareTo() {
- JsNumberLiteral zeroLiteral = program().getNumberLiteral(0);
JsBinaryOperator correspondingOperator = OperatorTable.getBinaryOperator(operationToken);
JsExpression methodCall = CallTranslator.translate(expression, context());
- return new JsBinaryOperation(correspondingOperator, methodCall, zeroLiteral);
+ return new JsBinaryOperation(correspondingOperator, methodCall, TranslationUtils.zeroLiteral(context()));
}
@NotNull
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java
index 48ab2f3c846..efb1400532b 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java
@@ -9,6 +9,8 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetArrayAccessExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
+import org.jetbrains.k2js.translate.intrinsic.array.ArrayGetIntrinsic;
+import org.jetbrains.k2js.translate.intrinsic.array.ArraySetIntrinsic;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
@@ -41,19 +43,47 @@ public final class ArrayAccessTranslator extends AccessTranslator {
@Override
@NotNull
- public JsInvocation translateAsGet() {
- return translateAsArrayAccessWithIndices();
+ public JsExpression translateAsGet() {
+ if (intrinsicCall()) {
+ return intrinsicGet();
+ }
+ return translateAsAccessMethodCall();
+ }
+
+ private boolean intrinsicCall() {
+ return context().intrinsics().isIntrinsic(methodDescriptor);
+ }
+
+ @NotNull
+ private JsExpression intrinsicGet() {
+ return ArrayGetIntrinsic.INSTANCE.apply(translateArrayExpression(), translateIndexExpressions(), context());
}
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression expression) {
- JsInvocation setCall = translateAsArrayAccessWithIndices();
+ if (intrinsicCall()) {
+ return intrinsicSet(expression);
+ }
+ return overloadedSet(expression);
+ }
+
+ @NotNull
+ private JsExpression intrinsicSet(@NotNull JsExpression expression) {
+ List arguments = translateIndexExpressions();
+ arguments.add(expression);
+ return ArraySetIntrinsic.INSTANCE.apply(translateArrayExpression(), arguments, context());
+ }
+
+ @NotNull
+ private JsExpression overloadedSet(@NotNull JsExpression expression) {
+ JsInvocation setCall = translateAsAccessMethodCall();
setCall.getArguments().add(expression);
return setCall;
}
- private JsInvocation translateAsArrayAccessWithIndices() {
+ @NotNull
+ private JsInvocation translateAsAccessMethodCall() {
JsNameRef accessMethodReference = getAccessMethodReference();
AstUtil.setQualifier(accessMethodReference, translateArrayExpression());
return AstUtil.newInvocation(accessMethodReference, translateIndexExpressions());
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
index 9654fe06b27..ed69ce8513d 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java
@@ -26,18 +26,9 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
/**
* @author Talanov Pavel
*/
+//TODO: write tests on calling backing fields as functions
public final class CallTranslator extends AbstractTranslator {
-
- //TODO: remove?
-
-// public static boolean isFunctionCall(@NotNull JetOperationExpression expression,
-// @NotNull TranslationContext context) {
-// DeclarationDescriptor descriptor = getDescriptorForReferenceExpression
-// (context.bindingContext(), expression.getOperation());
-// return (descriptor instanceof FunctionDescriptor);
-// }
-
public static JsExpression translate(@NotNull JetUnaryExpression unaryExpression,
@NotNull TranslationContext context) {
JsExpression receiver = TranslationUtils.translateBaseExpression(context, unaryExpression);
@@ -48,6 +39,7 @@ public final class CallTranslator extends AbstractTranslator {
return (new CallTranslator(receiver, arguments, (FunctionDescriptor) descriptor, context)).translate();
}
+ //TODO: method too long
public static JsExpression translate(@NotNull JetDotQualifiedExpression dotExpression,
@NotNull TranslationContext context) {
//TODO: look for duplication
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java
index 85cfa97cd21..8dc2386237b 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java
@@ -7,6 +7,7 @@ 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.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
@@ -15,9 +16,11 @@ import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.Translation;
-import org.jetbrains.k2js.translate.utils.BindingUtils;
+import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getSelectorAsSimpleName;
+import static org.jetbrains.k2js.translate.utils.PsiUtils.isBackingFieldReference;
+import static org.jetbrains.k2js.translate.utils.TranslationUtils.backingFieldReference;
/**
* @author Talanov Pavel
@@ -85,7 +88,8 @@ public final class PropertyAccessTranslator extends AccessTranslator {
public static boolean canBePropertyGetterCall(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
- return (BindingUtils.getPropertyDescriptorForSimpleName(context.bindingContext(), expression) != null);
+ return (getDescriptorForReferenceExpression
+ (context.bindingContext(), expression) instanceof PropertyDescriptor);
}
public static boolean canBePropertyGetterCall(@NotNull JetExpression expression,
@@ -108,19 +112,23 @@ public final class PropertyAccessTranslator extends AccessTranslator {
private final JetExpression qualifier;
@NotNull
private final PropertyDescriptor propertyDescriptor;
+ private final boolean isBackingFieldAccess;
private PropertyAccessTranslator(@NotNull JetSimpleNameExpression simpleName,
@NotNull TranslationContext context) {
super(context);
this.qualifier = null;
this.propertyDescriptor = getPropertyDescriptor(simpleName);
+ this.isBackingFieldAccess = isBackingFieldReference(simpleName);
}
private PropertyAccessTranslator(@NotNull JetQualifiedExpression qualifiedExpression,
@NotNull TranslationContext context) {
super(context);
this.qualifier = qualifiedExpression.getReceiverExpression();
- this.propertyDescriptor = getPropertyDescriptor(getNotNullSelector(qualifiedExpression));
+ JetSimpleNameExpression selector = getNotNullSelector(qualifiedExpression);
+ this.propertyDescriptor = getPropertyDescriptor(selector);
+ this.isBackingFieldAccess = isBackingFieldReference(selector);
}
private PropertyAccessTranslator(@NotNull PropertyDescriptor descriptor,
@@ -128,11 +136,26 @@ public final class PropertyAccessTranslator extends AccessTranslator {
super(context);
this.qualifier = null;
this.propertyDescriptor = descriptor;
+ this.isBackingFieldAccess = false;
}
@Override
@NotNull
public JsExpression translateAsGet() {
+ if (isBackingFieldAccess) {
+ return backingFieldGet();
+ } else {
+ return getterCall();
+ }
+ }
+
+ @NotNull
+ private JsExpression backingFieldGet() {
+ return backingFieldReference(context(), propertyDescriptor);
+ }
+
+ @NotNull
+ private JsExpression getterCall() {
JsName getterName = getGetterName();
return qualifiedAccessorInvocation(getterName);
}
@@ -140,12 +163,27 @@ public final class PropertyAccessTranslator extends AccessTranslator {
@Override
@NotNull
public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
+ if (isBackingFieldAccess) {
+ return backingFieldAssignment(toSetTo);
+ } else {
+ return setterCall(toSetTo);
+ }
+ }
+
+ @NotNull
+ private JsExpression setterCall(@NotNull JsExpression toSetTo) {
JsName setterName = getSetterName();
JsInvocation setterCall = qualifiedAccessorInvocation(setterName);
setterCall.getArguments().add(toSetTo);
return setterCall;
}
+ @NotNull
+ private JsExpression backingFieldAssignment(@NotNull JsExpression toSetTo) {
+ JsNameRef backingFieldReference = backingFieldReference(context(), propertyDescriptor);
+ return AstUtil.newAssignment(backingFieldReference, toSetTo);
+ }
+
@NotNull
private JsInvocation qualifiedAccessorInvocation(@NotNull JsName accessorName) {
JsNameRef accessorReference = accessorName.makeRef();
@@ -197,12 +235,12 @@ public final class PropertyAccessTranslator extends AccessTranslator {
return setter;
}
-
@NotNull
private PropertyDescriptor getPropertyDescriptor(@NotNull JetSimpleNameExpression expression) {
- PropertyDescriptor propertyDescriptor =
- BindingUtils.getPropertyDescriptorForSimpleName(context().bindingContext(), expression);
- assert propertyDescriptor != null;
- return propertyDescriptor;
+ DeclarationDescriptor descriptor =
+ getDescriptorForReferenceExpression(context().bindingContext(), expression);
+ //TODO
+ assert descriptor instanceof PropertyDescriptor;
+ return (PropertyDescriptor) descriptor;
}
}
diff --git a/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java
index 4bca7ed2206..25bcbbc3560 100644
--- a/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java
+++ b/translator/src/org/jetbrains/k2js/translate/reference/ReferenceTranslator.java
@@ -12,61 +12,14 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.utils.BindingUtils;
import org.jetbrains.k2js.translate.utils.TranslationUtils;
+import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
+
/**
* @author Talanov Pavel
*/
public class ReferenceTranslator extends AbstractTranslator {
- @NotNull
- private final JetSimpleNameExpression simpleName;
-
- @Nullable
- private JsExpression result;
-
- @NotNull
- public static JsExpression translateSimpleName(@NotNull JetSimpleNameExpression expression,
- @NotNull TranslationContext context) {
- return (new ReferenceTranslator(expression, context)).translateSimpleName();
- }
-
- private ReferenceTranslator(@NotNull JetSimpleNameExpression expression, @NotNull TranslationContext context) {
- super(context);
- this.simpleName = expression;
- this.result = null;
- }
-
- @NotNull
- //TODO: make this process simpler and clearer
- public JsExpression translateSimpleName() {
- tryResolveAsAlias();
- tryResolveAsPropertyAccess();
- tryResolveAsReference();
- if (result != null) {
- return result;
- }
- throw new AssertionError("Undefined name in this scope: " + simpleName.getReferencedName());
- }
-
- //TODO: refactor
- private void tryResolveAsReference() {
- if (alreadyResolved()) return;
-
- DeclarationDescriptor referencedDescriptor =
- BindingUtils.getDescriptorForReferenceExpression(context().bindingContext(), simpleName);
-
- if (referencedDescriptor == null) return;
- if (!context().isDeclared(referencedDescriptor)) return;
-
- JsName referencedName = context().getNameForDescriptor(referencedDescriptor);
- JsExpression implicitReceiver = getImplicitReceiver(referencedDescriptor, context());
-
- if (implicitReceiver != null) {
- result = AstUtil.qualified(referencedName, implicitReceiver);
- } else {
- result = context().getNameForDescriptor(referencedDescriptor).makeRef();
- }
- }
-
+ // TODO: move to other util
@Nullable
public static JsExpression getImplicitReceiver(@NotNull DeclarationDescriptor referencedDescriptor,
@NotNull TranslationContext context) {
@@ -80,28 +33,74 @@ public class ReferenceTranslator extends AbstractTranslator {
return context.declarations().getQualifier(referencedDescriptor);
}
+ @NotNull
+ public static JsExpression translateSimpleName(@NotNull JetSimpleNameExpression expression,
+ @NotNull TranslationContext context) {
+ if (PropertyAccessTranslator.canBePropertyAccess(expression, context)) {
+ return PropertyAccessTranslator.translateAsPropertyGetterCall(expression, context);
+ }
+ DeclarationDescriptor referencedDescriptor =
+ getDescriptorForReferenceExpression(context.bindingContext(), expression);
+ return (new ReferenceTranslator(referencedDescriptor, context)).translate();
+ }
+
+ @NotNull
+ public static JsExpression translateReference(@NotNull DeclarationDescriptor referencedDescriptor,
+ @NotNull TranslationContext context) {
+ return (new ReferenceTranslator(referencedDescriptor, context)).translate();
+ }
+
+ @NotNull
+ private final DeclarationDescriptor referencedDescriptor;
+
+ @Nullable
+ private JsExpression result;
+
+ private ReferenceTranslator(@NotNull DeclarationDescriptor referencedDescriptor, @NotNull TranslationContext context) {
+ super(context);
+ this.referencedDescriptor = referencedDescriptor;
+ this.result = null;
+ }
+
+ @NotNull
+ public JsExpression translate() {
+ tryResolveAsAlias();
+ tryResolveAsReference();
+ if (result != null) {
+ return result;
+ }
+ throw new AssertionError("Undefined name in this scope: " + referencedDescriptor.getName());
+ }
+
private void tryResolveAsAlias() {
- //TODO: decide if this code is meaningful
if (alreadyResolved()) return;
- DeclarationDescriptor referencedDescriptor =
- BindingUtils.getDescriptorForReferenceExpression(context().bindingContext(), simpleName);
-
- if (referencedDescriptor == null) return;
if (!context().aliaser().hasAliasForDeclaration(referencedDescriptor)) return;
result = context().aliaser().getAliasForDeclaration(referencedDescriptor);
}
+
+ private void tryResolveAsReference() {
+ if (alreadyResolved()) return;
+
+ if (!context().isDeclared(referencedDescriptor)) return;
+
+ JsName referencedName = context().getNameForDescriptor(referencedDescriptor);
+ JsExpression implicitReceiver = getImplicitReceiver(referencedDescriptor, context());
+
+ generateReference(referencedName, implicitReceiver);
+ }
+
+ private void generateReference(@NotNull JsName referencedName, @Nullable JsExpression implicitReceiver) {
+ if (implicitReceiver != null) {
+ result = AstUtil.qualified(referencedName, implicitReceiver);
+ } else {
+ result = context().getNameForDescriptor(referencedDescriptor).makeRef();
+ }
+ }
+
private boolean alreadyResolved() {
return result != null;
}
-
- private void tryResolveAsPropertyAccess() {
- if (alreadyResolved()) return;
-
- if (!PropertyAccessTranslator.canBePropertyGetterCall(simpleName, context())) return;
-
- result = PropertyAccessTranslator.translateAsPropertyGetterCall(simpleName, context());
- }
}
diff --git a/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java
index 8a1c2d32d75..6e2be99b2d5 100644
--- a/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java
+++ b/translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java
@@ -14,6 +14,8 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getVariableDescriptorForVariableAsFunction;
+
/**
* @author Talanov Pavel
*
@@ -32,6 +34,7 @@ public final class BindingUtils {
assert descriptor != null;
assert descriptorClass.isInstance(descriptor)
: expression.toString() + " expected to have of type" + descriptorClass.toString();
+ //noinspection unchecked
return (D) descriptor;
}
@@ -64,23 +67,6 @@ public final class BindingUtils {
return getDescriptorForExpression(context, declaration, PropertyDescriptor.class);
}
- //TODO: possibly remove
-// @NotNull
-// public static PropertySetterDescriptor getPropertySetterDescriptorForProperty(@NotNull BindingContext context,
-// @NotNull JetProperty property) {
-// PropertySetterDescriptor result = getPropertyDescriptor(context, property).getSetter();
-// assert result != null : "Property should have a setter descriptor";
-// return result;
-// }
-//
-// @NotNull
-// public static PropertyGetterDescriptor getPropertyGetterDescriptorForProperty(@NotNull BindingContext context,
-// @NotNull JetProperty property) {
-// PropertyGetterDescriptor result = getPropertyDescriptor(context, property).getGetter();
-// assert result != null : "Property should have a getter descriptor";
-// return result;
-// }
-
@NotNull
public static JetClass getClassForDescriptor(@NotNull BindingContext context,
@NotNull ClassDescriptor descriptor) {
@@ -89,17 +75,6 @@ public final class BindingUtils {
return (JetClass) result;
}
- //TODO: delete?
- @Nullable
- public static JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context,
- @NotNull DeclarationDescriptor descriptor) {
- PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
- if (!(result instanceof JetDeclaration)) {
- return null;
- }
- return (JetDeclaration) result;
- }
-
@NotNull
public static List getSuperclassDescriptors(@NotNull BindingContext context,
@NotNull JetClass classDeclaration) {
@@ -131,7 +106,7 @@ public final class BindingUtils {
public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClass classDeclaration) {
List superclassDescriptors = getSuperclassDescriptors(context, classDeclaration);
- return (findAncestorClass(superclassDescriptors) != null);
+ return (DescriptorUtils.findAncestorClass(superclassDescriptors) != null);
}
public static boolean isStatement(@NotNull BindingContext context, @NotNull JetExpression expression) {
@@ -170,25 +145,26 @@ public final class BindingUtils {
return (JetProperty) result;
}
- @Nullable
+ @NotNull
public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context,
@NotNull JetReferenceExpression reference) {
- return context.get(BindingContext.REFERENCE_TARGET, reference);
+ DeclarationDescriptor referencedDescriptor = getNullableDescriptorForReferenceExpression(context, reference);
+ assert referencedDescriptor != null : "Reference expression must reference a descriptor.";
+ return referencedDescriptor;
}
- static private boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) {
- return !superClassDescriptor.equals(JetStandardClasses.getAny());
- }
-
- //TODO move unrelated utils to other class
@Nullable
- public static ClassDescriptor findAncestorClass(@NotNull List superclassDescriptors) {
- for (ClassDescriptor descriptor : superclassDescriptors) {
- if (descriptor.getKind() == ClassKind.CLASS) {
- return descriptor;
- }
+ private static DeclarationDescriptor getNullableDescriptorForReferenceExpression(@NotNull BindingContext context,
+ @NotNull JetReferenceExpression reference) {
+ DeclarationDescriptor referencedDescriptor = context.get(BindingContext.REFERENCE_TARGET, reference);
+ if (referencedDescriptor instanceof VariableAsFunctionDescriptor) {
+ return getVariableDescriptorForVariableAsFunction((VariableAsFunctionDescriptor) referencedDescriptor);
}
- return null;
+ return referencedDescriptor;
+ }
+
+ private static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) {
+ return !superClassDescriptor.equals(JetStandardClasses.getAny());
}
//TODO: duplication
@@ -210,48 +186,30 @@ public final class BindingUtils {
return (descriptor.getContainingDeclaration() instanceof ClassDescriptor);
}
-
- //TODO: refactor, check with getDescriptorForReferenceExpression
- @Nullable
- public static PropertyDescriptor getPropertyDescriptorForSimpleName(@NotNull BindingContext context,
- @NotNull JetSimpleNameExpression expression) {
- ResolvedCall> resolvedCall = BindingUtils.getResolvedCall(context, expression);
- if (resolvedCall == null) return null;
-
- DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor();
- if (descriptor instanceof PropertyDescriptor) {
- return (PropertyDescriptor) descriptor;
- }
- if (descriptor instanceof VariableAsFunctionDescriptor) {
- VariableAsFunctionDescriptor functionVariable = (VariableAsFunctionDescriptor) descriptor;
- VariableDescriptor variableDescriptor = functionVariable.getVariableDescriptor();
- if (variableDescriptor instanceof PropertyDescriptor) {
- return (PropertyDescriptor) variableDescriptor;
- }
- }
- return null;
- }
-
- @Nullable
+ @NotNull
public static ResolvedCall> getResolvedCall(@NotNull BindingContext context,
@NotNull JetExpression expression) {
- return (context.get(BindingContext.RESOLVED_CALL, expression));
+ ResolvedCall extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression);
+ assert resolvedCall != null : "Must resolve to a call.";
+ return resolvedCall;
}
@NotNull
public static FunctionDescriptor getFunctionDescriptorForCallExpression(@NotNull BindingContext context,
@NotNull JetCallExpression expression) {
- //TODO: move to PSI utils
- JetExpression calleeExpression = expression.getCalleeExpression();
- assert calleeExpression != null;
+ JetExpression calleeExpression = PsiUtils.getCallee(expression);
ResolvedCall> resolvedCall = getResolvedCall(context, calleeExpression);
- //TODO
- CallableDescriptor descriptor = resolvedCall.getCandidateDescriptor();
+ CallableDescriptor descriptor = getDescriptorForResolvedCall(resolvedCall);
assert descriptor instanceof FunctionDescriptor :
"Callee expression must have resolved call with descriptor of type FunctionDescriptor";
return (FunctionDescriptor) descriptor;
}
+ @NotNull
+ private static CallableDescriptor getDescriptorForResolvedCall(@NotNull ResolvedCall> resolvedCall) {
+ return resolvedCall.getCandidateDescriptor();
+ }
+
public static boolean isVariableReassignment(@NotNull BindingContext context, @NotNull JetExpression expression) {
Boolean result = context.get(BindingContext.VARIABLE_REASSIGNMENT, expression);
assert result != null;
@@ -262,7 +220,7 @@ public final class BindingUtils {
@Nullable
public static FunctionDescriptor getFunctionDescriptorForOperationExpression(@NotNull BindingContext context,
@NotNull JetOperationExpression expression) {
- DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
+ DeclarationDescriptor descriptorForReferenceExpression = getNullableDescriptorForReferenceExpression
(context, expression.getOperation());
if (descriptorForReferenceExpression == null) return null;
diff --git a/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java
index bdec4be4d93..be9bb81ca04 100644
--- a/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java
+++ b/translator/src/org/jetbrains/k2js/translate/utils/DescriptorUtils.java
@@ -1,15 +1,15 @@
package org.jetbrains.k2js.translate.utils;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
-import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
-import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.descriptors.*;
+import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Set;
/**
* @author Talanov Pavel
@@ -58,4 +58,43 @@ public final class DescriptorUtils {
}
return resultingList;
}
+
+ @NotNull
+ public static FunctionDescriptor getFunctionByName(@NotNull ClassDescriptor classDescriptor,
+ @NotNull String name) {
+ JetScope scope = classDescriptor.getDefaultType().getMemberScope();
+ return getFunctionByName(scope, name);
+ }
+
+ @NotNull
+ public static FunctionDescriptor getFunctionByName(@NotNull JetScope scope,
+ @NotNull String name) {
+ Set functionDescriptors = scope.getFunctions(name);
+ assert functionDescriptors.size() == 1 :
+ "In scope " + scope + " supposed to be exactly one " + name + " function.";
+ //noinspection LoopStatementThatDoesntLoop
+ for (FunctionDescriptor descriptor : functionDescriptors) {
+ return descriptor;
+ }
+ throw new AssertionError("In scope " + scope
+ + " supposed to be exactly one " + name + " function.");
+ }
+
+ @Nullable
+ public static ClassDescriptor findAncestorClass(@NotNull List superclassDescriptors) {
+ for (ClassDescriptor descriptor : superclassDescriptors) {
+ if (descriptor.getKind() == ClassKind.CLASS) {
+ return descriptor;
+ }
+ }
+ return null;
+ }
+
+ @NotNull
+ /*package*/ static VariableDescriptor getVariableDescriptorForVariableAsFunction
+ (@NotNull VariableAsFunctionDescriptor descriptor) {
+ VariableDescriptor functionVariable = descriptor.getVariableDescriptor();
+ assert functionVariable != null;
+ return functionVariable;
+ }
}
diff --git a/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java
index 5635b200e6f..bb84f5ced33 100644
--- a/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java
+++ b/translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java
@@ -47,4 +47,15 @@ public final class PsiUtils {
public static boolean isAssignment(JetToken token) {
return (token == JetTokens.EQ);
}
+
+ public static boolean isBackingFieldReference(@NotNull JetSimpleNameExpression expression) {
+ return expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
+ }
+
+ @NotNull
+ /*package*/ static JetExpression getCallee(@NotNull JetCallExpression expression) {
+ JetExpression calleeExpression = expression.getCalleeExpression();
+ assert calleeExpression != null;
+ return calleeExpression;
+ }
}
diff --git a/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
index 15f7fadfaca..16ab6ee6a89 100644
--- a/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
+++ b/translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java
@@ -76,15 +76,6 @@ public final class TranslationUtils {
return AstUtil.qualified(backingFieldName, qualifier);
}
- @NotNull
- public static String getPropertyName(@NotNull JetProperty expression) {
- String propertyName = expression.getName();
- if (propertyName == null) {
- throw new AssertionError("Property with no name encountered!");
- }
- return propertyName;
- }
-
@Nullable
public static JsExpression translateInitializerForProperty(@NotNull JetProperty declaration,
@NotNull TranslationContext context) {
@@ -212,4 +203,9 @@ public final class TranslationUtils {
return JsFunction.getAnonymousFunctionWithScope(scope.jsScope());
}
+ @NotNull
+ public static JsNumberLiteral zeroLiteral(@NotNull TranslationContext context) {
+ return context.program().getNumberLiteral(0);
+ }
+
}
diff --git a/translator/test/org/jetbrains/k2js/test/StandardClassesTest.java b/translator/test/org/jetbrains/k2js/test/StandardClassesTest.java
index b1b5a38b06c..0a1f87203c6 100644
--- a/translator/test/org/jetbrains/k2js/test/StandardClassesTest.java
+++ b/translator/test/org/jetbrains/k2js/test/StandardClassesTest.java
@@ -1,5 +1,7 @@
package org.jetbrains.k2js.test;
+import org.junit.Test;
+
/**
* @author Talanov Pavel
*/
@@ -11,14 +13,13 @@ public class StandardClassesTest extends TranslationTest {
return MAIN;
}
- //TODO: implement via intrinsics
-// @Test
-// public void array() throws Exception {
-// testFooBoxIsTrue("array.kt");
-// }
-//
-// @Test
-// public void arrayAccess() throws Exception {
-// testFooBoxIsTrue("arrayAccess.kt");
-// }
+ @Test
+ public void array() throws Exception {
+ testFooBoxIsTrue("array.kt");
+ }
+
+ @Test
+ public void arrayAccess() throws Exception {
+ testFooBoxIsTrue("arrayAccess.kt");
+ }
}
diff --git a/translator/testFiles/kotlinLib/cases/array.js b/translator/testFiles/kotlinLib/cases/array.js
index db84987aca7..4a3adb7f6cc 100644
--- a/translator/testFiles/kotlinLib/cases/array.js
+++ b/translator/testFiles/kotlinLib/cases/array.js
@@ -1,6 +1,8 @@
function test() {
- var a = new Kotlin.Array();
+ var a = new Kotlin.Array(3, function () {
+ return 3
+ });
a.set(0, "1")
a.set(2, "4")
- return (a.get(0) == "1") && (a.get(2) == "4") && (a.get(1) == undefined);
+ return (a.get(0) == "1") && (a.get(2) == "4") && (a.get(1) == 3);
}
\ No newline at end of file
diff --git a/translator/testFiles/kotlin_lib.js b/translator/testFiles/kotlin_lib.js
index 9872777595c..5f12c89782e 100644
--- a/translator/testFiles/kotlin_lib.js
+++ b/translator/testFiles/kotlin_lib.js
@@ -447,17 +447,35 @@ Object.extend(Function.prototype, (function () {
})());
Kotlin = {}
+Kotlin.Exceptions = {}
+Kotlin.Exceptions.IndexOutOfBounds = {}
+Kotlin.array = function (len) {
+ return new Kotlin.Array(len, function () {
+ return null
+ });
+}
Kotlin.Array = Class.create({
- initialize:function () {
+ initialize:function (len, f) {
this.array = [];
+ var i = 0;
+ while (i < len) {
+ this.array.push(f(i));
+ ++i;
+ }
},
get:function (index) {
+ if ((index < 0) || (index > this.array.length)) {
+ throw Kotlin.Exceptions.IndexOutOfBounds;
+ }
return (this.array)[index];
},
set:function (index, value) {
+ if ((index < 0) || (index > this.array.length)) {
+ throw Kotlin.Exceptions.IndexOutOfBounds;
+ }
(this.array)[index] = value;
}
-})
+});
Kotlin.Class = Class
Kotlin.Namespace = Namespace