JS backend: added source mapping for some expressions.

(cherry picked from commit a35fe5a)
This commit is contained in:
develar
2013-09-20 17:10:53 +04:00
committed by Zalim Bashorov
parent 619e9758c8
commit 6878a0b657
11 changed files with 68 additions and 61 deletions
Binary file not shown.
Binary file not shown.
@@ -34,12 +34,12 @@ public class JsSourceGenerationVisitor extends JsToStringGenerationVisitor imple
}
@Override
public void visitProgramFragment(JsProgramFragment x, JsContext context) {
x.acceptChildren(this, context);
public void visitProgramFragment(JsProgramFragment x) {
x.acceptChildren(this);
}
@Override
public void visitBlock(JsBlock x, JsContext ctx) {
public void visitBlock(JsBlock x) {
printJsBlock(x, false, true);
}
@@ -60,9 +60,16 @@ public class JsSourceGenerationVisitor extends JsToStringGenerationVisitor imple
}
@Override
protected void doAccept(JsNode node, JsContext context) {
public void accept(JsNode node) {
if (!(node instanceof JsNameRef)) {
mapSource(node);
}
super.accept(node);
}
private void mapSource(JsNode node) {
if (sourceMapBuilder != null) {
Object sourceInfo = node.getSourceInfo();
Object sourceInfo = node.getSource();
if (sourceInfo != null) {
assert pendingSourceInfo == null;
if (p.isJustNewlined()) {
@@ -73,12 +80,16 @@ public class JsSourceGenerationVisitor extends JsToStringGenerationVisitor imple
}
}
}
super.doAccept(node, context);
}
@Override
public void visitProgram(JsProgram program, JsContext context) {
program.acceptChildren(this, context);
protected void beforeNodePrinted(JsNode node) {
mapSource(node);
}
@Override
public void visitProgram(JsProgram program) {
program.acceptChildren(this);
if (sourceMapBuilder != null) {
sourceMapBuilder.addLink();
}
@@ -113,7 +113,10 @@ public class SourceMap3Builder implements SourceMapBuilder {
out.append(',');
}
Base64VLQ.encode(out, textOutput.getColumn() - previousGeneratedColumn);
int columnDiff = textOutput.getColumn() - previousGeneratedColumn;
// TODO fix sections overlapping
// assert columnDiff != 0;
Base64VLQ.encode(out, columnDiff);
previousGeneratedColumn = textOutput.getColumn();
int sourceIndex = getSourceIndex(source);
Base64VLQ.encode(out, sourceIndex - previousSourceIndex);
@@ -100,7 +100,7 @@ public final class K2JSTranslator {
) throws TranslationException {
JsProgram program = generateProgram(files, mainCallParameters);
JsSourceGenerationVisitor sourceGenerator = new JsSourceGenerationVisitor(output, sourceMapBuilder);
program.accept(sourceGenerator, null);
program.accept(sourceGenerator);
return output.toString();
}
@@ -113,7 +113,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
jsBlock.getStatements().add(convertToStatement(jsNode));
}
}
return source(jsBlock, jetBlock);
return jsBlock;
}
@Override
@@ -128,8 +128,8 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsNode visitReturnExpression(@NotNull JetReturnExpression jetReturnExpression,
@NotNull TranslationContext context) {
JetExpression returnedExpression = jetReturnExpression.getReturnedExpression();
return source(new JsReturn(returnedExpression != null ? translateAsExpression(returnedExpression, context) : null), jetReturnExpression);
JetExpression returned = jetReturnExpression.getReturnedExpression();
return new JsReturn(returned != null ? translateAsExpression(returned, context) : null).source(jetReturnExpression);
}
@Override
@@ -164,14 +164,14 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
context.aliasingContext().registerAlias(descriptor, alias);
}
return source(newVar(name, initializer), expression);
return newVar(name, initializer).source(expression);
}
@Override
@NotNull
public JsNode visitCallExpression(@NotNull JetCallExpression expression,
@NotNull TranslationContext context) {
return source(CallExpressionTranslator.translate(expression, null, CallType.NORMAL, context), expression);
return CallExpressionTranslator.translate(expression, null, CallType.NORMAL, context).source(expression);
}
@Override
@@ -187,11 +187,11 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
boolean isKotlinStatement = BindingUtils.isStatement(context.bindingContext(), expression);
boolean canBeJsExpression = thenNode instanceof JsExpression && elseNode instanceof JsExpression;
if (!isKotlinStatement && canBeJsExpression) {
return source(new JsConditional(testExpression, convertToExpression(thenNode), convertToExpression(elseNode)), expression);
return new JsConditional(testExpression, convertToExpression(thenNode), convertToExpression(elseNode)).source(expression);
}
else {
JsIf ifStatement = new JsIf(testExpression, convertToStatement(thenNode), elseNode == null ? null : convertToStatement(elseNode));
source(ifStatement, expression);
ifStatement.source(expression);
if (isKotlinStatement) {
return ifStatement;
}
@@ -207,7 +207,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsExpression visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression,
@NotNull TranslationContext context) {
return ReferenceTranslator.translateSimpleName(expression, context);
return ReferenceTranslator.translateSimpleName(expression, context).source(expression);
}
@NotNull
@@ -251,7 +251,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
private JsNode createWhile(@NotNull JsWhile result, @NotNull JetWhileExpressionBase expression, @NotNull TranslationContext context) {
result.setCondition(translateConditionExpression(expression.getCondition(), context));
result.setBody(translateNullableExpressionAsNotNullStatement(expression.getBody(), context));
return source(result, expression);
return result.source(expression);
}
@Override
@@ -262,7 +262,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
if (stringLiteral != null) {
return stringLiteral;
}
return source(resolveAsTemplate(expression, context), expression);
return resolveAsTemplate(expression, context).source(expression);
}
@NotNull
@@ -298,22 +298,24 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
) {
JetSimpleNameExpression operationReference = expression.getOperationReference();
IElementType operationToken = operationReference.getReferencedNameElementType();
JsNode result;
if (JetTokens.LABELS.contains(operationToken)) {
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
return source(new JsLabel(context.scope().declareName(getReferencedName(operationReference)),
convertToStatement(baseExpression.accept(this, context))), expression);
result = new JsLabel(context.scope().declareName(getReferencedName(operationReference)),
convertToStatement(baseExpression.accept(this, context)));
}
else {
return UnaryOperationTranslator.translate(expression, context);
result = UnaryOperationTranslator.translate(expression, context);
}
return result.source(expression);
}
@Override
@NotNull
public JsNode visitPostfixExpression(@NotNull JetPostfixExpression expression,
@NotNull TranslationContext context) {
return UnaryOperationTranslator.translate(expression, context);
return UnaryOperationTranslator.translate(expression, context).source(expression);
}
@Override
@@ -327,7 +329,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsNode visitSafeQualifiedExpression(@NotNull JetSafeQualifiedExpression expression,
@NotNull TranslationContext context) {
return QualifiedExpressionTranslator.translateQualifiedExpression(expression, context);
return QualifiedExpressionTranslator.translateQualifiedExpression(expression, context).source(expression);
}
@Override
@@ -344,16 +346,16 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
JsExpression jsExpression = Translation.translateAsExpression(expression.getLeft(), context);
if (expression.getOperationReference().getReferencedNameElementType() != JetTokens.AS_KEYWORD)
return jsExpression;
return jsExpression.source(expression);
JetTypeReference type = expression.getRight();
assert type != null;
if (BindingContextUtils.getNotNull(context.bindingContext(), BindingContext.TYPE, type).isNullable())
return jsExpression;
return jsExpression.source(expression);
// KT-2670
// we actually do not care for types in js
return TranslationUtils.sure(jsExpression, context);
return TranslationUtils.sure(jsExpression, context).source(expression);
}
private static String getReferencedName(JetSimpleNameExpression expression) {
@@ -377,14 +379,14 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsNode visitBreakExpression(@NotNull JetBreakExpression expression,
@NotNull TranslationContext context) {
return source(new JsBreak(getTargetLabel(expression, context)), expression);
return new JsBreak(getTargetLabel(expression, context)).source(expression);
}
@Override
@NotNull
public JsNode visitContinueExpression(@NotNull JetContinueExpression expression,
@NotNull TranslationContext context) {
return source(new JsContinue(getTargetLabel(expression, context)), expression);
return new JsContinue(getTargetLabel(expression, context)).source(expression);
}
@Override
@@ -401,7 +403,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
JsExpression alias = context.literalFunctionTranslator().translate(expression, descriptor, context);
JsName name = context.scope().declareFreshName(descriptor.getName().asString());
context.aliasingContext().registerAlias(descriptor, name.makeRef());
return source(new JsVars(new JsVars.JsVar(name, alias)), expression);
return new JsVars(new JsVars.JsVar(name, alias)).source(expression);
}
@Override
@@ -410,7 +412,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
DeclarationDescriptor thisExpression =
getDescriptorForReferenceExpression(context.bindingContext(), expression.getInstanceReference());
assert thisExpression != null : "This expression must reference a descriptor: " + expression.getText();
return context.getThisObject(thisExpression);
return context.getThisObject(thisExpression).source(expression);
}
@Override
@@ -424,14 +426,14 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
public JsNode visitForExpression(@NotNull JetForExpression expression,
@NotNull TranslationContext context) {
return source(ForTranslator.translate(expression, context), expression);
return ForTranslator.translate(expression, context).source(expression);
}
@Override
@NotNull
public JsNode visitTryExpression(@NotNull JetTryExpression expression,
@NotNull TranslationContext context) {
return source(TryTranslator.translate(expression, context), expression);
return TryTranslator.translate(expression, context).source(expression);
}
@Override
@@ -440,7 +442,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull TranslationContext context) {
JetExpression thrownExpression = expression.getThrownExpression();
assert thrownExpression != null : "Thrown expression must not be null";
return source(new JsThrow(translateAsExpression(thrownExpression, context)), expression);
return new JsThrow(translateAsExpression(thrownExpression, context)).source(expression);
}
@Override
@@ -458,6 +460,6 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
DeclarationDescriptor descriptor = getDescriptorForElement(context.bindingContext(), objectDeclarationName);
JsName propertyName = context.getNameForDescriptor(descriptor);
JsExpression value = ClassTranslator.generateClassCreation(expression, context);
return source(newVar(propertyName, value), expression);
return newVar(propertyName, value).source(expression);
}
}
@@ -16,7 +16,9 @@
package org.jetbrains.k2js.translate.operation;
import com.google.dart.compiler.backend.js.ast.*;
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 org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
@@ -37,7 +39,6 @@ import static org.jetbrains.k2js.translate.operation.CompareToTranslator.isCompa
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.not;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.source;
import static org.jetbrains.k2js.translate.utils.PsiUtils.*;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
@@ -49,14 +50,14 @@ public final class BinaryOperationTranslator extends AbstractTranslator {
public static JsExpression translate(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
JsExpression jsExpression = new BinaryOperationTranslator(expression, context).translate();
return source(jsExpression, expression);
return jsExpression.source(expression);
}
@NotNull
/*package*/ static JsExpression translateAsOverloadedCall(@NotNull JetBinaryExpression expression,
@NotNull TranslationContext context) {
JsExpression jsExpression = (new BinaryOperationTranslator(expression, context)).translateAsOverloadedBinaryOperation();
return source(jsExpression, expression);
return jsExpression.source(expression);
}
@NotNull
@@ -38,7 +38,6 @@ import java.util.List;
import static org.jetbrains.k2js.translate.reference.CallParametersResolver.resolveCallParameters;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier;
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.isConstructorDescriptor;
//TODO: write tests on calling backing fields as functions
public final class CallTranslator extends AbstractTranslator {
@@ -83,7 +82,7 @@ public final class CallTranslator extends AbstractTranslator {
if (result != null) {
return result;
}
if (isConstructor()) {
if ((descriptor instanceof ConstructorDescriptor)) {
return createConstructorCallExpression(translateAsFunctionWithNoThisObject(descriptor));
}
if (resolvedCall.getReceiverArgument().exists()) {
@@ -124,10 +123,6 @@ public final class CallTranslator extends AbstractTranslator {
return null;
}
private boolean isConstructor() {
return isConstructorDescriptor(descriptor);
}
@NotNull
public HasArguments createConstructorCallExpression(@NotNull JsExpression constructorReference) {
return new JsNew(constructorReference, arguments);
@@ -56,10 +56,12 @@ public final class QualifiedExpressionTranslator {
}
@NotNull
private static JsExpression dispatchToCorrectTranslator(@Nullable JsExpression receiver,
@NotNull JetExpression selector,
@NotNull CallType callType,
@NotNull TranslationContext context) {
private static JsExpression dispatchToCorrectTranslator(
@Nullable JsExpression receiver,
@NotNull JetExpression selector,
@NotNull CallType callType,
@NotNull TranslationContext context
) {
if (PropertyAccessTranslator.canBePropertyGetterCall(selector, context)) {
assert selector instanceof JetSimpleNameExpression : "Selectors for properties must be simple names.";
return PropertyAccessTranslator.translateAsPropertyGetterCall
@@ -20,6 +20,10 @@ import com.google.dart.compiler.backend.js.ast.*;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
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.Modality;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.k2js.translate.context.TranslationContext;
@@ -240,11 +244,4 @@ public final class JsAstUtils {
public static JsObjectLiteral wrapValue(@NotNull JsExpression label, @NotNull JsExpression value) {
return new JsObjectLiteral(Collections.singletonList(new JsPropertyInitializer(label, value)));
}
@NotNull
public static <T extends JsNode> T source(@NotNull T jsNode, @NotNull JetElement ktElement) {
jsNode.setSourceInfo(ktElement);
return jsNode;
}
}
@@ -52,10 +52,6 @@ public final class JsDescriptorUtils {
return (functionDescriptor.getName().equals(OperatorConventions.COMPARE_TO));
}
public static boolean isConstructorDescriptor(@NotNull CallableDescriptor descriptor) {
return (descriptor instanceof ConstructorDescriptor);
}
@Nullable
public static ClassDescriptor findAncestorClass(@NotNull List<ClassDescriptor> superclassDescriptors) {
for (ClassDescriptor descriptor : superclassDescriptors) {