refactor and fix assignment operator on property bug

This commit is contained in:
Pavel Talanov
2011-12-02 20:58:16 +04:00
parent d2b4778029
commit a775c61ccf
18 changed files with 501 additions and 742 deletions
+341 -630
View File
File diff suppressed because it is too large Load Diff
@@ -102,7 +102,8 @@ public final class DeclarationVisitor extends DeclarationDescriptorVisitor<Void,
public void extractAccessor(@Nullable PropertyAccessorDescriptor descriptor, boolean isGetter, public void extractAccessor(@Nullable PropertyAccessorDescriptor descriptor, boolean isGetter,
@NotNull String propertyName, @NotNull DeclarationContext context) { @NotNull String propertyName, @NotNull DeclarationContext context) {
assert descriptor != null : "Accessor descriptor should not be null"; if (descriptor == null) return;
String accessorName = Namer.getNameForAccessor(propertyName, isGetter); String accessorName = Namer.getNameForAccessor(propertyName, isGetter);
declareName(descriptor, context, accessorName); declareName(descriptor, context, accessorName);
declareScope(descriptor, context, (isGetter ? "getter " : "setter ") + propertyName); declareScope(descriptor, context, (isGetter ? "getter " : "setter ") + propertyName);
@@ -11,6 +11,7 @@ import org.jetbrains.k2js.translate.reference.AccessTranslator;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment; import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.PsiUtils.isAssignment;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation; import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression; import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
@@ -22,7 +23,7 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
public static boolean isAssignmentOperator(JetBinaryExpression expression) { public static boolean isAssignmentOperator(JetBinaryExpression expression) {
JetToken operationToken = getOperationToken(expression); JetToken operationToken = getOperationToken(expression);
return (OperatorConventions.ASSIGNMENT_OPERATIONS.keySet().contains(operationToken) return (OperatorConventions.ASSIGNMENT_OPERATIONS.keySet().contains(operationToken)
|| OperatorTable.isAssignment(operationToken)); || isAssignment(operationToken));
} }
@NotNull @NotNull
@@ -49,8 +50,4 @@ public abstract class AssignmentTranslator extends AbstractTranslator {
this.accessTranslator = AccessTranslator.getAccessTranslator(expression.getLeft(), context()); this.accessTranslator = AccessTranslator.getAccessTranslator(expression.getLeft(), context());
this.right = translateRightExpression(context(), expression); this.right = translateRightExpression(context(), expression);
} }
@NotNull
abstract protected JsExpression translate();
} }
@@ -5,10 +5,8 @@ import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsExpression;
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.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetBinaryExpression;
import org.jetbrains.jet.lang.psi.JetOperationExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
@@ -20,8 +18,8 @@ import org.jetbrains.k2js.translate.reference.CallTranslator;
import java.util.Arrays; import java.util.Arrays;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isEquals;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression; import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression; import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
@@ -32,17 +30,6 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRight
*/ */
public final class BinaryOperationTranslator extends AbstractTranslator { public final class BinaryOperationTranslator extends AbstractTranslator {
//TODO: move to utils
@NotNull
private static DeclarationDescriptor getOperationDescriptor(@NotNull JetOperationExpression expression,
@NotNull TranslationContext context) {
DeclarationDescriptor descriptorForReferenceExpression = getDescriptorForReferenceExpression
(context.bindingContext(), expression.getOperation());
assert descriptorForReferenceExpression != null;
return descriptorForReferenceExpression;
}
@NotNull @NotNull
public static JsExpression translate(@NotNull JetBinaryExpression expression, public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
@@ -68,32 +55,22 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
if (AssignmentTranslator.isAssignmentOperator(expression)) { if (AssignmentTranslator.isAssignmentOperator(expression)) {
return AssignmentTranslator.translate(expression, context()); return AssignmentTranslator.translate(expression, context());
} }
if (operationDescriptor == null) {
return translateAsUnOverloadableBinaryOperation();
}
if (CompareToTranslator.isCompareToCall(expression, context())) { if (CompareToTranslator.isCompareToCall(expression, context())) {
return CompareToTranslator.translate(expression, context()); return CompareToTranslator.translate(expression, context());
} }
if (isEqualsCall()) { if (isEquals(operationDescriptor)) {
return translateAsEqualsCall(); return translateAsEqualsCall();
} }
if (operationDescriptor == null) {
return translateAsUnOverloadableBinaryOperation();
}
return CallTranslator.translate(expression, context()); return CallTranslator.translate(expression, context());
} }
private boolean isEqualsCall() {
//TODO: add descriptor is equals utils
if (operationDescriptor == null) {
return false;
}
boolean isEquals = operationDescriptor.getName().equals("equals");
boolean isIntrinsic = context().intrinsics().hasDescriptor(operationDescriptor);
return isEquals && isIntrinsic;
}
@NotNull @NotNull
private JsExpression translateAsEqualsCall() { private JsExpression translateAsEqualsCall() {
Intrinsic intrinsic = context().intrinsics(). assert operationDescriptor != null : "Equals operation must resolve to descriptor.";
getIntrinsic(getOperationDescriptor(expression, context())); Intrinsic intrinsic = context().intrinsics().getIntrinsic(operationDescriptor);
//TODO //TODO
((EqualsIntrinsic) intrinsic).setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ)); ((EqualsIntrinsic) intrinsic).setNegated(expression.getOperationToken().equals(JetTokens.EXCLEQ));
JsExpression left = translateLeftExpression(context(), expression); JsExpression left = translateLeftExpression(context(), expression);
@@ -18,6 +18,7 @@ import org.jetbrains.k2js.translate.reference.CallTranslator;
import java.util.Arrays; import java.util.Arrays;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isCompareTo;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*; import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
@@ -28,13 +29,12 @@ public final class CompareToTranslator extends AbstractTranslator {
public static boolean isCompareToCall(@NotNull JetBinaryExpression expression, public static boolean isCompareToCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
//move to util
FunctionDescriptor operationDescriptor = FunctionDescriptor operationDescriptor =
getFunctionDescriptorForOperationExpression(context.bindingContext(), expression); getFunctionDescriptorForOperationExpression(context.bindingContext(), expression);
if (operationDescriptor == null) return false; if (operationDescriptor == null) return false;
return (operationDescriptor.getName().equals("compareTo")); return (isCompareTo(operationDescriptor));
} }
@NotNull @NotNull
@@ -88,6 +88,4 @@ public final class CompareToTranslator extends AbstractTranslator {
JsExpression right = translateRightExpression(context(), expression); JsExpression right = translateRightExpression(context(), expression);
return intrinsic.apply(left, Arrays.asList(right), context()); return intrinsic.apply(left, Arrays.asList(right), context());
} }
} }
@@ -6,7 +6,6 @@ import com.google.dart.compiler.backend.js.ast.JsNameRef;
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.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetPrefixExpression;
import org.jetbrains.jet.lang.psi.JetUnaryExpression; import org.jetbrains.jet.lang.psi.JetUnaryExpression;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
@@ -15,7 +14,7 @@ import org.jetbrains.k2js.translate.reference.AccessTranslator;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isStatement; import static org.jetbrains.k2js.translate.utils.BindingUtils.isStatement;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment; import static org.jetbrains.k2js.translate.utils.BindingUtils.isVariableReassignment;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation; import static org.jetbrains.k2js.translate.utils.TranslationUtils.isIntrinsicOperation;
/** /**
@@ -41,20 +40,14 @@ public abstract class IncrementTranslator extends AbstractTranslator {
protected final JetUnaryExpression expression; protected final JetUnaryExpression expression;
@NotNull @NotNull
protected final AccessTranslator accessTranslator; protected final AccessTranslator accessTranslator;
protected final boolean isPrefix;
private final boolean isVariableReassignment; private final boolean isVariableReassignment;
private final boolean isStatement;
protected IncrementTranslator(@NotNull JetUnaryExpression expression, protected IncrementTranslator(@NotNull JetUnaryExpression expression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
super(context); super(context);
this.expression = expression; this.expression = expression;
this.isPrefix = isPrefix(expression);
this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression); this.isVariableReassignment = isVariableReassignment(context.bindingContext(), expression);
this.isStatement = isStatement(context().bindingContext(), expression); JetExpression baseExpression = getBaseExpression(expression);
//TODO: use util method
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
this.accessTranslator = AccessTranslator.getAccessTranslator(baseExpression, context()); this.accessTranslator = AccessTranslator.getAccessTranslator(baseExpression, context());
} }
@@ -63,7 +56,7 @@ public abstract class IncrementTranslator extends AbstractTranslator {
@NotNull @NotNull
protected JsExpression translateAsMethodCall() { protected JsExpression translateAsMethodCall() {
if (isStatement || isPrefix) { if (returnValueIgnored() || isPrefix(expression)) {
return asPrefix(); return asPrefix();
} }
if (isVariableReassignment) { if (isVariableReassignment) {
@@ -73,6 +66,10 @@ public abstract class IncrementTranslator extends AbstractTranslator {
} }
} }
private boolean returnValueIgnored() {
return isStatement(context().bindingContext(), expression);
}
@NotNull @NotNull
private JsExpression asPrefix() { private JsExpression asPrefix() {
JsExpression getExpression = accessTranslator.translateAsGet(); JsExpression getExpression = accessTranslator.translateAsGet();
@@ -114,11 +111,6 @@ public abstract class IncrementTranslator extends AbstractTranslator {
@NotNull @NotNull
abstract JsExpression operationExpression(@NotNull JsExpression receiver); abstract JsExpression operationExpression(@NotNull JsExpression receiver);
private boolean isPrefix(@NotNull JetUnaryExpression expression) {
return (expression instanceof JetPrefixExpression);
}
//TODO: consider moving into context //TODO: consider moving into context
protected final class TemporaryVariable { protected final class TemporaryVariable {
@@ -1,13 +1,17 @@
package org.jetbrains.k2js.translate.operation; package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; import com.google.dart.compiler.backend.js.ast.JsBinaryOperation;
import com.google.dart.compiler.backend.js.ast.JsBinaryOperator;
import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsExpression;
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.types.expressions.OperatorConventions;
import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.reference.ReferenceAccessTranslator;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.PsiUtils.isAssignment;
/** /**
* @author Talanov Pavel * @author Talanov Pavel
@@ -27,24 +31,56 @@ public final class IntrinsicAssignmentTranslator extends AssignmentTranslator {
} }
@NotNull @NotNull
@Override
protected JsExpression translate() { protected JsExpression translate() {
return asBinaryOperation(); if (isAssignment(getOperationToken(expression))) {
return translateAsPlainAssignment();
}
return translateAsAssignmentOperation();
} }
//TODO: refactor
@NotNull @NotNull
private JsExpression asBinaryOperation() { private JsExpression translateAsAssignmentOperation() {
if (OperatorTable.isAssignment(getOperationToken(expression))) { if (accessTranslator instanceof ReferenceAccessTranslator) {
return accessTranslator.translateAsSet(right); return translateAsPlainAssignmentOperation();
} }
//TODO: logic broken return translateAsAssignToCounterpart();
JetToken token = getOperationToken(expression);
if (OperatorTable.hasCorrespondingBinaryOperator(token)) {
return new JsBinaryOperation(OperatorTable.getBinaryOperator(token),
accessTranslator.translateAsGet(), right);
}
throw new AssertionError("Unsupported token encountered: " + token.toString());
} }
@NotNull
private JsExpression translateAsAssignToCounterpart() {
JsBinaryOperator operator = getCounterpartOperator();
JsBinaryOperation counterpartOperation =
new JsBinaryOperation(operator, accessTranslator.translateAsGet(), right);
return accessTranslator.translateAsSet(counterpartOperation);
}
@NotNull
private JsBinaryOperator getCounterpartOperator() {
JetToken assignmentOperationToken = getOperationToken(expression);
assert OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(assignmentOperationToken);
JetToken counterpartToken = OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(assignmentOperationToken);
assert OperatorTable.hasCorrespondingBinaryOperator(counterpartToken) :
"Unsupported token encountered: " + counterpartToken.toString();
return OperatorTable.getBinaryOperator(counterpartToken);
}
@NotNull
private JsExpression translateAsPlainAssignmentOperation() {
JsBinaryOperator operator = getAssignmentOperator();
return new JsBinaryOperation(operator, accessTranslator.translateAsGet(), right);
}
@NotNull
private JsBinaryOperator getAssignmentOperator() {
JetToken token = getOperationToken(expression);
assert OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(token);
assert OperatorTable.hasCorrespondingBinaryOperator(token) :
"Unsupported token encountered: " + token.toString();
return OperatorTable.getBinaryOperator(token);
}
@NotNull
private JsExpression translateAsPlainAssignment() {
return accessTranslator.translateAsSet(right);
}
} }
@@ -9,6 +9,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.reference.ReferenceAccessTranslator; import org.jetbrains.k2js.translate.reference.ReferenceAccessTranslator;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
import static org.jetbrains.k2js.translate.utils.PsiUtils.isPrefix;
/** /**
@@ -46,7 +47,7 @@ public final class IntrinsicIncrementTranslator extends IncrementTranslator {
private JsExpression jsUnaryExpression() { private JsExpression jsUnaryExpression() {
JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression)); JsUnaryOperator operator = OperatorTable.getUnaryOperator(getOperationToken(expression));
JsExpression getExpression = accessTranslator.translateAsGet(); JsExpression getExpression = accessTranslator.translateAsGet();
if (isPrefix) { if (isPrefix(expression)) {
return new JsPrefixOperation(operator, getExpression); return new JsPrefixOperation(operator, getExpression);
} else { } else {
return new JsPostfixOperation(operator, getExpression); return new JsPostfixOperation(operator, getExpression);
@@ -56,16 +57,17 @@ public final class IntrinsicIncrementTranslator extends IncrementTranslator {
@Override @Override
@NotNull @NotNull
protected JsExpression operationExpression(@NotNull JsExpression receiver) { protected JsExpression operationExpression(@NotNull JsExpression receiver) {
return unaryAsBinary(getOperationToken(expression), receiver); return unaryAsBinary(receiver);
} }
public JsBinaryOperation unaryAsBinary(@NotNull JetToken token, @NotNull JsExpression expression) { public JsBinaryOperation unaryAsBinary(@NotNull JsExpression leftExpression) {
JsNumberLiteral oneLiteral = context().program().getNumberLiteral(1); JsNumberLiteral oneLiteral = context().program().getNumberLiteral(1);
JetToken token = getOperationToken(expression);
if (token.equals(JetTokens.PLUSPLUS)) { if (token.equals(JetTokens.PLUSPLUS)) {
return new JsBinaryOperation(JsBinaryOperator.ADD, expression, oneLiteral); return new JsBinaryOperation(JsBinaryOperator.ADD, leftExpression, oneLiteral);
} }
if (token.equals(JetTokens.MINUSMINUS)) { if (token.equals(JetTokens.MINUSMINUS)) {
return new JsBinaryOperation(JsBinaryOperator.SUB, expression, oneLiteral); return new JsBinaryOperation(JsBinaryOperator.SUB, leftExpression, oneLiteral);
} }
throw new AssertionError("This method should be called only for increment and decrement operators"); throw new AssertionError("This method should be called only for increment and decrement operators");
} }
@@ -63,8 +63,4 @@ public final class OperatorTable {
assert JetTokens.OPERATIONS.contains(token) : "Token should represent an operation!"; assert JetTokens.OPERATIONS.contains(token) : "Token should represent an operation!";
return unaryOperatorsMap.get(token); return unaryOperatorsMap.get(token);
} }
static public boolean isAssignment(JetToken token) {
return (token == JetTokens.EQ);
}
} }
@@ -36,7 +36,6 @@ public final class OverloadedAssignmentTranslator extends AssignmentTranslator {
this.operationReference = overloadedOperationReference; this.operationReference = overloadedOperationReference;
} }
@Override
@NotNull @NotNull
protected JsExpression translate() { protected JsExpression translate() {
if (isVariableReassignment) { if (isVariableReassignment) {
@@ -21,6 +21,7 @@ import java.util.List;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; 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.BindingUtils.getFunctionDescriptorForCallExpression;
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.isConstructorDescriptor;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.*; import static org.jetbrains.k2js.translate.utils.TranslationUtils.*;
/** /**
@@ -1,7 +1,9 @@
package org.jetbrains.k2js.translate.utils; package org.jetbrains.k2js.translate.utils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
/** /**
* @author Talanov Pavel * @author Talanov Pavel
@@ -11,7 +13,6 @@ public final class DescriptorUtils {
private DescriptorUtils() { private DescriptorUtils() {
} }
private static int valueParametersCount(@NotNull FunctionDescriptor functionDescriptor) { private static int valueParametersCount(@NotNull FunctionDescriptor functionDescriptor) {
return functionDescriptor.getValueParameters().size(); return functionDescriptor.getValueParameters().size();
} }
@@ -20,4 +21,15 @@ public final class DescriptorUtils {
return (valueParametersCount(functionDescriptor) > 0); return (valueParametersCount(functionDescriptor) > 0);
} }
public static boolean isEquals(@NotNull FunctionDescriptor functionDescriptor) {
return (functionDescriptor.getName().equals(OperatorConventions.EQUALS));
}
public static boolean isCompareTo(@NotNull FunctionDescriptor functionDescriptor) {
return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO));
}
public static boolean isConstructorDescriptor(@NotNull FunctionDescriptor descriptor) {
return (descriptor instanceof ConstructorDescriptor);
}
} }
@@ -3,11 +3,9 @@ package org.jetbrains.k2js.translate.utils;
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.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.psi.JetOperationExpression;
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
/** /**
* @author Talanov Pavel * @author Talanov Pavel
@@ -34,4 +32,19 @@ public final class PsiUtils {
assert elementType instanceof JetToken : "Unary expression should have operation token of type JetToken"; assert elementType instanceof JetToken : "Unary expression should have operation token of type JetToken";
return (JetToken) elementType; return (JetToken) elementType;
} }
@NotNull
public static JetExpression getBaseExpression(@NotNull JetUnaryExpression expression) {
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
return baseExpression;
}
public static boolean isPrefix(@NotNull JetUnaryExpression expression) {
return (expression instanceof JetPrefixExpression);
}
public static boolean isAssignment(JetToken token) {
return (token == JetTokens.EQ);
}
} }
@@ -4,7 +4,6 @@ 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.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.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
@@ -72,7 +71,13 @@ public final class TranslationUtils {
public static JsNameRef backingFieldReference(@NotNull TranslationContext context, public static JsNameRef backingFieldReference(@NotNull TranslationContext context,
@NotNull PropertyDescriptor descriptor) { @NotNull PropertyDescriptor descriptor) {
JsName backingFieldName = getBackingFieldName(descriptor.getName(), context); JsName backingFieldName = getBackingFieldName(descriptor.getName(), context);
return getThisQualifiedNameReference(context, backingFieldName); if (BindingUtils.isOwnedByClass(descriptor)) {
return getThisQualifiedNameReference(context, backingFieldName);
}
assert BindingUtils.isOwnedByNamespace(descriptor)
: "Only classes and namespaces may own descriptors";
JsNameRef qualifier = context.declarations().getQualifier(descriptor);
return AstUtil.qualified(backingFieldName, qualifier);
} }
@NotNull @NotNull
@@ -102,11 +107,6 @@ public final class TranslationUtils {
return jsInitExpression; return jsInitExpression;
} }
//TODO: move to descriptor UTILS
public static boolean isConstructorDescriptor(@NotNull FunctionDescriptor descriptor) {
return (descriptor instanceof ConstructorDescriptor);
}
@NotNull @NotNull
public static JsStatement assignmentToBackingFieldFromParameter(@NotNull TranslationContext context, public static JsStatement assignmentToBackingFieldFromParameter(@NotNull TranslationContext context,
@NotNull PropertyDescriptor descriptor, @NotNull PropertyDescriptor descriptor,
@@ -168,32 +168,13 @@ public final class TranslationUtils {
return result; return result;
} }
public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
@NotNull JetReferenceExpression expression) {
DeclarationDescriptor descriptor =
BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), expression);
if (descriptor == null) return true;
return (context.intrinsics().hasDescriptor(descriptor));
}
@NotNull @NotNull
public static JsExpression translateBaseExpression(@NotNull TranslationContext context, public static JsExpression translateBaseExpression(@NotNull TranslationContext context,
@NotNull JetUnaryExpression expression) { @NotNull JetUnaryExpression expression) {
JetExpression baseExpression = getBaseExpression(expression); JetExpression baseExpression = PsiUtils.getBaseExpression(expression);
return Translation.translateAsExpression(baseExpression, context); 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 @NotNull
public static JsExpression translateReceiver(@NotNull TranslationContext context, public static JsExpression translateReceiver(@NotNull TranslationContext context,
@NotNull JetDotQualifiedExpression expression) { @NotNull JetDotQualifiedExpression expression) {
@@ -215,7 +196,6 @@ public final class TranslationUtils {
return Translation.translateAsExpression(rightExpression, context); return Translation.translateAsExpression(rightExpression, context);
} }
//TODO: check function with same name
public static boolean isIntrinsicOperation(@NotNull TranslationContext context, public static boolean isIntrinsicOperation(@NotNull TranslationContext context,
@NotNull JetOperationExpression expression) { @NotNull JetOperationExpression expression) {
FunctionDescriptor operationDescriptor = FunctionDescriptor operationDescriptor =
@@ -24,7 +24,6 @@ public class BasicClassTest extends TranslationTest {
testFooBoxIsTrue("methodDeclarationAndCall.kt"); testFooBoxIsTrue("methodDeclarationAndCall.kt");
} }
//TODO: wait for bugfix and implement properties as constructor parameter declaration
@Test @Test
public void constructorWithParameter() throws Exception { public void constructorWithParameter() throws Exception {
testFooBoxIsTrue("constructorWithParameter.kt"); testFooBoxIsTrue("constructorWithParameter.kt");
@@ -0,0 +1,27 @@
package org.jetbrains.k2js.test;
import org.junit.Test;
/**
* @author Talanov Pavel
*/
public class IntrinsicTest extends AbstractExpressionTest {
final private static String MAIN = "intrinsic/";
@Override
protected String mainDirectory() {
return MAIN;
}
@Test
public void intrinsicPlusAssign() throws Exception {
testFooBoxIsTrue("plusAssign.kt");
}
@Test
public void minusAssignOnProperty() throws Exception {
testFooBoxIsTrue("minusAssignOnProperty.kt");
}
}
@@ -0,0 +1,10 @@
namespace foo
var a = 3
fun box() : Boolean {
a -= 10
return (a == -7)
}
@@ -0,0 +1,8 @@
namespace foo
fun box() : Boolean {
var a = 3
a += 3
return (a == 6)
}