Generate JvmOverloads methods as final
#KT-33240 Fixed
This commit is contained in:
+5
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen
|
|||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.getDispatchReceiverParameterForConstructorCall
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.getDispatchReceiverParameterForConstructorCall
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
@@ -132,10 +133,13 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
|||||||
val remainingParametersDeclarations =
|
val remainingParametersDeclarations =
|
||||||
remainingParameters.map { DescriptorToSourceUtils.descriptorToDeclaration(it) as? KtParameter }
|
remainingParameters.map { DescriptorToSourceUtils.descriptorToDeclaration(it) as? KtParameter }
|
||||||
|
|
||||||
|
val generateAsFinal =
|
||||||
|
functionDescriptor.modality == Modality.FINAL ||
|
||||||
|
state.languageVersionSettings.supportsFeature(LanguageFeature.GenerateJvmOverloadsAsFinal)
|
||||||
val flags =
|
val flags =
|
||||||
baseMethodFlags or
|
baseMethodFlags or
|
||||||
(if (isStatic) Opcodes.ACC_STATIC else 0) or
|
(if (isStatic) Opcodes.ACC_STATIC else 0) or
|
||||||
(if (functionDescriptor.modality == Modality.FINAL && functionDescriptor !is ConstructorDescriptor) Opcodes.ACC_FINAL else 0) or
|
(if (generateAsFinal && functionDescriptor !is ConstructorDescriptor) Opcodes.ACC_FINAL else 0) or
|
||||||
(if (remainingParameters.lastOrNull()?.varargElementType != null) Opcodes.ACC_VARARGS else 0)
|
(if (remainingParameters.lastOrNull()?.varargElementType != null) Opcodes.ACC_VARARGS else 0)
|
||||||
val signature = typeMapper.mapSignatureWithCustomParameters(functionDescriptor, contextKind, remainingParameters, false)
|
val signature = typeMapper.mapSignatureWithCustomParameters(functionDescriptor, contextKind, remainingParameters, false)
|
||||||
val mv = classBuilder.newMethod(
|
val mv = classBuilder.newMethod(
|
||||||
|
|||||||
+8
-3
@@ -6,11 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||||
@@ -137,13 +139,16 @@ private class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : C
|
|||||||
}
|
}
|
||||||
is IrSimpleFunction -> {
|
is IrSimpleFunction -> {
|
||||||
val descriptor = WrappedSimpleFunctionDescriptor(oldFunction.descriptor.annotations)
|
val descriptor = WrappedSimpleFunctionDescriptor(oldFunction.descriptor.annotations)
|
||||||
|
val modality =
|
||||||
|
if (context.state.languageVersionSettings.supportsFeature(LanguageFeature.GenerateJvmOverloadsAsFinal)) Modality.FINAL
|
||||||
|
else oldFunction.modality
|
||||||
IrFunctionImpl(
|
IrFunctionImpl(
|
||||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER,
|
JvmLoweredDeclarationOrigin.JVM_OVERLOADS_WRAPPER,
|
||||||
IrSimpleFunctionSymbolImpl(descriptor),
|
IrSimpleFunctionSymbolImpl(descriptor),
|
||||||
oldFunction.name,
|
oldFunction.name,
|
||||||
oldFunction.visibility,
|
oldFunction.visibility,
|
||||||
oldFunction.modality,
|
modality,
|
||||||
returnType = oldFunction.returnType,
|
returnType = oldFunction.returnType,
|
||||||
isInline = oldFunction.isInline,
|
isInline = oldFunction.isInline,
|
||||||
isExternal = false,
|
isExternal = false,
|
||||||
@@ -151,7 +156,7 @@ private class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : C
|
|||||||
isSuspend = oldFunction.isSuspend,
|
isSuspend = oldFunction.isSuspend,
|
||||||
isExpect = false,
|
isExpect = false,
|
||||||
isFakeOverride = false,
|
isFakeOverride = false,
|
||||||
isOperator = false
|
isOperator = false,
|
||||||
).apply {
|
).apply {
|
||||||
descriptor.bind(this)
|
descriptor.bind(this)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
open class Foo {
|
||||||
|
@JvmOverloads
|
||||||
|
open fun bar(x: Int = 42, y: Int = -1): Int = x + y
|
||||||
|
}
|
||||||
|
|
||||||
|
// TESTED_OBJECT_KIND: function
|
||||||
|
// TESTED_OBJECTS: Foo, bar, (II)I
|
||||||
|
// FLAGS: ACC_PUBLIC
|
||||||
|
|
||||||
|
// TESTED_OBJECT_KIND: function
|
||||||
|
// TESTED_OBJECTS: Foo, bar, (I)I
|
||||||
|
// FLAGS: ACC_PUBLIC, ACC_FINAL
|
||||||
|
|
||||||
|
// TESTED_OBJECT_KIND: function
|
||||||
|
// TESTED_OBJECTS: Foo, bar, ()I
|
||||||
|
// FLAGS: ACC_PUBLIC, ACC_FINAL
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// !LANGUAGE: -GenerateJvmOverloadsAsFinal
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
open class Foo {
|
||||||
|
@JvmOverloads
|
||||||
|
open fun bar(x: Int = 42, y: Int = -1): Int = x + y
|
||||||
|
}
|
||||||
|
|
||||||
|
// TESTED_OBJECT_KIND: function
|
||||||
|
// TESTED_OBJECTS: Foo, bar, (II)I
|
||||||
|
// FLAGS: ACC_PUBLIC
|
||||||
|
|
||||||
|
// TESTED_OBJECT_KIND: function
|
||||||
|
// TESTED_OBJECTS: Foo, bar, (I)I
|
||||||
|
// FLAGS: ACC_PUBLIC
|
||||||
|
|
||||||
|
// TESTED_OBJECT_KIND: function
|
||||||
|
// TESTED_OBJECTS: Foo, bar, ()I
|
||||||
|
// FLAGS: ACC_PUBLIC
|
||||||
+36
-22
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.flags;
|
|||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||||
import org.jetbrains.kotlin.codegen.CodegenTestCase;
|
import org.jetbrains.kotlin.codegen.CodegenTestCase;
|
||||||
import org.jetbrains.org.objectweb.asm.*;
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
@@ -34,7 +35,7 @@ import static org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPref
|
|||||||
* Test correctness of written flags in class file
|
* Test correctness of written flags in class file
|
||||||
*
|
*
|
||||||
* TESTED_OBJECT_KIND - maybe class, function or property
|
* TESTED_OBJECT_KIND - maybe class, function or property
|
||||||
* TESTED_OBJECTS - className, [function/property name]
|
* TESTED_OBJECTS - className, [function/property name], [function/property signature]
|
||||||
* FLAGS - only flags which must be true (could be skipped if ABSENT is TRUE)
|
* FLAGS - only flags which must be true (could be skipped if ABSENT is TRUE)
|
||||||
* ABSENT - true or false, optional (false by default)
|
* ABSENT - true or false, optional (false by default)
|
||||||
*
|
*
|
||||||
@@ -46,6 +47,10 @@ import static org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPref
|
|||||||
* TESTED_OBJECT_KIND: property
|
* TESTED_OBJECT_KIND: property
|
||||||
* TESTED_OBJECTS: Test, prop$delegate
|
* TESTED_OBJECTS: Test, prop$delegate
|
||||||
* FLAGS: ACC_STATIC, ACC_FINAL, ACC_PRIVATE
|
* FLAGS: ACC_STATIC, ACC_FINAL, ACC_PRIVATE
|
||||||
|
*
|
||||||
|
* TESTED_OBJECT_KIND: function
|
||||||
|
* TESTED_OBJECTS: Test, function, (ILjava/lang/String;)[Ljava/lang/Object;
|
||||||
|
* FLAGS: ACC_PUBLIC, ACC_SYNTHETIC
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
||||||
|
|
||||||
@@ -72,11 +77,11 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
assertNotNull(outputFile);
|
assertNotNull(outputFile);
|
||||||
|
|
||||||
ClassReader cr = new ClassReader(outputFile.asByteArray());
|
ClassReader cr = new ClassReader(outputFile.asByteArray());
|
||||||
TestClassVisitor classVisitor = getClassVisitor(testedObject.kind, testedObject.name, false);
|
TestClassVisitor classVisitor = getClassVisitor(testedObject, false);
|
||||||
cr.accept(classVisitor, ClassReader.SKIP_CODE);
|
cr.accept(classVisitor, ClassReader.SKIP_CODE);
|
||||||
|
|
||||||
if (!classVisitor.isExists()) {
|
if (!classVisitor.isExists()) {
|
||||||
classVisitor = getClassVisitor(testedObject.kind, testedObject.name, true);
|
classVisitor = getClassVisitor(testedObject, true);
|
||||||
cr.accept(classVisitor, ClassReader.SKIP_CODE);
|
cr.accept(classVisitor, ClassReader.SKIP_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +105,7 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
TestedObject testObject = new TestedObject();
|
TestedObject testObject = new TestedObject();
|
||||||
testObject.textData = testData;
|
testObject.textData = testData;
|
||||||
List<String> testedObjects = findListWithPrefixes(testData, "// TESTED_OBJECTS: ");
|
List<String> testedObjects = findListWithPrefixes(testData, "// TESTED_OBJECTS: ");
|
||||||
assertTrue("Cannot find TESTED_OBJECTS instruction", !testedObjects.isEmpty());
|
assertFalse("Cannot find TESTED_OBJECTS instruction", testedObjects.isEmpty());
|
||||||
testObject.containingClass = testedObjects.get(0);
|
testObject.containingClass = testedObjects.get(0);
|
||||||
if (testedObjects.size() == 1) {
|
if (testedObjects.size() == 1) {
|
||||||
testObject.name = testedObjects.get(0);
|
testObject.name = testedObjects.get(0);
|
||||||
@@ -108,9 +113,13 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
else if (testedObjects.size() == 2) {
|
else if (testedObjects.size() == 2) {
|
||||||
testObject.name = testedObjects.get(1);
|
testObject.name = testedObjects.get(1);
|
||||||
}
|
}
|
||||||
|
else if (testedObjects.size() == 3) {
|
||||||
|
testObject.name = testedObjects.get(1);
|
||||||
|
testObject.signature = testedObjects.get(2);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"TESTED_OBJECTS instruction must contain one (for class) or two (for function and property) values");
|
"TESTED_OBJECTS instruction must contain one (for class), two or three (for function and property) values");
|
||||||
}
|
}
|
||||||
|
|
||||||
testObject.kind = findStringWithPrefixes(testData, "// TESTED_OBJECT_KIND: ");
|
testObject.kind = findStringWithPrefixes(testData, "// TESTED_OBJECT_KIND: ");
|
||||||
@@ -120,7 +129,7 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
}
|
}
|
||||||
objects.add(testObject);
|
objects.add(testObject);
|
||||||
}
|
}
|
||||||
assertTrue("Test description not present!", !objects.isEmpty());
|
assertFalse("Test description not present!", objects.isEmpty());
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,27 +139,28 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
public boolean isFullContainingClassName = true;
|
public boolean isFullContainingClassName = true;
|
||||||
public String kind;
|
public String kind;
|
||||||
public String textData;
|
public String textData;
|
||||||
|
public String signature;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Class = " + containingClass + ", name = " + name + ", kind = " + kind;
|
return "Class = " + containingClass + ", name = " + name + ", kind = " + kind +
|
||||||
|
(signature != null ? ", signature = " + signature : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TestClassVisitor getClassVisitor(String visitorKind, String testedObjectName, boolean allowSynthetic) {
|
private static TestClassVisitor getClassVisitor(@NotNull TestedObject object, boolean allowSynthetic) {
|
||||||
switch (visitorKind) {
|
switch (object.kind) {
|
||||||
case "class":
|
case "class":
|
||||||
return new ClassFlagsVisitor();
|
return new ClassFlagsVisitor();
|
||||||
case "function":
|
case "function":
|
||||||
return new FunctionFlagsVisitor(testedObjectName, allowSynthetic);
|
return new FunctionFlagsVisitor(object.name, object.signature, allowSynthetic);
|
||||||
case "property":
|
case "property":
|
||||||
return new PropertyFlagsVisitor(testedObjectName);
|
return new PropertyFlagsVisitor(object.name, object.signature);
|
||||||
case "innerClass":
|
case "innerClass":
|
||||||
return new InnerClassFlagsVisitor(testedObjectName);
|
return new InnerClassFlagsVisitor(object.name);
|
||||||
default:
|
default:
|
||||||
|
throw new IllegalArgumentException("Value of TESTED_OBJECT_KIND is incorrect: " + object.kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("Value of TESTED_OBJECT_KIND is incorrect: " + visitorKind);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static abstract class TestClassVisitor extends ClassVisitor {
|
protected static abstract class TestClassVisitor extends ClassVisitor {
|
||||||
@@ -170,7 +180,7 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
|
|
||||||
private static int getExpectedFlags(String text) {
|
private static int getExpectedFlags(String text) {
|
||||||
int expectedAccess = 0;
|
int expectedAccess = 0;
|
||||||
Class klass = Opcodes.class;
|
Class<?> klass = Opcodes.class;
|
||||||
List<String> flags = findListWithPrefixes(text, "// FLAGS: ");
|
List<String> flags = findListWithPrefixes(text, "// FLAGS: ");
|
||||||
for (String flag : flags) {
|
for (String flag : flags) {
|
||||||
try {
|
try {
|
||||||
@@ -202,16 +212,18 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
private static class FunctionFlagsVisitor extends TestClassVisitor {
|
private static class FunctionFlagsVisitor extends TestClassVisitor {
|
||||||
private int access = 0;
|
private int access = 0;
|
||||||
private final String funName;
|
private final String funName;
|
||||||
|
private final String funSignature;
|
||||||
private final boolean allowSynthetic;
|
private final boolean allowSynthetic;
|
||||||
|
|
||||||
public FunctionFlagsVisitor(String name, boolean allowSynthetic) {
|
public FunctionFlagsVisitor(@NotNull String name, @Nullable String signature, boolean allowSynthetic) {
|
||||||
funName = name;
|
this.funName = name;
|
||||||
|
this.funSignature = signature;
|
||||||
this.allowSynthetic = allowSynthetic;
|
this.allowSynthetic = allowSynthetic;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodVisitor visitMethod(int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions) {
|
public MethodVisitor visitMethod(int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions) {
|
||||||
if (name.equals(funName)) {
|
if (name.equals(funName) && (funSignature == null || funSignature.equals(desc))) {
|
||||||
if (!allowSynthetic && (access & Opcodes.ACC_SYNTHETIC) != 0) return null;
|
if (!allowSynthetic && (access & Opcodes.ACC_SYNTHETIC) != 0) return null;
|
||||||
this.access = access;
|
this.access = access;
|
||||||
isExists = true;
|
isExists = true;
|
||||||
@@ -228,14 +240,16 @@ public abstract class AbstractWriteFlagsTest extends CodegenTestCase {
|
|||||||
private static class PropertyFlagsVisitor extends TestClassVisitor {
|
private static class PropertyFlagsVisitor extends TestClassVisitor {
|
||||||
private int access = 0;
|
private int access = 0;
|
||||||
private final String propertyName;
|
private final String propertyName;
|
||||||
|
private final String propertySignature;
|
||||||
|
|
||||||
public PropertyFlagsVisitor(String name) {
|
public PropertyFlagsVisitor(@NotNull String name, @Nullable String signature) {
|
||||||
propertyName = name;
|
this.propertyName = name;
|
||||||
|
this.propertySignature = signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldVisitor visitField(int access, @NotNull String name, @NotNull String desc, String signature, Object value) {
|
public FieldVisitor visitField(int access, @NotNull String name, @NotNull String desc, String signature, Object value) {
|
||||||
if (name.equals(propertyName)) {
|
if (name.equals(propertyName) || (propertySignature == null || propertySignature.equals(desc))) {
|
||||||
this.access = access;
|
this.access = access;
|
||||||
isExists = true;
|
isExists = true;
|
||||||
}
|
}
|
||||||
|
|||||||
+23
@@ -821,6 +821,29 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/writeFlags/jvmOverloads")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JvmOverloads extends AbstractWriteFlagsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJvmOverloads() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/writeFlags/jvmOverloads"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("openFunction.kt")
|
||||||
|
public void testOpenFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/writeFlags/jvmOverloads/openFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("openFunction_1_3.kt")
|
||||||
|
public void testOpenFunction_1_3() throws Exception {
|
||||||
|
runTest("compiler/testData/writeFlags/jvmOverloads/openFunction_1_3.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/writeFlags/lambda")
|
@TestMetadata("compiler/testData/writeFlags/lambda")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+23
@@ -821,6 +821,29 @@ public class IrWriteFlagsTestGenerated extends AbstractIrWriteFlagsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/writeFlags/jvmOverloads")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class JvmOverloads extends AbstractIrWriteFlagsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInJvmOverloads() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/writeFlags/jvmOverloads"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("openFunction.kt")
|
||||||
|
public void testOpenFunction() throws Exception {
|
||||||
|
runTest("compiler/testData/writeFlags/jvmOverloads/openFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("openFunction_1_3.kt")
|
||||||
|
public void testOpenFunction_1_3() throws Exception {
|
||||||
|
runTest("compiler/testData/writeFlags/jvmOverloads/openFunction_1_3.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/writeFlags/lambda")
|
@TestMetadata("compiler/testData/writeFlags/lambda")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ enum class LanguageFeature(
|
|||||||
DoNotGenerateThrowsForDelegatedKotlinMembers(KOTLIN_1_4),
|
DoNotGenerateThrowsForDelegatedKotlinMembers(KOTLIN_1_4),
|
||||||
ProperIeee754Comparisons(KOTLIN_1_4, kind = BUG_FIX),
|
ProperIeee754Comparisons(KOTLIN_1_4, kind = BUG_FIX),
|
||||||
FunctionalInterfaceConversion(KOTLIN_1_4, kind = UNSTABLE_FEATURE),
|
FunctionalInterfaceConversion(KOTLIN_1_4, kind = UNSTABLE_FEATURE),
|
||||||
|
GenerateJvmOverloadsAsFinal(KOTLIN_1_4),
|
||||||
|
|
||||||
ProhibitSpreadOnSignaturePolymorphicCall(KOTLIN_1_5, kind = BUG_FIX),
|
ProhibitSpreadOnSignaturePolymorphicCall(KOTLIN_1_5, kind = BUG_FIX),
|
||||||
ProhibitInvisibleAbstractMethodsInSuperclasses(KOTLIN_1_5, kind = BUG_FIX),
|
ProhibitInvisibleAbstractMethodsInSuperclasses(KOTLIN_1_5, kind = BUG_FIX),
|
||||||
|
|||||||
Reference in New Issue
Block a user