[JS FE] Unify how the compiler checks parameters and return types for external declarations
This commit is contained in:
Vendored
+8
-8
@@ -2,24 +2,24 @@ external fun foo(<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>f: Int.() -> Int<
|
||||
|
||||
external fun bar(<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>vararg f: Int.() -> Int<!>)
|
||||
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>external fun baz(): Int.() -> Int<!>
|
||||
external fun baz(): <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!>
|
||||
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>external val prop: Int.() -> Int<!>
|
||||
external val prop: <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!>
|
||||
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>external var prop2: Int.() -> Int<!>
|
||||
external var prop2: <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!>
|
||||
|
||||
external val propGet
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>get(): Int.() -> Int<!> = definedExternally
|
||||
get(): <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!> = definedExternally
|
||||
|
||||
external var propSet
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>get(): Int.() -> Int<!> = definedExternally
|
||||
get(): <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!> = definedExternally
|
||||
set(<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>v: Int.() -> Int<!>) = definedExternally
|
||||
|
||||
external class A(<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>f: Int.() -> Int<!>)
|
||||
|
||||
external data class <!WRONG_EXTERNAL_DECLARATION!>B(
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION, EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>val a: Int.() -> Int<!>,
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION, EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>var b: Int.() -> Int<!>
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>val a: <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!><!>,
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>var b: <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!><!>
|
||||
)<!> {
|
||||
<!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>val c: Int.() -> Int<!>
|
||||
val c: <!EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION!>Int.() -> Int<!>
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
+25
-33
@@ -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()
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user