Fix generation of JS source maps for synthetic code in constructors
This commit is contained in:
@@ -65,4 +65,10 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/simple.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/simple.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("syntheticCodeInConstructors.kt")
|
||||||
|
public void testSyntheticCodeInConstructors() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/syntheticCodeInConstructors.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,12 +74,14 @@ public class AliasingContext {
|
|||||||
public JsExpression getAliasForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
public JsExpression getAliasForDescriptor(@NotNull DeclarationDescriptor descriptor) {
|
||||||
// these aliases cannot be shared and applicable only in current context
|
// these aliases cannot be shared and applicable only in current context
|
||||||
JsExpression alias = aliasesForDescriptors != null ? aliasesForDescriptors.get(descriptor.getOriginal()) : null;
|
JsExpression alias = aliasesForDescriptors != null ? aliasesForDescriptors.get(descriptor.getOriginal()) : null;
|
||||||
return alias != null || parent == null ? alias : parent.getAliasForDescriptor(descriptor);
|
JsExpression result = alias != null || parent == null ? alias : parent.getAliasForDescriptor(descriptor);
|
||||||
|
return result != null ? result.deepCopy() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public JsExpression getAliasForExpression(@NotNull KtExpression element) {
|
public JsExpression getAliasForExpression(@NotNull KtExpression element) {
|
||||||
JsExpression alias = aliasesForExpressions != null ? aliasesForExpressions.get(element) : null;
|
JsExpression alias = aliasesForExpressions != null ? aliasesForExpressions.get(element) : null;
|
||||||
return alias != null || parent == null ? alias : parent.getAliasForExpression(element);
|
JsExpression result = alias != null || parent == null ? alias : parent.getAliasForExpression(element);
|
||||||
|
return result != null ? result.deepCopy() : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -66,6 +66,9 @@ public final class DynamicContext {
|
|||||||
JsVar var = new JsVar(temporaryName, null);
|
JsVar var = new JsVar(temporaryName, null);
|
||||||
MetadataProperties.setSynthetic(var, true);
|
MetadataProperties.setSynthetic(var, true);
|
||||||
vars.add(var);
|
vars.add(var);
|
||||||
|
if (initExpression != null) {
|
||||||
|
var.source(initExpression.getSource());
|
||||||
|
}
|
||||||
return TemporaryVariable.create(temporaryName, initExpression);
|
return TemporaryVariable.create(temporaryName, initExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+18
-10
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -158,7 +158,8 @@ class ClassTranslator private constructor(
|
|||||||
val function = context().createRootScopedFunction(descriptor)
|
val function = context().createRootScopedFunction(descriptor)
|
||||||
function.name = JsScope.declareTemporaryName(StaticContext.getSuggestedName(descriptor) + "_initFields")
|
function.name = JsScope.declareTemporaryName(StaticContext.getSuggestedName(descriptor) + "_initFields")
|
||||||
val emptyFunction = context().createRootScopedFunction(descriptor)
|
val emptyFunction = context().createRootScopedFunction(descriptor)
|
||||||
function.body.statements += JsAstUtils.assignment(JsAstUtils.pureFqn(function.name, null), emptyFunction).makeStmt()
|
function.body.statements += JsAstUtils.assignment(JsAstUtils.pureFqn(function.name, null), emptyFunction)
|
||||||
|
.source(classDeclaration).makeStmt()
|
||||||
context().addDeclarationStatement(function.makeStmt())
|
context().addDeclarationStatement(function.makeStmt())
|
||||||
return function
|
return function
|
||||||
}
|
}
|
||||||
@@ -229,7 +230,8 @@ class ClassTranslator private constructor(
|
|||||||
superCallGenerators += { it += FunctionBodyTranslator.setDefaultValueForArguments(constructorDescriptor, context) }
|
superCallGenerators += { it += FunctionBodyTranslator.setDefaultValueForArguments(constructorDescriptor, context) }
|
||||||
|
|
||||||
val createInstance = Namer.createObjectWithPrototypeFrom(referenceToClass)
|
val createInstance = Namer.createObjectWithPrototypeFrom(referenceToClass)
|
||||||
val instanceVar = JsAstUtils.assignment(thisNameRef, JsAstUtils.or(thisNameRef, createInstance)).makeStmt()
|
val instanceVar = JsAstUtils.assignment(thisNameRef.deepCopy(), JsAstUtils.or(thisNameRef.deepCopy(), createInstance))
|
||||||
|
.source(constructor).makeStmt()
|
||||||
superCallGenerators += { it += instanceVar }
|
superCallGenerators += { it += instanceVar }
|
||||||
|
|
||||||
// Add parameter for outer instance
|
// Add parameter for outer instance
|
||||||
@@ -265,8 +267,10 @@ class ClassTranslator private constructor(
|
|||||||
superCallGenerators += {
|
superCallGenerators += {
|
||||||
val delegationConstructor = resolvedCall.resultingDescriptor
|
val delegationConstructor = resolvedCall.resultingDescriptor
|
||||||
val innerContext = context.innerBlock()
|
val innerContext = context.innerBlock()
|
||||||
val statement = CallTranslator.translate(innerContext, resolvedCall)
|
val statement = CallTranslator.translate(innerContext, resolvedCall).toInvocationWith(
|
||||||
.toInvocationWith(leadingArgs, delegationConstructor.valueParameters.size, thisNameRef).makeStmt()
|
leadingArgs, delegationConstructor.valueParameters.size, thisNameRef.deepCopy())
|
||||||
|
.source(resolvedCall.call.callElement)
|
||||||
|
.makeStmt()
|
||||||
it += innerContext.currentBlock.statements
|
it += innerContext.currentBlock.statements
|
||||||
it += statement
|
it += statement
|
||||||
}
|
}
|
||||||
@@ -280,11 +284,14 @@ class ClassTranslator private constructor(
|
|||||||
val closure = context.getClassOrConstructorClosure(classDescriptor).orEmpty().map {
|
val closure = context.getClassOrConstructorClosure(classDescriptor).orEmpty().map {
|
||||||
usageTracker.getNameForCapturedDescriptor(it)!!.makeRef()
|
usageTracker.getNameForCapturedDescriptor(it)!!.makeRef()
|
||||||
}
|
}
|
||||||
it += JsInvocation(Namer.getFunctionCallRef(referenceToClass), listOf(thisNameRef) + closure + leadingArgs).makeStmt()
|
it += JsInvocation(Namer.getFunctionCallRef(referenceToClass), listOf(thisNameRef.deepCopy()) + closure + leadingArgs)
|
||||||
|
.source(classDeclaration).makeStmt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructorInitializer.body.statements += JsReturn(thisNameRef)
|
constructorInitializer.body.statements += JsReturn(thisNameRef.deepCopy()).apply {
|
||||||
|
source = constructor
|
||||||
|
}
|
||||||
|
|
||||||
val compositeSuperCallGenerator: () -> Unit = {
|
val compositeSuperCallGenerator: () -> Unit = {
|
||||||
val additionalStatements = mutableListOf<JsStatement>()
|
val additionalStatements = mutableListOf<JsStatement>()
|
||||||
@@ -310,8 +317,9 @@ class ClassTranslator private constructor(
|
|||||||
val constructorMap = allConstructors.map { it.descriptor to it }.toMap()
|
val constructorMap = allConstructors.map { it.descriptor to it }.toMap()
|
||||||
|
|
||||||
val callSiteMap = callSites.groupBy {
|
val callSiteMap = callSites.groupBy {
|
||||||
val constructor = it.constructor
|
val constructor = it.constructor
|
||||||
if (constructor.isPrimary) constructor.containingDeclaration else constructor
|
val result: DeclarationDescriptor = if (constructor.isPrimary) constructor.containingDeclaration else constructor
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
val thisCalls = secondaryConstructors.map {
|
val thisCalls = secondaryConstructors.map {
|
||||||
@@ -437,7 +445,7 @@ class ClassTranslator private constructor(
|
|||||||
|
|
||||||
private fun addObjectCache(statements: MutableList<JsStatement>) {
|
private fun addObjectCache(statements: MutableList<JsStatement>) {
|
||||||
cachedInstanceName = JsScope.declareTemporaryName(StaticContext.getSuggestedName(descriptor) + Namer.OBJECT_INSTANCE_VAR_SUFFIX)
|
cachedInstanceName = JsScope.declareTemporaryName(StaticContext.getSuggestedName(descriptor) + Namer.OBJECT_INSTANCE_VAR_SUFFIX)
|
||||||
statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsObjectLiteral.THIS).makeStmt()
|
statements += JsAstUtils.assignment(cachedInstanceName.makeRef(), JsObjectLiteral.THIS).source(classDeclaration).makeStmt()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addObjectMethods() {
|
private fun addObjectMethods() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
+8
-5
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.translate.initializer;
|
package org.jetbrains.kotlin.js.translate.initializer;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
@@ -48,6 +49,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -173,14 +175,14 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
private void mayBeAddCallToSuperMethod(JsFunction initializer) {
|
private void mayBeAddCallToSuperMethod(JsFunction initializer) {
|
||||||
if (classDeclaration.hasModifier(KtTokens.ENUM_KEYWORD)) {
|
if (classDeclaration.hasModifier(KtTokens.ENUM_KEYWORD)) {
|
||||||
addCallToSuperMethod(Collections.emptyList(), initializer);
|
addCallToSuperMethod(Collections.emptyList(), initializer, classDeclaration);
|
||||||
}
|
}
|
||||||
else if (hasAncestorClass(bindingContext(), classDeclaration)) {
|
else if (hasAncestorClass(bindingContext(), classDeclaration)) {
|
||||||
ResolvedCall<FunctionDescriptor> superCall = getSuperCall(bindingContext(), classDeclaration);
|
ResolvedCall<FunctionDescriptor> superCall = getSuperCall(bindingContext(), classDeclaration);
|
||||||
|
|
||||||
if (superCall == null) {
|
if (superCall == null) {
|
||||||
if (DescriptorUtils.isEnumEntry(classDescriptor)) {
|
if (DescriptorUtils.isEnumEntry(classDescriptor)) {
|
||||||
addCallToSuperMethod(getAdditionalArgumentsForEnumConstructor(), initializer);
|
addCallToSuperMethod(getAdditionalArgumentsForEnumConstructor(), initializer, classDeclaration);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -234,7 +236,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (superDescriptor.isPrimary()) {
|
if (superDescriptor.isPrimary()) {
|
||||||
addCallToSuperMethod(arguments, initializer);
|
addCallToSuperMethod(arguments, initializer, superCall.getCall().getCallElement());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int maxValueArgumentIndex = 0;
|
int maxValueArgumentIndex = 0;
|
||||||
@@ -325,7 +327,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
return additionalArguments;
|
return additionalArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCallToSuperMethod(@NotNull List<JsExpression> arguments, @NotNull JsFunction initializer) {
|
private void addCallToSuperMethod(@NotNull List<JsExpression> arguments, @NotNull JsFunction initializer, @NotNull PsiElement psi) {
|
||||||
if (initializer.getName() == null) {
|
if (initializer.getName() == null) {
|
||||||
JsName ref = context().scope().declareName(Namer.CALLEE_NAME);
|
JsName ref = context().scope().declareName(Namer.CALLEE_NAME);
|
||||||
initializer.setName(ref);
|
initializer.setName(ref);
|
||||||
@@ -334,6 +336,7 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
|||||||
ClassDescriptor superclassDescriptor = DescriptorUtilsKt.getSuperClassOrAny(classDescriptor);
|
ClassDescriptor superclassDescriptor = DescriptorUtilsKt.getSuperClassOrAny(classDescriptor);
|
||||||
JsExpression superConstructorRef = context().getInnerReference(superclassDescriptor);
|
JsExpression superConstructorRef = context().getInnerReference(superclassDescriptor);
|
||||||
JsInvocation call = new JsInvocation(Namer.getFunctionCallRef(superConstructorRef));
|
JsInvocation call = new JsInvocation(Namer.getFunctionCallRef(superConstructorRef));
|
||||||
|
call.setSource(psi);
|
||||||
call.getArguments().add(JsLiteral.THIS);
|
call.getArguments().add(JsLiteral.THIS);
|
||||||
call.getArguments().addAll(arguments);
|
call.getArguments().addAll(arguments);
|
||||||
initFunction.getBody().getStatements().add(call.makeStmt());
|
initFunction.getBody().getStatements().add(call.makeStmt());
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ object O {
|
|||||||
val y = 23
|
val y = 23
|
||||||
}
|
}
|
||||||
|
|
||||||
// LINES: 2 3 4 6 7 8 12
|
// LINES: 2 3 4 6 7 8 11 12
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
object O {
|
||||||
|
init {
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class A(x: Int)
|
||||||
|
|
||||||
|
class B :
|
||||||
|
A(
|
||||||
|
23
|
||||||
|
)
|
||||||
|
|
||||||
|
class C : A {
|
||||||
|
constructor(x: Int) :
|
||||||
|
super(
|
||||||
|
x
|
||||||
|
) {
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() :
|
||||||
|
this (
|
||||||
|
42
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LINES: 1 3 * 10 11 * 15 16 17 14 19 15 22 23 24 22
|
||||||
Reference in New Issue
Block a user