diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index c824a2247e2..feb578523e6 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -731,7 +731,7 @@ class ControlFlowInformationProviderImpl private constructor( if (functionDescriptor.isExpect || functionDescriptor.isActual || functionDescriptor.isEffectivelyExternal() || - !diagnosticSuppressor.shouldReportUnusedParameter(variableDescriptor) + !diagnosticSuppressor.shouldReportUnusedParameter(variableDescriptor, trace.bindingContext) ) return when (val owner = element.parent.parent) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt index 6dd3ac1cad4..a11e02802c1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt @@ -21,23 +21,24 @@ import org.jetbrains.kotlin.container.PlatformExtensionsClashResolver import org.jetbrains.kotlin.container.PlatformSpecificExtension import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.resolve.BindingContext @DefaultImplementation(PlatformDiagnosticSuppressor.Default::class) interface PlatformDiagnosticSuppressor : PlatformSpecificExtension{ - fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean + fun shouldReportUnusedParameter(parameter: VariableDescriptor, bindingContext: BindingContext): Boolean fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean object Default : PlatformDiagnosticSuppressor { - override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean = true + override fun shouldReportUnusedParameter(parameter: VariableDescriptor, bindingContext: BindingContext): Boolean = true override fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean = true } } class CompositePlatformDiagnosticSuppressor(private val suppressors: List) : PlatformDiagnosticSuppressor { - override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean = - suppressors.all { it.shouldReportUnusedParameter(parameter) } + override fun shouldReportUnusedParameter(parameter: VariableDescriptor, bindingContext: BindingContext): Boolean = + suppressors.all { it.shouldReportUnusedParameter(parameter, bindingContext) } override fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean = suppressors.all { it.shouldReportNoBody(descriptor) } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt index 1aa32971b0f..5f57e846bce 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.name.JsStandardClassIds +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor private val nativeAnnotations = JsStandardClassIds.Annotations.nativeAnnotations.map { it.asSingleFqName() } @@ -35,7 +36,8 @@ private fun DeclarationDescriptor.isLexicallyInsideJsNative(): Boolean { } object JsNativeDiagnosticSuppressor : PlatformDiagnosticSuppressor { - override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean = !parameter.isLexicallyInsideJsNative() + override fun shouldReportUnusedParameter(parameter: VariableDescriptor, bindingContext: BindingContext): Boolean = + !parameter.isLexicallyInsideJsNative() override fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean = !descriptor.isLexicallyInsideJsNative() } diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/analyze/WasmDiagnosticSuppressor.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/analyze/WasmDiagnosticSuppressor.kt new file mode 100644 index 00000000000..3844668d0ef --- /dev/null +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/analyze/WasmDiagnosticSuppressor.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2023 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.wasm.analyze + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.JsStandardClassIds +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor +import org.jetbrains.kotlin.wasm.util.hasValidJsCodeBody + + +object WasmDiagnosticSuppressor : PlatformDiagnosticSuppressor { + override fun shouldReportUnusedParameter(parameter: VariableDescriptor, bindingContext: BindingContext): Boolean { + val containingDeclaration = parameter.containingDeclaration + if (containingDeclaration is FunctionDescriptor) { + return !containingDeclaration.hasValidJsCodeBody(bindingContext) + } + return true + } + + override fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean = true +} \ No newline at end of file diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt index c9c02971f0e..c811b1967e5 100644 --- a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt @@ -8,13 +8,13 @@ package org.jetbrains.kotlin.wasm.resolve import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.useImpl import org.jetbrains.kotlin.container.useInstance -import org.jetbrains.kotlin.js.analyze.JsNativeDiagnosticSuppressor import org.jetbrains.kotlin.js.naming.NameSuggestion import org.jetbrains.kotlin.js.resolve.ExtensionFunctionToExternalIsInlinable import org.jetbrains.kotlin.js.resolve.diagnostics.* import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase import org.jetbrains.kotlin.resolve.calls.checkers.LateinitIntrinsicApplicabilityChecker import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker +import org.jetbrains.kotlin.wasm.analyze.WasmDiagnosticSuppressor import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmExternalDeclarationChecker import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmExternalInheritanceChecker import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmImportAnnotationChecker @@ -50,7 +50,7 @@ object WasmPlatformConfigurator : PlatformConfiguratorBase( container.useImpl() container.useInstance(ExtensionFunctionToExternalIsInlinable) container.useInstance(JsQualifierChecker) - container.useInstance(JsNativeDiagnosticSuppressor) + container.useInstance(WasmDiagnosticSuppressor) } override fun configureModuleDependentCheckers(container: StorageComponentContainer) { diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/util/jsCodeUtils.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/util/jsCodeUtils.kt new file mode 100644 index 00000000000..31089c01cba --- /dev/null +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/util/jsCodeUtils.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2023 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.wasm.util + +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.js.resolve.diagnostics.JsCallChecker.Companion.isJsCall +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall +import org.jetbrains.kotlin.resolve.source.getPsi + +fun FunctionDescriptor.hasValidJsCodeBody(bindingContext: BindingContext): Boolean { + val psi = source.getPsi() as? KtNamedFunction ?: return false + return psi.hasValidJsCodeBody(bindingContext) +} + +private fun KtDeclarationWithBody.hasValidJsCodeBody(bindingContext: BindingContext): Boolean { + if (!hasBody()) return true + val body = bodyExpression!! + return when { + !hasBlockBody() -> body.isJsCall(bindingContext) + body is KtBlockExpression -> { + val statement = body.statements.singleOrNull() ?: return false + statement.isJsCall(bindingContext) + } + else -> false + } +} + +private fun KtExpression.isJsCall(bindingContext: BindingContext): Boolean { + return getResolvedCall(bindingContext)?.isJsCall() ?: false +} \ No newline at end of file