[KT-4124] Add support for super<T>@Outer.functionName() case
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
// Local classes are still unsupported
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
open class C(s: Int) {
|
open class C(s: Int) {
|
||||||
fun test() {
|
fun test() {
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ import java.util.regex.Pattern;
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class SuperTestGenerated extends AbstractSuperTest {
|
public class SuperTestGenerated extends AbstractSuperTest {
|
||||||
|
@TestMetadata("kt4173_3.kt")
|
||||||
|
public void ignoredKt4173_3() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt4173_3.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public void testAllFilesPresentInSuper() throws Exception {
|
public void testAllFilesPresentInSuper() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/super"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/super"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
@@ -125,12 +131,6 @@ public class SuperTestGenerated extends AbstractSuperTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("kt4173_3.kt")
|
|
||||||
public void testKt4173_3() throws Exception {
|
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt4173_3.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("kt4982.kt")
|
@TestMetadata("kt4982.kt")
|
||||||
public void testKt4982() throws Exception {
|
public void testKt4982() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt4982.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt4982.kt");
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
|
|||||||
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
||||||
import com.google.dart.compiler.backend.js.ast.JsConditional
|
import com.google.dart.compiler.backend.js.ast.JsConditional
|
||||||
import com.google.dart.compiler.backend.js.ast.JsBlock
|
import com.google.dart.compiler.backend.js.ast.JsBlock
|
||||||
|
import org.jetbrains.kotlin.js.translate.general.Translation
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.psi.KtSuperExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
|
||||||
|
|
||||||
interface CallInfo {
|
interface CallInfo {
|
||||||
val context: TranslationContext
|
val context: TranslationContext
|
||||||
@@ -55,6 +60,31 @@ class VariableAccessInfo(callInfo: CallInfo, val value: JsExpression? = null) :
|
|||||||
|
|
||||||
class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : AbstractCallInfo(), CallInfo by callInfo
|
class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : AbstractCallInfo(), CallInfo by callInfo
|
||||||
|
|
||||||
|
val CallInfo.superCallReceiver : JsExpression?
|
||||||
|
get() {
|
||||||
|
val receiver = this.resolvedCall.dispatchReceiver
|
||||||
|
return when (receiver) {
|
||||||
|
is ExpressionReceiver -> {
|
||||||
|
val expr = receiver.expression
|
||||||
|
when (expr) {
|
||||||
|
is KtSuperExpression -> {
|
||||||
|
val superDescriptor = context.getSuperTarget(expr);
|
||||||
|
context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(superDescriptor))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Translation.translateAsExpression(receiver.expression, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ThisClassReceiver -> {
|
||||||
|
JsLiteral.THIS
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* no receivers - extensionOrDispatchReceiver = null, extensionReceiver = null
|
* no receivers - extensionOrDispatchReceiver = null, extensionReceiver = null
|
||||||
* this - extensionOrDispatchReceiver = this, extensionReceiver = null
|
* this - extensionOrDispatchReceiver = this, extensionReceiver = null
|
||||||
|
|||||||
+7
-25
@@ -23,21 +23,17 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
|||||||
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
|
||||||
import org.jetbrains.kotlin.js.translate.operation.OperatorTable
|
import org.jetbrains.kotlin.js.translate.operation.OperatorTable
|
||||||
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
|
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
|
||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.PsiUtils
|
import org.jetbrains.kotlin.js.translate.utils.PsiUtils
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
|
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import java.util.ArrayList
|
import java.util.*
|
||||||
|
|
||||||
fun CallArgumentTranslator.ArgumentsInfo.argsWithReceiver(receiver: JsExpression): List<JsExpression> {
|
fun CallArgumentTranslator.ArgumentsInfo.argsWithReceiver(receiver: JsExpression): List<JsExpression> {
|
||||||
val allArguments = ArrayList<JsExpression>(1 + reifiedArguments.size + valueArguments.size)
|
val allArguments = ArrayList<JsExpression>(1 + reifiedArguments.size + valueArguments.size)
|
||||||
@@ -226,26 +222,10 @@ object ConstructorCallCase : FunctionCallCase() {
|
|||||||
val functionRef = context.aliasOrValue(callableDescriptor) { fqName }
|
val functionRef = context.aliasOrValue(callableDescriptor) { fqName }
|
||||||
|
|
||||||
val constructorDescriptor = callableDescriptor as ConstructorDescriptor
|
val constructorDescriptor = callableDescriptor as ConstructorDescriptor
|
||||||
val receiver = this.resolvedCall.dispatchReceiver
|
val receiver = this.superCallReceiver
|
||||||
var allArguments = when (receiver) {
|
var allArguments = when (receiver) {
|
||||||
is ExpressionReceiver -> {
|
null -> argumentsInfo.translateArguments
|
||||||
val expr = receiver.expression
|
else -> (sequenceOf(receiver) + argumentsInfo.translateArguments).toList()
|
||||||
when (expr) {
|
|
||||||
is KtSuperExpression -> {
|
|
||||||
val superDescriptor = context.getSuperTarget(expr);
|
|
||||||
val jsReceiver = context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(superDescriptor))
|
|
||||||
(sequenceOf(jsReceiver) + argumentsInfo.translateArguments).toList()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
val jsReceiver = Translation.translateAsExpression(receiver.expression, context)
|
|
||||||
(sequenceOf(jsReceiver) + argumentsInfo.translateArguments).toList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is ThisClassReceiver -> {
|
|
||||||
(sequenceOf(JsLiteral.THIS) + argumentsInfo.translateArguments).toList()
|
|
||||||
}
|
|
||||||
else -> argumentsInfo.translateArguments
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constructorDescriptor.isPrimary || AnnotationsUtils.isNativeObject(constructorDescriptor)) {
|
if (constructorDescriptor.isPrimary || AnnotationsUtils.isNativeObject(constructorDescriptor)) {
|
||||||
@@ -266,7 +246,9 @@ object SuperCallCase : FunctionCallCase() {
|
|||||||
// TODO: spread operator
|
// TODO: spread operator
|
||||||
val prototypeClass = JsNameRef(Namer.getPrototypeName(), dispatchReceiver!!)
|
val prototypeClass = JsNameRef(Namer.getPrototypeName(), dispatchReceiver!!)
|
||||||
val functionRef = Namer.getFunctionCallRef(JsNameRef(functionName, prototypeClass))
|
val functionRef = Namer.getFunctionCallRef(JsNameRef(functionName, prototypeClass))
|
||||||
return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(JsLiteral.THIS))
|
val superReceiver = this.superCallReceiver
|
||||||
|
val receiver = if (superReceiver != null) superReceiver else JsLiteral.THIS;
|
||||||
|
return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(receiver))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-21
@@ -25,10 +25,6 @@ import java.util.Collections
|
|||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure
|
import org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor
|
import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor
|
||||||
import org.jetbrains.kotlin.js.translate.general.Translation
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.psi.KtSuperExpression
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
|
||||||
|
|
||||||
|
|
||||||
object NativeVariableAccessCase : VariableAccessCase() {
|
object NativeVariableAccessCase : VariableAccessCase() {
|
||||||
@@ -114,23 +110,10 @@ object DelegatePropertyAccessIntrinsic : DelegateIntrinsic<VariableAccessInfo> {
|
|||||||
object SuperPropertyAccessCase : VariableAccessCase() {
|
object SuperPropertyAccessCase : VariableAccessCase() {
|
||||||
override fun VariableAccessInfo.dispatchReceiver(): JsExpression {
|
override fun VariableAccessInfo.dispatchReceiver(): JsExpression {
|
||||||
val variableName = context.program().getStringLiteral(this.variableName.ident)
|
val variableName = context.program().getStringLiteral(this.variableName.ident)
|
||||||
val receiver = this.resolvedCall.dispatchReceiver
|
val jsReceiver = this.superCallReceiver
|
||||||
var propertyOwner = when (receiver) {
|
var propertyOwner = when (jsReceiver) {
|
||||||
is ExpressionReceiver -> {
|
null -> JsLiteral.THIS
|
||||||
val expr = receiver.expression
|
else -> jsReceiver
|
||||||
when (expr) {
|
|
||||||
is KtSuperExpression -> {
|
|
||||||
val superDescriptor = context.getSuperTarget(expr);
|
|
||||||
context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(superDescriptor))
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
Translation.translateAsExpression(receiver.expression, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
JsLiteral.THIS
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return if (isGetAccess())
|
return if (isGetAccess())
|
||||||
JsInvocation(context.namer().callGetProperty, propertyOwner, dispatchReceiver!!, variableName)
|
JsInvocation(context.namer().callGetProperty, propertyOwner, dispatchReceiver!!, variableName)
|
||||||
+4
-3
@@ -379,9 +379,10 @@ public class TranslationContext {
|
|||||||
return alias;
|
return alias;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (classDescriptor == cls
|
if (classDescriptor == cls ||
|
||||||
|| (classDescriptor != null && cls != null && DescriptorUtils.isSubclass(classDescriptor, cls))
|
(classDescriptor != null &&
|
||||||
|| parent == null) {
|
cls != null && DescriptorUtils.isSubclass(classDescriptor, cls)) ||
|
||||||
|
parent == null) {
|
||||||
return JsLiteral.THIS;
|
return JsLiteral.THIS;
|
||||||
}
|
}
|
||||||
ClassDescriptor parentDescriptor = parent.classDescriptor;
|
ClassDescriptor parentDescriptor = parent.classDescriptor;
|
||||||
|
|||||||
+2
-1
@@ -125,7 +125,8 @@ var Kotlin = {};
|
|||||||
property = staticProperties[p];
|
property = staticProperties[p];
|
||||||
if (typeof property === "function" && typeof property.type !== "undefined" && property.type === Kotlin.TYPE.INIT_FUN) {
|
if (typeof property === "function" && typeof property.type !== "undefined" && property.type === Kotlin.TYPE.INIT_FUN) {
|
||||||
metadata.types[p] = property;
|
metadata.types[p] = property;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
metadata.staticMembers[p] = property;
|
metadata.staticMembers[p] = property;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user