From 589085369ee1b2f3830405a76f0c364626cae6ba Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 21 Aug 2018 12:31:38 +0300 Subject: [PATCH] [JS FE] Unify how the compiler checks parameters and return types for external declarations --- .../extensionFunctionArgumentOrReturnType.kt | 16 ++--- .../js/resolve/diagnostics/ErrorsJs.java | 2 +- .../resolve/diagnostics/JsExternalChecker.kt | 58 ++++++++----------- 3 files changed, 34 insertions(+), 42 deletions(-) diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionArgumentOrReturnType.kt b/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionArgumentOrReturnType.kt index d6bb34bf0ff..dfe629c5eeb 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionArgumentOrReturnType.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/native/extensionFunctionArgumentOrReturnType.kt @@ -2,24 +2,24 @@ external fun foo(f: Int.() -> Int< external fun bar(vararg f: Int.() -> Int) -external fun baz(): Int.() -> Int +external fun baz(): Int.() -> Int -external val prop: Int.() -> Int +external val prop: Int.() -> Int -external var prop2: Int.() -> Int +external var prop2: Int.() -> Int external val propGet - get(): Int.() -> Int = definedExternally + get(): Int.() -> Int = definedExternally external var propSet - get(): Int.() -> Int = definedExternally + get(): Int.() -> Int = definedExternally set(v: Int.() -> Int) = definedExternally external class A(f: Int.() -> Int) external data class B( - val a: Int.() -> Int, - var b: Int.() -> Int + val a: Int.() -> Int, + var b: Int.() -> Int ) { - val c: Int.() -> Int + val c: Int.() -> Int } \ No newline at end of file diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java index 031cd0e6e0a..2268d61102c 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/ErrorsJs.java @@ -30,7 +30,7 @@ public interface ErrorsJs { DiagnosticFactory1 NOT_SUPPORTED = DiagnosticFactory1.create(ERROR, DEFAULT); DiagnosticFactory0 JSCODE_NO_JAVASCRIPT_PRODUCED = DiagnosticFactory0.create(ERROR, DEFAULT); DiagnosticFactory1 WRONG_EXTERNAL_DECLARATION = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); - DiagnosticFactory0 EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); + DiagnosticFactory0 EXTENSION_FUNCTION_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory0 NESTED_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory0 INLINE_CLASS_IN_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); 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 4eafe9ac627..2dc959c3bb0 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 @@ -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, + 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() ) {