diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 7b758f61948..5e872346380 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.BindingContext.* import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractDeclaration import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator +import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.source.KotlinSourceElement @@ -49,10 +50,13 @@ internal class DeclarationsCheckerBuilder( private val annotationChecker: AnnotationChecker, private val identifierChecker: IdentifierChecker, private val languageVersionSettings: LanguageVersionSettings, - private val typeSpecificityComparator: TypeSpecificityComparator + private val typeSpecificityComparator: TypeSpecificityComparator, + private val diagnosticSuppressor: PlatformDiagnosticSuppressor ) { - fun withTrace(trace: BindingTrace) = - DeclarationsChecker(descriptorResolver, originalModifiersChecker, annotationChecker, identifierChecker, trace, languageVersionSettings, typeSpecificityComparator) + fun withTrace(trace: BindingTrace) = DeclarationsChecker( + descriptorResolver, originalModifiersChecker, annotationChecker, identifierChecker, trace, languageVersionSettings, + typeSpecificityComparator, diagnosticSuppressor + ) } class DeclarationsChecker( @@ -62,7 +66,8 @@ class DeclarationsChecker( private val identifierChecker: IdentifierChecker, private val trace: BindingTrace, private val languageVersionSettings: LanguageVersionSettings, - typeSpecificityComparator: TypeSpecificityComparator + typeSpecificityComparator: TypeSpecificityComparator, + private val diagnosticSuppressor: PlatformDiagnosticSuppressor ) { private val modifiersChecker = modifiersChecker.withTrace(trace) @@ -670,11 +675,13 @@ class DeclarationsChecker( if (propertyDescriptor.extensionReceiverParameter != null && !hasAccessorImplementation) { trace.report(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT.on(property)) } - else if (containingDeclaration !is ClassDescriptor || hasAccessorImplementation) { - trace.report(MUST_BE_INITIALIZED.on(property)) - } - else { - trace.report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property)) + else if (diagnosticSuppressor.shouldReportNoBody(propertyDescriptor)) { + if (containingDeclaration !is ClassDescriptor || hasAccessorImplementation) { + trace.report(MUST_BE_INITIALIZED.on(property)) + } + else { + trace.report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property)) + } } } else if (property.typeReference == null && !languageVersionSettings.supportsFeature(LanguageFeature.ShortSyntaxForPropertyGetters)) { @@ -733,12 +740,14 @@ class DeclarationsChecker( trace.report(REDUNDANT_OPEN_IN_INTERFACE.on(function)) } } - if (!hasBody && !hasAbstractModifier && !hasExternalModifier && !inInterface && !isExpectClass) { + if (!hasBody && !hasAbstractModifier && !hasExternalModifier && !inInterface && !isExpectClass && + diagnosticSuppressor.shouldReportNoBody(functionDescriptor)) { trace.report(NON_ABSTRACT_FUNCTION_WITH_NO_BODY.on(function, functionDescriptor)) } } else /* top-level only */ { - if (!function.hasBody() && !hasAbstractModifier && !hasExternalModifier && !functionDescriptor.isExpect) { + if (!function.hasBody() && !hasAbstractModifier && !hasExternalModifier && !functionDescriptor.isExpect && + diagnosticSuppressor.shouldReportNoBody(functionDescriptor)) { trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor)) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt index d8fe33fa43f..6fa7a9e47ab 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/PlatformDiagnosticSuppressor.kt @@ -17,13 +17,18 @@ package org.jetbrains.kotlin.resolve.checkers import org.jetbrains.kotlin.container.DefaultImplementation +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor @DefaultImplementation(PlatformDiagnosticSuppressor.Default::class) interface PlatformDiagnosticSuppressor { fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean + fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean + object Default : PlatformDiagnosticSuppressor { override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean = true + + override fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean = true } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/diagnostics/KotlinSuppressCache.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/diagnostics/KotlinSuppressCache.kt index 388f997e610..55dcd1fb941 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/diagnostics/KotlinSuppressCache.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/diagnostics/KotlinSuppressCache.kt @@ -33,15 +33,6 @@ import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.util.ExtensionProvider -interface SuppressStringProvider { - operator fun get(annotationDescriptor: AnnotationDescriptor): List - - companion object { - val EP_NAME: ExtensionPointName = - ExtensionPointName.create("org.jetbrains.kotlin.suppressStringProvider") - } -} - interface DiagnosticSuppressor { fun isSuppressed(diagnostic: Diagnostic): Boolean @@ -52,8 +43,7 @@ interface DiagnosticSuppressor { } abstract class KotlinSuppressCache { - private val ADDITIONAL_SUPPRESS_STRING_PROVIDERS = ExtensionProvider.create(SuppressStringProvider.EP_NAME) - private val DIAGNOSTIC_SUPPRESSORS = ExtensionProvider.create(DiagnosticSuppressor.EP_NAME) + private val diagnosticSuppressors = ExtensionProvider.create(DiagnosticSuppressor.EP_NAME) // The cache is weak: we're OK with losing it private val suppressors = ContainerUtil.createConcurrentWeakValueMap() @@ -77,7 +67,7 @@ abstract class KotlinSuppressCache { } if (request is DiagnosticSuppressRequest) { - for (suppressor in DIAGNOSTIC_SUPPRESSORS.get()) { + for (suppressor in diagnosticSuppressors.get()) { if (suppressor.isSuppressed(request.diagnostic)) return true } } @@ -158,10 +148,6 @@ abstract class KotlinSuppressCache { } private fun processAnnotation(builder: ImmutableSet.Builder, annotationDescriptor: AnnotationDescriptor) { - for (suppressStringProvider in ADDITIONAL_SUPPRESS_STRING_PROVIDERS.get()) { - builder.addAll(suppressStringProvider[annotationDescriptor]) - } - if (annotationDescriptor.fqName != KotlinBuiltIns.FQ_NAMES.suppress) return // We only add strings and skip other values to facilitate recovery in presence of erroneous code diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/diagnostics/SuppressDiagnosticsByAnnotations.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/diagnostics/SuppressDiagnosticsByAnnotations.kt deleted file mode 100644 index 7f43c9e513d..00000000000 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/diagnostics/SuppressDiagnosticsByAnnotations.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010-2015 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.resolve.diagnostics - -import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -import org.jetbrains.kotlin.diagnostics.* -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.psi.KtFunction -import org.jetbrains.kotlin.psi.KtProperty - -val FUNCTION_NO_BODY_ERRORS: List> = - listOf(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, Errors.NON_MEMBER_FUNCTION_NO_BODY) - -val PROPERTY_NOT_INITIALIZED_ERRORS: List> = - listOf(Errors.MUST_BE_INITIALIZED, Errors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT) - -abstract class SuppressDiagnosticsByAnnotations( - diagnosticsToSuppress: List>, - vararg annotationFqNames: FqName -) : SuppressStringProvider { - - private val stringsToSuppress = diagnosticsToSuppress.map { it.name.toLowerCase() } - private val expectedFqNames = annotationFqNames.toSet() - - override fun get(annotationDescriptor: AnnotationDescriptor): List { - return if (annotationDescriptor.fqName in expectedFqNames) stringsToSuppress else emptyList() - } -} diff --git a/idea/src/META-INF/extensions/common.xml b/idea/src/META-INF/extensions/common.xml index c26a7b5aab8..fd38a3f1b4a 100644 --- a/idea/src/META-INF/extensions/common.xml +++ b/idea/src/META-INF/extensions/common.xml @@ -2,8 +2,6 @@ org.jetbrains.kotlin - org.jetbrains.kotlin - diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt index 46495cf64ee..e07f5b294e3 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/suppressWarnings.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.js.analyze +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic @@ -26,25 +27,24 @@ import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor import org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor -import org.jetbrains.kotlin.resolve.diagnostics.FUNCTION_NO_BODY_ERRORS -import org.jetbrains.kotlin.resolve.diagnostics.PROPERTY_NOT_INITIALIZED_ERRORS -import org.jetbrains.kotlin.resolve.diagnostics.SuppressDiagnosticsByAnnotations private val NATIVE_ANNOTATIONS = arrayOf(NATIVE.fqName, NATIVE_INVOKE.fqName, NATIVE_GETTER.fqName, NATIVE_SETTER.fqName) -object JsNativeDiagnosticSuppressor : PlatformDiagnosticSuppressor { - override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean { - var descriptor: DeclarationDescriptor = parameter - while (true) { - val annotations = descriptor.annotations - if (!annotations.isEmpty() && NATIVE_ANNOTATIONS.any(annotations::hasAnnotation)) return false - descriptor = descriptor.containingDeclaration ?: break - } - return true +private fun DeclarationDescriptor.isLexicallyInsideJsNative(): Boolean { + var descriptor: DeclarationDescriptor = this + while (true) { + val annotations = descriptor.annotations + if (!annotations.isEmpty() && NATIVE_ANNOTATIONS.any(annotations::hasAnnotation)) return true + descriptor = descriptor.containingDeclaration ?: break } + return false } -class SuppressNoBodyErrorsForNativeDeclarations : SuppressDiagnosticsByAnnotations(FUNCTION_NO_BODY_ERRORS + PROPERTY_NOT_INITIALIZED_ERRORS, *NATIVE_ANNOTATIONS) +object JsNativeDiagnosticSuppressor : PlatformDiagnosticSuppressor { + override fun shouldReportUnusedParameter(parameter: VariableDescriptor): Boolean = !parameter.isLexicallyInsideJsNative() + + override fun shouldReportNoBody(descriptor: CallableMemberDescriptor): Boolean = !descriptor.isLexicallyInsideJsNative() +} class SuppressUninitializedErrorsForNativeDeclarations : DiagnosticSuppressor { override fun isSuppressed(diagnostic: Diagnostic): Boolean {