Do not use IntelliJ extensions for declaration without body suppressor in JS
This commit is contained in:
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+2
-16
@@ -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<String>
|
||||
|
||||
companion object {
|
||||
val EP_NAME: ExtensionPointName<SuppressStringProvider> =
|
||||
ExtensionPointName.create<SuppressStringProvider>("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<KtAnnotated, Suppressor>()
|
||||
@@ -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<String>, 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
|
||||
|
||||
-43
@@ -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<DiagnosticFactory1<KtFunction, SimpleFunctionDescriptor>> =
|
||||
listOf(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, Errors.NON_MEMBER_FUNCTION_NO_BODY)
|
||||
|
||||
val PROPERTY_NOT_INITIALIZED_ERRORS: List<DiagnosticFactory0<KtProperty>> =
|
||||
listOf(Errors.MUST_BE_INITIALIZED, Errors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT)
|
||||
|
||||
abstract class SuppressDiagnosticsByAnnotations(
|
||||
diagnosticsToSuppress: List<DiagnosticFactory<out Diagnostic>>,
|
||||
vararg annotationFqNames: FqName
|
||||
) : SuppressStringProvider {
|
||||
|
||||
private val stringsToSuppress = diagnosticsToSuppress.map { it.name.toLowerCase() }
|
||||
private val expectedFqNames = annotationFqNames.toSet()
|
||||
|
||||
override fun get(annotationDescriptor: AnnotationDescriptor): List<String> {
|
||||
return if (annotationDescriptor.fqName in expectedFqNames) stringsToSuppress else emptyList()
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@
|
||||
<id>org.jetbrains.kotlin</id>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint name="suppressStringProvider"
|
||||
interface="org.jetbrains.kotlin.resolve.diagnostics.SuppressStringProvider"/>
|
||||
<extensionPoint name="diagnosticSuppressor"
|
||||
interface="org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor"/>
|
||||
<extensionPoint name="expressionCodegenExtension"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<id>org.jetbrains.kotlin</id>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<suppressStringProvider implementation="org.jetbrains.kotlin.js.analyze.SuppressNoBodyErrorsForNativeDeclarations"/>
|
||||
<diagnosticSuppressor implementation="org.jetbrains.kotlin.js.analyze.SuppressUninitializedErrorsForNativeDeclarations"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user