[JS FE] Unify how the compiler checks parameters and return types for external declarations

This commit is contained in:
Zalim Bashorov
2018-08-21 12:31:38 +03:00
parent 9d0b880f67
commit 589085369e
3 changed files with 34 additions and 42 deletions
@@ -30,7 +30,7 @@ public interface ErrorsJs {
DiagnosticFactory1<KtElement, KtElement> NOT_SUPPORTED = DiagnosticFactory1.create(ERROR, DEFAULT);
DiagnosticFactory0<KtExpression> JSCODE_NO_JAVASCRIPT_PRODUCED = DiagnosticFactory0.create(ERROR, DEFAULT);
DiagnosticFactory1<KtExpression, String> WRONG_EXTERNAL_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtExpression> EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtElement> EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtExpression> NESTED_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtElement> INLINE_CLASS_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.js.resolve.diagnostics
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.js.PredefinedAnnotation
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
@@ -86,46 +87,37 @@ object JsExternalChecker : DeclarationChecker {
trace.report(ErrorsJs.INLINE_EXTERNAL_DECLARATION.on(declaration))
}
if (descriptor is CallableMemberDescriptor && !(descriptor is PropertyAccessorDescriptor && descriptor.isDefault)) {
fun checkTypeIsNotInlineClass(type: KotlinType, elementToReport: KtElement) {
if (type.isInlineClassType()) {
trace.report(ErrorsJs.INLINE_CLASS_IN_EXTERNAL_DECLARATION.on(elementToReport))
fun reportOnParametersAndReturnTypesIf(
diagnosticFactory: DiagnosticFactory0<KtElement>,
condition: (KotlinType) -> Boolean
) {
if (descriptor is CallableMemberDescriptor && !(descriptor is PropertyAccessorDescriptor && descriptor.isDefault)) {
fun checkTypeIsNotInlineClass(type: KotlinType, elementToReport: KtElement) {
if (condition(type)) {
trace.report(diagnosticFactory.on(elementToReport))
}
}
}
for (p in descriptor.valueParameters) {
val ktParam = p.source.getPsi() as? KtParameter ?: declaration
checkTypeIsNotInlineClass(p.varargElementType ?: p.type, ktParam)
}
val elementToReport = when (declaration) {
is KtCallableDeclaration -> declaration.typeReference
is KtPropertyAccessor -> declaration.returnTypeReference
else -> declaration
}
elementToReport?.let {
checkTypeIsNotInlineClass(descriptor.returnType!!, it)
}
}
if (descriptor is CallableMemberDescriptor && !(descriptor is PropertyAccessorDescriptor && descriptor.isDefault)) {
for (p in descriptor.valueParameters) {
if ((p.varargElementType ?: p.type).isExtensionFunctionType) {
for (p in descriptor.valueParameters) {
val ktParam = p.source.getPsi() as? KtParameter ?: declaration
trace.report(ErrorsJs.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION.on(ktParam))
checkTypeIsNotInlineClass(p.varargElementType ?: p.type, ktParam)
}
val elementToReport = when (declaration) {
is KtCallableDeclaration -> declaration.typeReference
is KtPropertyAccessor -> declaration.returnTypeReference
else -> declaration
}
elementToReport?.let {
checkTypeIsNotInlineClass(descriptor.returnType!!, it)
}
}
// Only report on properties if there are no custom accessors
val propertyWithCustomAccessors = descriptor is PropertyDescriptor &&
!(descriptor.getter?.isDefault ?: true && descriptor.setter?.isDefault ?: true)
if (!propertyWithCustomAccessors && descriptor.returnType?.isExtensionFunctionType ?: false) {
trace.report(ErrorsJs.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION.on(declaration))
}
}
reportOnParametersAndReturnTypesIf(ErrorsJs.INLINE_CLASS_IN_EXTERNAL_DECLARATION, KotlinType::isInlineClassType)
reportOnParametersAndReturnTypesIf(ErrorsJs.EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION, KotlinType::isExtensionFunctionType)
if (descriptor is CallableMemberDescriptor && descriptor.isNonAbstractMemberOfInterface() &&
!descriptor.isNullableProperty()
) {