From 881997585ac9d90a60115957cca7c63aafd1b5cf Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Wed, 4 Oct 2023 15:31:16 +0200 Subject: [PATCH] [Wasm] Add K2 checkers.web.common module (KT-56849) This module is created to share JS and Wasm checker logic Extract isEffectivelyExternal util fun from K/JS in order to reuse it in Wasm checkers --- build.gradle.kts | 1 + .../fir/checkers/checkers.js/build.gradle.kts | 1 + .../fir/analysis/js/checkers/FirJsHelpers.kt | 24 ----------- .../FirJsExternalArgumentCallChecker.kt | 2 +- .../checkers/checkers.wasm/build.gradle.kts | 6 ++- .../checkers.web.common/build.gradle.kts | 26 ++++++++++++ .../declarations/utils/FirWebCommonHelpers.kt | 42 +++++++++++++++++++ settings.gradle | 1 + 8 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 compiler/fir/checkers/checkers.web.common/build.gradle.kts create mode 100644 compiler/fir/checkers/checkers.web.common/src/org/jetbrains/kotlin/fir/declarations/utils/FirWebCommonHelpers.kt diff --git a/build.gradle.kts b/build.gradle.kts index cc5ff5a1bd2..47319c3c816 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -168,6 +168,7 @@ val firCompilerCoreModules = arrayOf( ":compiler:fir:checkers:checkers.js", ":compiler:fir:checkers:checkers.native", ":compiler:fir:checkers:checkers.wasm", + ":compiler:fir:checkers:checkers.web.common", ":compiler:fir:entrypoint", // TODO should not be in core modules but FIR IDE uses DependencyListForCliModule from this module ":compiler:fir:fir2ir:jvm-backend", // TODO should not be in core modules but FIR IDE uses Fir2IrSignatureComposer from this module ":compiler:fir:fir2ir" // TODO should not be in core modules but FIR IDE uses Fir2IrSignatureComposer from this module diff --git a/compiler/fir/checkers/checkers.js/build.gradle.kts b/compiler/fir/checkers/checkers.js/build.gradle.kts index e2ce96adbe3..7894c1c7af8 100644 --- a/compiler/fir/checkers/checkers.js/build.gradle.kts +++ b/compiler/fir/checkers/checkers.js/build.gradle.kts @@ -9,6 +9,7 @@ dependencies { api(project(":core:compiler.common.js")) api(project(":js:js.ast")) api(project(":compiler:fir:checkers")) + api(project(":compiler:fir:checkers:checkers.web.common")) // FE checks for modules use ModuleKind // This dependency can be removed when we stop supporting PLAIN and UMD module systems diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt index 7d6c6a0700b..506b4ec41b7 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/FirJsHelpers.kt @@ -31,30 +31,6 @@ import org.jetbrains.kotlin.js.common.isES5IdentifierPart import org.jetbrains.kotlin.js.common.isES5IdentifierStart import org.jetbrains.kotlin.name.JsStandardClassIds -private val FirBasedSymbol<*>.isExternal - get() = when (this) { - is FirCallableSymbol<*> -> isExternal - is FirClassSymbol<*> -> isExternal - else -> false - } - -fun FirBasedSymbol<*>.isEffectivelyExternal(session: FirSession): Boolean { - if (fir is FirMemberDeclaration && isExternal) return true - - if (this is FirPropertyAccessorSymbol) { - val property = propertySymbol - if (property.isEffectivelyExternal(session)) return true - } - - if (this is FirPropertySymbol) { - if (getterSymbol?.isExternal == true && (!isVar || setterSymbol?.isExternal == true)) { - return true - } - } - - return getContainingClassSymbol(session)?.isEffectivelyExternal(session) == true -} - fun FirBasedSymbol<*>.isEffectivelyExternalMember(session: FirSession): Boolean { return fir is FirMemberDeclaration && isEffectivelyExternal(session) } diff --git a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsExternalArgumentCallChecker.kt b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsExternalArgumentCallChecker.kt index 9e827f26cbb..c59b9ab44c5 100644 --- a/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsExternalArgumentCallChecker.kt +++ b/compiler/fir/checkers/checkers.js/src/org/jetbrains/kotlin/fir/analysis/js/checkers/expression/FirJsExternalArgumentCallChecker.kt @@ -10,8 +10,8 @@ import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirCallChecker import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors -import org.jetbrains.kotlin.fir.analysis.js.checkers.isEffectivelyExternal import org.jetbrains.kotlin.fir.declarations.hasAnnotation +import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal import org.jetbrains.kotlin.fir.expressions.FirCall import org.jetbrains.kotlin.fir.expressions.resolvedArgumentMapping import org.jetbrains.kotlin.fir.expressions.unwrapArgument diff --git a/compiler/fir/checkers/checkers.wasm/build.gradle.kts b/compiler/fir/checkers/checkers.wasm/build.gradle.kts index 458ef39c8e6..25a6d5f9810 100644 --- a/compiler/fir/checkers/checkers.wasm/build.gradle.kts +++ b/compiler/fir/checkers/checkers.wasm/build.gradle.kts @@ -7,6 +7,7 @@ plugins { dependencies { api(project(":compiler:fir:checkers")) + api(project(":compiler:fir:checkers:checkers.web.common")) api(project(":core:compiler.common.wasm")) /* @@ -27,8 +28,9 @@ sourceSets { "test" { none() } } -val compileKotlin by tasks -compileKotlin.dependsOn(":compiler:fir:checkers:generateCheckersComponents") +tasks.named("compileKotlin").configure { + dependsOn(":compiler:fir:checkers:generateCheckersComponents") +} if (kotlinBuildProperties.isInJpsBuildIdeaSync) { apply(plugin = "idea") diff --git a/compiler/fir/checkers/checkers.web.common/build.gradle.kts b/compiler/fir/checkers/checkers.web.common/build.gradle.kts new file mode 100644 index 00000000000..58b2a672870 --- /dev/null +++ b/compiler/fir/checkers/checkers.web.common/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + kotlin("jvm") + id("jps-compatible") +} + +dependencies { + api(project(":compiler:fir:checkers")) + api(project(":core:compiler.common.wasm")) + + /* + * We can't remove this dependency until we use + * diagnostics framework from FE 1.0 + */ + implementation(project(":compiler:frontend")) + implementation(project(":compiler:psi")) + + compileOnly(intellijCore()) +} + +sourceSets { + "main" { + projectDefault() + generatedDir() + } + "test" { none() } +} diff --git a/compiler/fir/checkers/checkers.web.common/src/org/jetbrains/kotlin/fir/declarations/utils/FirWebCommonHelpers.kt b/compiler/fir/checkers/checkers.web.common/src/org/jetbrains/kotlin/fir/declarations/utils/FirWebCommonHelpers.kt new file mode 100644 index 00000000000..f03756f3bb4 --- /dev/null +++ b/compiler/fir/checkers/checkers.web.common/src/org/jetbrains/kotlin/fir/declarations/utils/FirWebCommonHelpers.kt @@ -0,0 +1,42 @@ +/* + * 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. + */ + +@file:OptIn(SymbolInternals::class) + +package org.jetbrains.kotlin.fir.declarations.utils + +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol +import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.SymbolInternals +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol + +private val FirBasedSymbol<*>.isExternal + get() = when (this) { + is FirCallableSymbol<*> -> isExternal + is FirClassSymbol<*> -> isExternal + else -> false + } + +fun FirBasedSymbol<*>.isEffectivelyExternal(session: FirSession): Boolean { + if (fir is FirMemberDeclaration && isExternal) return true + + if (this is FirPropertyAccessorSymbol) { + val property = propertySymbol + if (property.isEffectivelyExternal(session)) return true + } + + if (this is FirPropertySymbol) { + if (getterSymbol?.isExternal == true && (!isVar || setterSymbol?.isExternal == true)) { + return true + } + } + + return getContainingClassSymbol(session)?.isEffectivelyExternal(session) == true +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 5e3714cb40a..95d5cb647c0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -301,6 +301,7 @@ include ":compiler:fir", ":compiler:fir:checkers:checkers.js", ":compiler:fir:checkers:checkers.native", ":compiler:fir:checkers:checkers.wasm", + ":compiler:fir:checkers:checkers.web.common", ":compiler:fir:checkers:checkers-component-generator", ":compiler:fir:entrypoint", ":compiler:fir:analysis-tests",