KT-12877: add diagnostics on JsModule/JsNonModule:
1) for all cases of misusing of JsModule report on JsNonModule as well 2) report about non-top-level declarations with JsModule/JsNonModule 3) report about JsModule/JsNonModule declarations inside file marked with JsModule/JsNonModule 4) report about usages of declarations not marked with both JsModule and JsNonModule from UMD module
This commit is contained in:
committed by
Alexey Andreev
parent
08a7f9c298
commit
31a1d6ca66
+10
-1
@@ -50,10 +50,19 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy {
|
||||
put(ErrorsJs.JS_NAME_PROHIBITED_FOR_NAMED_NATIVE, "@JsName is prohibited for @native declaration with explicit name")
|
||||
put(ErrorsJs.JS_MODULE_PROHIBITED_ON_VAR, "@JsModule annotation prohibited for 'var' declarations. Use 'val' instead.")
|
||||
put(ErrorsJs.JS_MODULE_PROHIBITED_ON_NON_NATIVE, "@JsModule annotation prohibited for non-@native declarations.")
|
||||
put(ErrorsJs.JS_MODULE_PROHIBITED_ON_VAR, "@JsModule and @JsNonModule annotations prohibited for 'var' declarations. " +
|
||||
"Use 'val' instead.")
|
||||
put(ErrorsJs.JS_MODULE_PROHIBITED_ON_NON_NATIVE, "@JsModule and @JsNonModule annotations prohibited for non-@native declarations.")
|
||||
put(ErrorsJs.JS_MODULE_PROHIBITED_ON_NON_TOPLEVEL, "@JsModule and @JsNonModule annotations are only allowed to appear " +
|
||||
"on packages and top-level declarations")
|
||||
put(ErrorsJs.NESTED_JS_MODULE_PROHIBITED, "@JsModule and @JsNonModule can't appear on here since the file is already " +
|
||||
"marked by either @JsModule or @JsNonModule")
|
||||
put(ErrorsJs.CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM, "Can't access declaration marked with @JsModule annotation " +
|
||||
"from non-modular project")
|
||||
put(ErrorsJs.CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM, "Can't access declaration marked with @JsNonModule annotation " +
|
||||
"from modular project")
|
||||
"from modular project")
|
||||
put(ErrorsJs.CALL_FROM_UMD_MUST_BE_JS_MODULE_AND_JS_NON_MODULE, "When accessing module declarations from UMD, " +
|
||||
"they must be marked by both @JsModule and @JsNonModule")
|
||||
put(ErrorsJs.CANNOT_CHECK_FOR_NATIVE_INTERFACE, "Cannot check for native interface: {0}", RENDER_TYPE)
|
||||
put(ErrorsJs.UNCHECKED_CAST_TO_NATIVE_INTERFACE, "Unchecked cast to native interface: {0} to {1}", RENDER_TYPE, RENDER_TYPE)
|
||||
put(ErrorsJs.NATIVE_INTERFACE_AS_REIFIED_TYPE_ARGUMENT, "Cannot pass native interface {0} for reified type parameter", RENDER_TYPE)
|
||||
|
||||
@@ -54,8 +54,11 @@ public interface ErrorsJs {
|
||||
DiagnosticFactory0<PsiElement> JS_NAME_PROHIBITED_FOR_NAMED_NATIVE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtElement> JS_MODULE_PROHIBITED_ON_VAR = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||
DiagnosticFactory0<KtElement> JS_MODULE_PROHIBITED_ON_NON_NATIVE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||
DiagnosticFactory0<KtElement> JS_MODULE_PROHIBITED_ON_NON_TOPLEVEL = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||
DiagnosticFactory0<KtElement> NESTED_JS_MODULE_PROHIBITED = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||
DiagnosticFactory0<PsiElement> CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM = DiagnosticFactory0.create(ERROR, DEFAULT);
|
||||
DiagnosticFactory0<PsiElement> CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM = DiagnosticFactory0.create(ERROR, DEFAULT);
|
||||
DiagnosticFactory0<PsiElement> CALL_FROM_UMD_MUST_BE_JS_MODULE_AND_JS_NON_MODULE = DiagnosticFactory0.create(ERROR, DEFAULT);
|
||||
DiagnosticFactory1<PsiElement, KotlinType> CANNOT_CHECK_FOR_NATIVE_INTERFACE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, KotlinType, KotlinType> UNCHECKED_CAST_TO_NATIVE_INTERFACE = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, KotlinType> NATIVE_INTERFACE_AS_REIFIED_TYPE_ARGUMENT = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
+13
-6
@@ -42,14 +42,21 @@ object JsModuleCallChecker : CallChecker {
|
||||
AnnotationsUtils.getFileModuleName(bindingContext, callee) != null
|
||||
val callToNonModule = AnnotationsUtils.isNonModule(callee) || AnnotationsUtils.isFromNonModuleFile(bindingContext, callee)
|
||||
|
||||
if (moduleKind == ModuleKind.PLAIN || moduleKind == ModuleKind.UMD) {
|
||||
if (!callToNonModule && callToModule) {
|
||||
context.trace.report(ErrorsJs.CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM.on(reportOn))
|
||||
if (moduleKind == ModuleKind.UMD) {
|
||||
if (!callToNonModule && callToModule || callToNonModule && !callToModule) {
|
||||
context.trace.report(ErrorsJs.CALL_FROM_UMD_MUST_BE_JS_MODULE_AND_JS_NON_MODULE.on(reportOn))
|
||||
}
|
||||
}
|
||||
if (moduleKind != ModuleKind.PLAIN) {
|
||||
if (!callToModule && callToNonModule) {
|
||||
context.trace.report(ErrorsJs.CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM.on(reportOn))
|
||||
else {
|
||||
if (moduleKind == ModuleKind.PLAIN) {
|
||||
if (!callToNonModule && callToModule) {
|
||||
context.trace.report(ErrorsJs.CALL_TO_JS_MODULE_WITHOUT_MODULE_SYSTEM.on(reportOn))
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!callToModule && callToNonModule) {
|
||||
context.trace.report(ErrorsJs.CALL_TO_JS_NON_MODULE_WITH_MODULE_SYSTEM.on(reportOn))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
object JsModuleChecker : SimpleDeclarationChecker {
|
||||
override fun check(
|
||||
@@ -31,14 +32,24 @@ object JsModuleChecker : SimpleDeclarationChecker {
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext
|
||||
) {
|
||||
val moduleName = AnnotationsUtils.getModuleName(descriptor)
|
||||
if (AnnotationsUtils.getModuleName(descriptor) == null && !AnnotationsUtils.isNonModule(descriptor)) return
|
||||
|
||||
if (moduleName != null && descriptor is PropertyDescriptor && descriptor.isVar) {
|
||||
if (descriptor is PropertyDescriptor && descriptor.isVar) {
|
||||
diagnosticHolder.report(ErrorsJs.JS_MODULE_PROHIBITED_ON_VAR.on(declaration))
|
||||
}
|
||||
|
||||
if (moduleName != null && !AnnotationsUtils.isNativeObject(descriptor)) {
|
||||
if (!AnnotationsUtils.isNativeObject(descriptor)) {
|
||||
diagnosticHolder.report(ErrorsJs.JS_MODULE_PROHIBITED_ON_NON_NATIVE.on(declaration))
|
||||
}
|
||||
|
||||
if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||
diagnosticHolder.report(ErrorsJs.JS_MODULE_PROHIBITED_ON_NON_TOPLEVEL.on(declaration))
|
||||
}
|
||||
|
||||
val isFileModuleOrNonModule = AnnotationsUtils.getFileModuleName(bindingContext, descriptor) != null ||
|
||||
AnnotationsUtils.isFromNonModuleFile(bindingContext, descriptor)
|
||||
if (isFileModuleOrNonModule) {
|
||||
diagnosticHolder.report(ErrorsJs.NESTED_JS_MODULE_PROHIBITED.on(declaration))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user