JS backend: don't use the temporary variables in SafeCall and SureCall when is not necessary.
For example: val a : A? = null a!! a?.foo() translated before: var a = null; var tmp$0, tmp$1; (tmp$0 = a) != null ? tmp$0 : Kotlin.throwNPE(); (tmp$1 = a) != null ? tmp$1.foo() : null; translated after: var a = null; a != null ? a : Kotlin.throwNPE(); a != null ? a.foo() : null;
This commit is contained in:
@@ -156,8 +156,8 @@ public final class Namer {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression throwNPEFunctionCall() {
|
||||
return new JsInvocation(new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject()));
|
||||
public JsExpression throwNPEFunctionRef() {
|
||||
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -311,6 +311,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@NotNull
|
||||
public JsNode visitBinaryWithTypeRHSExpression(@NotNull JetBinaryExpressionWithTypeRHS expression,
|
||||
@NotNull TranslationContext context) {
|
||||
// KT-2670
|
||||
// we actually do not care for types in js
|
||||
return Translation.translateExpression(expression.getLeft(), context);
|
||||
}
|
||||
|
||||
+2
-12
@@ -16,12 +16,10 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.operation;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsConditional;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryConstVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||
import org.jetbrains.k2js.translate.reference.CallType;
|
||||
@@ -33,8 +31,7 @@ import static org.jetbrains.k2js.translate.general.Translation.translateAsExpres
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getBaseExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.sure;
|
||||
|
||||
public final class UnaryOperationTranslator {
|
||||
private UnaryOperationTranslator() {
|
||||
@@ -58,14 +55,7 @@ public final class UnaryOperationTranslator {
|
||||
|
||||
@NotNull
|
||||
private static JsExpression translateExclExclOperator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) {
|
||||
JsExpression translatedExpression = translateAsExpression(getBaseExpression(expression), context);
|
||||
TemporaryConstVariable tempVar = context.getOrDeclareTemporaryConstVariable(translatedExpression);
|
||||
|
||||
JsConditional ensureNotNull = new JsConditional(isNotNullCheck(tempVar.value()), tempVar.value(), context.namer().throwNPEFunctionCall());
|
||||
|
||||
// associate (cache) ensureNotNull expression to new LazyValue with same name.
|
||||
context.associateExpressionToLazyValue(ensureNotNull, new TemporaryConstVariable(tempVar.name(), ensureNotNull));
|
||||
return ensureNotNull;
|
||||
return sure(translateAsExpression(getBaseExpression(expression), context), context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -24,10 +24,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryConstVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.notNullConditional;
|
||||
|
||||
public enum CallType {
|
||||
SAFE {
|
||||
@@ -36,9 +35,9 @@ public enum CallType {
|
||||
JsExpression constructCall(@Nullable JsExpression receiver, @NotNull CallConstructor constructor,
|
||||
@NotNull TranslationContext context) {
|
||||
assert receiver != null;
|
||||
|
||||
TemporaryConstVariable tempVar = context.getOrDeclareTemporaryConstVariable(receiver);
|
||||
return new JsConditional(isNotNullCheck(tempVar.value()), constructor.construct(tempVar.value()), JsLiteral.NULL);
|
||||
JsConditional expression = notNullConditional(receiver, JsLiteral.NULL, context);
|
||||
expression.setThenExpression(constructor.construct(expression.getThenExpression()));
|
||||
return expression;
|
||||
}
|
||||
},
|
||||
//TODO: bang qualifier is not implemented in frontend for now
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryConstVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
|
||||
@@ -75,7 +76,28 @@ public final class TranslationUtils {
|
||||
JsBinaryOperator operator = isNegated ? JsBinaryOperator.NEQ : JsBinaryOperator.EQ;
|
||||
return new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static JsConditional notNullConditional(
|
||||
@NotNull JsExpression expression,
|
||||
@NotNull JsExpression elseExpression,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
JsExpression testExpression;
|
||||
JsExpression thenExpression;
|
||||
if (isCacheNeeded(expression)) {
|
||||
TemporaryConstVariable tempVar = context.getOrDeclareTemporaryConstVariable(expression);
|
||||
testExpression = isNotNullCheck(tempVar.value());
|
||||
thenExpression = tempVar.value();
|
||||
}
|
||||
else {
|
||||
testExpression = isNotNullCheck(expression);
|
||||
thenExpression = expression;
|
||||
}
|
||||
|
||||
return new JsConditional(testExpression, thenExpression, elseExpression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
|
||||
@NotNull List<? extends ValueArgument> jetArguments) {
|
||||
@@ -189,4 +211,19 @@ public final class TranslationUtils {
|
||||
return Pair.create(null, expression);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsConditional sure(@NotNull JsExpression expression, @NotNull TranslationContext context) {
|
||||
JsInvocation throwNPE = new JsInvocation(context.namer().throwNPEFunctionRef());
|
||||
JsConditional ensureNotNull = notNullConditional(expression, throwNPE, context);
|
||||
|
||||
JsExpression thenExpression = ensureNotNull.getThenExpression();
|
||||
if (thenExpression instanceof JsNameRef) {
|
||||
// associate (cache) ensureNotNull expression to new TemporaryConstVariable with same name.
|
||||
context.associateExpressionToLazyValue(ensureNotNull,
|
||||
new TemporaryConstVariable(((JsNameRef) thenExpression).getName(), ensureNotNull));
|
||||
}
|
||||
|
||||
return ensureNotNull;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user