From 6fc0de39c251f4f188044857e435d456ed34fa70 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Thu, 17 Dec 2020 12:51:53 +0100 Subject: [PATCH 001/197] [PSI2IR] Propagate smart cast information for variable loads. This gives us more precise type information and can enable backend optimizations. This was motivated by when expressions not compiled to table switches in the JVM_IR backend. Fixed KT-36845. --- .../kotlin/psi2ir/generators/CallGenerator.kt | 23 +++++++++++++------ .../psi2ir/generators/StatementGenerator.kt | 4 +++- .../whenEnumOptimization/kt14597_full.kt | 3 --- .../whenEnumOptimization/kt14802.kt | 3 --- .../caoWithAdaptationForSam.kt.txt | 2 +- .../caoWithAdaptationForSam.txt | 2 +- .../ir/irText/expressions/elvis.kt.txt | 4 ++-- .../testData/ir/irText/expressions/elvis.txt | 10 ++++---- .../nullableAnyAsIntToDouble.kt.txt | 8 +------ .../nullableAnyAsIntToDouble.txt | 15 ++---------- .../expressions/implicitCastToNonNull.kt.txt | 4 ++-- .../expressions/implicitCastToNonNull.txt | 4 ++-- .../sam/genericSamSmartcast.kt.txt | 2 +- .../expressions/sam/genericSamSmartcast.txt | 3 ++- ...mConversionInGenericConstructorCall.kt.txt | 2 +- .../samConversionInGenericConstructorCall.txt | 2 +- ...nversionInGenericConstructorCall_NI.kt.txt | 2 +- ...mConversionInGenericConstructorCall_NI.txt | 2 +- .../sam/samConversionToGeneric.kt.txt | 4 ++-- .../sam/samConversionToGeneric.txt | 4 ++-- .../smartCastsWithDestructuring.kt.txt | 6 ++--- .../smartCastsWithDestructuring.txt | 11 +++++---- .../smartCastOnFakeOverrideReceiver.kt.txt | 4 ++-- .../types/smartCastOnFakeOverrideReceiver.txt | 4 ++-- 24 files changed, 59 insertions(+), 69 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index b1fba08cf1a..fc847e6e90c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -86,13 +86,14 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator endOffset: Int, descriptor: DeclarationDescriptor, resolvedCall: ResolvedCall<*>?, - origin: IrStatementOrigin? + origin: IrStatementOrigin?, + irType: IrType? = null ): IrExpression = when (descriptor) { is FakeCallableDescriptorForObject -> - generateValueReference(startOffset, endOffset, descriptor.getReferencedDescriptor(), resolvedCall, origin) + generateValueReference(startOffset, endOffset, descriptor.getReferencedDescriptor(), resolvedCall, origin, irType) is TypeAliasDescriptor -> - generateValueReference(startOffset, endOffset, descriptor.classDescriptor!!, null, origin) + generateValueReference(startOffset, endOffset, descriptor.classDescriptor!!, null, origin, irType) is ClassDescriptor -> { val classValueType = descriptor.classValueType!! statementGenerator.generateSingletonReference(descriptor, startOffset, endOffset, classValueType) @@ -107,7 +108,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator IrGetFieldImpl(startOffset, endOffset, field, fieldType, receiver?.load()) } is VariableDescriptor -> - generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin) + generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin, irType) else -> TODO("Unexpected callable descriptor: $descriptor ${descriptor::class.java.simpleName}") } @@ -117,7 +118,8 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator endOffset: Int, descriptor: VariableDescriptor, typeArguments: Map?, - origin: IrStatementOrigin? = null + origin: IrStatementOrigin? = null, + irType: IrType? = null ) = if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) { val getterDescriptor = descriptor.getter!! @@ -128,8 +130,15 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator context.callToSubstitutedDescriptorMap[this] = getterDescriptor putTypeArguments(typeArguments) { it.toIrType() } } - } else - IrGetValueImpl(startOffset, endOffset, descriptor.type.toIrType(), context.symbolTable.referenceValue(descriptor), origin) + } else { + val getValue = + IrGetValueImpl(startOffset, endOffset, descriptor.type.toIrType(), context.symbolTable.referenceValue(descriptor), origin) + if (irType != null) { + IrTypeOperatorCallImpl(startOffset, endOffset, irType, IrTypeOperator.IMPLICIT_CAST, irType, getValue) + } else { + getValue + } + } fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder): IrExpression = call.callReceiver.call { dispatchReceiver, extensionReceiver -> diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt index cd6bfe7c0b5..dbe3a0d34fe 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue import org.jetbrains.kotlin.psi2ir.intermediate.createTemporaryVariableInBlock import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingContext.SMARTCAST import org.jetbrains.kotlin.resolve.BindingContextUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -327,7 +328,8 @@ class StatementGenerator( ): IrExpression = CallGenerator(this).generateValueReference( expression.startOffsetSkippingComments, expression.endOffset, - descriptor, resolvedCall, null + descriptor, resolvedCall, null, + context.bindingContext.get(SMARTCAST, expression)?.defaultType?.toIrType() ) override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement { diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14597_full.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14597_full.kt index e006b5a0a45..6e79d96a82d 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14597_full.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14597_full.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// TODO KT-36845 Generate enum-based TABLESWITCH/LOOKUPSWITCH on a value with smart cast to enum in JVM_IR - enum class En { A, B, С } fun box() { diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14802.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14802.kt index 96b7ce38d35..edd99cad712 100644 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14802.kt +++ b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14802.kt @@ -1,6 +1,3 @@ -// IGNORE_BACKEND: JVM_IR -// TODO KT-36845 Generate enum-based TABLESWITCH/LOOKUPSWITCH on a value with smart cast to enum in JVM_IR - class EncapsulatedEnum>(val value: T) enum class MyEnum(val value: String) { diff --git a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.kt.txt b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.kt.txt index 2a8da60a737..225648dd90a 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.kt.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.kt.txt @@ -89,7 +89,7 @@ fun test5(a: Any) { a as Function1 /*~> Unit */ { // BLOCK val tmp0_array: A = A - val tmp2_sam: IFoo = a /*as Function1<@ParameterName(name = "i") Int, Unit> */ /*-> IFoo */ + val tmp2_sam: IFoo = a /*as Function1 */ /*-> IFoo */ tmp0_array.set(i = tmp2_sam, newValue = tmp0_array.get(i = tmp2_sam).plus(other = 1)) } } diff --git a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.txt b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.txt index a832bdbd431..46b03f58936 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/caoWithAdaptationForSam.txt @@ -199,7 +199,7 @@ FILE fqName: fileName:/caoWithAdaptationForSam.kt GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.A VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:.IFoo [val] TYPE_OP type=.IFoo origin=SAM_CONVERSION typeOperand=.IFoo - TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'i')] kotlin.Int, kotlin.Unit> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'i')] kotlin.Int, kotlin.Unit> + TYPE_OP type=kotlin.Function1 origin=IMPLICIT_CAST typeOperand=kotlin.Function1 GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null CALL 'public final fun set (i: .IFoo, newValue: kotlin.Int): kotlin.Unit [operator] declared in ' type=kotlin.Unit origin=PLUSEQ $receiver: GET_VAR 'val tmp_8: .A [val] declared in .test5' type=.A origin=null diff --git a/compiler/testData/ir/irText/expressions/elvis.kt.txt b/compiler/testData/ir/irText/expressions/elvis.kt.txt index 1906fcd3efa..25899bebd6a 100644 --- a/compiler/testData/ir/irText/expressions/elvis.kt.txt +++ b/compiler/testData/ir/irText/expressions/elvis.kt.txt @@ -34,10 +34,10 @@ fun test3(a: Any?, b: Any?): String { a !is String? -> return "" } return { // BLOCK - val tmp0_elvis_lhs: Any? = a + val tmp0_elvis_lhs: String? = a /*as String? */ when { EQEQ(arg0 = tmp0_elvis_lhs, arg1 = null) -> b /*as String */ - else -> tmp0_elvis_lhs /*as String */ + else -> tmp0_elvis_lhs } } } diff --git a/compiler/testData/ir/irText/expressions/elvis.txt b/compiler/testData/ir/irText/expressions/elvis.txt index 4d0432e69bf..3fe78d58f46 100644 --- a/compiler/testData/ir/irText/expressions/elvis.txt +++ b/compiler/testData/ir/irText/expressions/elvis.txt @@ -64,19 +64,19 @@ FILE fqName: fileName:/elvis.kt CONST String type=kotlin.String value="" RETURN type=kotlin.Nothing from='public final fun test3 (a: kotlin.Any?, b: kotlin.Any?): kotlin.String declared in ' BLOCK type=kotlin.String origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Any? [val] - GET_VAR 'a: kotlin.Any? declared in .test3' type=kotlin.Any? origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] + TYPE_OP type=kotlin.String? origin=IMPLICIT_CAST typeOperand=kotlin.String? + GET_VAR 'a: kotlin.Any? declared in .test3' type=kotlin.Any? origin=null WHEN type=kotlin.String origin=null BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_2: kotlin.Any? [val] declared in .test3' type=kotlin.Any? origin=null + arg0: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .test3' type=kotlin.String? origin=null arg1: CONST Null type=kotlin.Nothing? value=null then: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String GET_VAR 'b: kotlin.Any? declared in .test3' type=kotlin.Any? origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true - then: TYPE_OP type=kotlin.String origin=IMPLICIT_CAST typeOperand=kotlin.String - GET_VAR 'val tmp_2: kotlin.Any? [val] declared in .test3' type=kotlin.Any? origin=null + then: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .test3' type=kotlin.String? origin=null FUN name:test4 visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Any VALUE_PARAMETER name:x index:0 type:kotlin.Any BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt.txt b/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt.txt index 30e1040f2a5..994da11b45d 100644 --- a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt.txt +++ b/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt.txt @@ -1,12 +1,6 @@ fun test(x: Any?, y: Double): Boolean { return when { - x is Int -> less(arg0 = { // BLOCK - val tmp0_safe_receiver: Any? = x - when { - EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null - else -> tmp0_safe_receiver /*as Int */.toDouble() - } - }, arg1 = y) + x is Int -> less(arg0 = x /*as Int */.toDouble(), arg1 = y) else -> false } } diff --git a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.txt b/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.txt index 4fba5465ab7..c9b9b99b311 100644 --- a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.txt +++ b/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.txt @@ -9,20 +9,9 @@ FILE fqName: fileName:/nullableAnyAsIntToDouble.kt if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Int GET_VAR 'x: kotlin.Any? declared in .test' type=kotlin.Any? origin=null then: CALL 'public final fun less (arg0: kotlin.Double, arg1: kotlin.Double): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT - arg0: BLOCK type=kotlin.Double? origin=SAFE_CALL - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any? [val] + arg0: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Int' type=kotlin.Double origin=null + $this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int GET_VAR 'x: kotlin.Any? declared in .test' type=kotlin.Any? origin=null - WHEN type=kotlin.Double? origin=null - BRANCH - if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null - arg1: CONST Null type=kotlin.Nothing? value=null - then: CONST Null type=kotlin.Nothing? value=null - BRANCH - if: CONST Boolean type=kotlin.Boolean value=true - then: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Int' type=kotlin.Double origin=null - $this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int - GET_VAR 'val tmp_0: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null arg1: GET_VAR 'y: kotlin.Double declared in .test' type=kotlin.Double origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true diff --git a/compiler/testData/ir/irText/expressions/implicitCastToNonNull.kt.txt b/compiler/testData/ir/irText/expressions/implicitCastToNonNull.kt.txt index 4b880aec3fc..70ed96c17a8 100644 --- a/compiler/testData/ir/irText/expressions/implicitCastToNonNull.kt.txt +++ b/compiler/testData/ir/irText/expressions/implicitCastToNonNull.kt.txt @@ -15,14 +15,14 @@ fun test2(x: T): Int { inline fun test3(x: Any): Int { return when { x !is T -> 0 - else -> x /*as CharSequence */.() + else -> x /*as T */.() } } inline fun test4(x: Any?): Int { return when { x !is T -> 0 - else -> x /*as CharSequence */.() + else -> x /*as T */.() } } diff --git a/compiler/testData/ir/irText/expressions/implicitCastToNonNull.txt b/compiler/testData/ir/irText/expressions/implicitCastToNonNull.txt index 41a2e36e965..5d32173c40c 100644 --- a/compiler/testData/ir/irText/expressions/implicitCastToNonNull.txt +++ b/compiler/testData/ir/irText/expressions/implicitCastToNonNull.txt @@ -41,7 +41,7 @@ FILE fqName: fileName:/implicitCastToNonNull.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public abstract fun (): kotlin.Int declared in kotlin.CharSequence' type=kotlin.Int origin=GET_PROPERTY - $this: TYPE_OP type=kotlin.CharSequence origin=IMPLICIT_CAST typeOperand=kotlin.CharSequence + $this: TYPE_OP type=T of .test3 origin=IMPLICIT_CAST typeOperand=T of .test3 GET_VAR 'x: kotlin.Any declared in .test3' type=kotlin.Any origin=null FUN name:test4 visibility:public modality:FINAL (x:kotlin.Any?) returnType:kotlin.Int [inline] TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.CharSequence] @@ -56,7 +56,7 @@ FILE fqName: fileName:/implicitCastToNonNull.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CALL 'public abstract fun (): kotlin.Int declared in kotlin.CharSequence' type=kotlin.Int origin=GET_PROPERTY - $this: TYPE_OP type=kotlin.CharSequence origin=IMPLICIT_CAST typeOperand=kotlin.CharSequence + $this: TYPE_OP type=T of .test4 origin=IMPLICIT_CAST typeOperand=T of .test4 GET_VAR 'x: kotlin.Any? declared in .test4' type=kotlin.Any? origin=null FUN name:test5 visibility:public modality:FINAL (x:T of .test5, fn:kotlin.Function1.test5, kotlin.Unit>) returnType:kotlin.Unit TYPE_PARAMETER name:T index:0 variance: superTypes:[S of .test5?] diff --git a/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.kt.txt b/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.kt.txt index 4188588622b..ff50d562da6 100644 --- a/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.kt.txt +++ b/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.kt.txt @@ -1,7 +1,7 @@ fun f(x: Any): String { when { x is A<*> -> { // BLOCK - return x /*as A */.call(block = local fun (y: Any?): @FlexibleNullability String? { + return x /*as A<*> */ /*as A */.call(block = local fun (y: Any?): @FlexibleNullability String? { return "OK" } /*-> @FlexibleNullability I<@FlexibleNullability T?>? */) /*!! String */ diff --git a/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.txt b/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.txt index 6691f1859ff..9ceb814ffab 100644 --- a/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.txt +++ b/compiler/testData/ir/irText/expressions/sam/genericSamSmartcast.txt @@ -11,7 +11,8 @@ FILE fqName: fileName:/genericSamSmartcast.kt TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String CALL 'public open fun call (block: @[FlexibleNullability] .A.I<@[FlexibleNullability] T of .A?>?): @[FlexibleNullability] kotlin.String? declared in .A' type=@[FlexibleNullability] kotlin.String? origin=null $this: TYPE_OP type=.A.A> origin=IMPLICIT_CAST typeOperand=.A.A> - GET_VAR 'x: kotlin.Any declared in .f' type=kotlin.Any origin=null + TYPE_OP type=.A<*> origin=IMPLICIT_CAST typeOperand=.A<*> + GET_VAR 'x: kotlin.Any declared in .f' type=kotlin.Any origin=null block: TYPE_OP type=@[FlexibleNullability] .A.I<@[FlexibleNullability] T of .A?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] .A.I<@[FlexibleNullability] T of .A?>? FUN_EXPR type=kotlin.Function1 origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (y:kotlin.Any?) returnType:@[FlexibleNullability] kotlin.String? diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt.txt index 799c183c678..b2a8e98e6ea 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.kt.txt @@ -4,6 +4,6 @@ fun test1(f: Function1): C<@FlexibleNullability String?> { fun test2(x: Any) { x as Function1 /*~> Unit */ - C<@FlexibleNullability String?>(jxx = x /*as Function1<@ParameterName(name = "x") @FlexibleNullability String?, @FlexibleNullability String?> */ /*-> @FlexibleNullability J<@FlexibleNullability String?, @FlexibleNullability String?>? */) /*~> Unit */ + C<@FlexibleNullability String?>(jxx = x /*as Function1 */ /*-> @FlexibleNullability J<@FlexibleNullability String?, @FlexibleNullability String?>? */) /*~> Unit */ } diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.txt index d0156cf0372..c99d235eca4 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall.txt @@ -17,5 +17,5 @@ FILE fqName: fileName:/samConversionInGenericConstructorCall.kt CONSTRUCTOR_CALL 'public constructor (jxx: @[FlexibleNullability] .J<@[FlexibleNullability] X of .C?, @[FlexibleNullability] X of .C?>?) declared in .C' type=.C<@[FlexibleNullability] kotlin.String?> origin=null : @[FlexibleNullability] kotlin.String? jxx: TYPE_OP type=@[FlexibleNullability] .J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] .J<@[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?>? - TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?> + TYPE_OP type=kotlin.Function1 origin=IMPLICIT_CAST typeOperand=kotlin.Function1 GET_VAR 'x: kotlin.Any declared in .test2' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt.txt index 179e9a35468..4de1ad8e837 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.kt.txt @@ -38,6 +38,6 @@ fun testGenericJavaCtor1(f: Function1): G<@FlexibleNullability Stri fun testGenericJavaCtor2(x: Any) { x as Function1 /*~> Unit */ - G<@FlexibleNullability String?, @FlexibleNullability Int?>(x = x /*as Function1<@ParameterName(name = "x") @FlexibleNullability String?, @FlexibleNullability Int?> */ /*-> @FlexibleNullability J<@FlexibleNullability Int?, @FlexibleNullability String?>? */) /*~> Unit */ + G<@FlexibleNullability String?, @FlexibleNullability Int?>(x = x /*as Function1 */ /*-> @FlexibleNullability J<@FlexibleNullability Int?, @FlexibleNullability String?>? */) /*~> Unit */ } diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.txt b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.txt index 7d57b2140ad..229419e46fa 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionInGenericConstructorCall_NI.txt @@ -110,5 +110,5 @@ FILE fqName: fileName:/samConversionInGenericConstructorCall_NI.kt : @[FlexibleNullability] kotlin.String? : @[FlexibleNullability] kotlin.Int? x: TYPE_OP type=@[FlexibleNullability] .J<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] .J<@[FlexibleNullability] kotlin.Int?, @[FlexibleNullability] kotlin.String?>? - TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.Int?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.Int?> + TYPE_OP type=kotlin.Function1 origin=IMPLICIT_CAST typeOperand=kotlin.Function1 GET_VAR 'x: kotlin.Any declared in .testGenericJavaCtor2' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt.txt b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt.txt index 73b504c7621..ed788a12528 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.kt.txt @@ -26,7 +26,7 @@ fun test4(a: Any) { fun test5(a: Any) { a as Function1 /*~> Unit */ - bar<@FlexibleNullability String?>(j = a /*as Function1<@ParameterName(name = "x") @FlexibleNullability String?, @FlexibleNullability String?> */ /*-> @FlexibleNullability J<@FlexibleNullability String?>? */) + bar<@FlexibleNullability String?>(j = a /*as Function1 */ /*-> @FlexibleNullability J<@FlexibleNullability String?>? */) } fun test6(a: Function1) { @@ -35,7 +35,7 @@ fun test6(a: Function1) { fun test7(a: Any) { a as Function1 /*~> Unit */ - bar<@FlexibleNullability T?>(j = a /*as Function1<@ParameterName(name = "x") @FlexibleNullability T?, @FlexibleNullability T?> */ /*-> @FlexibleNullability J<@FlexibleNullability T?>? */) + bar<@FlexibleNullability T?>(j = a /*as Function1 */ /*-> @FlexibleNullability J<@FlexibleNullability T?>? */) } fun test8(efn: @ExtensionFunctionType Function1): J<@FlexibleNullability String?> { diff --git a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.txt b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.txt index 5407c55305c..ce62696bc7b 100644 --- a/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.txt +++ b/compiler/testData/ir/irText/expressions/sam/samConversionToGeneric.txt @@ -50,7 +50,7 @@ FILE fqName: fileName:/samConversionToGeneric.kt CALL 'public open fun bar (j: @[FlexibleNullability] .J<@[FlexibleNullability] X of .H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null : @[FlexibleNullability] kotlin.String? j: TYPE_OP type=@[FlexibleNullability] .J<@[FlexibleNullability] kotlin.String?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] .J<@[FlexibleNullability] kotlin.String?>? - TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?> + TYPE_OP type=kotlin.Function1 origin=IMPLICIT_CAST typeOperand=kotlin.Function1 GET_VAR 'a: kotlin.Any declared in .test5' type=kotlin.Any origin=null FUN name:test6 visibility:public modality:FINAL (a:kotlin.Function1.test6, T of .test6>) returnType:kotlin.Unit TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] @@ -70,7 +70,7 @@ FILE fqName: fileName:/samConversionToGeneric.kt CALL 'public open fun bar (j: @[FlexibleNullability] .J<@[FlexibleNullability] X of .H.bar?>?): kotlin.Unit declared in .H' type=kotlin.Unit origin=null : @[FlexibleNullability] T of .test7? j: TYPE_OP type=@[FlexibleNullability] .J<@[FlexibleNullability] T of .test7?>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] .J<@[FlexibleNullability] T of .test7?>? - TYPE_OP type=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] T of .test7?, @[FlexibleNullability] T of .test7?> origin=IMPLICIT_CAST typeOperand=kotlin.Function1<@[ParameterName(name = 'x')] @[FlexibleNullability] T of .test7?, @[FlexibleNullability] T of .test7?> + TYPE_OP type=kotlin.Function1.test7, T of .test7> origin=IMPLICIT_CAST typeOperand=kotlin.Function1.test7, T of .test7> GET_VAR 'a: kotlin.Any declared in .test7' type=kotlin.Any origin=null FUN name:test8 visibility:public modality:FINAL <> (efn:@[ExtensionFunctionType] kotlin.Function1) returnType:.J<@[FlexibleNullability] kotlin.String?> VALUE_PARAMETER name:efn index:0 type:@[ExtensionFunctionType] kotlin.Function1 diff --git a/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.kt.txt b/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.kt.txt index b67ccc83075..103d5468f2e 100644 --- a/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.kt.txt +++ b/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.kt.txt @@ -19,9 +19,9 @@ fun test(x: I1) { x !is I2 -> return Unit } // COMPOSITE { - val tmp0_container: I1 = x - val c1: Int = tmp0_container.component1() - val c2: String = tmp0_container /*as I2 */.component2() + val tmp0_container: I2 = x /*as I2 */ + val c1: Int = tmp0_container /*as I1 */.component1() + val c2: String = tmp0_container.component2() // } } diff --git a/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt b/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt index c62a4a1435d..278e9257ecb 100644 --- a/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt +++ b/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt @@ -49,12 +49,13 @@ FILE fqName: fileName:/smartCastsWithDestructuring.kt then: RETURN type=kotlin.Nothing from='public final fun test (x: .I1): kotlin.Unit declared in ' GET_OBJECT 'CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit COMPOSITE type=kotlin.Unit origin=DESTRUCTURING_DECLARATION - VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.I1 [val] - GET_VAR 'x: .I1 declared in .test' type=.I1 origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.I2 [val] + TYPE_OP type=.I2 origin=IMPLICIT_CAST typeOperand=.I2 + GET_VAR 'x: .I1 declared in .test' type=.I1 origin=null VAR name:c1 type:kotlin.Int [val] CALL 'public final fun component1 (): kotlin.Int [operator] declared in ' type=kotlin.Int origin=COMPONENT_N(index=1) - $receiver: GET_VAR 'val tmp_0: .I1 [val] declared in .test' type=.I1 origin=null + $receiver: TYPE_OP type=.I1 origin=IMPLICIT_CAST typeOperand=.I1 + GET_VAR 'val tmp_0: .I2 [val] declared in .test' type=.I2 origin=null VAR name:c2 type:kotlin.String [val] CALL 'public final fun component2 (): kotlin.String [operator] declared in ' type=kotlin.String origin=COMPONENT_N(index=2) - $receiver: TYPE_OP type=.I2 origin=IMPLICIT_CAST typeOperand=.I2 - GET_VAR 'val tmp_0: .I1 [val] declared in .test' type=.I1 origin=null + $receiver: GET_VAR 'val tmp_0: .I2 [val] declared in .test' type=.I2 origin=null diff --git a/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.kt.txt b/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.kt.txt index 2d41ef13f73..f5cc9cd21b7 100644 --- a/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.kt.txt +++ b/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.kt.txt @@ -78,8 +78,8 @@ class GB : GA { fun testGB1(a: Any) { a as GB /*~> Unit */ - a /*as GB<*, *> */.f() /*~> Unit */ - a /*as GB<*, *> */.() /*~> Unit */ + a /*as GB */.f() /*~> Unit */ + a /*as GB */.() /*~> Unit */ } } diff --git a/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.txt b/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.txt index 0bb26d5c38d..8f6e2e2aa16 100644 --- a/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.txt +++ b/compiler/testData/ir/irText/types/smartCastOnFakeOverrideReceiver.txt @@ -187,11 +187,11 @@ FILE fqName: fileName:/smartCastOnFakeOverrideReceiver.kt GET_VAR 'a: kotlin.Any declared in .GB.testGB1' type=kotlin.Any origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit CALL 'public final fun f (): kotlin.Int [fake_override] declared in .GB' type=kotlin.Int origin=null - $this: TYPE_OP type=.GB<*, *> origin=IMPLICIT_CAST typeOperand=.GB<*, *> + $this: TYPE_OP type=.GB origin=IMPLICIT_CAST typeOperand=.GB GET_VAR 'a: kotlin.Any declared in .GB.testGB1' type=kotlin.Any origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit CALL 'public final fun (): kotlin.Int [fake_override] declared in .GB' type=kotlin.Int origin=GET_PROPERTY - $this: TYPE_OP type=.GB<*, *> origin=IMPLICIT_CAST typeOperand=.GB<*, *> + $this: TYPE_OP type=.GB origin=IMPLICIT_CAST typeOperand=.GB GET_VAR 'a: kotlin.Any declared in .GB.testGB1' type=kotlin.Any origin=null FUN FAKE_OVERRIDE name:f visibility:public modality:FINAL <> ($this:.GA.GB>) returnType:kotlin.Int [fake_override] overridden: From dfc86feecd85060e5f5cf7a2173638cbf5d98101 Mon Sep 17 00:00:00 2001 From: Mads Ager Date: Thu, 7 Jan 2021 13:56:02 +0100 Subject: [PATCH 002/197] [IR] Extend test coverage for smart cast handling. --- ...ackBoxAgainstJavaCodegenTestGenerated.java | 5 + .../ir/FirBlackBoxCodegenTestGenerated.java | 10 ++ .../kotlin/fir/Fir2IrTextTestGenerated.java | 10 ++ .../codegen/box/ieee754/smartCastToInt.kt | 8 ++ .../box/smartCasts/multipleSmartCast.kt | 22 +++ .../sam/smartCastSamConversion.kt | 22 +++ .../nullableAnyAsIntToDouble.fir.txt | 18 --- .../nullableAnyAsIntToDouble.kt | 1 + .../expressions/multipleSmartCasts.fir.kt.txt | 22 +++ .../expressions/multipleSmartCasts.fir.txt | 61 +++++++++ .../irText/expressions/multipleSmartCasts.kt | 13 ++ .../expressions/multipleSmartCasts.kt.txt | 24 ++++ .../irText/expressions/multipleSmartCasts.txt | 61 +++++++++ .../whenSmartCastToEnum.fir.kt.txt | 54 ++++++++ .../expressions/whenSmartCastToEnum.fir.txt | 124 +++++++++++++++++ .../irText/expressions/whenSmartCastToEnum.kt | 23 ++++ .../expressions/whenSmartCastToEnum.kt.txt | 56 ++++++++ .../expressions/whenSmartCastToEnum.txt | 126 ++++++++++++++++++ ...ackBoxAgainstJavaCodegenTestGenerated.java | 5 + .../codegen/BlackBoxCodegenTestGenerated.java | 10 ++ .../LightAnalysisModeTestGenerated.java | 10 ++ ...ackBoxAgainstJavaCodegenTestGenerated.java | 5 + .../ir/IrBlackBoxCodegenTestGenerated.java | 10 ++ .../kotlin/ir/IrTextTestCaseGenerated.java | 10 ++ .../IrJsCodegenBoxES6TestGenerated.java | 10 ++ .../IrJsCodegenBoxTestGenerated.java | 10 ++ .../semantics/JsCodegenBoxTestGenerated.java | 10 ++ .../IrCodegenBoxWasmTestGenerated.java | 10 ++ 28 files changed, 732 insertions(+), 18 deletions(-) create mode 100644 compiler/testData/codegen/box/ieee754/smartCastToInt.kt create mode 100644 compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt create mode 100644 compiler/testData/codegen/boxAgainstJava/sam/smartCastSamConversion.kt delete mode 100644 compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.fir.txt create mode 100644 compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.kt.txt create mode 100644 compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.txt create mode 100644 compiler/testData/ir/irText/expressions/multipleSmartCasts.kt create mode 100644 compiler/testData/ir/irText/expressions/multipleSmartCasts.kt.txt create mode 100644 compiler/testData/ir/irText/expressions/multipleSmartCasts.txt create mode 100644 compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.kt.txt create mode 100644 compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.txt create mode 100644 compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt create mode 100644 compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt.txt create mode 100644 compiler/testData/ir/irText/expressions/whenSmartCastToEnum.txt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java index 4fb4b1e293d..784f8b3cdcb 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxAgainstJavaCodegenTestGenerated.java @@ -710,6 +710,11 @@ public class FirBlackBoxAgainstJavaCodegenTestGenerated extends AbstractFirBlack runTest("compiler/testData/codegen/boxAgainstJava/sam/samConstructorGenericSignature.kt"); } + @TestMetadata("smartCastSamConversion.kt") + public void testSmartCastSamConversion() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/sam/smartCastSamConversion.kt"); + } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/sam/adapters") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 79721420c6e..779843e3493 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -13125,6 +13125,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("when.kt") public void testWhen() throws Exception { runTest("compiler/testData/codegen/box/ieee754/when.kt"); @@ -30781,6 +30786,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/smartCasts/lambdaArgumentWithoutType.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("nullSmartCast.kt") public void testNullSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt"); diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index 5384de8c033..6459d0e19a0 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1188,6 +1188,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/expressions/membersImportedFromObject.kt"); } + @TestMetadata("multipleSmartCasts.kt") + public void testMultipleSmartCasts() throws Exception { + runTest("compiler/testData/ir/irText/expressions/multipleSmartCasts.kt"); + } + @TestMetadata("multipleThisReferences.kt") public void testMultipleThisReferences() throws Exception { runTest("compiler/testData/ir/irText/expressions/multipleThisReferences.kt"); @@ -1453,6 +1458,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/expressions/whenReturnUnit.kt"); } + @TestMetadata("whenSmartCastToEnum.kt") + public void testWhenSmartCastToEnum() throws Exception { + runTest("compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt"); + } + @TestMetadata("whenUnusedExpression.kt") public void testWhenUnusedExpression() throws Exception { runTest("compiler/testData/ir/irText/expressions/whenUnusedExpression.kt"); diff --git a/compiler/testData/codegen/box/ieee754/smartCastToInt.kt b/compiler/testData/codegen/box/ieee754/smartCastToInt.kt new file mode 100644 index 00000000000..c08e492291f --- /dev/null +++ b/compiler/testData/codegen/box/ieee754/smartCastToInt.kt @@ -0,0 +1,8 @@ +fun test(x: Any?, y: Double) = + x is Int && x < y + +fun box(): String = + if (!test(0, -0.0)) + "OK" + else + "Failed" diff --git a/compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt b/compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt new file mode 100644 index 00000000000..1fc0b74749b --- /dev/null +++ b/compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt @@ -0,0 +1,22 @@ +interface IC1 { + operator fun component1(): String +} + +interface IC2 { + operator fun component2(): String +} + +class A : IC1, IC2 { + override fun component1(): String = "O" + override fun component2(): String = "K" +} + +fun test(x: Any): String { + if (x is IC1 && x is IC2) { + val (x1, x2) = x + return "$x1$x2" + } + return "FAIL" +} + +fun box(): String = test(A()) \ No newline at end of file diff --git a/compiler/testData/codegen/boxAgainstJava/sam/smartCastSamConversion.kt b/compiler/testData/codegen/boxAgainstJava/sam/smartCastSamConversion.kt new file mode 100644 index 00000000000..563ecbc76a8 --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/sam/smartCastSamConversion.kt @@ -0,0 +1,22 @@ +// FILE: test.kt +fun test(a: Any) { + a as (String) -> String + J.use(a) +} + +fun box(): String { + test({s: String? -> s}) + return "OK" +} + +// FILE: JFoo.java +public interface JFoo { + T foo(T x); +} + +// FILE: J.java +public class J { + public static void use(JFoo jfoo) { + jfoo.foo(null); + } +} diff --git a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.fir.txt b/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.fir.txt deleted file mode 100644 index c9b9b99b311..00000000000 --- a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.fir.txt +++ /dev/null @@ -1,18 +0,0 @@ -FILE fqName: fileName:/nullableAnyAsIntToDouble.kt - FUN name:test visibility:public modality:FINAL <> (x:kotlin.Any?, y:kotlin.Double) returnType:kotlin.Boolean - VALUE_PARAMETER name:x index:0 type:kotlin.Any? - VALUE_PARAMETER name:y index:1 type:kotlin.Double - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun test (x: kotlin.Any?, y: kotlin.Double): kotlin.Boolean declared in ' - WHEN type=kotlin.Boolean origin=ANDAND - BRANCH - if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Int - GET_VAR 'x: kotlin.Any? declared in .test' type=kotlin.Any? origin=null - then: CALL 'public final fun less (arg0: kotlin.Double, arg1: kotlin.Double): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT - arg0: CALL 'public open fun toDouble (): kotlin.Double declared in kotlin.Int' type=kotlin.Double origin=null - $this: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int - GET_VAR 'x: kotlin.Any? declared in .test' type=kotlin.Any? origin=null - arg1: GET_VAR 'y: kotlin.Double declared in .test' type=kotlin.Double origin=null - BRANCH - if: CONST Boolean type=kotlin.Boolean value=true - then: CONST Boolean type=kotlin.Boolean value=false diff --git a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt b/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt index ecbdc6d17aa..6876f02294c 100644 --- a/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt +++ b/compiler/testData/ir/irText/expressions/floatingPointComparisons/nullableAnyAsIntToDouble.kt @@ -1,2 +1,3 @@ +// FIR_IDENTICAL fun test(x: Any?, y: Double) = x is Int && x < y \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.kt.txt b/compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.kt.txt new file mode 100644 index 00000000000..1cdd20ca6d0 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.kt.txt @@ -0,0 +1,22 @@ +interface IC1 { + abstract operator fun component1(): Int + +} + +interface IC2 { + abstract operator fun component2(): String + +} + +fun test(x: Any) { + when { + when { + x is IC1 -> x /*as IC1 */ is IC2 + else -> false + } -> { // BLOCK + val : IC1 = x /*as IC1 */ + val x1: Int = .component1() + val x2: String = /*as IC2 */.component2() + } + } +} diff --git a/compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.txt b/compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.txt new file mode 100644 index 00000000000..3f44bf5ad7f --- /dev/null +++ b/compiler/testData/ir/irText/expressions/multipleSmartCasts.fir.txt @@ -0,0 +1,61 @@ +FILE fqName: fileName:/multipleSmartCasts.kt + CLASS INTERFACE name:IC1 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.IC1 + FUN name:component1 visibility:public modality:ABSTRACT <> ($this:.IC1) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.IC1 + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:IC2 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.IC2 + FUN name:component2 visibility:public modality:ABSTRACT <> ($this:.IC2) returnType:kotlin.String [operator] + $this: VALUE_PARAMETER name: type:.IC2 + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: WHEN type=kotlin.Boolean origin=ANDAND + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.IC1 + GET_VAR 'x: kotlin.Any declared in .test' type=kotlin.Any origin=null + then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.IC2 + TYPE_OP type=.IC1 origin=IMPLICIT_CAST typeOperand=.IC1 + GET_VAR 'x: kotlin.Any declared in .test' type=kotlin.Any origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CONST Boolean type=kotlin.Boolean value=false + then: BLOCK type=kotlin.Unit origin=null + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.IC1 [val] + TYPE_OP type=.IC1 origin=IMPLICIT_CAST typeOperand=.IC1 + GET_VAR 'x: kotlin.Any declared in .test' type=kotlin.Any origin=null + VAR name:x1 type:kotlin.Int [val] + CALL 'public abstract fun component1 (): kotlin.Int [operator] declared in .IC1' type=kotlin.Int origin=null + $this: GET_VAR 'val tmp_0: .IC1 [val] declared in .test' type=.IC1 origin=null + VAR name:x2 type:kotlin.String [val] + CALL 'public abstract fun component2 (): kotlin.String [operator] declared in .IC2' type=kotlin.String origin=null + $this: TYPE_OP type=.IC2 origin=IMPLICIT_CAST typeOperand=.IC2 + GET_VAR 'val tmp_0: .IC1 [val] declared in .test' type=.IC1 origin=null diff --git a/compiler/testData/ir/irText/expressions/multipleSmartCasts.kt b/compiler/testData/ir/irText/expressions/multipleSmartCasts.kt new file mode 100644 index 00000000000..1eb9384ea67 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/multipleSmartCasts.kt @@ -0,0 +1,13 @@ +interface IC1 { + operator fun component1(): Int +} + +interface IC2 { + operator fun component2(): String +} + +fun test(x: Any) { + if (x is IC1 && x is IC2) { + val (x1, x2) = x + } +} diff --git a/compiler/testData/ir/irText/expressions/multipleSmartCasts.kt.txt b/compiler/testData/ir/irText/expressions/multipleSmartCasts.kt.txt new file mode 100644 index 00000000000..ca4c7ca8d04 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/multipleSmartCasts.kt.txt @@ -0,0 +1,24 @@ +interface IC1 { + abstract operator fun component1(): Int + +} + +interface IC2 { + abstract operator fun component2(): String + +} + +fun test(x: Any) { + when { + when { + x is IC1 -> x is IC2 + else -> false + } -> { // BLOCK + // COMPOSITE { + val tmp0_container: Any = x + val x1: Int = tmp0_container /*as IC1 */.component1() + val x2: String = tmp0_container /*as IC2 */.component2() + // } + } + } +} diff --git a/compiler/testData/ir/irText/expressions/multipleSmartCasts.txt b/compiler/testData/ir/irText/expressions/multipleSmartCasts.txt new file mode 100644 index 00000000000..3279f283ead --- /dev/null +++ b/compiler/testData/ir/irText/expressions/multipleSmartCasts.txt @@ -0,0 +1,61 @@ +FILE fqName: fileName:/multipleSmartCasts.kt + CLASS INTERFACE name:IC1 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.IC1 + FUN name:component1 visibility:public modality:ABSTRACT <> ($this:.IC1) returnType:kotlin.Int [operator] + $this: VALUE_PARAMETER name: type:.IC1 + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:IC2 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.IC2 + FUN name:component2 visibility:public modality:ABSTRACT <> ($this:.IC2) returnType:kotlin.String [operator] + $this: VALUE_PARAMETER name: type:.IC2 + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:test visibility:public modality:FINAL <> (x:kotlin.Any) returnType:kotlin.Unit + VALUE_PARAMETER name:x index:0 type:kotlin.Any + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: WHEN type=kotlin.Boolean origin=ANDAND + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.IC1 + GET_VAR 'x: kotlin.Any declared in .test' type=kotlin.Any origin=null + then: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.IC2 + GET_VAR 'x: kotlin.Any declared in .test' type=kotlin.Any origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CONST Boolean type=kotlin.Boolean value=false + then: BLOCK type=kotlin.Unit origin=null + COMPOSITE type=kotlin.Unit origin=DESTRUCTURING_DECLARATION + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Any [val] + GET_VAR 'x: kotlin.Any declared in .test' type=kotlin.Any origin=null + VAR name:x1 type:kotlin.Int [val] + CALL 'public abstract fun component1 (): kotlin.Int [operator] declared in .IC1' type=kotlin.Int origin=COMPONENT_N(index=1) + $this: TYPE_OP type=.IC1 origin=IMPLICIT_CAST typeOperand=.IC1 + GET_VAR 'val tmp_0: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + VAR name:x2 type:kotlin.String [val] + CALL 'public abstract fun component2 (): kotlin.String [operator] declared in .IC2' type=kotlin.String origin=COMPONENT_N(index=2) + $this: TYPE_OP type=.IC2 origin=IMPLICIT_CAST typeOperand=.IC2 + GET_VAR 'val tmp_0: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.kt.txt b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.kt.txt new file mode 100644 index 00000000000..1b37d6124cf --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.kt.txt @@ -0,0 +1,54 @@ +enum class En : Enum { + private constructor() /* primary */ { + super/*Enum*/() + /* () */ + + } + + A = En() + + B = En() + + C = En() + + fun values(): Array /* Synthetic body for ENUM_VALUES */ + + fun valueOf(value: String): En /* Synthetic body for ENUM_VALUEOF */ + +} + +fun test() { + var r: String = "" + val x: Any? = En.A + when { + x /*as En */ is En -> { // BLOCK + val tmp0_subject: En = x /*as En */ + when { + EQEQ(arg0 = tmp0_subject, arg1 = En.A) -> { // BLOCK + r = "when1" + } + EQEQ(arg0 = tmp0_subject, arg1 = En.B) -> { // BLOCK + } + EQEQ(arg0 = tmp0_subject, arg1 = En.C) -> { // BLOCK + } + else -> noWhenBranchMatchedException() + } + } + } + val y: Any = En.A + when { + y /*as En */ is En -> { // BLOCK + val tmp1_subject: En = y /*as En */ + when { + EQEQ(arg0 = tmp1_subject, arg1 = En.A) -> { // BLOCK + r = "when2" + } + EQEQ(arg0 = tmp1_subject, arg1 = En.B) -> { // BLOCK + } + EQEQ(arg0 = tmp1_subject, arg1 = En.C) -> { // BLOCK + } + else -> noWhenBranchMatchedException() + } + } + } +} diff --git a/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.txt b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.txt new file mode 100644 index 00000000000..21bab26d0bf --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.fir.txt @@ -0,0 +1,124 @@ +FILE fqName: fileName:/whenSmartCastToEnum.kt + CLASS ENUM_CLASS name:En modality:FINAL visibility:public superTypes:[kotlin.Enum<.En>] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.En + CONSTRUCTOR visibility:private <> () returnType:.En [primary] + BLOCK_BODY + ENUM_CONSTRUCTOR_CALL 'public constructor (name: kotlin.String, ordinal: kotlin.Int) [primary] declared in kotlin.Enum' + : .En + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:En modality:FINAL visibility:public superTypes:[kotlin.Enum<.En>]' + ENUM_ENTRY name:A + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [primary] declared in .En' + ENUM_ENTRY name:B + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [primary] declared in .En' + ENUM_ENTRY name:C + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [primary] declared in .En' + FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<.En> + SYNTHETIC_BODY kind=ENUM_VALUES + FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:.En + VALUE_PARAMETER name:value index:0 type:kotlin.String + SYNTHETIC_BODY kind=ENUM_VALUEOF + FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Any [fake_override] + overridden: + protected final fun clone (): kotlin.Any declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + FUN FAKE_OVERRIDE name:compareTo visibility:public modality:FINAL <> ($this:kotlin.Enum, other:.En) returnType:kotlin.Int [fake_override,operator] + overridden: + public final fun compareTo (other: E of kotlin.Enum): kotlin.Int [operator] declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + VALUE_PARAMETER name:other index:0 type:.En + FUN FAKE_OVERRIDE name:equals visibility:public modality:FINAL <> ($this:kotlin.Enum, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public final fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Int [fake_override] + overridden: + public final fun hashCode (): kotlin.Int declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Enum) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [fake_override,val] + FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.String [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [fake_override,val] + overridden: + public final fun (): kotlin.String declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [fake_override,val] + FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:kotlin.Enum) returnType:kotlin.Int [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [fake_override,val] + overridden: + public final fun (): kotlin.Int declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:r type:kotlin.String [var] + CONST String type=kotlin.String value="" + VAR name:x type:kotlin.Any? [val] + GET_ENUM 'ENUM_ENTRY name:A' type=.En + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.En + TYPE_OP type=.En origin=IMPLICIT_CAST typeOperand=.En + GET_VAR 'val x: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null + then: BLOCK type=kotlin.Unit origin=WHEN + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.En [val] + TYPE_OP type=.En origin=IMPLICIT_CAST typeOperand=.En + GET_VAR 'val x: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null + WHEN type=kotlin.Unit origin=WHEN + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:A' type=.En + then: BLOCK type=kotlin.Unit origin=null + SET_VAR 'var r: kotlin.String [var] declared in .test' type=kotlin.Unit origin=EQ + CONST String type=kotlin.String value="when1" + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:B' type=.En + then: BLOCK type=kotlin.Unit origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:C' type=.En + then: BLOCK type=kotlin.Unit origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun noWhenBranchMatchedException (): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null + VAR name:y type:kotlin.Any [val] + GET_ENUM 'ENUM_ENTRY name:A' type=.En + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.En + TYPE_OP type=.En origin=IMPLICIT_CAST typeOperand=.En + GET_VAR 'val y: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + then: BLOCK type=kotlin.Unit origin=WHEN + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:.En [val] + TYPE_OP type=.En origin=IMPLICIT_CAST typeOperand=.En + GET_VAR 'val y: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + WHEN type=kotlin.Unit origin=WHEN + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:A' type=.En + then: BLOCK type=kotlin.Unit origin=null + SET_VAR 'var r: kotlin.String [var] declared in .test' type=kotlin.Unit origin=EQ + CONST String type=kotlin.String value="when2" + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:B' type=.En + then: BLOCK type=kotlin.Unit origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:C' type=.En + then: BLOCK type=kotlin.Unit origin=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun noWhenBranchMatchedException (): kotlin.Nothing declared in kotlin.internal.ir' type=kotlin.Nothing origin=null diff --git a/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt new file mode 100644 index 00000000000..f6f7c3ad1a2 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt @@ -0,0 +1,23 @@ +enum class En { A, B, C } + +fun test() { + var r = "" + + val x: Any? = En.A + if (x is En) { + when (x) { + En.A -> { r = "when1" } + En.B -> {} + En.C -> {} + } + } + + val y: Any = En.A + if (y is En) { + when (y) { + En.A -> { r = "when2" } + En.B -> {} + En.C -> {} + } + } +} diff --git a/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt.txt b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt.txt new file mode 100644 index 00000000000..4ec7d8471ab --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt.txt @@ -0,0 +1,56 @@ +enum class En : Enum { + private constructor() /* primary */ { + super/*Enum*/() + /* () */ + + } + + A = En() + + B = En() + + C = En() + + fun values(): Array /* Synthetic body for ENUM_VALUES */ + + fun valueOf(value: String): En /* Synthetic body for ENUM_VALUEOF */ + +} + +fun test() { + var r: String = "" + val x: Any? = En.A + when { + x is En -> { // BLOCK + { // BLOCK + val tmp0_subject: En = x /*as En */ + when { + EQEQ(arg0 = tmp0_subject, arg1 = En.A) -> { // BLOCK + r = "when1" + } + EQEQ(arg0 = tmp0_subject, arg1 = En.B) -> { // BLOCK + } + EQEQ(arg0 = tmp0_subject, arg1 = En.C) -> { // BLOCK + } + } + } + } + } + val y: Any = En.A + when { + y is En -> { // BLOCK + { // BLOCK + val tmp1_subject: En = y /*as En */ + when { + EQEQ(arg0 = tmp1_subject, arg1 = En.A) -> { // BLOCK + r = "when2" + } + EQEQ(arg0 = tmp1_subject, arg1 = En.B) -> { // BLOCK + } + EQEQ(arg0 = tmp1_subject, arg1 = En.C) -> { // BLOCK + } + } + } + } + } +} diff --git a/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.txt b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.txt new file mode 100644 index 00000000000..c20180ab65b --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenSmartCastToEnum.txt @@ -0,0 +1,126 @@ +FILE fqName: fileName:/whenSmartCastToEnum.kt + CLASS ENUM_CLASS name:En modality:FINAL visibility:public superTypes:[kotlin.Enum<.En>] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.En + CONSTRUCTOR visibility:private <> () returnType:.En [primary] + BLOCK_BODY + ENUM_CONSTRUCTOR_CALL 'public constructor (name: kotlin.String, ordinal: kotlin.Int) [primary] declared in kotlin.Enum' + : .En + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ENUM_CLASS name:En modality:FINAL visibility:public superTypes:[kotlin.Enum<.En>]' + ENUM_ENTRY name:A + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [primary] declared in .En' + ENUM_ENTRY name:B + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [primary] declared in .En' + ENUM_ENTRY name:C + init: EXPRESSION_BODY + ENUM_CONSTRUCTOR_CALL 'private constructor () [primary] declared in .En' + FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum<.En>) returnType:kotlin.Any [fake_override] + overridden: + protected final fun clone (): kotlin.Any declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + FUN FAKE_OVERRIDE name:finalize visibility:protected/*protected and package*/ modality:FINAL <> ($this:kotlin.Enum<.En>) returnType:kotlin.Unit [fake_override] + overridden: + protected/*protected and package*/ final fun finalize (): kotlin.Unit declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + FUN FAKE_OVERRIDE name:getDeclaringClass visibility:public modality:FINAL <> ($this:kotlin.Enum<.En>) returnType:@[FlexibleNullability] java.lang.Class<@[FlexibleNullability] .En?>? [fake_override] + overridden: + public final fun getDeclaringClass (): @[FlexibleNullability] java.lang.Class<@[FlexibleNullability] E of kotlin.Enum?>? declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + FUN FAKE_OVERRIDE name:compareTo visibility:public modality:FINAL <> ($this:kotlin.Enum<.En>, other:.En) returnType:kotlin.Int [fake_override,operator] + overridden: + public final fun compareTo (other: E of kotlin.Enum): kotlin.Int [operator] declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + VALUE_PARAMETER name:other index:0 type:.En + FUN FAKE_OVERRIDE name:equals visibility:public modality:FINAL <> ($this:kotlin.Enum<.En>, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public final fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:FINAL <> ($this:kotlin.Enum<.En>) returnType:kotlin.Int [fake_override] + overridden: + public final fun hashCode (): kotlin.Int declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [fake_override,val] + FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:kotlin.Enum<.En>) returnType:kotlin.String [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:name visibility:public modality:FINAL [fake_override,val] + overridden: + public final fun (): kotlin.String declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [fake_override,val] + FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:kotlin.Enum<.En>) returnType:kotlin.Int [fake_override] + correspondingProperty: PROPERTY FAKE_OVERRIDE name:ordinal visibility:public modality:FINAL [fake_override,val] + overridden: + public final fun (): kotlin.Int declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Enum<.En>) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Enum + $this: VALUE_PARAMETER name: type:kotlin.Enum<.En> + FUN ENUM_CLASS_SPECIAL_MEMBER name:values visibility:public modality:FINAL <> () returnType:kotlin.Array<.En> + SYNTHETIC_BODY kind=ENUM_VALUES + FUN ENUM_CLASS_SPECIAL_MEMBER name:valueOf visibility:public modality:FINAL <> (value:kotlin.String) returnType:.En + VALUE_PARAMETER name:value index:0 type:kotlin.String + SYNTHETIC_BODY kind=ENUM_VALUEOF + FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:r type:kotlin.String [var] + CONST String type=kotlin.String value="" + VAR name:x type:kotlin.Any? [val] + GET_ENUM 'ENUM_ENTRY name:A' type=.En + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.En + GET_VAR 'val x: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null + then: BLOCK type=kotlin.Unit origin=null + BLOCK type=kotlin.Unit origin=WHEN + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:.En [val] + TYPE_OP type=.En origin=IMPLICIT_CAST typeOperand=.En + GET_VAR 'val x: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null + WHEN type=kotlin.Unit origin=WHEN + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:A' type=.En + then: BLOCK type=kotlin.Unit origin=null + SET_VAR 'var r: kotlin.String [var] declared in .test' type=kotlin.Unit origin=EQ + CONST String type=kotlin.String value="when1" + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:B' type=.En + then: BLOCK type=kotlin.Unit origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:C' type=.En + then: BLOCK type=kotlin.Unit origin=null + VAR name:y type:kotlin.Any [val] + GET_ENUM 'ENUM_ENTRY name:A' type=.En + WHEN type=kotlin.Unit origin=IF + BRANCH + if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.En + GET_VAR 'val y: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + then: BLOCK type=kotlin.Unit origin=null + BLOCK type=kotlin.Unit origin=WHEN + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:.En [val] + TYPE_OP type=.En origin=IMPLICIT_CAST typeOperand=.En + GET_VAR 'val y: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + WHEN type=kotlin.Unit origin=WHEN + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:A' type=.En + then: BLOCK type=kotlin.Unit origin=null + SET_VAR 'var r: kotlin.String [var] declared in .test' type=kotlin.Unit origin=EQ + CONST String type=kotlin.String value="when2" + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:B' type=.En + then: BLOCK type=kotlin.Unit origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: .En [val] declared in .test' type=.En origin=null + arg1: GET_ENUM 'ENUM_ENTRY name:C' type=.En + then: BLOCK type=kotlin.Unit origin=null diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java index 322d706ae67..837d3d2cbd0 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxAgainstJavaCodegenTestGenerated.java @@ -740,6 +740,11 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxAga runTest("compiler/testData/codegen/boxAgainstJava/sam/samConstructorGenericSignature.kt"); } + @TestMetadata("smartCastSamConversion.kt") + public void testSmartCastSamConversion() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/sam/smartCastSamConversion.kt"); + } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/sam/adapters") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 4759421672c..7c749d7fd15 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -13125,6 +13125,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("when.kt") public void testWhen() throws Exception { runTest("compiler/testData/codegen/box/ieee754/when.kt"); @@ -31147,6 +31152,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/smartCasts/lambdaArgumentWithoutType.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("nullSmartCast.kt") public void testNullSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 0bde74ea74d..1faddd7267d 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -13125,6 +13125,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("when.kt") public void testWhen() throws Exception { runTest("compiler/testData/codegen/box/ieee754/when.kt"); @@ -28781,6 +28786,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/smartCasts/lambdaArgumentWithoutType.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("nullSmartCast.kt") public void testNullSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java index e3174981ecf..c9eb23e2af2 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxAgainstJavaCodegenTestGenerated.java @@ -710,6 +710,11 @@ public class IrBlackBoxAgainstJavaCodegenTestGenerated extends AbstractIrBlackBo runTest("compiler/testData/codegen/boxAgainstJava/sam/samConstructorGenericSignature.kt"); } + @TestMetadata("smartCastSamConversion.kt") + public void testSmartCastSamConversion() throws Exception { + runTest("compiler/testData/codegen/boxAgainstJava/sam/smartCastSamConversion.kt"); + } + @TestMetadata("compiler/testData/codegen/boxAgainstJava/sam/adapters") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 027c3930b0f..03082fce39e 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -13125,6 +13125,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("when.kt") public void testWhen() throws Exception { runTest("compiler/testData/codegen/box/ieee754/when.kt"); @@ -30781,6 +30786,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/smartCasts/lambdaArgumentWithoutType.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("nullSmartCast.kt") public void testNullSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 493a45eaf80..e64f9d6ebf1 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1187,6 +1187,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/expressions/membersImportedFromObject.kt"); } + @TestMetadata("multipleSmartCasts.kt") + public void testMultipleSmartCasts() throws Exception { + runTest("compiler/testData/ir/irText/expressions/multipleSmartCasts.kt"); + } + @TestMetadata("multipleThisReferences.kt") public void testMultipleThisReferences() throws Exception { runTest("compiler/testData/ir/irText/expressions/multipleThisReferences.kt"); @@ -1452,6 +1457,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/expressions/whenReturnUnit.kt"); } + @TestMetadata("whenSmartCastToEnum.kt") + public void testWhenSmartCastToEnum() throws Exception { + runTest("compiler/testData/ir/irText/expressions/whenSmartCastToEnum.kt"); + } + @TestMetadata("whenUnusedExpression.kt") public void testWhenUnusedExpression() throws Exception { runTest("compiler/testData/ir/irText/expressions/whenUnusedExpression.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index c7d1f85aee0..57da1c7969c 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -11220,6 +11220,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("whenNoSubject_properIeeeComparisons.kt") public void testWhenNoSubject_properIeeeComparisons() throws Exception { runTest("compiler/testData/codegen/box/ieee754/whenNoSubject_properIeeeComparisons.kt"); @@ -24857,6 +24862,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/smartCasts/lambdaArgumentWithoutType.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("nullSmartCast.kt") public void testNullSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 01a8b2c3154..21759f0fc3e 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -11220,6 +11220,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("whenNoSubject_properIeeeComparisons.kt") public void testWhenNoSubject_properIeeeComparisons() throws Exception { runTest("compiler/testData/codegen/box/ieee754/whenNoSubject_properIeeeComparisons.kt"); @@ -24857,6 +24862,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/smartCasts/lambdaArgumentWithoutType.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("nullSmartCast.kt") public void testNullSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index e4ae8e42cd8..206472c6123 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11275,6 +11275,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("when.kt") public void testWhen() throws Exception { runTest("compiler/testData/codegen/box/ieee754/when.kt"); @@ -24857,6 +24862,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/smartCasts/lambdaArgumentWithoutType.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("nullSmartCast.kt") public void testNullSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index c0b3f5fc551..4ef011f76c0 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -5886,6 +5886,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/ieee754/smartCastToDoubleAndComparableToDouble.kt"); } + @TestMetadata("smartCastToInt.kt") + public void testSmartCastToInt() throws Exception { + runTest("compiler/testData/codegen/box/ieee754/smartCastToInt.kt"); + } + @TestMetadata("whenNoSubject_properIeeeComparisons.kt") public void testWhenNoSubject_properIeeeComparisons() throws Exception { runTest("compiler/testData/codegen/box/ieee754/whenNoSubject_properIeeeComparisons.kt"); @@ -13253,6 +13258,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/smartCasts/kt19100.kt"); } + @TestMetadata("multipleSmartCast.kt") + public void testMultipleSmartCast() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/multipleSmartCast.kt"); + } + @TestMetadata("smartCastInsideIf.kt") public void testSmartCastInsideIf() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/smartCastInsideIf.kt"); From 1e677021284f4645cb2416d86997b422e53f47cc Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 30 Dec 2020 20:58:40 +0300 Subject: [PATCH 003/197] [Test] Introduce opt in @ObsoleteTestInfrastructure for migrating tests to new infrastructure --- .../org/jetbrains/kotlin/ObsoleteTestInfrastructure.kt | 9 +++++++++ .../jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt | 3 ++- .../checkers/AbstractDiagnosticsTestWithJsStdLib.kt | 2 ++ ...ctDiagnosticsTestWithJsStdLibAndBackendCompilation.kt | 2 ++ ...stractForeignAnnotationsCompiledJavaDiagnosticTest.kt | 2 ++ .../kotlin/checkers/AbstractJspecifyAnnotationsTest.kt | 2 ++ .../org/jetbrains/kotlin/checkers/CheckerTestUtilTest.kt | 2 ++ .../kotlin/spec/checkers/AbstractDiagnosticsTestSpec.kt | 2 ++ ...unctionsWithNonStableParameterNamesDiagnosticsTest.kt | 2 ++ .../AbstractSerializationPluginDiagnosticTest.kt | 2 ++ .../test/org/jetbrains/kotlin/noarg/NoArgTests.kt | 2 ++ .../AbstractSamWithReceiverScriptNewDefTest.kt | 2 ++ .../samWithReceiver/AbstractSamWithReceiverScriptTest.kt | 2 ++ .../samWithReceiver/AbstractSamWithReceiverTest.kt | 2 ++ 14 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 compiler/tests-common/tests/org/jetbrains/kotlin/ObsoleteTestInfrastructure.kt diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ObsoleteTestInfrastructure.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ObsoleteTestInfrastructure.kt new file mode 100644 index 00000000000..79d5b42532b --- /dev/null +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ObsoleteTestInfrastructure.kt @@ -0,0 +1,9 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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 + +@RequiresOptIn +annotation class ObsoleteTestInfrastructure(val replacer: String = "") diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt index 9fd33aaf46c..40023a9c2c1 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt @@ -13,6 +13,7 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.rt.execution.junit.FileComparisonFailure import junit.framework.AssertionFailedError import junit.framework.TestCase +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.TestsCompilerError import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory @@ -80,7 +81,7 @@ import java.util.* import java.util.function.Predicate import java.util.regex.Pattern -@Deprecated("Please use new test infrastructure from :compiler:tests-common:new. Check org.jetbrains.kotlin.test.runners.AbstractDiagnosticTest") +@ObsoleteTestInfrastructure("org.jetbrains.kotlin.test.runners.AbstractDiagnosticTest") abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() { override fun analyzeAndCheck(testDataFile: File, files: List) { try { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.kt index 895ddb6c76a..6b42d307ec1 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLib.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.checkers import com.intellij.openapi.util.text.StringUtil +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.JvmTarget @@ -28,6 +29,7 @@ import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.test.KotlinTestUtils import java.util.* +@ObsoleteTestInfrastructure("org.jetbrains.kotlin.test.runners.AbstractDiagnosticsTestWithJsStdLib") abstract class AbstractDiagnosticsTestWithJsStdLib : AbstractDiagnosticsTest() { private var lazyConfig: Lazy? = lazy(LazyThreadSafetyMode.NONE) { JsConfig(project, environment.configuration.copy().apply { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLibAndBackendCompilation.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLibAndBackendCompilation.kt index ce2934cc3a4..ed55c3e6985 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLibAndBackendCompilation.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTestWithJsStdLibAndBackendCompilation.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.checkers +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.context.ModuleContext @@ -27,6 +28,7 @@ import org.jetbrains.kotlin.js.facade.MainCallParameters import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingTrace +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractDiagnosticsTestWithJsStdLibAndBackendCompilation : AbstractDiagnosticsTestWithJsStdLib() { override fun analyzeModuleContents( moduleContext: ModuleContext, diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsCompiledJavaDiagnosticTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsCompiledJavaDiagnosticTest.kt index 650a476a60a..c52fe7fdc7d 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsCompiledJavaDiagnosticTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractForeignAnnotationsCompiledJavaDiagnosticTest.kt @@ -5,11 +5,13 @@ package org.jetbrains.kotlin.checkers +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.test.MockLibraryUtilExt.compileJavaFilesLibraryToJar import java.io.File import kotlin.io.path.ExperimentalPathApi import kotlin.io.path.createTempDirectory +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractForeignAnnotationsCompiledJavaDiagnosticTest : AbstractDiagnosticsTest() { @OptIn(ExperimentalPathApi::class) override fun doMultiFileTest( diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractJspecifyAnnotationsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractJspecifyAnnotationsTest.kt index f702b80bf06..32aa5612061 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractJspecifyAnnotationsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractJspecifyAnnotationsTest.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.checkers import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS import org.jetbrains.kotlin.test.MockLibraryUtilExt @@ -21,6 +22,7 @@ const val JSPECIFY_NULLNESS_MISMATCH_MARK = "jspecify_nullness_mismatch" const val JSPECIFY_NULLABLE_ANNOTATION = "@Nullable" const val JSPECIFY_NULLNESS_UNSPECIFIED_ANNOTATION = "@NullnessUnspecified" +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractJspecifyAnnotationsTest : AbstractDiagnosticsTest() { override fun doMultiFileTest( wholeFile: File, diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CheckerTestUtilTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CheckerTestUtilTest.kt index 60132ea8691..0fa9b5ae0aa 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CheckerTestUtilTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CheckerTestUtilTest.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.checkers import com.google.common.collect.Lists import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.checkers.diagnostics.ActualDiagnostic import org.jetbrains.kotlin.checkers.diagnostics.TextDiagnostic import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil @@ -203,6 +204,7 @@ class CheckerTestUtilTest : KotlinTestWithEnvironment() { } fun testAbstractJetDiagnosticsTest() { + @OptIn(ObsoleteTestInfrastructure::class) val test = object : AbstractDiagnosticsTest() { init { setUp() diff --git a/compiler/tests-spec/tests/org/jetbrains/kotlin/spec/checkers/AbstractDiagnosticsTestSpec.kt b/compiler/tests-spec/tests/org/jetbrains/kotlin/spec/checkers/AbstractDiagnosticsTestSpec.kt index 45babdd43ee..74acca7a33f 100644 --- a/compiler/tests-spec/tests/org/jetbrains/kotlin/spec/checkers/AbstractDiagnosticsTestSpec.kt +++ b/compiler/tests-spec/tests/org/jetbrains/kotlin/spec/checkers/AbstractDiagnosticsTestSpec.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.spec.checkers import com.intellij.openapi.project.Project import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.TestExceptionsComparator import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl @@ -23,6 +24,7 @@ import org.junit.Assert import java.io.File import java.util.regex.Matcher +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractDiagnosticsTestSpec : org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest() { companion object { private val withoutDescriptorsTestGroups = listOf( diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/InteropFunctionsWithNonStableParameterNamesDiagnosticsTest.kt b/compiler/tests/org/jetbrains/kotlin/checkers/InteropFunctionsWithNonStableParameterNamesDiagnosticsTest.kt index e71724ccb7b..9deb82e730c 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/InteropFunctionsWithNonStableParameterNamesDiagnosticsTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/checkers/InteropFunctionsWithNonStableParameterNamesDiagnosticsTest.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.checkers +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer @@ -30,6 +31,7 @@ import org.jetbrains.kotlin.test.KlibTestUtil import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File +@OptIn(ObsoleteTestInfrastructure::class) class InteropFunctionsWithNonStableParameterNamesDiagnosticsTest : AbstractDiagnosticsTest() { private lateinit var klibFile: File diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/test/org/jetbrains/kotlinx/serialization/AbstractSerializationPluginDiagnosticTest.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/test/org/jetbrains/kotlinx/serialization/AbstractSerializationPluginDiagnosticTest.kt index ccc4b7ba344..f4c6607c75e 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/test/org/jetbrains/kotlinx/serialization/AbstractSerializationPluginDiagnosticTest.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/test/org/jetbrains/kotlinx/serialization/AbstractSerializationPluginDiagnosticTest.kt @@ -5,11 +5,13 @@ package org.jetbrains.kotlinx.serialization +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationComponentRegistrar +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractSerializationPluginDiagnosticTest : AbstractDiagnosticsTest() { private val runtimeLibraryPath = getSerializationLibraryRuntimeJar() diff --git a/plugins/noarg/noarg-cli/test/org/jetbrains/kotlin/noarg/NoArgTests.kt b/plugins/noarg/noarg-cli/test/org/jetbrains/kotlin/noarg/NoArgTests.kt index bf9ab0512e0..312b6934637 100644 --- a/plugins/noarg/noarg-cli/test/org/jetbrains/kotlin/noarg/NoArgTests.kt +++ b/plugins/noarg/noarg-cli/test/org/jetbrains/kotlin/noarg/NoArgTests.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.noarg +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.AbstractBlackBoxCodegenTest @@ -40,6 +41,7 @@ abstract class AbstractIrBytecodeListingTestForNoArg : AbstractBytecodeListingTe override val backend: TargetBackend get() = TargetBackend.JVM_IR } +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractDiagnosticsTestForNoArg : AbstractDiagnosticsTest() { override fun setupEnvironment(environment: KotlinCoreEnvironment) { NoArgComponentRegistrar.registerNoArgComponents(environment.project, NOARG_ANNOTATIONS, backend.isIR, false) diff --git a/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptNewDefTest.kt b/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptNewDefTest.kt index c2eea952d44..2605fe6deab 100644 --- a/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptNewDefTest.kt +++ b/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptNewDefTest.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.samWithReceiver import com.intellij.mock.MockProject +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.TestsCompilerError import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment @@ -32,6 +33,7 @@ import kotlin.script.experimental.host.toScriptSource import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.experimental.jvmhost.createJvmScriptDefinitionFromTemplate +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractSamWithReceiverScriptNewDefTest : AbstractDiagnosticsTest() { override fun setupEnvironment(environment: KotlinCoreEnvironment) { diff --git a/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptTest.kt b/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptTest.kt index 8dadbeade18..0f993805671 100644 --- a/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptTest.kt +++ b/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverScriptTest.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.samWithReceiver +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor @@ -26,6 +27,7 @@ import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration import kotlin.script.extensions.SamWithReceiverAnnotations import kotlin.script.templates.ScriptTemplateDefinition +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractSamWithReceiverScriptTest : AbstractDiagnosticsTest() { override fun setupEnvironment(environment: KotlinCoreEnvironment) { diff --git a/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverTest.kt b/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverTest.kt index 8ae4122978f..f84c0b4474e 100644 --- a/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverTest.kt +++ b/plugins/sam-with-receiver/sam-with-receiver-cli/test/org/jetbrains/kotlin/samWithReceiver/AbstractSamWithReceiverTest.kt @@ -16,10 +16,12 @@ package org.jetbrains.kotlin.samWithReceiver +import org.jetbrains.kotlin.ObsoleteTestInfrastructure import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor +@OptIn(ObsoleteTestInfrastructure::class) abstract class AbstractSamWithReceiverTest : AbstractDiagnosticsTest() { private companion object { private val TEST_ANNOTATIONS = listOf("SamWithReceiver") From 9fd250b2b1116576c1b927394efc7b7862e83e0c Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 6 Jan 2021 17:34:00 +0100 Subject: [PATCH 004/197] Exclude libraries/stdlib/wasm/build in CodeConformanceTest Similarly to libraries/stdlib/js-ir/build, there are some copyrights produced during the build, which should not be checked in this test. --- compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt index 6ae128d070c..1b1d73c9744 100644 --- a/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/code/CodeConformanceTest.kt @@ -90,6 +90,7 @@ class CodeConformanceTest : TestCase() { "libraries/stdlib/js-v1/.gradle", "libraries/stdlib/js-v1/build", "libraries/stdlib/js-v1/node_modules", + "libraries/stdlib/wasm/build", "libraries/tools/kotlin-gradle-plugin-integration-tests/build", "libraries/tools/kotlin-maven-plugin-test/target", "libraries/tools/kotlin-test-js-runner/.gradle", From b8d7b39e2c14fb7b60447a6062c63995bc6722d9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 6 Jan 2021 21:47:14 +0100 Subject: [PATCH 005/197] Extract Java 9 module test about irrelevant jars in JDK home Skip it on JDKs where ant-javafx.jar is not present. --- .../main/module-info.java | 3 + .../main/test.kt | 4 ++ .../main/test.kt | 4 ++ .../javaModules/jdkModulesFromNamed/main.txt | 16 ------ .../jdkModulesFromNamed/main/test.kt | 4 -- .../jdkModulesFromUnnamed/main.txt | 18 +----- .../jdkModulesFromUnnamed/main/test.kt | 4 -- .../compiler/Java9ModulesIntegrationTest.kt | 57 ++++++++++++------- 8 files changed, 49 insertions(+), 61 deletions(-) create mode 100644 compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/module-info.java create mode 100644 compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/test.kt create mode 100644 compiler/testData/javaModules/doNotLoadIrrelevantJarsFromUnnamed/main/test.kt diff --git a/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/module-info.java b/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/module-info.java new file mode 100644 index 00000000000..e7e86dd9f44 --- /dev/null +++ b/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/module-info.java @@ -0,0 +1,3 @@ +module main { + requires kotlin.stdlib; +} diff --git a/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/test.kt b/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/test.kt new file mode 100644 index 00000000000..ca6836f760c --- /dev/null +++ b/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromNamed/main/test.kt @@ -0,0 +1,4 @@ +fun main() { + val x: com.sun.javafx.tools.ant.AntLog? = null + println(x) +} diff --git a/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromUnnamed/main/test.kt b/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromUnnamed/main/test.kt new file mode 100644 index 00000000000..ca6836f760c --- /dev/null +++ b/compiler/testData/javaModules/doNotLoadIrrelevantJarsFromUnnamed/main/test.kt @@ -0,0 +1,4 @@ +fun main() { + val x: com.sun.javafx.tools.ant.AntLog? = null + println(x) +} diff --git a/compiler/testData/javaModules/jdkModulesFromNamed/main.txt b/compiler/testData/javaModules/jdkModulesFromNamed/main.txt index 23263452275..1f03e3bed1e 100644 --- a/compiler/testData/javaModules/jdkModulesFromNamed/main.txt +++ b/compiler/testData/javaModules/jdkModulesFromNamed/main.txt @@ -14,20 +14,4 @@ public inline fun println(message: Long): Unit defined in kotlin.io public inline fun println(message: Short): Unit defined in kotlin.io println(s) ^ -compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt:19:20: error: unresolved reference: javafx - val x: com.sun.javafx.tools.ant.AntLog? = null - ^ -compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt:20:5: error: overload resolution ambiguity: -public inline fun println(message: Any?): Unit defined in kotlin.io -public inline fun println(message: Boolean): Unit defined in kotlin.io -public inline fun println(message: Byte): Unit defined in kotlin.io -public inline fun println(message: Char): Unit defined in kotlin.io -public inline fun println(message: CharArray): Unit defined in kotlin.io -public inline fun println(message: Double): Unit defined in kotlin.io -public inline fun println(message: Float): Unit defined in kotlin.io -public inline fun println(message: Int): Unit defined in kotlin.io -public inline fun println(message: Long): Unit defined in kotlin.io -public inline fun println(message: Short): Unit defined in kotlin.io - println(x) - ^ COMPILATION_ERROR diff --git a/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt b/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt index 917eeda39e5..38a46ba0042 100644 --- a/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt +++ b/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt @@ -14,8 +14,4 @@ fun main(args: Array) { // Module oracle.desktop val a: com.oracle.awt.AWTUtils? = null println(a) - - // No module, this class is declared in $JDK_9/lib/ant-javafx.jar - val x: com.sun.javafx.tools.ant.AntLog? = null - println(x) } diff --git a/compiler/testData/javaModules/jdkModulesFromUnnamed/main.txt b/compiler/testData/javaModules/jdkModulesFromUnnamed/main.txt index f93be16ff13..d86bac9de59 100644 --- a/compiler/testData/javaModules/jdkModulesFromUnnamed/main.txt +++ b/compiler/testData/javaModules/jdkModulesFromUnnamed/main.txt @@ -1,17 +1 @@ -compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt:19:33: error: unresolved reference: ant - val x: com.sun.javafx.tools.ant.AntLog? = null - ^ -compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt:20:5: error: overload resolution ambiguity: -public inline fun println(message: Any?): Unit defined in kotlin.io -public inline fun println(message: Boolean): Unit defined in kotlin.io -public inline fun println(message: Byte): Unit defined in kotlin.io -public inline fun println(message: Char): Unit defined in kotlin.io -public inline fun println(message: CharArray): Unit defined in kotlin.io -public inline fun println(message: Double): Unit defined in kotlin.io -public inline fun println(message: Float): Unit defined in kotlin.io -public inline fun println(message: Int): Unit defined in kotlin.io -public inline fun println(message: Long): Unit defined in kotlin.io -public inline fun println(message: Short): Unit defined in kotlin.io - println(x) - ^ -COMPILATION_ERROR +OK diff --git a/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt b/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt index 31eefeed37f..b9626822910 100644 --- a/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt +++ b/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt @@ -14,8 +14,4 @@ fun main(args: Array) { // Module oracle.desktop val a: com.oracle.awt.AWTUtils? = null println(a) - - // No module, this class is declared in $JDK_9/lib/ant-javafx.jar - val x: com.sun.javafx.tools.ant.AntLog? = null - println(x) } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt index f39a36da96b..8d58b8ff89d 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/Java9ModulesIntegrationTest.kt @@ -19,11 +19,12 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { get() = "compiler/testData/javaModules/" private fun module( - name: String, - modulePath: List = emptyList(), - addModules: List = emptyList(), - additionalKotlinArguments: List = emptyList(), - manifest: Manifest? = null + name: String, + modulePath: List = emptyList(), + addModules: List = emptyList(), + additionalKotlinArguments: List = emptyList(), + manifest: Manifest? = null, + checkKotlinOutput: (String) -> Unit = this.checkKotlinOutput(name), ): File { val paths = (modulePath + ForTestCompileRuntime.runtimeJarForTests()).joinToString(separator = File.pathSeparator) { it.path } @@ -38,21 +39,21 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { kotlinOptions += additionalKotlinArguments return compileLibrary( - name, - additionalOptions = kotlinOptions, - compileJava = { _, javaFiles, outputDir -> - val javaOptions = mutableListOf( - "-d", outputDir.path, - "--module-path", paths - ) - if (addModules.isNotEmpty()) { - javaOptions += "--add-modules" - javaOptions += addModules.joinToString() - } - KotlinTestUtils.compileJavaFilesExternallyWithJava9(javaFiles, javaOptions) - }, - checkKotlinOutput = checkKotlinOutput(name), - manifest = manifest + name, + additionalOptions = kotlinOptions, + compileJava = { _, javaFiles, outputDir -> + val javaOptions = mutableListOf( + "-d", outputDir.path, + "--module-path", paths + ) + if (addModules.isNotEmpty()) { + javaOptions += "--add-modules" + javaOptions += addModules.joinToString() + } + KotlinTestUtils.compileJavaFilesExternallyWithJava9(javaFiles, javaOptions) + }, + checkKotlinOutput = checkKotlinOutput, + manifest = manifest ) } @@ -274,4 +275,20 @@ class Java9ModulesIntegrationTest : AbstractKotlinCompilerIntegrationTest() { assertEquals("", stderr) assertEquals("OK", stdout) } + + fun testDoNotLoadIrrelevantJarsFromUnnamed() { + // This test checks that we don't load irrelevant .jar files from the JDK distribution when resolving JDK dependencies. + // Here we're testing that references to symbols from lib/ant-javafx are unresolved, if that file is present. + // The test succeeds though even if the file is absent, because it's not guaranteed to be present in JDK. + module("main", checkKotlinOutput = { + assertTrue(it, it.trimEnd().endsWith("COMPILATION_ERROR")) + }) + } + + fun testDoNotLoadIrrelevantJarsFromNamed() { + // See the comment in testDoNotLoadIrrelevantJarsFromUnnamed. + module("main", checkKotlinOutput = { + assertTrue(it, it.trimEnd().endsWith("COMPILATION_ERROR")) + }) + } } From b8fb1ce83cfdfbd4459b16470262f1da49e2b76b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 6 Jan 2021 21:49:32 +0100 Subject: [PATCH 006/197] Fix Java 9 module tests for many JDKs Module 'oracle.desktop' is not guaranteed to be present in JDK. Also, its usage in these tests doesn't check anything new that isn't already checked by usages of jdk.net and jdk.httpserver. --- .../javaModules/jdkModulesFromNamed/main/module-info.java | 1 - .../testData/javaModules/jdkModulesFromNamed/main/test.kt | 6 +----- .../testData/javaModules/jdkModulesFromUnnamed/main/test.kt | 6 +----- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java b/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java index 87a88c8de60..34214936efd 100644 --- a/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java +++ b/compiler/testData/javaModules/jdkModulesFromNamed/main/module-info.java @@ -1,7 +1,6 @@ module main { requires java.naming; requires jdk.net; - requires oracle.desktop; requires kotlin.stdlib; } diff --git a/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt b/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt index 38a46ba0042..9015e5b65c7 100644 --- a/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt +++ b/compiler/testData/javaModules/jdkModulesFromNamed/main/test.kt @@ -1,4 +1,4 @@ -fun main(args: Array) { +fun main() { // Module java.naming val b: javax.naming.Binding? = null println(b) @@ -10,8 +10,4 @@ fun main(args: Array) { // Module jdk.httpserver (this module doesn't depend on it) val s: com.sun.net.httpserver.HttpServer? = null println(s) - - // Module oracle.desktop - val a: com.oracle.awt.AWTUtils? = null - println(a) } diff --git a/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt b/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt index b9626822910..63075be02a4 100644 --- a/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt +++ b/compiler/testData/javaModules/jdkModulesFromUnnamed/main/test.kt @@ -1,4 +1,4 @@ -fun main(args: Array) { +fun main() { // Module java.naming val b: javax.naming.Binding? = null println(b) @@ -10,8 +10,4 @@ fun main(args: Array) { // Module jdk.httpserver val s: com.sun.net.httpserver.HttpServer? = null println(s) - - // Module oracle.desktop - val a: com.oracle.awt.AWTUtils? = null - println(a) } From 22d0e5eb65953ea573afabf65f052e177f5cb630 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 30 Dec 2020 21:33:48 +0100 Subject: [PATCH 007/197] Rename -Xno-use-ir -> -Xuse-old-backend, add Gradle option As soon as JVM IR is enabled by default (in language version 1.5), use the CLI argument `-Xuse-old-backend` or Gradle option `useOldBackend` to switch to the old JVM backend. --- .../common/arguments/K2JVMCompilerArguments.kt | 7 ++++--- .../jetbrains/kotlin/cli/jvm/jvmArguments.kt | 10 ++++------ compiler/testData/cli/jvm/extraHelp.out | 2 +- .../idea/highlighter/KotlinPsiChecker.kt | 18 ++++++++++++------ .../coroutines-experimental/build.gradle.kts | 9 ++++++--- .../kotlin/gradle/dsl/KotlinCommonOptions.kt | 2 +- .../kotlin/gradle/dsl/KotlinJvmOptions.kt | 6 ++++++ .../kotlin/gradle/dsl/KotlinJvmOptionsBase.kt | 9 +++++++++ 8 files changed, 43 insertions(+), 20 deletions(-) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 0c4252ef04c..b31275c493d 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -85,8 +85,9 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { @Argument(value = "-Xuse-ir", description = "Use the IR backend") var useIR: Boolean by FreezableVar(false) - @Argument(value = "-Xno-use-ir", description = "Do not use the IR backend. Useful for a custom-built compiler where IR backend is enabled by default") - var noUseIR: Boolean by FreezableVar(false) + @GradleOption(DefaultValues.BooleanFalseDefault::class) + @Argument(value = "-Xuse-old-backend", description = "Use the old JVM backend") + var useOldBackend: Boolean by FreezableVar(false) @Argument( value = "-Xallow-unstable-dependencies", @@ -462,7 +463,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { } override fun checkIrSupport(languageVersionSettings: LanguageVersionSettings, collector: MessageCollector) { - if (!useIR) return + if (!useIR || useOldBackend) return if (languageVersionSettings.languageVersion < LanguageVersion.KOTLIN_1_3 || languageVersionSettings.apiVersion < ApiVersion.KOTLIN_1_3 diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index cbb8f6d9f58..97a7aee5242 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -165,7 +165,7 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr put(JVMConfigurationKeys.PARAMETERS_METADATA, arguments.javaParameters) - val useIR = (arguments.useIR && !arguments.noUseIR) || arguments.useFir + val useIR = (arguments.useIR && !arguments.useOldBackend) || arguments.useFir put(JVMConfigurationKeys.IR, useIR) val abiStability = JvmAbiStability.fromStringOrNull(arguments.abiStability) @@ -242,11 +242,9 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr } fun CompilerConfiguration.configureKlibPaths(arguments: K2JVMCompilerArguments) { - assert(arguments.useIR || arguments.klibLibraries == null) { "Klib libraries can only be used with IR backend" } - arguments.klibLibraries?.split(File.pathSeparator.toRegex()) - ?.toTypedArray() - ?.filterNot { it.isEmpty() } - ?.let { put(JVMConfigurationKeys.KLIB_PATHS, it) } + val libraries = arguments.klibLibraries ?: return + assert(arguments.useIR && !arguments.useOldBackend) { "Klib libraries can only be used with IR backend" } + put(JVMConfigurationKeys.KLIB_PATHS, libraries.split(File.pathSeparator.toRegex()).filterNot(String::isEmpty)) } private val CompilerConfiguration.messageCollector: MessageCollector diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 836cb96f001..e126aba4d5e 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -86,7 +86,6 @@ where advanced options include: -Xno-receiver-assertions Don't generate not-null assertion for extension receiver arguments of platform types -Xno-reset-jar-timestamps Do not reset jar entry timestamps to a fixed date -Xno-unified-null-checks Use pre-1.4 exception types in null checks instead of java.lang.NPE. See KT-22275 for more details - -Xno-use-ir Do not use the IR backend. Useful for a custom-built compiler where IR backend is enabled by default -Xprofile= Debug option: Run compiler with async profiler, save snapshots to outputDir, command is passed to async-profiler on start You'll have to provide async-profiler.jar on classpath to use this @@ -116,6 +115,7 @@ where advanced options include: Suppress the "cannot access built-in declaration" error (useful with -no-stdlib) -Xuse-ir Use the IR backend -Xuse-javac Use javac for Java source and class files analysis + -Xuse-old-backend Use the old JVM backend -Xuse-old-class-files-reading Use old class files reading implementation. This may slow down the build and cause problems with Groovy interop. Should be used in case of problems with the new implementation -Xuse-14-inline-classes-mangling-scheme diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinPsiChecker.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinPsiChecker.kt index 35506e98243..18b0bd371fd 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinPsiChecker.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinPsiChecker.kt @@ -17,6 +17,7 @@ import com.intellij.psi.MultiRangeReference import com.intellij.psi.PsiElement import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.config.KotlinFacetSettings import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic @@ -273,14 +274,19 @@ private class ElementAnnotator( } private fun isUnstableAbiClassDiagnosticForModulesWithEnabledUnstableAbi(diagnostic: Diagnostic): Boolean { - val setting = when (diagnostic.factory) { - Errors.IR_WITH_UNSTABLE_ABI_COMPILED_CLASS -> K2JVMCompilerArguments::useIR - Errors.FIR_COMPILED_CLASS -> K2JVMCompilerArguments::useFir - else -> return false - } + val factory = diagnostic.factory + if (factory != Errors.IR_WITH_UNSTABLE_ABI_COMPILED_CLASS && factory != Errors.FIR_COMPILED_CLASS) return false + val module = element.module ?: return false val moduleFacetSettings = KotlinFacetSettingsProvider.getInstance(element.project)?.getSettings(module) ?: return false - return moduleFacetSettings.isCompilerSettingPresent(setting) + return when (factory) { + Errors.IR_WITH_UNSTABLE_ABI_COMPILED_CLASS -> + moduleFacetSettings.isCompilerSettingPresent(K2JVMCompilerArguments::useIR) && + !moduleFacetSettings.isCompilerSettingPresent(K2JVMCompilerArguments::useOldBackend) + Errors.FIR_COMPILED_CLASS -> + moduleFacetSettings.isCompilerSettingPresent(K2JVMCompilerArguments::useFir) + else -> error(factory) + } } companion object { diff --git a/libraries/stdlib/coroutines-experimental/build.gradle.kts b/libraries/stdlib/coroutines-experimental/build.gradle.kts index 98c75f39c5c..58cbeb5a486 100644 --- a/libraries/stdlib/coroutines-experimental/build.gradle.kts +++ b/libraries/stdlib/coroutines-experimental/build.gradle.kts @@ -51,7 +51,8 @@ tasks { "-Xopt-in=kotlin.contracts.ExperimentalContracts", "-Xcoroutines=enable", "-XXLanguage:-ReleaseCoroutines", - "-Xno-use-ir" + "-Xno-use-ir", + "-Xuse-old-backend" ) moduleName = "kotlin-coroutines-experimental-compat" } @@ -62,7 +63,8 @@ tasks { apiVersion = "1.2" freeCompilerArgs = listOf( "-Xcoroutines=enable", - "-Xno-use-ir" + "-Xno-use-ir", + "-Xuse-old-backend" ) } } @@ -71,7 +73,8 @@ tasks { languageVersion = "1.3" apiVersion = "1.3" freeCompilerArgs = listOf( - "-Xno-use-ir" + "-Xno-use-ir", + "-Xuse-old-backend" ) } } diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinCommonOptions.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinCommonOptions.kt index ba5d1c01b53..3ebb848ec74 100644 --- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinCommonOptions.kt +++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinCommonOptions.kt @@ -17,4 +17,4 @@ interface KotlinCommonOptions : org.jetbrains.kotlin.gradle.dsl.KotlinCommonToo * Default value: null */ var languageVersion: kotlin.String? -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt index c19b1025183..2cb72665d13 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptions.kt @@ -58,4 +58,10 @@ interface KotlinJvmOptions : org.jetbrains.kotlin.gradle.dsl.KotlinCommonOption * Default value: false */ var useIR: kotlin.Boolean + + /** + * Use the old JVM backend + * Default value: false + */ + var useOldBackend: kotlin.Boolean } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptionsBase.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptionsBase.kt index 54c336764d2..db21b3735dc 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptionsBase.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/dsl/KotlinJvmOptionsBase.kt @@ -102,6 +102,13 @@ internal abstract class KotlinJvmOptionsBase : org.jetbrains.kotlin.gradle.dsl.K useIRField = value } + private var useOldBackendField: kotlin.Boolean? = null + override var useOldBackend: kotlin.Boolean + get() = useOldBackendField ?: false + set(value) { + useOldBackendField = value + } + internal open fun updateArguments(args: org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments) { allWarningsAsErrorsField?.let { args.allWarningsAsErrors = it } suppressWarningsField?.let { args.suppressWarnings = it } @@ -117,6 +124,7 @@ internal abstract class KotlinJvmOptionsBase : org.jetbrains.kotlin.gradle.dsl.K noReflectField?.let { args.noReflect = it } noStdlibField?.let { args.noStdlib = it } useIRField?.let { args.useIR = it } + useOldBackendField?.let { args.useOldBackend = it } } } @@ -135,4 +143,5 @@ internal fun org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments.fi noReflect = true noStdlib = true useIR = false + useOldBackend = false } From cb3191769d1351fb1ada745aae522597afbf3932 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 30 Dec 2020 21:57:45 +0100 Subject: [PATCH 008/197] Enable JVM IR by default if language version is >= 1.5 #KT-44021 Fixed --- .../org/jetbrains/kotlin/cli/jvm/jvmArguments.kt | 7 ++++++- compiler/testData/cli/jvm/jvmIrByDefault.kt | 13 +++++++++++++ compiler/testData/cli/jvm/jvmIrByDefault1_4.args | 5 +++++ compiler/testData/cli/jvm/jvmIrByDefault1_4.out | 1 + compiler/testData/cli/jvm/jvmIrByDefault1_4.test | 1 + compiler/testData/cli/jvm/jvmIrByDefault1_5.args | 5 +++++ compiler/testData/cli/jvm/jvmIrByDefault1_5.out | 2 ++ compiler/testData/cli/jvm/jvmIrByDefault1_5.test | 1 + .../org/jetbrains/kotlin/cli/CliTestGenerated.java | 10 ++++++++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + 10 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/cli/jvm/jvmIrByDefault.kt create mode 100644 compiler/testData/cli/jvm/jvmIrByDefault1_4.args create mode 100644 compiler/testData/cli/jvm/jvmIrByDefault1_4.out create mode 100644 compiler/testData/cli/jvm/jvmIrByDefault1_4.test create mode 100644 compiler/testData/cli/jvm/jvmIrByDefault1_5.args create mode 100644 compiler/testData/cli/jvm/jvmIrByDefault1_5.out create mode 100644 compiler/testData/cli/jvm/jvmIrByDefault1_5.test diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index 97a7aee5242..60267840fd7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -165,7 +165,12 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr put(JVMConfigurationKeys.PARAMETERS_METADATA, arguments.javaParameters) - val useIR = (arguments.useIR && !arguments.useOldBackend) || arguments.useFir + val useIR = arguments.useFir || + if (languageVersionSettings.supportsFeature(LanguageFeature.JvmIrEnabledByDefault)) { + !arguments.useOldBackend + } else { + arguments.useIR && !arguments.useOldBackend + } put(JVMConfigurationKeys.IR, useIR) val abiStability = JvmAbiStability.fromStringOrNull(arguments.abiStability) diff --git a/compiler/testData/cli/jvm/jvmIrByDefault.kt b/compiler/testData/cli/jvm/jvmIrByDefault.kt new file mode 100644 index 00000000000..16576cea591 --- /dev/null +++ b/compiler/testData/cli/jvm/jvmIrByDefault.kt @@ -0,0 +1,13 @@ +// This test checks that with -language-version 1.4 we're using the old JVM backend, +// and with -language-version 1.5 -- the new JVM IR backend. +// JVM IR doesn't produce classes for local functions, so the test checks which backend +// is used by asserting that the file for the anonymous class does or doesn't exist. + +// Feel free to remove both _1_4 and _1_5 tests as soon as either the old JVM backend +// or LV 1.4 is removed, whichever happens earlier. + +class C { + fun test() { + fun local() {} + } +} diff --git a/compiler/testData/cli/jvm/jvmIrByDefault1_4.args b/compiler/testData/cli/jvm/jvmIrByDefault1_4.args new file mode 100644 index 00000000000..e82803d8640 --- /dev/null +++ b/compiler/testData/cli/jvm/jvmIrByDefault1_4.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/jvmIrByDefault.kt +-d +$TEMP_DIR$ +-language-version +1.4 diff --git a/compiler/testData/cli/jvm/jvmIrByDefault1_4.out b/compiler/testData/cli/jvm/jvmIrByDefault1_4.out new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/cli/jvm/jvmIrByDefault1_4.out @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/cli/jvm/jvmIrByDefault1_4.test b/compiler/testData/cli/jvm/jvmIrByDefault1_4.test new file mode 100644 index 00000000000..6992627b278 --- /dev/null +++ b/compiler/testData/cli/jvm/jvmIrByDefault1_4.test @@ -0,0 +1 @@ +// EXISTS: C$test$1.class diff --git a/compiler/testData/cli/jvm/jvmIrByDefault1_5.args b/compiler/testData/cli/jvm/jvmIrByDefault1_5.args new file mode 100644 index 00000000000..21fdb80fe66 --- /dev/null +++ b/compiler/testData/cli/jvm/jvmIrByDefault1_5.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/jvmIrByDefault.kt +-d +$TEMP_DIR$ +-language-version +1.5 diff --git a/compiler/testData/cli/jvm/jvmIrByDefault1_5.out b/compiler/testData/cli/jvm/jvmIrByDefault1_5.out new file mode 100644 index 00000000000..5be61f3d3c9 --- /dev/null +++ b/compiler/testData/cli/jvm/jvmIrByDefault1_5.out @@ -0,0 +1,2 @@ +warning: language version 1.5 is experimental, there are no backwards compatibility guarantees for new language and library features +OK diff --git a/compiler/testData/cli/jvm/jvmIrByDefault1_5.test b/compiler/testData/cli/jvm/jvmIrByDefault1_5.test new file mode 100644 index 00000000000..c7ca4da7275 --- /dev/null +++ b/compiler/testData/cli/jvm/jvmIrByDefault1_5.test @@ -0,0 +1 @@ +// ABSENT: C$test$1.class diff --git a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java index 7ae942f9f08..4966fb383e0 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -541,6 +541,16 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/jvmDefaultAll.args"); } + @TestMetadata("jvmIrByDefault1_4.args") + public void testJvmIrByDefault1_4() throws Exception { + runTest("compiler/testData/cli/jvm/jvmIrByDefault1_4.args"); + } + + @TestMetadata("jvmIrByDefault1_5.args") + public void testJvmIrByDefault1_5() throws Exception { + runTest("compiler/testData/cli/jvm/jvmIrByDefault1_5.args"); + } + @TestMetadata("jvmRecordOk.args") public void testJvmRecordOk() throws Exception { runTest("compiler/testData/cli/jvm/jvmRecordOk.args"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index f18abdfe537..0a6ec5932cc 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -144,6 +144,7 @@ enum class LanguageFeature( AllowSealedInheritorsInDifferentFilesOfSamePackage(KOTLIN_1_5), SealedInterfaces(KOTLIN_1_5), + JvmIrEnabledByDefault(KOTLIN_1_5), /* * Improvements include the following: From 12078666c27c0dd6fb721e8b67f4e3c246029a0a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 7 Jan 2021 22:58:04 +0100 Subject: [PATCH 009/197] Add warning if both -Xuse-ir and -Xuse-old-backend are passed --- .../src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt | 10 ++++++++++ compiler/testData/cli/jvm/bothJvmIrAndOldBackend.args | 5 +++++ compiler/testData/cli/jvm/bothJvmIrAndOldBackend.out | 2 ++ .../integration/ant/jvm/verbose/build.log.expected | 1 + .../org/jetbrains/kotlin/cli/CliTestGenerated.java | 5 +++++ 5 files changed, 23 insertions(+) create mode 100644 compiler/testData/cli/jvm/bothJvmIrAndOldBackend.args create mode 100644 compiler/testData/cli/jvm/bothJvmIrAndOldBackend.out diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index 60267840fd7..c904fce6bf4 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -171,6 +171,16 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr } else { arguments.useIR && !arguments.useOldBackend } + + if (arguments.useIR && arguments.useOldBackend) { + messageCollector.report( + STRONG_WARNING, + "Both -Xuse-ir and -Xuse-old-backend are passed. This is an inconsistent configuration. " + + "The compiler will use the ${if (useIR) "JVM IR" else "old JVM"} backend" + ) + } + messageCollector.report(LOGGING, "Using ${if (useIR) "JVM IR" else "old JVM"} backend") + put(JVMConfigurationKeys.IR, useIR) val abiStability = JvmAbiStability.fromStringOrNull(arguments.abiStability) diff --git a/compiler/testData/cli/jvm/bothJvmIrAndOldBackend.args b/compiler/testData/cli/jvm/bothJvmIrAndOldBackend.args new file mode 100644 index 00000000000..aaa2e4e226f --- /dev/null +++ b/compiler/testData/cli/jvm/bothJvmIrAndOldBackend.args @@ -0,0 +1,5 @@ +$TESTDATA_DIR$/simple.kt +-d +$TEMP_DIR$ +-Xuse-ir +-Xuse-old-backend diff --git a/compiler/testData/cli/jvm/bothJvmIrAndOldBackend.out b/compiler/testData/cli/jvm/bothJvmIrAndOldBackend.out new file mode 100644 index 00000000000..c0cc8259fe5 --- /dev/null +++ b/compiler/testData/cli/jvm/bothJvmIrAndOldBackend.out @@ -0,0 +1,2 @@ +warning: both -Xuse-ir and -Xuse-old-backend are passed. This is an inconsistent configuration. The compiler will use the old JVM backend +OK diff --git a/compiler/testData/integration/ant/jvm/verbose/build.log.expected b/compiler/testData/integration/ant/jvm/verbose/build.log.expected index 9591d3091af..663032953a2 100644 --- a/compiler/testData/integration/ant/jvm/verbose/build.log.expected +++ b/compiler/testData/integration/ant/jvm/verbose/build.log.expected @@ -4,6 +4,7 @@ Buildfile: [TestData]/build.xml build: [kotlinc] Compiling [[TestData]/hello.kt] => [[Temp]/hello.jar] [kotlinc] logging: using Kotlin home directory [KotlinProjectHome]/dist/kotlinc + [kotlinc] logging: using old JVM backend [kotlinc] logging: configuring the compilation environment [kotlinc] logging: configure scripting: Added template org.jetbrains.kotlin.mainKts.MainKtsScript from [[CompilerLib]/kotlin-main-kts.jar, [CompilerLib]/kotlin-reflect.jar, [CompilerLib]/kotlin-script-runtime.jar, [CompilerLib]/kotlin-stdlib.jar] diff --git a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java index 4966fb383e0..0890254a7d2 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -101,6 +101,11 @@ public class CliTestGenerated extends AbstractCliTest { runTest("compiler/testData/cli/jvm/argumentPassedMultipleTimes.args"); } + @TestMetadata("bothJvmIrAndOldBackend.args") + public void testBothJvmIrAndOldBackend() throws Exception { + runTest("compiler/testData/cli/jvm/bothJvmIrAndOldBackend.args"); + } + @TestMetadata("classAndFileClassClash.args") public void testClassAndFileClassClash() throws Exception { runTest("compiler/testData/cli/jvm/classAndFileClassClash.args"); From 4d3ec301c0add47d42ba97569e46568025ef296a Mon Sep 17 00:00:00 2001 From: Mikhail Galanin Date: Sat, 9 Jan 2021 15:23:25 +0000 Subject: [PATCH 010/197] Misprint: "val or val" instead of "val or var" --- .../frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 410934cb361..ee724725e62 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -395,7 +395,7 @@ class TypeResolver( } param.valOrVarKeyword?.let { - c.trace.report(Errors.UNSUPPORTED.on(it, "val or val on parameter in function type")) + c.trace.report(Errors.UNSUPPORTED.on(it, "val or var on parameter in function type")) } } }) From 093f62caac71f59a4563ad34dff2a26042ecf3bb Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Fri, 8 Jan 2021 12:56:09 -0800 Subject: [PATCH 011/197] FIR2IR: check non-parameter Unit type for adapted callable references --- .../kotlin/fir/backend/generators/AdapterGenerator.kt | 8 ++++---- .../box/coroutines/suspendFunctionMethodReference.kt | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt index 4633c6c2675..df955f46770 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AdapterGenerator.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.declarations.* @@ -51,8 +50,6 @@ internal class AdapterGenerator( private val conversionScope: Fir2IrConversionScope ) : Fir2IrComponents by components { - private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() } - private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() } internal fun needToGenerateAdaptedCallableReference( @@ -85,7 +82,10 @@ internal class AdapterGenerator( */ private fun needCoercionToUnit(type: IrSimpleType, function: IrFunction): Boolean { val expectedReturnType = type.arguments.last().typeOrNull - return expectedReturnType?.isUnit() == true && !function.returnType.isUnit() + val actualReturnType = function.returnType + return expectedReturnType?.isUnit() == true && + // In case of an external function whose return type is a type parameter, e.g., operator fun invoke(T): R + !actualReturnType.isUnit() && !actualReturnType.isTypeParameter() } /** diff --git a/compiler/testData/codegen/box/coroutines/suspendFunctionMethodReference.kt b/compiler/testData/codegen/box/coroutines/suspendFunctionMethodReference.kt index a75eb869d8d..916a4cb3d54 100644 --- a/compiler/testData/codegen/box/coroutines/suspendFunctionMethodReference.kt +++ b/compiler/testData/codegen/box/coroutines/suspendFunctionMethodReference.kt @@ -1,6 +1,5 @@ // WITH_RUNTIME // WITH_COROUTINES -// IGNORE_BACKEND_FIR: JVM_IR import kotlin.coroutines.* import helpers.* From b02a9846d043d79ffd81217f9b52ee32e7a9f988 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 11 Jan 2021 13:43:01 +0300 Subject: [PATCH 012/197] IR KT-44233 support flexible nullability in IrTypeSystemContext ^KT-44233 Fixed Target versions 1.5-M1 --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 +++ .../kotlin/ir/types/IrTypeSystemContext.kt | 25 +++++++++--- .../org/jetbrains/kotlin/ir/types/irTypes.kt | 23 +++++------ .../ir/types/jvmSpecificFlexibleTypes.kt | 39 +++++++++++++++++++ .../codegen/box/collections/kt44233.kt | 18 +++++++++ .../collectionStubs/kt44233.kt | 14 +++++++ .../collectionStubs/kt44233.txt | 15 +++++++ .../collectionStubs/kt44233_ir.txt | 15 +++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++ .../codegen/BytecodeListingTestGenerated.java | 5 +++ .../LightAnalysisModeTestGenerated.java | 5 +++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++ .../ir/IrBytecodeListingTestGenerated.java | 5 +++ 13 files changed, 163 insertions(+), 16 deletions(-) create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/jvmSpecificFlexibleTypes.kt create mode 100644 compiler/testData/codegen/box/collections/kt44233.kt create mode 100644 compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt create mode 100644 compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.txt create mode 100644 compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233_ir.txt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 779843e3493..6849164f38c 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -5068,6 +5068,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/collections/kt41123.kt"); } + @TestMetadata("kt44233.kt") + public void testKt44233() throws Exception { + runTest("compiler/testData/codegen/box/collections/kt44233.kt"); + } + @TestMetadata("mutableList.kt") public void testMutableList() throws Exception { runTest("compiler/testData/codegen/box/collections/mutableList.kt"); diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index e9dd29d08ac..e6a34e2a4ed 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -33,7 +33,16 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun KotlinTypeMarker.asSimpleType() = this as? SimpleTypeMarker - override fun KotlinTypeMarker.asFlexibleType() = this as? IrDynamicType + override fun KotlinTypeMarker.asFlexibleType(): FlexibleTypeMarker? { + if (this is FlexibleTypeMarker) return this + + if (this is IrType) { + val jvmFlexibleType = this.asJvmFlexibleType() + if (jvmFlexibleType != null) return jvmFlexibleType + } + + return null + } override fun KotlinTypeMarker.isError() = this is IrErrorType @@ -44,13 +53,19 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun FlexibleTypeMarker.asRawType(): RawTypeMarker? = null override fun FlexibleTypeMarker.upperBound(): SimpleTypeMarker { - require(this is IrDynamicType) - return irBuiltIns.anyNType as IrSimpleType + return when (this) { + is IrDynamicType -> irBuiltIns.anyNType as IrSimpleType + is IrJvmFlexibleType -> this.upperBound + else -> error("Unexpected flexible type ${this::class.java.simpleName}: $this") + } } override fun FlexibleTypeMarker.lowerBound(): SimpleTypeMarker { - require(this is IrDynamicType) - return irBuiltIns.nothingType as IrSimpleType + return when (this) { + is IrDynamicType -> irBuiltIns.nothingType as IrSimpleType + is IrJvmFlexibleType -> this.lowerBound + else -> error("Unexpected flexible type ${this::class.java.simpleName}: $this") + } } override fun SimpleTypeMarker.asCapturedType(): CapturedTypeMarker? = null diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt index a7427edd14b..50298b854d5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.isAnonymousObject import org.jetbrains.kotlin.ir.util.isPropertyAccessor import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable @@ -30,19 +29,21 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs fun IrType.withHasQuestionMark(newHasQuestionMark: Boolean): IrType = when (this) { - is IrSimpleType -> - if (this.hasQuestionMark == newHasQuestionMark) - this - else - buildSimpleType { - hasQuestionMark = newHasQuestionMark - kotlinType = originalKotlinType?.run { - if (newHasQuestionMark) makeNullable() else makeNotNullable() - } - } + is IrSimpleType -> withHasQuestionMark(newHasQuestionMark) else -> this } +fun IrSimpleType.withHasQuestionMark(newHasQuestionMark: Boolean): IrSimpleType = + if (this.hasQuestionMark == newHasQuestionMark) + this + else + buildSimpleType { + hasQuestionMark = newHasQuestionMark + kotlinType = originalKotlinType?.run { + if (newHasQuestionMark) makeNullable() else makeNotNullable() + } + } + fun IrType.addAnnotations(newAnnotations: List): IrType = if (newAnnotations.isEmpty()) this diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/jvmSpecificFlexibleTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/jvmSpecificFlexibleTypes.kt new file mode 100644 index 00000000000..7f927cc3ca6 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/jvmSpecificFlexibleTypes.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.ir.types + +import org.jetbrains.kotlin.ir.util.hasAnnotation +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.model.FlexibleTypeMarker +import org.jetbrains.kotlin.types.model.SimpleTypeMarker + +internal interface IrJvmFlexibleType : FlexibleTypeMarker { + val lowerBound: SimpleTypeMarker + val upperBound: SimpleTypeMarker +} + +internal class IrJvmFlexibleNullabilityType(val irType: IrSimpleType) : IrJvmFlexibleType { + override val lowerBound get() = irType.withHasQuestionMark(false) + override val upperBound get() = irType.withHasQuestionMark(true) +} + +internal val FLEXIBLE_NULLABILITY_FQN = FqName("kotlin.internal.ir").child(Name.identifier("FlexibleNullability")) + +internal fun IrType.isWithFlexibleNullability() = + hasAnnotation(FLEXIBLE_NULLABILITY_FQN) + +internal fun IrType.asJvmFlexibleType() = + when { + this is IrSimpleType && isWithFlexibleNullability() -> + IrJvmFlexibleNullabilityType( + this.removeAnnotations { irCtorCall -> + irCtorCall.type.classFqName == FLEXIBLE_NULLABILITY_FQN + } as IrSimpleType + ) + else -> + null + } \ No newline at end of file diff --git a/compiler/testData/codegen/box/collections/kt44233.kt b/compiler/testData/codegen/box/collections/kt44233.kt new file mode 100644 index 00000000000..5d2cb6cb2b1 --- /dev/null +++ b/compiler/testData/codegen/box/collections/kt44233.kt @@ -0,0 +1,18 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// FULL_JDK + +import java.util.concurrent.ConcurrentSkipListSet + +class StringIterable : Iterable { + private val strings = ConcurrentSkipListSet() + override fun iterator() = strings.iterator() +} + +fun box(): String { + val si = StringIterable() + return if (si.iterator().hasNext()) + "Failed" + else + "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt b/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt new file mode 100644 index 00000000000..4772276359a --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt @@ -0,0 +1,14 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// FULL_JDK + +import java.util.concurrent.* + +class Test1 : Iterable { + private val received = ConcurrentSkipListSet() + override fun iterator() = received.iterator() +} + +class Test2 : Iterable { + private val received = Array(0) { "" } + override fun iterator() = received.iterator() +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.txt b/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.txt new file mode 100644 index 00000000000..9129aa0d9b4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.txt @@ -0,0 +1,15 @@ +@kotlin.Metadata +public final class Test1 { + // source: 'kt44233.kt' + private final field received: java.util.concurrent.ConcurrentSkipListSet + public method (): void + public @org.jetbrains.annotations.NotNull method iterator(): java.util.Iterator +} + +@kotlin.Metadata +public final class Test2 { + // source: 'kt44233.kt' + private final field received: java.lang.String[] + public method (): void + public @org.jetbrains.annotations.NotNull method iterator(): java.util.Iterator +} diff --git a/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233_ir.txt b/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233_ir.txt new file mode 100644 index 00000000000..342ea4b02f4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233_ir.txt @@ -0,0 +1,15 @@ +@kotlin.Metadata +public final class Test1 { + // source: 'kt44233.kt' + private final @org.jetbrains.annotations.NotNull field received: java.util.concurrent.ConcurrentSkipListSet + public method (): void + public @org.jetbrains.annotations.NotNull method iterator(): java.util.Iterator +} + +@kotlin.Metadata +public final class Test2 { + // source: 'kt44233.kt' + private final @org.jetbrains.annotations.NotNull field received: java.lang.String[] + public method (): void + public @org.jetbrains.annotations.NotNull method iterator(): java.util.Iterator +} diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 7c749d7fd15..7692c587f8e 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5068,6 +5068,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/collections/kt41123.kt"); } + @TestMetadata("kt44233.kt") + public void testKt44233() throws Exception { + runTest("compiler/testData/codegen/box/collections/kt44233.kt"); + } + @TestMetadata("mutableList.kt") public void testMutableList() throws Exception { runTest("compiler/testData/codegen/box/collections/mutableList.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 436776ab37a..d54049b27e8 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -410,6 +410,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/inheritingFromAbstractMutableList.kt"); } + @TestMetadata("kt44233.kt") + public void testKt44233() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt"); + } + @TestMetadata("mapOfPrimitivesFullJdk.kt") public void testMapOfPrimitivesFullJdk() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/mapOfPrimitivesFullJdk.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 1faddd7267d..002c29dda39 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -5068,6 +5068,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/collections/kt41123.kt"); } + @TestMetadata("kt44233.kt") + public void testKt44233() throws Exception { + runTest("compiler/testData/codegen/box/collections/kt44233.kt"); + } + @TestMetadata("mutableList.kt") public void testMutableList() throws Exception { runTest("compiler/testData/codegen/box/collections/mutableList.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 03082fce39e..2c8b40a254d 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5068,6 +5068,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/collections/kt41123.kt"); } + @TestMetadata("kt44233.kt") + public void testKt44233() throws Exception { + runTest("compiler/testData/codegen/box/collections/kt44233.kt"); + } + @TestMetadata("mutableList.kt") public void testMutableList() throws Exception { runTest("compiler/testData/codegen/box/collections/mutableList.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index a9ef97c564d..e1e072ffb74 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -410,6 +410,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/inheritingFromAbstractMutableList.kt"); } + @TestMetadata("kt44233.kt") + public void testKt44233() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt"); + } + @TestMetadata("mapOfPrimitivesFullJdk.kt") public void testMapOfPrimitivesFullJdk() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/mapOfPrimitivesFullJdk.kt"); From 3f5e515bd65b2b09286b6b344d4e6e78362a6c19 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 11 Jan 2021 16:14:37 +0300 Subject: [PATCH 013/197] Fix broken ABI in DiagnosticFactory #KT-44145 Fixed --- .../diagnostics/DiagnosticFactoryWithPsiElement.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/DiagnosticFactoryWithPsiElement.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/DiagnosticFactoryWithPsiElement.java index 62f2a6ba77d..74d734b6cd8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/DiagnosticFactoryWithPsiElement.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/DiagnosticFactoryWithPsiElement.java @@ -40,4 +40,11 @@ public abstract class DiagnosticFactoryWithPsiElement getPositioningStrategy() { return positioningStrategy; } + + @SuppressWarnings("MethodOverloadsMethodOfSuperclass") + @Deprecated + // ABI-compatibility only (used in Android plugin) + public D cast(Diagnostic d) { + return super.cast(d); + } } From 33037fd885ce9ed39318cf7df852db7a295566ea Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 28 Dec 2020 19:22:55 +0300 Subject: [PATCH 014/197] FirAbstractImportingScope: minor simplification --- .../fir/scopes/impl/FirAbstractImportingScope.kt | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt index 525e5c16987..ab426c4c27e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope -import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -60,24 +59,16 @@ abstract class FirAbstractImportingScope( token: TowerScopeLevel.Token, processor: (FirCallableSymbol<*>) -> Unit ) { - val callableId = CallableId(import.packageFqName, import.relativeClassName, name) - val classId = import.resolvedClassId if (classId != null) { val scope = getStaticsScope(classId) ?: return when (token) { - TowerScopeLevel.Token.Functions -> scope.processFunctionsByName( - callableId.callableName, - processor - ) - TowerScopeLevel.Token.Properties -> scope.processPropertiesByName( - callableId.callableName, - processor - ) + TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name, processor) + TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name, processor) } } else if (name.isSpecial || name.identifier.isNotEmpty()) { - val symbols = provider.getTopLevelCallableSymbols(callableId.packageName, callableId.callableName) + val symbols = provider.getTopLevelCallableSymbols(import.packageFqName, name) if (symbols.isEmpty()) { return } From fd99f2b2cf12c372ba6c5a67d2f2519b2238562c Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 28 Dec 2020 20:06:17 +0300 Subject: [PATCH 015/197] FirDefaultStarImportingScope: improve measurements --- .../scopes/impl/FirAbstractImportingScope.kt | 4 ++-- .../impl/FirDefaultStarImportingScope.kt | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt index ab426c4c27e..e7bb00fa47d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt @@ -86,14 +86,14 @@ abstract class FirAbstractImportingScope( processor: (FirCallableSymbol<*>) -> Unit ) - final override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { + override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { return processCallables( name, TowerScopeLevel.Token.Functions ) { if (it is FirNamedFunctionSymbol) processor(it) } } - final override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { + override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { return processCallables( name, TowerScopeLevel.Token.Properties diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt index 5e88e0159bc..3f70a0919a3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt @@ -10,6 +10,10 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.builder.buildImport import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.name.Name class FirDefaultStarImportingScope( session: FirSession, @@ -33,4 +37,18 @@ class FirDefaultStarImportingScope( } } ?: emptyList() } + + override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { + processCallables( + name, + TowerScopeLevel.Token.Functions + ) { if (it is FirNamedFunctionSymbol) processor(it) } + } + + override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { + processCallables( + name, + TowerScopeLevel.Token.Properties + ) { if (it is FirVariableSymbol<*>) processor(it) } + } } From 4e4293b6090dcdb06db276bdde19d3a070ec6c27 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 14 Dec 2020 13:23:22 +0300 Subject: [PATCH 016/197] [FIR] Introduce separate getTopLevelFunction/PropertySymbols --- .../impl/FirBuiltinSymbolProvider.kt | 15 ++++ .../kotlin/fir/java/JavaSymbolProvider.kt | 8 +++ .../KotlinDeserializedJvmSymbolsProvider.kt | 18 ++++- .../resolve/providers/FirSymbolProvider.kt | 16 +++++ .../impl/FirCloneableSymbolProvider.kt | 16 +++-- .../impl/FirCompositeSymbolProvider.kt | 16 +++++ .../impl/FirDependenciesSymbolProviderImpl.kt | 26 +++++++ .../resolve/providers/impl/FirProviderImpl.kt | 70 +++++++++++++------ .../scopes/impl/FirAbstractImportingScope.kt | 67 +++++++----------- .../impl/FirAbstractSimpleImportingScope.kt | 21 +++--- .../impl/FirAbstractStarImportingScope.kt | 22 +++--- .../impl/FirDefaultStarImportingScope.kt | 23 +++--- .../fir/scopes/impl/FirPackageMemberScope.kt | 28 ++++---- .../low/level/api/providers/FirIdeProvider.kt | 20 +++++- ...FirModuleWithDependenciesSymbolProvider.kt | 18 +++++ .../level/api/providers/FirProviderHelper.kt | 10 +++ .../FirThreadSafeSymbolProviderWrapper.kt | 20 ++++++ 17 files changed, 297 insertions(+), 117 deletions(-) diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt index b58f0e01bbc..dffb33032b7 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt @@ -237,6 +237,17 @@ class FirBuiltinSymbolProvider(session: FirSession, val kotlinScopeProvider: Kot } } + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + allPackageFragments[packageFqName]?.flatMapTo(destination) { + it.getTopLevelFunctionSymbols(name) + } + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + } + private class BuiltInsPackageFragment( stream: InputStream, val fqName: FqName, val session: FirSession, val kotlinScopeProvider: KotlinScopeProvider, @@ -297,6 +308,10 @@ class FirBuiltinSymbolProvider(session: FirSession, val kotlinScopeProvider: Kot } fun getTopLevelCallableSymbols(name: Name): List> { + return getTopLevelFunctionSymbols(name) + } + + fun getTopLevelFunctionSymbols(name: Name): List { return packageProto.`package`.functionList.filter { nameResolver.getName(it.name) == name }.map { memberDeserializer.loadFunction(it).symbol } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 1b4301c4b7f..62b4626d765 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -71,6 +71,14 @@ class JavaSymbolProvider( override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) { } + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + } + private fun JavaTypeParameter.toFirTypeParameterSymbol( javaTypeParameterStack: JavaTypeParameterStack ): Pair { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt index 191135f168a..49222281729 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/KotlinDeserializedJvmSymbolsProvider.kt @@ -363,14 +363,14 @@ class KotlinDeserializedJvmSymbolsProvider( return symbol } - private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List> { + private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List { val functionIds = part.topLevelFunctionNameIndex[name] ?: return emptyList() return functionIds.map { part.context.memberDeserializer.loadFunction(part.proto.getFunction(it)).symbol } } - private fun loadPropertiesByName(part: PackagePartsCacheData, name: Name): List> { + private fun loadPropertiesByName(part: PackagePartsCacheData, name: Name): List { val propertyIds = part.topLevelPropertyNameIndex[name] ?: return emptyList() return propertyIds.map { part.context.memberDeserializer.loadProperty(part.proto.getProperty(it)).symbol @@ -384,6 +384,20 @@ class KotlinDeserializedJvmSymbolsProvider( } } + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + getPackageParts(packageFqName).flatMapTo(destination) { part -> + loadFunctionsByName(part, name) + } + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + getPackageParts(packageFqName).flatMapTo(destination) { part -> + loadPropertiesByName(part, name) + } + } + private fun getPackageParts(packageFqName: FqName): Collection { return packagePartsCache.lookupCacheOrCalculate(packageFqName) { try { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt index 1763efbc62a..b4b016e6d93 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt @@ -32,6 +32,22 @@ abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent @FirSymbolProviderInternals abstract fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) + @OptIn(ExperimentalStdlibApi::class, FirSymbolProviderInternals::class) + open fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List { + return buildList { getTopLevelFunctionSymbolsTo(this, packageFqName, name) } + } + + @FirSymbolProviderInternals + abstract fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) + + @OptIn(ExperimentalStdlibApi::class, FirSymbolProviderInternals::class) + open fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List { + return buildList { getTopLevelPropertySymbolsTo(this, packageFqName, name) } + } + + @FirSymbolProviderInternals + abstract fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) + abstract fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt index 33825d8e5cc..3008451da25 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCloneableSymbolProvider.kt @@ -21,10 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.scopes.FirScopeProvider import org.jetbrains.kotlin.fir.symbols.CallableId -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -71,7 +68,16 @@ class FirCloneableSymbolProvider(session: FirSession, scopeProvider: FirScopePro } @FirSymbolProviderInternals - override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) {} + override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) { + } + + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + } override fun getPackage(fqName: FqName): FqName? { return null diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCompositeSymbolProvider.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCompositeSymbolProvider.kt index 65529f0a587..1709c13c3c7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCompositeSymbolProvider.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCompositeSymbolProvider.kt @@ -11,6 +11,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -27,6 +29,20 @@ class FirCompositeSymbolProvider(session: FirSession, val providers: List, packageFqName: FqName, name: Name) { + providers.forEach { + it.getTopLevelFunctionSymbolsTo(destination, packageFqName, name) + } + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + providers.forEach { + it.getTopLevelPropertySymbolsTo(destination, packageFqName, name) + } + } + override fun getPackage(fqName: FqName): FqName? { return providers.firstNotNullResult { it.getPackage(fqName) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt index e4450b4b1c5..98ffefa6c29 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt @@ -15,6 +15,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.SymbolProviderCache import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -23,6 +25,8 @@ import org.jetbrains.kotlin.name.Name open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolProvider(session) { private val classCache = SymbolProviderCache>() private val topLevelCallableCache = SymbolProviderCache>>() + private val topLevelFunctionCache = SymbolProviderCache>() + private val topLevelPropertyCache = SymbolProviderCache>() private val packageCache = SymbolProviderCache() protected open val dependencyProviders by lazy { @@ -32,6 +36,28 @@ open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolPro }.toList() } + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += topLevelFunctionCache.lookupCacheOrCalculate(CallableId(packageFqName, null, name)) { + val result = mutableListOf() + dependencyProviders.forEach { + it.getTopLevelFunctionSymbolsTo(result, packageFqName, name) + } + result + } ?: emptyList() + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += topLevelPropertyCache.lookupCacheOrCalculate(CallableId(packageFqName, null, name)) { + val result = mutableListOf() + dependencyProviders.forEach { + it.getTopLevelPropertySymbolsTo(result, packageFqName, name) + } + result + } ?: emptyList() + } + @FirSymbolProviderInternals override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) { destination += getTopLevelCallableSymbols(packageFqName, name) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirProviderImpl.kt index e2956676d6d..7661556daf2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirProviderImpl.kt @@ -18,9 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider import org.jetbrains.kotlin.fir.symbols.CallableId -import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -60,13 +58,21 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc return getFirClassifierByFqName(classId)?.symbol } - override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List> { - return (state.callableMap[CallableId(packageFqName, null, name)] ?: emptyList()) + @FirSymbolProviderInternals + override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) { + destination += (state.functionMap[CallableId(packageFqName, null, name)] ?: emptyList()) + destination += (state.propertyMap[CallableId(packageFqName, null, name)] ?: emptyList()) + } @FirSymbolProviderInternals - override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) { - destination += getTopLevelCallableSymbols(packageFqName, name) + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += (state.functionMap[CallableId(packageFqName, null, name)] ?: emptyList()) + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += (state.propertyMap[CallableId(packageFqName, null, name)] ?: emptyList()) } override fun getPackage(fqName: FqName): FqName? { @@ -121,33 +127,47 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc state.classifierContainerFileMap[classId] = file } - override fun > visitCallableDeclaration( - callableDeclaration: FirCallableDeclaration, + override fun visitPropertyAccessor( + propertyAccessor: FirPropertyAccessor, data: Pair ) { - val symbol = callableDeclaration.symbol + val symbol = propertyAccessor.symbol + val (state, file) = data + state.callableContainerMap[symbol] = file + } + + private inline fun , S : FirCallableSymbol> registerCallable( + symbol: S, + data: Pair, + map: MutableMap> + ) { val callableId = symbol.callableId val (state, file) = data - state.callableMap.merge(callableId, listOf(symbol)) { a, b -> a + b } + map.merge(callableId, listOf(symbol)) { a, b -> a + b } state.callableContainerMap[symbol] = file } override fun visitConstructor(constructor: FirConstructor, data: Pair) { - visitCallableDeclaration(constructor, data) + val symbol = constructor.symbol + registerCallable(symbol, data, data.first.constructorMap) } override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Pair) { - visitCallableDeclaration(simpleFunction, data) + val symbol = simpleFunction.symbol + registerCallable(symbol, data, data.first.functionMap) } override fun visitProperty(property: FirProperty, data: Pair) { - visitCallableDeclaration(property, data) - property.getter?.let { visitCallableDeclaration(it, data) } - property.setter?.let { visitCallableDeclaration(it, data) } + val symbol = property.symbol + registerCallable(symbol, data, data.first.propertyMap) + property.getter?.let { visitPropertyAccessor(it, data) } + property.setter?.let { visitPropertyAccessor(it, data) } } override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Pair) { - visitCallableDeclaration(enumEntry, data) + val symbol = enumEntry.symbol + val (state, file) = data + state.callableContainerMap[symbol] = file } } @@ -158,20 +178,26 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc val classifierMap = mutableMapOf>() val classifierContainerFileMap = mutableMapOf() val classesInPackage = mutableMapOf>() - val callableMap = mutableMapOf>>() + val functionMap = mutableMapOf>() + val propertyMap = mutableMapOf>() + val constructorMap = mutableMapOf>() val callableContainerMap = mutableMapOf, FirFile>() fun setFrom(other: State) { fileMap.clear() classifierMap.clear() classifierContainerFileMap.clear() - callableMap.clear() + functionMap.clear() + propertyMap.clear() + constructorMap.clear() callableContainerMap.clear() fileMap.putAll(other.fileMap) classifierMap.putAll(other.classifierMap) classifierContainerFileMap.putAll(other.classifierContainerFileMap) - callableMap.putAll(other.callableMap) + functionMap.putAll(other.functionMap) + propertyMap.putAll(other.propertyMap) + constructorMap.putAll(other.constructorMap) callableContainerMap.putAll(other.callableContainerMap) classesInPackage.putAll(other.classesInPackage) } @@ -246,7 +272,9 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc checkMMapDiff("fileMap", state.fileMap, newState.fileMap) checkMapDiff("classifierMap", state.classifierMap, newState.classifierMap) checkMapDiff("classifierContainerFileMap", state.classifierContainerFileMap, newState.classifierContainerFileMap) - checkMMapDiff("callableMap", state.callableMap, newState.callableMap) + checkMMapDiff("callableMap", state.functionMap, newState.functionMap) + checkMMapDiff("callableMap", state.propertyMap, newState.propertyMap) + checkMMapDiff("callableMap", state.constructorMap, newState.constructorMap) checkMapDiff("callableContainerMap", state.callableContainerMap, newState.callableContainerMap) if (!rebuildIndex) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt index e7bb00fa47d..1a4fbdd05ad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractImportingScope.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirResolvedImport import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls import org.jetbrains.kotlin.fir.scopes.FirScope @@ -53,51 +52,39 @@ abstract class FirAbstractImportingScope( return getStaticsScope(symbol) } - protected fun > processCallables( - import: FirResolvedImport, + protected inline fun processFunctionsByNameWithImport( name: Name, - token: TowerScopeLevel.Token, - processor: (FirCallableSymbol<*>) -> Unit + import: FirResolvedImport, + crossinline processor: (FirNamedFunctionSymbol) -> Unit ) { - val classId = import.resolvedClassId - if (classId != null) { - val scope = getStaticsScope(classId) ?: return - - when (token) { - TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name, processor) - TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name, processor) - } - } else if (name.isSpecial || name.identifier.isNotEmpty()) { - val symbols = provider.getTopLevelCallableSymbols(import.packageFqName, name) - if (symbols.isEmpty()) { - return - } - - for (symbol in symbols) { - symbol.ensureResolvedForCalls(session) - processor(symbol) + import.resolvedClassId?.let { classId -> + getStaticsScope(classId)?.processFunctionsByName(name) { processor(it) } + } ?: run { + if (name.isSpecial || name.identifier.isNotEmpty()) { + val symbols = provider.getTopLevelFunctionSymbols(import.packageFqName, name) + for (symbol in symbols) { + symbol.ensureResolvedForCalls(session) + processor(symbol) + } } } } - abstract fun > processCallables( + protected inline fun processPropertiesByNameWithImport( name: Name, - token: TowerScopeLevel.Token, - processor: (FirCallableSymbol<*>) -> Unit - ) - - override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { - return processCallables( - name, - TowerScopeLevel.Token.Functions - ) { if (it is FirNamedFunctionSymbol) processor(it) } + import: FirResolvedImport, + crossinline processor: (FirVariableSymbol<*>) -> Unit + ) { + import.resolvedClassId?.let { classId -> + getStaticsScope(classId)?.processPropertiesByName(name) { processor(it) } + } ?: run { + if (name.isSpecial || name.identifier.isNotEmpty()) { + val symbols = provider.getTopLevelPropertySymbols(import.packageFqName, name) + for (symbol in symbols) { + symbol.ensureResolvedForCalls(session) + processor(symbol) + } + } + } } - - override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { - return processCallables( - name, - TowerScopeLevel.Token.Properties - ) { if (it is FirVariableSymbol<*>) processor(it) } - } - } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt index 678e8e6b620..71dcf49a767 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt @@ -8,11 +8,11 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirResolvedImport import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -38,16 +38,17 @@ abstract class FirAbstractSimpleImportingScope( } } - override fun > processCallables( - name: Name, - token: TowerScopeLevel.Token, - processor: (FirCallableSymbol<*>) -> Unit - ) { + override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { val imports = simpleImports[name] ?: return - if (imports.isEmpty()) return - for (import in imports) { - processCallables(import, import.importedName!!, token, processor) + processFunctionsByNameWithImport(import.importedName!!, import, processor) + } + } + + override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { + val imports = simpleImports[name] ?: return + for (import in imports) { + processPropertiesByNameWithImport(import.importedName!!, import, processor) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractStarImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractStarImportingScope.kt index a6654ab432c..601a6d39d51 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractStarImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractStarImportingScope.kt @@ -8,10 +8,10 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirResolvedImport import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -47,17 +47,15 @@ abstract class FirAbstractStarImportingScope( } } - - override fun > processCallables( - name: Name, - token: TowerScopeLevel.Token, - processor: (FirCallableSymbol<*>) -> Unit - ) { - if (starImports.isEmpty()) { - return - } + override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { for (import in starImports) { - processCallables(import, name, token, processor) + processFunctionsByNameWithImport(name, import, processor) + } + } + + override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { + for (import in starImports) { + processPropertiesByNameWithImport(name, import, processor) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt index 3f70a0919a3..8fda4a031b2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirDefaultStarImportingScope.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.builder.buildImport import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.name.Name @@ -39,16 +38,22 @@ class FirDefaultStarImportingScope( } override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { - processCallables( - name, - TowerScopeLevel.Token.Functions - ) { if (it is FirNamedFunctionSymbol) processor(it) } + if (name.isSpecial || name.identifier.isNotEmpty()) { + for (import in starImports) { + for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, name)) { + processor(symbol) + } + } + } } override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { - processCallables( - name, - TowerScopeLevel.Token.Properties - ) { if (it is FirVariableSymbol<*>) processor(it) } + if (name.isSpecial || name.identifier.isNotEmpty()) { + for (import in starImports) { + for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, name)) { + processor(symbol) + } + } + } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt index 01a2658079c..6b895a5e9df 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt @@ -18,7 +18,8 @@ import org.jetbrains.kotlin.name.Name class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirScope() { private val symbolProvider = session.firSymbolProvider private val classifierCache: MutableMap?> = mutableMapOf() - private val callableCache: MutableMap>> = mutableMapOf() + private val functionCache: MutableMap> = mutableMapOf() + private val propertyCache: MutableMap> = mutableMapOf() override fun processClassifiersByNameWithSubstitution( name: Name, @@ -37,25 +38,22 @@ class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirSc } override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) { - processCallables(name, processor) + val symbols = functionCache.getOrPut(name) { + symbolProvider.getTopLevelFunctionSymbols(fqName, name) + } + for (symbol in symbols) { + symbol.ensureResolvedForCalls(session) + processor(symbol) + } } override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { - processCallables(name, processor) - } - - private inline fun > processCallables( - name: Name, - processor: (D) -> Unit - ) { - val symbols = callableCache.getOrPut(name) { - symbolProvider.getTopLevelCallableSymbols(fqName, name) + val symbols = propertyCache.getOrPut(name) { + symbolProvider.getTopLevelPropertySymbols(fqName, name) } for (symbol in symbols) { - if (symbol is D) { - symbol.ensureResolvedForCalls(session) - processor(symbol) - } + symbol.ensureResolvedForCalls(session) + processor(symbol) } } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt index 16f47e39360..26d426be04c 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirIdeProvider.kt @@ -19,9 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider -import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceCheckerForSingleModule @@ -131,6 +129,22 @@ internal class FirIdeProvider( destination += getTopLevelCallableSymbols(packageFqName, name) } + override fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List = + providerHelper.getTopLevelFunctionSymbols(packageFqName, name) + + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += getTopLevelFunctionSymbols(packageFqName, name) + } + + override fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List = + providerHelper.getTopLevelPropertySymbols(packageFqName, name) + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += getTopLevelPropertySymbols(packageFqName, name) + } + override fun getPackage(fqName: FqName): FqName? = providerHelper.getPackage(fqName) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt index b940142e127..316f17d9c5c 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirModuleWithDependenciesSymbolProvider.kt @@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -35,6 +37,22 @@ internal class FirModuleWithDependenciesSymbolProvider( } } + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + providers.forEach { it.getTopLevelFunctionSymbolsTo(destination, packageFqName, name) } + withDependent { + dependentProviders.forEach { it.getTopLevelFunctionSymbolsTo(destination, packageFqName, name) } + } + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + providers.forEach { it.getTopLevelPropertySymbolsTo(destination, packageFqName, name) } + withDependent { + dependentProviders.forEach { it.getTopLevelPropertySymbolsTo(destination, packageFqName, name) } + } + } + override fun getPackage(fqName: FqName): FqName? = providers.firstNotNullResult { it.getPackage(fqName) } ?: withDependent(default = null) { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirProviderHelper.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirProviderHelper.kt index 6f582392a45..1878a8cba61 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirProviderHelper.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirProviderHelper.kt @@ -11,6 +11,8 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceChecker import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder @@ -67,6 +69,14 @@ internal class FirProviderHelper( } } + fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List { + return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance() + } + + fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List { + return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance() + } + private fun FirFile.collectCallableDeclarationsTo(list: MutableList>, name: Name) { declarations.mapNotNullTo(list) { declaration -> if (declaration is FirCallableDeclaration<*> && declaration.symbol.callableId.callableName == name) { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirThreadSafeSymbolProviderWrapper.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirThreadSafeSymbolProviderWrapper.kt index 8a1302623e9..e4e703774ba 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirThreadSafeSymbolProviderWrapper.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/providers/FirThreadSafeSymbolProviderWrapper.kt @@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -34,11 +36,29 @@ internal class FirThreadSafeSymbolProviderWrapper(private val provider: FirSymbo provider.getTopLevelCallableSymbols(packageFqName, name) } ?: emptyList() + override fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List { + return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance() + } + + override fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List { + return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance() + } + @FirSymbolProviderInternals override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) { error("Should not be called for wrapper") } + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += getTopLevelFunctionSymbols(packageFqName, name) + } + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) { + destination += getTopLevelPropertySymbols(packageFqName, name) + } + override fun getPackage(fqName: FqName): FqName? = packages.getOrCompute(fqName) { provider.getPackage(fqName) } } From 0c0dbd6245a5568208d8c6b98daf01215bd2d2d7 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 29 Dec 2020 13:32:22 +0300 Subject: [PATCH 017/197] [FIR] Perform more accurate pre-check of candidate receiver type --- .../resolve/calls/tower/TowerLevelHandler.kt | 34 ----------- .../fir/resolve/calls/tower/TowerLevels.kt | 58 ++++++++++++++----- ...allDefaultConstructorOfUnsignedType.fir.kt | 2 +- ...inlineOrdinaryOfCrossinlineOrdinary.fir.kt | 2 +- .../inlineOrdinaryOfNoinlineOrdinary.fir.kt | 2 +- .../inlineOrdinaryOfOrdinary.fir.kt | 2 +- .../inlineSuspendOfCrossinlineOrdinary.fir.kt | 2 +- .../inlineSuspendOfNoinlineOrdinary.fir.kt | 2 +- .../inlineSuspendOfOrdinary.fir.kt | 2 +- .../kotlin.nothing/p-1/neg/2.1.fir.kt | 2 +- .../analysis/smartcasts/neg/15.fir.kt | 4 +- .../diagnostics/notLinked/dfa/neg/1.fir.kt | 2 +- 12 files changed, 54 insertions(+), 60 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt index 8b8042e77aa..6c17c315da7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt @@ -5,21 +5,12 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower -import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.typeContext -import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.ConeStarProjection -import org.jetbrains.kotlin.fir.types.coneType -import org.jetbrains.kotlin.fir.types.constructClassType import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind -import org.jetbrains.kotlin.types.AbstractTypeChecker internal class CandidateFactoriesAndCollectors( // Common calls @@ -88,31 +79,6 @@ private class TowerScopeLevelProcessor( scope: FirScope, builtInExtensionFunctionReceiverValue: ReceiverValue? ) { - // Check explicit extension receiver for default package members - if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null && - extensionReceiverValue != null && - callInfo.explicitReceiver !is FirResolvedQualifier && - symbol.callableId.packageName.startsWith(defaultPackage) - ) { - val extensionReceiverType = extensionReceiverValue.type as? ConeClassLikeType - if (extensionReceiverType != null) { - val declarationReceiverType = (symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef?.coneType - if (declarationReceiverType is ConeClassLikeType) { - if (!AbstractTypeChecker.isSubtypeOf( - candidateFactory.context.session.typeContext, - extensionReceiverType, - declarationReceiverType.lookupTag.constructClassType( - declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(), - isNullable = true - ) - ) - ) { - return - } - } - } - } - // --- resultCollector.consumeCandidate( group, candidateFactory.createCandidate( callInfo, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index 5912506b72c..37fbc428bad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -15,12 +15,18 @@ import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.impl.FirDefaultStarImportingScope import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData import org.jetbrains.kotlin.fir.scopes.processClassifiersByName import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeStarProjection +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.constructClassType import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.util.OperatorNameConventions abstract class TowerScopeLevel { @@ -178,12 +184,6 @@ class ScopeTowerLevel( private val extensionsOnly: Boolean, private val includeInnerConstructors: Boolean ) : SessionBasedTowerLevel(session) { - private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: Receiver?): Boolean = - when { - extensionsOnly && !hasExtensionReceiver() -> false - !hasConsistentExtensionReceiver(extensionReceiver) -> false - else -> true - } private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? { candidate.fir.importedFromObjectData?.let { data -> @@ -215,20 +215,48 @@ class ScopeTowerLevel( } } + private fun shouldSkipCandidateWithInconsistentExtensionReceiver(candidate: FirCallableSymbol<*>): Boolean { + // Pre-check explicit extension receiver for default package top-level members + if (scope is FirDefaultStarImportingScope && extensionReceiver != null) { + val extensionReceiverType = extensionReceiver.type + if (extensionReceiverType is ConeClassLikeType) { + val declarationReceiverType = candidate.fir.receiverTypeRef?.coneType + if (declarationReceiverType is ConeClassLikeType) { + if (!AbstractTypeChecker.isSubtypeOf( + session.typeContext, + extensionReceiverType, + declarationReceiverType.lookupTag.constructClassType( + declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(), + isNullable = true + ) + ) + ) { + return true + } + } + } + } + return false + } + private fun > consumeCallableCandidate( candidate: FirCallableSymbol<*>, processor: TowerScopeLevelProcessor ) { - if (candidate.hasConsistentReceivers(extensionReceiver)) { - val dispatchReceiverValue = dispatchReceiverValue(candidate) - val unwrappedCandidate = candidate.fir.importedFromObjectData?.original?.symbol ?: candidate - @Suppress("UNCHECKED_CAST") - processor.consumeCandidate( - unwrappedCandidate as T, dispatchReceiverValue, - extensionReceiverValue = extensionReceiver, - scope - ) + val candidateReceiverTypeRef = candidate.fir.receiverTypeRef + val receiverExpected = extensionsOnly || extensionReceiver != null + if (candidateReceiverTypeRef == null == receiverExpected) return + val dispatchReceiverValue = dispatchReceiverValue(candidate) + if (dispatchReceiverValue == null && shouldSkipCandidateWithInconsistentExtensionReceiver(candidate)) { + return } + val unwrappedCandidate = candidate.fir.importedFromObjectData?.original?.symbol ?: candidate + @Suppress("UNCHECKED_CAST") + processor.consumeCandidate( + unwrappedCandidate as T, dispatchReceiverValue, + extensionReceiverValue = extensionReceiver, + scope + ) } override fun processFunctionsByName( diff --git a/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt b/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt index cb8bae9af5b..761b6af164b 100644 --- a/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt +++ b/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt @@ -1 +1 @@ -val foo = UInt() +val foo = UInt() diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt index 10b112eae1c..947e56276e4 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt @@ -21,7 +21,7 @@ inline fun test(crossinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } suspend fun calculate() = "OK" diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt index 74f94fa1795..405495a2714 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt @@ -20,7 +20,7 @@ inline fun test(noinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } suspend fun calculate() = "OK" diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt index 2a6c74bef99..4085e871dd5 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt @@ -21,7 +21,7 @@ inline fun test(c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } fun builder(c: suspend () -> Unit) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt index 3a8b813993b..7dadb75ca42 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt @@ -20,7 +20,7 @@ suspend inline fun test(crossinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } fun builder(c: suspend () -> Unit) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt index 65833bc430a..a24f85d9853 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt @@ -20,7 +20,7 @@ suspend inline fun test(noinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } fun builder(c: suspend () -> Unit) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt index cfea83085db..c036c55114a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt @@ -20,7 +20,7 @@ suspend inline fun test(c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } suspend fun calculate() = "OK" diff --git a/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt index 4417f42a6d7..bbed635db8b 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt @@ -6,7 +6,7 @@ class Case1(val nothing: Nothing) fun case1() { - val res = Case1(Nothing()) + val res = Case1(Nothing()) } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt index b737b5d437f..f9794f96f88 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt @@ -30,14 +30,14 @@ import contracts.* // TESTCASE NUMBER: 1 fun case_1(value: Any) { if (contracts.case_1_2(contracts.case_1_1(value is Char))) { - println(value.category) + println(value.category) } } // TESTCASE NUMBER: 2 fun case_2(value: Any) { if (contracts.case_2(value is Char) is Boolean) { - println(value.category) + println(value.category) } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt index 02adb3416d6..dd25f83a07c 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt @@ -263,7 +263,7 @@ fun case_16() { // TESTCASE NUMBER: 17 val case_17 = if (nullableIntProperty == null == true == false) 0 else { nullableIntProperty - nullableIntProperty.java + nullableIntProperty.java } //TESTCASE NUMBER: 18 From 92f3b759c0ad973d4277aef57a40d6a4deb3683f Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 11 Jan 2021 17:20:55 +0100 Subject: [PATCH 018/197] Fix codegen test data for genericTypeWithNothing.kt #KT-18367 Fixed Co-authored-by: Zalim Bashorov --- .../codegen/box/typeMapping/genericTypeWithNothing.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/testData/codegen/box/typeMapping/genericTypeWithNothing.kt b/compiler/testData/codegen/box/typeMapping/genericTypeWithNothing.kt index 8cd253b338c..5dd6e1799db 100644 --- a/compiler/testData/codegen/box/typeMapping/genericTypeWithNothing.kt +++ b/compiler/testData/codegen/box/typeMapping/genericTypeWithNothing.kt @@ -57,28 +57,28 @@ fun testAllDeclaredMembers(klass: KClass<*>, expectedIsRaw: Boolean): String? { val clazz = klass.java for (it in clazz.declaredFields) { - if ((it.type == it.genericType) == expectedIsRaw) return "failed on field '${clazz.simpleName}::${it.name}'" + if ((it.type == it.genericType) != expectedIsRaw) return "failed on field '${clazz.simpleName}::${it.name}'" } for (m in clazz.declaredMethods) { for (i in m.parameterTypes.indices) { - if ((m.parameterTypes[i] == m.genericParameterTypes[i]) == expectedIsRaw) return "failed on type of param#$i of method '${clazz.simpleName}::${m.name}'" + if ((m.parameterTypes[i] == m.genericParameterTypes[i]) != expectedIsRaw) return "failed on type of param#$i of method '${clazz.simpleName}::${m.name}'" } - if (m.returnType != Void.TYPE && (m.returnType == m.genericReturnType) == expectedIsRaw) return "failed on return type of method '${clazz.simpleName}::${m.name}'" + if (m.returnType != Void.TYPE && (m.returnType == m.genericReturnType) != expectedIsRaw) return "failed on return type of method '${clazz.simpleName}::${m.name}'" } return null } fun box(): String { - testAllDeclaredMembers(TestRaw::class, expectedIsRaw = true) ?: + testAllDeclaredMembers(TestRaw::class, expectedIsRaw = true)?.let { return it } testAllDeclaredMembers(TestNotRaw::class, expectedIsRaw = false)?.let { return it } if (C1::class.java.superclass != C1::class.java.genericSuperclass) return "failed on C1 superclass" if (C2::class.java.superclass == C2::class.java.genericSuperclass) return "failed on C2 superclass" - testAllDeclaredMembers(C1::class, expectedIsRaw = true) ?: + testAllDeclaredMembers(C1::class, expectedIsRaw = true)?.let { return it } testAllDeclaredMembers(C2::class, expectedIsRaw = false)?.let { return it } return "OK" From c2d7b69e5fdfa6bd4162d4e81a0b8b5475e76591 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 11 Jan 2021 17:27:03 +0100 Subject: [PATCH 019/197] Remove bytecode text test kt15806.kt It's not correct to expect that the backend generates the `when` in this test as tableswitch because there are only two branches. JVM IR has a cutoff in the when optimization and generates `when`s with fewer than 3 branches as if-else chains, which is probably better. Note that there's also a corresponding box test in when/enumOptimization/, so the backend behavior is still tested. --- .../ir/FirBytecodeTextTestGenerated.java | 5 ---- .../whenEnumOptimization/kt15806.kt | 29 ------------------- .../codegen/BytecodeTextTestGenerated.java | 5 ---- .../ir/IrBytecodeTextTestGenerated.java | 5 ---- 4 files changed, 44 deletions(-) delete mode 100644 compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt15806.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java index d15c74a552d..5aab02dcb1e 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBytecodeTextTestGenerated.java @@ -4974,11 +4974,6 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14802.kt"); } - @TestMetadata("kt15806.kt") - public void testKt15806() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt15806.kt"); - } - @TestMetadata("manyWhensWithinClass.kt") public void testManyWhensWithinClass() throws Exception { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt"); diff --git a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt15806.kt b/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt15806.kt deleted file mode 100644 index 5be6fa29db8..00000000000 --- a/compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt15806.kt +++ /dev/null @@ -1,29 +0,0 @@ -// IGNORE_BACKEND: JVM_IR -// TODO KT-36845 Generate enum-based TABLESWITCH/LOOKUPSWITCH on a value with smart cast to enum in JVM_IR - -private fun Any?.doTheThing(): String { - when (this) { - is String -> return this - is Level -> { - when (this) { - Level.O -> return Level.O.name - Level.K -> return Level.K.name - } - } - - else -> return "fail" - } -} - - -enum class Level { - O, - K -} - - -fun box(): String { - return "O".doTheThing() + Level.K.doTheThing() -} - -// 1 TABLESWITCH diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 6fcef959ef7..748faa774f3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -4991,11 +4991,6 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14802.kt"); } - @TestMetadata("kt15806.kt") - public void testKt15806() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt15806.kt"); - } - @TestMetadata("manyWhensWithinClass.kt") public void testManyWhensWithinClass() throws Exception { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index f8976f8f180..c6f9499ee57 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -4974,11 +4974,6 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt14802.kt"); } - @TestMetadata("kt15806.kt") - public void testKt15806() throws Exception { - runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/kt15806.kt"); - } - @TestMetadata("manyWhensWithinClass.kt") public void testManyWhensWithinClass() throws Exception { runTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt"); From 43b61a618d47d1c25c1b4f6ca66495ac02f62254 Mon Sep 17 00:00:00 2001 From: Kristoffer Andersen Date: Wed, 9 Dec 2020 17:15:46 +0100 Subject: [PATCH 020/197] [IR+Tests] Improve Local Function Debugging Experience This change improves the debugging experience around local functions on the IR backend. The changes include moving old checkLocalVariablesTable (cLVT) tests to the new stepping/local variable infrastructure in order to refine the tests and further define the behavior of the two JVM backends, and their differences. The primary ported test case is cLVT/localFun.kt that documents the discrepancy in implementation strategy for local functions on the two backends. The old backend implements local functions as lambdas assigned to a local variable while the IR backend lifts them out as static funtions on the surrounding class. The discrepancies and their consequences are documented in bytecodeListing, idea-stepping, localVariableTable and debugStepping tests. The only _code change_ is disabling the captured variable name mangling for captured variables on the IR backend. Captured variables are passed as arguments to the static function, so in the debugger, they really just are local variables. For them to show properly in the debugger and be detectable by evaluate expression, they simply need no mangling. Finally, this change cleans 3 redundant cLVT tests, copyFunction.kt and destructuringInlineLambda.kt and destructuringInFor.kt, that are all covered in the new suite. The stepping behavior needs to be made precise around for loops, but that is an entirely seperate issue. --- .../common/lower/LocalDeclarationsLowering.kt | 27 ++++++---- .../checkLocalVariablesTable/copyFunction.kt | 6 --- .../destructuringInFor.kt | 14 ------ .../destructuringInlineLambda.kt | 22 -------- .../checkLocalVariablesTable/localFun.kt | 18 ------- .../codegen/bytecodeListing/localFunction.kt | 5 ++ .../codegen/bytecodeListing/localFunction.txt | 18 +++++++ .../bytecodeListing/localFunction_ir.txt | 6 +++ .../localVariables/destructuringInFor.kt | 21 ++++---- .../testData/debug/localVariables/emptyFun.kt | 13 +++++ .../testData/debug/localVariables/localFun.kt | 50 ++++++++++++++++--- .../debug/localVariables/localFunUnused.kt | 31 ++++++++++++ .../localFunctionWIthOnelineExpressionBody.kt | 25 ++++++++++ .../codegen/BytecodeListingTestGenerated.java | 5 ++ ...CheckLocalVariablesTableTestGenerated.java | 20 -------- .../IrLocalVariableTestGenerated.java | 12 +++++ .../IrSteppingTestGenerated.java | 6 +++ .../LocalVariableTestGenerated.java | 12 +++++ .../SteppingTestGenerated.java | 6 +++ .../ir/IrBytecodeListingTestGenerated.java | 5 ++ ...CheckLocalVariablesTableTestGenerated.java | 20 -------- ...KotlinEvaluateExpressionTestGenerated.java | 5 ++ .../test/IrKotlinSteppingTestGenerated.java | 10 ++++ ...KotlinEvaluateExpressionTestGenerated.java | 5 ++ .../test/KotlinSteppingTestGenerated.java | 10 ++++ .../localFunctionCapturedLocalVariable.kt | 13 +++++ .../localFunctionCapturedLocalVariable.out | 8 +++ .../stepping/stepOver/localFunction.ir.out | 6 +++ .../stepping/stepOver/localFunction.kt | 12 +++++ .../stepping/stepOver/localFunction.out | 8 +++ ...unctionWithSingleLineExpressionBody.ir.out | 9 ++++ ...calFunctionWithSingleLineExpressionBody.kt | 13 +++++ ...alFunctionWithSingleLineExpressionBody.out | 10 ++++ 33 files changed, 324 insertions(+), 127 deletions(-) delete mode 100644 compiler/testData/checkLocalVariablesTable/copyFunction.kt delete mode 100644 compiler/testData/checkLocalVariablesTable/destructuringInFor.kt delete mode 100644 compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt delete mode 100644 compiler/testData/checkLocalVariablesTable/localFun.kt create mode 100644 compiler/testData/codegen/bytecodeListing/localFunction.kt create mode 100644 compiler/testData/codegen/bytecodeListing/localFunction.txt create mode 100644 compiler/testData/codegen/bytecodeListing/localFunction_ir.txt create mode 100644 compiler/testData/debug/localVariables/emptyFun.kt create mode 100644 compiler/testData/debug/localVariables/localFunUnused.kt create mode 100644 compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.out create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.ir.out create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.out create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.ir.out create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt create mode 100644 idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.out diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt index aa4ad74b6a0..df578217bcc 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LocalDeclarationsLowering.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.CommonBackendContext -import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString import org.jetbrains.kotlin.backend.common.ir.* import org.jetbrains.kotlin.backend.common.runOnFilePostfix @@ -633,7 +632,7 @@ class LocalDeclarationsLowering( newDeclaration.copyAttributes(oldDeclaration) newDeclaration.valueParameters += createTransformedValueParameters( - capturedValues, localFunctionContext, oldDeclaration, newDeclaration + capturedValues, localFunctionContext, oldDeclaration, newDeclaration, isExplicitLocalFunction = oldDeclaration.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA ) newDeclaration.recordTransformedValueParameters(localFunctionContext) @@ -646,7 +645,8 @@ class LocalDeclarationsLowering( capturedValues: List, localFunctionContext: LocalContext, oldDeclaration: IrFunction, - newDeclaration: IrFunction + newDeclaration: IrFunction, + isExplicitLocalFunction: Boolean = false ) = ArrayList(capturedValues.size + oldDeclaration.valueParameters.size).apply { val generatedNames = mutableSetOf() capturedValues.mapIndexedTo(this) { i, capturedValue -> @@ -657,7 +657,7 @@ class LocalDeclarationsLowering( origin = if (p is IrValueParameter && p.index < 0 && newDeclaration is IrConstructor) BOUND_RECEIVER_PARAMETER else BOUND_VALUE_PARAMETER - name = suggestNameForCapturedValue(p, generatedNames) + name = suggestNameForCapturedValue(p, generatedNames, isExplicitLocalFunction = isExplicitLocalFunction) index = i type = localFunctionContext.remapType(p.type) isCrossInline = (capturedValue as? IrValueParameterSymbol)?.owner?.isCrossinline == true @@ -786,7 +786,7 @@ class LocalDeclarationsLowering( private fun Name.stripSpecialMarkers(): String = if (isSpecial) asString().substring(1, asString().length - 1) else asString() - private fun suggestNameForCapturedValue(declaration: IrValueDeclaration, usedNames: MutableSet): Name { + private fun suggestNameForCapturedValue(declaration: IrValueDeclaration, usedNames: MutableSet, isExplicitLocalFunction: Boolean = false): Name { if (declaration is IrValueParameter) { if (declaration.name.asString() == "" && declaration.isDispatchReceiver()) { return findFirstUnusedName("this\$0", usedNames) { @@ -804,12 +804,21 @@ class LocalDeclarationsLowering( } } } - val base = if (declaration.name.isSpecial) + + val base = if (declaration.name.isSpecial) { declaration.name.stripSpecialMarkers() - else + } else { declaration.name.asString() - return findFirstUnusedName(base.synthesizedString, usedNames) { - "$base$$it".synthesizedString + } + + return if (isExplicitLocalFunction && declaration is IrVariable) { + findFirstUnusedName(base, usedNames) { + "$base$$it" + } + } else { + findFirstUnusedName(base.synthesizedString, usedNames) { + "$base$$it".synthesizedString + } } } diff --git a/compiler/testData/checkLocalVariablesTable/copyFunction.kt b/compiler/testData/checkLocalVariablesTable/copyFunction.kt deleted file mode 100644 index 667a6cafbbf..00000000000 --- a/compiler/testData/checkLocalVariablesTable/copyFunction.kt +++ /dev/null @@ -1,6 +0,0 @@ -data class someClass(val a: Double, val b: Double) - -// METHOD : someClass.copy(DD)LsomeClass; -// VARIABLE : NAME=this TYPE=LsomeClass; INDEX=0 -// VARIABLE : NAME=a TYPE=D INDEX=1 -// VARIABLE : NAME=b TYPE=D INDEX=3 \ No newline at end of file diff --git a/compiler/testData/checkLocalVariablesTable/destructuringInFor.kt b/compiler/testData/checkLocalVariablesTable/destructuringInFor.kt deleted file mode 100644 index c68ccef4d3f..00000000000 --- a/compiler/testData/checkLocalVariablesTable/destructuringInFor.kt +++ /dev/null @@ -1,14 +0,0 @@ -// WITH_RUNTIME - -fun box() { - val map: Map = mapOf() - for ((a, b) in map) { - a + b - } -} - -// METHOD : DestructuringInForKt.box()V - -// VARIABLE : NAME=b TYPE=Ljava/lang/String; INDEX=4 -// VARIABLE : NAME=a TYPE=Ljava/lang/String; INDEX=3 -// VARIABLE : NAME=map TYPE=Ljava/util/Map; INDEX=0 \ No newline at end of file diff --git a/compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt b/compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt deleted file mode 100644 index 2026e03abc0..00000000000 --- a/compiler/testData/checkLocalVariablesTable/destructuringInlineLambda.kt +++ /dev/null @@ -1,22 +0,0 @@ -inline fun foo(x: (Int, Station) -> Unit) { - x(1, Station(null, "", 1)) -} - -data class Station( - val id: String?, - val name: String, - val distance: Int) - -fun box(): String { - foo { i, (a1, a2, a3) -> i + a3 } - return "OK" -} - -// METHOD : DestructuringInlineLambdaKt.box()Ljava/lang/String; -// VARIABLE : NAME=a1 TYPE=Ljava/lang/String; INDEX=4 -// VARIABLE : NAME=a2 TYPE=Ljava/lang/String; INDEX=5 -// VARIABLE : NAME=a3 TYPE=I INDEX=6 -// VARIABLE : NAME=i TYPE=I INDEX=2 -// VARIABLE : NAME=$dstr$a1$a2$a3 TYPE=LStation; INDEX=1 -// VARIABLE : NAME=$i$a$-foo-DestructuringInlineLambdaKt$box$1 TYPE=I INDEX=3 -// VARIABLE : NAME=$i$f$foo TYPE=I INDEX=0 diff --git a/compiler/testData/checkLocalVariablesTable/localFun.kt b/compiler/testData/checkLocalVariablesTable/localFun.kt deleted file mode 100644 index b69677cfe1e..00000000000 --- a/compiler/testData/checkLocalVariablesTable/localFun.kt +++ /dev/null @@ -1,18 +0,0 @@ -fun foo() { - val x = 1 - fun bar() { - val y = x - } -} - -// Local function bodies are in a separate class (implementing FunctionN) for non-IR, and are static methods in the enclosing class for IR. - -// JVM_TEMPLATES -// METHOD : LocalFunKt$foo$1.invoke()V -// VARIABLE : NAME=y TYPE=I INDEX=1 -// VARIABLE : NAME=this TYPE=LLocalFunKt$foo$1; INDEX=0 - -// JVM_IR_TEMPLATES -// METHOD : LocalFunKt.foo$bar(I)V -// VARIABLE : NAME=y TYPE=I INDEX=1 -// VARIABLE : NAME=$x TYPE=I INDEX=0 diff --git a/compiler/testData/codegen/bytecodeListing/localFunction.kt b/compiler/testData/codegen/bytecodeListing/localFunction.kt new file mode 100644 index 00000000000..1be855eee20 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/localFunction.kt @@ -0,0 +1,5 @@ +fun foo() { + fun bar() { + + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/localFunction.txt b/compiler/testData/codegen/bytecodeListing/localFunction.txt new file mode 100644 index 00000000000..a071f7b3a38 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/localFunction.txt @@ -0,0 +1,18 @@ +@kotlin.Metadata +final class LocalFunctionKt$foo$1 { + // source: 'localFunction.kt' + enclosing method LocalFunctionKt.foo()V + public final static field INSTANCE: LocalFunctionKt$foo$1 + inner (anonymous) class LocalFunctionKt$foo$1 + static method (): void + method (): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +public final class LocalFunctionKt { + // source: 'localFunction.kt' + inner (anonymous) class LocalFunctionKt$foo$1 + public final static method foo(): void +} diff --git a/compiler/testData/codegen/bytecodeListing/localFunction_ir.txt b/compiler/testData/codegen/bytecodeListing/localFunction_ir.txt new file mode 100644 index 00000000000..0cc950fc7a1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/localFunction_ir.txt @@ -0,0 +1,6 @@ +@kotlin.Metadata +public final class LocalFunctionKt { + // source: 'localFunction.kt' + private final static method foo$bar(): void + public final static method foo(): void +} diff --git a/compiler/testData/debug/localVariables/destructuringInFor.kt b/compiler/testData/debug/localVariables/destructuringInFor.kt index 4d690efa9b4..82e63627456 100644 --- a/compiler/testData/debug/localVariables/destructuringInFor.kt +++ b/compiler/testData/debug/localVariables/destructuringInFor.kt @@ -1,19 +1,16 @@ + + //FILE: test.kt - -// WITH_RUNTIME - fun box() { val map: Map = mapOf("1" to "23") - for ((a, b) - in map) { + for ((a, b) in map) { a + b } } -// IGNORE_BACKEND: JVM_IR + // LOCAL VARIABLES -// test.kt:6 box: -// test.kt:8 box: map:java.util.Map=java.util.Collections$SingletonMap -// test.kt:7 box: map:java.util.Map=java.util.Collections$SingletonMap -// test.kt:9 box: map:java.util.Map=java.util.Collections$SingletonMap, a:java.lang.String="1":java.lang.String, b:java.lang.String="23":java.lang.String -// test.kt:7 box: map:java.util.Map=java.util.Collections$SingletonMap -// test.kt:11 box: map:java.util.Map=java.util.Collections$SingletonMap \ No newline at end of file +// test.kt:5 box: +// test.kt:6 box: map:java.util.Map=java.util.Collections$SingletonMap +// test.kt:7 box: map:java.util.Map=java.util.Collections$SingletonMap, a:java.lang.String="1":java.lang.String, b:java.lang.String="23":java.lang.String +// test.kt:6 box: map:java.util.Map=java.util.Collections$SingletonMap +// test.kt:9 box: map:java.util.Map=java.util.Collections$SingletonMap \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/emptyFun.kt b/compiler/testData/debug/localVariables/emptyFun.kt new file mode 100644 index 00000000000..96113cacffa --- /dev/null +++ b/compiler/testData/debug/localVariables/emptyFun.kt @@ -0,0 +1,13 @@ + + +// FILE: test.kt +fun foo() {} + +fun box() { + foo() +} + +// LOCAL VARIABLES +// test.kt:7 box: +// test.kt:4 foo: +// test.kt:8 box: \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/localFun.kt b/compiler/testData/debug/localVariables/localFun.kt index c925105848f..12816a47206 100644 --- a/compiler/testData/debug/localVariables/localFun.kt +++ b/compiler/testData/debug/localVariables/localFun.kt @@ -1,16 +1,54 @@ -//FILE: test.kt + +//FILE: test.kt fun foo() { + val x = 1 fun bar() { + val y = x } + bar() } fun box() { foo() } -// IGNORE_BACKEND: JVM_IR + +// Local functions are compiled to private static functions on the class +// containing the local funtion. This has a number of consequences observable +// from a debugging perspective, for this test specifically: +// - local functions do not figure in the LVT of the outer function, as they +// are not instantiated. +// - the _declaration_ of the local function does not figure in the byte code +// of the outer function and hence, has no line number +// - captures are treated differently, according to the implementation +// strategy: on the IR, captures are passed as arguments to the static +// function, on the old backend, they are added to fields on the lambda +// object. Hence, for debugging purposes, captures are "just" +// variables local to the function, and hence need no name mangling to +// properly figure in the debugger. + // LOCAL VARIABLES -// test.kt:9 box: -// test.kt:4 foo: -// test.kt:6 foo: $fun$bar$1:TestKt$foo$1=TestKt$foo$1 -// test.kt:10 box: \ No newline at end of file +// test.kt:13 box: +// test.kt:5 foo: + +// LOCAL VARIABLES JVM +// test.kt:6 foo: x:int=1:int + +// LOCAL VARIABLES JVM +// test.kt:9 foo: x:int=1:int, $fun$bar$1:TestKt$foo$1=TestKt$foo$1 +// LOCAL VARIABLES JVM_IR +// test.kt:9 foo: x:int=1:int + +// LOCAL VARIABLES JVM +// test.kt:7 invoke: +// test.kt:8 invoke: y:int=1:int +// LOCAL VARIABLES JVM_IR +// test.kt:7 foo$bar: x:int=1:int +// test.kt:8 foo$bar: x:int=1:int, y:int=1:int + +// LOCAL VARIABLES JVM +// test.kt:10 foo: x:int=1:int, $fun$bar$1:TestKt$foo$1=TestKt$foo$1 +// test.kt:14 box: +// LOCAL VARIABLES JVM_IR +// test.kt:10 foo: x:int=1:int +// test.kt:14 box: \ No newline at end of file diff --git a/compiler/testData/debug/localVariables/localFunUnused.kt b/compiler/testData/debug/localVariables/localFunUnused.kt new file mode 100644 index 00000000000..594a4695a32 --- /dev/null +++ b/compiler/testData/debug/localVariables/localFunUnused.kt @@ -0,0 +1,31 @@ + + +//FILE: test.kt +fun foo() { + fun bar() { + } +} + +fun box() { + foo() +} + +// Local functions are compiled to private static functions on the class +// containing the local funtion. This has a number of consequences observable +// from a debugging perspective, for this test specically: +// - local functions do not figure in the LVT of the outer function, as they +// are not instantiated. +// - the _declaration_ of the local function does not figure in the byte code +// of the outer function and hence, has no line number + +// LOCAL VARIABLES +// LOCAL VARIABLES JVM +// test.kt:10 box: +// test.kt:5 foo: +// test.kt:7 foo: $fun$bar$1:TestKt$foo$1=TestKt$foo$1 +// test.kt:11 box: + +// LOCAL VARIABLES JVM_IR +// test.kt:10 box: +// test.kt:7 foo: +// test.kt:11 box: \ No newline at end of file diff --git a/compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt b/compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt new file mode 100644 index 00000000000..3d06594087a --- /dev/null +++ b/compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt @@ -0,0 +1,25 @@ +// FILE: test.kt + +fun box() { + "OK" + fun bar() = "OK" + "OK" + bar() + "OK" +} + +// LINENUMBERS +// test.kt:4 box +// LINENUMBERS JVM +// test.kt:5 box +// LINENUMBERS +// test.kt:6 box +// test.kt:7 box +// LINENUMBERS JVM +// test.kt:5 invoke +// LINENUMBERS JVM_IR +// test.kt:5 box$bar +// LINENUMBERS +// test.kt:7 box +// test.kt:8 box +// test.kt:9 box \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index d54049b27e8..382d70c5f14 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -155,6 +155,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/kt43519.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/localFunction.kt"); + } + @TestMetadata("localFunctionInInitBlock.kt") public void testLocalFunctionInInitBlock() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java index 267f391e8fd..9c0bc844e66 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/CheckLocalVariablesTableTestGenerated.java @@ -30,26 +30,11 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/checkLocalVariablesTable"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } - @TestMetadata("copyFunction.kt") - public void testCopyFunction() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/copyFunction.kt"); - } - - @TestMetadata("destructuringInFor.kt") - public void testDestructuringInFor() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/destructuringInFor.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"); @@ -90,11 +75,6 @@ public class CheckLocalVariablesTableTestGenerated extends AbstractCheckLocalVar runTest("compiler/testData/checkLocalVariablesTable/lambdaAsVar.kt"); } - @TestMetadata("localFun.kt") - public void testLocalFun() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/localFun.kt"); - } - @TestMetadata("objectInLocalPropertyDelegate.kt") public void testObjectInLocalPropertyDelegate() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/objectInLocalPropertyDelegate.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java index 4094a1216a5..127b565293f 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrLocalVariableTestGenerated.java @@ -56,6 +56,12 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest { runTest("compiler/testData/debug/localVariables/destructuringInLambdas.kt"); } + @Test + @TestMetadata("emptyFun.kt") + public void testEmptyFun() throws Exception { + runTest("compiler/testData/debug/localVariables/emptyFun.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -74,6 +80,12 @@ public class IrLocalVariableTestGenerated extends AbstractIrLocalVariableTest { runTest("compiler/testData/debug/localVariables/localFun.kt"); } + @Test + @TestMetadata("localFunUnused.kt") + public void testLocalFunUnused() throws Exception { + runTest("compiler/testData/debug/localVariables/localFunUnused.kt"); + } + @Test @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java index 26c4c084cf6..3f4c484da59 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/IrSteppingTestGenerated.java @@ -266,6 +266,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest { runTest("compiler/testData/debug/stepping/localFunction.kt"); } + @Test + @TestMetadata("localFunctionWIthOnelineExpressionBody.kt") + public void testLocalFunctionWIthOnelineExpressionBody() throws Exception { + runTest("compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt"); + } + @Test @TestMetadata("multilineFunctionCall.kt") public void testMultilineFunctionCall() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java index f2d72bf62ae..dc9082c975d 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/LocalVariableTestGenerated.java @@ -56,6 +56,12 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { runTest("compiler/testData/debug/localVariables/destructuringInLambdas.kt"); } + @Test + @TestMetadata("emptyFun.kt") + public void testEmptyFun() throws Exception { + runTest("compiler/testData/debug/localVariables/emptyFun.kt"); + } + @Test @TestMetadata("inlineProperty.kt") public void testInlineProperty() throws Exception { @@ -74,6 +80,12 @@ public class LocalVariableTestGenerated extends AbstractLocalVariableTest { runTest("compiler/testData/debug/localVariables/localFun.kt"); } + @Test + @TestMetadata("localFunUnused.kt") + public void testLocalFunUnused() throws Exception { + runTest("compiler/testData/debug/localVariables/localFunUnused.kt"); + } + @Test @TestMetadata("underscoreNames.kt") public void testUnderscoreNames() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java index 648c92c215e..eacf41515d0 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/debugInformation/SteppingTestGenerated.java @@ -266,6 +266,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest { runTest("compiler/testData/debug/stepping/localFunction.kt"); } + @Test + @TestMetadata("localFunctionWIthOnelineExpressionBody.kt") + public void testLocalFunctionWIthOnelineExpressionBody() throws Exception { + runTest("compiler/testData/debug/stepping/localFunctionWIthOnelineExpressionBody.kt"); + } + @Test @TestMetadata("multilineFunctionCall.kt") public void testMultilineFunctionCall() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index e1e072ffb74..d9e1a3e75aa 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -155,6 +155,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/kt43519.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/localFunction.kt"); + } + @TestMetadata("localFunctionInInitBlock.kt") public void testLocalFunctionInInitBlock() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/localFunctionInInitBlock.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java index d26c883b88e..dca584a14d3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCheckLocalVariablesTableTestGenerated.java @@ -30,26 +30,11 @@ public class IrCheckLocalVariablesTableTestGenerated extends AbstractIrCheckLoca KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/checkLocalVariablesTable"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } - @TestMetadata("copyFunction.kt") - public void testCopyFunction() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/copyFunction.kt"); - } - - @TestMetadata("destructuringInFor.kt") - public void testDestructuringInFor() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/destructuringInFor.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"); @@ -90,11 +75,6 @@ public class IrCheckLocalVariablesTableTestGenerated extends AbstractIrCheckLoca runTest("compiler/testData/checkLocalVariablesTable/lambdaAsVar.kt"); } - @TestMetadata("localFun.kt") - public void testLocalFun() throws Exception { - runTest("compiler/testData/checkLocalVariablesTable/localFun.kt"); - } - @TestMetadata("objectInLocalPropertyDelegate.kt") public void testObjectInLocalPropertyDelegate() throws Exception { runTest("compiler/testData/checkLocalVariablesTable/objectInLocalPropertyDelegate.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java index 31b25014a26..6e643a5f381 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinEvaluateExpressionTestGenerated.java @@ -337,6 +337,11 @@ public class IrKotlinEvaluateExpressionTestGenerated extends AbstractIrKotlinEva runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localClass.kt"); } + @TestMetadata("localFunctionCapturedLocalVariable.kt") + public void testLocalFunctionCapturedLocalVariable() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt"); + } + @TestMetadata("localFunctionsWithReceivers.kt") public void testLocalFunctionsWithReceivers() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionsWithReceivers.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java index 6b39eec53a2..6ac4bf55172 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/IrKotlinSteppingTestGenerated.java @@ -503,6 +503,16 @@ public class IrKotlinSteppingTestGenerated extends AbstractIrKotlinSteppingTest runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/lambdaToInlineMapFiltersDisabled.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt"); + } + + @TestMetadata("localFunctionWithSingleLineExpressionBody.kt") + public void testLocalFunctionWithSingleLineExpressionBody() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt"); + } + @TestMetadata("noParameterExtensionLambdaArgumentCallInInline.kt") public void testNoParameterExtensionLambdaArgumentCallInInline() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/noParameterExtensionLambdaArgumentCallInInline.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java index a0ff77b097c..49c8b3c954b 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinEvaluateExpressionTestGenerated.java @@ -336,6 +336,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localClass.kt"); } + @TestMetadata("localFunctionCapturedLocalVariable.kt") + public void testLocalFunctionCapturedLocalVariable() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt"); + } + @TestMetadata("localFunctionsWithReceivers.kt") public void testLocalFunctionsWithReceivers() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionsWithReceivers.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java index 60e08be64e6..1fce43faee8 100644 --- a/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java +++ b/idea/jvm-debugger/jvm-debugger-test/test/org/jetbrains/kotlin/idea/debugger/test/KotlinSteppingTestGenerated.java @@ -503,6 +503,16 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest { runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/lambdaToInlineMapFiltersDisabled.kt"); } + @TestMetadata("localFunction.kt") + public void testLocalFunction() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt"); + } + + @TestMetadata("localFunctionWithSingleLineExpressionBody.kt") + public void testLocalFunctionWithSingleLineExpressionBody() throws Exception { + runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt"); + } + @TestMetadata("noParameterExtensionLambdaArgumentCallInInline.kt") public void testNoParameterExtensionLambdaArgumentCallInInline() throws Exception { runTest("idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/noParameterExtensionLambdaArgumentCallInInline.kt"); diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt new file mode 100644 index 00000000000..a0b11dd2ddb --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.kt @@ -0,0 +1,13 @@ +package localFunctionCapturedLocalVariable + +fun main(args: Array) { + val a = 1 + fun local() { + //Breakpoint! + val x = a + 2 + } + local() +} + +// EXPRESSION: a +// RESULT: 1: I diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.out b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.out new file mode 100644 index 00000000000..691ea28030f --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/evaluation/singleBreakpoint/localFunctionCapturedLocalVariable.out @@ -0,0 +1,8 @@ +LineBreakpoint created at localFunctionCapturedLocalVariable.kt:7 +Run Java +Connected to the target VM +localFunctionCapturedLocalVariable.kt:7 +Compile bytecode for a +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.ir.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.ir.out new file mode 100644 index 00000000000..caafbbb6392 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.ir.out @@ -0,0 +1,6 @@ +LineBreakpoint created at localFunction.kt:5 +Run Java +Connected to the target VM +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt new file mode 100644 index 00000000000..b50621e97a3 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.kt @@ -0,0 +1,12 @@ +package localFunction + +fun main() { + //Breakpoint! + fun bar() { + "OK" + } + bar() +} + +// STEP_OVER: 1 +// Code compiled on the IR cannot break on local function declarations \ No newline at end of file diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.out new file mode 100644 index 00000000000..13aac9ff50a --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunction.out @@ -0,0 +1,8 @@ +LineBreakpoint created at localFunction.kt:5 +Run Java +Connected to the target VM +localFunction.kt:5 +localFunction.kt:8 +Disconnected from the target VM + +Process finished with exit code 0 diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.ir.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.ir.out new file mode 100644 index 00000000000..1ce6d75cc17 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.ir.out @@ -0,0 +1,9 @@ +LineBreakpoint created at localFunctionWithSingleLineExpressionBody.kt:5 +Run Java +Connected to the target VM +localFunctionWithSingleLineExpressionBody.kt:5 +localFunctionWithSingleLineExpressionBody.kt:7 +Disconnected from the target VM + +Process finished with exit code 0 + diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt new file mode 100644 index 00000000000..92dd8e98f50 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.kt @@ -0,0 +1,13 @@ +package localFunctionWithSingleLineExpressionBody + +fun main() { + //Breakpoint! + fun bar() = "OK" + val x = 1 + bar() +} + +// STEP_OVER: 1 +// The behavior of the two backends is different because they stop at two different instructions. +// - The JVM backend stops on the declaration of bar on main:5, so stepping over proceeds to main:6 +// - The IR backend stops on the _body_ of bar when called from main:7, so proceeds to main:7 \ No newline at end of file diff --git a/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.out b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.out new file mode 100644 index 00000000000..64c08d8fe31 --- /dev/null +++ b/idea/jvm-debugger/jvm-debugger-test/testData/stepping/stepOver/localFunctionWithSingleLineExpressionBody.out @@ -0,0 +1,10 @@ +LineBreakpoint created at localFunctionWithSingleLineExpressionBody.kt:5 +Run Java +Connected to the target VM +localFunctionWithSingleLineExpressionBody.kt:5 +localFunctionWithSingleLineExpressionBody.kt:6 +resuming localFunctionWithSingleLineExpressionBody.kt:5 +Disconnected from the target VM + +Process finished with exit code 0 + From 0e3aaceb16d204c3fc7bd54e72a4ba99ebfa7606 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Mon, 11 Jan 2021 18:04:21 +0300 Subject: [PATCH 021/197] Fix ultra light structure for @JvmRecord classes --- .../kotlin/asJava/classes/ultraLightClass.kt | 6 ++-- .../classes/ultraLightMembersCreator.kt | 5 +-- .../asJava/ultraLightClasses/jvmRecord.java | 24 ++++++++++++++ .../asJava/ultraLightClasses/jvmRecord.kt | 8 +++++ .../classes/FirClassLoadingTestGenerated.java | 5 +++ .../KotlinLightCodeInsightFixtureTestCase.kt | 5 ++- .../AbstractUltraLightClassLoadingTest.kt | 31 ++++++++++--------- .../UltraLightClassLoadingTestGenerated.java | 5 +++ 8 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 compiler/testData/asJava/ultraLightClasses/jvmRecord.java create mode 100644 compiler/testData/asJava/ultraLightClasses/jvmRecord.kt diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt index c870ac26212..e4d57f63012 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME +import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_RECORD_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny @@ -282,7 +283,8 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor parameter.isMutable, forceStatic = false, onlyJvmStatic = false, - createAsAnnotationMethod = isAnnotationType + createAsAnnotationMethod = isAnnotationType, + isJvmRecord = classOrObject.hasAnnotation(JVM_RECORD_ANNOTATION_FQ_NAME), ) ) } @@ -509,4 +511,4 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor return super.getTextRange() } -} \ No newline at end of file +} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt index 8952b5394ac..f75639c9810 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightMembersCreator.kt @@ -405,7 +405,8 @@ internal class UltraLightMembersCreator( mutable: Boolean, forceStatic: Boolean, onlyJvmStatic: Boolean, - createAsAnnotationMethod: Boolean = false + createAsAnnotationMethod: Boolean = false, + isJvmRecord: Boolean = false, ): List { val propertyName = declaration.name ?: return emptyList() @@ -454,7 +455,7 @@ internal class UltraLightMembersCreator( auxiliaryOriginalElement = auxiliaryOrigin ) - val defaultGetterName = if (createAsAnnotationMethod) propertyName else JvmAbi.getterName(propertyName) + val defaultGetterName = if (createAsAnnotationMethod || isJvmRecord) propertyName else JvmAbi.getterName(propertyName) val getterName = computeMethodName(auxiliaryOrigin, defaultGetterName, MethodType.GETTER) val getterPrototype = lightMethod(getterName, auxiliaryOrigin, forceStatic = onlyJvmStatic || forceStatic) val getterWrapper = KtUltraLightMethodForSourceDeclaration( diff --git a/compiler/testData/asJava/ultraLightClasses/jvmRecord.java b/compiler/testData/asJava/ultraLightClasses/jvmRecord.java new file mode 100644 index 00000000000..26459b28e6f --- /dev/null +++ b/compiler/testData/asJava/ultraLightClasses/jvmRecord.java @@ -0,0 +1,24 @@ +@kotlin.jvm.JvmRecord() +public final class MyRec /* pkg.MyRec*/ { + @org.jetbrains.annotations.NotNull() + private final java.lang.String name; + + @org.jetbrains.annotations.NotNull() + public final java.lang.String component1();// component1() + + @org.jetbrains.annotations.NotNull() + public final java.lang.String name();// name() + + @org.jetbrains.annotations.NotNull() + public final pkg.MyRec copy(@org.jetbrains.annotations.NotNull() java.lang.String);// copy(java.lang.String) + + @org.jetbrains.annotations.NotNull() + public java.lang.String toString();// toString() + + public MyRec(@org.jetbrains.annotations.NotNull() java.lang.String);// .ctor(java.lang.String) + + public boolean equals(@org.jetbrains.annotations.Nullable() java.lang.Object);// equals(java.lang.Object) + + public int hashCode();// hashCode() + +} diff --git a/compiler/testData/asJava/ultraLightClasses/jvmRecord.kt b/compiler/testData/asJava/ultraLightClasses/jvmRecord.kt new file mode 100644 index 00000000000..d7a04af2228 --- /dev/null +++ b/compiler/testData/asJava/ultraLightClasses/jvmRecord.kt @@ -0,0 +1,8 @@ +// CHECK_BY_JAVA_FILE +// API_VERSION: 1.5 +// JVM_TARGET: 15 +// COMPILER_ARGUMENTS: -XXLanguage:+JvmRecordSupport -Xjvm-enable-preview +package pkg + +@JvmRecord +data class MyRec(val name: String) diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/asJava/classes/FirClassLoadingTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/asJava/classes/FirClassLoadingTestGenerated.java index 7b94904f4a7..f76176205ec 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/asJava/classes/FirClassLoadingTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/asJava/classes/FirClassLoadingTestGenerated.java @@ -134,6 +134,11 @@ public class FirClassLoadingTestGenerated extends AbstractFirClassLoadingTest { runTest("compiler/testData/asJava/ultraLightClasses/jvmOverloads.kt"); } + @TestMetadata("jvmRecord.kt") + public void testJvmRecord() throws Exception { + runTest("compiler/testData/asJava/ultraLightClasses/jvmRecord.kt"); + } + @TestMetadata("jvmSynthetic.kt") public void testJvmSynthetic() throws Exception { runTest("compiler/testData/asJava/ultraLightClasses/jvmSynthetic.kt"); diff --git a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt index cb376751591..bfb2894acee 100644 --- a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt +++ b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt @@ -46,6 +46,7 @@ import org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.COMPILER_ARGUMENTS_DIRECTIVE import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.JVM_TARGET_DIRECTIVE import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.LANGUAGE_VERSION_DIRECTIVE +import org.jetbrains.kotlin.idea.test.CompilerTestDirectives.API_VERSION_DIRECTIVE import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils @@ -245,6 +246,7 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix object CompilerTestDirectives { const val LANGUAGE_VERSION_DIRECTIVE = "LANGUAGE_VERSION:" + const val API_VERSION_DIRECTIVE = "API_VERSION:" const val JVM_TARGET_DIRECTIVE = "JVM_TARGET:" const val COMPILER_ARGUMENTS_DIRECTIVE = "COMPILER_ARGUMENTS:" @@ -265,6 +267,7 @@ fun withCustomCompilerOptions(fileText: String, project: Project, module: Mo private fun configureCompilerOptions(fileText: String, project: Project, module: Module): Boolean { val version = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $LANGUAGE_VERSION_DIRECTIVE ") + val apiVersion = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $API_VERSION_DIRECTIVE ") val jvmTarget = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// $JVM_TARGET_DIRECTIVE ") // We can have several such directives in quickFixMultiFile tests // TODO: refactor such tests or add sophisticated check for the directive @@ -274,7 +277,7 @@ private fun configureCompilerOptions(fileText: String, project: Project, module: configureLanguageAndApiVersion( project, module, version ?: LanguageVersion.LATEST_STABLE.versionString, - null + apiVersion ) val facetSettings = KotlinFacet.get(module)!!.configuration.settings diff --git a/idea/tests/org/jetbrains/kotlin/asJava/classes/AbstractUltraLightClassLoadingTest.kt b/idea/tests/org/jetbrains/kotlin/asJava/classes/AbstractUltraLightClassLoadingTest.kt index debe8714cdf..fb050f385a8 100644 --- a/idea/tests/org/jetbrains/kotlin/asJava/classes/AbstractUltraLightClassLoadingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/asJava/classes/AbstractUltraLightClassLoadingTest.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.idea.perf.UltraLightChecker.checkByJavaFile import org.jetbrains.kotlin.idea.perf.UltraLightChecker.checkDescriptorsLeak import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.idea.test.withCustomCompilerOptions import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils @@ -24,24 +25,26 @@ abstract class AbstractUltraLightClassLoadingTest : KotlinLightCodeInsightFixtur open fun doTest(testDataPath: String) { val sourceText = File(testDataPath).readText() - val file = myFixture.addFileToProject(testDataPath, sourceText) as KtFile + withCustomCompilerOptions(sourceText, project, module) { + val file = myFixture.addFileToProject(testDataPath, sourceText) as KtFile - UltraLightChecker.checkForReleaseCoroutine(sourceText, module) + UltraLightChecker.checkForReleaseCoroutine(sourceText, module) - val checkByJavaFile = InTextDirectivesUtils.isDirectiveDefined(sourceText, "CHECK_BY_JAVA_FILE") + val checkByJavaFile = InTextDirectivesUtils.isDirectiveDefined(sourceText, "CHECK_BY_JAVA_FILE") - val ktClassOrObjects = UltraLightChecker.allClasses(file) + val ktClassOrObjects = UltraLightChecker.allClasses(file) - if (checkByJavaFile) { - val classFabric = LightClassGenerationSupport.getInstance(project) - val classList = ktClassOrObjects.mapNotNull { classFabric.createUltraLightClass(it) } - checkByJavaFile(testDataPath, classList) - classList.forEach { checkDescriptorsLeak(it) } - } else { - for (ktClass in ktClassOrObjects) { - val ultraLightClass = UltraLightChecker.checkClassEquivalence(ktClass) - if (ultraLightClass != null) { - checkDescriptorsLeak(ultraLightClass) + if (checkByJavaFile) { + val classFabric = LightClassGenerationSupport.getInstance(project) + val classList = ktClassOrObjects.mapNotNull { classFabric.createUltraLightClass(it) } + checkByJavaFile(testDataPath, classList) + classList.forEach { checkDescriptorsLeak(it) } + } else { + for (ktClass in ktClassOrObjects) { + val ultraLightClass = UltraLightChecker.checkClassEquivalence(ktClass) + if (ultraLightClass != null) { + checkDescriptorsLeak(ultraLightClass) + } } } } diff --git a/idea/tests/org/jetbrains/kotlin/asJava/classes/UltraLightClassLoadingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/asJava/classes/UltraLightClassLoadingTestGenerated.java index b5ad2192456..092946c7d3d 100644 --- a/idea/tests/org/jetbrains/kotlin/asJava/classes/UltraLightClassLoadingTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/asJava/classes/UltraLightClassLoadingTestGenerated.java @@ -134,6 +134,11 @@ public class UltraLightClassLoadingTestGenerated extends AbstractUltraLightClass runTest("compiler/testData/asJava/ultraLightClasses/jvmOverloads.kt"); } + @TestMetadata("jvmRecord.kt") + public void testJvmRecord() throws Exception { + runTest("compiler/testData/asJava/ultraLightClasses/jvmRecord.kt"); + } + @TestMetadata("jvmSynthetic.kt") public void testJvmSynthetic() throws Exception { runTest("compiler/testData/asJava/ultraLightClasses/jvmSynthetic.kt"); From bd708da82ca00082a549468d72d85500ef8c0b00 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Mon, 11 Jan 2021 19:50:22 +0100 Subject: [PATCH 022/197] Do not check script discovery file extension it is optional (so far), so this check was incorrect. #KT-44117 fixed --- .../kotlin/idea/script/ScriptTemplatesClassRootsIndex.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/script/ScriptTemplatesClassRootsIndex.kt b/idea/src/org/jetbrains/kotlin/idea/script/ScriptTemplatesClassRootsIndex.kt index 5381f3fc4cb..090fa264b22 100644 --- a/idea/src/org/jetbrains/kotlin/idea/script/ScriptTemplatesClassRootsIndex.kt +++ b/idea/src/org/jetbrains/kotlin/idea/script/ScriptTemplatesClassRootsIndex.kt @@ -50,6 +50,5 @@ class ScriptTemplatesClassRootsIndex : val parent = file.parent ?: return false return parent.isDirectory && parent.path.endsWith(suffix) - && file.path.endsWith(SCRIPT_DEFINITION_MARKERS_EXTENSION_WITH_DOT) } } \ No newline at end of file From f6187632505b9f6f177e9850cdbf7e0bb19a7d2a Mon Sep 17 00:00:00 2001 From: pyos Date: Thu, 7 Jan 2021 14:25:24 +0100 Subject: [PATCH 023/197] FIR: implement -Xfriend-paths --- .../compiler/KotlinToJVMBytecodeCompiler.kt | 2 +- .../fir/session/ComponentsContainers.kt | 1 + .../kotlin/fir/session/FirJvmModuleInfo.kt | 18 ++++++--- .../session/FirJvmModuleVisibilityChecker.kt | 39 +++++++++++++++++++ .../deserialization/FirMemberDeserializer.kt | 1 + .../kotlin/fir/FirVisibilityChecker.kt | 10 +++-- .../fir/declarations/FirDeclarationUtil.kt | 7 ++++ .../internalFromFriendModuleFir/library/a.kt | 15 +++++++ .../internalFromFriendModuleFir/output.txt | 1 + .../internalFromFriendModuleFir/source.kt | 10 +++++ .../frontend/fir/FirModuleInfoProvider.kt | 7 +--- .../CompileKotlinAgainstCustomBinariesTest.kt | 5 +++ 12 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleVisibilityChecker.kt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/library/a.kt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/output.txt create mode 100644 compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/source.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 6087fdd8f86..625581cdb7a 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -328,7 +328,7 @@ object KotlinToJVMBytecodeCompiler { project, environment.createPackagePartProvider(librariesScope) ) - val moduleInfo = FirJvmModuleInfo(module.getModuleName(), listOf(librariesModuleInfo)) + val moduleInfo = FirJvmModuleInfo(module, listOf(librariesModuleInfo)) val session = FirSessionFactory.createJavaModuleBasedSession(moduleInfo, provider, scope, project) { if (extendedAnalysisMode) { registerExtendedCommonCheckers() diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt index f80acef9c82..b4ab7cfed61 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt @@ -58,6 +58,7 @@ fun FirSession.registerResolveComponents() { @OptIn(SessionConfiguration::class) fun FirSession.registerJavaSpecificResolveComponents() { register(FirVisibilityChecker::class, FirJavaVisibilityChecker) + register(FirModuleVisibilityChecker::class, FirJvmModuleVisibilityChecker(this)) register(ConeCallConflictResolverFactory::class, JvmCallConflictResolverFactory) register(FirEffectiveVisibilityResolver::class, FirJvmEffectiveVisibilityResolver(this)) register(FirPlatformClassMapper::class, FirJavaClassMapper(this)) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleInfo.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleInfo.kt index e342b7f50e3..83a709cce48 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleInfo.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleInfo.kt @@ -6,23 +6,30 @@ package org.jetbrains.kotlin.fir.session import org.jetbrains.kotlin.analyzer.ModuleInfo +import org.jetbrains.kotlin.modules.Module import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices -class FirJvmModuleInfo(override val name: Name, val dependencies: List) : ModuleInfo { +class FirJvmModuleInfo( + override val name: Name, + val dependencies: List = emptyList(), + val friendPaths: List = emptyList(), + val outputDirectory: String? = null +) : ModuleInfo { companion object { val LIBRARIES_MODULE_NAME = Name.special("") fun createForLibraries(mainModuleName: String? = null): FirJvmModuleInfo { val name = mainModuleName?.let { Name.special("") } ?: LIBRARIES_MODULE_NAME - return FirJvmModuleInfo(name, emptyList()) + return FirJvmModuleInfo(name) } } - constructor(moduleName: String, dependencies: List) : this(Name.identifier(moduleName), dependencies) + constructor(module: Module, dependencies: List) : + this(Name.identifier(module.getModuleName()), dependencies, module.getFriendPaths(), module.getOutputDirectory()) override val platform: TargetPlatform get() = JvmPlatforms.unspecifiedJvmPlatform @@ -30,7 +37,6 @@ class FirJvmModuleInfo(override val name: Name, val dependencies: List { - return dependencies - } + override fun dependencies(): List = + dependencies } diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleVisibilityChecker.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleVisibilityChecker.kt new file mode 100644 index 00000000000..82392c7b648 --- /dev/null +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmModuleVisibilityChecker.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.fir.session + +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.openapi.vfs.VfsUtilCore +import org.jetbrains.kotlin.fir.FirModuleVisibilityChecker +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.containerSource +import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource +import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement +import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass +import java.nio.file.Paths + +class FirJvmModuleVisibilityChecker(private val session: FirSession) : FirModuleVisibilityChecker { + override fun isInFriendModule(declaration: FirMemberDeclaration): Boolean { + val moduleInfo = session.moduleInfo as? FirJvmModuleInfo ?: return false + val binaryClass = when (val source = declaration.containerSource) { + is KotlinJvmBinarySourceElement -> source.binaryClass + is JvmPackagePartSource -> source.knownJvmBinaryClass + else -> null + } as? VirtualFileKotlinClass ?: return false + // For incremental compilation, the already compiled part of the module should be accessible. + return moduleInfo.friendPaths.any { binaryClass.isIn(it) } || moduleInfo.outputDirectory?.let { binaryClass.isIn(it) } == true + } + + private fun VirtualFileKotlinClass.isIn(jarOrDirectory: String): Boolean = + when (file.fileSystem.protocol) { + StandardFileSystems.FILE_PROTOCOL -> + VfsUtilCore.virtualToIoFile(file).toPath().startsWith(jarOrDirectory) + StandardFileSystems.JAR_PROTOCOL -> + VfsUtilCore.getVirtualFileForJar(file)?.let(VfsUtilCore::virtualToIoFile)?.toPath() == Paths.get(jarOrDirectory) + else -> false + } +} diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index ac5d59a33cd..82ad9989de7 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -449,6 +449,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { ) annotations += c.annotationDeserializer.loadConstructorAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) + containerSource = c.containerSource }.build().apply { containingClassAttr = c.dispatchReceiver!!.lookupTag versionRequirementsTable = c.versionRequirementTable diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt index 542cb938d3d..719f95c1c95 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -22,6 +22,10 @@ import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName +interface FirModuleVisibilityChecker : FirSessionComponent { + fun isInFriendModule(declaration: FirMemberDeclaration): Boolean +} + abstract class FirVisibilityChecker : FirSessionComponent { @NoMutableState object Default : FirVisibilityChecker() { @@ -54,14 +58,13 @@ abstract class FirVisibilityChecker : FirSessionComponent { val session = callInfo.session val provider = session.firProvider - return when (declaration.visibility) { Visibilities.Internal -> { - declaration.session == callInfo.session + declaration.session == session || session.moduleVisibilityChecker?.isInFriendModule(declaration) == true } Visibilities.Private, Visibilities.PrivateToThis -> { val ownerId = symbol.getOwnerId() - if (declaration.session == callInfo.session) { + if (declaration.session == session) { if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) { val candidateFile = when (symbol) { is FirClassLikeSymbol<*> -> provider.getFirClassifierContainerFileIfAny(symbol) @@ -194,6 +197,7 @@ abstract class FirVisibilityChecker : FirSessionComponent { } } +val FirSession.moduleVisibilityChecker: FirModuleVisibilityChecker? by FirSession.nullableSessionComponentAccessor() val FirSession.visibilityChecker: FirVisibilityChecker by FirSession.sessionComponentAccessor() fun AbstractFirBasedSymbol<*>.getOwnerId(): ClassId? { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt index b0802632424..7982410414e 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt @@ -132,6 +132,13 @@ fun FirRegularClass.addDeclaration(declaration: FirDeclaration) { private object SourceElementKey : FirDeclarationDataKey() var FirRegularClass.sourceElement: SourceElement? by FirDeclarationDataRegistry.data(SourceElementKey) +val FirMemberDeclaration.containerSource: SourceElement? + get() = when (this) { + is FirCallableMemberDeclaration<*> -> containerSource + is FirRegularClass -> sourceElement + else -> null + } + private object IsFromVarargKey : FirDeclarationDataKey() var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey) private object IsReferredViaField : FirDeclarationDataKey() diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/library/a.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/library/a.kt new file mode 100644 index 00000000000..0aba9878eca --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/library/a.kt @@ -0,0 +1,15 @@ +package a + +internal interface InternalInterface + +public class PublicClass internal constructor() { + internal fun internalMemberFun() {} + + internal companion object {} +} + +internal val internalVal = "" + +internal fun internalFun(s: String): String = s + +internal typealias InternalTypealias = InternalInterface diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/output.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/output.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/source.kt new file mode 100644 index 00000000000..5e872880a78 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/internalFromFriendModuleFir/source.kt @@ -0,0 +1,10 @@ +import a.* + +private fun test(i: InternalInterface): InternalTypealias { + PublicClass().internalMemberFun() + PublicClass.Companion + + internalFun(internalVal) + + return i +} diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirModuleInfoProvider.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirModuleInfoProvider.kt index 2b2fd88df6f..b41a7763cf0 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirModuleInfoProvider.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/FirModuleInfoProvider.kt @@ -27,16 +27,13 @@ class FirModuleInfoProvider( module.dependencies.mapTo(dependencies) { convertToFirModuleInfo(testServices.dependencyProvider.getTestModule(it.moduleName)) } - FirJvmModuleInfo( - module.name, - dependencies - ) + FirJvmModuleInfo(Name.identifier(module.name), dependencies) } } fun builtinsModuleInfoForModule(module: TestModule): FirJvmModuleInfo { return builtinsByModule.getOrPut(module) { - FirJvmModuleInfo(Name.special(""), emptyList()) + FirJvmModuleInfo(Name.special("")) } } } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index f6c05bc2bea..d49f6840d2f 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -626,6 +626,11 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xfriend-paths=${library.path}")) } + fun testInternalFromFriendModuleFir() { + val library = compileLibrary("library") + compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-Xfriend-paths=${library.path}", "-Xuse-fir")) + } + fun testJvmDefaultClashWithOld() { val library = compileLibrary("library", additionalOptions = listOf("-Xjvm-default=disable")) compileKotlin("source.kt", tmpdir, listOf(library), additionalOptions = listOf("-jvm-target", "1.8", "-Xjvm-default=all")) From d53354057a57ef1d33c8e308672527bd6c5385f2 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Mon, 4 Jan 2021 13:25:03 -0800 Subject: [PATCH 024/197] FIR: build functional type for SAM with receiver properly --- .../resolve/inference/extensionCallableReferences.fir.txt | 2 +- .../resolve/references/referenceToExtension.fir.txt | 6 +++--- .../moreSpecificAmbiguousExtensions.fir.txt | 2 +- .../src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt | 1 + .../src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt | 8 +++++++- .../src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt | 3 ++- .../jetbrains/kotlin/fir/types/ConeInferenceContext.kt | 2 +- .../codegen/box/funInterface/funInterfaceWithReceiver.kt | 1 - 8 files changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.fir.txt b/compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.fir.txt index 3482c040eaa..822511f8efd 100644 --- a/compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/inference/extensionCallableReferences.fir.txt @@ -27,5 +27,5 @@ FILE: extensionCallableReferences.kt } public final fun test_1(): R|kotlin/Unit| { lval extensionValRef: R|kotlin/reflect/KProperty1| = Q|B|::R|/extensionVal| - lval extensionFunRef: R|kotlin/reflect/KFunction1| = Q|B|::R|/extensionFun| + lval extensionFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1| = Q|B|::R|/extensionFun| } diff --git a/compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.fir.txt b/compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.fir.txt index 7245b85dce5..4f827884899 100644 --- a/compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/references/referenceToExtension.fir.txt @@ -36,7 +36,7 @@ FILE: referenceToExtension.kt public final fun test_1(): R|kotlin/Unit| { lval memberValRef: R|kotlin/reflect/KProperty1, GenericTest.A>| = Q|GenericTest.B|::R|SubstitutionOverride|>| - lval memberFunRef: R|kotlin/reflect/KFunction1, GenericTest.A>| = Q|GenericTest.B|::R|SubstitutionOverride|>| + lval memberFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1, GenericTest.A>| = Q|GenericTest.B|::R|SubstitutionOverride|>| } public final fun test_2(): R|kotlin/Unit| { @@ -82,12 +82,12 @@ FILE: referenceToExtension.kt public final fun test_1(): R|kotlin/Unit| { lval extensionValRef: R|kotlin/reflect/KProperty1| = Q|NoGenericTest.B|::R|/NoGenericTest.extensionVal| - lval extensionFunRef: R|kotlin/reflect/KFunction1| = Q|NoGenericTest.B|::R|/NoGenericTest.extensionFun| + lval extensionFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1| = Q|NoGenericTest.B|::R|/NoGenericTest.extensionFun| } public final fun test_2(): R|kotlin/Unit| { lval memberValRef: R|kotlin/reflect/KProperty1| = Q|NoGenericTest.B|::R|/NoGenericTest.B.memberVal| - lval memberFunRef: R|kotlin/reflect/KFunction1| = Q|NoGenericTest.B|::R|/NoGenericTest.B.memberFun| + lval memberFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1| = Q|NoGenericTest.B|::R|/NoGenericTest.B.memberFun| } } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/fromBasicDiagnosticTests/moreSpecificAmbiguousExtensions.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/fromBasicDiagnosticTests/moreSpecificAmbiguousExtensions.fir.txt index 8bcf37726bb..8365898a4b8 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/fromBasicDiagnosticTests/moreSpecificAmbiguousExtensions.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/callableReferences/fromBasicDiagnosticTests/moreSpecificAmbiguousExtensions.fir.txt @@ -8,7 +8,7 @@ FILE: moreSpecificAmbiguousExtensions.kt public final fun R|IB|.extFun(x: R|IA|): R|kotlin/Unit| { } public final fun test(): R|kotlin/Unit| { - lval extFun1: R|kotlin/reflect/KFunction2| = Q|IA|::R|/extFun| + lval extFun1: R|@ExtensionFunctionType kotlin/reflect/KFunction2| = Q|IA|::R|/extFun| lval extFun2: = Q|IB|::# } public final fun testWithExpectedType(): R|kotlin/Unit| { diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt index c8a0341d8d1..378fb5d1b76 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt @@ -34,6 +34,7 @@ class ConeAttributes private constructor(attributes: List>) : A } val Empty: ConeAttributes = ConeAttributes(emptyList()) + val WithExtensionFunctionType: ConeAttributes = ConeAttributes(listOf(CompilerConeAttributes.ExtensionFunctionType)) internal val WithFlexibleNullability: ConeAttributes = ConeAttributes(listOf(CompilerConeAttributes.FlexibleNullability)) fun create(attributes: List>): ConeAttributes { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index fe2be9fac2b..eb7923544b8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -78,7 +78,13 @@ fun createFunctionalType( } val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(receiverAndParameterTypes.size - 1)) - return ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(functionalTypeId), receiverAndParameterTypes.toTypedArray(), isNullable = false) + val attributes = if (receiverType != null) ConeAttributes.WithExtensionFunctionType else ConeAttributes.Empty + return ConeClassLikeTypeImpl( + ConeClassLikeLookupTagImpl(functionalTypeId), + receiverAndParameterTypes.toTypedArray(), + isNullable = false, + attributes = attributes + ) } fun createKPropertyType( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt index ed9ea28cca3..d53b24c2d44 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt @@ -346,7 +346,8 @@ private fun FirSimpleFunction.getFunctionTypeForAbstractMethod(): ConeLookupTagB } return createFunctionalType( - parameterTypes, receiverType = null, + parameterTypes, + receiverType = receiverTypeRef?.coneType, rawReturnType = returnTypeRef.coneType, isSuspend = this.isSuspend ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index 71ab78fc4c2..8b24fb9e583 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -61,7 +61,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo isExtensionFunction: Boolean ): SimpleTypeMarker { val attributes = if (isExtensionFunction) // TODO: assert correct type constructor - ConeAttributes.create(listOf(CompilerConeAttributes.ExtensionFunctionType)) + ConeAttributes.WithExtensionFunctionType else ConeAttributes.Empty @Suppress("UNCHECKED_CAST") return when (constructor) { diff --git a/compiler/testData/codegen/box/funInterface/funInterfaceWithReceiver.kt b/compiler/testData/codegen/box/funInterface/funInterfaceWithReceiver.kt index 80d36d9821f..5bcc2a5cb15 100644 --- a/compiler/testData/codegen/box/funInterface/funInterfaceWithReceiver.kt +++ b/compiler/testData/codegen/box/funInterface/funInterfaceWithReceiver.kt @@ -1,6 +1,5 @@ // DONT_TARGET_EXACT_BACKEND: WASM // WASM_MUTE_REASON: SAM_CONVERSIONS -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR_ES6 fun interface FunWithReceiver { From 032c64669cd678cc84d85c987d6fa6bb5f1b0640 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Tue, 12 Jan 2021 08:56:36 +0300 Subject: [PATCH 025/197] Show pre-released 1.5 version in configuration preferences ^KT-44116 Fixed --- .../org/jetbrains/kotlin/config/LanguageVersionSettings.kt | 3 +++ .../kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt | 3 ++- .../jetbrains/kotlin/idea/maven/MavenCompletionProviders.kt | 5 +++-- .../configuration/KotlinCompilerConfigurableTab.java | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 0a6ec5932cc..be9702f8928 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -324,6 +324,9 @@ enum class LanguageVersion(val major: Int, val minor: Int) : DescriptionAware { } } +fun LanguageVersion.isStableOrReadyForPreview(): Boolean = + isStable || this == KOTLIN_1_5 + interface LanguageVersionSettings { fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt index bf00531efd4..811a8750237 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/EnableUnsupportedFeatureFix.kt @@ -17,6 +17,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.isStableOrReadyForPreview import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.KotlinJvmBundle @@ -104,7 +105,7 @@ sealed class EnableUnsupportedFeatureFix( val apiVersionOnly = sinceVersion <= languageFeatureSettings.languageVersion && feature.sinceApiVersion > languageFeatureSettings.apiVersion - if (!sinceVersion.isStable && !ApplicationManager.getApplication().isInternal) { + if (!sinceVersion.isStableOrReadyForPreview() && !ApplicationManager.getApplication().isInternal) { return null } diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/MavenCompletionProviders.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/MavenCompletionProviders.kt index 967995c144a..a3950b57b3b 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/MavenCompletionProviders.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/MavenCompletionProviders.kt @@ -11,14 +11,15 @@ import org.jetbrains.idea.maven.plugins.api.MavenFixedValueReferenceProvider import org.jetbrains.kotlin.cli.common.arguments.DefaultValues import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.config.isStableOrReadyForPreview class MavenLanguageVersionsCompletionProvider : MavenFixedValueReferenceProvider( - LanguageVersion.values().filter { it.isStable || ApplicationManager.getApplication().isInternal }.map { it.versionString } + LanguageVersion.values().filter { it.isStableOrReadyForPreview() || ApplicationManager.getApplication().isInternal }.map { it.versionString } .toTypedArray() ) class MavenApiVersionsCompletionProvider : MavenFixedValueReferenceProvider( - LanguageVersion.values().filter { it.isStable || ApplicationManager.getApplication().isInternal }.map { it.versionString } + LanguageVersion.values().filter { it.isStableOrReadyForPreview() || ApplicationManager.getApplication().isInternal }.map { it.versionString } .toTypedArray() ) diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java index 087aa7e8f1e..d3ba8f912a1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java @@ -370,7 +370,7 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { apiVersionComboBox.addItem(VersionView.LatestStable.INSTANCE); for (LanguageVersion version : LanguageVersion.values()) { - if (version.isUnsupported() || !version.isStable() && !ApplicationManager.getApplication().isInternal()) { + if (version.isUnsupported() || !LanguageVersionSettingsKt.isStableOrReadyForPreview(version) && !ApplicationManager.getApplication().isInternal()) { continue; } From 77180a5b133120a8069ad1544c2d60d47b1fec60 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sat, 26 Dec 2020 21:42:46 +0700 Subject: [PATCH 026/197] [JVM IR] Make file classes with all private members package-private --- .../backend/jvm/lower/FileClassLowering.kt | 32 ++++++++++++------- ...eClassWithPrivateDeclarationsOnly_after.kt | 14 ++++++++ ...ClassWithPrivateDeclarationsOnly_after.txt | 23 +++++++++++++ ...ClassWithPrivateDeclarationsOnly_before.kt | 14 ++++++++ ...lassWithPrivateDeclarationsOnly_before.txt | 23 +++++++++++++ .../codegen/BytecodeListingTestGenerated.java | 10 ++++++ .../ir/IrBytecodeListingTestGenerated.java | 10 ++++++ .../kotlin/config/LanguageVersionSettings.kt | 2 ++ 8 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.kt create mode 100644 compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.txt create mode 100644 compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.kt create mode 100644 compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.txt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt index 74f5944f4b9..58aab0fbbbd 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FileClassLowering.kt @@ -22,22 +22,20 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.config.JvmAnalysisFlags +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.JvmSimpleFileClassInfo import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl -import org.jetbrains.kotlin.ir.util.IdSignature -import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl -import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable -import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.psi2ir.PsiSourceManager +import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.JvmClassName import java.util.* @@ -61,7 +59,8 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa irFile.declarations.forEach { when (it) { - is IrScript -> {} + is IrScript -> { + } is IrClass -> classes.add(it) else -> fileClassMembers.add(it) } @@ -79,19 +78,27 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa private fun createFileClass(irFile: IrFile, fileClassMembers: List): IrClass { val fileEntry = irFile.fileEntry - val fileClassInfo: JvmFileClassInfo? - when (fileEntry) { + val fileClassInfo = when (fileEntry) { is PsiSourceManager.PsiFileEntry -> { val ktFile = context.psiSourceManager.getKtFile(fileEntry) ?: throw AssertionError("Unexpected file entry: $fileEntry") - fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(ktFile) + JvmFileClassUtil.getFileClassInfoNoResolve(ktFile) } is NaiveSourceBasedFileEntryImpl -> { - fileClassInfo = JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(irFile.fqName, fileEntry.name), false) + JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(irFile.fqName, fileEntry.name), false) } else -> error("unknown kind of file entry: $fileEntry") } val isMultifilePart = fileClassInfo.withJvmMultifileClass + + val onlyPrivateDeclarationsAndFeatureIsEnabled = + context.state.languageVersionSettings.supportsFeature(LanguageFeature.PackagePrivateFileClassesWithAllPrivateMembers) && fileClassMembers + .all { + val isPrivate = it is IrDeclarationWithVisibility && DescriptorVisibilities.isPrivate(it.visibility) + val isInlineOnly = it.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) + isPrivate || isInlineOnly + } + return IrClassImpl( 0, fileEntry.maxOffset, if (!isMultifilePart || context.state.languageVersionSettings.getFlag(JvmAnalysisFlags.inheritMultifileParts)) @@ -99,7 +106,10 @@ private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPa symbol = IrClassSymbolImpl(), name = fileClassInfo.fileClassFqName.shortName(), kind = ClassKind.CLASS, - visibility = if (!isMultifilePart) DescriptorVisibilities.PUBLIC else JavaDescriptorVisibilities.PACKAGE_VISIBILITY, + visibility = if (isMultifilePart || onlyPrivateDeclarationsAndFeatureIsEnabled) + JavaDescriptorVisibilities.PACKAGE_VISIBILITY + else + DescriptorVisibilities.PUBLIC, modality = Modality.FINAL ).apply { superTypes = listOf(context.irBuiltIns.anyType) diff --git a/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.kt b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.kt new file mode 100644 index 00000000000..29615fc98b9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// IGNORE_BACKEND: JVM +// !LANGUAGE: +PackagePrivateFileClassesWithAllPrivateMembers + +private fun f() { +} + +private val a = Unit +private val b by lazy { Unit } + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.InlineOnly +public fun g() { +} diff --git a/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.txt b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.txt new file mode 100644 index 00000000000..5265d3b0fbe --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.txt @@ -0,0 +1,23 @@ +@kotlin.Metadata +final class FileClassWithPrivateDeclarationsOnly_afterKt$b$2 { + // source: 'fileClassWithPrivateDeclarationsOnly_after.kt' + enclosing method FileClassWithPrivateDeclarationsOnly_afterKt.()V + public final static field INSTANCE: FileClassWithPrivateDeclarationsOnly_afterKt$b$2 + inner (anonymous) class FileClassWithPrivateDeclarationsOnly_afterKt$b$2 + static method (): void + method (): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +final class FileClassWithPrivateDeclarationsOnly_afterKt { + // source: 'fileClassWithPrivateDeclarationsOnly_after.kt' + private final static @org.jetbrains.annotations.NotNull field a: kotlin.Unit + private final static @org.jetbrains.annotations.NotNull field b$delegate: kotlin.Lazy + inner (anonymous) class FileClassWithPrivateDeclarationsOnly_afterKt$b$2 + static method (): void + private final static method f(): void + public final static @kotlin.internal.InlineOnly method g(): void + private final static method getB(): kotlin.Unit +} diff --git a/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.kt b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.kt new file mode 100644 index 00000000000..2acfde62879 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// IGNORE_BACKEND: JVM +// !LANGUAGE: -PackagePrivateFileClassesWithAllPrivateMembers + +private fun f() { +} + +private val a = Unit +private val b by lazy { Unit } + +@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@kotlin.internal.InlineOnly +public fun g() { +} diff --git a/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.txt b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.txt new file mode 100644 index 00000000000..8e85499a697 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.txt @@ -0,0 +1,23 @@ +@kotlin.Metadata +final class FileClassWithPrivateDeclarationsOnly_beforeKt$b$2 { + // source: 'fileClassWithPrivateDeclarationsOnly_before.kt' + enclosing method FileClassWithPrivateDeclarationsOnly_beforeKt.()V + public final static field INSTANCE: FileClassWithPrivateDeclarationsOnly_beforeKt$b$2 + inner (anonymous) class FileClassWithPrivateDeclarationsOnly_beforeKt$b$2 + static method (): void + method (): void + public synthetic bridge method invoke(): java.lang.Object + public final method invoke(): void +} + +@kotlin.Metadata +public final class FileClassWithPrivateDeclarationsOnly_beforeKt { + // source: 'fileClassWithPrivateDeclarationsOnly_before.kt' + private final static @org.jetbrains.annotations.NotNull field a: kotlin.Unit + private final static @org.jetbrains.annotations.NotNull field b$delegate: kotlin.Lazy + inner (anonymous) class FileClassWithPrivateDeclarationsOnly_beforeKt$b$2 + static method (): void + private final static method f(): void + public final static @kotlin.internal.InlineOnly method g(): void + private final static method getB(): kotlin.Unit +} diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 382d70c5f14..0707ec688df 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -90,6 +90,16 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/extension.kt"); } + @TestMetadata("fileClassWithPrivateDeclarationsOnly_after.kt") + public void testFileClassWithPrivateDeclarationsOnly_after() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.kt"); + } + + @TestMetadata("fileClassWithPrivateDeclarationsOnly_before.kt") + public void testFileClassWithPrivateDeclarationsOnly_before() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.kt"); + } + @TestMetadata("immutableCollection.kt") public void testImmutableCollection() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/immutableCollection.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index d9e1a3e75aa..fabfa8b0978 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -90,6 +90,16 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/extension.kt"); } + @TestMetadata("fileClassWithPrivateDeclarationsOnly_after.kt") + public void testFileClassWithPrivateDeclarationsOnly_after() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_after.kt"); + } + + @TestMetadata("fileClassWithPrivateDeclarationsOnly_before.kt") + public void testFileClassWithPrivateDeclarationsOnly_before() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/fileClassWithPrivateDeclarationsOnly_before.kt"); + } + @TestMetadata("immutableCollection.kt") public void testImmutableCollection() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/immutableCollection.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index be9702f8928..bebb209059d 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -145,6 +145,8 @@ enum class LanguageFeature( AllowSealedInheritorsInDifferentFilesOfSamePackage(KOTLIN_1_5), SealedInterfaces(KOTLIN_1_5), JvmIrEnabledByDefault(KOTLIN_1_5), + // Disabled until the breaking change is approved by the committee, see KT-10884. + PackagePrivateFileClassesWithAllPrivateMembers(KOTLIN_1_5, defaultState = State.DISABLED), /* * Improvements include the following: From ee952db1a2202f054e37ce54f62856168f622975 Mon Sep 17 00:00:00 2001 From: Kris Hall Date: Thu, 19 Nov 2020 15:26:08 -0600 Subject: [PATCH 027/197] Added samples for String.replace() function --- libraries/stdlib/common/src/kotlin/TextH.kt | 4 ++++ libraries/stdlib/samples/test/samples/text/strings.kt | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/libraries/stdlib/common/src/kotlin/TextH.kt b/libraries/stdlib/common/src/kotlin/TextH.kt index 10e88020a10..e750cd88edb 100644 --- a/libraries/stdlib/common/src/kotlin/TextH.kt +++ b/libraries/stdlib/common/src/kotlin/TextH.kt @@ -196,12 +196,16 @@ public expect fun CharSequence.repeat(n: Int): String /** * Returns a new string with all occurrences of [oldChar] replaced with [newChar]. + * + * @sample samples.text.Strings.replace */ expect fun String.replace(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String /** * Returns a new string obtained by replacing all occurrences of the [oldValue] substring in this string * with the specified [newValue] string. + * + * @sample samples.text.Strings.replace */ expect fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String diff --git a/libraries/stdlib/samples/test/samples/text/strings.kt b/libraries/stdlib/samples/test/samples/text/strings.kt index 6faa1ef3826..70379dfc58e 100644 --- a/libraries/stdlib/samples/test/samples/text/strings.kt +++ b/libraries/stdlib/samples/test/samples/text/strings.kt @@ -445,4 +445,13 @@ class Strings { assertPrints(emptyString.lastOrNull(), "null") assertFails { emptyString.last() } } + + @Sample + fun replace() { + val inputString0 = "Mississippi" + val inputString1 = "Insufficient data for meaningful answer." + + assertPrints(inputString0.replace('s', 'z'), "Mizzizzippi") + assertPrints(inputString1.replace("data", "information"), "Insufficient information for meaningful answer.") + } } From 0110b4e4b4df0350e600a6bd1eb3050eb8b4b260 Mon Sep 17 00:00:00 2001 From: scaventz Date: Fri, 4 Dec 2020 18:00:54 +0800 Subject: [PATCH 028/197] Ant: Add support for fork-mode #KT-44293 --- .../jetbrains/kotlin/ant/Kotlin2JvmTask.kt | 53 ++++++++++++++++++- .../kotlin/ant/KotlinCompilerBaseTask.kt | 2 +- .../ant/jvm/fork/build.log.expected | 16 ++++++ .../integration/ant/jvm/fork/build.xml | 25 +++++++++ .../integration/ant/jvm/fork/hello.kt | 5 ++ .../ant/jvm/fork/premain/Premain.java | 14 +++++ .../ant/jvm/forkOnError/build.log.expected | 24 +++++++++ .../integration/ant/jvm/forkOnError/build.xml | 25 +++++++++ .../ant/jvm/forkOnError/premain/Premain.java | 14 +++++ .../integration/ant/jvm/forkOnError/test.kt | 5 ++ .../integration/AntTaskTestGenerated.java | 10 ++++ 11 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/integration/ant/jvm/fork/build.log.expected create mode 100644 compiler/testData/integration/ant/jvm/fork/build.xml create mode 100644 compiler/testData/integration/ant/jvm/fork/hello.kt create mode 100644 compiler/testData/integration/ant/jvm/fork/premain/Premain.java create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/build.log.expected create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/build.xml create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java create mode 100644 compiler/testData/integration/ant/jvm/forkOnError/test.kt diff --git a/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt b/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt index aea749a85e8..33f946e31f5 100644 --- a/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt +++ b/ant/src/org/jetbrains/kotlin/ant/Kotlin2JvmTask.kt @@ -16,9 +16,12 @@ package org.jetbrains.kotlin.ant -import org.apache.tools.ant.types.Path -import org.apache.tools.ant.types.Reference +import org.apache.tools.ant.BuildException +import org.apache.tools.ant.taskdefs.Execute +import org.apache.tools.ant.taskdefs.Redirector +import org.apache.tools.ant.types.* import java.io.File.pathSeparator +import java.io.File.separator class Kotlin2JvmTask : KotlinCompilerBaseTask() { override val compilerFqName = "org.jetbrains.kotlin.cli.jvm.K2JVMCompiler" @@ -28,6 +31,9 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() { var noReflect: Boolean = false + private val cmdl = CommandlineJava() + var fork: Boolean = false + private var compileClasspath: Path? = null fun setClasspath(classpath: Path) { @@ -73,4 +79,47 @@ class Kotlin2JvmTask : KotlinCompilerBaseTask() { if (noReflect) args.add("-no-reflect") if (includeRuntime) args.add("-include-runtime") } + + override fun execute() { + if (!fork) + super.execute() + else { + exec() + } + } + + private fun exec() { + val javaHome = System.getProperty("java.home") + val javaBin = javaHome + separator + "bin" + separator + "java" + val redirector = Redirector(this) + + fillArguments() + + val command = ArrayList() + command.add(javaBin) + command.addAll(cmdl.vmCommand.arguments) // jvm args + command.add("-Dorg.jetbrains.kotlin.cliMessageRenderer=FullPath") // same MessageRenderer as non-forking mode + command.add("-cp") + command.add(KotlinAntTaskUtil.compilerJar.canonicalPath) + command.add(compilerFqName) + command.addAll(args) // compiler args + + // streamHandler: used to handle the input and output streams of the subprocess. + // watchdog: a watchdog for the subprocess or null to disable a timeout for the subprocess. + // TODO: support timeout for the subprocess + val exe = Execute(redirector.createHandler(), null) + exe.setAntRun(getProject()) + exe.commandline = command.toTypedArray() + log("Executing command: ${command.joinToString(" ")}", LogLevel.DEBUG.level) + log("Compiling ${src!!.list().toList()} => [${output!!.canonicalPath}]") + val exitCode = exe.execute() + redirector.complete() + if (failOnError && exitCode != 0) { + throw BuildException("Compile failed; see the compiler error output for details.") + } + } + + fun createJvmarg(): Commandline.Argument { + return cmdl.createVmArgument() + } } diff --git a/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt b/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt index 417068ef8a8..f39bfdadf2a 100644 --- a/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt +++ b/ant/src/org/jetbrains/kotlin/ant/KotlinCompilerBaseTask.kt @@ -80,7 +80,7 @@ abstract class KotlinCompilerBaseTask : Task() { fillSpecificArguments() } - final override fun execute() { + override fun execute() { fillArguments() val compilerClass = KotlinAntTaskUtil.getOrCreateClassLoader().loadClass(compilerFqName) diff --git a/compiler/testData/integration/ant/jvm/fork/build.log.expected b/compiler/testData/integration/ant/jvm/fork/build.log.expected new file mode 100644 index 00000000000..6a303908cd8 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/build.log.expected @@ -0,0 +1,16 @@ +OUT: +Buildfile: [TestData]/build.xml + +premain: + [javac] Compiling 1 source file to [Temp] + [jar] Building jar: [Temp]/premain.jar + +build: + [kotlinc] Compiling [[TestData]] => [[Temp]/fork.jar] + [kotlinc] -Xms64m + [kotlinc] -Xmx128m + +BUILD SUCCESSFUL +Total time: [time] + +Return code: 0 diff --git a/compiler/testData/integration/ant/jvm/fork/build.xml b/compiler/testData/integration/ant/jvm/fork/build.xml new file mode 100644 index 00000000000..5dffa59b1db --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/build.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compiler/testData/integration/ant/jvm/fork/hello.kt b/compiler/testData/integration/ant/jvm/fork/hello.kt new file mode 100644 index 00000000000..4106d5b5fdc --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/hello.kt @@ -0,0 +1,5 @@ +package hello + +fun main() { + println(0 as String) +} diff --git a/compiler/testData/integration/ant/jvm/fork/premain/Premain.java b/compiler/testData/integration/ant/jvm/fork/premain/Premain.java new file mode 100644 index 00000000000..48fa3a0401f --- /dev/null +++ b/compiler/testData/integration/ant/jvm/fork/premain/Premain.java @@ -0,0 +1,14 @@ +import java.lang.instrument.Instrumentation; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.List; + +public class Premain { + public static void premain(String agentArgs, Instrumentation inst) { + RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); + List arguments = bean.getInputArguments(); + arguments.stream().filter(param -> + param.startsWith("-Xmx") || param.startsWith("-Xms") + ).sorted().forEach(System.out::println); + } +} diff --git a/compiler/testData/integration/ant/jvm/forkOnError/build.log.expected b/compiler/testData/integration/ant/jvm/forkOnError/build.log.expected new file mode 100644 index 00000000000..2d6555d5737 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/build.log.expected @@ -0,0 +1,24 @@ +OUT: +Buildfile: [TestData]/build.xml + +premain: + [javac] Compiling 1 source file to [Temp] + [jar] Building jar: [Temp]/premain.jar + +build: + [kotlinc] Compiling [[TestData]] => [[Temp]/fork.jar] + [kotlinc] -Xms64m + [kotlinc] -Xmx128m + [kotlinc] error: warnings found and -Werror specified + [kotlinc] [TestData]/test.kt:4:15: warning: this cast can never succeed + [kotlinc] println(0 as String) + [kotlinc] ^ + +ERR: + +BUILD FAILED +[TestData]/build.xml:18: Compile failed; see the compiler error output for details. + +Total time: [time] + +Return code: 1 diff --git a/compiler/testData/integration/ant/jvm/forkOnError/build.xml b/compiler/testData/integration/ant/jvm/forkOnError/build.xml new file mode 100644 index 00000000000..e62ad865146 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/build.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java b/compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java new file mode 100644 index 00000000000..48fa3a0401f --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/premain/Premain.java @@ -0,0 +1,14 @@ +import java.lang.instrument.Instrumentation; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.List; + +public class Premain { + public static void premain(String agentArgs, Instrumentation inst) { + RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean(); + List arguments = bean.getInputArguments(); + arguments.stream().filter(param -> + param.startsWith("-Xmx") || param.startsWith("-Xms") + ).sorted().forEach(System.out::println); + } +} diff --git a/compiler/testData/integration/ant/jvm/forkOnError/test.kt b/compiler/testData/integration/ant/jvm/forkOnError/test.kt new file mode 100644 index 00000000000..f6bac26d258 --- /dev/null +++ b/compiler/testData/integration/ant/jvm/forkOnError/test.kt @@ -0,0 +1,5 @@ +package hello + +fun main() { + println(0 as String) +} \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java index 749b799377d..01878446123 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/integration/AntTaskTestGenerated.java @@ -44,6 +44,16 @@ public class AntTaskTestGenerated extends AbstractAntTaskTest { runTest("compiler/testData/integration/ant/jvm/failOnErrorByDefault/"); } + @TestMetadata("fork") + public void testFork() throws Exception { + runTest("compiler/testData/integration/ant/jvm/fork/"); + } + + @TestMetadata("forkOnError") + public void testForkOnError() throws Exception { + runTest("compiler/testData/integration/ant/jvm/forkOnError/"); + } + @TestMetadata("helloWorld") public void testHelloWorld() throws Exception { runTest("compiler/testData/integration/ant/jvm/helloWorld/"); From 2d88ff6fb291db8b140e9c87bf06e3675e6c52da Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Mon, 11 Jan 2021 17:00:05 +0300 Subject: [PATCH 029/197] [JS IR] Fix unsgined integer default arguemtns (KT-44180) Const lowering didn't exprect null constants with unsigned number types and crashed with NPE. This commit fixes that. --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 +++++ .../ir/backend/js/lower/ConstLowering.kt | 2 +- .../box/unsignedTypes/defaultArguments.kt | 20 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++++ .../IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++++ 10 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 6849164f38c..38d146b334b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -32343,6 +32343,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt index fc30602d3b5..267eff257db 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ConstLowering.kt @@ -45,7 +45,7 @@ class ConstTransformer(private val context: JsIrBackendContext) : IrElementTrans override fun visitConst(expression: IrConst): IrExpression { with(context.intrinsics) { - if (expression.type.isUnsigned()) { + if (expression.type.isUnsigned() && expression.kind != IrConstKind.Null) { return when (expression.type.classifierOrNull) { uByteClassSymbol -> lowerConst(uByteClassSymbol, IrConstImpl.Companion::byte, IrConstKind.Byte.valueOf(expression)) diff --git a/compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt b/compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt new file mode 100644 index 00000000000..1c73f971e30 --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME + +// Case of KT-44180 + +fun foo( + p0: UByte = 1u, + p1: UShort = 1u, + p2: UInt = 1u, + p4: ULong = 1uL, +): ULong { + return p0.toULong() + p1.toUShort() + p2.toUInt() + p4 +} + +fun box(): String { + if (foo() != 4uL) return "Fail 1" + if (foo(p2 = 10u) != 13uL) return "Fail 2" + if (foo(10u, 10u, 10u, 10uL) != 40uL) return "Fail 3" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 7692c587f8e..182df123be2 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -32709,6 +32709,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 002c29dda39..c04fc51edf2 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -30348,6 +30348,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 2c8b40a254d..f2f5dabdc9b 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -32343,6 +32343,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 57da1c7969c..f0c9b263cd1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -26154,6 +26154,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 21759f0fc3e..cc9d02119a6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -26154,6 +26154,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 206472c6123..f956b3453ad 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -26154,6 +26154,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 4ef011f76c0..36b3661044b 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -14352,6 +14352,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/unsignedTypes/checkBasicUnsignedLiterals.kt"); } + @TestMetadata("defaultArguments.kt") + public void testDefaultArguments() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/defaultArguments.kt"); + } + @TestMetadata("equalsImplForInlineClassWrappingNullableInlineClass.kt") public void testEqualsImplForInlineClassWrappingNullableInlineClass() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/equalsImplForInlineClassWrappingNullableInlineClass.kt"); From ab753625fefbddac984367ffb2b52315406b085f Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Mon, 11 Jan 2021 21:49:06 +0300 Subject: [PATCH 030/197] [JS Legacy] Fix returning Char from suspend functions (KT-44221) Mark translated expression with a proper type, like we do with non-suspending calls, to coerce it later. --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 ++++ .../codegen/box/coroutines/kt44221.kt | 24 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 ++++ .../LightAnalysisModeTestGenerated.java | 5 ++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 ++++ .../IrJsCodegenBoxES6TestGenerated.java | 5 ++++ .../IrJsCodegenBoxTestGenerated.java | 5 ++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 ++++ .../callTranslator/CallTranslator.kt | 2 +- 9 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/coroutines/kt44221.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 38d146b334b..0a15602d41b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -6853,6 +6853,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/coroutines/kt42554.kt"); } + @TestMetadata("kt44221.kt") + public void testKt44221() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt44221.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/compiler/testData/codegen/box/coroutines/kt44221.kt b/compiler/testData/codegen/box/coroutines/kt44221.kt new file mode 100644 index 00000000000..631344981e5 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/kt44221.kt @@ -0,0 +1,24 @@ +// WITH_RUNTIME + +import kotlin.coroutines.* + +fun launch(block: suspend () -> String): String { + var result = "" + block.startCoroutine(Continuation(EmptyCoroutineContext) { result = it.getOrThrow() }) + return result +} + + +private class CharTest { + private val test: Char = '!' + + fun simpleTest() = launch { + val ch = get() + if (ch == '!') "OK" else "Fail" + } + + suspend fun get(): Char? = test +} + + +fun box(): String = CharTest().simpleTest() \ No newline at end of file diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 182df123be2..4a77950d146 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -6853,6 +6853,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/coroutines/kt42554.kt"); } + @TestMetadata("kt44221.kt") + public void testKt44221() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt44221.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index c04fc51edf2..fb923e6527a 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -6853,6 +6853,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/coroutines/kt42554.kt"); } + @TestMetadata("kt44221.kt") + public void testKt44221() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt44221.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index f2f5dabdc9b..52df58a5186 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -6853,6 +6853,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/coroutines/kt42554.kt"); } + @TestMetadata("kt44221.kt") + public void testKt44221() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt44221.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index f0c9b263cd1..d73f082b1d0 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -5658,6 +5658,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/coroutines/kt42554.kt"); } + @TestMetadata("kt44221.kt") + public void testKt44221() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt44221.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index cc9d02119a6..4ff74f60449 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -5658,6 +5658,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/coroutines/kt42554.kt"); } + @TestMetadata("kt44221.kt") + public void testKt44221() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt44221.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index f956b3453ad..b71e5cf4809 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -5658,6 +5658,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/coroutines/kt42554.kt"); } + @TestMetadata("kt44221.kt") + public void testKt44221() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/kt44221.kt"); + } + @TestMetadata("lastExpressionIsLoop.kt") public void testLastExpressionIsLoop() throws Exception { runTest("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt index 6054d7af253..1177ee34099 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallTranslator.kt @@ -157,7 +157,7 @@ private fun translateFunctionCall( source = resolvedCall.call.callElement })) context.currentBlock.statements += statement - return context.createCoroutineResult(resolvedCall) + callExpression = context.createCoroutineResult(resolvedCall) } else { callExpression = callInfo.constructSafeCallIfNeeded(callExpression) From df75cddcb88c42ec5305505daa2629b4272af76f Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Mon, 11 Jan 2021 14:11:05 +0300 Subject: [PATCH 031/197] [Gradle, JS] Add possibility to set jvmArgs for dce process ^KT-44104 fixed --- .../jetbrains/kotlin/compilerRunner/reportUtils.kt | 12 ++++++++++-- .../org/jetbrains/kotlin/gradle/tasks/KotlinJsDce.kt | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt index db4d36918d6..3b92aa31037 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/compilerRunner/reportUtils.kt @@ -90,14 +90,22 @@ internal fun runToolInSeparateProcess( compilerClassName: String, classpath: List, logger: KotlinLogger, - buildDir: File + buildDir: File, + jvmArgs: List = emptyList() ): ExitCode { val javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java" val classpathString = classpath.map { it.absolutePath }.joinToString(separator = File.pathSeparator) val compilerOptions = writeArgumentsToFile(buildDir, argsArray) - val builder = ProcessBuilder(javaBin, "-cp", classpathString, compilerClassName, "@${compilerOptions.absolutePath}") + val builder = ProcessBuilder( + javaBin, + *(jvmArgs.toTypedArray()), + "-cp", + classpathString, + compilerClassName, + "@${compilerOptions.absolutePath}" + ) val messageCollector = createLoggingMessageCollector(logger) val process = launchProcessWithFallback(builder, DaemonReportingTargets(messageCollector = messageCollector)) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinJsDce.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinJsDce.kt index 05571a30469..b9d50a20f16 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinJsDce.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinJsDce.kt @@ -71,6 +71,9 @@ open class KotlinJsDce : AbstractKotlinCompileTool(), KotlinJs keep += fqn } + @Input + var jvmArgs = mutableListOf() + @TaskAction fun performDce() { val inputFiles = (listOf(source) + classpath @@ -91,7 +94,8 @@ open class KotlinJsDce : AbstractKotlinCompileTool(), KotlinJs K2JSDce::class.java.name, computedCompilerClasspath, log, - project.buildDir + project.buildDir, + jvmArgs ) throwGradleExceptionIfError(exitCode) From 742fef90421f98f516e28223ed99f95bf8935870 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 8 Jan 2021 18:00:04 +0100 Subject: [PATCH 032/197] Rewrite generator for OperationsMapGenerated Do not generate operations as lambdas; instead use `when` over strings/enums, which is generated to tableswitch in the bytecode. This reduces the proguarded compiler jar size by ~0.57%. #KT-23565 Fixed --- .../evaluate/ConstantExpressionEvaluator.kt | 126 +-- .../evaluate/OperationsMapGenerated.kt | 938 +++++++++++------- generators/evaluate/GenerateOperationsMap.kt | 185 ++-- 3 files changed, 740 insertions(+), 509 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index 7ec2595116c..b113512816f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker import org.jetbrains.kotlin.resolve.constants.* +import org.jetbrains.kotlin.resolve.constants.evaluate.CompileTimeType.* import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils @@ -903,7 +904,7 @@ private class ConstantExpressionEvaluatorVisitor( return null } - private class OperationArgument(val value: Any, val ctcType: CompileTimeType<*>, val expression: KtExpression) + private class OperationArgument(val value: Any, val ctcType: CompileTimeType, val expression: KtExpression) private fun createOperationArgumentForReceiver(resolvedCall: ResolvedCall<*>, expression: KtExpression): OperationArgument? { val receiverExpressionType = getReceiverExpressionType(resolvedCall) ?: return null @@ -927,7 +928,7 @@ private class ConstantExpressionEvaluatorVisitor( return createOperationArgument(argumentExpression, parameter.type, argumentCompileTimeType) } - private fun getCompileTimeType(c: KotlinType): CompileTimeType? = + private fun getCompileTimeType(c: KotlinType): CompileTimeType? = when (TypeUtils.makeNotNullable(c)) { builtIns.intType -> INT builtIns.byteType -> BYTE @@ -945,7 +946,7 @@ private class ConstantExpressionEvaluatorVisitor( private fun createOperationArgument( expression: KtExpression, parameterType: KotlinType, - compileTimeType: CompileTimeType<*> + compileTimeType: CompileTimeType, ): OperationArgument? { val compileTimeConstant = constantExpressionEvaluator.evaluateExpression(expression, trace, parameterType) ?: return null if (compileTimeConstant is TypedCompileTimeConstant && !compileTimeConstant.type.isSubtypeOf(parameterType)) return null @@ -1098,44 +1099,11 @@ private fun getReceiverExpressionType(resolvedCall: ResolvedCall<*>): KotlinType } } -internal class CompileTimeType(val name: String) { - override fun toString() = name +internal enum class CompileTimeType { + BYTE, SHORT, INT, LONG, DOUBLE, FLOAT, CHAR, BOOLEAN, + STRING, ANY } -internal val BYTE = CompileTimeType("Byte") -internal val SHORT = CompileTimeType("Short") -internal val INT = CompileTimeType("Int") -internal val LONG = CompileTimeType("Long") -internal val DOUBLE = CompileTimeType("Double") -internal val FLOAT = CompileTimeType("Float") -internal val CHAR = CompileTimeType("Char") -internal val BOOLEAN = CompileTimeType("Boolean") -internal val STRING = CompileTimeType("String") -internal val ANY = CompileTimeType("Any") - -@Suppress("UNCHECKED_CAST") -internal fun binaryOperation( - a: CompileTimeType, - b: CompileTimeType, - functionName: String, - operation: Function2, - checker: Function2 -) = BinaryOperationKey(a, b, functionName) to Pair( - operation, - checker -) as Pair, Function2> - -@Suppress("UNCHECKED_CAST") -internal fun unaryOperation( - a: CompileTimeType, - functionName: String, - operation: Function1, - checker: Function1 -) = UnaryOperationKey(a, functionName) to Pair(operation, checker) as Pair, Function1> - -internal data class BinaryOperationKey(val f: CompileTimeType, val s: CompileTimeType, val functionName: String) -internal data class UnaryOperationKey(val f: CompileTimeType, val functionName: String) - fun ConstantValue<*>.isStandaloneOnlyConstant(): Boolean { return this is KClassValue || this is EnumValue || this is AnnotationValue || this is ArrayValue } @@ -1156,39 +1124,28 @@ private fun isZero(value: Any?): Boolean { } private fun typeStrToCompileTimeType(str: String) = when (str) { - BYTE.name -> BYTE - SHORT.name -> SHORT - INT.name -> INT - LONG.name -> LONG - DOUBLE.name -> DOUBLE - FLOAT.name -> FLOAT - CHAR.name -> CHAR - BOOLEAN.name -> BOOLEAN - STRING.name -> STRING - ANY.name -> ANY + "Byte" -> BYTE + "Short" -> SHORT + "Int" -> INT + "Long" -> LONG + "Double" -> DOUBLE + "Float" -> FLOAT + "Char" -> CHAR + "Boolean" -> BOOLEAN + "String" -> STRING + "Any" -> ANY else -> throw IllegalArgumentException("Unsupported type: $str") } -fun evaluateUnary(name: String, typeStr: String, value: Any): Any? { - return evaluateUnaryAndCheck(name, typeStrToCompileTimeType(typeStr), value) -} +fun evaluateUnary(name: String, typeStr: String, value: Any): Any? = + evalUnaryOp(name, typeStrToCompileTimeType(typeStr), value) -private fun evaluateUnaryAndCheck(name: String, type: CompileTimeType<*>, value: Any, tracer: () -> Unit = {}): Any? { - val functions = unaryOperations[UnaryOperationKey(type, name)] ?: return null - - val (function, check) = functions - val result = function(value) - if (check == emptyUnaryFun) { - return result +private fun evaluateUnaryAndCheck(name: String, type: CompileTimeType, value: Any, reportIntegerOverflow: () -> Unit): Any? = + evalUnaryOp(name, type, value).also { result -> + if (isIntegerType(value) && (name == "minus" || name == "unaryMinus") && value == result && !isZero(value)) { + reportIntegerOverflow() + } } - assert(isIntegerType(value)) { "Only integer constants should be checked for overflow" } - assert(name == "minus" || name == "unaryMinus") { "Only negation should be checked for overflow" } - - if (value == result && !isZero(value)) { - tracer() - } - return result -} fun evaluateBinary( name: String, @@ -1200,42 +1157,35 @@ fun evaluateBinary( val receiverType = typeStrToCompileTimeType(receiverTypeStr) val parameterType = typeStrToCompileTimeType(parameterTypeStr) - return evaluateBinaryAndCheck(name, receiverType, receiverValue, parameterType, parameterValue) + return try { + evalBinaryOp(name, receiverType, receiverValue, parameterType, parameterValue) + } catch (e: Exception) { + null + } } private fun evaluateBinaryAndCheck( name: String, - receiverType: CompileTimeType<*>, + receiverType: CompileTimeType, receiverValue: Any, - parameterType: CompileTimeType<*>, + parameterType: CompileTimeType, parameterValue: Any, - tracer: () -> Unit = {} + reportIntegerOverflow: () -> Unit, ): Any? { - val functions = binaryOperations[BinaryOperationKey(receiverType, parameterType, name)] ?: return null - - val (function, checker) = functions val actualResult = try { - function(receiverValue, parameterValue) + evalBinaryOp(name, receiverType, receiverValue, parameterType, parameterValue) } catch (e: Exception) { null } - if (checker == emptyBinaryFun) { - return actualResult - } - assert(isIntegerType(receiverValue) && isIntegerType(parameterValue)) { "Only integer constants should be checked for overflow" } fun toBigInteger(value: Any?) = BigInteger.valueOf((value as Number).toLong()) - val refinedChecker = if (name == OperatorNameConventions.MOD.asString()) { - binaryOperations[BinaryOperationKey(receiverType, parameterType, OperatorNameConventions.REM.asString())]?.second ?: return null - } else { - checker + if (actualResult != null && isIntegerType(receiverValue) && isIntegerType(parameterValue)) { + val checkedResult = checkBinaryOp(name, receiverType, toBigInteger(receiverValue), parameterType, toBigInteger(parameterValue)) + if (checkedResult != null && toBigInteger(actualResult) != checkedResult) { + reportIntegerOverflow() + } } - val resultInBigIntegers = refinedChecker(toBigInteger(receiverValue), toBigInteger(parameterValue)) - - if (toBigInteger(actualResult) != resultInBigIntegers) { - tracer() - } return actualResult } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/OperationsMapGenerated.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/OperationsMapGenerated.kt index 4e60845f696..a05c37eb6b1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/OperationsMapGenerated.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/OperationsMapGenerated.kt @@ -14,344 +14,616 @@ * limitations under the License. */ -@file:Suppress("DEPRECATION", "DEPRECATION_ERROR") +@file:Suppress("DEPRECATION", "DEPRECATION_ERROR", "NON_EXHAUSTIVE_WHEN") package org.jetbrains.kotlin.resolve.constants.evaluate +import org.jetbrains.kotlin.resolve.constants.evaluate.CompileTimeType.* import java.math.BigInteger -import java.util.HashMap -/** This file is generated by org.jetbrains.kotlin.generators.evaluate:generate(). DO NOT MODIFY MANUALLY */ +/** This file is generated by `./gradlew generateOperationsMap`. DO NOT MODIFY MANUALLY */ -internal val emptyBinaryFun: Function2 = { _, _ -> BigInteger("0") } -internal val emptyUnaryFun: Function1 = { _ -> 1.toLong() } +internal fun evalUnaryOp(name: String, type: CompileTimeType, value: Any): Any? { + when (type) { + BOOLEAN -> when (name) { + "not" -> return (value as Boolean).not() + "toString" -> return (value as Boolean).toString() + } + BYTE -> when (name) { + "toByte" -> return (value as Byte).toByte() + "toChar" -> return (value as Byte).toChar() + "toDouble" -> return (value as Byte).toDouble() + "toFloat" -> return (value as Byte).toFloat() + "toInt" -> return (value as Byte).toInt() + "toLong" -> return (value as Byte).toLong() + "toShort" -> return (value as Byte).toShort() + "toString" -> return (value as Byte).toString() + "unaryMinus" -> return (value as Byte).unaryMinus() + "unaryPlus" -> return (value as Byte).unaryPlus() + } + CHAR -> when (name) { + "toByte" -> return (value as Char).toByte() + "toChar" -> return (value as Char).toChar() + "toDouble" -> return (value as Char).toDouble() + "toFloat" -> return (value as Char).toFloat() + "toInt" -> return (value as Char).toInt() + "toLong" -> return (value as Char).toLong() + "toShort" -> return (value as Char).toShort() + "toString" -> return (value as Char).toString() + } + DOUBLE -> when (name) { + "toByte" -> return (value as Double).toByte() + "toChar" -> return (value as Double).toChar() + "toDouble" -> return (value as Double).toDouble() + "toFloat" -> return (value as Double).toFloat() + "toInt" -> return (value as Double).toInt() + "toLong" -> return (value as Double).toLong() + "toShort" -> return (value as Double).toShort() + "toString" -> return (value as Double).toString() + "unaryMinus" -> return (value as Double).unaryMinus() + "unaryPlus" -> return (value as Double).unaryPlus() + } + FLOAT -> when (name) { + "toByte" -> return (value as Float).toByte() + "toChar" -> return (value as Float).toChar() + "toDouble" -> return (value as Float).toDouble() + "toFloat" -> return (value as Float).toFloat() + "toInt" -> return (value as Float).toInt() + "toLong" -> return (value as Float).toLong() + "toShort" -> return (value as Float).toShort() + "toString" -> return (value as Float).toString() + "unaryMinus" -> return (value as Float).unaryMinus() + "unaryPlus" -> return (value as Float).unaryPlus() + } + INT -> when (name) { + "inv" -> return (value as Int).inv() + "toByte" -> return (value as Int).toByte() + "toChar" -> return (value as Int).toChar() + "toDouble" -> return (value as Int).toDouble() + "toFloat" -> return (value as Int).toFloat() + "toInt" -> return (value as Int).toInt() + "toLong" -> return (value as Int).toLong() + "toShort" -> return (value as Int).toShort() + "toString" -> return (value as Int).toString() + "unaryMinus" -> return (value as Int).unaryMinus() + "unaryPlus" -> return (value as Int).unaryPlus() + } + LONG -> when (name) { + "inv" -> return (value as Long).inv() + "toByte" -> return (value as Long).toByte() + "toChar" -> return (value as Long).toChar() + "toDouble" -> return (value as Long).toDouble() + "toFloat" -> return (value as Long).toFloat() + "toInt" -> return (value as Long).toInt() + "toLong" -> return (value as Long).toLong() + "toShort" -> return (value as Long).toShort() + "toString" -> return (value as Long).toString() + "unaryMinus" -> return (value as Long).unaryMinus() + "unaryPlus" -> return (value as Long).unaryPlus() + } + SHORT -> when (name) { + "toByte" -> return (value as Short).toByte() + "toChar" -> return (value as Short).toChar() + "toDouble" -> return (value as Short).toDouble() + "toFloat" -> return (value as Short).toFloat() + "toInt" -> return (value as Short).toInt() + "toLong" -> return (value as Short).toLong() + "toShort" -> return (value as Short).toShort() + "toString" -> return (value as Short).toString() + "unaryMinus" -> return (value as Short).unaryMinus() + "unaryPlus" -> return (value as Short).unaryPlus() + } + STRING -> when (name) { + "length" -> return (value as String).length + "toString" -> return (value as String).toString() + } + } + return null +} -internal val unaryOperations: HashMap, Pair, Function1>> - = hashMapOf, Pair, Function1>>( - unaryOperation(BOOLEAN, "not", { a -> a.not() }, emptyUnaryFun), - unaryOperation(BOOLEAN, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(BYTE, "toByte", { a -> a.toByte() }, emptyUnaryFun), - unaryOperation(BYTE, "toChar", { a -> a.toChar() }, emptyUnaryFun), - unaryOperation(BYTE, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), - unaryOperation(BYTE, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), - unaryOperation(BYTE, "toInt", { a -> a.toInt() }, emptyUnaryFun), - unaryOperation(BYTE, "toLong", { a -> a.toLong() }, emptyUnaryFun), - unaryOperation(BYTE, "toShort", { a -> a.toShort() }, emptyUnaryFun), - unaryOperation(BYTE, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(BYTE, "unaryMinus", { a -> a.unaryMinus() }, { a -> a.unaryMinus() }), - unaryOperation(BYTE, "unaryPlus", { a -> a.unaryPlus() }, emptyUnaryFun), - unaryOperation(CHAR, "toByte", { a -> a.toByte() }, emptyUnaryFun), - unaryOperation(CHAR, "toChar", { a -> a.toChar() }, emptyUnaryFun), - unaryOperation(CHAR, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), - unaryOperation(CHAR, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), - unaryOperation(CHAR, "toInt", { a -> a.toInt() }, emptyUnaryFun), - unaryOperation(CHAR, "toLong", { a -> a.toLong() }, emptyUnaryFun), - unaryOperation(CHAR, "toShort", { a -> a.toShort() }, emptyUnaryFun), - unaryOperation(CHAR, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toByte", { a -> a.toByte() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toChar", { a -> a.toChar() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toInt", { a -> a.toInt() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toLong", { a -> a.toLong() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toShort", { a -> a.toShort() }, emptyUnaryFun), - unaryOperation(DOUBLE, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(DOUBLE, "unaryMinus", { a -> a.unaryMinus() }, emptyUnaryFun), - unaryOperation(DOUBLE, "unaryPlus", { a -> a.unaryPlus() }, emptyUnaryFun), - unaryOperation(FLOAT, "toByte", { a -> a.toByte() }, emptyUnaryFun), - unaryOperation(FLOAT, "toChar", { a -> a.toChar() }, emptyUnaryFun), - unaryOperation(FLOAT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), - unaryOperation(FLOAT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), - unaryOperation(FLOAT, "toInt", { a -> a.toInt() }, emptyUnaryFun), - unaryOperation(FLOAT, "toLong", { a -> a.toLong() }, emptyUnaryFun), - unaryOperation(FLOAT, "toShort", { a -> a.toShort() }, emptyUnaryFun), - unaryOperation(FLOAT, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(FLOAT, "unaryMinus", { a -> a.unaryMinus() }, emptyUnaryFun), - unaryOperation(FLOAT, "unaryPlus", { a -> a.unaryPlus() }, emptyUnaryFun), - unaryOperation(INT, "inv", { a -> a.inv() }, emptyUnaryFun), - unaryOperation(INT, "toByte", { a -> a.toByte() }, emptyUnaryFun), - unaryOperation(INT, "toChar", { a -> a.toChar() }, emptyUnaryFun), - unaryOperation(INT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), - unaryOperation(INT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), - unaryOperation(INT, "toInt", { a -> a.toInt() }, emptyUnaryFun), - unaryOperation(INT, "toLong", { a -> a.toLong() }, emptyUnaryFun), - unaryOperation(INT, "toShort", { a -> a.toShort() }, emptyUnaryFun), - unaryOperation(INT, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(INT, "unaryMinus", { a -> a.unaryMinus() }, { a -> a.unaryMinus() }), - unaryOperation(INT, "unaryPlus", { a -> a.unaryPlus() }, emptyUnaryFun), - unaryOperation(LONG, "inv", { a -> a.inv() }, emptyUnaryFun), - unaryOperation(LONG, "toByte", { a -> a.toByte() }, emptyUnaryFun), - unaryOperation(LONG, "toChar", { a -> a.toChar() }, emptyUnaryFun), - unaryOperation(LONG, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), - unaryOperation(LONG, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), - unaryOperation(LONG, "toInt", { a -> a.toInt() }, emptyUnaryFun), - unaryOperation(LONG, "toLong", { a -> a.toLong() }, emptyUnaryFun), - unaryOperation(LONG, "toShort", { a -> a.toShort() }, emptyUnaryFun), - unaryOperation(LONG, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(LONG, "unaryMinus", { a -> a.unaryMinus() }, { a -> a.unaryMinus() }), - unaryOperation(LONG, "unaryPlus", { a -> a.unaryPlus() }, emptyUnaryFun), - unaryOperation(SHORT, "toByte", { a -> a.toByte() }, emptyUnaryFun), - unaryOperation(SHORT, "toChar", { a -> a.toChar() }, emptyUnaryFun), - unaryOperation(SHORT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun), - unaryOperation(SHORT, "toFloat", { a -> a.toFloat() }, emptyUnaryFun), - unaryOperation(SHORT, "toInt", { a -> a.toInt() }, emptyUnaryFun), - unaryOperation(SHORT, "toLong", { a -> a.toLong() }, emptyUnaryFun), - unaryOperation(SHORT, "toShort", { a -> a.toShort() }, emptyUnaryFun), - unaryOperation(SHORT, "toString", { a -> a.toString() }, emptyUnaryFun), - unaryOperation(SHORT, "unaryMinus", { a -> a.unaryMinus() }, { a -> a.unaryMinus() }), - unaryOperation(SHORT, "unaryPlus", { a -> a.unaryPlus() }, emptyUnaryFun), - unaryOperation(STRING, "length", { a -> a.length }, emptyUnaryFun), - unaryOperation(STRING, "toString", { a -> a.toString() }, emptyUnaryFun) -) -internal val binaryOperations: HashMap, Pair, Function2>> - = hashMapOf, Pair, Function2>>( - binaryOperation(BOOLEAN, BOOLEAN, "and", { a, b -> a.and(b) }, emptyBinaryFun), - binaryOperation(BOOLEAN, BOOLEAN, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(BOOLEAN, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(BOOLEAN, BOOLEAN, "or", { a, b -> a.or(b) }, emptyBinaryFun), - binaryOperation(BOOLEAN, BOOLEAN, "xor", { a, b -> a.xor(b) }, emptyBinaryFun), - binaryOperation(BYTE, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(BYTE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(BYTE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(BYTE, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(BYTE, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(BYTE, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(BYTE, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(BYTE, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(BYTE, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(BYTE, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(BYTE, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(BYTE, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(BYTE, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(BYTE, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(BYTE, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(BYTE, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(BYTE, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(BYTE, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(BYTE, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(BYTE, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(BYTE, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(BYTE, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(BYTE, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(BYTE, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(BYTE, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(BYTE, BYTE, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(BYTE, DOUBLE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(BYTE, FLOAT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(BYTE, INT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(BYTE, LONG, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(BYTE, SHORT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(BYTE, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(BYTE, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(BYTE, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(BYTE, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(BYTE, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(BYTE, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(CHAR, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(CHAR, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(CHAR, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(CHAR, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(CHAR, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, BYTE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, BYTE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, DOUBLE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, FLOAT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, INT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, LONG, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, SHORT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(DOUBLE, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(FLOAT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(FLOAT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(FLOAT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(FLOAT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(FLOAT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(FLOAT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(FLOAT, BYTE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(FLOAT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(FLOAT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(FLOAT, INT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(FLOAT, LONG, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(FLOAT, SHORT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(FLOAT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(FLOAT, BYTE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, INT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, LONG, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, SHORT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, BYTE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, INT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, LONG, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, SHORT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(FLOAT, BYTE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(FLOAT, DOUBLE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(FLOAT, FLOAT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(FLOAT, INT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(FLOAT, LONG, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(FLOAT, SHORT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(FLOAT, BYTE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(FLOAT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(FLOAT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(FLOAT, INT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(FLOAT, LONG, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(FLOAT, SHORT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }), - binaryOperation(INT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(INT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(INT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(INT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(INT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(INT, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(INT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(INT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(INT, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(INT, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(INT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(INT, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(INT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(INT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(INT, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(INT, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(INT, INT, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }), - binaryOperation(INT, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(INT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(INT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(INT, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(INT, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(INT, BYTE, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(INT, DOUBLE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(INT, FLOAT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(INT, LONG, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(INT, SHORT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(INT, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun), - binaryOperation(INT, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(INT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(INT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(INT, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(INT, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(INT, INT, "ushr", { a, b -> a.ushr(b) }, emptyBinaryFun), - binaryOperation(INT, INT, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }), - binaryOperation(LONG, LONG, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }), - binaryOperation(LONG, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(LONG, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(LONG, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(LONG, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(LONG, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(LONG, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(LONG, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(LONG, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(LONG, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(LONG, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(LONG, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(LONG, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(LONG, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(LONG, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(LONG, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(LONG, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(LONG, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(LONG, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(LONG, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(LONG, LONG, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }), - binaryOperation(LONG, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(LONG, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(LONG, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(LONG, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(LONG, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(LONG, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(LONG, BYTE, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(LONG, DOUBLE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(LONG, FLOAT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(LONG, INT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(LONG, LONG, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(LONG, SHORT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(LONG, INT, "shl", { a, b -> a.shl(b) }, emptyBinaryFun), - binaryOperation(LONG, INT, "shr", { a, b -> a.shr(b) }, emptyBinaryFun), - binaryOperation(LONG, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(LONG, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(LONG, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(LONG, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(LONG, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(LONG, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(LONG, INT, "ushr", { a, b -> a.ushr(b) }, emptyBinaryFun), - binaryOperation(LONG, LONG, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }), - binaryOperation(SHORT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(SHORT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(SHORT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(SHORT, INT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(SHORT, LONG, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(SHORT, SHORT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(SHORT, BYTE, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(SHORT, DOUBLE, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(SHORT, FLOAT, "div", { a, b -> a.div(b) }, emptyBinaryFun), - binaryOperation(SHORT, INT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(SHORT, LONG, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(SHORT, SHORT, "div", { a, b -> a.div(b) }, { a, b -> a.divide(b) }), - binaryOperation(SHORT, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(SHORT, BYTE, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(SHORT, DOUBLE, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(SHORT, FLOAT, "minus", { a, b -> a.minus(b) }, emptyBinaryFun), - binaryOperation(SHORT, INT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(SHORT, LONG, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(SHORT, SHORT, "minus", { a, b -> a.minus(b) }, { a, b -> a.subtract(b) }), - binaryOperation(SHORT, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(SHORT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(SHORT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun), - binaryOperation(SHORT, INT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(SHORT, LONG, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(SHORT, SHORT, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }), - binaryOperation(SHORT, BYTE, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(SHORT, DOUBLE, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(SHORT, FLOAT, "rem", { a, b -> a.rem(b) }, emptyBinaryFun), - binaryOperation(SHORT, INT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(SHORT, LONG, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(SHORT, SHORT, "rem", { a, b -> a.rem(b) }, { a, b -> a.rem(b) }), - binaryOperation(SHORT, BYTE, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(SHORT, DOUBLE, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(SHORT, FLOAT, "times", { a, b -> a.times(b) }, emptyBinaryFun), - binaryOperation(SHORT, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(SHORT, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(SHORT, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }), - binaryOperation(STRING, STRING, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun), - binaryOperation(STRING, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun), - binaryOperation(STRING, INT, "get", { a, b -> a.get(b) }, emptyBinaryFun), - binaryOperation(STRING, ANY, "plus", { a, b -> a.plus(b) }, emptyBinaryFun) -) +internal fun evalBinaryOp(name: String, leftType: CompileTimeType, left: Any, rightType: CompileTimeType, right: Any): Any? { + when (leftType) { + BOOLEAN -> when (rightType) { + BOOLEAN -> when (name) { + "and" -> return (left as Boolean).and(right as Boolean) + "compareTo" -> return (left as Boolean).compareTo(right as Boolean) + "or" -> return (left as Boolean).or(right as Boolean) + "xor" -> return (left as Boolean).xor(right as Boolean) + } + ANY -> when (name) { + "equals" -> return (left as Boolean).equals(right) + } + } + BYTE -> when (rightType) { + BYTE -> when (name) { + "compareTo" -> return (left as Byte).compareTo(right as Byte) + "div" -> return (left as Byte).div(right as Byte) + "minus" -> return (left as Byte).minus(right as Byte) + "plus" -> return (left as Byte).plus(right as Byte) + "rem" -> return (left as Byte).rem(right as Byte) + "times" -> return (left as Byte).times(right as Byte) + } + DOUBLE -> when (name) { + "compareTo" -> return (left as Byte).compareTo(right as Double) + "div" -> return (left as Byte).div(right as Double) + "minus" -> return (left as Byte).minus(right as Double) + "plus" -> return (left as Byte).plus(right as Double) + "rem" -> return (left as Byte).rem(right as Double) + "times" -> return (left as Byte).times(right as Double) + } + FLOAT -> when (name) { + "compareTo" -> return (left as Byte).compareTo(right as Float) + "div" -> return (left as Byte).div(right as Float) + "minus" -> return (left as Byte).minus(right as Float) + "plus" -> return (left as Byte).plus(right as Float) + "rem" -> return (left as Byte).rem(right as Float) + "times" -> return (left as Byte).times(right as Float) + } + INT -> when (name) { + "compareTo" -> return (left as Byte).compareTo(right as Int) + "div" -> return (left as Byte).div(right as Int) + "minus" -> return (left as Byte).minus(right as Int) + "plus" -> return (left as Byte).plus(right as Int) + "rem" -> return (left as Byte).rem(right as Int) + "times" -> return (left as Byte).times(right as Int) + } + LONG -> when (name) { + "compareTo" -> return (left as Byte).compareTo(right as Long) + "div" -> return (left as Byte).div(right as Long) + "minus" -> return (left as Byte).minus(right as Long) + "plus" -> return (left as Byte).plus(right as Long) + "rem" -> return (left as Byte).rem(right as Long) + "times" -> return (left as Byte).times(right as Long) + } + SHORT -> when (name) { + "compareTo" -> return (left as Byte).compareTo(right as Short) + "div" -> return (left as Byte).div(right as Short) + "minus" -> return (left as Byte).minus(right as Short) + "plus" -> return (left as Byte).plus(right as Short) + "rem" -> return (left as Byte).rem(right as Short) + "times" -> return (left as Byte).times(right as Short) + } + ANY -> when (name) { + "equals" -> return (left as Byte).equals(right) + } + } + CHAR -> when (rightType) { + CHAR -> when (name) { + "compareTo" -> return (left as Char).compareTo(right as Char) + "minus" -> return (left as Char).minus(right as Char) + } + ANY -> when (name) { + "equals" -> return (left as Char).equals(right) + } + INT -> when (name) { + "minus" -> return (left as Char).minus(right as Int) + "plus" -> return (left as Char).plus(right as Int) + } + } + DOUBLE -> when (rightType) { + BYTE -> when (name) { + "compareTo" -> return (left as Double).compareTo(right as Byte) + "div" -> return (left as Double).div(right as Byte) + "minus" -> return (left as Double).minus(right as Byte) + "plus" -> return (left as Double).plus(right as Byte) + "rem" -> return (left as Double).rem(right as Byte) + "times" -> return (left as Double).times(right as Byte) + } + DOUBLE -> when (name) { + "compareTo" -> return (left as Double).compareTo(right as Double) + "div" -> return (left as Double).div(right as Double) + "minus" -> return (left as Double).minus(right as Double) + "plus" -> return (left as Double).plus(right as Double) + "rem" -> return (left as Double).rem(right as Double) + "times" -> return (left as Double).times(right as Double) + } + FLOAT -> when (name) { + "compareTo" -> return (left as Double).compareTo(right as Float) + "div" -> return (left as Double).div(right as Float) + "minus" -> return (left as Double).minus(right as Float) + "plus" -> return (left as Double).plus(right as Float) + "rem" -> return (left as Double).rem(right as Float) + "times" -> return (left as Double).times(right as Float) + } + INT -> when (name) { + "compareTo" -> return (left as Double).compareTo(right as Int) + "div" -> return (left as Double).div(right as Int) + "minus" -> return (left as Double).minus(right as Int) + "plus" -> return (left as Double).plus(right as Int) + "rem" -> return (left as Double).rem(right as Int) + "times" -> return (left as Double).times(right as Int) + } + LONG -> when (name) { + "compareTo" -> return (left as Double).compareTo(right as Long) + "div" -> return (left as Double).div(right as Long) + "minus" -> return (left as Double).minus(right as Long) + "plus" -> return (left as Double).plus(right as Long) + "rem" -> return (left as Double).rem(right as Long) + "times" -> return (left as Double).times(right as Long) + } + SHORT -> when (name) { + "compareTo" -> return (left as Double).compareTo(right as Short) + "div" -> return (left as Double).div(right as Short) + "minus" -> return (left as Double).minus(right as Short) + "plus" -> return (left as Double).plus(right as Short) + "rem" -> return (left as Double).rem(right as Short) + "times" -> return (left as Double).times(right as Short) + } + ANY -> when (name) { + "equals" -> return (left as Double).equals(right) + } + } + FLOAT -> when (rightType) { + BYTE -> when (name) { + "compareTo" -> return (left as Float).compareTo(right as Byte) + "div" -> return (left as Float).div(right as Byte) + "minus" -> return (left as Float).minus(right as Byte) + "plus" -> return (left as Float).plus(right as Byte) + "rem" -> return (left as Float).rem(right as Byte) + "times" -> return (left as Float).times(right as Byte) + } + DOUBLE -> when (name) { + "compareTo" -> return (left as Float).compareTo(right as Double) + "div" -> return (left as Float).div(right as Double) + "minus" -> return (left as Float).minus(right as Double) + "plus" -> return (left as Float).plus(right as Double) + "rem" -> return (left as Float).rem(right as Double) + "times" -> return (left as Float).times(right as Double) + } + FLOAT -> when (name) { + "compareTo" -> return (left as Float).compareTo(right as Float) + "div" -> return (left as Float).div(right as Float) + "minus" -> return (left as Float).minus(right as Float) + "plus" -> return (left as Float).plus(right as Float) + "rem" -> return (left as Float).rem(right as Float) + "times" -> return (left as Float).times(right as Float) + } + INT -> when (name) { + "compareTo" -> return (left as Float).compareTo(right as Int) + "div" -> return (left as Float).div(right as Int) + "minus" -> return (left as Float).minus(right as Int) + "plus" -> return (left as Float).plus(right as Int) + "rem" -> return (left as Float).rem(right as Int) + "times" -> return (left as Float).times(right as Int) + } + LONG -> when (name) { + "compareTo" -> return (left as Float).compareTo(right as Long) + "div" -> return (left as Float).div(right as Long) + "minus" -> return (left as Float).minus(right as Long) + "plus" -> return (left as Float).plus(right as Long) + "rem" -> return (left as Float).rem(right as Long) + "times" -> return (left as Float).times(right as Long) + } + SHORT -> when (name) { + "compareTo" -> return (left as Float).compareTo(right as Short) + "div" -> return (left as Float).div(right as Short) + "minus" -> return (left as Float).minus(right as Short) + "plus" -> return (left as Float).plus(right as Short) + "rem" -> return (left as Float).rem(right as Short) + "times" -> return (left as Float).times(right as Short) + } + ANY -> when (name) { + "equals" -> return (left as Float).equals(right) + } + } + INT -> when (rightType) { + INT -> when (name) { + "and" -> return (left as Int).and(right as Int) + "compareTo" -> return (left as Int).compareTo(right as Int) + "div" -> return (left as Int).div(right as Int) + "minus" -> return (left as Int).minus(right as Int) + "or" -> return (left as Int).or(right as Int) + "plus" -> return (left as Int).plus(right as Int) + "rem" -> return (left as Int).rem(right as Int) + "shl" -> return (left as Int).shl(right as Int) + "shr" -> return (left as Int).shr(right as Int) + "times" -> return (left as Int).times(right as Int) + "ushr" -> return (left as Int).ushr(right as Int) + "xor" -> return (left as Int).xor(right as Int) + } + BYTE -> when (name) { + "compareTo" -> return (left as Int).compareTo(right as Byte) + "div" -> return (left as Int).div(right as Byte) + "minus" -> return (left as Int).minus(right as Byte) + "plus" -> return (left as Int).plus(right as Byte) + "rem" -> return (left as Int).rem(right as Byte) + "times" -> return (left as Int).times(right as Byte) + } + DOUBLE -> when (name) { + "compareTo" -> return (left as Int).compareTo(right as Double) + "div" -> return (left as Int).div(right as Double) + "minus" -> return (left as Int).minus(right as Double) + "plus" -> return (left as Int).plus(right as Double) + "rem" -> return (left as Int).rem(right as Double) + "times" -> return (left as Int).times(right as Double) + } + FLOAT -> when (name) { + "compareTo" -> return (left as Int).compareTo(right as Float) + "div" -> return (left as Int).div(right as Float) + "minus" -> return (left as Int).minus(right as Float) + "plus" -> return (left as Int).plus(right as Float) + "rem" -> return (left as Int).rem(right as Float) + "times" -> return (left as Int).times(right as Float) + } + LONG -> when (name) { + "compareTo" -> return (left as Int).compareTo(right as Long) + "div" -> return (left as Int).div(right as Long) + "minus" -> return (left as Int).minus(right as Long) + "plus" -> return (left as Int).plus(right as Long) + "rem" -> return (left as Int).rem(right as Long) + "times" -> return (left as Int).times(right as Long) + } + SHORT -> when (name) { + "compareTo" -> return (left as Int).compareTo(right as Short) + "div" -> return (left as Int).div(right as Short) + "minus" -> return (left as Int).minus(right as Short) + "plus" -> return (left as Int).plus(right as Short) + "rem" -> return (left as Int).rem(right as Short) + "times" -> return (left as Int).times(right as Short) + } + ANY -> when (name) { + "equals" -> return (left as Int).equals(right) + } + } + LONG -> when (rightType) { + LONG -> when (name) { + "and" -> return (left as Long).and(right as Long) + "compareTo" -> return (left as Long).compareTo(right as Long) + "div" -> return (left as Long).div(right as Long) + "minus" -> return (left as Long).minus(right as Long) + "or" -> return (left as Long).or(right as Long) + "plus" -> return (left as Long).plus(right as Long) + "rem" -> return (left as Long).rem(right as Long) + "times" -> return (left as Long).times(right as Long) + "xor" -> return (left as Long).xor(right as Long) + } + BYTE -> when (name) { + "compareTo" -> return (left as Long).compareTo(right as Byte) + "div" -> return (left as Long).div(right as Byte) + "minus" -> return (left as Long).minus(right as Byte) + "plus" -> return (left as Long).plus(right as Byte) + "rem" -> return (left as Long).rem(right as Byte) + "times" -> return (left as Long).times(right as Byte) + } + DOUBLE -> when (name) { + "compareTo" -> return (left as Long).compareTo(right as Double) + "div" -> return (left as Long).div(right as Double) + "minus" -> return (left as Long).minus(right as Double) + "plus" -> return (left as Long).plus(right as Double) + "rem" -> return (left as Long).rem(right as Double) + "times" -> return (left as Long).times(right as Double) + } + FLOAT -> when (name) { + "compareTo" -> return (left as Long).compareTo(right as Float) + "div" -> return (left as Long).div(right as Float) + "minus" -> return (left as Long).minus(right as Float) + "plus" -> return (left as Long).plus(right as Float) + "rem" -> return (left as Long).rem(right as Float) + "times" -> return (left as Long).times(right as Float) + } + INT -> when (name) { + "compareTo" -> return (left as Long).compareTo(right as Int) + "div" -> return (left as Long).div(right as Int) + "minus" -> return (left as Long).minus(right as Int) + "plus" -> return (left as Long).plus(right as Int) + "rem" -> return (left as Long).rem(right as Int) + "shl" -> return (left as Long).shl(right as Int) + "shr" -> return (left as Long).shr(right as Int) + "times" -> return (left as Long).times(right as Int) + "ushr" -> return (left as Long).ushr(right as Int) + } + SHORT -> when (name) { + "compareTo" -> return (left as Long).compareTo(right as Short) + "div" -> return (left as Long).div(right as Short) + "minus" -> return (left as Long).minus(right as Short) + "plus" -> return (left as Long).plus(right as Short) + "rem" -> return (left as Long).rem(right as Short) + "times" -> return (left as Long).times(right as Short) + } + ANY -> when (name) { + "equals" -> return (left as Long).equals(right) + } + } + SHORT -> when (rightType) { + BYTE -> when (name) { + "compareTo" -> return (left as Short).compareTo(right as Byte) + "div" -> return (left as Short).div(right as Byte) + "minus" -> return (left as Short).minus(right as Byte) + "plus" -> return (left as Short).plus(right as Byte) + "rem" -> return (left as Short).rem(right as Byte) + "times" -> return (left as Short).times(right as Byte) + } + DOUBLE -> when (name) { + "compareTo" -> return (left as Short).compareTo(right as Double) + "div" -> return (left as Short).div(right as Double) + "minus" -> return (left as Short).minus(right as Double) + "plus" -> return (left as Short).plus(right as Double) + "rem" -> return (left as Short).rem(right as Double) + "times" -> return (left as Short).times(right as Double) + } + FLOAT -> when (name) { + "compareTo" -> return (left as Short).compareTo(right as Float) + "div" -> return (left as Short).div(right as Float) + "minus" -> return (left as Short).minus(right as Float) + "plus" -> return (left as Short).plus(right as Float) + "rem" -> return (left as Short).rem(right as Float) + "times" -> return (left as Short).times(right as Float) + } + INT -> when (name) { + "compareTo" -> return (left as Short).compareTo(right as Int) + "div" -> return (left as Short).div(right as Int) + "minus" -> return (left as Short).minus(right as Int) + "plus" -> return (left as Short).plus(right as Int) + "rem" -> return (left as Short).rem(right as Int) + "times" -> return (left as Short).times(right as Int) + } + LONG -> when (name) { + "compareTo" -> return (left as Short).compareTo(right as Long) + "div" -> return (left as Short).div(right as Long) + "minus" -> return (left as Short).minus(right as Long) + "plus" -> return (left as Short).plus(right as Long) + "rem" -> return (left as Short).rem(right as Long) + "times" -> return (left as Short).times(right as Long) + } + SHORT -> when (name) { + "compareTo" -> return (left as Short).compareTo(right as Short) + "div" -> return (left as Short).div(right as Short) + "minus" -> return (left as Short).minus(right as Short) + "plus" -> return (left as Short).plus(right as Short) + "rem" -> return (left as Short).rem(right as Short) + "times" -> return (left as Short).times(right as Short) + } + ANY -> when (name) { + "equals" -> return (left as Short).equals(right) + } + } + STRING -> when (rightType) { + STRING -> when (name) { + "compareTo" -> return (left as String).compareTo(right as String) + } + ANY -> when (name) { + "equals" -> return (left as String).equals(right) + "plus" -> return (left as String).plus(right) + } + INT -> when (name) { + "get" -> return (left as String).get(right as Int) + } + } + } + return null +} + +internal fun checkBinaryOp( + name: String, leftType: CompileTimeType, left: BigInteger, rightType: CompileTimeType, right: BigInteger +): BigInteger? { + when (leftType) { + BYTE -> when (rightType) { + BYTE -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + INT -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + LONG -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + SHORT -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + } + INT -> when (rightType) { + INT -> when (name) { + "and" -> return left.and(right) + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "or" -> return left.or(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + "xor" -> return left.xor(right) + } + BYTE -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + LONG -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + SHORT -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + } + LONG -> when (rightType) { + LONG -> when (name) { + "and" -> return left.and(right) + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "or" -> return left.or(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + "xor" -> return left.xor(right) + } + BYTE -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + INT -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + SHORT -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + } + SHORT -> when (rightType) { + BYTE -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + INT -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + LONG -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + SHORT -> when (name) { + "div" -> return left.divide(right) + "minus" -> return left.subtract(right) + "plus" -> return left.add(right) + "rem" -> return left.rem(right) + "times" -> return left.multiply(right) + } + } + } + return null +} diff --git a/generators/evaluate/GenerateOperationsMap.kt b/generators/evaluate/GenerateOperationsMap.kt index e2a7646c391..acf4d3931fa 100644 --- a/generators/evaluate/GenerateOperationsMap.kt +++ b/generators/evaluate/GenerateOperationsMap.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.utils.Printer import java.io.File @@ -27,29 +27,30 @@ fun generate(): String { val sb = StringBuilder() val p = Printer(sb) p.println(File("license/COPYRIGHT.txt").readText()) - p.println("@file:Suppress(\"DEPRECATION\", \"DEPRECATION_ERROR\")") + p.println("@file:Suppress(\"DEPRECATION\", \"DEPRECATION_ERROR\", \"NON_EXHAUSTIVE_WHEN\")") p.println() p.println("package org.jetbrains.kotlin.resolve.constants.evaluate") p.println() + p.println("import org.jetbrains.kotlin.resolve.constants.evaluate.CompileTimeType.*") p.println("import java.math.BigInteger") - p.println("import java.util.HashMap") p.println() - p.println("/** This file is generated by org.jetbrains.kotlin.generators.evaluate:generate(). DO NOT MODIFY MANUALLY */") + p.println("/** This file is generated by `./gradlew generateOperationsMap`. DO NOT MODIFY MANUALLY */") p.println() val unaryOperationsMap = arrayListOf, Boolean>>() val binaryOperationsMap = arrayListOf>>() val builtIns = DefaultBuiltIns.Instance + @Suppress("UNCHECKED_CAST") val allPrimitiveTypes = builtIns.builtInsPackageScope.getContributedDescriptors() - .filter { it is ClassDescriptor && KotlinBuiltIns.isPrimitiveType(it.defaultType) } as List + .filter { it is ClassDescriptor && KotlinBuiltIns.isPrimitiveType(it.defaultType) } as List for (descriptor in allPrimitiveTypes + builtIns.string) { @Suppress("UNCHECKED_CAST") val functions = descriptor.getMemberScope(listOf()).getContributedDescriptors() - .filter { it is CallableDescriptor && !EXCLUDED_FUNCTIONS.contains(it.getName().asString()) } as List + .filter { it is CallableDescriptor && !EXCLUDED_FUNCTIONS.contains(it.getName().asString()) } as List for (function in functions) { val parametersTypes = function.getParametersTypes() @@ -57,108 +58,116 @@ fun generate(): String { when (parametersTypes.size) { 1 -> unaryOperationsMap.add(Triple(function.name.asString(), parametersTypes, function is FunctionDescriptor)) 2 -> binaryOperationsMap.add(function.name.asString() to parametersTypes) - else -> throw IllegalStateException("Couldn't add following method from builtins to operations map: ${function.name} in class ${descriptor.name}") + else -> throw IllegalStateException( + "Couldn't add following method from builtins to operations map: ${function.name} in class ${descriptor.name}" + ) } } } - p.println("internal val emptyBinaryFun: Function2 = { _, _ -> BigInteger(\"0\") }") - p.println("internal val emptyUnaryFun: Function1 = { _ -> 1.toLong() }") - p.println() - p.println("internal val unaryOperations: HashMap, Pair, Function1>>") - p.println(" = hashMapOf, Pair, Function1>>(") + p.println("internal fun evalUnaryOp(name: String, type: CompileTimeType, value: Any): Any? {") p.pushIndent() - - val unaryOperationsMapIterator = unaryOperationsMap.iterator() - while (unaryOperationsMapIterator.hasNext()) { - val (funcName, parameters, isFunction) = unaryOperationsMapIterator.next() - val parenthesesOrBlank = if (isFunction) "()" else "" - p.println( - "unaryOperation(", - parameters.map { it.asString() }.joinToString(", "), - ", ", - "\"$funcName\"", - ", { a -> a.$funcName$parenthesesOrBlank }, ", - renderCheckUnaryOperation(funcName, parameters), - ")", - if (unaryOperationsMapIterator.hasNext()) "," else "" - ) + p.println("when (type) {") + p.pushIndent() + for ((type, operations) in unaryOperationsMap.groupBy { (_, parameters, _) -> parameters.single() }) { + p.println("${type.asString()} -> when (name) {") + p.pushIndent() + for ((name, _, isFunction) in operations) { + val parenthesesOrBlank = if (isFunction) "()" else "" + p.println("\"$name\" -> return (value as ${type.typeName}).$name$parenthesesOrBlank") + } + p.popIndent() + p.println("}") } p.popIndent() - p.println(")") - + p.println("}") + p.println("return null") + p.popIndent() + p.println("}") + p.println() p.println() - p.println("internal val binaryOperations: HashMap, Pair, Function2>>") - p.println(" = hashMapOf, Pair, Function2>>(") + p.println("internal fun evalBinaryOp(name: String, leftType: CompileTimeType, left: Any, rightType: CompileTimeType, right: Any): Any? {") p.pushIndent() - - val binaryOperationsMapIterator = binaryOperationsMap.iterator() - while (binaryOperationsMapIterator.hasNext()) { - val (funcName, parameters) = binaryOperationsMapIterator.next() - p.println( - "binaryOperation(", - parameters.map { it.asString() }.joinToString(", "), - ", ", - "\"$funcName\"", - ", { a, b -> a.$funcName(b) }, ", - renderCheckBinaryOperation(funcName, parameters), - ")", - if (binaryOperationsMapIterator.hasNext()) "," else "" - ) + p.println("when (leftType) {") + p.pushIndent() + for ((leftType, operationsOnThisLeftType) in binaryOperationsMap.groupBy { (_, parameters) -> parameters.first() }) { + p.println("${leftType.asString()} -> when (rightType) {") + p.pushIndent() + for ((rightType, operations) in operationsOnThisLeftType.groupBy { (_, parameters) -> parameters[1] }) { + p.println("${rightType.asString()} -> when (name) {") + p.pushIndent() + for ((name, _) in operations) { + val castToRightType = if (rightType.typeName == "Any") "" else " as ${rightType.typeName}" + p.println("\"$name\" -> return (left as ${leftType.typeName}).$name(right$castToRightType)") + } + p.popIndent() + p.println("}") + } + p.popIndent() + p.println("}") } p.popIndent() - p.println(")") + p.println("}") + p.println("return null") + p.popIndent() + p.println("}") + p.println() + + p.println("internal fun checkBinaryOp(") + p.println(" name: String, leftType: CompileTimeType, left: BigInteger, rightType: CompileTimeType, right: BigInteger") + p.println("): BigInteger? {") + p.pushIndent() + p.println("when (leftType) {") + p.pushIndent() + val checkedBinaryOperations = + binaryOperationsMap.filter { (name, parameters) -> getBinaryCheckerName(name, parameters[0], parameters[1]) != null } + for ((leftType, operationsOnThisLeftType) in checkedBinaryOperations.groupBy { (_, parameters) -> parameters.first() }) { + p.println("${leftType.asString()} -> when (rightType) {") + p.pushIndent() + for ((rightType, operations) in operationsOnThisLeftType.groupBy { (_, parameters) -> parameters[1] }) { + p.println("${rightType.asString()} -> when (name) {") + p.pushIndent() + for ((name, _) in operations) { + val checkerName = getBinaryCheckerName(name, leftType, rightType)!! + p.println("\"$name\" -> return left.$checkerName(right)") + } + p.popIndent() + p.println("}") + } + p.popIndent() + p.println("}") + } + p.popIndent() + p.println("}") + p.println("return null") + p.popIndent() + p.println("}") return sb.toString() } -fun renderCheckUnaryOperation(name: String, params: List): String { - val isAllParamsIntegers = params.fold(true) { a, b -> a && b.isIntegerType() } - if (!isAllParamsIntegers) { - return "emptyUnaryFun" - } +private fun getBinaryCheckerName(name: String, leftType: KotlinType, rightType: KotlinType): String? { + if (!leftType.isIntegerType() || !rightType.isIntegerType()) return null - return when(name) { - "unaryMinus", "minus" -> "{ a -> a.$name() }" - else -> "emptyUnaryFun" + return when (name) { + "plus" -> "add" + "minus" -> "subtract" + "div" -> "divide" + "times" -> "multiply" + "mod", "rem", "xor", "or", "and" -> name + else -> null } } -fun renderCheckBinaryOperation(name: String, params: List): String { - val isAllParamsIntegers = params.fold(true) { a, b -> a && b.isIntegerType() } - if (!isAllParamsIntegers) { - return "emptyBinaryFun" - } +private fun KotlinType.isIntegerType(): Boolean = + KotlinBuiltIns.isInt(this) || KotlinBuiltIns.isShort(this) || KotlinBuiltIns.isByte(this) || KotlinBuiltIns.isLong(this) - return when(name) { - "plus" -> "{ a, b -> a.add(b) }" - "minus" -> "{ a, b -> a.subtract(b) }" - "div" -> "{ a, b -> a.divide(b) }" - "times" -> "{ a, b -> a.multiply(b) }" - "mod", - "rem", - "xor", - "or", - "and" -> "{ a, b -> a.$name(b) }" - else -> "emptyBinaryFun" - } -} +private fun CallableDescriptor.getParametersTypes(): List = + listOf((containingDeclaration as ClassDescriptor).defaultType) + + valueParameters.map { it.type.makeNotNullable() } -private fun KotlinType.isIntegerType(): Boolean { - return KotlinBuiltIns.isInt(this) || - KotlinBuiltIns.isShort(this) || - KotlinBuiltIns.isByte(this) || - KotlinBuiltIns.isLong(this) -} +private fun KotlinType.asString(): String = typeName.toUpperCase() - -private fun CallableDescriptor.getParametersTypes(): List { - val list = arrayListOf((containingDeclaration as ClassDescriptor).defaultType) - valueParameters.map { it.type }.forEach { - list.add(TypeUtils.makeNotNullable(it)) - } - return list -} - -private fun KotlinType.asString(): String = constructor.declarationDescriptor!!.name.asString().toUpperCase() +private val KotlinType.typeName: String + get(): String = constructor.declarationDescriptor!!.name.asString() From 4374438ff1a873245ee095912465ecd4112cec4b Mon Sep 17 00:00:00 2001 From: scaventz Date: Thu, 24 Dec 2020 21:44:32 +0800 Subject: [PATCH 033/197] Kotlinc: Exclude module-info.class from resulting jar when "-include-runtime" is specified --- .../jvm/compiler/CompileEnvironmentUtil.java | 4 ++ ...ministicOutputTest.kt => JarOutputTest.kt} | 41 +++++++++++++------ 2 files changed, 33 insertions(+), 12 deletions(-) rename compiler/tests/org/jetbrains/kotlin/cli/{DeterministicOutputTest.kt => JarOutputTest.kt} (73%) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java index bc73eeeb1b9..bf145a2e193 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.cli.jvm.compiler; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import kotlin.io.FilesKt; +import kotlin.text.StringsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.backend.common.output.OutputFile; @@ -131,6 +132,9 @@ public class CompileEnvironmentUtil { if (e == null) { break; } + if (StringsKt.substringAfterLast(e.getName(), "/", e.getName()).equals("module-info.class")) { + continue; + } if (resetJarTimestamps) { e.setTime(DOS_EPOCH); } diff --git a/compiler/tests/org/jetbrains/kotlin/cli/DeterministicOutputTest.kt b/compiler/tests/org/jetbrains/kotlin/cli/JarOutputTest.kt similarity index 73% rename from compiler/tests/org/jetbrains/kotlin/cli/DeterministicOutputTest.kt rename to compiler/tests/org/jetbrains/kotlin/cli/JarOutputTest.kt index 4ba2a4cf8c3..f32c85e8274 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/DeterministicOutputTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/cli/JarOutputTest.kt @@ -17,16 +17,14 @@ package org.jetbrains.kotlin.cli import java.io.File -import java.io.FileInputStream -import java.util.jar.JarInputStream -import java.util.zip.ZipEntry import kotlin.test.assertEquals import kotlin.test.assertNotEquals import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil.DOS_EPOCH import org.jetbrains.kotlin.test.TestCaseWithTmpdir +import java.util.jar.JarFile -class DeterministicOutputTest : TestCaseWithTmpdir() { +class JarOutputTest : TestCaseWithTmpdir() { fun testDeterministicOutput() { val fooKt = tmpdir.resolve("foo.kt").also { @@ -63,21 +61,40 @@ class DeterministicOutputTest : TestCaseWithTmpdir() { assertNoTimestampsAreReset(jar) } + /** + * KT-44078 + */ + fun testNoModuleInfoClass() { + val fooKt = tmpdir.resolve("foo.kt").also { + it.writeText("class Foo") + } + val jar = tmpdir.resolve("jarWithoutModuleInfoClass.jar") + AbstractCliTest.executeCompilerGrabOutput( + K2JVMCompiler(), + listOf(fooKt.path, "-d", jar.path, "-include-runtime") + ) + + assertNoModuleInfoClass(jar) + } + private fun assertAllTimestampsAreReset(jar: File) { - val zis = JarInputStream(FileInputStream(jar)) - var entry: ZipEntry? = zis.nextEntry - while (entry != null) { + for (entry in JarFile(jar).entries()) { assertEquals(entry.time, DOS_EPOCH, "$entry timestamp should be reset") - entry = zis.nextEntry } } private fun assertNoTimestampsAreReset(jar: File) { - val zis = JarInputStream(FileInputStream(jar)) - var entry: ZipEntry? = zis.nextEntry - while (entry != null) { + for (entry in JarFile(jar).entries()) { assertNotEquals(entry.time, DOS_EPOCH, "$entry timestamp should not be reset") - entry = zis.nextEntry + } + } + + private fun assertNoModuleInfoClass(jar: File) { + for (entry in JarFile(jar).entries()) { + assertNotEquals( + "module-info.class", entry.name.substringAfterLast("/"), + "$entry is expected to be excluded from the resulting jar" + ) } } } From 0fef890d1a412c9c72c3e74bac91315b05ed4492 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 12 Jan 2021 13:08:45 +0100 Subject: [PATCH 034/197] Minor refactoring in CompileEnvironmentUtil --- .../cli/jvm/compiler/CompileEnvironmentUtil.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java index bf145a2e193..ec109d3b274 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java @@ -129,19 +129,17 @@ public class CompileEnvironmentUtil { try (JarInputStream jis = new JarInputStream(new FileInputStream(jarPath))) { while (true) { JarEntry e = jis.getNextJarEntry(); - if (e == null) { - break; - } - if (StringsKt.substringAfterLast(e.getName(), "/", e.getName()).equals("module-info.class")) { + if (e == null) break; + + if (!FileUtilRt.extensionEquals(e.getName(), "class") || + StringsKt.substringAfterLast(e.getName(), "/", e.getName()).equals("module-info.class")) { continue; } if (resetJarTimestamps) { e.setTime(DOS_EPOCH); } - if (FileUtilRt.extensionEquals(e.getName(), "class")) { - stream.putNextEntry(e); - FileUtil.copy(jis, stream); - } + stream.putNextEntry(e); + FileUtil.copy(jis, stream); } } } From 69e1d60b088a44812637e5a817c867cf9ac47626 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 2 Dec 2020 12:59:16 +0300 Subject: [PATCH 035/197] [IDE] Drop coroutines combo box from compiler configuration tab --- .../messages/KotlinBundle.properties | 3 +- .../KotlinCompilerConfigurableTab.form | 24 ------------ .../KotlinCompilerConfigurableTab.java | 39 ------------------- .../idea/facet/KotlinFacetEditorGeneralTab.kt | 1 - .../idea/facet/MultipleKotlinFacetEditor.kt | 3 +- 5 files changed, 2 insertions(+), 68 deletions(-) diff --git a/idea/resources-en/messages/KotlinBundle.properties b/idea/resources-en/messages/KotlinBundle.properties index 7a3536e6bf2..2bcbf9fcc28 100644 --- a/idea/resources-en/messages/KotlinBundle.properties +++ b/idea/resources-en/messages/KotlinBundle.properties @@ -1850,7 +1850,6 @@ destination.directory=&Destination directory language.version=&Language version add.prefix.to.paths.in.source.map=Add prefix to paths in source map: api.version=AP&I version -compiler.coroutines=Coro&utines embed.source.code.into.source.map=Embed source code into source map: enable.incremental.compilation=Enable incremental compilation keep.compiler.process.alive.between.invocations=Keep compiler process alive between invocations @@ -2222,4 +2221,4 @@ hints.codevision.inheritors.to_many.format={0,number}+ Inheritors hints.codevision.overrides.format={0, choice, 1#1 Override|2#{0,number} Overrides} hints.codevision.overrides.to_many.format={0,number}+ Overrides hints.codevision.settings=Settings... -inspection.unused.result.of.data.class.copy=Unused result of data class copy \ No newline at end of file +inspection.unused.result.of.data.class.copy=Unused result of data class copy diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form index 9e9e89f373f..745e6a86801 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.form @@ -331,30 +331,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java index d3ba8f912a1..7c1ce14f70d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java +++ b/idea/src/org/jetbrains/kotlin/idea/compiler/configuration/KotlinCompilerConfigurableTab.java @@ -103,7 +103,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { private JPanel k2jsPanel; private JComboBox jvmVersionComboBox; private JComboBox languageVersionComboBox; - private JComboBox coroutineSupportComboBox; private JComboBox apiVersionComboBox; private JPanel scriptPanel; private JLabel labelForOutputPrefixFile; @@ -141,7 +140,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { additionalArgsOptionsField.attachLabel(additionalArgsLabel); fillLanguageAndAPIVersionList(); - fillCoroutineSupportList(); if (CidrUtil.isRunningInCidrIde()) { keepAliveCheckBox.setVisible(false); @@ -382,14 +380,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { apiVersionComboBox.setRenderer(new DescriptionListCellRenderer()); } - @SuppressWarnings("unchecked") - private void fillCoroutineSupportList() { - for (LanguageFeature.State coroutineSupport : languageFeatureStates) { - coroutineSupportComboBox.addItem(coroutineSupport); - } - coroutineSupportComboBox.setRenderer(new DescriptionListCellRenderer()); - } - public void setTargetPlatform(@Nullable IdePlatformKind targetPlatform) { k2jsPanel.setVisible(JsIdePlatformUtil.isJavaScript(targetPlatform)); scriptPanel.setVisible(JvmIdePlatformUtil.isJvm(targetPlatform)); @@ -444,7 +434,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { return isModified(reportWarningsCheckBox, !commonCompilerArguments.getSuppressWarnings()) || !getSelectedLanguageVersionView().equals(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)) || !getSelectedAPIVersionView().equals(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)) || - !getSelectedCoroutineState().equals(commonCompilerArguments.getCoroutinesState()) || !additionalArgsOptionsField.getText().equals(compilerSettings.getAdditionalArguments()) || isModified(scriptTemplatesField, compilerSettings.getScriptTemplates()) || isModified(scriptTemplatesClasspathField, compilerSettings.getScriptTemplatesClasspath()) || @@ -492,26 +481,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { return item != null ? (VersionView) item : VersionView.LatestStable.INSTANCE; } - @NotNull - private String getSelectedCoroutineState() { - if (getSelectedLanguageVersionView().getVersion().compareTo(LanguageVersion.KOTLIN_1_3) >= 0) { - return CommonCompilerArguments.DEFAULT; - } - - LanguageFeature.State state = (LanguageFeature.State) coroutineSupportComboBox.getSelectedItem(); - if (state == null) return CommonCompilerArguments.DEFAULT; - switch (state) { - case ENABLED: - return CommonCompilerArguments.ENABLE; - case ENABLED_WITH_WARNING: - return CommonCompilerArguments.WARN; - case ENABLED_WITH_ERROR: - return CommonCompilerArguments.ERROR; - default: - return CommonCompilerArguments.DEFAULT; - } - } - public void applyTo( CommonCompilerArguments commonCompilerArguments, K2JVMCompilerArguments k2jvmCompilerArguments, @@ -522,7 +491,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { boolean shouldInvalidateCaches = !getSelectedLanguageVersionView().equals(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)) || !getSelectedAPIVersionView().equals(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)) || - !getSelectedCoroutineState().equals(commonCompilerArguments.getCoroutinesState()) || !additionalArgsOptionsField.getText().equals(compilerSettings.getAdditionalArguments()); if (shouldInvalidateCaches) { @@ -542,8 +510,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { KotlinFacetSettingsKt.setLanguageVersionView(commonCompilerArguments, getSelectedLanguageVersionView()); KotlinFacetSettingsKt.setApiVersionView(commonCompilerArguments, getSelectedAPIVersionView()); - commonCompilerArguments.setCoroutinesState(getSelectedCoroutineState()); - compilerSettings.setAdditionalArguments(additionalArgsOptionsField.getText()); compilerSettings.setScriptTemplates(scriptTemplatesField.getText()); compilerSettings.setScriptTemplatesClasspath(scriptTemplatesClasspathField.getText()); @@ -595,7 +561,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { setSelectedItem(languageVersionComboBox, KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)); onLanguageLevelChanged((VersionView) languageVersionComboBox.getSelectedItem()); // getSelectedLanguageVersionView() replaces null setSelectedItem(apiVersionComboBox, KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)); - coroutineSupportComboBox.setSelectedItem(CoroutineSupport.byCompilerArguments(commonCompilerArguments)); additionalArgsOptionsField.setText(compilerSettings.getAdditionalArguments()); scriptTemplatesField.setText(compilerSettings.getScriptTemplates()); scriptTemplatesClasspathField.setText(compilerSettings.getScriptTemplatesClasspath()); @@ -701,10 +666,6 @@ public class KotlinCompilerConfigurableTab implements SearchableConfigurable { return apiVersionComboBox; } - public JComboBox getCoroutineSupportComboBox() { - return coroutineSupportComboBox; - } - public void setEnabled(boolean value) { isEnabled = value; UIUtil.setEnabled(getContentPane(), value, true); diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt index 369626ef947..c48330588e9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/KotlinFacetEditorGeneralTab.kt @@ -347,7 +347,6 @@ class KotlinFacetEditorGeneralTab( doValidate() } apiVersionComboBox.validateOnChange() - coroutineSupportComboBox.validateOnChange() } editor.targetPlatformSelectSingleCombobox.validateOnChange() diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt b/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt index 4e487f54677..eb51021232b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/MultipleKotlinFacetEditor.kt @@ -45,7 +45,6 @@ class MultipleKotlinFacetEditor( helper.bind(scriptTemplatesClasspathField, editors) { it.compilerConfigurable.scriptTemplatesClasspathField } helper.bind(languageVersionComboBox, editors) { it.compilerConfigurable.languageVersionComboBox } helper.bind(apiVersionComboBox, editors) { it.compilerConfigurable.apiVersionComboBox } - helper.bind(coroutineSupportComboBox, editors) { it.compilerConfigurable.coroutineSupportComboBox } } } } @@ -56,4 +55,4 @@ class MultipleKotlinFacetEditor( // Their settings might have changed to non-project one due to UI control binding editors.map { it.tabEditor }.filter { it.useProjectSettingsCheckBox.isSelected }.forEach { it.updateCompilerConfigurable() } } -} \ No newline at end of file +} From a8b65bc6736f580042ed632cc44bc2bef091ac26 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 2 Dec 2020 13:03:19 +0300 Subject: [PATCH 036/197] [IDE] Drop coroutines KotlinFacetSettings.coroutineSupport --- .../jetbrains/kotlin/idea/project/Platform.kt | 26 +------------------ .../gradle/GradleFacetImportTest.kt | 20 -------------- .../kotlin/config/KotlinFacetSettings.kt | 15 ----------- .../KotlinWithLibraryConfigurator.kt | 1 - .../idea/maven/KotlinMavenImporterTest.kt | 7 +---- .../jetbrains/kotlin/idea/facet/facetUtils.kt | 1 - .../resolve/MultiModuleHighlightingTest.kt | 2 -- .../UpdateConfigurationQuickFixTest.kt | 24 ----------------- .../idea/stubs/AbstractMultiModuleTest.kt | 1 - 9 files changed, 2 insertions(+), 95 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt index 1a62ac4b45c..5919ae3daea 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt @@ -136,18 +136,7 @@ fun Project.getLanguageVersionSettings( compilerSettings.additionalArgumentsAsList ) - val extraLanguageFeatures = additionalArguments.configureLanguageFeatures(MessageCollector.NONE).apply { - configureCoroutinesSupport( - CoroutineSupport.byCompilerArguments(KotlinCommonCompilerArgumentsHolder.getInstance(this@getLanguageVersionSettings).settings), - languageVersion - ) - if (isReleaseCoroutines != null) { - put( - LanguageFeature.ReleaseCoroutines, - if (isReleaseCoroutines) LanguageFeature.State.ENABLED else LanguageFeature.State.DISABLED - ) - } - } + val extraLanguageFeatures = additionalArguments.configureLanguageFeatures(MessageCollector.NONE) val extraAnalysisFlags = additionalArguments.configureAnalysisFlags(MessageCollector.NONE).apply { if (javaTypeEnhancementState != null) put(JvmAnalysisFlags.javaTypeEnhancementState, javaTypeEnhancementState) @@ -228,7 +217,6 @@ private fun Module.computeLanguageVersionSettings(): LanguageVersionSettings { } val languageFeatures = facetSettings?.mergedCompilerArguments?.configureLanguageFeatures(MessageCollector.NONE)?.apply { - configureCoroutinesSupport(facetSettings.coroutineSupport, languageVersion) configureMultiplatformSupport(facetSettings.targetPlatform?.idePlatformKind, this@computeLanguageVersionSettings) }.orEmpty() @@ -281,18 +269,6 @@ private fun parseArguments( return platformKind.createArguments { parseCommandLineArguments(additionalArguments, this) } } -fun MutableMap.configureCoroutinesSupport( - coroutineSupport: LanguageFeature.State?, - languageVersion: LanguageVersion -) { - val state = if (languageVersion >= LanguageVersion.KOTLIN_1_3) { - LanguageFeature.State.ENABLED - } else { - coroutineSupport ?: LanguageFeature.Coroutines.defaultState - } - put(LanguageFeature.Coroutines, state) -} - fun MutableMap.configureMultiplatformSupport( platformKind: IdePlatformKind<*>?, module: Module? diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt index 7769a937a51..a4ac279f0f4 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt @@ -185,26 +185,6 @@ class GradleFacetImportTest : GradleImportingTestCase() { ) } - @Test - fun testCoroutineImportByOptions() { - configureByFiles() - importProject() - - with(facetSettings) { - Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) - } - } - - @Test - fun testCoroutineImportByProperties() { - configureByFiles() - importProject() - - with(facetSettings) { - Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) - } - } - @Test fun testJsImport() { configureByFiles() diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt index 372eb485866..a7936542f98 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt @@ -275,21 +275,6 @@ class KotlinFacetSettings { return targetPlatform?.toIdePlatform() } - var coroutineSupport: LanguageFeature.State? - get() { - val languageVersion = languageLevel ?: return LanguageFeature.Coroutines.defaultState - if (languageVersion < LanguageFeature.Coroutines.sinceVersion!!) return LanguageFeature.State.DISABLED - return CoroutineSupport.byCompilerArgumentsOrNull(compilerArguments) - } - set(value) { - compilerArguments?.coroutinesState = when (value) { - null -> CommonCompilerArguments.DEFAULT - LanguageFeature.State.ENABLED -> CommonCompilerArguments.ENABLE - LanguageFeature.State.ENABLED_WITH_WARNING -> CommonCompilerArguments.WARN - LanguageFeature.State.ENABLED_WITH_ERROR, LanguageFeature.State.DISABLED -> CommonCompilerArguments.ERROR - } - } - var implementedModuleNames: List = emptyList() // used for first implementation of MPP, aka 'old' MPP var dependsOnModuleNames: List = emptyList() // used for New MPP and later implementations diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index 993dbe513e8..ed06c5d4572 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -357,7 +357,6 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project)?.getInitializedSettings(module) if (facetSettings != null) { ModuleRootModificationUtil.updateModel(module) { - facetSettings.coroutineSupport = state facetSettings.apiLevel = LanguageVersion.KOTLIN_1_1 facetSettings.languageLevel = LanguageVersion.KOTLIN_1_1 } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt index debbbc86483..32b6bc60840 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenImporterTest.kt @@ -625,7 +625,6 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertFalse(compilerArguments!!.autoAdvanceLanguageVersion) Assert.assertFalse(compilerArguments!!.autoAdvanceApiVersion) Assert.assertEquals(true, compilerArguments!!.suppressWarnings) - Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) Assert.assertEquals("JVM 1.8", targetPlatform!!.oldFashionedDescription) Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) Assert.assertEquals("foobar.jar", (compilerArguments as K2JVMCompilerArguments).classpath) @@ -821,7 +820,6 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertFalse(compilerArguments!!.autoAdvanceLanguageVersion) Assert.assertFalse(compilerArguments!!.autoAdvanceApiVersion) Assert.assertEquals(true, compilerArguments!!.suppressWarnings) - Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) Assert.assertTrue(targetPlatform.isJs()) with(compilerArguments as K2JSCompilerArguments) { Assert.assertEquals(true, sourceMap) @@ -976,7 +974,6 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { Assert.assertEquals("1.0", apiLevel!!.versionString) Assert.assertEquals("1.0", compilerArguments!!.apiVersion) Assert.assertEquals(true, compilerArguments!!.suppressWarnings) - Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) Assert.assertEquals("JVM 1.8", targetPlatform!!.oldFashionedDescription) Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) Assert.assertEquals("foobar.jar", (compilerArguments as K2JVMCompilerArguments).classpath) @@ -1039,7 +1036,6 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { with(facetSettings) { Assert.assertEquals("JVM 1.8", targetPlatform!!.oldFashionedDescription) Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) - Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) Assert.assertEquals("c:/program files/jdk1.8", (compilerArguments as K2JVMCompilerArguments).classpath) } } @@ -1095,7 +1091,6 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { with(facetSettings) { Assert.assertEquals("JVM 1.8", targetPlatform!!.oldFashionedDescription) Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) - Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) Assert.assertEquals("c:/program files/jdk1.8", (compilerArguments as K2JVMCompilerArguments).classpath) } } @@ -3047,4 +3042,4 @@ class KotlinMavenImporterTest : MavenImportingTestCase() { private val facetSettings: KotlinFacetSettings get() = facetSettings("project") -} \ No newline at end of file +} diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index 38b2cef7790..fddbda66d62 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -187,7 +187,6 @@ fun KotlinFacet.configureFacet( if (languageLevel != null && apiLevel != null && apiLevel > languageLevel) { this.apiLevel = languageLevel } - this.coroutineSupport = if (languageLevel != null && languageLevel < LanguageVersion.KOTLIN_1_3) coroutineSupport else null this.pureKotlinSourceFolders = pureKotlinSourceFolders } diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt index bf52b8f41bf..5eddff1babc 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiModuleHighlightingTest.kt @@ -273,13 +273,11 @@ open class MultiModuleHighlightingTest : AbstractMultiModuleHighlightingTest() { ) val moduleNew = module("moduleNew").setupKotlinFacet { - settings.coroutineSupport = LanguageFeature.State.ENABLED settings.languageLevel = LanguageVersion.KOTLIN_1_3 settings.apiLevel = LanguageVersion.KOTLIN_1_3 } val moduleOld = module("moduleOld").setupKotlinFacet { - settings.coroutineSupport = LanguageFeature.State.ENABLED settings.languageLevel = LanguageVersion.KOTLIN_1_2 settings.apiLevel = LanguageVersion.KOTLIN_1_2 } diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt b/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt index 7a8c4b44f08..d07f4bae94a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt @@ -79,30 +79,6 @@ class UpdateConfigurationQuickFixTest : KotlinLightPlatformCodeInsightFixtureTes assertEquals(LanguageFeature.State.ENABLED_WITH_ERROR, coroutineSupport) } - fun testEnableCoroutinesFacet() { - configureRuntime("mockRuntime11") - val facet = configureKotlinFacet(module) { - settings.languageLevel = LanguageVersion.KOTLIN_1_1 - } - resetProjectSettings(LanguageVersion.KOTLIN_1_1) - myFixture.configureByText("foo.kt", "suspend fun foo()") - - assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, facet.configuration.settings.coroutineSupport) - myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the current module")) - assertEquals(LanguageFeature.State.ENABLED, facet.configuration.settings.coroutineSupport) - } - - fun testEnableCoroutines_UpdateRuntime() { - configureRuntime("mockRuntime106") - resetProjectSettings(LanguageVersion.KOTLIN_1_1) - myFixture.configureByText("foo.kt", "suspend fun foo()") - - assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, coroutineSupport) - myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the project")) - assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) - assertEquals(bundledRuntimeVersion(), getRuntimeLibraryVersion(myFixture.module)) - } - fun testIncreaseLangLevel() { configureRuntime("mockRuntime11") resetProjectSettings(LanguageVersion.KOTLIN_1_0) diff --git a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt index f74071338f3..0a46a4ef891 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/stubs/AbstractMultiModuleTest.kt @@ -135,7 +135,6 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() { ?: error("Facet settings are not found") facetSettings.useProjectSettings = false - facetSettings.coroutineSupport = LanguageFeature.State.ENABLED } protected fun checkFiles( From 7f4a925b857c63724425e394653ff7d7d40fd99b Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 2 Dec 2020 13:08:09 +0300 Subject: [PATCH 037/197] [FE] Drop `isReleaseCoroutines` flag from LanguageSettingsProvider --- .../src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt | 6 ++---- .../kotlin/idea/caches/resolve/IdeaResolverForProject.kt | 4 ++-- .../kotlin/idea/compiler/IDELanguageSettingsProvider.kt | 5 ++--- .../src/org/jetbrains/kotlin/idea/project/Platform.kt | 3 +-- .../kotlin/ide/konan/NativePlatformKindResolution.kt | 3 +-- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt index 9c7f9e7ec19..1ade8914a3e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt @@ -200,8 +200,7 @@ interface PackageOracleFactory { interface LanguageSettingsProvider { fun getLanguageVersionSettings( moduleInfo: ModuleInfo, - project: Project, - isReleaseCoroutines: Boolean? = null + project: Project ): LanguageVersionSettings fun getTargetPlatform(moduleInfo: ModuleInfo, project: Project): TargetPlatformVersion @@ -209,8 +208,7 @@ interface LanguageSettingsProvider { object Default : LanguageSettingsProvider { override fun getLanguageVersionSettings( moduleInfo: ModuleInfo, - project: Project, - isReleaseCoroutines: Boolean? + project: Project ) = LanguageVersionSettingsImpl.DEFAULT override fun getTargetPlatform(moduleInfo: ModuleInfo, project: Project): TargetPlatformVersion = TargetPlatformVersion.NoVersion diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt index c18b9ab4272..efc49edb9ec 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt @@ -74,7 +74,7 @@ class IdeaResolverForProject( val moduleContent = ModuleContent(moduleInfo, syntheticFilesByModule[moduleInfo] ?: listOf(), moduleInfo.contentScope()) val languageVersionSettings = - IDELanguageSettingsProvider.getLanguageVersionSettings(moduleInfo, projectContext.project, isReleaseCoroutines) + IDELanguageSettingsProvider.getLanguageVersionSettings(moduleInfo, projectContext.project) val resolverForModuleFactory = getResolverForModuleFactory(moduleInfo) @@ -180,4 +180,4 @@ class IdeaResolverForProject( interface BuiltInsCacheKey { object DefaultBuiltInsKey : BuiltInsCacheKey -} \ No newline at end of file +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt index 525c74181f2..d70e3bc6994 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt @@ -45,13 +45,12 @@ import org.jetbrains.kotlin.utils.JavaTypeEnhancementState object IDELanguageSettingsProvider : LanguageSettingsProvider { override fun getLanguageVersionSettings( moduleInfo: ModuleInfo, - project: Project, - isReleaseCoroutines: Boolean? + project: Project ): LanguageVersionSettings = when (moduleInfo) { is ModuleSourceInfo -> moduleInfo.module.languageVersionSettings is LibraryInfo -> project.getLanguageVersionSettings( - javaTypeEnhancementState = computeJavaTypeEnhancementState(project), isReleaseCoroutines = isReleaseCoroutines + javaTypeEnhancementState = computeJavaTypeEnhancementState(project) ) is ScriptModuleInfo -> { getLanguageSettingsForScripts( diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt index 5919ae3daea..4f433f33130 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt @@ -116,8 +116,7 @@ fun Module.getStableName(): Name { @JvmOverloads fun Project.getLanguageVersionSettings( contextModule: Module? = null, - javaTypeEnhancementState: JavaTypeEnhancementState? = null, - isReleaseCoroutines: Boolean? = null + javaTypeEnhancementState: JavaTypeEnhancementState? = null ): LanguageVersionSettings { val kotlinFacetSettings = contextModule?.let { KotlinFacetSettingsProvider.getInstance(this)?.getInitializedSettings(it) diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt index 7152af66d0b..a289bd935c5 100644 --- a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/NativePlatformKindResolution.kt @@ -118,8 +118,7 @@ class NativePlatformKindResolution : IdePlatformKindResolution { val languageVersionSettings = IDELanguageSettingsProvider.getLanguageVersionSettings( stdlibInfo, - project, - isReleaseCoroutines = false + project ) val stdlibPackageFragmentProvider = createKlibPackageFragmentProvider( From df3b12e13bc878541b7919bf5f5958d193ad4535 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 2 Dec 2020 13:19:37 +0300 Subject: [PATCH 038/197] [FE] Drop `coroutinesState` from build configurations plugins --- .../GradleBuildScriptManipulator.kt | 4 +- .../GroovyBuildScriptManipulator.kt | 14 +--- .../KotlinBuildScriptManipulator.kt | 3 - .../KotlinGradleSourceSetDataService.kt | 10 --- .../KotlinSourceSetDataService.kt | 6 -- .../KotlinWithGradleConfigurator.kt | 28 +------ .../gradle/GradleConfiguratorTest.kt | 53 ------------- .../kotlin/config/KotlinFacetSettings.kt | 23 ------ .../KotlinProjectConfigurator.kt | 2 - .../KotlinWithLibraryConfigurator.kt | 17 ---- .../quickfix/ChangeCoroutineSupportFix.kt | 78 ------------------- .../idea/quickfix/JvmQuickFixRegistrar.kt | 5 +- .../configuration/KotlinMavenConfigurator.kt | 46 ----------- .../jetbrains/kotlin/idea/facet/facetUtils.kt | 4 +- .../configuration/ConfigureKotlinTest.java | 5 -- .../jetbrains/kotlin/gradle/CoroutinesIT.kt | 52 ------------- .../kotlin/maven/KotlinCompileMojoBase.java | 4 - 17 files changed, 6 insertions(+), 348 deletions(-) delete mode 100644 idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt delete mode 100644 libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CoroutinesIT.kt diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleBuildScriptManipulator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleBuildScriptManipulator.kt index 7eb86290754..cf015645c4e 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleBuildScriptManipulator.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GradleBuildScriptManipulator.kt @@ -45,8 +45,6 @@ interface GradleBuildScriptManipulator { fun configureProjectBuildScript(kotlinPluginName: String, version: String): Boolean - fun changeCoroutineConfiguration(coroutineOption: String): PsiElement? - fun changeLanguageFeatureConfiguration(feature: LanguageFeature, state: LanguageFeature.State, forTests: Boolean): PsiElement? fun changeLanguageVersion(version: String, forTests: Boolean): PsiElement? @@ -125,4 +123,4 @@ fun GradleVersion.scope(directive: String): String { } return directive -} \ No newline at end of file +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt index 709a9dcd9c5..da3f6e30c07 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/GroovyBuildScriptManipulator.kt @@ -139,18 +139,6 @@ class GroovyBuildScriptManipulator( return oldText != scriptFile.text } - override fun changeCoroutineConfiguration(coroutineOption: String): PsiElement? { - val snippet = "coroutines \"$coroutineOption\"" - val kotlinBlock = scriptFile.getKotlinBlock() - kotlinBlock.getBlockOrCreate("experimental").apply { - addOrReplaceExpression(snippet) { stmt -> - (stmt as? GrMethodCall)?.invokedExpression?.text == "coroutines" - } - } - - return kotlinBlock.parent - } - override fun changeLanguageFeatureConfiguration( feature: LanguageFeature, state: LanguageFeature.State, @@ -501,4 +489,4 @@ class GroovyBuildScriptManipulator( return true } } -} \ No newline at end of file +} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt index 32a636a84ce..24017ddb6e7 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinBuildScriptManipulator.kt @@ -100,9 +100,6 @@ class KotlinBuildScriptManipulator( return originalText != scriptFile.text } - override fun changeCoroutineConfiguration(coroutineOption: String): PsiElement? = - scriptFile.changeCoroutineConfiguration(coroutineOption) - override fun changeLanguageFeatureConfiguration( feature: LanguageFeature, state: LanguageFeature.State, diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt index 3a41e46f483..934514eb457 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleSourceSetDataService.kt @@ -273,14 +273,9 @@ fun configureFacetByGradleModule( // TODO there should be a way to figure out the correct platform version val platform = platformKind?.defaultPlatform - val coroutinesProperty = CoroutineSupport.byCompilerArgument( - moduleNode.coroutines ?: findKotlinCoroutinesProperty(ideModule.project) - ) - val kotlinFacet = ideModule.getOrCreateFacet(modelsProvider, false, GradleConstants.SYSTEM_ID.id) kotlinFacet.configureFacet( compilerVersion, - coroutinesProperty, platform, modelsProvider ) @@ -338,8 +333,3 @@ internal fun adjustClasspath(kotlinFacet: KotlinFacet, dependencyClasspath: List val newClasspath = fullClasspath - dependencyClasspath arguments.classpath = if (newClasspath.isNotEmpty()) newClasspath.joinToString(File.pathSeparator) else null } - -internal fun findKotlinCoroutinesProperty(project: Project): String { - return GradlePropertiesFileFacade.forProject(project).readProperty("kotlin.coroutines") - ?: CoroutineSupport.getCompilerArgument(LanguageFeature.Coroutines.defaultState) -} diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinSourceSetDataService.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinSourceSetDataService.kt index 13f636896ee..6c888ff8f69 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinSourceSetDataService.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/configuration/KotlinSourceSetDataService.kt @@ -18,14 +18,12 @@ import com.intellij.openapi.roots.DependencyScope import com.intellij.openapi.roots.ExportableOrderEntry import com.intellij.openapi.roots.ModifiableRootModel import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments -import org.jetbrains.kotlin.config.CoroutineSupport import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.KotlinModuleKind import org.jetbrains.kotlin.gradle.KotlinCompilation import org.jetbrains.kotlin.gradle.KotlinModule import org.jetbrains.kotlin.gradle.KotlinPlatform import org.jetbrains.kotlin.gradle.KotlinSourceSet -import org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService.Companion.isRelevantFor import org.jetbrains.kotlin.idea.facet.* import org.jetbrains.kotlin.idea.inspections.gradle.findAll import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion @@ -184,9 +182,6 @@ class KotlinSourceSetDataService : AbstractProjectDataService( ) } -object CoroutineSupport { - @JvmStatic - fun byCompilerArguments(arguments: CommonCompilerArguments?): LanguageFeature.State = - byCompilerArgumentsOrNull(arguments) ?: LanguageFeature.Coroutines.defaultState - - fun byCompilerArgumentsOrNull(arguments: CommonCompilerArguments?): LanguageFeature.State? = when (arguments?.coroutinesState) { - CommonCompilerArguments.ENABLE -> LanguageFeature.State.ENABLED - CommonCompilerArguments.WARN, CommonCompilerArguments.DEFAULT -> LanguageFeature.State.ENABLED_WITH_WARNING - CommonCompilerArguments.ERROR -> LanguageFeature.State.ENABLED_WITH_ERROR - else -> null - } - - fun byCompilerArgument(argument: String): LanguageFeature.State = - LanguageFeature.State.values().find { getCompilerArgument(it).equals(argument, ignoreCase = true) } - ?: LanguageFeature.Coroutines.defaultState - - fun getCompilerArgument(state: LanguageFeature.State): String = when (state) { - LanguageFeature.State.ENABLED -> "enable" - LanguageFeature.State.ENABLED_WITH_WARNING -> "warn" - LanguageFeature.State.ENABLED_WITH_ERROR, LanguageFeature.State.DISABLED -> "error" - } -} - sealed class VersionView : DescriptionAware { abstract val version: LanguageVersion diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt index c2049fb3a4e..1a32294b909 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinProjectConfigurator.kt @@ -70,8 +70,6 @@ interface KotlinProjectConfigurator { forTests: Boolean ) - fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) - fun changeGeneralFeatureConfiguration( module: Module, feature: LanguageFeature, diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index ed06c5d4572..702aa8120da 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -346,23 +346,6 @@ abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinPro return module.getBuildSystemType() == BuildSystemType.JPS } - override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) { - val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED && - getRuntimeLibraryVersion(module).toApiVersion() == ApiVersion.KOTLIN_1_0 - - if (runtimeUpdateRequired && !askUpdateRuntime(module, LanguageFeature.Coroutines.sinceApiVersion)) { - return - } - - val facetSettings = KotlinFacetSettingsProvider.getInstance(module.project)?.getInitializedSettings(module) - if (facetSettings != null) { - ModuleRootModificationUtil.updateModel(module) { - facetSettings.apiLevel = LanguageVersion.KOTLIN_1_1 - facetSettings.languageLevel = LanguageVersion.KOTLIN_1_1 - } - } - } - override fun changeGeneralFeatureConfiguration( module: Module, feature: LanguageFeature, diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt deleted file mode 100644 index 7f5d309ef6f..00000000000 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/ChangeCoroutineSupportFix.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * 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.idea.quickfix - -import com.intellij.codeInsight.intention.IntentionAction -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.module.ModuleUtilCore -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.config.LanguageFeature -import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.idea.KotlinJvmBundle -import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder -import org.jetbrains.kotlin.idea.configuration.findApplicableConfigurator -import org.jetbrains.kotlin.idea.roots.invalidateProjectRoots -import org.jetbrains.kotlin.psi.KtFile - -sealed class ChangeCoroutineSupportFix( - element: PsiElement, - coroutineSupport: LanguageFeature.State -) : AbstractChangeFeatureSupportLevelFix(element, LanguageFeature.Coroutines, coroutineSupport, shortFeatureName) { - - class InModule(element: PsiElement, coroutineSupport: LanguageFeature.State) : ChangeCoroutineSupportFix(element, coroutineSupport) { - override fun getText() = KotlinJvmBundle.message("fix.0.in.current.module", super.getText()) - - override fun invoke(project: Project, editor: Editor?, file: KtFile) { - val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return - - findApplicableConfigurator(module).changeCoroutineConfiguration(module, featureSupport) - } - } - - class InProject(element: PsiElement, coroutineSupport: LanguageFeature.State) : ChangeCoroutineSupportFix(element, coroutineSupport) { - override fun getText() = KotlinJvmBundle.message("fix.0.in.the.project", super.getText()) - - override fun invoke(project: Project, editor: Editor?, file: KtFile) { - if (featureSupportEnabled) { - if (!checkUpdateRuntime(project, LanguageFeature.Coroutines.sinceApiVersion)) return - } - - KotlinCommonCompilerArgumentsHolder.getInstance(project).update { - coroutinesState = when (featureSupport) { - LanguageFeature.State.ENABLED -> CommonCompilerArguments.ENABLE - LanguageFeature.State.ENABLED_WITH_WARNING -> CommonCompilerArguments.WARN - LanguageFeature.State.ENABLED_WITH_ERROR, LanguageFeature.State.DISABLED -> CommonCompilerArguments.ERROR - } - } - project.invalidateProjectRoots() - } - - } - - companion object : FeatureSupportIntentionActionsFactory() { - private val shortFeatureName get() = KotlinJvmBundle.message("short.feature.name.coroutine") - - fun getFixText(state: LanguageFeature.State) = getFixText(state, shortFeatureName) - - override fun doCreateActions(diagnostic: Diagnostic): List { - val module = ModuleUtilCore.findModuleForPsiElement(diagnostic.psiElement) ?: return emptyList() - - return doCreateActions( - diagnostic, LanguageFeature.Coroutines, allowWarningAndErrorMode = true, - quickFixConstructor = if (shouldConfigureInProject(module)) { element, _, coroutineSupport -> - InProject( - element, - coroutineSupport - ) - } else { element, _, coroutineSupport -> - InModule(element, coroutineSupport) - } - ) - } - } -} diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/JvmQuickFixRegistrar.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/JvmQuickFixRegistrar.kt index faba21fc1dd..60759ae6b6d 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/JvmQuickFixRegistrar.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/quickfix/JvmQuickFixRegistrar.kt @@ -33,9 +33,6 @@ class JvmQuickFixRegistrar : QuickFixContributor { UNSUPPORTED_FEATURE.registerFactory(EnableUnsupportedFeatureFix) - EXPERIMENTAL_FEATURE_ERROR.registerFactory(ChangeCoroutineSupportFix) - EXPERIMENTAL_FEATURE_WARNING.registerFactory(ChangeCoroutineSupportFix) - EXPERIMENTAL_FEATURE_ERROR.registerFactory(ChangeGeneralLanguageFeatureSupportFix) EXPERIMENTAL_FEATURE_WARNING.registerFactory(ChangeGeneralLanguageFeatureSupportFix) @@ -43,4 +40,4 @@ class JvmQuickFixRegistrar : QuickFixContributor { MISSING_SCRIPT_STANDARD_TEMPLATE.registerFactory(AddScriptRuntimeQuickFix) } -} \ No newline at end of file +} diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt index 19b4da920b7..4ef7ca1b3d0 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt @@ -30,14 +30,12 @@ import org.jetbrains.idea.maven.model.MavenId import org.jetbrains.idea.maven.project.MavenProjectsManager import org.jetbrains.idea.maven.utils.MavenArtifactScope import org.jetbrains.kotlin.config.ApiVersion -import org.jetbrains.kotlin.config.CoroutineSupport import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.configuration.* import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion import org.jetbrains.kotlin.idea.facet.toApiVersion import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion import org.jetbrains.kotlin.idea.maven.* -import org.jetbrains.kotlin.idea.quickfix.ChangeCoroutineSupportFix import org.jetbrains.kotlin.idea.quickfix.ChangeGeneralLanguageFeatureSupportFix import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor @@ -249,28 +247,6 @@ protected constructor( JavaProjectModelModificationService.getInstance(module.project).addDependency(module, library, scope) } - override fun changeCoroutineConfiguration(module: Module, state: LanguageFeature.State) { - val runtimeUpdateRequired = state != LanguageFeature.State.DISABLED && - getRuntimeLibraryVersion(module).toApiVersion() == ApiVersion.KOTLIN_1_0 - - val messageTitle = ChangeCoroutineSupportFix.getFixText(state) - if (runtimeUpdateRequired) { - Messages.showErrorDialog( - module.project, - KotlinMavenBundle.message("update.language.version.coroutines"), - messageTitle - ) - return - } - - val element = changeMavenCoroutineConfiguration(module, CoroutineSupport.getCompilerArgument(state), messageTitle) - - if (element != null) { - OpenFileDescriptor(module.project, element.containingFile.virtualFile, element.textRange.startOffset).navigate(true) - } - - } - override fun changeGeneralFeatureConfiguration( module: Module, feature: LanguageFeature, @@ -299,28 +275,6 @@ protected constructor( } - private fun changeMavenCoroutineConfiguration( - module: Module, - value: String, - messageTitle: String - ): PsiElement? { - fun doChangeMavenCoroutineConfiguration(): PsiElement? { - val psi = findModulePomFile(module) as? XmlFile ?: return null - val pom = PomFile.forFileOrNull(psi) ?: return null - return pom.changeCoroutineConfiguration(value) - } - - val element = doChangeMavenCoroutineConfiguration() - if (element == null) { - Messages.showErrorDialog( - module.project, - KotlinMavenBundle.message("error.failed.update.pom"), - messageTitle - ) - } - return element - } - private fun changeMavenFeatureConfiguration( module: Module, feature: LanguageFeature, diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index fddbda66d62..1fa05222c73 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -153,16 +153,14 @@ fun Module.removeKotlinFacet( //method used for non-mpp modules fun KotlinFacet.configureFacet( compilerVersion: String?, - coroutineSupport: LanguageFeature.State, platform: TargetPlatform?, modelsProvider: IdeModifiableModelsProvider ) { - configureFacet(compilerVersion, coroutineSupport, platform, modelsProvider, false, emptyList(), emptyList()) + configureFacet(compilerVersion, platform, modelsProvider, false, emptyList(), emptyList()) } fun KotlinFacet.configureFacet( compilerVersion: String?, - coroutineSupport: LanguageFeature.State, platform: TargetPlatform?, // if null, detect by module dependencies modelsProvider: IdeModifiableModelsProvider, hmppEnabled: Boolean, diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java index 32e75b41590..69e97dcbba8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java @@ -214,7 +214,6 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { assertEquals(JvmPlatforms.INSTANCE.getJvm18(), settings.getTargetPlatform()); assertEquals("1.1", arguments.getLanguageVersion()); assertEquals("1.0", arguments.getApiVersion()); - assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, CoroutineSupport.byCompilerArguments(arguments)); assertEquals("1.7", arguments.getJvmTarget()); assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().getAdditionalArguments()); } @@ -229,7 +228,6 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { assertEquals(JsPlatforms.INSTANCE.getDefaultJsPlatform(), settings.getTargetPlatform()); assertEquals("1.1", arguments.getLanguageVersion()); assertEquals("1.0", arguments.getApiVersion()); - assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, CoroutineSupport.byCompilerArguments(arguments)); assertEquals("amd", arguments.getModuleKind()); assertEquals("-version -meta-info", settings.getCompilerSettings().getAdditionalArguments()); } @@ -244,7 +242,6 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { assertEquals(JvmPlatforms.INSTANCE.getJvm18(), settings.getTargetPlatform()); assertEquals("1.1", arguments.getLanguageVersion()); assertEquals("1.0", arguments.getApiVersion()); - assertEquals(LanguageFeature.State.ENABLED, CoroutineSupport.byCompilerArguments(arguments)); assertEquals("1.7", arguments.getJvmTarget()); assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().getAdditionalArguments()); } @@ -259,7 +256,6 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { assertEquals(JsPlatforms.INSTANCE.getDefaultJsPlatform(), settings.getTargetPlatform()); assertEquals("1.1", arguments.getLanguageVersion()); assertEquals("1.0", arguments.getApiVersion()); - assertEquals(LanguageFeature.State.ENABLED_WITH_ERROR, CoroutineSupport.byCompilerArguments(arguments)); assertEquals("amd", arguments.getModuleKind()); assertEquals("-version -meta-info", settings.getCompilerSettings().getAdditionalArguments()); } @@ -274,7 +270,6 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { assertEquals(JvmPlatforms.INSTANCE.getJvm18(), settings.getTargetPlatform()); assertEquals("1.1", arguments.getLanguageVersion()); assertEquals("1.0", arguments.getApiVersion()); - assertEquals(LanguageFeature.State.ENABLED, CoroutineSupport.byCompilerArguments(arguments)); assertEquals("1.7", arguments.getJvmTarget()); assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().getAdditionalArguments()); } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CoroutinesIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CoroutinesIT.kt deleted file mode 100644 index d2345dd059d..00000000000 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CoroutinesIT.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.gradle - -import org.junit.Test -import java.io.File - -class CoroutinesIT : BaseGradleIT() { - @Test - fun testCoroutinesJvmDefault() { - jvmProject.doTest("default", null) - } - - @Test - fun testCoroutinesJsDefault() { - jsProject.doTest("default", null) - } - - // todo: replace with project that actually uses coroutines after their syntax is finalized - private val jvmProject: Project - get() = Project("kotlinProject") - - private val jsProject: Project - get() = Project("kotlin2JsProject") - - private fun Project.doTest(coroutineSupport: String, propertyFileName: String?) { - if (propertyFileName != null) { - setupWorkingDir() - val propertyFile = File(projectDir, propertyFileName) - val coroutinesProperty = "kotlin.coroutines=$coroutineSupport" - propertyFile.writeText(coroutinesProperty) - } - - build("build") { - assertContains("args.coroutinesState=$coroutineSupport") - } - } -} \ No newline at end of file diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java index 33145c2ba4e..15f543099a9 100644 --- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java @@ -441,10 +441,6 @@ public abstract class KotlinCompileMojoBase e arguments.setApiVersion(apiVersion); arguments.setMultiPlatform(multiPlatform); - if (experimentalCoroutines != null) { - arguments.setCoroutinesState(experimentalCoroutines); - } - configureSpecificCompilerArguments(arguments, sourceRoots); try { From e991c9d476c7cf59db7ecd585efeb77f8357ab24 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 2 Dec 2020 13:22:40 +0300 Subject: [PATCH 039/197] [CLI] Drop `CommonCompilerArguments.coroutinesState` --- .../jetbrains/kotlin/build/BuildMetaInfo.kt | 9 ---- .../kotlin/build/CommonBuildMetaInfo.kt | 9 ---- .../jetbrains/kotlin/build/JsBuildMetaInfo.kt | 9 ---- .../kotlin/build/JvmBuildMetaInfo.kt | 9 ---- .../arguments/CommonCompilerArguments.kt | 30 -------------- compiler/testData/cli/js/jsExtraHelp.out | 2 - .../testData/cli/jvm/coroutinesEnable.out | 2 +- compiler/testData/cli/jvm/coroutinesError.out | 2 +- .../cli/jvm/coroutinesErrorAndEnable.out | 4 +- compiler/testData/cli/jvm/coroutinesWarn.out | 2 +- compiler/testData/cli/jvm/extraHelp.out | 2 - .../kotlin/config/facetSerialization.kt | 41 +------------------ .../kotlin/idea/maven/KotlinMavenImporter.kt | 7 +--- .../KotlinLightCodeInsightFixtureTestCase.kt | 2 +- .../jetbrains/kotlin/idea/facet/facetUtils.kt | 18 +------- .../kotlin/asJava/KtLightAnnotationTest.kt | 5 +-- .../configuration/ConfigureKotlinTest.java | 1 - .../UpdateConfigurationQuickFixTest.kt | 29 ------------- .../internal/CompilerArgumentsContributor.kt | 11 +---- 19 files changed, 13 insertions(+), 181 deletions(-) diff --git a/build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt index 4697144218d..5a3d395f026 100644 --- a/build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/build/BuildMetaInfo.kt @@ -17,9 +17,6 @@ interface BuildMetaInfo { val compilerBuildVersion: String val languageVersionString: String val apiVersionString: String - val coroutinesEnable: Boolean - val coroutinesWarn: Boolean - val coroutinesError: Boolean val multiplatformEnable: Boolean val metadataVersionMajor: Int val metadataVersionMinor: Int @@ -35,9 +32,6 @@ abstract class BuildMetaInfoFactory(private val metaInfoClass compilerBuildVersion: String, languageVersionString: String, apiVersionString: String, - coroutinesEnable: Boolean, - coroutinesWarn: Boolean, - coroutinesError: Boolean, multiplatformEnable: Boolean, ownVersion: Int, coroutinesVersion: Int, @@ -53,9 +47,6 @@ abstract class BuildMetaInfoFactory(private val metaInfoClass compilerBuildVersion = KotlinCompilerVersion.VERSION, languageVersionString = languageVersion.versionString, apiVersionString = args.apiVersion ?: languageVersion.versionString, - coroutinesEnable = args.coroutinesState == CommonCompilerArguments.ENABLE, - coroutinesWarn = args.coroutinesState == CommonCompilerArguments.WARN, - coroutinesError = args.coroutinesState == CommonCompilerArguments.ERROR, multiplatformEnable = args.multiPlatform, ownVersion = OWN_VERSION, coroutinesVersion = COROUTINES_VERSION, diff --git a/build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt index 468e6df0665..09e6931fbeb 100644 --- a/build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/build/CommonBuildMetaInfo.kt @@ -15,9 +15,6 @@ data class CommonBuildMetaInfo( override val compilerBuildVersion: String, override val languageVersionString: String, override val apiVersionString: String, - override val coroutinesEnable: Boolean, - override val coroutinesWarn: Boolean, - override val coroutinesError: Boolean, override val multiplatformEnable: Boolean, override val metadataVersionMajor: Int, override val metadataVersionMinor: Int, @@ -32,9 +29,6 @@ data class CommonBuildMetaInfo( compilerBuildVersion: String, languageVersionString: String, apiVersionString: String, - coroutinesEnable: Boolean, - coroutinesWarn: Boolean, - coroutinesError: Boolean, multiplatformEnable: Boolean, ownVersion: Int, coroutinesVersion: Int, @@ -47,9 +41,6 @@ data class CommonBuildMetaInfo( compilerBuildVersion = compilerBuildVersion, languageVersionString = languageVersionString, apiVersionString = apiVersionString, - coroutinesEnable = coroutinesEnable, - coroutinesWarn = coroutinesWarn, - coroutinesError = coroutinesError, multiplatformEnable = multiplatformEnable, metadataVersionMajor = metadataVersion.major, metadataVersionMinor = metadataVersion.minor, diff --git a/build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt index be273b4e1fb..6d97112df9c 100644 --- a/build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/build/JsBuildMetaInfo.kt @@ -15,9 +15,6 @@ data class JsBuildMetaInfo( override val compilerBuildVersion: String, override val languageVersionString: String, override val apiVersionString: String, - override val coroutinesEnable: Boolean, - override val coroutinesWarn: Boolean, - override val coroutinesError: Boolean, override val multiplatformEnable: Boolean, override val metadataVersionMajor: Int, override val metadataVersionMinor: Int, @@ -32,9 +29,6 @@ data class JsBuildMetaInfo( compilerBuildVersion: String, languageVersionString: String, apiVersionString: String, - coroutinesEnable: Boolean, - coroutinesWarn: Boolean, - coroutinesError: Boolean, multiplatformEnable: Boolean, ownVersion: Int, coroutinesVersion: Int, @@ -47,9 +41,6 @@ data class JsBuildMetaInfo( compilerBuildVersion = compilerBuildVersion, languageVersionString = languageVersionString, apiVersionString = apiVersionString, - coroutinesEnable = coroutinesEnable, - coroutinesWarn = coroutinesWarn, - coroutinesError = coroutinesError, multiplatformEnable = multiplatformEnable, metadataVersionMajor = metadataVersion.major, metadataVersionMinor = metadataVersion.minor, diff --git a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt index 4c2ed1755b2..cc2cd3f5f7e 100644 --- a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt @@ -27,9 +27,6 @@ data class JvmBuildMetaInfo( override val compilerBuildVersion: String, override val languageVersionString: String, override val apiVersionString: String, - override val coroutinesEnable: Boolean, - override val coroutinesWarn: Boolean, - override val coroutinesError: Boolean, override val multiplatformEnable: Boolean, override val metadataVersionMajor: Int, override val metadataVersionMinor: Int, @@ -47,9 +44,6 @@ data class JvmBuildMetaInfo( compilerBuildVersion: String, languageVersionString: String, apiVersionString: String, - coroutinesEnable: Boolean, - coroutinesWarn: Boolean, - coroutinesError: Boolean, multiplatformEnable: Boolean, ownVersion: Int, coroutinesVersion: Int, @@ -62,9 +56,6 @@ data class JvmBuildMetaInfo( compilerBuildVersion = compilerBuildVersion, languageVersionString = languageVersionString, apiVersionString = apiVersionString, - coroutinesEnable = coroutinesEnable, - coroutinesWarn = coroutinesWarn, - coroutinesError = coroutinesError, multiplatformEnable = multiplatformEnable, metadataVersionMajor = metadataVersion.major, metadataVersionMinor = metadataVersion.minor, diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index 4c7a24a22bc..497470153e6 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -121,13 +121,6 @@ abstract class CommonCompilerArguments : CommonToolArguments() { ) var intellijPluginRoot: String? by NullableStringFreezableVar(null) - @Argument( - value = "-Xcoroutines", - valueDescription = "{enable|warn|error}", - description = "Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier" - ) - var coroutinesState: String? by NullableStringFreezableVar(DEFAULT) - @Argument( value = "-Xnew-inference", description = "Enable new experimental generic type inference algorithm" @@ -385,17 +378,6 @@ abstract class CommonCompilerArguments : CommonToolArguments() { put(LanguageFeature.MultiPlatformProjects, LanguageFeature.State.ENABLED) } - when (coroutinesState) { - CommonCompilerArguments.ERROR -> put(LanguageFeature.Coroutines, LanguageFeature.State.ENABLED_WITH_ERROR) - CommonCompilerArguments.ENABLE -> put(LanguageFeature.Coroutines, LanguageFeature.State.ENABLED) - CommonCompilerArguments.WARN, CommonCompilerArguments.DEFAULT -> { - } - else -> { - val message = "Invalid value of -Xcoroutines (should be: enable, warn or error): " + coroutinesState - collector.report(CompilerMessageSeverity.ERROR, message, null) - } - } - if (newInference) { put(LanguageFeature.NewInference, LanguageFeature.State.ENABLED) put(LanguageFeature.SamConversionPerArgument, LanguageFeature.State.ENABLED) @@ -525,7 +507,6 @@ abstract class CommonCompilerArguments : CommonToolArguments() { configureLanguageFeatures(collector) ) - checkCoroutines(languageVersionSettings, collector) checkIrSupport(languageVersionSettings, collector) return languageVersionSettings @@ -596,17 +577,6 @@ abstract class CommonCompilerArguments : CommonToolArguments() { } } - private fun checkCoroutines(languageVersionSettings: LanguageVersionSettings, collector: MessageCollector) { - if (languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) { - if (coroutinesState != DEFAULT) { - collector.report( - CompilerMessageSeverity.STRONG_WARNING, - "-Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond" - ) - } - } - } - protected open fun checkIrSupport(languageVersionSettings: LanguageVersionSettings, collector: MessageCollector) { // backend-specific } diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 5dec79a8564..63f9b4b89f7 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -30,8 +30,6 @@ where advanced options include: Run sticky condition checks on subsequent phases as well. Implies -Xcheck-phase-conditions -Xcommon-sources= Sources of the common module that need to be compiled together with this module in the multi-platform mode. Should be a subset of sources passed as free arguments - -Xcoroutines={enable|warn|error} - Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier -Xdisable-default-scripting-plugin Do not enable scripting plugin by default -Xdisable-phases Disable backend phases diff --git a/compiler/testData/cli/jvm/coroutinesEnable.out b/compiler/testData/cli/jvm/coroutinesEnable.out index f91ef107ba5..bb82d423938 100644 --- a/compiler/testData/cli/jvm/coroutinesEnable.out +++ b/compiler/testData/cli/jvm/coroutinesEnable.out @@ -1,2 +1,2 @@ -warning: -Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond +warning: flag is not supported by this version of the compiler: -Xcoroutines=enable OK diff --git a/compiler/testData/cli/jvm/coroutinesError.out b/compiler/testData/cli/jvm/coroutinesError.out index f91ef107ba5..d7e005ad4f3 100644 --- a/compiler/testData/cli/jvm/coroutinesError.out +++ b/compiler/testData/cli/jvm/coroutinesError.out @@ -1,2 +1,2 @@ -warning: -Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond +warning: flag is not supported by this version of the compiler: -Xcoroutines=error OK diff --git a/compiler/testData/cli/jvm/coroutinesErrorAndEnable.out b/compiler/testData/cli/jvm/coroutinesErrorAndEnable.out index d5e60387dd1..0a8b6d689bf 100644 --- a/compiler/testData/cli/jvm/coroutinesErrorAndEnable.out +++ b/compiler/testData/cli/jvm/coroutinesErrorAndEnable.out @@ -1,3 +1,3 @@ -warning: argument -Xcoroutines is passed multiple times. Only the last value will be used: enable -warning: -Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond +warning: flag is not supported by this version of the compiler: -Xcoroutines=error +warning: flag is not supported by this version of the compiler: -Xcoroutines=enable OK diff --git a/compiler/testData/cli/jvm/coroutinesWarn.out b/compiler/testData/cli/jvm/coroutinesWarn.out index f91ef107ba5..f6b6a1718ec 100644 --- a/compiler/testData/cli/jvm/coroutinesWarn.out +++ b/compiler/testData/cli/jvm/coroutinesWarn.out @@ -1,2 +1,2 @@ -warning: -Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond +warning: flag is not supported by this version of the compiler: -Xcoroutines=warn OK diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index e126aba4d5e..27aabe3201f 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -130,8 +130,6 @@ where advanced options include: Run sticky condition checks on subsequent phases as well. Implies -Xcheck-phase-conditions -Xcommon-sources= Sources of the common module that need to be compiled together with this module in the multi-platform mode. Should be a subset of sources passed as free arguments - -Xcoroutines={enable|warn|error} - Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier -Xdisable-default-scripting-plugin Do not enable scripting plugin by default -Xdisable-phases Disable backend phases diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt index f1d770d423c..40b90f2071a 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt @@ -195,19 +195,7 @@ private fun readElementsList(element: Element, rootElementName: String, elementN } private fun readV2Config(element: Element): KotlinFacetSettings { - return readV2AndLaterConfig(element).apply { - element.getChild("compilerArguments")?.children?.let { args -> - when { - args.any { arg -> arg.attributes[0].value == "coroutinesEnable" && arg.attributes[1].booleanValue } -> - compilerArguments!!.coroutinesState = CommonCompilerArguments.ENABLE - args.any { arg -> arg.attributes[0].value == "coroutinesWarn" && arg.attributes[1].booleanValue } -> - compilerArguments!!.coroutinesState = CommonCompilerArguments.WARN - args.any { arg -> arg.attributes[0].value == "coroutinesError" && arg.attributes[1].booleanValue } -> - compilerArguments!!.coroutinesState = CommonCompilerArguments.ERROR - else -> compilerArguments!!.coroutinesState = CommonCompilerArguments.DEFAULT - } - } - } + return readV2AndLaterConfig(element) } private fun readLatestConfig(element: Element): KotlinFacetSettings { @@ -408,35 +396,10 @@ fun Element.dropVersionsIfNecessary(settings: CommonCompilerArguments) { } } -// Special treatment of v2 may be dropped after transition to IDEA 172 -private fun KotlinFacetSettings.writeV2Config(element: Element) { - writeLatestConfig(element) - element.getChild("compilerArguments")?.let { - it.getOption("coroutinesState")?.detach() - val coroutineOption = when (compilerArguments?.coroutinesState) { - CommonCompilerArguments.ENABLE -> "coroutinesEnable" - CommonCompilerArguments.WARN -> "coroutinesWarn" - CommonCompilerArguments.ERROR -> "coroutinesError" - else -> null - } - if (coroutineOption != null) { - Element("option").apply { - setAttribute("name", coroutineOption) - setAttribute("value", "true") - it.addContent(this) - } - } - } -} - fun KotlinFacetSettings.serializeFacetSettings(element: Element) { val versionToWrite = if (version == 2) version else KotlinFacetSettings.CURRENT_VERSION element.setAttribute("version", versionToWrite.toString()) - if (versionToWrite == 2) { - writeV2Config(element) - } else { - writeLatestConfig(element) - } + writeLatestConfig(element) } private fun TargetPlatform.serializeComponentPlatforms(): String { diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt index c6339b35d9e..db002f26b28 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt @@ -190,10 +190,6 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ arguments.multiPlatform = configuration?.getChild("multiPlatform")?.text?.trim()?.toBoolean() ?: false arguments.suppressWarnings = configuration?.getChild("nowarn")?.text?.trim()?.toBoolean() ?: false - configuration?.getChild("experimentalCoroutines")?.text?.trim()?.let { - arguments.coroutinesState = it - } - when (arguments) { is K2JVMCompilerArguments -> { arguments.classpath = configuration?.getChild("classpath")?.text @@ -256,7 +252,6 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ kotlinFacet.configureFacet( compilerVersion, - LanguageFeature.Coroutines.defaultState, platform, modifiableModelsProvider ) @@ -425,4 +420,4 @@ class KotlinImporterComponent : PersistentStateComponent { fun Module.externalSystemTestRunTasks() = externalSystemRunTasks().filterIsInstance() fun Module.externalSystemNativeMainRunTasks() = externalSystemRunTasks().filterIsInstance() -@Suppress("DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith") -@Deprecated( - message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform", - level = DeprecationLevel.ERROR -) -fun KotlinFacet.configureFacet( - compilerVersion: String?, - coroutineSupport: LanguageFeature.State, - platform: IdePlatform<*, *>, - modelsProvider: IdeModifiableModelsProvider -) { - configureFacet(compilerVersion, coroutineSupport, platform.toNewPlatform(), modelsProvider) -} - - fun KotlinFacet.noVersionAutoAdvance() { configuration.settings.compilerArguments?.let { it.autoAdvanceLanguageVersion = false @@ -226,8 +211,7 @@ fun KotlinFacet.noVersionAutoAdvance() { val commonUIExposedFields = listOf( CommonCompilerArguments::languageVersion.name, CommonCompilerArguments::apiVersion.name, - CommonCompilerArguments::suppressWarnings.name, - CommonCompilerArguments::coroutinesState.name + CommonCompilerArguments::suppressWarnings.name ) private val commonUIHiddenFields = listOf( CommonCompilerArguments::pluginClasspaths.name, diff --git a/idea/tests/org/jetbrains/kotlin/asJava/KtLightAnnotationTest.kt b/idea/tests/org/jetbrains/kotlin/asJava/KtLightAnnotationTest.kt index 9dbafd8c571..d4d28a3c403 100644 --- a/idea/tests/org/jetbrains/kotlin/asJava/KtLightAnnotationTest.kt +++ b/idea/tests/org/jetbrains/kotlin/asJava/KtLightAnnotationTest.kt @@ -18,7 +18,6 @@ import junit.framework.TestCase import org.jetbrains.kotlin.asJava.elements.KtLightAnnotationForSourceEntry import org.jetbrains.kotlin.asJava.elements.KtLightPsiArrayInitializerMemberValue import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime -import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.completion.test.assertInstanceOf import org.jetbrains.kotlin.idea.facet.configureFacet import org.jetbrains.kotlin.idea.facet.getOrCreateFacet @@ -926,9 +925,9 @@ class KtLightAnnotationTest : KotlinLightCodeInsightFixtureTestCase() { WriteAction.run { val modelsProvider = IdeModifiableModelsProviderImpl(project) val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false) - facet.configureFacet(version, LanguageFeature.State.DISABLED, null, modelsProvider) + facet.configureFacet(version, null, modelsProvider) modelsProvider.commit() } } -} \ No newline at end of file +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java index 69e97dcbba8..96df5bbdda2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinTest.java @@ -346,7 +346,6 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest { FacetUtilsKt.configureFacet( facet, "1.1", - LanguageFeature.State.ENABLED, platform, modelsProvider ); diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt b/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt index d07f4bae94a..1fbd077e5a0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/UpdateConfigurationQuickFixTest.kt @@ -7,15 +7,12 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.facet.FacetManager import com.intellij.facet.impl.FacetUtil -import com.intellij.openapi.module.Module import com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.JarFileSystem import com.intellij.openapi.vfs.LocalFileSystem -import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments.Companion.DEFAULT import org.jetbrains.kotlin.config.CompilerSettings.Companion.DEFAULT_ADDITIONAL_ARGUMENTS import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersion @@ -57,28 +54,6 @@ class UpdateConfigurationQuickFixTest : KotlinLightPlatformCodeInsightFixtureTes assertEquals(LanguageFeature.State.ENABLED, inlineClassesSupport) } - fun testEnableCoroutines() { - configureRuntime("mockRuntime11") - resetProjectSettings(LanguageVersion.KOTLIN_1_1) - myFixture.configureByText("foo.kt", "suspend fun foo()") - - assertEquals(DEFAULT, KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.coroutinesState) - assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, coroutineSupport) - myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the project")) - assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) - } - - fun testDisableCoroutines() { - configureRuntime("mockRuntime11") - resetProjectSettings(LanguageVersion.KOTLIN_1_1) - myFixture.configureByText("foo.kt", "suspend fun foo()") - - assertEquals(DEFAULT, KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.coroutinesState) - assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, coroutineSupport) - myFixture.launchAction(myFixture.findSingleIntention("Disable coroutine support in the project")) - assertEquals(LanguageFeature.State.ENABLED_WITH_ERROR, coroutineSupport) - } - fun testIncreaseLangLevel() { configureRuntime("mockRuntime11") resetProjectSettings(LanguageVersion.KOTLIN_1_0) @@ -189,13 +164,9 @@ class UpdateConfigurationQuickFixTest : KotlinLightPlatformCodeInsightFixtureTes KotlinCommonCompilerArgumentsHolder.getInstance(project).update { languageVersion = version.versionString apiVersion = version.versionString - coroutinesState = DEFAULT } } - private val coroutineSupport: LanguageFeature.State - get() = project.getLanguageVersionSettings().getFeatureSupport(LanguageFeature.Coroutines) - private val inlineClassesSupport: LanguageFeature.State get() = project.getLanguageVersionSettings().getFeatureSupport(LanguageFeature.InlineClasses) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/CompilerArgumentsContributor.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/CompilerArgumentsContributor.kt index d41009c43a2..a96aea2d896 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/CompilerArgumentsContributor.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/CompilerArgumentsContributor.kt @@ -53,15 +53,6 @@ internal open class AbstractKotlinCompileArgumentsContributor ) { - args.coroutinesState = when (coroutines.get()) { - Coroutines.ENABLE -> CommonCompilerArguments.ENABLE - Coroutines.WARN -> CommonCompilerArguments.WARN - Coroutines.ERROR -> CommonCompilerArguments.ERROR - Coroutines.DEFAULT -> CommonCompilerArguments.DEFAULT - } - - logger.kotlinDebug { "args.coroutinesState=${args.coroutinesState}" } - if (logger.isDebugEnabled) { args.verbose = true } @@ -114,4 +105,4 @@ internal open class KotlinJvmCompilerArgumentsContributor( kotlinOptions.forEach { it?.updateArguments(args) } } -} \ No newline at end of file +} From af94bcebeac2b1641d2dfd6448beeb7f7930edca Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 29 Dec 2020 13:47:21 +0300 Subject: [PATCH 040/197] [IDE] Propagate KotlinFacetSettings version and completely drop isReleaseCoroutines flag Also this commit removes number of tests related to support experimental coroutines --- .../kotlin/build/BuildMetaInfoTest.kt | 10 +---- .../multiplatform/compilerArguments/common.kt | 9 ---- .../compilerArguments/output.txt | 4 -- ...MultiPlatformIntegrationTestGenerated.java | 5 --- .../CompileKotlinAgainstCustomBinariesTest.kt | 37 ----------------- .../caches/resolve/IdeaResolverForProject.kt | 1 - .../caches/resolve/KotlinCacheServiceImpl.kt | 28 +++---------- .../caches/resolve/ProjectResolutionFacade.kt | 1 - .../GradleUpdateConfigurationQuickFixTest.kt | 6 --- .../kotlin/config/KotlinFacetSettings.kt | 2 +- .../kotlin/config/facetSerialization.kt | 10 ++++- .../MavenUpdateConfigurationQuickFixTest.kt | 5 --- .../jvmProjectWithV4FacetConfig/module.iml | 26 ++++++++++++ .../projectFile.ipr | 41 +++++++++++++++++++ .../jvmProjectWithV4FacetConfig/src/foo.kt | 0 .../module.iml | 3 +- .../module.iml | 3 +- .../module.iml | 3 +- .../module.iml | 3 +- .../libNew/libN.kt | 4 -- .../libOld/libO.kt | 4 -- .../moduleNew/main.kt | 18 -------- .../moduleOld/main.kt | 17 -------- .../resolve/MultiModuleHighlightingTest.kt | 37 ----------------- .../ConfigureKotlinInTempDirTest.kt | 2 +- .../configuration/ConfigureKotlinTest.java | 14 +++++++ 26 files changed, 104 insertions(+), 189 deletions(-) delete mode 100644 compiler/testData/multiplatform/compilerArguments/common.kt delete mode 100644 compiler/testData/multiplatform/compilerArguments/output.txt create mode 100644 idea/testData/configuration/jvmProjectWithV4FacetConfig/module.iml create mode 100644 idea/testData/configuration/jvmProjectWithV4FacetConfig/projectFile.ipr create mode 100644 idea/testData/configuration/jvmProjectWithV4FacetConfig/src/foo.kt delete mode 100644 idea/testData/multiModuleHighlighting/coroutineMixedReleaseStatus/libNew/libN.kt delete mode 100644 idea/testData/multiModuleHighlighting/coroutineMixedReleaseStatus/libOld/libO.kt delete mode 100644 idea/testData/multiModuleHighlighting/coroutineMixedReleaseStatus/moduleNew/main.kt delete mode 100644 idea/testData/multiModuleHighlighting/coroutineMixedReleaseStatus/moduleOld/main.kt diff --git a/build-common/test/org/jetbrains/kotlin/build/BuildMetaInfoTest.kt b/build-common/test/org/jetbrains/kotlin/build/BuildMetaInfoTest.kt index 17cc4f04ba9..cc7e504553b 100644 --- a/build-common/test/org/jetbrains/kotlin/build/BuildMetaInfoTest.kt +++ b/build-common/test/org/jetbrains/kotlin/build/BuildMetaInfoTest.kt @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.build import junit.framework.TestCase -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.junit.Assert.assertNotEquals import org.junit.Test @@ -34,10 +33,7 @@ class BuildMetaInfoTest : TestCase() { "bytecodeVersionMinor", "bytecodeVersionPatch", "compilerBuildVersion", - "coroutinesEnable", - "coroutinesError", "coroutinesVersion", - "coroutinesWarn", "isEAP", "languageVersionString", "metadataVersionMajor", @@ -71,14 +67,12 @@ class BuildMetaInfoTest : TestCase() { @Test fun testJvmEquals() { val args1 = K2JVMCompilerArguments() - args1.coroutinesState = CommonCompilerArguments.ENABLE val info1 = JvmBuildMetaInfo.create(args1) val args2 = K2JVMCompilerArguments() - args2.coroutinesState = CommonCompilerArguments.WARN val info2 = JvmBuildMetaInfo.create(args2) - assertNotEquals(info1, info2) - assertEquals(info1, info2.copy(coroutinesEnable = true, coroutinesWarn = false)) + assertEquals(info1, info2) + assertEquals(info1, info2.copy()) } } diff --git a/compiler/testData/multiplatform/compilerArguments/common.kt b/compiler/testData/multiplatform/compilerArguments/common.kt deleted file mode 100644 index b6cc8d59849..00000000000 --- a/compiler/testData/multiplatform/compilerArguments/common.kt +++ /dev/null @@ -1,9 +0,0 @@ -// ADDITIONAL_COMPILER_ARGUMENTS: -Xcoroutines=enable - -fun f(g: suspend () -> Unit): Any = g - -suspend fun h() = f { } - -expect suspend fun k() - -expect fun l(g: suspend () -> Unit): Any diff --git a/compiler/testData/multiplatform/compilerArguments/output.txt b/compiler/testData/multiplatform/compilerArguments/output.txt deleted file mode 100644 index 48ea2319fee..00000000000 --- a/compiler/testData/multiplatform/compilerArguments/output.txt +++ /dev/null @@ -1,4 +0,0 @@ --- Common -- -Exit code: OK -Output: -warning: -Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond diff --git a/compiler/tests-gen/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java index 1c8ddc02ed2..be904fbe7a3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java @@ -34,11 +34,6 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform runTest("compiler/testData/multiplatform/compatibleProperties/"); } - @TestMetadata("compilerArguments") - public void testCompilerArguments() throws Exception { - runTest("compiler/testData/multiplatform/compilerArguments/"); - } - @TestMetadata("contracts") public void testContracts() throws Exception { runTest("compiler/testData/multiplatform/contracts/"); diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index d49f6840d2f..da81812e3d5 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -526,43 +526,6 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration ) } - fun testObsoleteInlineSuspend() { - val version = intArrayOf(1, 0, 1) // legacy coroutines metadata - val options = listOf("-language-version", "1.2", "-Xcoroutines=enable") - val library = transformJar( - compileLibrary( - "library", - additionalOptions = options, - extraClassPath = listOf(ForTestCompileRuntime.coroutinesCompatForTests()), - checkKotlinOutput = { actual -> - KotlinTestUtils.assertEqualsToFile(File(testDataDirectory, "library.output.txt"), actual) - } - ), - { _, bytes -> - val (resultBytes, removedCounter) = stripSuspensionMarksToImitateLegacyCompiler( - WrongBytecodeVersionTest.transformMetadataInClassFile(bytes) { name, _ -> - if (name == JvmAnnotationNames.BYTECODE_VERSION_FIELD_NAME) version else null - }) - // we expect 4 instructions to be removed in this test library - assertEquals(4, removedCounter) - resultBytes - }) - compileKotlin( - "source.kt", tmpdir, listOf(library, ForTestCompileRuntime.coroutinesCompatForTests()), K2JVMCompiler(), - additionalOptions = options - ) - val classLoader = URLClassLoader( - arrayOf(library.toURI().toURL(), tmpdir.toURI().toURL(), ForTestCompileRuntime.coroutinesCompatForTests().toURI().toURL()), - ForTestCompileRuntime.runtimeJarClassLoader() - ) - @Suppress("UNCHECKED_CAST") - val result = classLoader - .loadClass("SourceKt") - .getDeclaredMethod("run") - .invoke(null) as Array - assertEquals(result[0], result[1]) - } - fun testInlineFunctionsWithMatchingJvmSignatures() { val library = compileLibrary( "library", diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt index efc49edb9ec..62b83cabb50 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IdeaResolverForProject.kt @@ -43,7 +43,6 @@ class IdeaResolverForProject( private val syntheticFilesByModule: Map>, delegateResolver: ResolverForProject, fallbackModificationTracker: ModificationTracker? = null, - private val isReleaseCoroutines: Boolean? = null, // TODO(dsavvinov): this is needed only for non-composite analysis, extract separate resolver implementation instead private val constantSdkDependencyIfAny: SdkInfo? = null ) : AbstractResolverForProject( diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt index e278758636e..8f32bfb3d6a 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/KotlinCacheServiceImpl.kt @@ -80,20 +80,16 @@ internal val LOG = Logger.getInstance(KotlinCacheService::class.java) * This mode is currently enabled only for HMPP projects */ sealed class PlatformAnalysisSettings { - // Effectively unused as a property. Needed only to distinguish different modes when being put in a map - abstract val isReleaseCoroutines: Boolean - companion object { fun create( project: Project, platform: TargetPlatform, sdk: Sdk?, - isAdditionalBuiltInFeaturesSupported: Boolean, - isReleaseCoroutines: Boolean + isAdditionalBuiltInFeaturesSupported: Boolean ) = if (project.useCompositeAnalysis) - CompositeAnalysisSettings(isReleaseCoroutines) + CompositeAnalysisSettings else - PlatformAnalysisSettingsImpl(platform, sdk, isAdditionalBuiltInFeaturesSupported, isReleaseCoroutines) + PlatformAnalysisSettingsImpl(platform, sdk, isAdditionalBuiltInFeaturesSupported) } } @@ -101,11 +97,9 @@ data class PlatformAnalysisSettingsImpl( val platform: TargetPlatform, val sdk: Sdk?, val isAdditionalBuiltInFeaturesSupported: Boolean, - override val isReleaseCoroutines: Boolean ) : PlatformAnalysisSettings() -data class CompositeAnalysisSettings(override val isReleaseCoroutines: Boolean) : PlatformAnalysisSettings() { -} +object CompositeAnalysisSettings : PlatformAnalysisSettings() class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService { override fun getResolutionFacade(elements: List): ResolutionFacade { @@ -149,10 +143,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService { ): ProjectResolutionFacade { val sdk = dependenciesModuleInfo.sdk val platform = JvmPlatforms.defaultJvmPlatform // TODO: Js scripts? - val settings = PlatformAnalysisSettings.create( - project, platform, sdk, true, - LanguageFeature.ReleaseCoroutines.defaultState == LanguageFeature.State.ENABLED - ) + val settings = PlatformAnalysisSettings.create(project, platform, sdk, true) val dependenciesForScriptDependencies = listOf( LibraryModificationTracker.getInstance(project), @@ -227,16 +218,9 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService { private fun IdeaModuleInfo.platformSettings(targetPlatform: TargetPlatform) = PlatformAnalysisSettings.create( this@KotlinCacheServiceImpl.project, targetPlatform, sdk, - supportsAdditionalBuiltInsMembers(this@KotlinCacheServiceImpl.project), - isReleaseCoroutines() + supportsAdditionalBuiltInsMembers(this@KotlinCacheServiceImpl.project) ) - private fun IdeaModuleInfo.isReleaseCoroutines(): Boolean { - return IDELanguageSettingsProvider - .getLanguageVersionSettings(this, this@KotlinCacheServiceImpl.project) - .supportsFeature(LanguageFeature.ReleaseCoroutines) - } - private fun facadeForModules(settings: PlatformAnalysisSettings) = getOrBuildGlobalFacade(settings).facadeForModules diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt index 2e036fa2654..14c2100ab61 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/ProjectResolutionFacade.kt @@ -122,7 +122,6 @@ internal class ProjectResolutionFacade( syntheticFilesByModule, delegateResolverForProject, if (invalidateOnOOCB) KotlinModificationTrackerService.getInstance(project).outOfBlockModificationTracker else null, - settings.isReleaseCoroutines, constantSdkDependencyIfAny = if (settings is PlatformAnalysisSettingsImpl) settings.sdk?.let { SdkInfo(project, it) } else null ) diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleUpdateConfigurationQuickFixTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleUpdateConfigurationQuickFixTest.kt index 688f37da309..6509b3272c6 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleUpdateConfigurationQuickFixTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleUpdateConfigurationQuickFixTest.kt @@ -66,12 +66,6 @@ class GradleUpdateConfigurationQuickFixTest : GradleImportingTestCase() { doTest("Set module language version to 1.1") } - @Test - @TargetVersions("4.7 <=> 6.0") - fun testEnableCoroutines() { - doTest("Enable coroutine support in the current module") - } - @Test @TargetVersions("4.7 <=> 6.0") fun testAddKotlinReflect() { diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt index 6360f251c18..3d0094627a2 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt @@ -160,7 +160,7 @@ data class ExternalSystemNativeMainRunTask( class KotlinFacetSettings { companion object { // Increment this when making serialization-incompatible changes to configuration data - val CURRENT_VERSION = 3 + val CURRENT_VERSION = 4 val DEFAULT_VERSION = 0 } diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt index 40b90f2071a..7412c7a016f 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/facetSerialization.kt @@ -194,6 +194,10 @@ private fun readElementsList(element: Element, rootElementName: String, elementN return null } +private fun readV3Config(element: Element): KotlinFacetSettings { + return readV2AndLaterConfig(element) +} + private fun readV2Config(element: Element): KotlinFacetSettings { return readV2AndLaterConfig(element) } @@ -211,6 +215,7 @@ fun deserializeFacetSettings(element: Element): KotlinFacetSettings { return when (version) { 1 -> readV1Config(element) 2 -> readV2Config(element) + 3 -> readV3Config(element) KotlinFacetSettings.CURRENT_VERSION -> readLatestConfig(element) else -> return KotlinFacetSettings() // Reset facet configuration if versions don't match }.apply { this.version = version } @@ -397,7 +402,10 @@ fun Element.dropVersionsIfNecessary(settings: CommonCompilerArguments) { } fun KotlinFacetSettings.serializeFacetSettings(element: Element) { - val versionToWrite = if (version == 2) version else KotlinFacetSettings.CURRENT_VERSION + val versionToWrite = when (version) { + 2, 3 -> version + else -> KotlinFacetSettings.CURRENT_VERSION + } element.setAttribute("version", versionToWrite.toString()) writeLatestConfig(element) } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt index f458c94c61d..d3356715613 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/MavenUpdateConfigurationQuickFixTest.kt @@ -72,11 +72,6 @@ class MavenUpdateConfigurationQuickFixTest : MavenImportingTestCase() { doTest("Set module language version to 1.1") } - @Test - fun testEnableCoroutines() { - doTest("Enable coroutine support in the current module") - } - @Test fun testEnableInlineClasses() { doTest("Enable inline classes support in the current module") diff --git a/idea/testData/configuration/jvmProjectWithV4FacetConfig/module.iml b/idea/testData/configuration/jvmProjectWithV4FacetConfig/module.iml new file mode 100644 index 00000000000..ca7f7a87b20 --- /dev/null +++ b/idea/testData/configuration/jvmProjectWithV4FacetConfig/module.iml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/idea/testData/configuration/jvmProjectWithV4FacetConfig/projectFile.ipr b/idea/testData/configuration/jvmProjectWithV4FacetConfig/projectFile.ipr new file mode 100644 index 00000000000..a1407e2c8cd --- /dev/null +++ b/idea/testData/configuration/jvmProjectWithV4FacetConfig/projectFile.ipr @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/configuration/jvmProjectWithV4FacetConfig/src/foo.kt b/idea/testData/configuration/jvmProjectWithV4FacetConfig/src/foo.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/configuration/loadAndSaveOldNativePlatformNewNativeFacet/module.iml b/idea/testData/configuration/loadAndSaveOldNativePlatformNewNativeFacet/module.iml index 1bb831be9cc..fdfb6b85db5 100644 --- a/idea/testData/configuration/loadAndSaveOldNativePlatformNewNativeFacet/module.iml +++ b/idea/testData/configuration/loadAndSaveOldNativePlatformNewNativeFacet/module.iml @@ -9,7 +9,6 @@ @@ -23,4 +22,4 @@ - \ No newline at end of file + diff --git a/idea/testData/configuration/loadAndSaveOldNativePlatformOldNativeFacet/module.iml b/idea/testData/configuration/loadAndSaveOldNativePlatformOldNativeFacet/module.iml index 13d086cf8b9..621852d3d56 100644 --- a/idea/testData/configuration/loadAndSaveOldNativePlatformOldNativeFacet/module.iml +++ b/idea/testData/configuration/loadAndSaveOldNativePlatformOldNativeFacet/module.iml @@ -9,7 +9,6 @@ @@ -23,4 +22,4 @@ - \ No newline at end of file + diff --git a/idea/testData/configuration/loadAndSaveProjectWithV2FacetConfig/module.iml b/idea/testData/configuration/loadAndSaveProjectWithV2FacetConfig/module.iml index 593634d6d64..0b4d94829af 100644 --- a/idea/testData/configuration/loadAndSaveProjectWithV2FacetConfig/module.iml +++ b/idea/testData/configuration/loadAndSaveProjectWithV2FacetConfig/module.iml @@ -10,7 +10,6 @@