implement some of the intrinsic functionality
This commit is contained in:
@@ -309,6 +309,13 @@ public class AstUtil {
|
|||||||
throw new AssertionError("Set qualifier should be applied only to JsInvocation or JsNameRef instances");
|
throw new AssertionError("Set qualifier should be applied only to JsInvocation or JsNameRef instances");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: look for should-be-usages
|
||||||
|
public static JsNameRef qualified(JsName selector, JsExpression qualifier) {
|
||||||
|
JsNameRef reference = selector.makeRef();
|
||||||
|
AstUtil.setQualifier(reference, qualifier);
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
|
||||||
public static JsBinaryOperation equals(JsExpression arg1, JsExpression arg2) {
|
public static JsBinaryOperation equals(JsExpression arg1, JsExpression arg2) {
|
||||||
return new JsBinaryOperation(JsBinaryOperator.REF_EQ, arg1, arg2);
|
return new JsBinaryOperation(JsBinaryOperator.REF_EQ, arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.jetbrains.k2js.intrinsic;
|
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
|
||||||
import org.jetbrains.k2js.translate.operation.IntrinsicBinaryOperationTranslator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Talanov Pavel
|
|
||||||
*/
|
|
||||||
public enum BinaryOperationIntrinsic implements Intrinsic {
|
|
||||||
|
|
||||||
INSTANCE;
|
|
||||||
|
|
||||||
/*package*/ BinaryOperationIntrinsic() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public JsExpression apply(@NotNull JetExpression expression,
|
|
||||||
@NotNull TranslationContext context) {
|
|
||||||
assert expression instanceof JetBinaryExpression : "This intrinsic must be applied to binary operations.";
|
|
||||||
return IntrinsicBinaryOperationTranslator.translate((JetBinaryExpression) expression, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.jetbrains.k2js.intrinsic;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Talanov Pavel
|
|
||||||
*/
|
|
||||||
public final class IntrinsicFactory {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final Intrinsics intrinsics;
|
|
||||||
|
|
||||||
private IntrinsicFactory(@NotNull Intrinsics intrinsics) {
|
|
||||||
this.intrinsics = intrinsics;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public Intrinsic getIntrinsicForExpression(@NotNull FunctionDescriptor descriptor,
|
|
||||||
// @NotNull JetExpression expression,
|
|
||||||
// @NotNull TranslationContext context) {
|
|
||||||
// assert intrinsics.hasDescriptor(descriptor);
|
|
||||||
// if (JetExpression instanceof JetBinaryExpression) {
|
|
||||||
// return new BinaryOperationIntrinsic()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package org.jetbrains.k2js.intrinsic;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|
||||||
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Talanov Pavel
|
|
||||||
*/
|
|
||||||
public final class Intrinsics {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final Map<DeclarationDescriptor, Intrinsic> descriptorToIntrinsicMap =
|
|
||||||
new HashMap<DeclarationDescriptor, Intrinsic>();
|
|
||||||
|
|
||||||
public static Intrinsics standardLibraryIntrinsics(@NotNull JetStandardLibrary library) {
|
|
||||||
return new Intrinsics(library);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Intrinsics(@NotNull JetStandardLibrary library) {
|
|
||||||
IntrinsicDeclarationVisitor visitor = new IntrinsicDeclarationVisitor(this);
|
|
||||||
for (DeclarationDescriptor descriptor : library.getLibraryScope().getAllDescriptors()) {
|
|
||||||
descriptor.accept(visitor, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*package*/ void declareIntrinsic(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
//TODO: this is a hack
|
|
||||||
descriptorToIntrinsicMap.put(descriptor, null);
|
|
||||||
addBinaryIntrinsics(descriptor);
|
|
||||||
// addUnaryIntrinsics(descriptor);
|
|
||||||
// addAssignmentIntrinsics(descriptor);
|
|
||||||
// addEqualsIntrinsics(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// private void addEqualsIntrinsics(FunctionDescriptor descriptor) {
|
|
||||||
// //BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
|
||||||
// String functionName = descriptor.getName();
|
|
||||||
// if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsValue(functionName)) {
|
|
||||||
// descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void addUnaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
|
||||||
// BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
|
||||||
// String functionName = descriptor.getName();
|
|
||||||
// if (OperatorConventions.UNARY_OPERATION_NAMES.containsValue(functionName)) {
|
|
||||||
// descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
private void addBinaryIntrinsics(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
String functionName = descriptor.getName();
|
|
||||||
if (OperatorConventions.BINARY_OPERATION_NAMES.containsValue(functionName)) {
|
|
||||||
descriptorToIntrinsicMap.put(descriptor, BinaryOperationIntrinsic.INSTANCE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// private void addAssignmentIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
|
||||||
// String functionName = descriptor.getName();
|
|
||||||
// if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsValue(functionName)) {
|
|
||||||
// BinaryOperationIntrinsic binaryOperationIntrinsic = new BinaryOperationIntrinsic();
|
|
||||||
// descriptorToIntrinsicMap.put(descriptor, binaryOperationIntrinsic);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
public boolean hasDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (descriptor instanceof FunctionDescriptor) {
|
|
||||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor.getOriginal();
|
|
||||||
return descriptorToIntrinsicMap.containsKey(functionDescriptor);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Intrinsic getIntrinsic(@NotNull DeclarationDescriptor descriptor) {
|
|
||||||
Intrinsic intrinsic = descriptorToIntrinsicMap.get(descriptor);
|
|
||||||
// assert intrinsic != null;
|
|
||||||
return intrinsic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,6 +14,7 @@ import org.jetbrains.k2js.translate.general.TranslatorVisitor;
|
|||||||
import org.jetbrains.k2js.translate.operation.OperationTranslator;
|
import org.jetbrains.k2js.translate.operation.OperationTranslator;
|
||||||
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
|
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.reference.CallTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
import org.jetbrains.k2js.translate.reference.ReferenceTranslator;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
@@ -108,24 +109,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsNode visitCallExpression(JetCallExpression expression, TranslationContext context) {
|
public JsNode visitCallExpression(@NotNull JetCallExpression expression,
|
||||||
JsExpression callee = translateCallee(expression, context);
|
@NotNull TranslationContext context) {
|
||||||
List<JsExpression> arguments = translateArgumentList(expression.getValueArguments(), context);
|
return CallTranslator.translate(expression, context);
|
||||||
if (isConstructorInvocation(context, expression)) {
|
|
||||||
JsNew constructorCall = new JsNew(callee);
|
|
||||||
constructorCall.setArguments(arguments);
|
|
||||||
return constructorCall;
|
|
||||||
}
|
|
||||||
return AstUtil.newInvocation(callee, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsExpression translateCallee(@NotNull JetCallExpression expression, @NotNull TranslationContext context) {
|
|
||||||
JetExpression callee = expression.getCalleeExpression();
|
|
||||||
if (callee == null) {
|
|
||||||
throw new AssertionError("Call expression with no callee encountered!");
|
|
||||||
}
|
|
||||||
return translateAsExpression(callee, context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import org.jetbrains.jet.lang.psi.JetElement;
|
|||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
import org.jetbrains.k2js.declarations.Declarations;
|
import org.jetbrains.k2js.declarations.Declarations;
|
||||||
import org.jetbrains.k2js.intrinsic.Intrinsics;
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||||
import org.jetbrains.k2js.translate.utils.Namer;
|
import org.jetbrains.k2js.translate.utils.Namer;
|
||||||
|
|
||||||
public class StaticContext {
|
public class StaticContext {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
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.k2js.declarations.Declarations;
|
import org.jetbrains.k2js.declarations.Declarations;
|
||||||
import org.jetbrains.k2js.intrinsic.Intrinsics;
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.Namer;
|
import org.jetbrains.k2js.translate.utils.Namer;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<JsExpression> translateArguments(@NotNull JetDelegatorToSuperCall superCall) {
|
private List<JsExpression> translateArguments(@NotNull JetDelegatorToSuperCall superCall) {
|
||||||
return TranslationUtils.translateArgumentList(superCall.getValueArguments(), context());
|
return TranslationUtils.translateArgumentList(context(), superCall.getValueArguments());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
|
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.lexer.JetToken;
|
||||||
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public class BinaryOperationIntrinsic implements Intrinsic {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
/*package*/ static BinaryOperationIntrinsic newInstance(@NotNull JetToken token) {
|
||||||
|
JsBinaryOperator operator = OperatorTable.getBinaryOperator(token);
|
||||||
|
return new BinaryOperationIntrinsic(operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final JsBinaryOperator operator;
|
||||||
|
|
||||||
|
private BinaryOperationIntrinsic(@NotNull JsBinaryOperator operator) {
|
||||||
|
this.operator = operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JsExpression apply(@NotNull 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
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 Talanov Pavel
|
||||||
|
*/
|
||||||
|
public abstract class CompareToIntrinsic implements Intrinsic {
|
||||||
|
|
||||||
|
private JetToken comparisonToken = null;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public abstract class EqualsIntrinsic implements Intrinsic {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Boolean isNegated = false;
|
||||||
|
|
||||||
|
public void setNegated(boolean isNegated) {
|
||||||
|
this.isNegated = isNegated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNegated() {
|
||||||
|
return isNegated;
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-3
@@ -1,17 +1,18 @@
|
|||||||
package org.jetbrains.k2js.intrinsic;
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
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.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
*/
|
*/
|
||||||
public interface Intrinsic {
|
public interface Intrinsic {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsExpression apply(@NotNull JetExpression expression,
|
public JsExpression apply(@NotNull JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||||
@NotNull TranslationContext context);
|
@NotNull TranslationContext context);
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.jetbrains.k2js.intrinsic;
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
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.operation.OperatorTable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class Intrinsics {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Map<FunctionDescriptor, Intrinsic> descriptorToIntrinsicMap =
|
||||||
|
new HashMap<FunctionDescriptor, Intrinsic>();
|
||||||
|
|
||||||
|
public static Intrinsics standardLibraryIntrinsics(@NotNull JetStandardLibrary library) {
|
||||||
|
return new Intrinsics(library);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Intrinsics(@NotNull JetStandardLibrary library) {
|
||||||
|
IntrinsicDeclarationVisitor visitor = new IntrinsicDeclarationVisitor(this);
|
||||||
|
for (DeclarationDescriptor descriptor : library.getLibraryScope().getAllDescriptors()) {
|
||||||
|
descriptor.accept(visitor, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ void declareIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||||
|
//TODO: HACK!
|
||||||
|
addCompareToIntrinsics(descriptor);
|
||||||
|
addEqualsIntrinsics(descriptor);
|
||||||
|
addUnaryIntrinsics(descriptor);
|
||||||
|
addBinaryIntrinsics(descriptor);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCompareToIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||||
|
String functionName = descriptor.getName();
|
||||||
|
if (functionName.equals("compareTo")) {
|
||||||
|
descriptorToIntrinsicMap.put(descriptor, PrimitiveCompareToIntrinsic.newInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEqualsIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||||
|
String functionName = descriptor.getName();
|
||||||
|
if (functionName.equals("equals")) {
|
||||||
|
descriptorToIntrinsicMap.put(descriptor, PrimitiveEqualsIntrinsic.newInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addUnaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||||
|
String functionName = descriptor.getName();
|
||||||
|
JetToken token = OperatorConventions.UNARY_OPERATION_NAMES.inverse().get(functionName);
|
||||||
|
if (token != null) {
|
||||||
|
descriptorToIntrinsicMap.put(descriptor, UnaryOperationIntrinsic.newInstance(token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBinaryIntrinsics(@NotNull FunctionDescriptor descriptor) {
|
||||||
|
String functionName = descriptor.getName();
|
||||||
|
JetToken token = OperatorConventions.BINARY_OPERATION_NAMES.inverse().get(functionName);
|
||||||
|
if (token != null && OperatorTable.hasCorrespondingBinaryOperator(token)) {
|
||||||
|
descriptorToIntrinsicMap.put(descriptor, BinaryOperationIntrinsic.newInstance(token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
|
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor.getOriginal();
|
||||||
|
return (descriptorToIntrinsicMap.get(functionDescriptor) != null);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Intrinsic getIntrinsic(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
assert descriptor instanceof FunctionDescriptor;
|
||||||
|
Intrinsic intrinsic = descriptorToIntrinsicMap.get(descriptor);
|
||||||
|
return intrinsic;
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
|
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.general.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class PrimitiveCompareToIntrinsic extends CompareToIntrinsic {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
/*package*/ static PrimitiveCompareToIntrinsic newInstance() {
|
||||||
|
return new PrimitiveCompareToIntrinsic();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression apply(@NotNull 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
|
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.general.TranslationContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class PrimitiveEqualsIntrinsic extends EqualsIntrinsic {
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
/*package*/ static PrimitiveEqualsIntrinsic newInstance() {
|
||||||
|
return new PrimitiveEqualsIntrinsic();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JsExpression apply(@NotNull JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
assert arguments.size() == 1 : "Equals operation should have one argument";
|
||||||
|
if (isNegated()) {
|
||||||
|
return AstUtil.notEqual(receiver, arguments.get(0));
|
||||||
|
} else {
|
||||||
|
return AstUtil.equals(receiver, arguments.get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package org.jetbrains.k2js.translate.intrinsic;
|
||||||
|
|
||||||
|
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.jet.lexer.JetToken;
|
||||||
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.operation.OperatorTable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public class UnaryOperationIntrinsic implements Intrinsic {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
/*package*/ static UnaryOperationIntrinsic newInstance(@NotNull JetToken token) {
|
||||||
|
JsUnaryOperator operator = OperatorTable.getUnaryOperator(token);
|
||||||
|
return new UnaryOperationIntrinsic(operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final JsUnaryOperator operator;
|
||||||
|
|
||||||
|
private UnaryOperationIntrinsic(@NotNull JsUnaryOperator operator) {
|
||||||
|
this.operator = operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JsExpression apply(@NotNull JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
assert arguments.size() == 0 : "Unary operator should not have arguments.";
|
||||||
|
//TODO: note that we cannot use this for increment/decrement
|
||||||
|
return new JsPrefixOperation(operator, receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-15
@@ -4,12 +4,15 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
|
|||||||
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
|
||||||
import org.jetbrains.jet.lexer.JetToken;
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
|
||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
*/
|
*/
|
||||||
@@ -29,26 +32,16 @@ public abstract class BinaryOperationTranslator extends OperationTranslator {
|
|||||||
super(context);
|
super(context);
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
this.isPropertyOnTheLeft = isPropertyAccess(expression.getLeft());
|
this.isPropertyOnTheLeft = isPropertyAccess(expression.getLeft());
|
||||||
this.isVariableReassignment = isVariableReassignment(expression);
|
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
|
||||||
|
|
||||||
this.right = translateRightExpression();
|
this.right = translateRightExpression(context(), expression);
|
||||||
//TODO: decide whether it is harmful to possibly translateNamespace left expression more than once
|
//TODO: decide whether it is harmful to possibly translateNamespace left expression more than once
|
||||||
this.left = translateLeftExpression();
|
this.left = translateLeftExpression(context(), expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
abstract protected JsExpression translate();
|
abstract protected JsExpression translate();
|
||||||
|
|
||||||
private JsExpression translateLeftExpression() {
|
|
||||||
return Translation.translateAsExpression(expression.getLeft(), context());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsExpression translateRightExpression() {
|
|
||||||
JetExpression rightExpression = expression.getRight();
|
|
||||||
assert rightExpression != null : "Binary expression should have a right expression";
|
|
||||||
return Translation.translateAsExpression(rightExpression, context());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected JetToken getOperationToken() {
|
protected JetToken getOperationToken() {
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.jetbrains.k2js.translate.operation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class EqualsTranslator {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
package org.jetbrains.k2js.translate.operation;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||||
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class IntrinsicUnaryOperationTranslator extends UnaryOperationTranslator {
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression translate(@NotNull JetUnaryExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
return (new IntrinsicUnaryOperationTranslator(expression, context))
|
||||||
|
.translate();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntrinsicUnaryOperationTranslator(@NotNull JetUnaryExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
super(expression, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
protected JsExpression translate() {
|
||||||
|
if (isPropertyAccess) {
|
||||||
|
return translateAsMethodCall();
|
||||||
|
}
|
||||||
|
return jsUnaryExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression jsUnaryExpression() {
|
||||||
|
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken());
|
||||||
|
if (isPrefix) {
|
||||||
|
return new JsPrefixOperation(operator, baseExpression);
|
||||||
|
} else {
|
||||||
|
return new JsPostfixOperation(operator, baseExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
protected JsExpression operationExpression(@NotNull JsExpression receiver) {
|
||||||
|
return unaryAsBinary(getOperationToken(), receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsBinaryOperation unaryAsBinary(@NotNull JetToken token, @NotNull JsExpression expression) {
|
||||||
|
JsNumberLiteral oneLiteral = context().program().getNumberLiteral(1);
|
||||||
|
if (token.equals(JetTokens.PLUSPLUS)) {
|
||||||
|
return new JsBinaryOperation(JsBinaryOperator.ADD, expression, oneLiteral);
|
||||||
|
}
|
||||||
|
if (token.equals(JetTokens.MINUSMINUS)) {
|
||||||
|
return new JsBinaryOperation(JsBinaryOperator.SUB, expression, oneLiteral);
|
||||||
|
}
|
||||||
|
throw new AssertionError("This method should be called only for increment and decrement operators");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,14 +9,24 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
import org.jetbrains.jet.lang.psi.JetOperationExpression;
|
||||||
import org.jetbrains.k2js.intrinsic.Intrinsic;
|
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||||
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.intrinsic.CompareToIntrinsic;
|
||||||
|
import org.jetbrains.k2js.translate.intrinsic.EqualsIntrinsic;
|
||||||
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
|
||||||
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
|
import org.jetbrains.k2js.translate.reference.ArrayAccessTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.reference.CallTranslator;
|
||||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
@@ -24,67 +34,92 @@ import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
|||||||
public class OperationTranslator extends AbstractTranslator {
|
public class OperationTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public JsExpression translate(@NotNull JetBinaryExpression expression,
|
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
JsExpression result = tryToApplyIntrinsic(expression, context);
|
//TODO: move to assignment translator
|
||||||
if (result != null) return result;
|
|
||||||
|
|
||||||
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
|
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
|
||||||
return ArrayAccessTranslator.translateAsArraySetterCall(expression, context);
|
return ArrayAccessTranslator.translateAsArraySetterCall(expression, context);
|
||||||
}
|
}
|
||||||
return translateAsBinary(expression, context);
|
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
|
||||||
|
(context.bindingContext(), expression.getOperation());
|
||||||
|
if (descriptorForReferenceExpression == null) {
|
||||||
|
return IntrinsicBinaryOperationTranslator.translate(expression, context);
|
||||||
|
}
|
||||||
|
if (isEqualsCall(expression, context)) {
|
||||||
|
return translateAsEqualsCall(expression, context);
|
||||||
|
}
|
||||||
|
if (isCompareToCall(expression, context)) {
|
||||||
|
return translateAsCompareToCall(expression, context);
|
||||||
|
}
|
||||||
|
return CallTranslator.translate(expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static JsExpression translateAsBinary(@NotNull JetBinaryExpression expression,
|
public static JsExpression translate(@NotNull JetUnaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
if (TranslationUtils.isIntrinsicOperation(context, expression.getOperationReference())) {
|
return CallTranslator.translate(expression, context);
|
||||||
return IntrinsicBinaryOperationTranslator.translate(expression, context);
|
|
||||||
} else {
|
|
||||||
return OverloadedBinaryOperationTranslator.translate(expression, context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static JsExpression tryToApplyIntrinsic(@NotNull JetBinaryExpression expression,
|
public static boolean isEqualsCall(@NotNull JetBinaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
DeclarationDescriptor descriptor = BindingUtils.getDescriptorForReferenceExpression
|
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression, context);
|
||||||
(context.bindingContext(), expression.getOperationReference());
|
//TODO: add descriptor is equals utils
|
||||||
if (descriptor == null) {
|
boolean isEquals = operationDescriptor.getName().equals("equals");
|
||||||
return null;
|
boolean isIntrinsic = context.intrinsics().hasDescriptor(operationDescriptor);
|
||||||
}
|
return isEquals && isIntrinsic;
|
||||||
if (!context.intrinsics().hasDescriptor(descriptor)) {
|
}
|
||||||
return null;
|
|
||||||
}
|
@NotNull
|
||||||
//TODO: should be no nulls here
|
public static JsExpression translateAsEqualsCall(@NotNull JetBinaryExpression expression,
|
||||||
Intrinsic intrinsic = context.intrinsics().getIntrinsic(descriptor);
|
@NotNull TranslationContext context) {
|
||||||
if (intrinsic == null) return null;
|
Intrinsic intrinsic = context.intrinsics().
|
||||||
return intrinsic.apply(expression, context);
|
getIntrinsic(getOperationDescriptor(expression, context));
|
||||||
|
//TODO
|
||||||
|
((EqualsIntrinsic) intrinsic).setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ));
|
||||||
|
return intrinsic.apply(translateLeftExpression(context, expression),
|
||||||
|
Arrays.asList(translateRightExpression(context, expression)), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCompareToCall(@NotNull JetBinaryExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression, context);
|
||||||
|
return (operationDescriptor.getName().equals("compareTo")
|
||||||
|
&& (context.intrinsics().hasDescriptor(operationDescriptor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression translateAsCompareToCall(@NotNull JetBinaryExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
Intrinsic intrinsic = context.intrinsics().
|
||||||
|
getIntrinsic(getOperationDescriptor(expression, context));
|
||||||
|
((CompareToIntrinsic) intrinsic).setComparisonToken((JetToken) expression.getOperationToken());
|
||||||
|
return intrinsic.apply(translateLeftExpression(context, expression),
|
||||||
|
Arrays.asList(translateRightExpression(context, expression)), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected OperationTranslator(@NotNull TranslationContext context) {
|
protected OperationTranslator(@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: refactor
|
||||||
@Nullable
|
@Nullable
|
||||||
protected JsNameRef getOverloadedOperationReference(@NotNull JetSimpleNameExpression operationExpression) {
|
protected static JsNameRef getOverloadedOperationReference(@NotNull JetOperationExpression operationExpression,
|
||||||
DeclarationDescriptor operationDescriptor = getOperationDescriptor(operationExpression);
|
@NotNull TranslationContext context) {
|
||||||
if (operationDescriptor == null) {
|
DeclarationDescriptor operationDescriptor = getOperationDescriptor(operationExpression, context);
|
||||||
|
if (!context.isDeclared(operationDescriptor)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (context().intrinsics().hasDescriptor(operationDescriptor)) {
|
return context.getNameForDescriptor(operationDescriptor).makeRef();
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!context().isDeclared(operationDescriptor)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return context().getNameForDescriptor(operationDescriptor).makeRef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@NotNull
|
||||||
private DeclarationDescriptor getOperationDescriptor(@NotNull JetSimpleNameExpression expression) {
|
private static DeclarationDescriptor getOperationDescriptor(@NotNull JetOperationExpression expression,
|
||||||
return BindingUtils.getDescriptorForReferenceExpression
|
@NotNull TranslationContext context) {
|
||||||
(context().bindingContext(), expression);
|
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
|
||||||
|
(context.bindingContext(), expression.getOperation());
|
||||||
|
assert descriptorForReferenceExpression != null;
|
||||||
|
return descriptorForReferenceExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isPropertyAccess(@NotNull JetExpression expression) {
|
protected boolean isPropertyAccess(@NotNull JetExpression expression) {
|
||||||
@@ -92,12 +127,6 @@ public class OperationTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isVariableReassignment(@NotNull JetExpression expression) {
|
|
||||||
return BindingUtils.isVariableReassignment
|
|
||||||
(context().bindingContext(), expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected final class TemporaryVariable {
|
protected final class TemporaryVariable {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ public final class OverloadedBinaryOperationTranslator extends BinaryOperationTr
|
|||||||
private OverloadedBinaryOperationTranslator(@NotNull JetBinaryExpression expression,
|
private OverloadedBinaryOperationTranslator(@NotNull JetBinaryExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
super(expression, context);
|
super(expression, context);
|
||||||
JsNameRef overloadedOperationReference = getOverloadedOperationReference(expression.getOperationReference());
|
JsNameRef overloadedOperationReference = getOverloadedOperationReference(expression, context);
|
||||||
assert overloadedOperationReference != null;
|
assert overloadedOperationReference != null;
|
||||||
this.operationReference = overloadedOperationReference;
|
this.operationReference = overloadedOperationReference;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package org.jetbrains.k2js.translate.operation;
|
||||||
|
|
||||||
|
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.jet.lang.psi.JetUnaryExpression;
|
||||||
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class OverloadedUnaryOperationTranslator extends UnaryOperationTranslator {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression translate(@NotNull JetUnaryExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
return (new OverloadedUnaryOperationTranslator(expression, context))
|
||||||
|
.translate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final JsNameRef operationReference;
|
||||||
|
|
||||||
|
private OverloadedUnaryOperationTranslator(@NotNull JetUnaryExpression expression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
super(expression, context);
|
||||||
|
this.operationReference = getOverloadedOperationReference(expression, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
protected JsExpression translate() {
|
||||||
|
return translateAsMethodCall();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
protected JsExpression operationExpression(@NotNull JsExpression receiver) {
|
||||||
|
AstUtil.setQualifier(operationReference, receiver);
|
||||||
|
return AstUtil.newInvocation(operationReference);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+31
-80
@@ -1,70 +1,55 @@
|
|||||||
package org.jetbrains.k2js.translate.operation;
|
package org.jetbrains.k2js.translate.operation;
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.JetPrefixExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||||
import org.jetbrains.jet.lexer.JetToken;
|
import org.jetbrains.jet.lexer.JetToken;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
|
||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.getBaseExpression;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateBaseExpression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
*/
|
*/
|
||||||
public final class UnaryOperationTranslator extends OperationTranslator {
|
//TODO: reexamine class, see if can be clearer
|
||||||
|
public abstract class UnaryOperationTranslator extends OperationTranslator {
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static public JsExpression translate(@NotNull JetPrefixExpression expression,
|
|
||||||
@NotNull TranslationContext context) {
|
|
||||||
return (new UnaryOperationTranslator(context, expression, true)).translate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static public JsExpression translate(@NotNull JetPostfixExpression expression,
|
|
||||||
@NotNull TranslationContext context) {
|
|
||||||
return (new UnaryOperationTranslator(context, expression, false)).translate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JetUnaryExpression expression;
|
private final JetUnaryExpression expression;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final JsExpression baseExpression;
|
protected final JsExpression baseExpression;
|
||||||
private final boolean isPrefix;
|
protected final boolean isPrefix;
|
||||||
private final boolean isVariableReassignment;
|
private final boolean isVariableReassignment;
|
||||||
private final boolean isStatement;
|
private final boolean isStatement;
|
||||||
private final boolean isPropertyAccess;
|
protected final boolean isPropertyAccess;
|
||||||
@Nullable
|
|
||||||
private final JsNameRef operationReference;
|
|
||||||
|
|
||||||
private UnaryOperationTranslator(@NotNull TranslationContext context, @NotNull JetUnaryExpression expression,
|
protected UnaryOperationTranslator(@NotNull JetUnaryExpression expression,
|
||||||
boolean isPrefix) {
|
@NotNull TranslationContext context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
this.isPrefix = isPrefix;
|
this.isPrefix = isPrefix(expression);
|
||||||
this.isVariableReassignment = isVariableReassignment(expression);
|
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
|
||||||
this.isStatement = BindingUtils.isStatement(context().bindingContext(), expression);
|
this.isStatement = BindingUtils.isStatement(context().bindingContext(), expression);
|
||||||
this.baseExpression = translateBaseExpression();
|
this.baseExpression = translateBaseExpression(context, expression);
|
||||||
this.isPropertyAccess = isPropertyAccess(getBaseExpression());
|
this.isPropertyAccess = isPropertyAccess(getBaseExpression(expression));
|
||||||
this.operationReference = getOverloadedOperationReference(expression.getOperationSign());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
JsExpression translate() {
|
protected abstract JsExpression translate();
|
||||||
if ((operationReference != null) || isPropertyAccess) {
|
|
||||||
return translateOverload();
|
|
||||||
}
|
|
||||||
return jsUnaryExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression translateOverload() {
|
protected JsExpression translateAsMethodCall() {
|
||||||
if (isStatement || isPrefix) {
|
if (isStatement || isPrefix) {
|
||||||
return asPrefix();
|
return asPrefix();
|
||||||
}
|
}
|
||||||
@@ -99,7 +84,6 @@ public final class UnaryOperationTranslator extends OperationTranslator {
|
|||||||
private JsExpression asPostfixWithNoReassignment() {
|
private JsExpression asPostfixWithNoReassignment() {
|
||||||
// code fragment: expr(a++)
|
// code fragment: expr(a++)
|
||||||
// generate: expr( (t1 = a, t2 = t1, t2.inc(), t1) )
|
// generate: expr( (t1 = a, t2 = t1, t2.inc(), t1) )
|
||||||
assert operationReference != null;
|
|
||||||
TemporaryVariable t1 = declareTemporary(baseExpression);
|
TemporaryVariable t1 = declareTemporary(baseExpression);
|
||||||
TemporaryVariable t2 = declareTemporary(t1.nameReference());
|
TemporaryVariable t2 = declareTemporary(t1.nameReference());
|
||||||
JsExpression methodCall = operationExpression(t2.nameReference());
|
JsExpression methodCall = operationExpression(t2.nameReference());
|
||||||
@@ -122,7 +106,7 @@ public final class UnaryOperationTranslator extends OperationTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression propertyReassignment(@NotNull JsExpression toCallMethodUpon) {
|
private JsExpression propertyReassignment(@NotNull JsExpression toCallMethodUpon) {
|
||||||
JetExpression jetBaseExpression = getBaseExpression();
|
JetExpression jetBaseExpression = getBaseExpression(expression);
|
||||||
JsInvocation setterCall =
|
JsInvocation setterCall =
|
||||||
PropertyAccessTranslator.translateAsPropertySetterCall(jetBaseExpression, context());
|
PropertyAccessTranslator.translateAsPropertySetterCall(jetBaseExpression, context());
|
||||||
assert PropertyAccessTranslator.canBePropertyGetterCall(jetBaseExpression, context()) : "Should be a getter call";
|
assert PropertyAccessTranslator.canBePropertyGetterCall(jetBaseExpression, context()) : "Should be a getter call";
|
||||||
@@ -132,52 +116,19 @@ public final class UnaryOperationTranslator extends OperationTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression operationExpression(@NotNull JsExpression receiver) {
|
abstract JsExpression operationExpression(@NotNull JsExpression receiver);
|
||||||
if (operationReference != null) {
|
|
||||||
AstUtil.setQualifier(operationReference, receiver);
|
|
||||||
return AstUtil.newInvocation(operationReference);
|
|
||||||
}
|
|
||||||
return unaryAsBinary(getOperationToken(), receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression jsUnaryExpression() {
|
protected JetToken getOperationToken() {
|
||||||
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken());
|
JetSimpleNameExpression operationExpression = expression.getOperation();
|
||||||
if (isPrefix) {
|
|
||||||
return new JsPrefixOperation(operator, baseExpression);
|
|
||||||
} else {
|
|
||||||
return new JsPostfixOperation(operator, baseExpression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsExpression translateBaseExpression() {
|
|
||||||
JetExpression baseExpression = getBaseExpression();
|
|
||||||
return Translation.translateAsExpression(baseExpression, context());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JetExpression getBaseExpression() {
|
|
||||||
JetExpression baseExpression = expression.getBaseExpression();
|
|
||||||
assert baseExpression != null : "Unary expression should have a base expression";
|
|
||||||
return baseExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JetToken getOperationToken() {
|
|
||||||
JetSimpleNameExpression operationExpression = expression.getOperationSign();
|
|
||||||
IElementType elementType = operationExpression.getReferencedNameElementType();
|
IElementType elementType = operationExpression.getReferencedNameElementType();
|
||||||
assert elementType instanceof JetToken : "Unary expression should have IElementType of type JetToken";
|
assert elementType instanceof JetToken : "Unary expression should have IElementType of type JetToken";
|
||||||
return (JetToken) elementType;
|
return (JetToken) elementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsBinaryOperation unaryAsBinary(@NotNull JetToken token, @NotNull JsExpression expression) {
|
private boolean isPrefix(JetUnaryExpression expression) {
|
||||||
JsNumberLiteral oneLiteral = context().program().getNumberLiteral(1);
|
return (expression instanceof JetPrefixExpression);
|
||||||
if (token.equals(JetTokens.PLUSPLUS)) {
|
|
||||||
return new JsBinaryOperation(JsBinaryOperator.ADD, expression, oneLiteral);
|
|
||||||
}
|
|
||||||
if (token.equals(JetTokens.MINUSMINUS)) {
|
|
||||||
return new JsBinaryOperation(JsBinaryOperator.SUB, expression, oneLiteral);
|
|
||||||
}
|
|
||||||
throw new AssertionError("This method should be called only for increment and decrement operators");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package org.jetbrains.k2js.translate.reference;
|
||||||
|
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsNew;
|
||||||
|
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.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
import org.jetbrains.k2js.translate.intrinsic.Intrinsic;
|
||||||
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForCallExpression;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Talanov Pavel
|
||||||
|
*/
|
||||||
|
public final class CallTranslator extends AbstractTranslator {
|
||||||
|
|
||||||
|
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);
|
||||||
|
List<JsExpression> arguments = Collections.emptyList();
|
||||||
|
DeclarationDescriptor descriptor = getDescriptorForReferenceExpression
|
||||||
|
(context.bindingContext(), unaryExpression.getOperation());
|
||||||
|
assert descriptor instanceof FunctionDescriptor;
|
||||||
|
return (new CallTranslator(receiver, arguments, (FunctionDescriptor) descriptor, context)).translate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsExpression translate(@NotNull JetDotQualifiedExpression dotExpression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
//TODO: look for duplication
|
||||||
|
JsExpression receiver = translateReceiver(context, dotExpression);
|
||||||
|
JetExpression selectorExpression = dotExpression.getSelectorExpression();
|
||||||
|
assert selectorExpression instanceof JetCallExpression;
|
||||||
|
JetCallExpression callExpression = (JetCallExpression) selectorExpression;
|
||||||
|
List<JsExpression> arguments =
|
||||||
|
translateArgumentList(context, callExpression.getValueArguments());
|
||||||
|
FunctionDescriptor descriptor =
|
||||||
|
getFunctionDescriptorForCallExpression(context.bindingContext(), callExpression);
|
||||||
|
return (new CallTranslator(receiver, arguments, descriptor, context)).translate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsExpression translate(@NotNull JetCallExpression callExpression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
DeclarationDescriptor descriptor =
|
||||||
|
getFunctionDescriptorForCallExpression(context.bindingContext(), callExpression);
|
||||||
|
JsExpression receiver = ReferenceTranslator.getImplicitReceiver(descriptor, context);
|
||||||
|
List<JsExpression> arguments = translateArgumentList(context, callExpression.getValueArguments());
|
||||||
|
return (new CallTranslator(receiver, arguments, (FunctionDescriptor) descriptor, context)).translate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsExpression translate(@NotNull JetBinaryExpression binaryExpression,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
JsExpression receiver = translateLeftExpression(context, binaryExpression);
|
||||||
|
List<JsExpression> arguments = Arrays.asList(translateRightExpression(context, binaryExpression));
|
||||||
|
//TODO: use PSI util method to get operation reference
|
||||||
|
DeclarationDescriptor descriptor = getDescriptorForReferenceExpression
|
||||||
|
(context.bindingContext(), binaryExpression.getOperation());
|
||||||
|
assert descriptor instanceof FunctionDescriptor;
|
||||||
|
return (new CallTranslator(receiver, arguments, (FunctionDescriptor) descriptor, context)).translate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final JsExpression receiver;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final List<JsExpression> arguments;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final FunctionDescriptor descriptor;
|
||||||
|
|
||||||
|
private CallTranslator(@Nullable JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||||
|
@NotNull FunctionDescriptor descriptor, @NotNull TranslationContext context) {
|
||||||
|
super(context);
|
||||||
|
this.receiver = receiver;
|
||||||
|
this.arguments = arguments;
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression translate() {
|
||||||
|
if (context().intrinsics().hasDescriptor(descriptor)) {
|
||||||
|
Intrinsic intrinsic = context().intrinsics().getIntrinsic(descriptor);
|
||||||
|
assert receiver != null : "Functions that have intrinsic implementation should have a receiver.";
|
||||||
|
return intrinsic.apply(receiver, arguments, context());
|
||||||
|
}
|
||||||
|
if (isConstructorDescriptor(descriptor)) {
|
||||||
|
return constructorCall();
|
||||||
|
}
|
||||||
|
return AstUtil.newInvocation(qualifiedMethodReference(), arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsNameRef qualifiedMethodReference() {
|
||||||
|
JsName methodName = context().getNameForDescriptor(descriptor);
|
||||||
|
if (receiver != null) {
|
||||||
|
return AstUtil.qualified(methodName, receiver);
|
||||||
|
}
|
||||||
|
return methodName.makeRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsExpression constructorCall() {
|
||||||
|
JsNew constructorCall = new JsNew(qualifiedMethodReference());
|
||||||
|
constructorCall.setArguments(arguments);
|
||||||
|
return constructorCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
// //TODO: delete?
|
||||||
|
// @NotNull
|
||||||
|
// private JsExpression translateCallee(@NotNull JetCallExpression expression) {
|
||||||
|
// JetExpression callee = expression.getCalleeExpression();
|
||||||
|
// assert callee != null : "Call expression with no callee encountered!";
|
||||||
|
// return Translation.translateAsExpression(callee, context);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+3
-13
@@ -18,7 +18,6 @@ import org.jetbrains.k2js.translate.general.Translation;
|
|||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.PsiUtils;
|
import org.jetbrains.k2js.translate.utils.PsiUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Talanov Pavel
|
* @author Talanov Pavel
|
||||||
@@ -147,17 +146,6 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
|||||||
return AstUtil.newInvocation(accessorReference);
|
return AstUtil.newInvocation(accessorReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsExpression defaultQualifier() {
|
|
||||||
if (BindingUtils.isOwnedByClass(propertyDescriptor)) {
|
|
||||||
return TranslationUtils.getThisQualifier(context());
|
|
||||||
}
|
|
||||||
assert BindingUtils.isOwnedByNamespace(propertyDescriptor)
|
|
||||||
: "Property can be a member of class or a namespace.";
|
|
||||||
//NOTE: qualifier for descriptor and it's accessor should be equal
|
|
||||||
return context().declarations().getQualifier(propertyDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public JsInvocation translateAsPropertySetterCall() {
|
public JsInvocation translateAsPropertySetterCall() {
|
||||||
JsName setterName = getNotNullSetterName();
|
JsName setterName = getNotNullSetterName();
|
||||||
@@ -169,7 +157,9 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
|||||||
if (qualifier != null) {
|
if (qualifier != null) {
|
||||||
return Translation.translateAsExpression(qualifier, context());
|
return Translation.translateAsExpression(qualifier, context());
|
||||||
}
|
}
|
||||||
return defaultQualifier();
|
JsExpression implicitReceiver = ReferenceTranslator.getImplicitReceiver(propertyDescriptor, context());
|
||||||
|
assert implicitReceiver != null : "Property can only be a member of class or a namespace.";
|
||||||
|
return implicitReceiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package org.jetbrains.k2js.translate.reference;
|
|||||||
|
|
||||||
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.JsName;
|
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||||
|
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.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||||
@@ -38,10 +38,9 @@ public class ReferenceTranslator extends AbstractTranslator {
|
|||||||
@NotNull
|
@NotNull
|
||||||
//TODO: make this process simpler and clearer
|
//TODO: make this process simpler and clearer
|
||||||
public JsExpression translateSimpleName() {
|
public JsExpression translateSimpleName() {
|
||||||
tryResolveAsPropertyAccess();
|
|
||||||
tryResolveAsThisQualifiedExpression();
|
|
||||||
tryResolveAsAliasReference();
|
tryResolveAsAliasReference();
|
||||||
tryResolveAsGlobalReference();
|
tryResolveAsPropertyAccess();
|
||||||
|
tryResolveAsImplicitlyQualifiedExpression();
|
||||||
tryResolveAsLocalReference();
|
tryResolveAsLocalReference();
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
return result;
|
return result;
|
||||||
@@ -49,7 +48,8 @@ public class ReferenceTranslator extends AbstractTranslator {
|
|||||||
throw new AssertionError("Undefined name in this scope: " + simpleName.getReferencedName());
|
throw new AssertionError("Undefined name in this scope: " + simpleName.getReferencedName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryResolveAsThisQualifiedExpression() {
|
//TODO: refactor
|
||||||
|
private void tryResolveAsImplicitlyQualifiedExpression() {
|
||||||
if (alreadyResolved()) return;
|
if (alreadyResolved()) return;
|
||||||
|
|
||||||
DeclarationDescriptor referencedDescriptor =
|
DeclarationDescriptor referencedDescriptor =
|
||||||
@@ -59,24 +59,24 @@ public class ReferenceTranslator extends AbstractTranslator {
|
|||||||
if (!context().isDeclared(referencedDescriptor)) return;
|
if (!context().isDeclared(referencedDescriptor)) return;
|
||||||
|
|
||||||
JsName referencedName = context().getNameForDescriptor(referencedDescriptor);
|
JsName referencedName = context().getNameForDescriptor(referencedDescriptor);
|
||||||
|
JsExpression implicitReceiver = getImplicitReceiver(referencedDescriptor, context());
|
||||||
|
|
||||||
if (!requiresThisQualifier(simpleName, referencedName)) return;
|
if (implicitReceiver == null) return;
|
||||||
|
|
||||||
if (BindingUtils.isOwnedByClass(referencedDescriptor)) {
|
result = AstUtil.qualified(referencedName, implicitReceiver);
|
||||||
result = TranslationUtils.getThisQualifiedNameReference(context(), referencedName);
|
|
||||||
}
|
|
||||||
if (BindingUtils.isOwnedByNamespace(referencedDescriptor)) {
|
|
||||||
result = TranslationUtils.getQualifiedReference(context(), referencedDescriptor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean requiresThisQualifier(@NotNull JetSimpleNameExpression expression,
|
@Nullable
|
||||||
@NotNull JsName referencedName) {
|
public static JsExpression getImplicitReceiver(@NotNull DeclarationDescriptor referencedDescriptor,
|
||||||
|
@NotNull TranslationContext context) {
|
||||||
|
if (!context.isDeclared(referencedDescriptor)) return null;
|
||||||
|
|
||||||
JsName name = context().enclosingScope().findExistingName(referencedName.getIdent());
|
if (BindingUtils.isOwnedByClass(referencedDescriptor)) {
|
||||||
boolean isClassMember = context().classScope().ownsName(name);
|
return TranslationUtils.getThisQualifier(context);
|
||||||
boolean isBackingFieldAccess = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
|
}
|
||||||
return (isBackingFieldAccess || isClassMember);
|
if (!BindingUtils.isOwnedByNamespace(referencedDescriptor)) return null;
|
||||||
|
|
||||||
|
return context.declarations().getQualifier(referencedDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryResolveAsAliasReference() {
|
private void tryResolveAsAliasReference() {
|
||||||
@@ -104,18 +104,6 @@ public class ReferenceTranslator extends AbstractTranslator {
|
|||||||
result = PropertyAccessTranslator.translateAsPropertyGetterCall(simpleName, context());
|
result = PropertyAccessTranslator.translateAsPropertyGetterCall(simpleName, context());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryResolveAsGlobalReference() {
|
|
||||||
if (alreadyResolved()) return;
|
|
||||||
|
|
||||||
DeclarationDescriptor referencedDescriptor =
|
|
||||||
BindingUtils.getDescriptorForReferenceExpression(context().bindingContext(), simpleName);
|
|
||||||
|
|
||||||
if (referencedDescriptor == null) return;
|
|
||||||
if (!context().isDeclared(referencedDescriptor)) return;
|
|
||||||
|
|
||||||
result = TranslationUtils.getQualifiedReference(context(), referencedDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryResolveAsLocalReference() {
|
private void tryResolveAsLocalReference() {
|
||||||
if (alreadyResolved()) return;
|
if (alreadyResolved()) return;
|
||||||
|
|
||||||
|
|||||||
@@ -36,37 +36,37 @@ public final class BindingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public ClassDescriptor getClassDescriptor(@NotNull BindingContext context, @NotNull JetClass declaration) {
|
public static ClassDescriptor getClassDescriptor(@NotNull BindingContext context, @NotNull JetClass declaration) {
|
||||||
return getDescriptorForExpression(context, declaration, ClassDescriptor.class);
|
return getDescriptorForExpression(context, declaration, ClassDescriptor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context,
|
public static NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull JetNamespace declaration) {
|
@NotNull JetNamespace declaration) {
|
||||||
return getDescriptorForExpression(context, declaration, NamespaceDescriptor.class);
|
return getDescriptorForExpression(context, declaration, NamespaceDescriptor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context,
|
public static FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull JetNamedFunction declaration) {
|
@NotNull JetNamedFunction declaration) {
|
||||||
return getDescriptorForExpression(context, declaration, FunctionDescriptor.class);
|
return getDescriptorForExpression(context, declaration, FunctionDescriptor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public PropertyAccessorDescriptor getPropertyAccessorDescriptor(@NotNull BindingContext context,
|
public static PropertyAccessorDescriptor getPropertyAccessorDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull JetPropertyAccessor declaration) {
|
@NotNull JetPropertyAccessor declaration) {
|
||||||
return getDescriptorForExpression(context, declaration, PropertyAccessorDescriptor.class);
|
return getDescriptorForExpression(context, declaration, PropertyAccessorDescriptor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context,
|
public static PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull JetProperty declaration) {
|
@NotNull JetProperty declaration) {
|
||||||
return getDescriptorForExpression(context, declaration, PropertyDescriptor.class);
|
return getDescriptorForExpression(context, declaration, PropertyDescriptor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: possibly remove
|
//TODO: possibly remove
|
||||||
// @NotNull
|
// @NotNull
|
||||||
// static public PropertySetterDescriptor getPropertySetterDescriptorForProperty(@NotNull BindingContext context,
|
// public static PropertySetterDescriptor getPropertySetterDescriptorForProperty(@NotNull BindingContext context,
|
||||||
// @NotNull JetProperty property) {
|
// @NotNull JetProperty property) {
|
||||||
// PropertySetterDescriptor result = getPropertyDescriptor(context, property).getSetter();
|
// PropertySetterDescriptor result = getPropertyDescriptor(context, property).getSetter();
|
||||||
// assert result != null : "Property should have a setter descriptor";
|
// assert result != null : "Property should have a setter descriptor";
|
||||||
@@ -74,7 +74,7 @@ public final class BindingUtils {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @NotNull
|
// @NotNull
|
||||||
// static public PropertyGetterDescriptor getPropertyGetterDescriptorForProperty(@NotNull BindingContext context,
|
// public static PropertyGetterDescriptor getPropertyGetterDescriptorForProperty(@NotNull BindingContext context,
|
||||||
// @NotNull JetProperty property) {
|
// @NotNull JetProperty property) {
|
||||||
// PropertyGetterDescriptor result = getPropertyDescriptor(context, property).getGetter();
|
// PropertyGetterDescriptor result = getPropertyDescriptor(context, property).getGetter();
|
||||||
// assert result != null : "Property should have a getter descriptor";
|
// assert result != null : "Property should have a getter descriptor";
|
||||||
@@ -82,7 +82,7 @@ public final class BindingUtils {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public JetClass getClassForDescriptor(@NotNull BindingContext context,
|
public static JetClass getClassForDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull ClassDescriptor descriptor) {
|
@NotNull ClassDescriptor descriptor) {
|
||||||
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||||
assert result instanceof JetClass : "ClassDescriptor should have declaration of type JetClass";
|
assert result instanceof JetClass : "ClassDescriptor should have declaration of type JetClass";
|
||||||
@@ -91,7 +91,7 @@ public final class BindingUtils {
|
|||||||
|
|
||||||
//TODO: delete?
|
//TODO: delete?
|
||||||
@Nullable
|
@Nullable
|
||||||
static public JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context,
|
public static JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull DeclarationDescriptor descriptor) {
|
@NotNull DeclarationDescriptor descriptor) {
|
||||||
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||||
if (!(result instanceof JetDeclaration)) {
|
if (!(result instanceof JetDeclaration)) {
|
||||||
@@ -101,14 +101,14 @@ public final class BindingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public List<ClassDescriptor> getSuperclassDescriptors(@NotNull BindingContext context,
|
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull BindingContext context,
|
||||||
@NotNull JetClass classDeclaration) {
|
@NotNull JetClass classDeclaration) {
|
||||||
ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration);
|
ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration);
|
||||||
return getSuperclassDescriptors(classDescriptor);
|
return getSuperclassDescriptors(classDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
|
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
|
||||||
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
|
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
|
||||||
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
|
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
|
||||||
for (JetType type : superclassTypes) {
|
for (JetType type : superclassTypes) {
|
||||||
@@ -121,7 +121,7 @@ public final class BindingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
|
public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
|
||||||
DeclarationDescriptor superClassDescriptor =
|
DeclarationDescriptor superClassDescriptor =
|
||||||
type.getConstructor().getDeclarationDescriptor();
|
type.getConstructor().getDeclarationDescriptor();
|
||||||
assert superClassDescriptor instanceof ClassDescriptor
|
assert superClassDescriptor instanceof ClassDescriptor
|
||||||
@@ -129,19 +129,19 @@ public final class BindingUtils {
|
|||||||
return (ClassDescriptor) superClassDescriptor;
|
return (ClassDescriptor) superClassDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClass classDeclaration) {
|
public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClass classDeclaration) {
|
||||||
List<ClassDescriptor> superclassDescriptors = getSuperclassDescriptors(context, classDeclaration);
|
List<ClassDescriptor> superclassDescriptors = getSuperclassDescriptors(context, classDeclaration);
|
||||||
return (findAncestorClass(superclassDescriptors) != null);
|
return (findAncestorClass(superclassDescriptors) != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean isStatement(@NotNull BindingContext context, @NotNull JetExpression expression) {
|
public static boolean isStatement(@NotNull BindingContext context, @NotNull JetExpression expression) {
|
||||||
Boolean isStatement = context.get(BindingContext.STATEMENT, expression);
|
Boolean isStatement = context.get(BindingContext.STATEMENT, expression);
|
||||||
assert isStatement != null : "Invalid behaviour of get(BindingContext.STATEMENT)";
|
assert isStatement != null : "Invalid behaviour of get(BindingContext.STATEMENT)";
|
||||||
return isStatement;
|
return isStatement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public JetType getTypeByReference(@NotNull BindingContext context,
|
public static JetType getTypeByReference(@NotNull BindingContext context,
|
||||||
@NotNull JetTypeReference typeReference) {
|
@NotNull JetTypeReference typeReference) {
|
||||||
JetType result = context.get(BindingContext.TYPE, typeReference);
|
JetType result = context.get(BindingContext.TYPE, typeReference);
|
||||||
assert result != null : "TypeReference should reference a type";
|
assert result != null : "TypeReference should reference a type";
|
||||||
@@ -149,19 +149,19 @@ public final class BindingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
static public ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
|
public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
|
||||||
@NotNull JetTypeReference typeReference) {
|
@NotNull JetTypeReference typeReference) {
|
||||||
return getClassDescriptorForType(getTypeByReference(context, typeReference));
|
return getClassDescriptorForType(getTypeByReference(context, typeReference));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static public PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context,
|
public static PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context,
|
||||||
@NotNull JetParameter parameter) {
|
@NotNull JetParameter parameter) {
|
||||||
return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
|
return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static public JetProperty getPropertyForDescriptor(@NotNull BindingContext context,
|
public static JetProperty getPropertyForDescriptor(@NotNull BindingContext context,
|
||||||
@NotNull PropertyDescriptor property) {
|
@NotNull PropertyDescriptor property) {
|
||||||
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, property);
|
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, property);
|
||||||
if (!(result instanceof JetProperty)) {
|
if (!(result instanceof JetProperty)) {
|
||||||
@@ -171,7 +171,7 @@ public final class BindingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static public DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context,
|
public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context,
|
||||||
@NotNull JetReferenceExpression reference) {
|
@NotNull JetReferenceExpression reference) {
|
||||||
return context.get(BindingContext.REFERENCE_TARGET, reference);
|
return context.get(BindingContext.REFERENCE_TARGET, reference);
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ public final class BindingUtils {
|
|||||||
|
|
||||||
//TODO move unrelated utils to other class
|
//TODO move unrelated utils to other class
|
||||||
@Nullable
|
@Nullable
|
||||||
static public ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||||
for (ClassDescriptor descriptor : superclassDescriptors) {
|
for (ClassDescriptor descriptor : superclassDescriptors) {
|
||||||
if (descriptor.getKind() == ClassKind.CLASS) {
|
if (descriptor.getKind() == ClassKind.CLASS) {
|
||||||
return descriptor;
|
return descriptor;
|
||||||
@@ -191,11 +191,11 @@ public final class BindingUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean isOwnedByNamespace(@NotNull DeclarationDescriptor descriptor) {
|
public static boolean isOwnedByNamespace(@NotNull DeclarationDescriptor descriptor) {
|
||||||
return (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor);
|
return (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean isOwnedByClass(@NotNull DeclarationDescriptor descriptor) {
|
public static boolean isOwnedByClass(@NotNull DeclarationDescriptor descriptor) {
|
||||||
return (descriptor.getContainingDeclaration() instanceof ClassDescriptor);
|
return (descriptor.getContainingDeclaration() instanceof ClassDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,31 +204,44 @@ public final class BindingUtils {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static PropertyDescriptor getPropertyDescriptorForSimpleName(@NotNull BindingContext context,
|
public static PropertyDescriptor getPropertyDescriptorForSimpleName(@NotNull BindingContext context,
|
||||||
@NotNull JetSimpleNameExpression expression) {
|
@NotNull JetSimpleNameExpression expression) {
|
||||||
ResolvedCall<?> resolvedCall =
|
ResolvedCall<?> resolvedCall = BindingUtils.getResolvedCall(context, expression);
|
||||||
BindingUtils.getResolvedCall(context, expression);
|
if (resolvedCall == null) return null;
|
||||||
if (resolvedCall != null) {
|
|
||||||
DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor();
|
DeclarationDescriptor descriptor = resolvedCall.getCandidateDescriptor();
|
||||||
if (descriptor instanceof PropertyDescriptor) {
|
if (descriptor instanceof PropertyDescriptor) {
|
||||||
return (PropertyDescriptor) descriptor;
|
return (PropertyDescriptor) descriptor;
|
||||||
}
|
}
|
||||||
if (descriptor instanceof VariableAsFunctionDescriptor) {
|
if (descriptor instanceof VariableAsFunctionDescriptor) {
|
||||||
VariableAsFunctionDescriptor functionVariable = (VariableAsFunctionDescriptor) descriptor;
|
VariableAsFunctionDescriptor functionVariable = (VariableAsFunctionDescriptor) descriptor;
|
||||||
VariableDescriptor variableDescriptor = functionVariable.getVariableDescriptor();
|
VariableDescriptor variableDescriptor = functionVariable.getVariableDescriptor();
|
||||||
if (variableDescriptor instanceof PropertyDescriptor) {
|
if (variableDescriptor instanceof PropertyDescriptor) {
|
||||||
return (PropertyDescriptor) variableDescriptor;
|
return (PropertyDescriptor) variableDescriptor;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static public ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
|
public static ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
|
||||||
@NotNull JetExpression expression) {
|
@NotNull JetExpression expression) {
|
||||||
return (context.get(BindingContext.RESOLVED_CALL, expression));
|
return (context.get(BindingContext.RESOLVED_CALL, expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
static public boolean isVariableReassignment(@NotNull BindingContext context, @NotNull JetExpression expression) {
|
@NotNull
|
||||||
|
public static FunctionDescriptor getFunctionDescriptorForCallExpression(@NotNull BindingContext context,
|
||||||
|
@NotNull JetCallExpression expression) {
|
||||||
|
//TODO: move to PSI utils
|
||||||
|
JetExpression calleeExpression = expression.getCalleeExpression();
|
||||||
|
assert calleeExpression != null;
|
||||||
|
ResolvedCall<?> resolvedCall = getResolvedCall(context, calleeExpression);
|
||||||
|
//TODO
|
||||||
|
CallableDescriptor descriptor = resolvedCall.getCandidateDescriptor();
|
||||||
|
assert descriptor instanceof FunctionDescriptor :
|
||||||
|
"Callee expression must have resolved call with descriptor of type FunctionDescriptor";
|
||||||
|
return (FunctionDescriptor) descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isVariableReassignment(@NotNull BindingContext context, @NotNull JetExpression expression) {
|
||||||
Boolean result = context.get(BindingContext.VARIABLE_REASSIGNMENT, expression);
|
Boolean result = context.get(BindingContext.VARIABLE_REASSIGNMENT, expression);
|
||||||
assert result != null;
|
assert result != null;
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ import com.google.dart.compiler.backend.js.ast.*;
|
|||||||
import com.google.dart.compiler.util.AstUtil;
|
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.descriptors.CallableDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||||
|
|
||||||
@@ -43,8 +42,8 @@ public final class TranslationUtils {
|
|||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<JsExpression> translateArgumentList(@NotNull List<? extends ValueArgument> jetArguments,
|
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull List<? extends ValueArgument> jetArguments) {
|
||||||
List<JsExpression> jsArguments = new ArrayList<JsExpression>();
|
List<JsExpression> jsArguments = new ArrayList<JsExpression>();
|
||||||
for (ValueArgument argument : jetArguments) {
|
for (ValueArgument argument : jetArguments) {
|
||||||
jsArguments.add(translateArgument(context, argument));
|
jsArguments.add(translateArgument(context, argument));
|
||||||
@@ -102,15 +101,8 @@ public final class TranslationUtils {
|
|||||||
return jsInitExpression;
|
return jsInitExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isConstructorInvocation(@NotNull TranslationContext context,
|
//TODO: move to descriptor UTILS
|
||||||
@NotNull JetCallExpression expression) {
|
public static boolean isConstructorDescriptor(@NotNull FunctionDescriptor descriptor) {
|
||||||
JetExpression calleeExpression = expression.getCalleeExpression();
|
|
||||||
assert calleeExpression != null : "JetCallExpression should have not null callee";
|
|
||||||
ResolvedCall<?> resolvedCall = BindingUtils.getResolvedCall(context.bindingContext(), calleeExpression);
|
|
||||||
if (resolvedCall == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CallableDescriptor descriptor = resolvedCall.getCandidateDescriptor();
|
|
||||||
return (descriptor instanceof ConstructorDescriptor);
|
return (descriptor instanceof ConstructorDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,4 +176,42 @@ public final class TranslationUtils {
|
|||||||
|
|
||||||
return (context.intrinsics().hasDescriptor(descriptor));
|
return (context.intrinsics().hasDescriptor(descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression translateBaseExpression(@NotNull TranslationContext context,
|
||||||
|
@NotNull JetUnaryExpression expression) {
|
||||||
|
JetExpression baseExpression = getBaseExpression(expression);
|
||||||
|
return Translation.translateAsExpression(baseExpression, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: move to psi utils
|
||||||
|
@NotNull
|
||||||
|
public static JetExpression getBaseExpression(@NotNull JetUnaryExpression expression) {
|
||||||
|
JetExpression baseExpression = expression.getBaseExpression();
|
||||||
|
assert baseExpression != null : "Unary expression should have a base expression";
|
||||||
|
return baseExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression translateReceiver(@NotNull TranslationContext context,
|
||||||
|
@NotNull JetDotQualifiedExpression expression) {
|
||||||
|
return Translation.translateAsExpression(expression.getReceiverExpression(), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression translateLeftExpression(@NotNull TranslationContext context,
|
||||||
|
@NotNull JetBinaryExpression expression) {
|
||||||
|
return Translation.translateAsExpression(expression.getLeft(), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JsExpression translateRightExpression(@NotNull TranslationContext context,
|
||||||
|
@NotNull JetBinaryExpression expression) {
|
||||||
|
JetExpression rightExpression = expression.getRight();
|
||||||
|
assert rightExpression != null : "Binary expression should have a right expression";
|
||||||
|
return Translation.translateAsExpression(rightExpression, context);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user