Fix JS source maps for delegates and backing fields
This commit is contained in:
@@ -42,6 +42,12 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("backingField.kt")
|
||||
public void testBackingField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/backingField.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("catch.kt")
|
||||
public void testCatch() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/catch.kt");
|
||||
@@ -78,6 +84,18 @@ public class JsLineNumberTestGenerated extends AbstractJsLineNumberTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegatedProperty.kt")
|
||||
public void testDelegatedProperty() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/delegatedProperty.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegation.kt")
|
||||
public void testDelegation() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/delegation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doWhileWithComplexCondition.kt")
|
||||
public void testDoWhileWithComplexCondition() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/lineNumbers/doWhileWithComplexCondition.kt");
|
||||
|
||||
+4
-2
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.hasOrInheritsParametersWithDe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOwnParametersWithDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.utils.identity
|
||||
|
||||
class ClassModelGenerator(val context: StaticContext) {
|
||||
@@ -192,7 +193,8 @@ class ClassModelGenerator(val context: StaticContext) {
|
||||
val sourceName = context.getNameForDescriptor(key).ident
|
||||
val targetName = context.getNameForDescriptor(value).ident
|
||||
if (sourceName != targetName) {
|
||||
val statement = generateDelegateCall(descriptor, key, value, JsThisRef(), translationContext, false)
|
||||
val statement = generateDelegateCall(descriptor, key, value, JsThisRef(), translationContext, false,
|
||||
descriptor.source.getPsi())
|
||||
model.postDeclarationBlock.statements += statement
|
||||
}
|
||||
}
|
||||
@@ -229,7 +231,7 @@ class ClassModelGenerator(val context: StaticContext) {
|
||||
|
||||
val translationContext = TranslationContext.rootContext(context)
|
||||
model.postDeclarationBlock.statements += generateDelegateCall(descriptor, fromDescriptor, toDescriptor, JsThisRef(),
|
||||
translationContext, false)
|
||||
translationContext, false, descriptor.source.getPsi())
|
||||
}
|
||||
|
||||
private fun copyMethod(
|
||||
|
||||
+13
-7
@@ -77,27 +77,29 @@ class DelegationTranslator(
|
||||
val delegateInitExpr = Translation.translateAsExpression(expression, context)
|
||||
statements += context.dynamicContext().jsBlock().statements
|
||||
val lhs = JsAstUtils.pureFqn(field.name, JsThisRef())
|
||||
statements += JsAstUtils.assignment(lhs, delegateInitExpr).makeStmt()
|
||||
statements += JsAstUtils.assignment(lhs, delegateInitExpr)
|
||||
.apply { source = specifier }
|
||||
.makeStmt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generateDelegated() {
|
||||
for (specifier in delegationBySpecifiers) {
|
||||
generateDelegates(getSuperClass(specifier), fields[specifier]!!)
|
||||
generateDelegates(specifier, getSuperClass(specifier), fields[specifier]!!)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSuperClass(specifier: KtSuperTypeListEntry): ClassDescriptor =
|
||||
CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext())
|
||||
|
||||
private fun generateDelegates(toClass: ClassDescriptor, field: Field) {
|
||||
private fun generateDelegates(specifier: KtSuperTypeListEntry, toClass: ClassDescriptor, field: Field) {
|
||||
for ((descriptor, overriddenDescriptor) in DelegationResolver.getDelegates(classDescriptor, toClass)) {
|
||||
when (descriptor) {
|
||||
is PropertyDescriptor ->
|
||||
generateDelegateCallForPropertyMember(descriptor, field.name)
|
||||
generateDelegateCallForPropertyMember(specifier, descriptor, field.name)
|
||||
is FunctionDescriptor ->
|
||||
generateDelegateCallForFunctionMember(descriptor, overriddenDescriptor as FunctionDescriptor, field.name)
|
||||
generateDelegateCallForFunctionMember(specifier, descriptor, overriddenDescriptor as FunctionDescriptor, field.name)
|
||||
else ->
|
||||
throw IllegalArgumentException("Expected property or function $descriptor")
|
||||
}
|
||||
@@ -105,6 +107,7 @@ class DelegationTranslator(
|
||||
}
|
||||
|
||||
private fun generateDelegateCallForPropertyMember(
|
||||
specifier: KtSuperTypeListEntry,
|
||||
descriptor: PropertyDescriptor,
|
||||
delegateName: JsName
|
||||
) {
|
||||
@@ -122,6 +125,8 @@ class DelegationTranslator(
|
||||
JsNameRef(propertyName, delegateRef)
|
||||
}
|
||||
|
||||
returnExpression.source(specifier)
|
||||
|
||||
val jsFunction = simpleReturnFunction(context().getScopeForDescriptor(getterDescriptor.containingDeclaration), returnExpression)
|
||||
if (DescriptorUtils.isExtension(descriptor)) {
|
||||
val receiverName = jsFunction.scope.declareName(Namer.getReceiverParameterName())
|
||||
@@ -154,7 +159,7 @@ class DelegationTranslator(
|
||||
}
|
||||
|
||||
jsFunction.parameters.add(defaultParameter)
|
||||
jsFunction.body = JsBlock(setExpression.makeStmt())
|
||||
jsFunction.body = JsBlock(setExpression.apply { source = specifier }.makeStmt())
|
||||
return jsFunction
|
||||
}
|
||||
|
||||
@@ -191,12 +196,13 @@ class DelegationTranslator(
|
||||
|
||||
|
||||
private fun generateDelegateCallForFunctionMember(
|
||||
specifier: KtSuperTypeListEntry,
|
||||
descriptor: FunctionDescriptor,
|
||||
overriddenDescriptor: FunctionDescriptor,
|
||||
delegateName: JsName
|
||||
) {
|
||||
val delegateRef = JsNameRef(delegateName, JsThisRef())
|
||||
val statement = generateDelegateCall(classDescriptor, descriptor, overriddenDescriptor, delegateRef, context(), true)
|
||||
val statement = generateDelegateCall(classDescriptor, descriptor, overriddenDescriptor, delegateRef, context(), true, specifier)
|
||||
context().addDeclarationStatement(statement)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-4
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
|
||||
/**
|
||||
* Translates single property /w accessors.
|
||||
@@ -92,7 +93,7 @@ class DefaultPropertyTranslator(
|
||||
assert(!descriptor.isExtension) { "Unexpected extension property $descriptor}" }
|
||||
assert(descriptor is PropertyDescriptor) { "Property descriptor expected: $descriptor" }
|
||||
val result = backingFieldReference(context(), descriptor as PropertyDescriptor)
|
||||
function.body.statements += JsReturn(result)
|
||||
function.body.statements += JsReturn(result).apply { source = descriptor.source.getPsi() }
|
||||
}
|
||||
|
||||
private fun generateDelegatedGetterFunction(
|
||||
@@ -105,7 +106,9 @@ class DefaultPropertyTranslator(
|
||||
.newDeclarationIfNecessary(getterDescriptor, function)
|
||||
.contextWithPropertyMetadataCreationIntrinsified(delegatedCall, descriptor, host)
|
||||
|
||||
val delegatedJsCall = CallTranslator.translate(delegateContext, delegatedCall, delegateReference)
|
||||
val delegatedJsCall = CallTranslator.translate(delegateContext, delegatedCall, delegateReference).apply {
|
||||
source = getterDescriptor.source.getPsi()
|
||||
}
|
||||
|
||||
val returnResult = JsReturn(delegatedJsCall)
|
||||
function.addStatement(returnResult)
|
||||
@@ -123,14 +126,16 @@ class DefaultPropertyTranslator(
|
||||
val delegateContext = withAliased
|
||||
.newDeclarationIfNecessary(setterDescriptor, function)
|
||||
.contextWithPropertyMetadataCreationIntrinsified(delegatedCall, descriptor, host)
|
||||
val delegatedJsCall = CallTranslator.translate(delegateContext, delegatedCall, delegateReference)
|
||||
val delegatedJsCall = CallTranslator.translate(delegateContext, delegatedCall, delegateReference).apply {
|
||||
source = setterDescriptor.source.getPsi()
|
||||
}
|
||||
function.addStatement(delegatedJsCall.makeStmt())
|
||||
}
|
||||
else {
|
||||
assert(!descriptor.isExtension) { "Unexpected extension property $descriptor}" }
|
||||
assert(descriptor is PropertyDescriptor) { "Property descriptor expected: $descriptor" }
|
||||
val assignment = assignmentToBackingField(withAliased, descriptor as PropertyDescriptor, valueParameter.makeRef())
|
||||
function.addStatement(assignment.makeStmt())
|
||||
function.addStatement(assignment.apply { source = descriptor.source.getPsi() }.makeStmt())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.js.translate.utils
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.backend.common.COROUTINES_INTRINSICS_PACKAGE_FQ_NAME
|
||||
import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME
|
||||
@@ -45,7 +46,8 @@ fun generateDelegateCall(
|
||||
toDescriptor: FunctionDescriptor,
|
||||
thisObject: JsExpression,
|
||||
context: TranslationContext,
|
||||
detectDefaultParameters: Boolean
|
||||
detectDefaultParameters: Boolean,
|
||||
source: PsiElement?
|
||||
): JsStatement {
|
||||
fun FunctionDescriptor.getNameForFunctionWithPossibleDefaultParam() =
|
||||
if (detectDefaultParameters && hasOrInheritsParametersWithDefaultValue()) {
|
||||
@@ -82,6 +84,8 @@ fun generateDelegateCall(
|
||||
JsInvocation(overriddenMemberFunctionRef, args)
|
||||
}
|
||||
|
||||
invocation.source = source
|
||||
|
||||
val functionObject = simpleReturnFunction(context.scope(), invocation)
|
||||
functionObject.parameters.addAll(parameters)
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
open class A {
|
||||
open var x = 23
|
||||
|
||||
var y: String = "42"
|
||||
get() = field +
|
||||
"!"
|
||||
set(value) {
|
||||
print(
|
||||
field)
|
||||
field =
|
||||
value.removeSuffix("!")
|
||||
}
|
||||
}
|
||||
|
||||
// LINES: 2 4 2 2 * 5 6 8 9 10 11
|
||||
@@ -0,0 +1,18 @@
|
||||
import kotlin.reflect.*
|
||||
|
||||
open class A {
|
||||
var x: String by
|
||||
B()
|
||||
}
|
||||
|
||||
class B {
|
||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
println(value)
|
||||
}
|
||||
}
|
||||
|
||||
// LINES: 4 5 4 4 2 * 10 * 14
|
||||
@@ -0,0 +1,21 @@
|
||||
class A :
|
||||
I
|
||||
by o
|
||||
|
||||
interface I {
|
||||
fun foo(): String
|
||||
|
||||
var bar: Int
|
||||
}
|
||||
|
||||
val o = object : I {
|
||||
override fun foo(): String = "foo"
|
||||
|
||||
override var bar: Int
|
||||
get() = 23
|
||||
set(value) {
|
||||
println(value)
|
||||
}
|
||||
}
|
||||
|
||||
// LINES: 2 3 2 2 * 2 * 12 * 15 17
|
||||
Reference in New Issue
Block a user