diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt index dc3e1e07c45..7da86750641 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt @@ -46,7 +46,7 @@ object JsPlatformConfigurator : PlatformConfigurator( ReifiedTypeParameterSubstitutionChecker(), JsModuleCallChecker, JsDynamicCallChecker, - JsNoImplCallChecker + JsDefinedExternallyCallChecker ), additionalTypeCheckers = listOf(), additionalClassifierUsageCheckers = listOf(), diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsNoImplCallChecker.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsDefinedExternallyCallChecker.kt similarity index 88% rename from js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsNoImplCallChecker.kt rename to js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsDefinedExternallyCallChecker.kt index 63f27471963..20fd0e3fd09 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsNoImplCallChecker.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsDefinedExternallyCallChecker.kt @@ -17,16 +17,16 @@ package org.jetbrains.kotlin.js.resolve.diagnostics import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.js.resolve.diagnostics.JsExternalChecker.NO_IMPL_PROPERTY_NAME +import org.jetbrains.kotlin.js.resolve.diagnostics.JsExternalChecker.DEFINED_EXTENRALLY_PROPERTY_NAMES import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe -object JsNoImplCallChecker : CallChecker { +object JsDefinedExternallyCallChecker : CallChecker { override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { - if (resolvedCall.resultingDescriptor.fqNameUnsafe != NO_IMPL_PROPERTY_NAME) return + if (resolvedCall.resultingDescriptor.fqNameUnsafe !in DEFINED_EXTENRALLY_PROPERTY_NAMES) return val ownerDescriptor = context.scope.ownerDescriptor if (!AnnotationsUtils.isNativeObject(ownerDescriptor) && !AnnotationsUtils.isPredefinedObject(ownerDescriptor)) { diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt index 2226eab3c09..602fe430501 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsExternalChecker.kt @@ -36,7 +36,7 @@ import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.singletonOrEmptyList object JsExternalChecker : SimpleDeclarationChecker { - val NO_IMPL_PROPERTY_NAME = FqNameUnsafe("kotlin.js.noImpl") + val DEFINED_EXTENRALLY_PROPERTY_NAMES = setOf(FqNameUnsafe("kotlin.js.noImpl"), FqNameUnsafe("kotlin.js.definedExternally")) override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink, bindingContext: BindingContext) { @@ -109,12 +109,14 @@ object JsExternalChecker : SimpleDeclarationChecker { if (declaration is KtDeclarationWithBody && !declaration.hasValidExternalBody(bindingContext)) { diagnosticHolder.report(ErrorsJs.WRONG_BODY_OF_EXTERNAL_DECLARATION.on(declaration.bodyExpression!!)) } - else if (declaration is KtDeclarationWithInitializer && declaration.initializer?.isNoImplExpression(bindingContext) == false) { + else if (declaration is KtDeclarationWithInitializer && + declaration.initializer?.isDefinedExternallyExpression(bindingContext) == false + ) { diagnosticHolder.report(ErrorsJs.WRONG_INITIALIZER_OF_EXTERNAL_DECLARATION.on(declaration.initializer!!)) } if (declaration is KtCallableDeclaration) { for (defaultValue in declaration.valueParameters.mapNotNull { it.defaultValue }) { - if (!defaultValue.isNoImplExpression(bindingContext)) { + if (!defaultValue.isDefinedExternallyExpression(bindingContext)) { diagnosticHolder.report(ErrorsJs.WRONG_DEFAULT_VALUE_FOR_EXTERNAL_FUN_PARAMETER.on(defaultValue)) } } @@ -200,20 +202,20 @@ object JsExternalChecker : SimpleDeclarationChecker { if (!hasBody()) return true val body = bodyExpression!! return if (!hasBlockBody()) { - body.isNoImplExpression(bindingContext) + body.isDefinedExternallyExpression(bindingContext) } else if (body is KtBlockExpression) { val statement = body.statements.singleOrNull() ?: return false - statement.isNoImplExpression(bindingContext) + statement.isDefinedExternallyExpression(bindingContext) } else { false } } - private fun KtExpression.isNoImplExpression(bindingContext: BindingContext): Boolean { + private fun KtExpression.isDefinedExternallyExpression(bindingContext: BindingContext): Boolean { val descriptor = getResolvedCall(bindingContext)?.resultingDescriptor as? PropertyDescriptor ?: return false val container = descriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false - return container.fqNameUnsafe == NO_IMPL_PROPERTY_NAME.parent() && descriptor.name == NO_IMPL_PROPERTY_NAME.shortName() + return DEFINED_EXTENRALLY_PROPERTY_NAMES.any { container.fqNameUnsafe == it.parent() && descriptor.name == it.shortName() } } } diff --git a/js/js.libraries/src/core/core.kt b/js/js.libraries/src/core/core.kt index d036b27b6e3..7bdb23a2855 100644 --- a/js/js.libraries/src/core/core.kt +++ b/js/js.libraries/src/core/core.kt @@ -1,7 +1,10 @@ package kotlin.js public external val noImpl: Nothing - get() = noImpl + get() = definedExternally + +public external val definedExternally: Nothing + get() = definedExternally public external fun eval(expr: String): dynamic = noImpl