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
|
@NotNull
|
||||||
public JsExpression throwNPEFunctionCall() {
|
public JsExpression throwNPEFunctionRef() {
|
||||||
return new JsInvocation(new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject()));
|
return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -311,6 +311,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public JsNode visitBinaryWithTypeRHSExpression(@NotNull JetBinaryExpressionWithTypeRHS expression,
|
public JsNode visitBinaryWithTypeRHSExpression(@NotNull JetBinaryExpressionWithTypeRHS expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
|
// KT-2670
|
||||||
// we actually do not care for types in js
|
// we actually do not care for types in js
|
||||||
return Translation.translateExpression(expression.getLeft(), context);
|
return Translation.translateExpression(expression.getLeft(), context);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-12
@@ -16,12 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.operation;
|
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 com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
import org.jetbrains.jet.lang.psi.JetUnaryExpression;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
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.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
import org.jetbrains.k2js.translate.reference.CallBuilder;
|
||||||
import org.jetbrains.k2js.translate.reference.CallType;
|
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.BindingUtils.getResolvedCall;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getBaseExpression;
|
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.PsiUtils.getOperationToken;
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck;
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.sure;
|
||||||
|
|
||||||
|
|
||||||
public final class UnaryOperationTranslator {
|
public final class UnaryOperationTranslator {
|
||||||
private UnaryOperationTranslator() {
|
private UnaryOperationTranslator() {
|
||||||
@@ -58,14 +55,7 @@ public final class UnaryOperationTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static JsExpression translateExclExclOperator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) {
|
private static JsExpression translateExclExclOperator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) {
|
||||||
JsExpression translatedExpression = translateAsExpression(getBaseExpression(expression), context);
|
return sure(translateAsExpression(getBaseExpression(expression), context), 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression;
|
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
import org.jetbrains.jet.lang.psi.JetQualifiedExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression;
|
import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression;
|
||||||
import org.jetbrains.k2js.translate.context.TemporaryConstVariable;
|
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
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 {
|
public enum CallType {
|
||||||
SAFE {
|
SAFE {
|
||||||
@@ -36,9 +35,9 @@ public enum CallType {
|
|||||||
JsExpression constructCall(@Nullable JsExpression receiver, @NotNull CallConstructor constructor,
|
JsExpression constructCall(@Nullable JsExpression receiver, @NotNull CallConstructor constructor,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
assert receiver != null;
|
assert receiver != null;
|
||||||
|
JsConditional expression = notNullConditional(receiver, JsLiteral.NULL, context);
|
||||||
TemporaryConstVariable tempVar = context.getOrDeclareTemporaryConstVariable(receiver);
|
expression.setThenExpression(constructor.construct(expression.getThenExpression()));
|
||||||
return new JsConditional(isNotNullCheck(tempVar.value()), constructor.construct(tempVar.value()), JsLiteral.NULL);
|
return expression;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
//TODO: bang qualifier is not implemented in frontend for now
|
//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.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
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.context.TranslationContext;
|
||||||
import org.jetbrains.k2js.translate.general.Translation;
|
import org.jetbrains.k2js.translate.general.Translation;
|
||||||
|
|
||||||
@@ -76,6 +77,27 @@ public final class TranslationUtils {
|
|||||||
return new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL);
|
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
|
@NotNull
|
||||||
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
|
public static List<JsExpression> translateArgumentList(@NotNull TranslationContext context,
|
||||||
@NotNull List<? extends ValueArgument> jetArguments) {
|
@NotNull List<? extends ValueArgument> jetArguments) {
|
||||||
@@ -189,4 +211,19 @@ public final class TranslationUtils {
|
|||||||
return Pair.create(null, expression);
|
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