JS backend: expand jsCode at translator
This commit is contained in:
@@ -14,5 +14,6 @@
|
||||
<orderEntry type="module" module-name="js.dart-ast" exported="" />
|
||||
<orderEntry type="module" module-name="js.frontend" exported="" />
|
||||
<orderEntry type="module" module-name="js.inliner" exported="" />
|
||||
<orderEntry type="module" module-name="js.parser" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -191,8 +191,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
if (shouldBeInlined(expression, context) &&
|
||||
BindingContextUtilPackage.isUsedAsExpression(expression, context.bindingContext())) {
|
||||
TemporaryVariable temporaryVariable = context.declareTemporary(null);
|
||||
JsExpression callResult = CallExpressionTranslator.translate(expression, null, context).source(expression);
|
||||
context.addStatementToCurrentBlock(JsAstUtils.assignment(temporaryVariable.reference(), callResult).makeStmt());
|
||||
|
||||
JsNode callResult = CallExpressionTranslator.translate(expression, null, context).source(expression);
|
||||
assert callResult instanceof JsExpression;
|
||||
|
||||
JsExpression assignment = JsAstUtils.assignment(temporaryVariable.reference(), (JsExpression) callResult);
|
||||
context.addStatementToCurrentBlock(assignment.makeStmt());
|
||||
return temporaryVariable.reference();
|
||||
} else {
|
||||
return CallExpressionTranslator.translate(expression, null, context).source(expression);
|
||||
|
||||
+81
-9
@@ -16,32 +16,51 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.reference;
|
||||
|
||||
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.*;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.MetadataPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
import com.google.dart.compiler.common.SourceInfoImpl;
|
||||
import com.google.gwt.dev.js.JsParser;
|
||||
import com.google.gwt.dev.js.JsParserException;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall;
|
||||
import org.jetbrains.jet.lang.types.lang.InlineStrategy;
|
||||
import org.jetbrains.jet.lang.types.lang.InlineUtil;
|
||||
import org.jetbrains.jet.lang.psi.ValueArgument;
|
||||
import org.jetbrains.k2js.translate.callTranslator.CallTranslator;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.DescriptorPredicate;
|
||||
import org.jetbrains.k2js.translate.intrinsic.functions.patterns.PatternBuilder;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage.getFunctionResolvedCallWithAssert;
|
||||
|
||||
public final class CallExpressionTranslator extends AbstractCallExpressionTranslator {
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translate(
|
||||
private final static DescriptorPredicate JSCODE_PATTERN = PatternBuilder.pattern("kotlin.js.js(String)");
|
||||
|
||||
@NotNull
|
||||
public static JsNode translate(
|
||||
@NotNull JetCallExpression expression,
|
||||
@Nullable JsExpression receiver,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
if (matchesJsCode(expression, context)) {
|
||||
return (new CallExpressionTranslator(expression, receiver, context)).translateJsCode();
|
||||
}
|
||||
|
||||
JsExpression callExpression = (new CallExpressionTranslator(expression, receiver, context)).translate();
|
||||
|
||||
if (shouldBeInlined(expression, context)
|
||||
@@ -80,6 +99,16 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean matchesJsCode(
|
||||
@NotNull JetCallExpression expression,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
FunctionDescriptor descriptor = getFunctionResolvedCallWithAssert(expression, context.bindingContext())
|
||||
.getResultingDescriptor();
|
||||
|
||||
return JSCODE_PATTERN.apply(descriptor) && expression.getValueArguments().size() == 1;
|
||||
}
|
||||
|
||||
private CallExpressionTranslator(
|
||||
@NotNull JetCallExpression expression,
|
||||
@Nullable JsExpression receiver,
|
||||
@@ -92,4 +121,47 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
|
||||
private JsExpression translate() {
|
||||
return CallTranslator.INSTANCE$.translate(context(), resolvedCall, receiver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode translateJsCode() {
|
||||
List<? extends ValueArgument> arguments = expression.getValueArguments();
|
||||
JetExpression argumentExpression = arguments.get(0).getArgumentExpression();
|
||||
assert argumentExpression != null;
|
||||
|
||||
Object jsCode = BindingUtils.getCompileTimeValue(bindingContext(), argumentExpression);
|
||||
assert jsCode instanceof String: "jsCode must be compile time string";
|
||||
List<JsStatement> statements = parseJsCode((String) jsCode);
|
||||
int size = statements.size();
|
||||
|
||||
if (size == 0) {
|
||||
return program().getEmptyStatement();
|
||||
} else if (size > 1) {
|
||||
return new JsBlock(statements);
|
||||
} else {
|
||||
JsStatement resultStatement = statements.get(0);
|
||||
if (resultStatement instanceof JsExpressionStatement) {
|
||||
return ((JsExpressionStatement) resultStatement).getExpression();
|
||||
}
|
||||
|
||||
return resultStatement;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JsStatement> parseJsCode(@NotNull String jsCode) {
|
||||
List<JsStatement> statements = new ArrayList<JsStatement>();
|
||||
|
||||
try {
|
||||
SourceInfoImpl info = new SourceInfoImpl(null, 0, 0, 0, 0);
|
||||
JsScope scope = context().scope();
|
||||
StringReader reader = new StringReader(jsCode);
|
||||
statements.addAll(JsParser.parse(info, scope, reader, /* insideFunction= */ true));
|
||||
} catch (JsParserException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return statements;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-6
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.k2js.translate.reference;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
@@ -52,15 +53,17 @@ public final class QualifiedExpressionTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateQualifiedExpression(@NotNull JetQualifiedExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
public static JsNode translateQualifiedExpression(
|
||||
@NotNull JetQualifiedExpression expression,
|
||||
@NotNull TranslationContext context
|
||||
) {
|
||||
JsExpression receiver = translateReceiver(expression, context);
|
||||
JetExpression selector = getSelector(expression);
|
||||
return dispatchToCorrectTranslator(receiver, selector, context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsExpression dispatchToCorrectTranslator(
|
||||
private static JsNode dispatchToCorrectTranslator(
|
||||
@Nullable JsExpression receiver,
|
||||
@NotNull JetExpression selector,
|
||||
@NotNull TranslationContext context
|
||||
@@ -73,8 +76,12 @@ public final class QualifiedExpressionTranslator {
|
||||
if (shouldBeInlined((JetCallExpression) selector, context) &&
|
||||
BindingContextUtilPackage.isUsedAsExpression(selector, context.bindingContext())) {
|
||||
TemporaryVariable temporaryVariable = context.declareTemporary(null);
|
||||
JsExpression result = invokeCallExpressionTranslator(receiver, selector, context);
|
||||
context.addStatementToCurrentBlock(JsAstUtils.assignment(temporaryVariable.reference(), result).makeStmt());
|
||||
|
||||
JsNode result = invokeCallExpressionTranslator(receiver, selector, context);
|
||||
assert result instanceof JsExpression;
|
||||
|
||||
JsExpression assignment = JsAstUtils.assignment(temporaryVariable.reference(), (JsExpression) result);
|
||||
context.addStatementToCurrentBlock(assignment.makeStmt());
|
||||
return temporaryVariable.reference();
|
||||
} else {
|
||||
return invokeCallExpressionTranslator(receiver, selector, context);
|
||||
@@ -88,7 +95,7 @@ public final class QualifiedExpressionTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsExpression invokeCallExpressionTranslator(
|
||||
private static JsNode invokeCallExpressionTranslator(
|
||||
@Nullable JsExpression receiver,
|
||||
@NotNull JetExpression selector,
|
||||
@NotNull TranslationContext context
|
||||
|
||||
Reference in New Issue
Block a user