diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToModule.kt b/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToModule.kt index 015f3f17fc0..a01e5d955e6 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToModule.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToModule.kt @@ -40,11 +40,18 @@ fun box() { bar() baz() + println(::bar.name) + println(::baz.name) + println(A::f.name) + B.Nested() boo<B?>(null) boo(null as B?) boo<B.Nested?>(null) + + println(B::class) + println(B.Nested::class) } external class DerivedB : B diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToNonModule.kt b/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToNonModule.kt index 0cd5e6254b4..d209e99b51c 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToNonModule.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/module/wrongCallToNonModule.kt @@ -35,9 +35,15 @@ fun box() { bar() B.Nested() + println(::bar.name) + println(A::f.name) + boo<B?>(null) boo(null as B?) boo<B.Nested?>(null) + + println(B::class) + println(B.Nested::class) } external class DerivedB : B 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 33e3e9d5e9c..f86071e241f 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 @@ -64,6 +64,7 @@ object JsPlatformConfigurator : PlatformConfigurator( container.useInstance(JsTypeSpecificityComparator) container.useInstance(JsNameClashChecker()) container.useInstance(JsNameCharsChecker()) + container.useInstance(JsModuleClassLiteralChecker) container.useImpl() container.useImpl() container.useImpl() diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsModuleCheckUtil.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsModuleCheckUtil.kt index c7577c8116e..fafefa7184c 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsModuleCheckUtil.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsModuleCheckUtil.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.js.resolve.MODULE_KIND import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.serialization.js.ModuleKind fun checkJsModuleUsage( @@ -50,17 +51,22 @@ fun checkJsModuleUsage( else { if (moduleKind == ModuleKind.PLAIN) { if (!callToNonModule && callToModule) { - diagnosticSink.report(ErrorsJs.CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM.on(reportOn, callee)) + diagnosticSink.report(ErrorsJs.CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM.on(reportOn, normalizeDescriptor(callee))) } } else { if (!callToModule && callToNonModule) { - diagnosticSink.report(ErrorsJs.CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM.on(reportOn, callee)) + diagnosticSink.report(ErrorsJs.CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM.on(reportOn, normalizeDescriptor(callee))) } } } } +private fun normalizeDescriptor(descriptor: DeclarationDescriptor): DeclarationDescriptor { + if (descriptor is FakeCallableDescriptorForObject) return descriptor.classDescriptor + return descriptor +} + private fun findRoot(callee: DeclarationDescriptor) = generateSequence(callee) { it.containingDeclaration } .takeWhile { it !is PackageFragmentDescriptor } .last() \ No newline at end of file diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsModuleClassLiteralChecker.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsModuleClassLiteralChecker.kt new file mode 100644 index 00000000000..a13d7963b98 --- /dev/null +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsModuleClassLiteralChecker.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.resolve.diagnostics + +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.psi.KtClassLiteralExpression +import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.expressions.ClassLiteralChecker + +object JsModuleClassLiteralChecker : ClassLiteralChecker { + override fun check(expression: KtClassLiteralExpression, type: KotlinType, context: ResolutionContext<*>) { + val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return + checkJsModuleUsage(context.trace.bindingContext, context.trace, context.scope.ownerDescriptor, descriptor, expression) + } +}