[FIR JS] Stop reporting NON_MEMBER_FUNCTION_NO_BODY for js natives
diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsPlatformDiagnosticSuppressor.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsPlatformDiagnosticSuppressor.kt
new file mode 100644
index 0000000..1775486
--- /dev/null
+++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsPlatformDiagnosticSuppressor.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2022 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.analysis.js.checkers
+
+import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformDiagnosticSuppressor
+import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
+import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
+import org.jetbrains.kotlin.fir.declarations.FirDeclaration
+import org.jetbrains.kotlin.fir.declarations.FirVariable
+import org.jetbrains.kotlin.fir.declarations.hasAnnotationOrInsideAnnotatedClass
+import org.jetbrains.kotlin.name.StandardClassIds
+
+private val NATIVE_ANNOTATIONS = arrayOf(
+    StandardClassIds.Annotations.JsNative,
+    StandardClassIds.Annotations.JsNativeInvoke,
+    StandardClassIds.Annotations.JsNativeGetter,
+    StandardClassIds.Annotations.JsNativeSetter,
+)
+
+private fun FirDeclaration.isLexicallyInsideJsNative(context: CheckerContext): Boolean {
+    return NATIVE_ANNOTATIONS.any { hasAnnotationOrInsideAnnotatedClass(it, context.session) }
+}
+
+object FirJsPlatformDiagnosticSuppressor : FirPlatformDiagnosticSuppressor {
+    override fun shouldReportUnusedParameter(parameter: FirVariable, context: CheckerContext) =
+        !parameter.isLexicallyInsideJsNative(context)
+
+    override fun shouldReportNoBody(declaration: FirCallableDeclaration, context: CheckerContext) =
+        !declaration.isLexicallyInsideJsNative(context)
+}
diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt
index ae76fc8..cdc5a9c 100644
--- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt
+++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/JsDeclarationCheckers.kt
@@ -36,4 +36,9 @@
             FirJsExternalChecker,
             FirJsExternalFileChecker,
         )
+
+    override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>
+        get() = setOf(
+            FirJsTopLevelFunctionsChecker,
+        )
 }
diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsTopLevelFunctionsChecker.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsTopLevelFunctionsChecker.kt
new file mode 100644
index 0000000..2ab9dfa
--- /dev/null
+++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/declaration/FirJsTopLevelFunctionsChecker.kt
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2010-2022 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.analysis.js.checkers.declaration
+
+import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirTopLevelFunctionsChecker
+import org.jetbrains.kotlin.fir.analysis.js.checkers.FirJsPlatformDiagnosticSuppressor
+
+object FirJsTopLevelFunctionsChecker : FirTopLevelFunctionsChecker() {
+    override val suppressor = FirJsPlatformDiagnosticSuppressor
+}
diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt
index 09b460b..fba9f66 100644
--- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt
+++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/JvmDeclarationCheckers.kt
@@ -50,4 +50,9 @@
         get() = setOf(
             FirUpperBoundsChecker,
         )
+
+    override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>
+        get() = setOf(
+            FirJvmTopLevelFunctionsChecker,
+        )
 }
diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmTopLevelFunctionsChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmTopLevelFunctionsChecker.kt
new file mode 100644
index 0000000..b9d58e8
--- /dev/null
+++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmTopLevelFunctionsChecker.kt
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2010-2022 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.analysis.jvm.checkers.declaration
+
+import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformDiagnosticSuppressor
+import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirTopLevelFunctionsChecker
+
+object FirJvmTopLevelFunctionsChecker : FirTopLevelFunctionsChecker() {
+    override val suppressor = FirPlatformDiagnosticSuppressor.Default
+}
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt
index 2741c02..873746e 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt
@@ -53,7 +53,6 @@
             FirFunctionTypeParametersSyntaxChecker,
             FirOperatorModifierChecker,
             FirTailrecFunctionChecker,
-            FirTopLevelFunctionsChecker,
             FirMemberFunctionsChecker,
         )
 
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirPlatformDiagnosticSuppressor.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirPlatformDiagnosticSuppressor.kt
new file mode 100644
index 0000000..4ba6397
--- /dev/null
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirPlatformDiagnosticSuppressor.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2022 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.analysis.checkers
+
+import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
+import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
+import org.jetbrains.kotlin.fir.declarations.FirVariable
+
+interface FirPlatformDiagnosticSuppressor {
+    fun shouldReportUnusedParameter(parameter: FirVariable, context: CheckerContext): Boolean
+
+    fun shouldReportNoBody(declaration: FirCallableDeclaration, context: CheckerContext): Boolean
+
+    object Default : FirPlatformDiagnosticSuppressor {
+        override fun shouldReportUnusedParameter(parameter: FirVariable, context: CheckerContext): Boolean = true
+
+        override fun shouldReportNoBody(declaration: FirCallableDeclaration, context: CheckerContext): Boolean = true
+    }
+}
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionsChecker.kt
index 2fa4b59f..2fe9456 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionsChecker.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelFunctionsChecker.kt
@@ -8,6 +8,7 @@
 import org.jetbrains.kotlin.KtFakeSourceElementKind
 import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
 import org.jetbrains.kotlin.diagnostics.reportOn
+import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformDiagnosticSuppressor
 import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
 import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier
 import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
@@ -18,7 +19,9 @@
 import org.jetbrains.kotlin.lexer.KtTokens
 
 // See old FE's [DeclarationsChecker]
-object FirTopLevelFunctionsChecker : FirSimpleFunctionChecker() {
+abstract class FirTopLevelFunctionsChecker : FirSimpleFunctionChecker() {
+    abstract val suppressor: FirPlatformDiagnosticSuppressor
+
     override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) {
         // Only report on top level callable declarations
         if (context.containingDeclarations.size > 1) return
@@ -29,7 +32,7 @@
         // So, our source of truth should be the full modifier list retrieved from the source.
         if (declaration.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return
         if (declaration.isExternal) return
-        if (!declaration.hasBody && !declaration.isExpect) {
+        if (!declaration.hasBody && !declaration.isExpect && suppressor.shouldReportNoBody(declaration, context)) {
             reporter.reportOn(source, FirErrors.NON_MEMBER_FUNCTION_NO_BODY, declaration.symbol, context)
         }
 
diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt
index 5c1b6ed..8bd94ee 100644
--- a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt
+++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeGetter.kt
@@ -1,4 +1,3 @@
-// FIR_IGNORE
 // FIR_IDENTICAL
 // !DIAGNOSTICS: -DEPRECATION
 @nativeGetter
diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt
index fdd611a..63a43e7 100644
--- a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt
+++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeInvoke.kt
@@ -1,4 +1,3 @@
-// FIR_IGNORE
 // FIR_IDENTICAL
 // !DIAGNOSTICS: -DEPRECATION
 @nativeInvoke
diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt
index c913eb0..f15e8c8 100644
--- a/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt
+++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/optionlBody/nativeSetter.kt
@@ -1,4 +1,3 @@
-// FIR_IGNORE
 // FIR_IDENTICAL
 // !DIAGNOSTICS: -DEPRECATION
 @nativeSetter