[FIR JS] Implement FirJsExportDeclarationChecker
This commit is contained in:
+22
@@ -4987,6 +4987,28 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirJsErrors.WRONG_EXPORTED_DECLARATION) { firDiagnostic ->
|
||||||
|
WrongExportedDeclarationImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirJsErrors.NON_EXPORTABLE_TYPE) { firDiagnostic ->
|
||||||
|
NonExportableTypeImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b),
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirJsErrors.NON_CONSUMABLE_EXPORTED_IDENTIFIER) { firDiagnostic ->
|
||||||
|
NonConsumableExportedIdentifierImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirJsErrors.DELEGATION_BY_DYNAMIC) { firDiagnostic ->
|
add(FirJsErrors.DELEGATION_BY_DYNAMIC) { firDiagnostic ->
|
||||||
DelegationByDynamicImpl(
|
DelegationByDynamicImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+16
@@ -3466,6 +3466,22 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = NestedJsExport::class
|
override val diagnosticClass get() = NestedJsExport::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class WrongExportedDeclaration : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = WrongExportedDeclaration::class
|
||||||
|
abstract val kind: String
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class NonExportableType : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = NonExportableType::class
|
||||||
|
abstract val kind: String
|
||||||
|
abstract val type: KtType
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class NonConsumableExportedIdentifier : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = NonConsumableExportedIdentifier::class
|
||||||
|
abstract val name: String
|
||||||
|
}
|
||||||
|
|
||||||
abstract class DelegationByDynamic : KtFirDiagnostic<KtElement>() {
|
abstract class DelegationByDynamic : KtFirDiagnostic<KtElement>() {
|
||||||
override val diagnosticClass get() = DelegationByDynamic::class
|
override val diagnosticClass get() = DelegationByDynamic::class
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -4195,6 +4195,25 @@ internal class NestedJsExportImpl(
|
|||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
) : KtFirDiagnostic.NestedJsExport(), KtAbstractFirDiagnostic<KtElement>
|
) : KtFirDiagnostic.NestedJsExport(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class WrongExportedDeclarationImpl(
|
||||||
|
override val kind: String,
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.WrongExportedDeclaration(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class NonExportableTypeImpl(
|
||||||
|
override val kind: String,
|
||||||
|
override val type: KtType,
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.NonExportableType(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class NonConsumableExportedIdentifierImpl(
|
||||||
|
override val name: String,
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.NonConsumableExportedIdentifier(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
internal class DelegationByDynamicImpl(
|
internal class DelegationByDynamicImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
|
|||||||
+10
@@ -98,6 +98,16 @@ object JS_DIAGNOSTICS_LIST : DiagnosticList("FirJsErrors") {
|
|||||||
|
|
||||||
val EXPORT by object : DiagnosticGroup("Export") {
|
val EXPORT by object : DiagnosticGroup("Export") {
|
||||||
val NESTED_JS_EXPORT by error<KtElement>()
|
val NESTED_JS_EXPORT by error<KtElement>()
|
||||||
|
val WRONG_EXPORTED_DECLARATION by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
|
parameter<String>("kind")
|
||||||
|
}
|
||||||
|
val NON_EXPORTABLE_TYPE by warning<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
|
parameter<String>("kind")
|
||||||
|
parameter<ConeKotlinType>("type")
|
||||||
|
}
|
||||||
|
val NON_CONSUMABLE_EXPORTED_IDENTIFIER by warning<KtElement>(PositioningStrategy.DEFAULT) {
|
||||||
|
parameter<String>("name")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
val DYNAMICS by object : DiagnosticGroup("Dynamics") {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":core:compiler.common.js"))
|
api(project(":core:compiler.common.js"))
|
||||||
|
api(project(":js:js.ast"))
|
||||||
api(project(":compiler:fir:checkers"))
|
api(project(":compiler:fir:checkers"))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+3
@@ -81,6 +81,9 @@ object FirJsErrors {
|
|||||||
|
|
||||||
// Export
|
// Export
|
||||||
val NESTED_JS_EXPORT by error0<KtElement>()
|
val NESTED_JS_EXPORT by error0<KtElement>()
|
||||||
|
val WRONG_EXPORTED_DECLARATION by error1<KtElement, String>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
val NON_EXPORTABLE_TYPE by warning2<KtElement, String, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
val NON_CONSUMABLE_EXPORTED_IDENTIFIER by warning1<KtElement, String>()
|
||||||
|
|
||||||
// Dynamics
|
// Dynamics
|
||||||
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
|
val DELEGATION_BY_DYNAMIC by error0<KtElement>()
|
||||||
|
|||||||
+15
@@ -46,6 +46,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_CLASS
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_JS_EXPORT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NESTED_JS_EXPORT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NON_ABSTRACT_MEMBER_OF_EXTERNAL_INTERFACE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NON_CONSUMABLE_EXPORTED_IDENTIFIER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NON_EXPORTABLE_TYPE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.NON_EXTERNAL_DECLARATION_IN_INAPPROPRIATE_FILE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.OVERRIDING_EXTERNAL_FUN_WITH_OPTIONAL_PARAMS_WITH_FAKE
|
||||||
@@ -54,6 +56,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.RUNTIME_ANNO
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.UNCHECKED_CAST_TO_EXTERNAL_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_BODY_OF_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_EXPORTED_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors.WRONG_JS_QUALIFIER
|
||||||
@@ -169,6 +172,18 @@ object FirJsErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
)
|
)
|
||||||
map.put(EXTERNAL_INTERFACE_AS_CLASS_LITERAL, "Can't refer to external interface from class literal")
|
map.put(EXTERNAL_INTERFACE_AS_CLASS_LITERAL, "Can't refer to external interface from class literal")
|
||||||
map.put(NESTED_JS_EXPORT, "@JsExport is only allowed on files and top-level declarations")
|
map.put(NESTED_JS_EXPORT, "@JsExport is only allowed on files and top-level declarations")
|
||||||
|
map.put(WRONG_EXPORTED_DECLARATION, "Declaration of such kind ({0}) can''t be exported to JS", CommonRenderers.STRING)
|
||||||
|
map.put(
|
||||||
|
NON_EXPORTABLE_TYPE,
|
||||||
|
"Exported declaration uses non-exportable {0} type: {1}",
|
||||||
|
CommonRenderers.STRING,
|
||||||
|
FirDiagnosticRenderers.RENDER_TYPE,
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
NON_CONSUMABLE_EXPORTED_IDENTIFIER,
|
||||||
|
"Exported declaration contains non-consumable identifier '${0}', that can't be represented inside TS definitions and ESM",
|
||||||
|
CommonRenderers.STRING,
|
||||||
|
)
|
||||||
|
|
||||||
map.checkMissingMessages(FirJsErrors)
|
map.checkMissingMessages(FirJsErrors)
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-6
@@ -8,22 +8,22 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.js.checkers
|
package org.jetbrains.kotlin.fir.analysis.js.checkers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.directOverriddenFunctions
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationStringParameter
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.hasAnnotationOrInsideAnnotatedClass
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
import org.jetbrains.kotlin.fir.declarations.utils.isExternal
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
|
||||||
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
import org.jetbrains.kotlin.js.PredefinedAnnotation
|
||||||
|
import org.jetbrains.kotlin.js.common.isES5IdentifierPart
|
||||||
|
import org.jetbrains.kotlin.js.common.isES5IdentifierStart
|
||||||
import org.jetbrains.kotlin.name.JsStandardClassIds
|
import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||||
|
|
||||||
private val FirBasedSymbol<*>.isExternal
|
private val FirBasedSymbol<*>.isExternal
|
||||||
@@ -72,6 +72,13 @@ fun FirBasedSymbol<*>.getJsName(session: FirSession): String? {
|
|||||||
return getAnnotationStringParameter(JsStandardClassIds.Annotations.JsName, session)
|
return getAnnotationStringParameter(JsStandardClassIds.Annotations.JsName, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun sanitizeName(name: String): String {
|
||||||
|
if (name.isEmpty()) return "_"
|
||||||
|
|
||||||
|
val first = name.first().let { if (it.isES5IdentifierStart()) it else '_' }
|
||||||
|
return first.toString() + name.drop(1).map { if (it.isES5IdentifierPart()) it else '_' }.joinToString("")
|
||||||
|
}
|
||||||
|
|
||||||
fun FirBasedSymbol<*>.isNativeObject(session: FirSession): Boolean {
|
fun FirBasedSymbol<*>.isNativeObject(session: FirSession): Boolean {
|
||||||
if (hasAnnotationOrInsideAnnotatedClass(JsStandardClassIds.Annotations.JsNative, session) || isEffectivelyExternal(session)) {
|
if (hasAnnotationOrInsideAnnotatedClass(JsStandardClassIds.Annotations.JsNative, session) || isEffectivelyExternal(session)) {
|
||||||
return true
|
return true
|
||||||
@@ -109,8 +116,35 @@ fun FirBasedSymbol<*>.isPredefinedObject(session: FirSession): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirBasedSymbol<*>.isExportedObject(session: FirSession): Boolean {
|
||||||
|
val declaration = fir
|
||||||
|
|
||||||
|
if (declaration is FirMemberDeclaration) {
|
||||||
|
val visibility = declaration.visibility
|
||||||
|
if (visibility != Visibilities.Public && visibility != Visibilities.Protected) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return when {
|
||||||
|
hasAnnotationOrInsideAnnotatedClass(JsStandardClassIds.Annotations.JsExportIgnore, session) -> false
|
||||||
|
hasAnnotationOrInsideAnnotatedClass(JsStandardClassIds.Annotations.JsExport, session) -> true
|
||||||
|
else -> getContainingFile(session)?.hasAnnotation(JsStandardClassIds.Annotations.JsExport, session) == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirBasedSymbol<*>.getContainingFile(session: FirSession): FirFile? {
|
||||||
|
return when (this) {
|
||||||
|
is FirCallableSymbol<*> -> session.firProvider.getFirCallableContainerFile(this)
|
||||||
|
is FirClassLikeSymbol<*> -> session.firProvider.getFirClassifierContainerFileIfAny(this)
|
||||||
|
else -> return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun FirBasedSymbol<*>.isNativeObject(context: CheckerContext) = isNativeObject(context.session)
|
fun FirBasedSymbol<*>.isNativeObject(context: CheckerContext) = isNativeObject(context.session)
|
||||||
|
|
||||||
fun FirBasedSymbol<*>.isNativeInterface(context: CheckerContext) = isNativeInterface(context.session)
|
fun FirBasedSymbol<*>.isNativeInterface(context: CheckerContext) = isNativeInterface(context.session)
|
||||||
|
|
||||||
fun FirBasedSymbol<*>.isPredefinedObject(context: CheckerContext) = isPredefinedObject(context.session)
|
fun FirBasedSymbol<*>.isPredefinedObject(context: CheckerContext) = isPredefinedObject(context.session)
|
||||||
|
|
||||||
|
fun FirBasedSymbol<*>.isExportedObject(context: CheckerContext) = isExportedObject(context.session)
|
||||||
|
|||||||
+1
@@ -28,6 +28,7 @@ object JsDeclarationCheckers : DeclarationCheckers() {
|
|||||||
FirJsExternalFileChecker,
|
FirJsExternalFileChecker,
|
||||||
FirJsNameChecker,
|
FirJsNameChecker,
|
||||||
FirJsExportAnnotationChecker,
|
FirJsExportAnnotationChecker,
|
||||||
|
FirJsExportDeclarationChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val classCheckers: Set<FirClassChecker>
|
override val classCheckers: Set<FirClassChecker>
|
||||||
|
|||||||
+224
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* 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.fir.analysis.js.checkers.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationFirstArgument
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.isTopLevel
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.js.FirJsErrors
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.isExportedObject
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.js.checkers.sanitizeName
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.js.common.RESERVED_KEYWORDS
|
||||||
|
import org.jetbrains.kotlin.js.common.SPECIAL_KEYWORDS
|
||||||
|
import org.jetbrains.kotlin.name.JsStandardClassIds
|
||||||
|
|
||||||
|
object FirJsExportDeclarationChecker : FirBasicDeclarationChecker() {
|
||||||
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (!declaration.symbol.isExportedObject(context) || declaration !is FirMemberDeclaration) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkTypeParameter(typeParameter: FirTypeParameterRef) {
|
||||||
|
for (upperBound in typeParameter.symbol.resolvedBounds) {
|
||||||
|
if (!upperBound.type.isExportable(context.session)) {
|
||||||
|
reporter.reportOn(typeParameter.source, FirJsErrors.NON_EXPORTABLE_TYPE, "upper bound", upperBound.type, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkValueParameter(valueParameter: FirValueParameter) {
|
||||||
|
val type = valueParameter.returnTypeRef.coneType
|
||||||
|
if (!type.isExportable(context.session)) {
|
||||||
|
reporter.reportOn(valueParameter.source, FirJsErrors.NON_EXPORTABLE_TYPE, "parameter", type, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val hasJsName = declaration.hasAnnotation(JsStandardClassIds.Annotations.JsName, context.session)
|
||||||
|
|
||||||
|
fun reportWrongExportedDeclaration(kind: String) {
|
||||||
|
reporter.reportOn(declaration.source, FirJsErrors.WRONG_EXPORTED_DECLARATION, kind, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration.isExpect) {
|
||||||
|
reportWrongExportedDeclaration("expect")
|
||||||
|
}
|
||||||
|
|
||||||
|
validateDeclarationOnConsumableName(declaration, context, reporter)
|
||||||
|
|
||||||
|
when (declaration) {
|
||||||
|
is FirFunction -> {
|
||||||
|
for (typeParameter in declaration.typeParameters) {
|
||||||
|
checkTypeParameter(typeParameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration.isInlineWithReified) {
|
||||||
|
reportWrongExportedDeclaration("inline function with reified type parameters")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration.isSuspend) {
|
||||||
|
reportWrongExportedDeclaration("suspend function")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration is FirConstructor && !declaration.isPrimary && !hasJsName) {
|
||||||
|
reportWrongExportedDeclaration("secondary constructor without @JsName")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Properties are checked instead of property accessors
|
||||||
|
if (declaration is FirPropertyAccessor) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (parameter in declaration.valueParameters) {
|
||||||
|
checkValueParameter(parameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnType = declaration.returnTypeRef.coneType
|
||||||
|
|
||||||
|
if (!returnType.isExportable(context.session)) {
|
||||||
|
reporter.reportOn(declaration.source, FirJsErrors.NON_EXPORTABLE_TYPE, "return type", returnType, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is FirProperty -> {
|
||||||
|
if (declaration.source?.kind == KtFakeSourceElementKind.PropertyFromParameter) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration.isExtension) {
|
||||||
|
reportWrongExportedDeclaration("extension property")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnType = declaration.returnTypeRef.coneType
|
||||||
|
|
||||||
|
if (!returnType.isExportable(context.session)) {
|
||||||
|
reporter.reportOn(declaration.source, FirJsErrors.NON_EXPORTABLE_TYPE, "return type", returnType, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is FirClass -> {
|
||||||
|
for (typeParameter in declaration.typeParameters) {
|
||||||
|
checkTypeParameter(typeParameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
val wrongDeclaration: String? = when (declaration.classKind) {
|
||||||
|
ClassKind.ANNOTATION_CLASS -> "annotation class"
|
||||||
|
ClassKind.CLASS -> when {
|
||||||
|
context.isInsideInterface -> "nested class inside exported interface"
|
||||||
|
declaration.isInline -> "value class"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
else -> if (context.isInsideInterface) {
|
||||||
|
"${if (declaration.status.isCompanion) "companion object" else "nested/inner declaration"} inside exported interface"
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrongDeclaration != null) {
|
||||||
|
reportWrongExportedDeclaration(wrongDeclaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val CheckerContext.isInsideInterface
|
||||||
|
get(): Boolean {
|
||||||
|
val parent = containingDeclarations.lastOrNull() as? FirClass
|
||||||
|
return parent != null && parent.isInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
private val FirCallableDeclaration.isInlineWithReified: Boolean
|
||||||
|
get() = when (this) {
|
||||||
|
is FirPropertyAccessor -> {
|
||||||
|
@OptIn(SymbolInternals::class)
|
||||||
|
this.propertySymbol.fir.isInlineWithReified
|
||||||
|
}
|
||||||
|
else -> typeParameters.any { it.symbol.isReified }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeKotlinType.isExportableReturn(session: FirSession, currentlyProcessed: MutableSet<ConeKotlinType> = mutableSetOf()) =
|
||||||
|
isUnit || isExportable(session, currentlyProcessed)
|
||||||
|
|
||||||
|
private fun ConeKotlinType.isExportable(
|
||||||
|
session: FirSession,
|
||||||
|
currentlyProcessed: MutableSet<ConeKotlinType> = mutableSetOf(),
|
||||||
|
): Boolean {
|
||||||
|
if (!currentlyProcessed.add(this)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
currentlyProcessed.add(this)
|
||||||
|
val hasNonExportableArgument = typeArguments.any { it.type?.isExportable(session, currentlyProcessed) != true }
|
||||||
|
|
||||||
|
if (hasNonExportableArgument) {
|
||||||
|
currentlyProcessed.remove(this)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
currentlyProcessed.remove(this)
|
||||||
|
|
||||||
|
if (isBasicFunctionType(session)) {
|
||||||
|
typeArguments.lastOrNull()?.type?.isExportableReturn(session, currentlyProcessed)
|
||||||
|
}
|
||||||
|
|
||||||
|
val nonNullable = withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||||
|
val isPrimitiveExportableType = nonNullable.isAny || nonNullable.isNullableAny
|
||||||
|
|| nonNullable is ConeDynamicType || isPrimitiveExportableConeKotlinType
|
||||||
|
val symbol = toSymbol(session)
|
||||||
|
|
||||||
|
return when {
|
||||||
|
isPrimitiveExportableType -> true
|
||||||
|
@OptIn(SymbolInternals::class)
|
||||||
|
symbol?.fir is FirMemberDeclaration -> false
|
||||||
|
isEnum -> true
|
||||||
|
else -> symbol?.isEffectivelyExternal(session) == true || symbol?.isExportedObject(session) == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ConeKotlinType.isPrimitiveExportableConeKotlinType: Boolean
|
||||||
|
get() = this is ConeTypeParameterType
|
||||||
|
|| isBoolean
|
||||||
|
|| isThrowableOrNullableThrowable
|
||||||
|
|| isString
|
||||||
|
|| isPrimitiveNumberOrNullableType && !isLong
|
||||||
|
|| isNothingOrNullableNothing
|
||||||
|
|| isArrayType
|
||||||
|
|
||||||
|
private fun validateDeclarationOnConsumableName(
|
||||||
|
declaration: FirMemberDeclaration,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter,
|
||||||
|
) {
|
||||||
|
if (!context.isTopLevel || declaration.nameOrSpecialName.isSpecial) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val jsNameArgument = declaration.symbol.getAnnotationFirstArgument(JsStandardClassIds.Annotations.JsName, context.session)
|
||||||
|
val reportTarget = jsNameArgument?.source ?: declaration.source
|
||||||
|
val name = (jsNameArgument as? FirConstExpression<*>)?.value as? String ?: declaration.nameOrSpecialName.asString()
|
||||||
|
|
||||||
|
if (name in SPECIAL_KEYWORDS || (name !in RESERVED_KEYWORDS && sanitizeName(name) == name)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reporter.reportOn(reportTarget, FirJsErrors.NON_CONSUMABLE_EXPORTED_IDENTIFIER, name, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -736,9 +736,13 @@ fun FirBasedSymbol<*>.hasAnnotationOrInsideAnnotatedClass(classId: ClassId, sess
|
|||||||
fun FirDeclaration.hasAnnotationOrInsideAnnotatedClass(classId: ClassId, session: FirSession) =
|
fun FirDeclaration.hasAnnotationOrInsideAnnotatedClass(classId: ClassId, session: FirSession) =
|
||||||
symbol.hasAnnotationOrInsideAnnotatedClass(classId, session)
|
symbol.hasAnnotationOrInsideAnnotatedClass(classId, session)
|
||||||
|
|
||||||
fun FirBasedSymbol<*>.getAnnotationStringParameter(classId: ClassId, session: FirSession): String? {
|
fun FirBasedSymbol<*>.getAnnotationFirstArgument(classId: ClassId, session: FirSession): FirExpression? {
|
||||||
val annotation = getAnnotationByClassId(classId, session) as? FirAnnotationCall
|
val annotation = getAnnotationByClassId(classId, session) as? FirAnnotationCall
|
||||||
val expression = annotation?.argumentMapping?.mapping?.values?.firstOrNull() as? FirConstExpression<*>
|
return annotation?.argumentMapping?.mapping?.values?.firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun FirBasedSymbol<*>.getAnnotationStringParameter(classId: ClassId, session: FirSession): String? {
|
||||||
|
val expression = getAnnotationFirstArgument(classId, session) as? FirConstExpression<*>
|
||||||
return expression?.value as? String
|
return expression?.value as? String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,10 @@ val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boo
|
|||||||
val ConeKotlinType.isNullableBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, true)
|
val ConeKotlinType.isNullableBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, true)
|
||||||
val ConeKotlinType.isBooleanOrNullableBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, null)
|
val ConeKotlinType.isBooleanOrNullableBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, null)
|
||||||
|
|
||||||
|
val ConeKotlinType.isThrowableOrNullableThrowable: Boolean get() = isAnyOfBuiltinType(setOf(StandardClassIds.Throwable))
|
||||||
|
|
||||||
val ConeKotlinType.isChar: Boolean get() = isBuiltinType(StandardClassIds.Char, false)
|
val ConeKotlinType.isChar: Boolean get() = isBuiltinType(StandardClassIds.Char, false)
|
||||||
|
val ConeKotlinType.isCharOrNullableChar: Boolean get() = isAnyOfBuiltinType(setOf(StandardClassIds.Char))
|
||||||
val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false)
|
val ConeKotlinType.isString: Boolean get() = isBuiltinType(StandardClassIds.String, false)
|
||||||
|
|
||||||
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
|
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
|
||||||
@@ -37,6 +40,8 @@ val ConeKotlinType.isUInt: Boolean get() = isBuiltinType(StandardClassIds.UInt,
|
|||||||
val ConeKotlinType.isULong: Boolean get() = isBuiltinType(StandardClassIds.ULong, false)
|
val ConeKotlinType.isULong: Boolean get() = isBuiltinType(StandardClassIds.ULong, false)
|
||||||
val ConeKotlinType.isPrimitiveOrNullablePrimitive: Boolean get() = isAnyOfBuiltinType(StandardClassIds.primitiveTypes)
|
val ConeKotlinType.isPrimitiveOrNullablePrimitive: Boolean get() = isAnyOfBuiltinType(StandardClassIds.primitiveTypes)
|
||||||
val ConeKotlinType.isPrimitive: Boolean get() = isPrimitiveOrNullablePrimitive && nullability == ConeNullability.NOT_NULL
|
val ConeKotlinType.isPrimitive: Boolean get() = isPrimitiveOrNullablePrimitive && nullability == ConeNullability.NOT_NULL
|
||||||
|
val ConeKotlinType.isPrimitiveNumberOrNullableType: Boolean
|
||||||
|
get() = isPrimitiveOrNullablePrimitive && !isBooleanOrNullableBoolean && !isCharOrNullableChar
|
||||||
val ConeKotlinType.isArrayType: Boolean
|
val ConeKotlinType.isArrayType: Boolean
|
||||||
get() {
|
get() {
|
||||||
return isBuiltinType(StandardClassIds.Array, false) ||
|
return isBuiltinType(StandardClassIds.Array, false) ||
|
||||||
|
|||||||
@@ -540,15 +540,6 @@ fun FirBasedSymbol<*>.getOwnerLookupTag(): ConeClassLikeLookupTag? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirClassLikeSymbol<*>.getContainingClassLookupTag(): ConeClassLikeLookupTag? {
|
|
||||||
return if (classId.isLocal) {
|
|
||||||
(fir as? FirRegularClass)?.containingClassForLocal()
|
|
||||||
} else {
|
|
||||||
val ownerId = classId.outerClassId
|
|
||||||
ownerId?.let { it.toLookupTag() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FirBasedSymbol<*>.isVariableOrNamedFunction(): Boolean {
|
fun FirBasedSymbol<*>.isVariableOrNamedFunction(): Boolean {
|
||||||
return this is FirVariableSymbol || this is FirNamedFunctionSymbol || this is FirPropertyAccessorSymbol
|
return this is FirVariableSymbol || this is FirNamedFunctionSymbol || this is FirPropertyAccessorSymbol
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -233,7 +233,10 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
fun constructorTypeParametersFromConstructedClass(ownerTypeParameters: List<FirTypeParameterRef>): List<FirTypeParameterRef> {
|
fun constructorTypeParametersFromConstructedClass(ownerTypeParameters: List<FirTypeParameterRef>): List<FirTypeParameterRef> {
|
||||||
return ownerTypeParameters.mapNotNull {
|
return ownerTypeParameters.mapNotNull {
|
||||||
val declaredTypeParameter = (it as? FirTypeParameter) ?: return@mapNotNull null
|
val declaredTypeParameter = (it as? FirTypeParameter) ?: return@mapNotNull null
|
||||||
buildConstructedClassTypeParameterRef { symbol = declaredTypeParameter.symbol }
|
buildConstructedClassTypeParameterRef {
|
||||||
|
source = declaredTypeParameter.symbol.source?.fakeElement(KtFakeSourceElementKind.ConstructorTypeParameter)
|
||||||
|
symbol = declaredTypeParameter.symbol
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.PrivateForInline
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
|
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildOuterClassTypeParameterRef
|
import org.jetbrains.kotlin.fir.declarations.builder.buildOuterClassTypeParameterRef
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFileSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
@@ -48,6 +49,7 @@ class Context<T> {
|
|||||||
var forcedElementSourceKind: KtSourceElementKind? = null
|
var forcedElementSourceKind: KtSourceElementKind? = null
|
||||||
val dispatchReceiverTypesStack = mutableListOf<ConeClassLikeType>()
|
val dispatchReceiverTypesStack = mutableListOf<ConeClassLikeType>()
|
||||||
var containerIsExpect: Boolean = false
|
var containerIsExpect: Boolean = false
|
||||||
|
var containingFileSymbol: FirFileSymbol? = null
|
||||||
|
|
||||||
fun pushFirTypeParameters(isInnerOrLocal: Boolean, parameters: List<FirTypeParameterRef>) {
|
fun pushFirTypeParameters(isInnerOrLocal: Boolean, parameters: List<FirTypeParameterRef>) {
|
||||||
capturedTypeParameters.add(StatusFirTypeParameterSymbolList(isInnerOrLocal, parameters.map { it.symbol }))
|
capturedTypeParameters.add(StatusFirTypeParameterSymbolList(isInnerOrLocal, parameters.map { it.symbol }))
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
|||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeIntersectionType
|
import org.jetbrains.kotlin.fir.types.ConeIntersectionType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.toLookupTag
|
||||||
|
|
||||||
fun FirCallableSymbol<*>.dispatchReceiverClassTypeOrNull(): ConeClassLikeType? =
|
fun FirCallableSymbol<*>.dispatchReceiverClassTypeOrNull(): ConeClassLikeType? =
|
||||||
fir.dispatchReceiverClassTypeOrNull()
|
fir.dispatchReceiverClassTypeOrNull()
|
||||||
@@ -41,6 +43,15 @@ fun FirRegularClass.containingClassForLocal(): ConeClassLikeLookupTag? =
|
|||||||
fun FirDanglingModifierList.containingClass(): ConeClassLikeLookupTag? =
|
fun FirDanglingModifierList.containingClass(): ConeClassLikeLookupTag? =
|
||||||
containingClassAttr
|
containingClassAttr
|
||||||
|
|
||||||
|
fun FirClassLikeSymbol<*>.getContainingClassLookupTag(): ConeClassLikeLookupTag? {
|
||||||
|
return if (classId.isLocal) {
|
||||||
|
(fir as? FirRegularClass)?.containingClassForLocal()
|
||||||
|
} else {
|
||||||
|
val ownerId = classId.outerClassId
|
||||||
|
ownerId?.toLookupTag()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private object ContainingClassKey : FirDeclarationDataKey()
|
private object ContainingClassKey : FirDeclarationDataKey()
|
||||||
var FirCallableDeclaration.containingClassForStaticMemberAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
|
var FirCallableDeclaration.containingClassForStaticMemberAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
|
||||||
var FirRegularClass.containingClassForLocalAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
|
var FirRegularClass.containingClassForLocalAttr: ConeClassLikeLookupTag? by FirDeclarationDataRegistry.data(ContainingClassKey)
|
||||||
|
|||||||
+2
-12
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.fir.declarations.comparators
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
import org.jetbrains.kotlin.fir.declarations.utils.classId
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRefComparator
|
import org.jetbrains.kotlin.fir.types.FirTypeRefComparator
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
|
|
||||||
object FirMemberDeclarationComparator : Comparator<FirMemberDeclaration> {
|
object FirMemberDeclarationComparator : Comparator<FirMemberDeclaration> {
|
||||||
// Comparing different kinds of callable members by assigning distinct priorities to those members.
|
// Comparing different kinds of callable members by assigning distinct priorities to those members.
|
||||||
@@ -28,16 +28,6 @@ object FirMemberDeclarationComparator : Comparator<FirMemberDeclaration> {
|
|||||||
is FirBackingField -> 0
|
is FirBackingField -> 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirMemberDeclaration.name: Name
|
|
||||||
get() = when (this) {
|
|
||||||
is FirCallableDeclaration ->
|
|
||||||
this.symbol.callableId.callableName
|
|
||||||
is FirClass ->
|
|
||||||
this.classId.shortClassName
|
|
||||||
is FirTypeAlias ->
|
|
||||||
this.name
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun compare(a: FirMemberDeclaration, b: FirMemberDeclaration): Int {
|
override fun compare(a: FirMemberDeclaration, b: FirMemberDeclaration): Int {
|
||||||
val priorityDiff = a.priority - b.priority
|
val priorityDiff = a.priority - b.priority
|
||||||
if (priorityDiff != 0) {
|
if (priorityDiff != 0) {
|
||||||
@@ -51,7 +41,7 @@ object FirMemberDeclarationComparator : Comparator<FirMemberDeclaration> {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.name.compareTo(b.name)
|
return a.nameOrSpecialName.compareTo(b.nameOrSpecialName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
val FirTypeAlias.expandedConeType: ConeClassLikeType? get() = expandedTypeRef.coneTypeSafe()
|
val FirTypeAlias.expandedConeType: ConeClassLikeType? get() = expandedTypeRef.coneTypeSafe()
|
||||||
|
|
||||||
@@ -45,3 +46,13 @@ val FirDeclaration.isNonLocal
|
|||||||
}
|
}
|
||||||
|
|
||||||
val FirCallableDeclaration.isExtension get() = receiverParameter != null
|
val FirCallableDeclaration.isExtension get() = receiverParameter != null
|
||||||
|
|
||||||
|
val FirMemberDeclaration.nameOrSpecialName: Name
|
||||||
|
get() = when (this) {
|
||||||
|
is FirCallableDeclaration ->
|
||||||
|
this.symbol.callableId.callableName
|
||||||
|
is FirClass ->
|
||||||
|
this.classId.shortClassName
|
||||||
|
is FirTypeAlias ->
|
||||||
|
this.name
|
||||||
|
}
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor
|
|||||||
// with a fake source which refers to containing class
|
// with a fake source which refers to containing class
|
||||||
object ImplicitConstructor : KtFakeSourceElementKind()
|
object ImplicitConstructor : KtFakeSourceElementKind()
|
||||||
|
|
||||||
|
// for constructor type parameters, because they refer to the same source
|
||||||
|
// as the class type parameters themselves
|
||||||
|
object ConstructorTypeParameter : KtFakeSourceElementKind()
|
||||||
|
|
||||||
// for constructors which do not have delegated constructor call the fake one is generated
|
// for constructors which do not have delegated constructor call the fake one is generated
|
||||||
// with a fake sources which refers to the original constructor
|
// with a fake sources which refers to the original constructor
|
||||||
object DelegatingConstructorCall : KtFakeSourceElementKind()
|
object DelegatingConstructorCall : KtFakeSourceElementKind()
|
||||||
|
|||||||
+4
-4
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
fun f1(x: String) {}
|
fun f1(x: String) {}
|
||||||
fun f2(f: () -> Unit) {}
|
fun f2(f: () -> Unit) {}
|
||||||
fun test1() = <!INAPPLICABLE_CANDIDATE!>f2<!>(::<!UNRESOLVED_REFERENCE!>f1<!>)
|
fun test1() = <!INAPPLICABLE_CANDIDATE("fun f2(f: () -> Unit): Unit")!>f2<!>(::<!UNRESOLVED_REFERENCE("f1")!>f1<!>)
|
||||||
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE)
|
@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE)
|
||||||
@@ -12,14 +12,14 @@ annotation class Ann
|
|||||||
fun <@Ann R : @Ann Any> f3(a: Array<@Ann R>): Array<@Ann R?> = null!!
|
fun <@Ann R : @Ann Any> f3(a: Array<@Ann R>): Array<@Ann R?> = null!!
|
||||||
|
|
||||||
fun test2(a: @Ann Array<in @Ann Int>) {
|
fun test2(a: @Ann Array<in @Ann Int>) {
|
||||||
val r: Array<in Int?> = f3(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
val r: Array<in Int?> = f3(<!ARGUMENT_TYPE_MISMATCH("kotlin/Array<@R|Ann|() R>; @R|Ann|() kotlin/Array<in @R|Ann|() kotlin/Int>")!>a<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var test3: Int = 0
|
var test3: Int = 0
|
||||||
set(s: <!WRONG_SETTER_PARAMETER_TYPE!>@Ann String<!>) {}
|
set(s: <!WRONG_SETTER_PARAMETER_TYPE("kotlin/Int; @R|Ann|() kotlin/String")!>@Ann String<!>) {}
|
||||||
|
|
||||||
|
|
||||||
fun f4(fn: (@Ann Int, @Ann Int) -> Unit) {}
|
fun f4(fn: (@Ann Int, @Ann Int) -> Unit) {}
|
||||||
|
|
||||||
val test4 = f4 <!ARGUMENT_TYPE_MISMATCH!>{ single -> }<!>
|
val test4 = f4 <!ARGUMENT_TYPE_MISMATCH("kotlin/Function2<@R|Ann|() kotlin/Int, @R|Ann|() kotlin/Int, kotlin/Unit>; kotlin/Function1<@R|Ann|() kotlin/Int, kotlin/Unit>")!>{ single -> }<!>
|
||||||
|
|||||||
Vendored
+1
-1
@@ -11,5 +11,5 @@ open class B1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class D1 : B1() {
|
class D1 : B1() {
|
||||||
<!NOTHING_TO_OVERRIDE!>override<!> fun foo() {}
|
<!NOTHING_TO_OVERRIDE("foo")!>override<!> fun foo() {}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -11,5 +11,5 @@ class C<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(a: C<out CharSequence>) {
|
fun test(a: C<out CharSequence>) {
|
||||||
a[1] = <!ARGUMENT_TYPE_MISMATCH!>25<!>
|
a[1] = <!ARGUMENT_TYPE_MISMATCH("@R|A|() CapturedType(out kotlin/CharSequence); kotlin/Int")!>25<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -15,7 +15,7 @@ interface B {
|
|||||||
fun <T> a(@An arg: @An Int)
|
fun <T> a(@An arg: @An Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!CONFLICTING_INHERITED_MEMBERS!>interface C<!> : A, B
|
<!CONFLICTING_INHERITED_MEMBERS("C; a, a")!>interface C<!> : A, B
|
||||||
|
|
||||||
@An
|
@An
|
||||||
abstract class D {
|
abstract class D {
|
||||||
@@ -23,8 +23,8 @@ abstract class D {
|
|||||||
abstract val d: @An Int
|
abstract val d: @An Int
|
||||||
}
|
}
|
||||||
|
|
||||||
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class E<!> : D(), A
|
<!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED("Class E; d")!>class E<!> : D(), A
|
||||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class F<!> : A
|
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED("Class F; a")!>class F<!> : A
|
||||||
|
|
||||||
@An
|
@An
|
||||||
interface G {
|
interface G {
|
||||||
@@ -44,5 +44,5 @@ interface GI : G {
|
|||||||
override fun a(@An arg: @An Int) {}
|
override fun a(@An arg: @An Int) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class AG1<!>(val a: A, val g: G) : A by a, G by g
|
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED("Class AG1; a")!>class AG1<!>(val a: A, val g: G) : A by a, G by g
|
||||||
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED!>class AG2<!>() : AI, GI
|
<!MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED("Class AG2; a")!>class AG2<!>() : AI, GI
|
||||||
|
|||||||
+1
-1
@@ -7,5 +7,5 @@ annotation class Ann(val s: String = "")
|
|||||||
fun foo() {}
|
fun foo() {}
|
||||||
|
|
||||||
val bar = foo(
|
val bar = foo(
|
||||||
<!TOO_MANY_ARGUMENTS!>15<!>
|
<!TOO_MANY_ARGUMENTS("public final fun /foo(): R|kotlin/Unit|")!>15<!>
|
||||||
)
|
)
|
||||||
|
|||||||
Vendored
+1
-1
@@ -13,5 +13,5 @@ class C<T> {
|
|||||||
class Out<out F>
|
class Out<out F>
|
||||||
|
|
||||||
fun test(a: C<out CharSequence>, y: Out<CharSequence>) {
|
fun test(a: C<out CharSequence>, y: Out<CharSequence>) {
|
||||||
a + <!ARGUMENT_TYPE_MISMATCH!>y<!>
|
a + <!ARGUMENT_TYPE_MISMATCH("Out<@R|A|() CapturedType(out kotlin/CharSequence)>; Out<kotlin/CharSequence>")!>y<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -15,12 +15,12 @@ interface A {
|
|||||||
|
|
||||||
@An
|
@An
|
||||||
interface B : A {
|
interface B : A {
|
||||||
override val p1: <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>Int<!>
|
override val p1: <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE("p1; @An() val p1: @R|An|() String")!>Int<!>
|
||||||
@An
|
@An
|
||||||
override <!VAR_OVERRIDDEN_BY_VAL!>val<!> p2: @An String
|
override <!VAR_OVERRIDDEN_BY_VAL("public abstract override val /B.p2: R|@R|An|() kotlin/String| public get(): R|@R|An|() kotlin/String|; public abstract var /A.p2: R|@R|An|() kotlin/String| public get(): R|@R|An|() kotlin/String| public set(value: R|@R|An|() kotlin/String|): R|kotlin/Unit|")!>val<!> p2: @An String
|
||||||
override fun test(arg: String): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Int<!>
|
override fun test(arg: String): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE("test; @An() fun test(@An() arg: @R|An|() String): @R|An|() String")!>Int<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface C : A {
|
interface C : A {
|
||||||
override var p2: <!VAR_TYPE_MISMATCH_ON_OVERRIDE!>Int<!>
|
override var p2: <!VAR_TYPE_MISMATCH_ON_OVERRIDE("p2; @An() var p2: @R|An|() String")!>Int<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -27,7 +27,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
annotation class An
|
annotation class An
|
||||||
|
|
||||||
class B : A {
|
class B : A {
|
||||||
override fun foo(): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>String?<!> = null
|
override fun foo(): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE("foo; @NotNull() @An() @MyTypeQualifier() fun foo(): @EnhancedNullability String")!>String?<!> = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@An
|
@An
|
||||||
@@ -38,5 +38,5 @@ public interface C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class D : C {
|
class D : C {
|
||||||
override fun foo(): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>String?<!> = null
|
override fun foo(): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE("foo; @NotNull() @An() fun foo(): String")!>String?<!> = null
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-15
@@ -1,15 +0,0 @@
|
|||||||
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
|
||||||
// !RENDER_DIAGNOSTICS_MESSAGES
|
|
||||||
|
|
||||||
package foo
|
|
||||||
|
|
||||||
@JsExport
|
|
||||||
class C(val x: String) {
|
|
||||||
constructor(x: Int): this(x.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsExport
|
|
||||||
class C2(val x: String) {
|
|
||||||
@JsName("JsNameProvided")
|
|
||||||
constructor(x: Int): this(x.toString())
|
|
||||||
}
|
|
||||||
Vendored
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
||||||
// !RENDER_DIAGNOSTICS_MESSAGES
|
// !RENDER_DIAGNOSTICS_MESSAGES
|
||||||
|
|
||||||
|
|||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
|
||||||
// !RENDER_DIAGNOSTICS_MESSAGES
|
|
||||||
@file:JsExport
|
|
||||||
|
|
||||||
package foo
|
|
||||||
|
|
||||||
class C(val x: String) {
|
|
||||||
constructor(x: Int): this(x.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
class C2(val x: String) {
|
|
||||||
@JsName("JsNameProvided")
|
|
||||||
constructor(x: Int): this(x.toString())
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
||||||
// !RENDER_DIAGNOSTICS_MESSAGES
|
// !RENDER_DIAGNOSTICS_MESSAGES
|
||||||
@file:JsExport
|
@file:JsExport
|
||||||
|
|||||||
+13
-13
@@ -4,18 +4,18 @@
|
|||||||
|
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
@JsExport
|
<!WRONG_EXPORTED_DECLARATION("inline function with reified type parameters")!>@JsExport
|
||||||
inline fun <reified T> inlineReifiedFun(x: Any) = x is T
|
inline fun <reified T> inlineReifiedFun(x: Any)<!> = x is T
|
||||||
|
|
||||||
@JsExport
|
<!WRONG_EXPORTED_DECLARATION("suspend function")!>@JsExport
|
||||||
suspend fun suspendFun() { }
|
suspend fun suspendFun()<!> { }
|
||||||
|
|
||||||
@JsExport
|
<!WRONG_EXPORTED_DECLARATION("extension property")!>@JsExport
|
||||||
val String.extensionProperty
|
val String.extensionProperty<!>
|
||||||
get() = this.length
|
get() = this.length
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
annotation class AnnotationClass
|
annotation class <!WRONG_EXPORTED_DECLARATION("annotation class")!>AnnotationClass<!>
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
interface SomeInterface
|
interface SomeInterface
|
||||||
@@ -25,24 +25,24 @@ external interface GoodInterface
|
|||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
interface InterfaceWithCompanion {
|
interface InterfaceWithCompanion {
|
||||||
companion object {
|
companion <!WRONG_EXPORTED_DECLARATION("companion object inside exported interface")!>object<!> {
|
||||||
fun foo() = 42
|
fun foo() = 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
interface OuterInterface {
|
interface OuterInterface {
|
||||||
class Nested
|
class <!WRONG_EXPORTED_DECLARATION("nested class inside exported interface")!>Nested<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
value class A(val a: Int)
|
value class <!WRONG_EXPORTED_DECLARATION("value class")!>A(val a: Int)<!>
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
inline class B(val b: Int)
|
inline class <!WRONG_EXPORTED_DECLARATION("value class")!>B(val b: Int)<!>
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
inline value class C(val c: Int)
|
inline value class <!WRONG_EXPORTED_DECLARATION("value class")!>C(val c: Int)<!>
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
value inline class D(val d: Int)
|
value inline class <!WRONG_EXPORTED_DECLARATION("value class")!>D(val d: Int)<!>
|
||||||
|
|||||||
compiler/testData/diagnostics/testsWithJsStdLib/export/wrongExportedDeclarationInExportedFile.fir.kt
Vendored
-15
@@ -1,15 +0,0 @@
|
|||||||
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
|
||||||
// !RENDER_DIAGNOSTICS_MESSAGES
|
|
||||||
|
|
||||||
@file:JsExport
|
|
||||||
|
|
||||||
package foo
|
|
||||||
|
|
||||||
inline fun <reified T> inlineReifiedFun(x: Any) = x is T
|
|
||||||
|
|
||||||
suspend fun suspendFun() { }
|
|
||||||
|
|
||||||
val String.extensionProperty
|
|
||||||
get() = this.length
|
|
||||||
|
|
||||||
annotation class AnnotationClass
|
|
||||||
Vendored
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
// !OPT_IN: kotlin.js.ExperimentalJsExport
|
||||||
// !RENDER_DIAGNOSTICS_MESSAGES
|
// !RENDER_DIAGNOSTICS_MESSAGES
|
||||||
|
|
||||||
|
|||||||
+4
@@ -43,6 +43,10 @@ object FirDiagnosticsDirectives : SimpleDirectivesContainer() {
|
|||||||
description = "Defines which parser should be used for FIR compiler"
|
description = "Defines which parser should be used for FIR compiler"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val RENDER_DIAGNOSTICS_MESSAGES by directive(
|
||||||
|
description = "Forces diagnostic arguments to be rendered"
|
||||||
|
)
|
||||||
|
|
||||||
val FIR_DISABLE_LAZY_RESOLVE_CHECKS by directive(
|
val FIR_DISABLE_LAZY_RESOLVE_CHECKS by directive(
|
||||||
description = "Temporary disables lazy resolve checks until the lazy resolve contract violation is fixed"
|
description = "Temporary disables lazy resolve checks until the lazy resolve contract violation is fixed"
|
||||||
)
|
)
|
||||||
|
|||||||
+14
-7
@@ -70,6 +70,7 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
|
|
||||||
val lightTreeComparingModeEnabled = FirDiagnosticsDirectives.COMPARE_WITH_LIGHT_TREE in currentModule.directives
|
val lightTreeComparingModeEnabled = FirDiagnosticsDirectives.COMPARE_WITH_LIGHT_TREE in currentModule.directives
|
||||||
val lightTreeEnabled = currentModule.directives.singleValue(FirDiagnosticsDirectives.FIR_PARSER) == FirParser.LightTree
|
val lightTreeEnabled = currentModule.directives.singleValue(FirDiagnosticsDirectives.FIR_PARSER) == FirParser.LightTree
|
||||||
|
val forceRenderArguments = FirDiagnosticsDirectives.RENDER_DIAGNOSTICS_MESSAGES in currentModule.directives
|
||||||
|
|
||||||
for (file in currentModule.files) {
|
for (file in currentModule.files) {
|
||||||
val firFile = info.mainFirFiles[file] ?: continue
|
val firFile = info.mainFirFiles[file] ?: continue
|
||||||
@@ -84,10 +85,11 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
diagnostics.diagnosticCodeMetaInfos(
|
diagnostics.diagnosticCodeMetaInfos(
|
||||||
currentModule, file,
|
currentModule, file,
|
||||||
diagnosticsService, globalMetadataInfoHandler,
|
diagnosticsService, globalMetadataInfoHandler,
|
||||||
lightTreeEnabled, lightTreeComparingModeEnabled
|
lightTreeEnabled, lightTreeComparingModeEnabled,
|
||||||
|
forceRenderArguments,
|
||||||
)
|
)
|
||||||
globalMetadataInfoHandler.addMetadataInfosForFile(file, diagnosticsMetadataInfos)
|
globalMetadataInfoHandler.addMetadataInfosForFile(file, diagnosticsMetadataInfos)
|
||||||
collectSyntaxDiagnostics(currentModule, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
collectSyntaxDiagnostics(currentModule, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled, forceRenderArguments)
|
||||||
collectDebugInfoDiagnostics(currentModule, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
collectDebugInfoDiagnostics(currentModule, file, firFile, lightTreeEnabled, lightTreeComparingModeEnabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,7 +101,8 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
testFile: TestFile,
|
testFile: TestFile,
|
||||||
firFile: FirFile,
|
firFile: FirFile,
|
||||||
lightTreeEnabled: Boolean,
|
lightTreeEnabled: Boolean,
|
||||||
lightTreeComparingModeEnabled: Boolean
|
lightTreeComparingModeEnabled: Boolean,
|
||||||
|
forceRenderArguments: Boolean,
|
||||||
) {
|
) {
|
||||||
val metaInfos = if (firFile.psi != null) {
|
val metaInfos = if (firFile.psi != null) {
|
||||||
AnalyzingUtils.getSyntaxErrorRanges(firFile.psi!!).flatMap {
|
AnalyzingUtils.getSyntaxErrorRanges(firFile.psi!!).flatMap {
|
||||||
@@ -109,7 +112,8 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
testFile,
|
testFile,
|
||||||
globalMetadataInfoHandler1 = globalMetadataInfoHandler,
|
globalMetadataInfoHandler1 = globalMetadataInfoHandler,
|
||||||
lightTreeEnabled,
|
lightTreeEnabled,
|
||||||
lightTreeComparingModeEnabled
|
lightTreeComparingModeEnabled,
|
||||||
|
forceRenderArguments,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -120,7 +124,8 @@ class FirDiagnosticsHandler(testServices: TestServices) : FirAnalysisHandler(tes
|
|||||||
testFile,
|
testFile,
|
||||||
globalMetadataInfoHandler1 = globalMetadataInfoHandler,
|
globalMetadataInfoHandler1 = globalMetadataInfoHandler,
|
||||||
lightTreeEnabled,
|
lightTreeEnabled,
|
||||||
lightTreeComparingModeEnabled
|
lightTreeComparingModeEnabled,
|
||||||
|
forceRenderArguments,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -323,7 +328,8 @@ fun List<KtDiagnostic>.diagnosticCodeMetaInfos(
|
|||||||
diagnosticsService: DiagnosticsService,
|
diagnosticsService: DiagnosticsService,
|
||||||
globalMetadataInfoHandler: GlobalMetadataInfoHandler,
|
globalMetadataInfoHandler: GlobalMetadataInfoHandler,
|
||||||
lightTreeEnabled: Boolean,
|
lightTreeEnabled: Boolean,
|
||||||
lightTreeComparingModeEnabled: Boolean
|
lightTreeComparingModeEnabled: Boolean,
|
||||||
|
forceRenderArguments: Boolean = false,
|
||||||
): List<FirDiagnosticCodeMetaInfo> = flatMap { diagnostic ->
|
): List<FirDiagnosticCodeMetaInfo> = flatMap { diagnostic ->
|
||||||
if (!diagnosticsService.shouldRenderDiagnostic(
|
if (!diagnosticsService.shouldRenderDiagnostic(
|
||||||
module,
|
module,
|
||||||
@@ -339,7 +345,8 @@ fun List<KtDiagnostic>.diagnosticCodeMetaInfos(
|
|||||||
file,
|
file,
|
||||||
globalMetadataInfoHandler,
|
globalMetadataInfoHandler,
|
||||||
lightTreeEnabled,
|
lightTreeEnabled,
|
||||||
lightTreeComparingModeEnabled
|
lightTreeComparingModeEnabled,
|
||||||
|
forceRenderArguments,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ object JsStandardClassIds {
|
|||||||
val JsExport = "JsExport".jsId()
|
val JsExport = "JsExport".jsId()
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val JsExportIgnore = ClassId(JsExport.asSingleFqName(), Name.identifier("Ignore"))
|
val JsExportIgnore = JsExport.createNestedClassId(Name.identifier("Ignore"))
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val annotationsRequiringExternal = setOf(JsModule, JsQualifier)
|
val annotationsRequiringExternal = setOf(JsModule, JsQualifier)
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ interface TypeSystemCommonBackendContext : TypeSystemContext {
|
|||||||
|
|
||||||
fun KotlinTypeMarker.makeNullable(): KotlinTypeMarker =
|
fun KotlinTypeMarker.makeNullable(): KotlinTypeMarker =
|
||||||
asSimpleType()?.withNullability(true) ?: this
|
asSimpleType()?.withNullability(true) ?: this
|
||||||
|
|
||||||
fun TypeConstructorMarker.getPrimitiveType(): PrimitiveType?
|
fun TypeConstructorMarker.getPrimitiveType(): PrimitiveType?
|
||||||
fun TypeConstructorMarker.getPrimitiveArrayType(): PrimitiveType?
|
fun TypeConstructorMarker.getPrimitiveArrayType(): PrimitiveType?
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user