Primitive support for LocalVariables for function parameters
This commit is contained in:
committed by
Mikhael Bogdanov
parent
1a56af9bb0
commit
65c79ecfe9
@@ -58,7 +58,6 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeUtils;
|
||||
import org.jetbrains.kotlin.utils.StringsKt;
|
||||
import org.jetbrains.org.objectweb.asm.*;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
@@ -849,12 +848,12 @@ public class FunctionCodegen {
|
||||
|
||||
if (kind == JvmMethodParameterKind.VALUE) {
|
||||
ValueParameterDescriptor parameter = valueParameterIterator.next();
|
||||
List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
|
||||
String nameForDestructuredParameter = ValueParameterDescriptorImpl.getNameForDestructuredParameterOrNull(parameter);
|
||||
|
||||
parameterName =
|
||||
destructuringVariables == null
|
||||
nameForDestructuredParameter == null
|
||||
? computeParameterName(i, parameter)
|
||||
: "$" + joinParameterNames(destructuringVariables);
|
||||
: nameForDestructuredParameter;
|
||||
}
|
||||
else {
|
||||
String lowercaseKind = kind.name().toLowerCase();
|
||||
@@ -904,11 +903,11 @@ public class FunctionCodegen {
|
||||
List<ValueParameterDescriptor> destructuredParametersForSuspendLambda
|
||||
) {
|
||||
for (ValueParameterDescriptor parameter : destructuredParametersForSuspendLambda) {
|
||||
List<VariableDescriptor> destructuringVariables = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(parameter);
|
||||
if (destructuringVariables == null) continue;
|
||||
String nameForDestructuredParameter = ValueParameterDescriptorImpl.getNameForDestructuredParameterOrNull(parameter);
|
||||
if (nameForDestructuredParameter == null) continue;
|
||||
|
||||
Type type = typeMapper.mapType(parameter.getType());
|
||||
mv.visitLocalVariable("$" + joinParameterNames(destructuringVariables), type.getDescriptor(), null, methodBegin, methodEnd, shift);
|
||||
mv.visitLocalVariable(nameForDestructuredParameter, type.getDescriptor(), null, methodBegin, methodEnd, shift);
|
||||
shift += type.getSize();
|
||||
}
|
||||
return shift;
|
||||
@@ -923,14 +922,6 @@ public class FunctionCodegen {
|
||||
return parameter.getName().asString();
|
||||
}
|
||||
|
||||
private static String joinParameterNames(@NotNull List<VariableDescriptor> variables) {
|
||||
// stub for anonymous destructuring declaration entry
|
||||
return StringsKt.join(
|
||||
CollectionsKt.map(variables, descriptor -> descriptor.getName().isSpecial() ? "$_$" : descriptor.getName().asString()),
|
||||
"_"
|
||||
);
|
||||
}
|
||||
|
||||
private static void generateFacadeDelegateMethodBody(
|
||||
@NotNull MethodVisitor mv,
|
||||
@NotNull Method asmMethod,
|
||||
|
||||
+42
-6
@@ -24,11 +24,9 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeAlias
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
@@ -118,6 +116,7 @@ class ExpressionCodegen(
|
||||
|
||||
fun generate() {
|
||||
mv.visitCode()
|
||||
val startLabel = markNewLabel()
|
||||
irFunction.markLineNumber(true)
|
||||
val info = BlockInfo.create()
|
||||
val result = irFunction.body!!.accept(this, info)
|
||||
@@ -137,9 +136,35 @@ class ExpressionCodegen(
|
||||
}
|
||||
}
|
||||
writeLocalVariablesInTable(info)
|
||||
writeParameterInLocalVariableTable(startLabel)
|
||||
mv.visitEnd()
|
||||
}
|
||||
|
||||
private fun writeParameterInLocalVariableTable(startLabel: Label) {
|
||||
if (!irFunction.isStatic) {
|
||||
mv.visitLocalVariable("this", classCodegen.type.descriptor, null, startLabel, markNewLabel(), 0)
|
||||
}
|
||||
val extensionReceiverParameter = irFunction.extensionReceiverParameter
|
||||
if (extensionReceiverParameter != null) {
|
||||
writeValueParameterInLocalVariableTable(extensionReceiverParameter, startLabel)
|
||||
}
|
||||
for (param in irFunction.valueParameters) {
|
||||
writeValueParameterInLocalVariableTable(param, startLabel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeValueParameterInLocalVariableTable(param: IrValueParameter, startLabel: Label) {
|
||||
val descriptor = param.descriptor
|
||||
val nameForDestructuredParameter = if (descriptor is ValueParameterDescriptor)
|
||||
ValueParameterDescriptorImpl.getNameForDestructuredParameterOrNull(descriptor) else null
|
||||
val type = typeMapper.mapType(descriptor)
|
||||
// NOTE: we expect all value parameters to be present in the frame.
|
||||
mv.visitLocalVariable(
|
||||
nameForDestructuredParameter ?: param.name.asString(),
|
||||
type.descriptor, null, startLabel, markNewLabel(), findLocalIndex(param.symbol)
|
||||
)
|
||||
}
|
||||
|
||||
private fun endsWithReturn(body: IrBody): Boolean {
|
||||
val lastStatement = if (body is IrStatementContainer) {
|
||||
body.statements.lastOrNull() ?: body
|
||||
@@ -169,7 +194,18 @@ class ExpressionCodegen(
|
||||
private fun writeLocalVariablesInTable(info: BlockInfo) {
|
||||
val endLabel = markNewLabel()
|
||||
info.variables.forEach {
|
||||
mv.visitLocalVariable(it.declaration.name.asString(), it.type.descriptor, null, it.startLabel, endLabel, it.index)
|
||||
when (it.declaration.origin) {
|
||||
IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
IrDeclarationOrigin.FOR_LOOP_ITERATOR,
|
||||
IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE -> {
|
||||
// Ignore implicitly created variables
|
||||
}
|
||||
else -> {
|
||||
mv.visitLocalVariable(
|
||||
it.declaration.name.asString(), it.type.descriptor, null, it.startLabel, endLabel, it.index
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info.variables.reversed().forEach {
|
||||
@@ -1141,4 +1177,4 @@ fun DefaultCallArgs.generateOnStackIfNeeded(callGenerator: IrCallGenerator, isCo
|
||||
|
||||
internal fun CallableDescriptor.isInlineCall(state: GenerationState) =
|
||||
(!state.isInlineDisabled || InlineUtil.containsReifiedTypeParameters(this)) &&
|
||||
(InlineUtil.isInline(this) || InlineUtil.isArrayConstructorWithLambda(this))
|
||||
(InlineUtil.isInline(this) || InlineUtil.isArrayConstructorWithLambda(this))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
data class A(val x: String, val y: Int)
|
||||
|
||||
fun foo(a: A, block: (A) -> String): String = block(a)
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
data class Data(val x: String, val y: Int)
|
||||
|
||||
suspend fun test() {
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class A<T>(val x: String, val y: String, val z: T)
|
||||
|
||||
suspend fun <T> foo(a: A<T>, block: suspend (A<T>) -> String): String = block(a)
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
data class A<T, F>(val x: T, val y: F)
|
||||
|
||||
suspend fun <X, Y> foo(a: A<X, Y>, block: suspend (A<X, Y>) -> String) = block(a)
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
data class A(val x: String, val y: String)
|
||||
|
||||
suspend inline fun foo(a: A, block: suspend (A) -> String): String = block(a)
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
data class A(val x: String, val y: String)
|
||||
|
||||
suspend fun foo(a: A, block: suspend (Int, A, String) -> String): String = block(1, a, "#")
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class A {
|
||||
operator fun component1() = "O"
|
||||
operator fun component2(): String = throw RuntimeException("fail 0")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
public fun <T> Iterable<T>.myforEach(operation: (T) -> Unit) : Unit {
|
||||
for (element in this) operation(element)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun foo() {
|
||||
fun bar() : (Int) -> Unit {
|
||||
return {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class C {
|
||||
@kotlin.jvm.JvmOverloads fun foo(firstParam: Int, secondParam: String = "") {
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
class A(val value: String)
|
||||
|
||||
fun A.test(): String {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun foo() {
|
||||
var a = {
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun foo() {
|
||||
fun bar() {
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
data class A(val x: Double = 1.0, val y: String = "", val z: Char = '0')
|
||||
|
||||
fun foo(a: A, block: (A, String, Int) -> String): String = block(a, "", 1)
|
||||
|
||||
+7
-4
@@ -42,8 +42,8 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
|
||||
public abstract class AbstractCheckLocalVariablesTableTest extends TestCaseWithTmpdir {
|
||||
private File ktFile;
|
||||
private KotlinCoreEnvironment environment;
|
||||
protected File ktFile;
|
||||
protected KotlinCoreEnvironment environment;
|
||||
|
||||
public AbstractCheckLocalVariablesTableTest() {
|
||||
}
|
||||
@@ -82,6 +82,10 @@ public abstract class AbstractCheckLocalVariablesTableTest extends TestCaseWithT
|
||||
ClassReader cr = new ClassReader(outputFile.asByteArray());
|
||||
List<LocalVariable> actualLocalVariables = readLocalVariable(cr, methodName);
|
||||
|
||||
doCompare(text, actualLocalVariables);
|
||||
}
|
||||
|
||||
protected void doCompare(String text, List<LocalVariable> actualLocalVariables) {
|
||||
KotlinTestUtils.assertEqualsToFile(ktFile, text.substring(0, text.indexOf("// VARIABLE : ")) + getActualVariablesAsString(actualLocalVariables));
|
||||
}
|
||||
|
||||
@@ -93,8 +97,7 @@ public abstract class AbstractCheckLocalVariablesTableTest extends TestCaseWithT
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static class LocalVariable {
|
||||
protected static class LocalVariable {
|
||||
private final String name;
|
||||
private final String type;
|
||||
private final int index;
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.ir
|
||||
|
||||
import com.intellij.openapi.util.Comparing
|
||||
import org.jetbrains.kotlin.codegen.AbstractCheckLocalVariablesTableTest
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.junit.ComparisonFailure
|
||||
import java.nio.charset.Charset
|
||||
|
||||
abstract class AbstractIrCheckLocalVariablesTableTest : AbstractCheckLocalVariablesTableTest() {
|
||||
@Throws(Exception::class)
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
assert(environment != null)
|
||||
environment.configuration.put(JVMConfigurationKeys.IR, true)
|
||||
}
|
||||
|
||||
override fun doCompare(text: String?, actualLocalVariables: MutableList<LocalVariable>) {
|
||||
val actual = getActualVariablesAsList(actualLocalVariables)
|
||||
val expected = getExpectedVariablesAsList()
|
||||
if (!Comparing.equal(expected, actual)) {
|
||||
throw ComparisonFailure(
|
||||
"Variables differ from expected",
|
||||
expected.joinToString("\n"),
|
||||
actual.joinToString("\n")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getActualVariablesAsList(list: List<LocalVariable>): List<String> {
|
||||
return list.map { it.toString() }
|
||||
.map { line -> line.replaceFirst("INDEX=\\d+".toRegex(), "INDEX=*") } // Ignore index
|
||||
.sorted()
|
||||
}
|
||||
|
||||
private fun getExpectedVariablesAsList(): List<String> {
|
||||
return ktFile.readLines(Charset.forName("utf-8"))
|
||||
.filter { line -> line.startsWith("// VARIABLE ") }
|
||||
.filter { !it.contains("NAME=\$i\$") }
|
||||
.map { line -> line.replaceFirst("INDEX=\\d+".toRegex(), "INDEX=*") } // Ignore index
|
||||
.sorted()
|
||||
}
|
||||
}
|
||||
Generated
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.ir;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/checkLocalVariablesTable")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IrCheckLocalVariablesTableTestGenerated extends AbstractIrCheckLocalVariablesTableTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCheckLocalVariablesTable() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/checkLocalVariablesTable"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("catchClause.kt")
|
||||
public void testCatchClause() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/catchClause.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("copyFunction.kt")
|
||||
public void testCopyFunction() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/copyFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("destructuringInLambdas.kt")
|
||||
public void testDestructuringInLambdas() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInLambdas.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("destructuringInlineLambda.kt")
|
||||
public void testDestructuringInlineLambda() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineLambdaWithItParam.kt")
|
||||
public void testInlineLambdaWithItParam() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/inlineLambdaWithItParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineLambdaWithParam.kt")
|
||||
public void testInlineLambdaWithParam() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/inlineLambdaWithParam.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineProperty.kt")
|
||||
public void testInlineProperty() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/inlineProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineSimple.kt")
|
||||
public void testInlineSimple() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/inlineSimple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineSimpleChain.kt")
|
||||
public void testInlineSimpleChain() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/inlineSimpleChain.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("itInLambda.kt")
|
||||
public void testItInLambda() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/itInLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("itInReturnedLambda.kt")
|
||||
public void testItInReturnedLambda() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/itInReturnedLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmOverloads.kt")
|
||||
public void testJvmOverloads() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/jvmOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt11117.kt")
|
||||
public void testKt11117() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/kt11117.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaAsVar.kt")
|
||||
public void testLambdaAsVar() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/lambdaAsVar.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localFun.kt")
|
||||
public void testLocalFun() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/localFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/underscoreNames.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DestructuringInSuspendLambda extends AbstractIrCheckLocalVariablesTableTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDestructuringInSuspendLambda() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("dataClass.kt")
|
||||
public void testDataClass() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/dataClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionComponents.kt")
|
||||
public void testExtensionComponents() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/extensionComponents.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("generic.kt")
|
||||
public void testGeneric() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/generic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inline.kt")
|
||||
public void testInline() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/inline.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("otherParameters.kt")
|
||||
public void testOtherParameters() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/otherParameters.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreNames.kt")
|
||||
public void testUnderscoreNames() throws Exception {
|
||||
runTest("compiler/testData/checkLocalVariablesTable/destructuringInSuspendLambda/underscoreNames.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,10 +27,10 @@ import org.jetbrains.kotlin.cli.AbstractCliTest
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.defaultConstructor.AbstractDefaultArgumentsReflectionTest
|
||||
import org.jetbrains.kotlin.codegen.flags.AbstractWriteFlagsTest
|
||||
import org.jetbrains.kotlin.codegen.AbstractCustomScriptCodegenTest
|
||||
import org.jetbrains.kotlin.codegen.ir.AbstractIrBlackBoxAgainstJavaCodegenTest
|
||||
import org.jetbrains.kotlin.codegen.ir.AbstractIrBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.codegen.ir.AbstractIrBlackBoxInlineCodegenTest
|
||||
import org.jetbrains.kotlin.codegen.ir.AbstractIrCheckLocalVariablesTableTest
|
||||
import org.jetbrains.kotlin.generators.tests.generator.testGroup
|
||||
import org.jetbrains.kotlin.generators.util.KT_OR_KTS_WITHOUT_DOTS_IN_NAME
|
||||
import org.jetbrains.kotlin.integration.AbstractAntTaskTest
|
||||
@@ -356,6 +356,10 @@ fun main(args: Array<String>) {
|
||||
model("codegen/boxAgainstJava", targetBackend = TargetBackend.JVM_IR)
|
||||
}
|
||||
|
||||
testClass<AbstractIrCheckLocalVariablesTableTest> {
|
||||
model("checkLocalVariablesTable", targetBackend = TargetBackend.JVM_IR)
|
||||
}
|
||||
|
||||
testClass<AbstractIrBlackBoxInlineCodegenTest> {
|
||||
model("codegen/boxInline", targetBackend = TargetBackend.JVM_IR)
|
||||
}
|
||||
|
||||
+18
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.utils.join
|
||||
|
||||
open class ValueParameterDescriptorImpl(
|
||||
containingDeclaration: CallableDescriptor,
|
||||
@@ -60,6 +61,16 @@ open class ValueParameterDescriptorImpl(
|
||||
WithDestructuringDeclaration(containingDeclaration, original, index, annotations, name, outType,
|
||||
declaresDefaultValue, isCrossinline, isNoinline, varargElementType, source,
|
||||
destructuringVariables)
|
||||
|
||||
@JvmStatic
|
||||
fun getNameForDestructuredParameterOrNull(valueParameterDescriptor: ValueParameterDescriptor): String? {
|
||||
val variablesOrNull = ValueParameterDescriptorImpl.getDestructuringVariablesOrNull(valueParameterDescriptor)
|
||||
return if (variablesOrNull == null) null else
|
||||
"$" + join(
|
||||
variablesOrNull.map { descriptor -> if (descriptor.name.isSpecial) "\$_\$" else descriptor.name.asString() },
|
||||
"_"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class WithDestructuringDeclaration internal constructor(
|
||||
@@ -81,6 +92,13 @@ open class ValueParameterDescriptorImpl(
|
||||
// as value parameters.
|
||||
// Must be forced via ForceResolveUtil.forceResolveAllContents()
|
||||
val destructuringVariables by lazy(destructuringVariables)
|
||||
|
||||
override fun copy(newOwner: CallableDescriptor, newName: Name, newIndex: Int): ValueParameterDescriptor {
|
||||
return WithDestructuringDeclaration(
|
||||
newOwner, null, newIndex, annotations, newName, type, declaresDefaultValue(),
|
||||
isCrossinline, isNoinline, varargElementType, SourceElement.NO_SOURCE
|
||||
) { destructuringVariables }
|
||||
}
|
||||
}
|
||||
|
||||
private val original: ValueParameterDescriptor = original ?: this
|
||||
|
||||
Reference in New Issue
Block a user