From 8478c73434558009ef7ac61ead40325dfc122f46 Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Fri, 6 Jul 2018 18:20:26 +0300 Subject: [PATCH] Make @JvmStatic work on JVM_IR --- .../codegen/state/KotlinTypeMapper.java | 2 +- .../lower/DefaultArgumentStubGenerator.kt | 2 + .../kotlin/backend/jvm/DeclarationOrigins.kt | 1 + .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 4 +- .../backend/jvm/codegen/irCodegenUtils.kt | 3 +- .../jvm/lower/JvmStaticAnnotationLowering.kt | 247 ++++++++++++++++++ .../box/collections/platformValueContains.kt | 1 - .../box/jvmStatic/META-INF/main.kotlin_module | Bin 0 -> 28 bytes .../codegen/box/jvmStatic/annotations.kt | 1 - .../codegen/box/jvmStatic/companionObject.kt | 1 - .../testData/codegen/box/jvmStatic/default.kt | 1 - .../codegen/box/jvmStatic/explicitObject.kt | 1 - .../jvmStatic/importStaticMemberFromObject.kt | 1 - .../testData/codegen/box/jvmStatic/inline.kt | 1 - .../box/jvmStatic/inlinePropertyAccessors.kt | 1 - .../box/jvmStatic/interfaceCompanion.kt | 56 ++++ .../testData/codegen/box/jvmStatic/kt21246.kt | 1 - .../codegen/box/jvmStatic/kt9897_static.kt | 1 - .../testData/codegen/box/jvmStatic/object.kt | 1 - .../codegen/box/jvmStatic/postfixInc.kt | 1 - .../codegen/box/jvmStatic/prefixInc.kt | 1 - .../codegen/box/jvmStatic/privateSetter.kt | 1 - .../codegen/box/jvmStatic/propertyAccess.kt | 1 - .../box/jvmStatic/propertyAsDefault.kt | 1 - .../propertyGetterDelegatesToAnother.kt | 1 - .../testData/codegen/box/jvmStatic/simple.kt | 1 - .../box/jvmStatic/syntheticAccessor.kt | 1 - .../ir/IrBlackBoxCodegenTestGenerated.java | 18 ++ .../codegen/BlackBoxCodegenTestGenerated.java | 18 ++ .../LightAnalysisModeTestGenerated.java | 18 ++ .../BasicCompletionHandlerTestGenerated.java | 1 - .../QuickFixMultiFileTestGenerated.java | 39 +++ .../IrJsCodegenBoxTestGenerated.java | 18 ++ .../semantics/JsCodegenBoxTestGenerated.java | 18 ++ 34 files changed, 439 insertions(+), 25 deletions(-) create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt create mode 100644 compiler/testData/codegen/box/jvmStatic/META-INF/main.kotlin_module create mode 100644 compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 010c958b4a7..d4400f288ca 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -977,7 +977,7 @@ public class KotlinTypeMapper { } @NotNull - private String mapFunctionName(@NotNull FunctionDescriptor descriptor) { + public String mapFunctionName(@NotNull FunctionDescriptor descriptor) { if (!(descriptor instanceof JavaCallableMemberDescriptor)) { String platformName = getJvmName(descriptor); if (platformName != null) return platformName; diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt index 38771a426f9..ef5869683dd 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt @@ -460,6 +460,8 @@ private fun IrFunction.generateDefaultsFunction(context: CommonBackendContext): result.valueParameters += newValueParameters.also { it.forEach { it.parent = result } } + function.annotations.mapTo(result.annotations) { it.deepCopyWithSymbols() } + result } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt index 30f21df1e58..f9701894623 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/DeclarationOrigins.kt @@ -30,6 +30,7 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin { object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS") object SYNTHETIC_ACCESSOR : IrDeclarationOriginImpl("SYNTHETIC_ACCESSOR") object TO_ARRAY : IrDeclarationOriginImpl("TO_ARRAY") + object JVM_STATIC_WRAPPER : IrDeclarationOriginImpl("JVM_STATIC_WRAPPER") } interface JvmLoweredStatementOrigin : IrStatementOrigin { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 72090419eae..3c252ee2690 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.backend.jvm.lower.* import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -40,7 +39,6 @@ class JvmLower(val context: JvmBackendContext) { //Should be before interface lowering DefaultArgumentStubGenerator(context, false).runOnFilePostfix(irFile) - StaticDefaultFunctionLowering(context.state).runOnFilePostfix(irFile) InterfaceLowering(context.state).runOnFilePostfix(irFile) InterfaceDelegationLowering(context.state).runOnFilePostfix(irFile) @@ -64,6 +62,8 @@ class JvmLower(val context: JvmBackendContext) { SingletonReferencesLowering(context).runOnFilePostfix(irFile) SyntheticAccessorLowering(context).lower(irFile) BridgeLowering(context).runOnFilePostfix(irFile) + JvmStaticAnnotationLowering(context).lower(irFile) + StaticDefaultFunctionLowering(context.state).runOnFilePostfix(irFile) TailrecLowering(context).runOnFilePostfix(irFile) ToArrayLowering(context).runOnFilePostfix(irFile) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index ebbfb9d9f34..1f101b91e24 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -18,8 +18,7 @@ import org.jetbrains.org.objectweb.asm.Type class IrFrameMap : FrameMapBase() internal val IrFunction.isStatic - get() = (this.dispatchReceiverParameter == null && this !is IrConstructor) || - (parentAsClass.isObject && this.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME)) //TODO add lowering + get() = (this.dispatchReceiverParameter == null && this !is IrConstructor) fun IrFrameMap.enter(irDeclaration: IrSymbolOwner, type: Type): Int { return enter(irDeclaration.symbol, type) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt new file mode 100644 index 00000000000..4befd37cd8d --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt @@ -0,0 +1,247 @@ +/* + * 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.backend.jvm.lower + +import org.jetbrains.kotlin.backend.common.ClassLoweringPass +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.irBlock +import org.jetbrains.kotlin.backend.common.lower.irBlockBody +import org.jetbrains.kotlin.backend.common.runOnFilePostfix +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl +import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME +import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl +import org.jetbrains.kotlin.ir.types.classifierOrFail +import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.visitors.* +import org.jetbrains.org.objectweb.asm.Opcodes + +/* + * For @JvmStatic functions within companion objects of classes, we synthesize proxy static functions that redirect + * to the actual implementation. + * For @JvmStatic functions within static objects, we make the actual function static and modify all call sites. + */ +class JvmStaticAnnotationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass { + override fun lower(irFile: IrFile) { + CompanionObjectJvmStaticLowering(context).runOnFilePostfix(irFile) + + val functionsMadeStatic = + SingletonObjectJvmStaticLowering(context).apply { runOnFilePostfix(irFile) }.functionsMadeStatic + irFile.transformChildrenVoid(MakeCallsStatic(context, functionsMadeStatic)) + } +} + +private class CompanionObjectJvmStaticLowering(val context: JvmBackendContext) : ClassLoweringPass { + override fun lower(irClass: IrClass) { + val companion = irClass.declarations.find { + it is IrClass && it.isCompanion + } as IrClass? + + companion?.declarations?.filter(::isJvmStaticFunction)?.forEach { + val jvmStaticFunction = it as IrSimpleFunction + val newName = Name.identifier(context.state.typeMapper.mapFunctionName(jvmStaticFunction.symbol.descriptor)) + if (AsmUtil.getVisibilityAccessFlag(jvmStaticFunction.descriptor) != Opcodes.ACC_PUBLIC) { + // TODO: Synthetic accessor creation logic should be supported in SyntheticAccessorLowering in the future. + val accessorName = Name.identifier("access\$$newName") + val accessor = createProxy( + jvmStaticFunction, companion, companion, accessorName, Visibilities.PUBLIC, + isSynthetic = true + ) + companion.addMember(accessor) + val proxy = createProxy( + accessor, irClass, companion, newName, jvmStaticFunction.visibility, isSynthetic = false + ) + irClass.addMember(proxy) + } else { + val proxy = createProxy( + jvmStaticFunction, irClass, companion, newName, jvmStaticFunction.visibility, + isSynthetic = false + ) + irClass.addMember(proxy) + } + } + + } + + private fun createProxy( + target: IrFunction, + irClass: IrClass, + companion: IrClass, + name: Name, + visibility: Visibility, + isSynthetic: Boolean + ): IrFunction { + val proxyFunctionSymbol = makeJvmStaticFunctionSymbol(irClass, target.symbol, name, visibility, isSynthetic) + + val proxyIrFunction = IrFunctionImpl( + UNDEFINED_OFFSET, UNDEFINED_OFFSET, + JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER, + proxyFunctionSymbol + ) + proxyIrFunction.returnType = target.returnType + proxyIrFunction.createParameterDeclarations() + + val companionInstanceFieldSymbol = context.descriptorsFactory.getSymbolForObjectInstance(companion.symbol) + + context.createIrBuilder(proxyIrFunction.symbol).irBlockBody(proxyIrFunction) { + val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, target.returnType, target.symbol) + call.dispatchReceiver = IrGetFieldImpl( + UNDEFINED_OFFSET, + UNDEFINED_OFFSET, + companionInstanceFieldSymbol, + companion.defaultType + ) + proxyIrFunction.extensionReceiverParameter?.let { + call.extensionReceiver = IrGetValueImpl( + UNDEFINED_OFFSET, + UNDEFINED_OFFSET, + it.symbol + ) + } + proxyIrFunction.valueParameters.mapIndexed { i, valueParameter -> + call.putValueArgument( + i, + IrGetValueImpl( + UNDEFINED_OFFSET, + UNDEFINED_OFFSET, + valueParameter.symbol + ) + ) + } + +IrReturnImpl( + UNDEFINED_OFFSET, + UNDEFINED_OFFSET, + proxyIrFunction.returnType, + proxyIrFunction.symbol, + call + ) + }.apply { + proxyIrFunction.body = this + } + + return proxyIrFunction + } +} + +private class SingletonObjectJvmStaticLowering( + val context: JvmBackendContext +) : ClassLoweringPass { + val functionsMadeStatic: MutableSet = mutableSetOf() + + override fun lower(irClass: IrClass) { + if (!irClass.isObject || irClass.isCompanion) return + + irClass.declarations.filter(::isJvmStaticFunction).forEach { + val jvmStaticFunction = it as IrSimpleFunction + val oldDispatchReceiverParemeter = jvmStaticFunction.dispatchReceiverParameter!! + jvmStaticFunction.dispatchReceiverParameter = null + modifyBody(jvmStaticFunction, irClass, oldDispatchReceiverParemeter) + functionsMadeStatic.add(jvmStaticFunction.symbol) + } + } + + fun modifyBody(irFunction: IrFunction, irClass: IrClass, oldDispatchReceiverParameter: IrValueParameter) { + irFunction.body = irFunction.body?.transform(ReplaceThisByStaticReference(context, irClass, oldDispatchReceiverParameter), null) + } +} + +private class ReplaceThisByStaticReference( + val context: JvmBackendContext, + val irClass: IrClass, + val oldThisReceiverParameter: IrValueParameter +) : IrElementTransformer { + override fun visitGetValue(expression: IrGetValue, data: Nothing?): IrExpression { + val irGetValue = expression + if (irGetValue.symbol == oldThisReceiverParameter.symbol) { + val instanceSymbol = context.descriptorsFactory.getSymbolForObjectInstance(irClass.symbol) + return IrGetFieldImpl( + expression.startOffset, + expression.endOffset, + instanceSymbol, + irClass.defaultType + ) + } + return super.visitGetValue(irGetValue, data) + } +} + +private class MakeCallsStatic( + val context: JvmBackendContext, + val functionsMadeStatic: Set +) : IrElementTransformerVoid() { + override fun visitCall(expression: IrCall): IrExpression { + if (functionsMadeStatic.contains(expression.symbol)) { + return context.createIrBuilder(expression.symbol, expression.startOffset, expression.endOffset).irBlock(expression) { + // OldReceiver has to be evaluated for its side effects. + val oldReceiver = super.visitExpression(expression.dispatchReceiver!!) + // `coerceToUnit()` is private in InsertImplicitCasts, have to reproduce it here + val oldReceiverVoid = IrTypeOperatorCallImpl( + oldReceiver.startOffset, oldReceiver.endOffset, + context.irBuiltIns.unitType, + IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, + context.irBuiltIns.unitType, context.irBuiltIns.unitType.classifierOrFail, + oldReceiver + ) + + +super.visitExpression(oldReceiverVoid) + expression.dispatchReceiver = null + +super.visitCall(expression) + } + } + return super.visitCall(expression) + } +} + +private fun isJvmStaticFunction(declaration: IrDeclaration): Boolean = + declaration is IrSimpleFunction && + (declaration.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) || + declaration.correspondingProperty?.hasAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) == true) + +private fun makeJvmStaticFunctionSymbol( + ownerClass: IrClass, + oldFunctionSymbol: IrFunctionSymbol, + newName: Name, + visibility: Visibility, + isSynthetic: Boolean +): IrSimpleFunctionSymbol { + val proxyDescriptorForIrFunction = JvmFunctionDescriptorImpl( + ownerClass.descriptor, + null, + oldFunctionSymbol.descriptor.annotations, + newName, + CallableMemberDescriptor.Kind.SYNTHESIZED, + oldFunctionSymbol.descriptor.source, + extraFlags = if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0 + ) + + proxyDescriptorForIrFunction.initialize( + oldFunctionSymbol.descriptor.extensionReceiverParameter?.type, + null, + oldFunctionSymbol.descriptor.typeParameters, + oldFunctionSymbol.descriptor.valueParameters.map { it.copy(proxyDescriptorForIrFunction, it.name, it.index) }, + oldFunctionSymbol.descriptor.returnType, + // FINAL on static interface members makes JVM unhappy, so remove it. + if (ownerClass.isInterface) Modality.OPEN else oldFunctionSymbol.descriptor.modality, + visibility + ) + + return IrSimpleFunctionSymbolImpl(proxyDescriptorForIrFunction) +} diff --git a/compiler/testData/codegen/box/collections/platformValueContains.kt b/compiler/testData/codegen/box/collections/platformValueContains.kt index a1d06cd6a47..14d2cece53c 100644 --- a/compiler/testData/codegen/box/collections/platformValueContains.kt +++ b/compiler/testData/codegen/box/collections/platformValueContains.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: J.java diff --git a/compiler/testData/codegen/box/jvmStatic/META-INF/main.kotlin_module b/compiler/testData/codegen/box/jvmStatic/META-INF/main.kotlin_module new file mode 100644 index 0000000000000000000000000000000000000000..e634a1d744ec390d4e9caf1d6cd7a1b3abfe7512 GIT binary patch literal 28 dcmZQzU|?ooU|@t|ZZ0k^1|hbP)Z!BF5&#QB0;T`} literal 0 HcmV?d00001 diff --git a/compiler/testData/codegen/box/jvmStatic/annotations.kt b/compiler/testData/codegen/box/jvmStatic/annotations.kt index 0ea4061be87..e5972b1fc60 100644 --- a/compiler/testData/codegen/box/jvmStatic/annotations.kt +++ b/compiler/testData/codegen/box/jvmStatic/annotations.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/companionObject.kt b/compiler/testData/codegen/box/jvmStatic/companionObject.kt index 618008a3f3e..054847a904c 100644 --- a/compiler/testData/codegen/box/jvmStatic/companionObject.kt +++ b/compiler/testData/codegen/box/jvmStatic/companionObject.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/default.kt b/compiler/testData/codegen/box/jvmStatic/default.kt index de8221246b0..31004ce1eeb 100644 --- a/compiler/testData/codegen/box/jvmStatic/default.kt +++ b/compiler/testData/codegen/box/jvmStatic/default.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/explicitObject.kt b/compiler/testData/codegen/box/jvmStatic/explicitObject.kt index 63ab6e46ac9..f3a9a6adfb1 100644 --- a/compiler/testData/codegen/box/jvmStatic/explicitObject.kt +++ b/compiler/testData/codegen/box/jvmStatic/explicitObject.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/importStaticMemberFromObject.kt b/compiler/testData/codegen/box/jvmStatic/importStaticMemberFromObject.kt index 5fbe075ab45..2fc7b467e14 100644 --- a/compiler/testData/codegen/box/jvmStatic/importStaticMemberFromObject.kt +++ b/compiler/testData/codegen/box/jvmStatic/importStaticMemberFromObject.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/inline.kt b/compiler/testData/codegen/box/jvmStatic/inline.kt index c06f31c2f82..c96ed4874c9 100644 --- a/compiler/testData/codegen/box/jvmStatic/inline.kt +++ b/compiler/testData/codegen/box/jvmStatic/inline.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt b/compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt index 89390afc8e3..009297d7fca 100644 --- a/compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt +++ b/compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt b/compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt new file mode 100644 index 00000000000..f64abbc35d6 --- /dev/null +++ b/compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt @@ -0,0 +1,56 @@ +// !LANGUAGE: +JvmStaticInInterface +// JVM_TARGET: 1.8 +// IGNORE_BACKEND: JS_IR +// TODO: muted automatically, investigate should it be ran for JS or not +// IGNORE_BACKEND: JS, NATIVE + +// WITH_RUNTIME +// FILE: Test.java + +class Test { + + public static String test1() { + return A.test1(); + } + + public static String test2() { + return A.test2(); + } + + public static String test3() { + return A.test3("JAVA"); + } + + public static String test4() { + return A.getC(); + } + +} + +// FILE: simpleCompanionObject.kt + +interface A { + companion object { + val b: String = "OK" + + @JvmStatic val c: String = "OK" + + @JvmStatic fun test1() = b + + @JvmStatic fun test2() = b + + @JvmStatic fun String.test3() = this + b + } +} + +fun box(): String { + if (Test.test1() != "OK") return "fail 1" + + if (Test.test2() != "OK") return "fail 2" + + if (Test.test3() != "JAVAOK") return "fail 3" + + if (Test.test4() != "OK") return "fail 4" + + return "OK" +} diff --git a/compiler/testData/codegen/box/jvmStatic/kt21246.kt b/compiler/testData/codegen/box/jvmStatic/kt21246.kt index e692c73be1c..7c8504f9904 100644 --- a/compiler/testData/codegen/box/jvmStatic/kt21246.kt +++ b/compiler/testData/codegen/box/jvmStatic/kt21246.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // TARGET_BACKEND: JVM diff --git a/compiler/testData/codegen/box/jvmStatic/kt9897_static.kt b/compiler/testData/codegen/box/jvmStatic/kt9897_static.kt index 568ec178c65..1603c8b4262 100644 --- a/compiler/testData/codegen/box/jvmStatic/kt9897_static.kt +++ b/compiler/testData/codegen/box/jvmStatic/kt9897_static.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/object.kt b/compiler/testData/codegen/box/jvmStatic/object.kt index 1225d0b57f0..01a8b72b8b9 100644 --- a/compiler/testData/codegen/box/jvmStatic/object.kt +++ b/compiler/testData/codegen/box/jvmStatic/object.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/postfixInc.kt b/compiler/testData/codegen/box/jvmStatic/postfixInc.kt index 4523181b0dd..4b4d65cc45c 100644 --- a/compiler/testData/codegen/box/jvmStatic/postfixInc.kt +++ b/compiler/testData/codegen/box/jvmStatic/postfixInc.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/prefixInc.kt b/compiler/testData/codegen/box/jvmStatic/prefixInc.kt index f46ed41a837..e910ede09e4 100644 --- a/compiler/testData/codegen/box/jvmStatic/prefixInc.kt +++ b/compiler/testData/codegen/box/jvmStatic/prefixInc.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/privateSetter.kt b/compiler/testData/codegen/box/jvmStatic/privateSetter.kt index 6deba204cc3..f9057e1fd0f 100644 --- a/compiler/testData/codegen/box/jvmStatic/privateSetter.kt +++ b/compiler/testData/codegen/box/jvmStatic/privateSetter.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/propertyAccess.kt b/compiler/testData/codegen/box/jvmStatic/propertyAccess.kt index d29fdc216cc..5719ac4f21c 100644 --- a/compiler/testData/codegen/box/jvmStatic/propertyAccess.kt +++ b/compiler/testData/codegen/box/jvmStatic/propertyAccess.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/propertyAsDefault.kt b/compiler/testData/codegen/box/jvmStatic/propertyAsDefault.kt index 038e8ac9043..29a66f73a70 100644 --- a/compiler/testData/codegen/box/jvmStatic/propertyAsDefault.kt +++ b/compiler/testData/codegen/box/jvmStatic/propertyAsDefault.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/propertyGetterDelegatesToAnother.kt b/compiler/testData/codegen/box/jvmStatic/propertyGetterDelegatesToAnother.kt index 0f55589b992..767a0b188ae 100644 --- a/compiler/testData/codegen/box/jvmStatic/propertyGetterDelegatesToAnother.kt +++ b/compiler/testData/codegen/box/jvmStatic/propertyGetterDelegatesToAnother.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // TARGET_BACKEND: JVM object ObjectThisTest { diff --git a/compiler/testData/codegen/box/jvmStatic/simple.kt b/compiler/testData/codegen/box/jvmStatic/simple.kt index ce49b21d95c..dab2e4aa327 100644 --- a/compiler/testData/codegen/box/jvmStatic/simple.kt +++ b/compiler/testData/codegen/box/jvmStatic/simple.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt b/compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt index 29a6fd8ab95..3d00922e502 100644 --- a/compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt +++ b/compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 9de54753a31..05aa5515286 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -12240,6 +12240,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt"); } + @TestMetadata("interfaceCompanion.kt") + public void testInterfaceCompanion() throws Exception { + runTest("compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt"); + } + @TestMetadata("kt21246.kt") public void testKt21246() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/kt21246.kt"); @@ -12314,6 +12319,19 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testSyntheticAccessor() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt"); } + + @TestMetadata("compiler/testData/codegen/box/jvmStatic/META-INF") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class META_INF extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInMETA_INF() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmStatic/META-INF"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + } } @TestMetadata("compiler/testData/codegen/box/labels") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 979a44d2ac2..ca113b096fe 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -12240,6 +12240,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt"); } + @TestMetadata("interfaceCompanion.kt") + public void testInterfaceCompanion() throws Exception { + runTest("compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt"); + } + @TestMetadata("kt21246.kt") public void testKt21246() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/kt21246.kt"); @@ -12314,6 +12319,19 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testSyntheticAccessor() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt"); } + + @TestMetadata("compiler/testData/codegen/box/jvmStatic/META-INF") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class META_INF extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInMETA_INF() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmStatic/META-INF"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + } } @TestMetadata("compiler/testData/codegen/box/labels") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 7ab399e6642..b61de6afca0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -12240,6 +12240,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt"); } + @TestMetadata("interfaceCompanion.kt") + public void testInterfaceCompanion() throws Exception { + runTest("compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt"); + } + @TestMetadata("kt21246.kt") public void testKt21246() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/kt21246.kt"); @@ -12314,6 +12319,19 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testSyntheticAccessor() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt"); } + + @TestMetadata("compiler/testData/codegen/box/jvmStatic/META-INF") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class META_INF extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInMETA_INF() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmStatic/META-INF"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + } } @TestMetadata("compiler/testData/codegen/box/labels") diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java index bd4f1f942f9..46ba9744f86 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java @@ -119,7 +119,6 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion runTest("idea/idea-completion/testData/handlers/basic/KT23627.kt"); } - @TestMetadata("NestedTypeArg.kt") public void testNestedTypeArg() throws Exception { runTest("idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index 209e34ddb7f..209bc3896ea 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -3937,6 +3937,45 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } } + @TestMetadata("idea/testData/quickfix/typeMismatch/numberConversion") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NumberConversion extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInNumberConversion() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/numberConversion"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); + } + } + + @TestMetadata("idea/testData/quickfix/typeMismatch/parameterTypeMismatch") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ParameterTypeMismatch extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInParameterTypeMismatch() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/parameterTypeMismatch"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); + } + } + + @TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeMismatchOnReturnedExpression extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInTypeMismatchOnReturnedExpression() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true); + } + } + @TestMetadata("idea/testData/quickfix/typeMismatch/wrapWithCollectionLiteral") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index 742c365cef7..59ab1d2b2de 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -10735,6 +10735,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt"); } + @TestMetadata("interfaceCompanion.kt") + public void testInterfaceCompanion() throws Exception { + runTest("compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt"); + } + @TestMetadata("kt9897_static.kt") public void testKt9897_static() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/kt9897_static.kt"); @@ -10794,6 +10799,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testSyntheticAccessor() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt"); } + + @TestMetadata("compiler/testData/codegen/box/jvmStatic/META-INF") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class META_INF extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInMETA_INF() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmStatic/META-INF"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); + } + } } @TestMetadata("compiler/testData/codegen/box/labels") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 678fd8d1358..c78cafe44d9 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11730,6 +11730,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/jvmStatic/inlinePropertyAccessors.kt"); } + @TestMetadata("interfaceCompanion.kt") + public void testInterfaceCompanion() throws Exception { + runTest("compiler/testData/codegen/box/jvmStatic/interfaceCompanion.kt"); + } + @TestMetadata("kt9897_static.kt") public void testKt9897_static() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/kt9897_static.kt"); @@ -11789,6 +11794,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testSyntheticAccessor() throws Exception { runTest("compiler/testData/codegen/box/jvmStatic/syntheticAccessor.kt"); } + + @TestMetadata("compiler/testData/codegen/box/jvmStatic/META-INF") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class META_INF extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInMETA_INF() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmStatic/META-INF"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + } } @TestMetadata("compiler/testData/codegen/box/labels")