From 5d44e095c8407244b21cf04877b2ea70f82e6d03 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 21 Jul 2017 17:42:18 +0300 Subject: [PATCH] Nullability assertions for extension receiver In Kotlin 1.1 and before, there were no nullability assertions on extension receivers, because receiver is resolved with NO_EXPECTED_TYPE. So, if an expression of platform type is passed as an extension receiver to a non-private function, it would fail with IllegalArgumentException. However, if the function is private, then we generated no parameter assertions under assumption that such function can be called from Kotlin only, and all arguments are checked on the call site. Thus 'null' could propagate indefinitely. In Kotlin 1.2, we do the following: - Generate nullability assertions for expression receivers. NB nullability assertions are stored for ReceiverValue instances, not for expressions: given expression can act as receiver in different calls, each with an expected receiver type of its own. - Generate nullability assertions for extension receivers of private operator functions. NB it still can throw NPE for some particular "optimized" cases, but at least those nulls would not propagate indefinitely. This behavior is disabled by an "advanced" command-line option '-Xno-receiver-assertions'. --- .../org/jetbrains/kotlin/codegen/AsmUtil.java | 29 +++++-- .../kotlin/codegen/ExpressionCodegen.java | 10 ++- .../kotlin/codegen/state/GenerationState.kt | 7 +- .../arguments/K2JVMCompilerArguments.kt | 5 +- .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 3 + .../kotlin/config/JVMConfigurationKeys.java | 2 + .../resolve/jvm/JvmBindingContextSlices.kt | 5 ++ .../kotlin/resolve/jvm/RuntimeAssertions.kt | 62 ++++++++++++--- .../jvm/platform/JvmPlatformConfigurator.kt | 3 +- compiler/testData/cli/jvm/extraHelp.out | 3 +- ...bilityAssertionOnExtensionReceiver_lv12.kt | 28 +++++++ ...ExtensionReceiverInPrivateOperator_lv11.kt | 17 +++++ ...ExtensionReceiverInPrivateOperator_lv12.kt | 21 ++++++ ...bilityAssertionOnExtensionReceiver_lv11.kt | 21 ++++++ ...bilityAssertionOnExtensionReceiver_lv12.kt | 21 ++++++ ...bilityAssertionOnExtensionReceiver_lv11.kt | 17 +++++ ...bilityAssertionOnExtensionReceiver_lv12.kt | 17 +++++ ...ertionOnInlineFunExtensionReceiver_lv11.kt | 17 +++++ ...ertionOnInlineFunExtensionReceiver_lv12.kt | 19 +++++ ...AssertionOnMemberExtensionReceiver_lv12.kt | 20 +++++ ...onOnPrivateMemberExtensionReceiver_lv12.kt | 22 ++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 75 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 75 +++++++++++++++++++ .../LightAnalysisModeTestGenerated.java | 75 +++++++++++++++++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + .../semantics/JsCodegenBoxTestGenerated.java | 9 +++ 26 files changed, 563 insertions(+), 21 deletions(-) create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv11.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv12.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv11.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv12.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnMemberExtensionReceiver_lv12.kt create mode 100644 compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 3a2f34de01b..35e828a9f55 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.codegen.serialization.JvmStringTable; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.config.JvmTarget; +import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.lexer.KtTokens; @@ -660,8 +661,23 @@ public class AsmUtil { // currently when resuming a suspend function we pass default values instead of real arguments (i.e. nulls for references) if (descriptor.isSuspend()) return; - // Private method is not accessible from other classes, no assertions needed - if (getVisibilityAccessFlag(descriptor) == ACC_PRIVATE) return; + if (getVisibilityAccessFlag(descriptor) == ACC_PRIVATE) { + // Private method is not accessible from other classes, no assertions needed, + // unless we have a private operator function, in which we should generate a parameter assertion for an extension receiver. + + // HACK: this provides "fail fast" behavior for operator functions. + // Such functions can be invoked in operator conventions desugaring, + // which is currently done on ad hoc basis in ExpressionCodegen. + + if (state.isReceiverAssertionsDisabled()) return; + if (descriptor.isOperator()) { + ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); + if (receiverParameter != null) { + genParamAssertion(v, state.getTypeMapper(), frameMap, receiverParameter, "$receiver"); + } + } + return; + } ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); if (receiverParameter != null) { @@ -677,18 +693,19 @@ public class AsmUtil { @NotNull InstructionAdapter v, @NotNull KotlinTypeMapper typeMapper, @NotNull FrameMap frameMap, - @NotNull CallableDescriptor parameter, + @NotNull ParameterDescriptor parameter, @NotNull String name ) { - KotlinType type = parameter.getReturnType(); - if (type == null || isNullableType(type)) return; + KotlinType type = parameter.getType(); + if (isNullableType(type)) return; int index = frameMap.getIndex(parameter); Type asmType = typeMapper.mapType(type); if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { v.load(index, asmType); v.visitLdcInsn(name); - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkParameterIsNotNull", + String checkMethod = "checkParameterIsNotNull"; + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, checkMethod, "(Ljava/lang/Object;Ljava/lang/String;)V", false); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index a9e8d8618be..6e6a0e0ef66 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -52,6 +52,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.codegen.when.SwitchCodegen; import org.jetbrains.kotlin.codegen.when.SwitchCodegenProvider; import org.jetbrains.kotlin.config.ApiVersion; +import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; @@ -2466,7 +2467,14 @@ public class ExpressionCodegen extends KtVisitor impleme return generateExtensionReceiver(((ExtensionReceiver) receiverValue).getDeclarationDescriptor()); } else if (receiverValue instanceof ExpressionReceiver) { - return gen(((ExpressionReceiver) receiverValue).getExpression()); + ExpressionReceiver expressionReceiver = (ExpressionReceiver) receiverValue; + StackValue stackValue = gen(expressionReceiver.getExpression()); + if (!state.isReceiverAssertionsDisabled()) { + RuntimeAssertionInfo runtimeAssertionInfo = + bindingContext.get(JvmBindingContextSlices.RECEIVER_RUNTIME_ASSERTION_INFO, expressionReceiver); + stackValue = genNotNullAssertions(state, stackValue, runtimeAssertionInfo); + } + return stackValue; } else { throw new UnsupportedOperationException("Unsupported receiver value: " + receiverValue); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index 04777c54acd..95b31d648f1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -156,7 +156,12 @@ class GenerationState @JvmOverloads constructor( var hasResult: Boolean = false } + val languageVersionSettings = configuration.languageVersionSettings + val isCallAssertionsDisabled: Boolean = configuration.getBoolean(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS) + val isReceiverAssertionsDisabled: Boolean = + configuration.getBoolean(JVMConfigurationKeys.DISABLE_RECEIVER_ASSERTIONS) || + !languageVersionSettings.supportsFeature(LanguageFeature.NullabilityAssertionOnExtensionReceiver) val isParamAssertionsDisabled: Boolean = configuration.getBoolean(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS) val isInlineDisabled: Boolean = configuration.getBoolean(CommonConfigurationKeys.DISABLE_INLINE) val useTypeTableInSerializer: Boolean = configuration.getBoolean(JVMConfigurationKeys.USE_TYPE_TABLE) @@ -168,7 +173,7 @@ class GenerationState @JvmOverloads constructor( val generateParametersMetadata: Boolean = configuration.getBoolean(JVMConfigurationKeys.PARAMETERS_METADATA) - val languageVersionSettings = configuration.languageVersionSettings + val shouldInlineConstVals = languageVersionSettings.supportsFeature(LanguageFeature.InlineConstVals) init { 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 fd79b40e081..0329c0de1c0 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 @@ -93,9 +93,12 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { ) var additionalJavaModules: Array? by FreezableVar(null) - @Argument(value = "-Xno-call-assertions", description = "Don't generate not-null assertion after each invocation of method returning not-null") + @Argument(value = "-Xno-call-assertions", description = "Don't generate not-null assertions for arguments of platform types") var noCallAssertions: Boolean by FreezableVar(false) + @Argument(value = "-Xno-receiver-assertions", description = "Don't generate not-null assertion for extension receiver arguments of platform types") + var noReceiverAssertions: Boolean by FreezableVar(false) + @Argument(value = "-Xno-param-assertions", description = "Don't generate not-null assertions on parameters of methods accessible from Java") var noParamAssertions: Boolean by FreezableVar(false) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index 41d9d12cf59..76b9176ae11 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -341,6 +341,7 @@ class K2JVMCompiler : CLICompiler() { private fun putAdvancedOptions(configuration: CompilerConfiguration, arguments: K2JVMCompilerArguments) { configuration.put(JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS, arguments.noCallAssertions) + configuration.put(JVMConfigurationKeys.DISABLE_RECEIVER_ASSERTIONS, arguments.noReceiverAssertions) configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, arguments.noParamAssertions) configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize) configuration.put(JVMConfigurationKeys.INHERIT_MULTIFILE_PARTS, arguments.inheritMultifileParts) @@ -358,6 +359,8 @@ class K2JVMCompiler : CLICompiler() { configuration.put(JVMConfigurationKeys.ADD_BUILT_INS_FROM_COMPILER_TO_DEPENDENCIES, arguments.addCompilerBuiltIns) configuration.put(JVMConfigurationKeys.CREATE_BUILT_INS_FROM_MODULE_DEPENDENCIES, arguments.loadBuiltInsFromDependencies) + + arguments.declarationsOutputPath?.let { configuration.put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java index 111ef560f75..369e89f43d3 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java @@ -50,6 +50,8 @@ public class JVMConfigurationKeys { public static final CompilerConfigurationKey DISABLE_CALL_ASSERTIONS = CompilerConfigurationKey.create("disable not-null call assertions"); + public static final CompilerConfigurationKey DISABLE_RECEIVER_ASSERTIONS = + CompilerConfigurationKey.create("disable not-null call receiver assertions"); public static final CompilerConfigurationKey DISABLE_PARAM_ASSERTIONS = CompilerConfigurationKey.create("disable not-null parameter assertions"); public static final CompilerConfigurationKey DISABLE_OPTIMIZATION = diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmBindingContextSlices.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmBindingContextSlices.kt index 958fe8237f4..2022fd0cd22 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmBindingContextSlices.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmBindingContextSlices.kt @@ -18,6 +18,8 @@ package org.jetbrains.kotlin.resolve.jvm import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice import org.jetbrains.kotlin.util.slicedMap.RewritePolicy import org.jetbrains.kotlin.util.slicedMap.Slices @@ -27,6 +29,9 @@ object JvmBindingContextSlices { @JvmField val RUNTIME_ASSERTION_INFO: WritableSlice = BasicWritableSlice(RewritePolicy.DO_NOTHING) + @JvmField + val RECEIVER_RUNTIME_ASSERTION_INFO: WritableSlice = BasicWritableSlice(RewritePolicy.DO_NOTHING) + @JvmField val LOAD_FROM_JAVA_SIGNATURE_ERRORS: WritableSlice> = Slices.createCollectiveSlice() diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/RuntimeAssertions.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/RuntimeAssertions.kt index a0535f98197..b2e55e121c0 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/RuntimeAssertions.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/RuntimeAssertions.kt @@ -17,14 +17,24 @@ package org.jetbrains.kotlin.resolve.jvm import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker +import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker +import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory +import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.isError +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class RuntimeAssertionInfo(val needNotNullAssertion: Boolean, val message: String) { interface DataFlowExtras { @@ -73,6 +83,19 @@ class RuntimeAssertionInfo(val needNotNullAssertion: Boolean, val message: Strin } } +class RuntimeAssertionsDataFlowExtras( + private val c: ResolutionContext<*>, + private val dataFlowValue: DataFlowValue, + private val expression: KtExpression +) : RuntimeAssertionInfo.DataFlowExtras { + override val canBeNull: Boolean + get() = c.dataFlowInfo.getStableNullability(dataFlowValue).canBeNull() + override val possibleTypes: Set + get() = c.dataFlowInfo.getCollectedTypes(dataFlowValue) + override val presentableText: String + get() = StringUtil.trimMiddle(expression.text, 50) +} + object RuntimeAssertionsTypeChecker : AdditionalTypeChecker { override fun checkType(expression: KtExpression, expressionType: KotlinType, expressionTypeWithSmartCast: KotlinType, c: ResolutionContext<*>) { if (TypeUtils.noExpectedType(c.expectedType)) return @@ -80,20 +103,39 @@ object RuntimeAssertionsTypeChecker : AdditionalTypeChecker { val assertionInfo = RuntimeAssertionInfo.create( c.expectedType, expressionType, - object : RuntimeAssertionInfo.DataFlowExtras { - override val canBeNull: Boolean - get() = c.dataFlowInfo.getStableNullability(dataFlowValue).canBeNull() - override val possibleTypes: Set - get() = c.dataFlowInfo.getCollectedTypes(dataFlowValue) - override val presentableText: String - get() = StringUtil.trimMiddle(expression.text, 50) - - private val dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression, expressionType, c) - } + RuntimeAssertionsDataFlowExtras(c, DataFlowValueFactory.createDataFlowValue(expression, expressionType, c), expression) ) if (assertionInfo != null) { c.trace.record(JvmBindingContextSlices.RUNTIME_ASSERTION_INFO, expression, assertionInfo) } } + } + +object RuntimeAssertionsOnExtensionReceiverCallChecker : CallChecker { + override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { + if (resolvedCall.call.isSafeCall()) return + + val callee = resolvedCall.resultingDescriptor + checkReceiver(callee.extensionReceiverParameter, resolvedCall.extensionReceiver, context) + } + + private fun checkReceiver(receiverParameter: ReceiverParameterDescriptor?, receiverValue: ReceiverValue?, context: CallCheckerContext) { + if (receiverParameter == null || receiverValue == null) return + val expressionReceiverValue = receiverValue.safeAs() ?: return + val receiverExpression = expressionReceiverValue.expression + val c = context.resolutionContext + val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverExpression, receiverValue.type, c) + + val assertionInfo = RuntimeAssertionInfo.create( + receiverParameter.type, + receiverValue.type, + RuntimeAssertionsDataFlowExtras(c, dataFlowValue, receiverExpression) + ) + + if (assertionInfo != null) { + c.trace.record(JvmBindingContextSlices.RECEIVER_RUNTIME_ASSERTION_INFO, expressionReceiverValue, assertionInfo) + } + } +} \ No newline at end of file diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt index 9326bb48973..0badad5ea22 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt @@ -53,7 +53,8 @@ object JvmPlatformConfigurator : PlatformConfigurator( UnsupportedSyntheticCallableReferenceChecker(), SuperCallWithDefaultArgumentsChecker(), ProtectedSyntheticExtensionCallChecker, - ReifiedTypeParameterSubstitutionChecker() + ReifiedTypeParameterSubstitutionChecker(), + RuntimeAssertionsOnExtensionReceiverCallChecker ), additionalTypeCheckers = listOf( diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 2302f980146..fd460a16812 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -13,9 +13,10 @@ where advanced options include: Specify global behavior for JSR-305 nullability annotations: ignore, treat as other supported nullability annotations, or report a warning -Xload-builtins-from-dependencies Load definitions of built-in declarations from module dependencies, instead of from the compiler - -Xno-call-assertions Don't generate not-null assertion after each invocation of method returning not-null + -Xno-call-assertions Don't generate not-null assertions for arguments of platform types -Xno-optimize Disable optimizations -Xno-param-assertions Don't generate not-null assertions on parameters of methods accessible from Java + -Xno-receiver-assertions Don't generate not-null assertion for extension receiver arguments of platform types -Xreport-perf Report detailed performance statistics -Xscript-resolver-environment= Script resolver environment in key-value pairs (the value could be quoted and escaped) diff --git a/compiler/testData/codegen/box/nullabilityAssertions/destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt b/compiler/testData/codegen/box/nullabilityAssertions/destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt new file mode 100644 index 00000000000..52032e8f491 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt @@ -0,0 +1,28 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: test.kt +// LANGUAGE_VERSION: 1.2 +import kotlin.test.* + +var component1Evaluated = false + +// NB extension receiver is nullable +operator fun J?.component1() = 1.also { component1Evaluated = true } + +private operator fun J.component2() = 2 + +fun use(x: Any) {} + +fun box(): String { + assertFailsWith { + val (a, b) = J.j() + } + if (!component1Evaluated) return "component1 should be evaluated" + return "OK" +} + + +// FILE: J.java +public class J { + public static J j() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt new file mode 100644 index 00000000000..e14e5e764e4 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM +// FILE: test.kt +// WITH_RUNTIME +// LANGUAGE_VERSION: 1.1 +private operator fun A.inc() = A() + +fun box(): String { + var aNull = A.n() + aNull++ + // NB no exception is thrown in language version 1.1 + return "OK" +} + +// FILE: A.java +public class A { + public static A n() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt new file mode 100644 index 00000000000..2e09a3d9192 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt @@ -0,0 +1,21 @@ +// TARGET_BACKEND: JVM +// FILE: test.kt +// WITH_RUNTIME +// LANGUAGE_VERSION: 1.2 +import kotlin.test.* + +private operator fun A.inc() = A() + +fun box(): String { + assertFailsWith { + var aNull = A.n() + aNull++ + } + + return "OK" +} + +// FILE: A.java +public class A { + public static A n() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv11.kt b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv11.kt new file mode 100644 index 00000000000..8c1121f7777 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv11.kt @@ -0,0 +1,21 @@ +// TARGET_BACKEND: JVM +// FILE: test.kt +// WITH_RUNTIME +// LANGUAGE_VERSION: 1.1 +import kotlin.test.* + +operator fun A.inc() = A() + +fun box(): String { + assertFailsWith { + var aNull = A.n() + aNull++ + } + + return "OK" +} + +// FILE: A.java +public class A { + public static A n() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv12.kt b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv12.kt new file mode 100644 index 00000000000..330281df860 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv12.kt @@ -0,0 +1,21 @@ +// TARGET_BACKEND: JVM +// FILE: test.kt +// WITH_RUNTIME +// LANGUAGE_VERSION: 1.2 +import kotlin.test.* + +operator fun A.inc() = A() + +fun box(): String { + assertFailsWith { + var aNull = A.n() + aNull++ + } + + return "OK" +} + +// FILE: A.java +public class A { + public static A n() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv11.kt b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv11.kt new file mode 100644 index 00000000000..70e926c8b18 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv11.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: test.kt +// LANGUAGE_VERSION: 1.1 +import kotlin.test.* + +fun String.extension() {} + +fun box(): String { + assertFailsWith { J.s().extension() } + return "OK" +} + +// FILE: J.java +public class J { + public static String s() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv12.kt b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv12.kt new file mode 100644 index 00000000000..ece06c560ae --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv12.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: test.kt +// LANGUAGE_VERSION: 1.2 +import kotlin.test.* + +fun String.extension() {} + +fun box(): String { + assertFailsWith { J.s().extension() } + return "OK" +} + +// FILE: J.java +public class J { + public static String s() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt new file mode 100644 index 00000000000..4547e585579 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: test.kt +// LANGUAGE_VERSION: 1.1 +import kotlin.test.* + +inline fun String.extension() {} + +fun box(): String { + J.s().extension() // NB no exception thrown + return "OK" +} + +// FILE: J.java +public class J { + public static String s() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt new file mode 100644 index 00000000000..768e5c56e14 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt @@ -0,0 +1,19 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: test.kt +// LANGUAGE_VERSION: 1.2 +import kotlin.test.* + +inline fun String.extension() {} + +fun box(): String { + assertFailsWith { + J.s().extension() + } + return "OK" +} + +// FILE: J.java +public class J { + public static String s() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnMemberExtensionReceiver_lv12.kt b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnMemberExtensionReceiver_lv12.kt new file mode 100644 index 00000000000..816f669d74d --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnMemberExtensionReceiver_lv12.kt @@ -0,0 +1,20 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: test.kt +// LANGUAGE_VERSION: 1.2 +import kotlin.test.* + +class C { + fun test() { J.s().memberExtension() } + fun String.memberExtension() {} +} + +fun box(): String { + assertFailsWith { C().test() } + return "OK" +} + +// FILE: J.java +public class J { + public static String s() { return null; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt new file mode 100644 index 00000000000..5be1b082389 --- /dev/null +++ b/compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FILE: test.kt +// LANGUAGE_VERSION: 1.2 +import kotlin.test.* + +class C { + fun test() { J.s().memberExtension() } + private fun String.memberExtension() {} +} + +fun box(): String { + assertFailsWith { + C().test() + } + return "OK" +} + +// FILE: J.java +public class J { + public static String s() { return null; } +} \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 659c0082dfd..69175141ccd 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -11592,6 +11592,81 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/nullabilityAssertions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NullabilityAssertions extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInNullabilityAssertions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/nullabilityAssertions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testDestructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiver_lv11.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver_lv11.kt") + public void testNullabilityAssertionOnExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt") + public void testNullabilityAssertionOnInlineFunExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnInlineFunExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnMemberExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnMemberExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnMemberExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnPrivateMemberExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/objectIntrinsics") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 58890b421b0..ac069a6adea 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -11592,6 +11592,81 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/nullabilityAssertions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NullabilityAssertions extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInNullabilityAssertions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/nullabilityAssertions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testDestructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiver_lv11.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver_lv11.kt") + public void testNullabilityAssertionOnExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt") + public void testNullabilityAssertionOnInlineFunExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnInlineFunExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnMemberExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnMemberExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnMemberExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnPrivateMemberExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/objectIntrinsics") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 7c4799b0c49..b644b1e9a27 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11592,6 +11592,81 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/nullabilityAssertions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NullabilityAssertions extends AbstractLightAnalysisModeTest { + public void testAllFilesPresentInNullabilityAssertions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/nullabilityAssertions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testDestructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/destructuringAssignmentWithNullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiverInPrivateOperator_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiver_lv11.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("incWithNullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testIncWithNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/incWithNullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver_lv11.kt") + public void testNullabilityAssertionOnExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt") + public void testNullabilityAssertionOnInlineFunExtensionReceiver_lv11() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv11.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnInlineFunExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnInlineFunExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnMemberExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnMemberExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnMemberExtensionReceiver_lv12.kt"); + doTest(fileName); + } + + @TestMetadata("nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt") + public void testNullabilityAssertionOnPrivateMemberExtensionReceiver_lv12() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/nullabilityAssertions/nullabilityAssertionOnPrivateMemberExtensionReceiver_lv12.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/objectIntrinsics") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 000825d64b6..edaf38dddef 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -54,6 +54,7 @@ enum class LanguageFeature( InlineDefaultFunctionalParameters(KOTLIN_1_2), SoundSmartCastsAfterTry(KOTLIN_1_2), DeprecatedFieldForInvisibleCompanionObject(KOTLIN_1_2), + NullabilityAssertionOnExtensionReceiver(KOTLIN_1_2), SafeCastCheckBoundSmartCasts(KOTLIN_1_2), BooleanElvisBoundSmartCasts(KOTLIN_1_2), CapturedInClosureSmartCasts(KOTLIN_1_2), diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b999e5eb49e..9a2ec0ba8ef 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -12954,6 +12954,15 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/nullabilityAssertions") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class NullabilityAssertions extends AbstractJsCodegenBoxTest { + public void testAllFilesPresentInNullabilityAssertions() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/nullabilityAssertions"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + } + @TestMetadata("compiler/testData/codegen/box/objectIntrinsics") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)