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");
|
||||
}
|
||||
|
||||
//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) {
|
||||
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.UnaryOperationTranslator;
|
||||
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.ReferenceTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
@@ -108,24 +109,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitCallExpression(JetCallExpression expression, TranslationContext context) {
|
||||
JsExpression callee = translateCallee(expression, context);
|
||||
List<JsExpression> arguments = translateArgumentList(expression.getValueArguments(), 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);
|
||||
public JsNode visitCallExpression(@NotNull JetCallExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return CallTranslator.translate(expression, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
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;
|
||||
|
||||
public class StaticContext {
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
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.Namer;
|
||||
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ public final class ClassInitializerTranslator extends AbstractInitializerTransla
|
||||
|
||||
@NotNull
|
||||
private List<JsExpression> translateArguments(@NotNull JetDelegatorToSuperCall superCall) {
|
||||
return TranslationUtils.translateArgumentList(superCall.getValueArguments(), context());
|
||||
return TranslationUtils.translateArgumentList(context(), superCall.getValueArguments());
|
||||
}
|
||||
|
||||
@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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
*/
|
||||
public interface Intrinsic {
|
||||
|
||||
@NotNull
|
||||
public JsExpression apply(@NotNull JetExpression expression,
|
||||
public JsExpression apply(@NotNull JsExpression receiver, @NotNull List<JsExpression> arguments,
|
||||
@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.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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
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.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
|
||||
*/
|
||||
@@ -29,26 +32,16 @@ public abstract class BinaryOperationTranslator extends OperationTranslator {
|
||||
super(context);
|
||||
this.expression = expression;
|
||||
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
|
||||
this.left = translateLeftExpression();
|
||||
this.left = translateLeftExpression(context(), expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
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
|
||||
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.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.k2js.intrinsic.Intrinsic;
|
||||
import org.jetbrains.jet.lang.psi.JetOperationExpression;
|
||||
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.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.CallTranslator;
|
||||
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
|
||||
@@ -24,67 +34,92 @@ import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
public class OperationTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
static public JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||
public static JsExpression translate(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
JsExpression result = tryToApplyIntrinsic(expression, context);
|
||||
if (result != null) return result;
|
||||
|
||||
//TODO: move to assignment translator
|
||||
if (ArrayAccessTranslator.canBeArraySetterCall(expression)) {
|
||||
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
|
||||
private static JsExpression translateAsBinary(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
if (TranslationUtils.isIntrinsicOperation(context, expression.getOperationReference())) {
|
||||
return IntrinsicBinaryOperationTranslator.translate(expression, context);
|
||||
} else {
|
||||
return OverloadedBinaryOperationTranslator.translate(expression, context);
|
||||
}
|
||||
public static JsExpression translate(@NotNull JetUnaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return CallTranslator.translate(expression, context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static JsExpression tryToApplyIntrinsic(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
DeclarationDescriptor descriptor = BindingUtils.getDescriptorForReferenceExpression
|
||||
(context.bindingContext(), expression.getOperationReference());
|
||||
if (descriptor == null) {
|
||||
return null;
|
||||
}
|
||||
if (!context.intrinsics().hasDescriptor(descriptor)) {
|
||||
return null;
|
||||
}
|
||||
//TODO: should be no nulls here
|
||||
Intrinsic intrinsic = context.intrinsics().getIntrinsic(descriptor);
|
||||
if (intrinsic == null) return null;
|
||||
return intrinsic.apply(expression, context);
|
||||
|
||||
public static boolean isEqualsCall(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
DeclarationDescriptor operationDescriptor = getOperationDescriptor(expression, context);
|
||||
//TODO: add descriptor is equals utils
|
||||
boolean isEquals = operationDescriptor.getName().equals("equals");
|
||||
boolean isIntrinsic = context.intrinsics().hasDescriptor(operationDescriptor);
|
||||
return isEquals && isIntrinsic;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateAsEqualsCall(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
Intrinsic intrinsic = context.intrinsics().
|
||||
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) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
//TODO: refactor
|
||||
@Nullable
|
||||
protected JsNameRef getOverloadedOperationReference(@NotNull JetSimpleNameExpression operationExpression) {
|
||||
DeclarationDescriptor operationDescriptor = getOperationDescriptor(operationExpression);
|
||||
if (operationDescriptor == null) {
|
||||
protected static JsNameRef getOverloadedOperationReference(@NotNull JetOperationExpression operationExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
DeclarationDescriptor operationDescriptor = getOperationDescriptor(operationExpression, context);
|
||||
if (!context.isDeclared(operationDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
if (context().intrinsics().hasDescriptor(operationDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
if (!context().isDeclared(operationDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
return context().getNameForDescriptor(operationDescriptor).makeRef();
|
||||
return context.getNameForDescriptor(operationDescriptor).makeRef();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DeclarationDescriptor getOperationDescriptor(@NotNull JetSimpleNameExpression expression) {
|
||||
return BindingUtils.getDescriptorForReferenceExpression
|
||||
(context().bindingContext(), expression);
|
||||
@NotNull
|
||||
private static DeclarationDescriptor getOperationDescriptor(@NotNull JetOperationExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
|
||||
(context.bindingContext(), expression.getOperation());
|
||||
assert descriptorForReferenceExpression != null;
|
||||
return descriptorForReferenceExpression;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ public final class OverloadedBinaryOperationTranslator extends BinaryOperationTr
|
||||
private OverloadedBinaryOperationTranslator(@NotNull JetBinaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
super(expression, context);
|
||||
JsNameRef overloadedOperationReference = getOverloadedOperationReference(expression.getOperationReference());
|
||||
JsNameRef overloadedOperationReference = getOverloadedOperationReference(expression, context);
|
||||
assert overloadedOperationReference != null;
|
||||
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;
|
||||
|
||||
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.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
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.JetTokens;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.reference.PropertyAccessTranslator;
|
||||
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
|
||||
*/
|
||||
public final 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();
|
||||
}
|
||||
//TODO: reexamine class, see if can be clearer
|
||||
public abstract class UnaryOperationTranslator extends OperationTranslator {
|
||||
|
||||
@NotNull
|
||||
private final JetUnaryExpression expression;
|
||||
@NotNull
|
||||
private final JsExpression baseExpression;
|
||||
private final boolean isPrefix;
|
||||
protected final JsExpression baseExpression;
|
||||
protected final boolean isPrefix;
|
||||
private final boolean isVariableReassignment;
|
||||
private final boolean isStatement;
|
||||
private final boolean isPropertyAccess;
|
||||
@Nullable
|
||||
private final JsNameRef operationReference;
|
||||
protected final boolean isPropertyAccess;
|
||||
|
||||
private UnaryOperationTranslator(@NotNull TranslationContext context, @NotNull JetUnaryExpression expression,
|
||||
boolean isPrefix) {
|
||||
protected UnaryOperationTranslator(@NotNull JetUnaryExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
super(context);
|
||||
this.expression = expression;
|
||||
this.isPrefix = isPrefix;
|
||||
this.isVariableReassignment = isVariableReassignment(expression);
|
||||
this.isPrefix = isPrefix(expression);
|
||||
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
|
||||
this.isStatement = BindingUtils.isStatement(context().bindingContext(), expression);
|
||||
this.baseExpression = translateBaseExpression();
|
||||
this.isPropertyAccess = isPropertyAccess(getBaseExpression());
|
||||
this.operationReference = getOverloadedOperationReference(expression.getOperationSign());
|
||||
this.baseExpression = translateBaseExpression(context, expression);
|
||||
this.isPropertyAccess = isPropertyAccess(getBaseExpression(expression));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
JsExpression translate() {
|
||||
if ((operationReference != null) || isPropertyAccess) {
|
||||
return translateOverload();
|
||||
}
|
||||
return jsUnaryExpression();
|
||||
}
|
||||
protected abstract JsExpression translate();
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateOverload() {
|
||||
protected JsExpression translateAsMethodCall() {
|
||||
if (isStatement || isPrefix) {
|
||||
return asPrefix();
|
||||
}
|
||||
@@ -99,7 +84,6 @@ public final class UnaryOperationTranslator extends OperationTranslator {
|
||||
private JsExpression asPostfixWithNoReassignment() {
|
||||
// code fragment: expr(a++)
|
||||
// generate: expr( (t1 = a, t2 = t1, t2.inc(), t1) )
|
||||
assert operationReference != null;
|
||||
TemporaryVariable t1 = declareTemporary(baseExpression);
|
||||
TemporaryVariable t2 = declareTemporary(t1.nameReference());
|
||||
JsExpression methodCall = operationExpression(t2.nameReference());
|
||||
@@ -122,7 +106,7 @@ public final class UnaryOperationTranslator extends OperationTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression propertyReassignment(@NotNull JsExpression toCallMethodUpon) {
|
||||
JetExpression jetBaseExpression = getBaseExpression();
|
||||
JetExpression jetBaseExpression = getBaseExpression(expression);
|
||||
JsInvocation setterCall =
|
||||
PropertyAccessTranslator.translateAsPropertySetterCall(jetBaseExpression, context());
|
||||
assert PropertyAccessTranslator.canBePropertyGetterCall(jetBaseExpression, context()) : "Should be a getter call";
|
||||
@@ -132,52 +116,19 @@ public final class UnaryOperationTranslator extends OperationTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression operationExpression(@NotNull JsExpression receiver) {
|
||||
if (operationReference != null) {
|
||||
AstUtil.setQualifier(operationReference, receiver);
|
||||
return AstUtil.newInvocation(operationReference);
|
||||
}
|
||||
return unaryAsBinary(getOperationToken(), receiver);
|
||||
}
|
||||
abstract JsExpression operationExpression(@NotNull JsExpression receiver);
|
||||
|
||||
@NotNull
|
||||
private JsExpression jsUnaryExpression() {
|
||||
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken());
|
||||
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();
|
||||
protected JetToken getOperationToken() {
|
||||
JetSimpleNameExpression operationExpression = expression.getOperation();
|
||||
IElementType elementType = operationExpression.getReferencedNameElementType();
|
||||
assert elementType instanceof JetToken : "Unary expression should have IElementType of type JetToken";
|
||||
return (JetToken) elementType;
|
||||
}
|
||||
|
||||
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");
|
||||
private boolean isPrefix(JetUnaryExpression expression) {
|
||||
return (expression instanceof JetPrefixExpression);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.PsiUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
/**
|
||||
* @author Talanov Pavel
|
||||
@@ -147,17 +146,6 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
||||
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
|
||||
public JsInvocation translateAsPropertySetterCall() {
|
||||
JsName setterName = getNotNullSetterName();
|
||||
@@ -169,7 +157,9 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
||||
if (qualifier != null) {
|
||||
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.JsName;
|
||||
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.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
@@ -38,10 +38,9 @@ public class ReferenceTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
//TODO: make this process simpler and clearer
|
||||
public JsExpression translateSimpleName() {
|
||||
tryResolveAsPropertyAccess();
|
||||
tryResolveAsThisQualifiedExpression();
|
||||
tryResolveAsAliasReference();
|
||||
tryResolveAsGlobalReference();
|
||||
tryResolveAsPropertyAccess();
|
||||
tryResolveAsImplicitlyQualifiedExpression();
|
||||
tryResolveAsLocalReference();
|
||||
if (result != null) {
|
||||
return result;
|
||||
@@ -49,7 +48,8 @@ public class ReferenceTranslator extends AbstractTranslator {
|
||||
throw new AssertionError("Undefined name in this scope: " + simpleName.getReferencedName());
|
||||
}
|
||||
|
||||
private void tryResolveAsThisQualifiedExpression() {
|
||||
//TODO: refactor
|
||||
private void tryResolveAsImplicitlyQualifiedExpression() {
|
||||
if (alreadyResolved()) return;
|
||||
|
||||
DeclarationDescriptor referencedDescriptor =
|
||||
@@ -59,24 +59,24 @@ public class ReferenceTranslator extends AbstractTranslator {
|
||||
if (!context().isDeclared(referencedDescriptor)) return;
|
||||
|
||||
JsName referencedName = context().getNameForDescriptor(referencedDescriptor);
|
||||
JsExpression implicitReceiver = getImplicitReceiver(referencedDescriptor, context());
|
||||
|
||||
if (!requiresThisQualifier(simpleName, referencedName)) return;
|
||||
if (implicitReceiver == null) return;
|
||||
|
||||
if (BindingUtils.isOwnedByClass(referencedDescriptor)) {
|
||||
result = TranslationUtils.getThisQualifiedNameReference(context(), referencedName);
|
||||
}
|
||||
if (BindingUtils.isOwnedByNamespace(referencedDescriptor)) {
|
||||
result = TranslationUtils.getQualifiedReference(context(), referencedDescriptor);
|
||||
}
|
||||
result = AstUtil.qualified(referencedName, implicitReceiver);
|
||||
}
|
||||
|
||||
private boolean requiresThisQualifier(@NotNull JetSimpleNameExpression expression,
|
||||
@NotNull JsName referencedName) {
|
||||
@Nullable
|
||||
public static JsExpression getImplicitReceiver(@NotNull DeclarationDescriptor referencedDescriptor,
|
||||
@NotNull TranslationContext context) {
|
||||
if (!context.isDeclared(referencedDescriptor)) return null;
|
||||
|
||||
JsName name = context().enclosingScope().findExistingName(referencedName.getIdent());
|
||||
boolean isClassMember = context().classScope().ownsName(name);
|
||||
boolean isBackingFieldAccess = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
|
||||
return (isBackingFieldAccess || isClassMember);
|
||||
if (BindingUtils.isOwnedByClass(referencedDescriptor)) {
|
||||
return TranslationUtils.getThisQualifier(context);
|
||||
}
|
||||
if (!BindingUtils.isOwnedByNamespace(referencedDescriptor)) return null;
|
||||
|
||||
return context.declarations().getQualifier(referencedDescriptor);
|
||||
}
|
||||
|
||||
private void tryResolveAsAliasReference() {
|
||||
@@ -104,18 +104,6 @@ public class ReferenceTranslator extends AbstractTranslator {
|
||||
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() {
|
||||
if (alreadyResolved()) return;
|
||||
|
||||
|
||||
@@ -36,37 +36,37 @@ public final class BindingUtils {
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context,
|
||||
public static NamespaceDescriptor getNamespaceDescriptor(@NotNull BindingContext context,
|
||||
@NotNull JetNamespace declaration) {
|
||||
return getDescriptorForExpression(context, declaration, NamespaceDescriptor.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context,
|
||||
public static FunctionDescriptor getFunctionDescriptor(@NotNull BindingContext context,
|
||||
@NotNull JetNamedFunction declaration) {
|
||||
return getDescriptorForExpression(context, declaration, FunctionDescriptor.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public PropertyAccessorDescriptor getPropertyAccessorDescriptor(@NotNull BindingContext context,
|
||||
public static PropertyAccessorDescriptor getPropertyAccessorDescriptor(@NotNull BindingContext context,
|
||||
@NotNull JetPropertyAccessor declaration) {
|
||||
return getDescriptorForExpression(context, declaration, PropertyAccessorDescriptor.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context,
|
||||
public static PropertyDescriptor getPropertyDescriptor(@NotNull BindingContext context,
|
||||
@NotNull JetProperty declaration) {
|
||||
return getDescriptorForExpression(context, declaration, PropertyDescriptor.class);
|
||||
}
|
||||
|
||||
//TODO: possibly remove
|
||||
// @NotNull
|
||||
// static public PropertySetterDescriptor getPropertySetterDescriptorForProperty(@NotNull BindingContext context,
|
||||
// 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";
|
||||
@@ -74,7 +74,7 @@ public final class BindingUtils {
|
||||
// }
|
||||
//
|
||||
// @NotNull
|
||||
// static public PropertyGetterDescriptor getPropertyGetterDescriptorForProperty(@NotNull BindingContext context,
|
||||
// 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";
|
||||
@@ -82,7 +82,7 @@ public final class BindingUtils {
|
||||
// }
|
||||
|
||||
@NotNull
|
||||
static public JetClass getClassForDescriptor(@NotNull BindingContext context,
|
||||
public static JetClass getClassForDescriptor(@NotNull BindingContext context,
|
||||
@NotNull ClassDescriptor descriptor) {
|
||||
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||
assert result instanceof JetClass : "ClassDescriptor should have declaration of type JetClass";
|
||||
@@ -91,7 +91,7 @@ public final class BindingUtils {
|
||||
|
||||
//TODO: delete?
|
||||
@Nullable
|
||||
static public JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context,
|
||||
public static JetDeclaration getDeclarationForDescriptor(@NotNull BindingContext context,
|
||||
@NotNull DeclarationDescriptor descriptor) {
|
||||
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
|
||||
if (!(result instanceof JetDeclaration)) {
|
||||
@@ -101,14 +101,14 @@ public final class BindingUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public List<ClassDescriptor> getSuperclassDescriptors(@NotNull BindingContext context,
|
||||
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull BindingContext context,
|
||||
@NotNull JetClass classDeclaration) {
|
||||
ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration);
|
||||
return getSuperclassDescriptors(classDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
|
||||
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
|
||||
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
|
||||
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
|
||||
for (JetType type : superclassTypes) {
|
||||
@@ -121,7 +121,7 @@ public final class BindingUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
|
||||
public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
|
||||
DeclarationDescriptor superClassDescriptor =
|
||||
type.getConstructor().getDeclarationDescriptor();
|
||||
assert superClassDescriptor instanceof ClassDescriptor
|
||||
@@ -129,19 +129,19 @@ public final class BindingUtils {
|
||||
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);
|
||||
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);
|
||||
assert isStatement != null : "Invalid behaviour of get(BindingContext.STATEMENT)";
|
||||
return isStatement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public JetType getTypeByReference(@NotNull BindingContext context,
|
||||
public static JetType getTypeByReference(@NotNull BindingContext context,
|
||||
@NotNull JetTypeReference typeReference) {
|
||||
JetType result = context.get(BindingContext.TYPE, typeReference);
|
||||
assert result != null : "TypeReference should reference a type";
|
||||
@@ -149,19 +149,19 @@ public final class BindingUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static public ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
|
||||
public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
|
||||
@NotNull JetTypeReference typeReference) {
|
||||
return getClassDescriptorForType(getTypeByReference(context, typeReference));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static public PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context,
|
||||
public static PropertyDescriptor getPropertyDescriptorForConstructorParameter(@NotNull BindingContext context,
|
||||
@NotNull JetParameter parameter) {
|
||||
return context.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static public JetProperty getPropertyForDescriptor(@NotNull BindingContext context,
|
||||
public static JetProperty getPropertyForDescriptor(@NotNull BindingContext context,
|
||||
@NotNull PropertyDescriptor property) {
|
||||
PsiElement result = context.get(BindingContext.DESCRIPTOR_TO_DECLARATION, property);
|
||||
if (!(result instanceof JetProperty)) {
|
||||
@@ -171,7 +171,7 @@ public final class BindingUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static public DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context,
|
||||
public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context,
|
||||
@NotNull JetReferenceExpression reference) {
|
||||
return context.get(BindingContext.REFERENCE_TARGET, reference);
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public final class BindingUtils {
|
||||
|
||||
//TODO move unrelated utils to other class
|
||||
@Nullable
|
||||
static public ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
|
||||
for (ClassDescriptor descriptor : superclassDescriptors) {
|
||||
if (descriptor.getKind() == ClassKind.CLASS) {
|
||||
return descriptor;
|
||||
@@ -191,11 +191,11 @@ public final class BindingUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
static public boolean isOwnedByNamespace(@NotNull DeclarationDescriptor descriptor) {
|
||||
public static boolean isOwnedByNamespace(@NotNull DeclarationDescriptor descriptor) {
|
||||
return (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor);
|
||||
}
|
||||
|
||||
static public boolean isOwnedByClass(@NotNull DeclarationDescriptor descriptor) {
|
||||
public static boolean isOwnedByClass(@NotNull DeclarationDescriptor descriptor) {
|
||||
return (descriptor.getContainingDeclaration() instanceof ClassDescriptor);
|
||||
}
|
||||
|
||||
@@ -204,31 +204,44 @@ public final class BindingUtils {
|
||||
@Nullable
|
||||
public static PropertyDescriptor getPropertyDescriptorForSimpleName(@NotNull BindingContext context,
|
||||
@NotNull JetSimpleNameExpression expression) {
|
||||
ResolvedCall<?> resolvedCall =
|
||||
BindingUtils.getResolvedCall(context, expression);
|
||||
if (resolvedCall != 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;
|
||||
}
|
||||
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
|
||||
static public ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
|
||||
public static ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
|
||||
@NotNull JetExpression 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);
|
||||
assert result != null;
|
||||
return result;
|
||||
|
||||
@@ -4,12 +4,11 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||
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.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.general.TranslationContext;
|
||||
|
||||
@@ -43,8 +42,8 @@ public final class TranslationUtils {
|
||||
|
||||
|
||||
@NotNull
|
||||
public static List<JsExpression> translateArgumentList(@NotNull List<? extends ValueArgument> jetArguments,
|
||||
@NotNull TranslationContext context) {
|
||||
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
|
||||
@NotNull List<? extends ValueArgument> jetArguments) {
|
||||
List<JsExpression> jsArguments = new ArrayList<JsExpression>();
|
||||
for (ValueArgument argument : jetArguments) {
|
||||
jsArguments.add(translateArgument(context, argument));
|
||||
@@ -102,15 +101,8 @@ public final class TranslationUtils {
|
||||
return jsInitExpression;
|
||||
}
|
||||
|
||||
public static boolean isConstructorInvocation(@NotNull TranslationContext context,
|
||||
@NotNull JetCallExpression expression) {
|
||||
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();
|
||||
//TODO: move to descriptor UTILS
|
||||
public static boolean isConstructorDescriptor(@NotNull FunctionDescriptor descriptor) {
|
||||
return (descriptor instanceof ConstructorDescriptor);
|
||||
}
|
||||
|
||||
@@ -184,4 +176,42 @@ public final class TranslationUtils {
|
||||
|
||||
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