Added support for simple case of safe qualified access.
This commit is contained in:
@@ -143,7 +143,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitCallExpression(JetCallExpression expression, TranslationContext context) {
|
||||
JsExpression callee = getCallee(expression, context);
|
||||
JsExpression callee = translateCallee(expression, context);
|
||||
List<JsExpression> arguments = translateArgumentList(expression.getValueArguments(), context);
|
||||
if (isConstructorInvocation(expression, context)) {
|
||||
JsNew constructorCall = new JsNew(callee);
|
||||
@@ -165,7 +165,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression getCallee(@NotNull JetCallExpression expression, @NotNull TranslationContext context) {
|
||||
private JsExpression translateCallee(@NotNull JetCallExpression expression, @NotNull TranslationContext context) {
|
||||
JetExpression jetCallee = expression.getCalleeExpression();
|
||||
if (jetCallee == null) {
|
||||
throw new AssertionError("Call expression with no callee encountered!");
|
||||
@@ -291,26 +291,30 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@NotNull
|
||||
public JsNode visitDotQualifiedExpression(@NotNull JetDotQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return translateQualifiedExpression(expression, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode translateQualifiedExpression(@NotNull JetQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
JsInvocation getterCall = translateAsGetterCall(expression, context);
|
||||
if (getterCall != null) {
|
||||
return getterCall;
|
||||
}
|
||||
return translateAsQualifiedExpression(expression, context);
|
||||
return translateAsQualifiedAccess(expression, context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JsInvocation translateAsGetterCall(@NotNull JetDotQualifiedExpression expression,
|
||||
private JsInvocation translateAsGetterCall(@NotNull JetQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return Translation.propertyAccessTranslator(context).resolveAsPropertyGet(expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode translateAsQualifiedExpression(@NotNull JetDotQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
JsExpression receiver = AstUtil.convertToExpression(expression.getReceiverExpression().accept(this, context));
|
||||
JetExpression jetSelector = expression.getSelectorExpression();
|
||||
assert jetSelector != null : "Selector should not be null in dot qualified expression.";
|
||||
JsExpression selector = AstUtil.convertToExpression(jetSelector.accept(this, context));
|
||||
private JsNode translateAsQualifiedAccess(@NotNull JetQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
JsExpression receiver = translateReceiver(expression, context);
|
||||
JsExpression selector = translateSelector(expression, context);
|
||||
assert (selector instanceof JsNameRef || selector instanceof JsInvocation)
|
||||
: "Selector should be a name reference or a method invocation in dot qualified expression.";
|
||||
if (selector instanceof JsInvocation) {
|
||||
@@ -320,6 +324,20 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateSelector(@NotNull JetQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
JetExpression jetSelector = expression.getSelectorExpression();
|
||||
assert jetSelector != null : "Selector should not be null in dot qualified expression.";
|
||||
return AstUtil.convertToExpression(jetSelector.accept(this, context));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateReceiver(@NotNull JetQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return AstUtil.convertToExpression(expression.getReceiverExpression().accept(this, context));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode translateAsQualifiedNameReference(@NotNull JsExpression receiver, @NotNull JsNameRef selector) {
|
||||
selector.setQualifier(receiver);
|
||||
@@ -347,16 +365,8 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
public JsNode visitPostfixExpression(@NotNull JetPostfixExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
return Translation.operationTranslator(context).translatePostfixOperation(expression);
|
||||
|
||||
}
|
||||
|
||||
// @Override
|
||||
// @NotNull
|
||||
// public JsNode visitBinaryWithTypeRHSExpression(@NotNull JetBinaryExpressionWithTypeRHS expression,
|
||||
// @NotNull TranslationContext context) {
|
||||
// return Translation.typeOperationTranslator(context).translate(expression);
|
||||
// }
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitIsExpression(@NotNull JetIsExpression expression,
|
||||
@@ -364,5 +374,16 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
return Translation.typeOperationTranslator(context).translateIsExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
JsExpression receiver = translateReceiver(expression, context);
|
||||
JsBinaryOperation nullCheck = new JsBinaryOperation
|
||||
(JsBinaryOperator.NEQ, receiver, context.program().getNullLiteral());
|
||||
JsStatement thenStatement = AstUtil.convertToStatement(translateQualifiedExpression(expression, context));
|
||||
return new JsIf(nullCheck, thenStatement, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
@@ -33,7 +34,7 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JsInvocation resolveAsPropertyGet(@NotNull JetDotQualifiedExpression expression) {
|
||||
public JsInvocation resolveAsPropertyGet(@NotNull JetQualifiedExpression expression) {
|
||||
JetExpression selectorExpression = expression.getSelectorExpression();
|
||||
assert selectorExpression != null : "Selector should not be null.";
|
||||
JsName getterName = getPropertyGetterName(selectorExpression);
|
||||
@@ -54,9 +55,9 @@ public final class PropertyAccessTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsInvocation translateReceiverAndReturnAccessorInvocation
|
||||
(@NotNull JetDotQualifiedExpression dotQualifiedExpression, @NotNull JsName accessorName) {
|
||||
(@NotNull JetQualifiedExpression qualifiedExpression, @NotNull JsName accessorName) {
|
||||
JsNode node = Translation.expressionTranslator(translationContext())
|
||||
.translate(dotQualifiedExpression.getReceiverExpression());
|
||||
.translate(qualifiedExpression.getReceiverExpression());
|
||||
JsNameRef result = accessorName.makeRef();
|
||||
result.setQualifier(AstUtil.convertToExpression(node));
|
||||
return AstUtil.newInvocation(result);
|
||||
|
||||
@@ -39,6 +39,11 @@ public final class PropertyAccessorTest extends AbstractClassTest {
|
||||
testFooBoxIsTrue("customSetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void safeCall() throws Exception {
|
||||
testFooBoxIsTrue("safeCall.kt");
|
||||
}
|
||||
|
||||
//TODO test
|
||||
// @Test
|
||||
// public void namespaceCustomAccessors() throws Exception {
|
||||
|
||||
@@ -23,5 +23,4 @@ public class RTTITest extends AbstractClassTest {
|
||||
public void notIsOtherClass() throws Exception {
|
||||
testFooBoxIsTrue("notIsOtherClass.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace foo
|
||||
|
||||
class A() {
|
||||
fun doSomething() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : Boolean {
|
||||
var a : A? = null;
|
||||
a?.doSomething()
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user