K2: get rid of manual diagnostic suppression in checkers

This commit is contained in:
Mikhail Glukhikh
2022-07-21 11:59:50 +02:00
committed by Space
parent 07f16ef378
commit eba0e94429
31 changed files with 365 additions and 470 deletions
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.collectors.components.AbstractDiagnosticCollectorComponent
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.SessionHolderImpl
import org.jetbrains.kotlin.name.StandardClassIds
internal abstract class FileStructureElementDiagnosticRetriever {
abstract fun retrieve(
@@ -60,6 +61,7 @@ internal class SingleNonLocalDeclarationDiagnosticRetriever(
return when {
structureElementDeclaration !is FirRegularClass -> true
structureElementDeclaration == declaration -> true
declaration.hasAnnotation(StandardClassIds.Annotations.Suppress) -> true
else -> false
}
}
@@ -4216,6 +4216,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
public void testWithSuppression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression.kt");
}
@Test
@TestMetadata("withSuppression2.kt")
public void testWithSuppression2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression2.kt");
}
}
@Nested
@@ -3763,6 +3763,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
public void testWithSuppression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression.kt");
}
@TestMetadata("withSuppression2.kt")
public void testWithSuppression2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression2.kt");
}
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/types")
@@ -0,0 +1,37 @@
FILE: withSuppression2.kt
public abstract class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public final fun foo(i: R|kotlin/Int|): R|kotlin/Unit| {
}
public final inline class B : R|@R|kotlin/Suppress|(names = vararg(String(VALUE_CLASS_CANNOT_EXTEND_CLASSES))) A| {
public constructor(i: R|kotlin/Int|): R|B| {
super<R|@R|kotlin/Suppress|(names = vararg(String(VALUE_CLASS_CANNOT_EXTEND_CLASSES))) A|>()
}
public final val i: R|kotlin/Int| = R|<local>/i|
public get(): R|kotlin/Int|
@R|kotlin/Suppress|(names = vararg(String(SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_VALUE_CLASS))) public constructor(): R|B| {
this<R|B|>(Int(42))
R|/foo|(this@R|/B|.R|/B.i|)
}
@R|kotlin/Suppress|(names = vararg(String(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS))) public abstract val y: R|kotlin/Int|
public get(): R|kotlin/Int|
}
public abstract interface C : R|kotlin/Any| {
@R|kotlin/Suppress|(names = vararg(String(PRIVATE_PROPERTY_IN_INTERFACE))) private final val x: R|kotlin/Int|
private get(): R|kotlin/Int|
@R|kotlin/Suppress|(names = vararg(String(METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE))) public open override fun hashCode(): R|kotlin/Int| {
^hashCode Int(42)
}
}
@R|kotlin/Suppress|(names = vararg(String(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER))) public final val z: <ERROR TYPE REF: Cannot infer variable type without initializer / getter / delegate>
public get(): <ERROR TYPE REF: Cannot infer variable type without initializer / getter / delegate>
@@ -0,0 +1,24 @@
abstract class A
fun foo(i: Int) {}
<!VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION!>value<!> class B(val i: Int) : @Suppress("VALUE_CLASS_CANNOT_EXTEND_CLASSES") A() {
@Suppress("SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_VALUE_CLASS")
constructor() : this(42) {
foo(i)
}
@Suppress("ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS")
abstract val y: Int
}
interface C {
@Suppress("PRIVATE_PROPERTY_IN_INTERFACE")
private val x: Int
@Suppress("METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE")
override fun hashCode() = 42
}
<!MUST_BE_INITIALIZED!>@Suppress("PROPERTY_WITH_NO_TYPE_NO_INITIALIZER")
val z<!>
@@ -4216,6 +4216,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
public void testWithSuppression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression.kt");
}
@Test
@TestMetadata("withSuppression2.kt")
public void testWithSuppression2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression2.kt");
}
}
@Nested
@@ -4216,6 +4216,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
public void testWithSuppression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression.kt");
}
@Test
@TestMetadata("withSuppression2.kt")
public void testWithSuppression2() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/suppress/withSuppression2.kt");
}
}
@Nested
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirInlineDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.isLocalMember
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
import org.jetbrains.kotlin.fir.declarations.utils.isInline
@@ -35,10 +34,8 @@ object FirJvmInlineDeclarationChecker : FirInlineDeclarationChecker() {
if (declaration !is FirPropertyAccessor && declaration !is FirSimpleFunction) return
val effectiveVisibility = declaration.effectiveVisibility
withSuppressedDiagnostics(declaration, context) { ctx ->
checkInlineFunctionBody(declaration, effectiveVisibility, ctx, reporter)
checkCallableDeclaration(declaration, ctx, reporter)
}
checkInlineFunctionBody(declaration, effectiveVisibility, context, reporter)
checkCallableDeclaration(declaration, context, reporter)
}
override val inlineVisitor get() = ::InlineVisitor
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets
import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationRetention
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.isJvm6
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
@@ -87,15 +86,11 @@ object FirRepeatableAnnotationChecker : FirBasicDeclarationChecker() {
if (declaration is FirRegularClass) {
val javaRepeatable = annotations.find { it.classId == StandardClassIds.Annotations.Java.Repeatable }
if (javaRepeatable != null) {
withSuppressedDiagnostics(javaRepeatable, context) {
checkJavaRepeatableAnnotationDeclaration(javaRepeatable, declaration, it, reporter)
}
checkJavaRepeatableAnnotationDeclaration(javaRepeatable, declaration, context, reporter)
} else {
val kotlinRepeatable = annotations.find { it.classId == StandardClassIds.Annotations.Repeatable }
if (kotlinRepeatable != null) {
withSuppressedDiagnostics(kotlinRepeatable, context) {
checkKotlinRepeatableAnnotationDeclaration(kotlinRepeatable, declaration, it, reporter)
}
checkKotlinRepeatableAnnotationDeclaration(kotlinRepeatable, declaration, context, reporter)
}
}
}
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.expressions.*
@@ -184,10 +183,7 @@ fun checkRepeatedAnnotation(
val useSiteTarget = annotation.useSiteTarget ?: annotationContainer?.getDefaultUseSiteTarget(annotation, context)
val existingTargetsForAnnotation = annotationsMap.getOrPut(annotation.annotationTypeRef.coneType) { arrayListOf() }
withSuppressedDiagnostics(annotation, context) {
checkRepeatedAnnotation(useSiteTarget, existingTargetsForAnnotation, annotation, it, reporter)
}
checkRepeatedAnnotation(useSiteTarget, existingTargetsForAnnotation, annotation, context, reporter)
existingTargetsForAnnotation.add(useSiteTarget)
}
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -104,10 +103,8 @@ private fun buildDeepSubstitutionMultimap(
return
val superClassSymbol = fullyExpandedType.toRegularClassSymbol(session)
withSuppressedDiagnostics(superTypeRef, context) {
if (!fullyExpandedType.isEnum && superClassSymbol != null) {
fillInDeepSubstitutor(fullyExpandedType.typeArguments, superClassSymbol, it)
}
if (!fullyExpandedType.isEnum && superClassSymbol != null) {
fillInDeepSubstitutor(fullyExpandedType.typeArguments, superClassSymbol, context)
}
}
}
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
@@ -52,14 +51,10 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() {
deprecatedSinceKotlin = annotation
}
withSuppressedDiagnostics(annotation, context) {
checkAnnotationTarget(declaration, annotation, it, reporter)
}
checkAnnotationTarget(declaration, annotation, context, reporter)
}
if (deprecatedSinceKotlin != null) {
withSuppressedDiagnostics(deprecatedSinceKotlin, context) {
checkDeprecatedCalls(deprecatedSinceKotlin, deprecated, it, reporter)
}
checkDeprecatedCalls(deprecatedSinceKotlin, deprecated, context, reporter)
}
checkRepeatedAnnotations(declaration, context, reporter)
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.resolve.getContainingDeclaration
@@ -234,23 +233,21 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
inspector.declarationConflictingSymbols.forEach { (conflictingDeclaration, symbols) ->
val source = conflictingDeclaration.source
if (source != null && symbols.isNotEmpty()) {
withSuppressedDiagnostics(conflictingDeclaration, context) { ctx ->
when (conflictingDeclaration) {
is FirSimpleFunction,
is FirConstructor -> {
reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, ctx)
}
else -> {
val factory = if (conflictingDeclaration is FirClassLikeDeclaration &&
conflictingDeclaration.getContainingDeclaration(ctx.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> }
) {
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
} else {
FirErrors.REDECLARATION
}
reporter.reportOn(source, factory, symbols, ctx)
when (conflictingDeclaration) {
is FirSimpleFunction,
is FirConstructor -> {
reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
}
else -> {
val factory = if (conflictingDeclaration is FirClassLikeDeclaration &&
conflictingDeclaration.getContainingDeclaration(context.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> }
) {
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
} else {
FirErrors.REDECLARATION
}
reporter.reportOn(source, factory, symbols, context)
}
}
}
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOnWithSuppression
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.FirFunction
@@ -47,9 +46,8 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
val diagnostic = returnTypeRef.diagnostic
if (diagnostic is ConeSimpleDiagnostic && diagnostic.kind == DiagnosticKind.ValueParameterWithNoTypeAnnotation) {
reporter.reportOnWithSuppression(
valueParameter,
FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION,
reporter.reportOn(
valueParameter.source, FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION,
context
)
}
@@ -60,7 +58,7 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
val varargParameters = function.valueParameters.filter { it.isVararg }
if (varargParameters.size > 1) {
for (parameter in varargParameters) {
reporter.reportOnWithSuppression(parameter, FirErrors.MULTIPLE_VARARG_PARAMETERS, context)
reporter.reportOn(parameter.source, FirErrors.MULTIPLE_VARARG_PARAMETERS, context)
}
}
@@ -72,9 +70,8 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
// Note: comparing with FE1.0, we skip checking if the type is not primitive because primitive types are not inline. That
// is any primitive values are already allowed by the inline check.
) {
reporter.reportOnWithSuppression(
varargParameter,
FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE,
reporter.reportOn(
varargParameter.source, FirErrors.FORBIDDEN_VARARG_PARAMETER_TYPE,
varargParameterType,
context
)
@@ -100,9 +97,8 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
if (referredParameterIndex < 0) return
if (index <= referredParameterIndex) {
reporter.reportOnWithSuppression(
qualifiedAccessExpression,
FirErrors.UNINITIALIZED_PARAMETER,
reporter.reportOn(
qualifiedAccessExpression.source, FirErrors.UNINITIALIZED_PARAMETER,
referredParameter.symbol,
context
)
@@ -16,8 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOnWithSuppression
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
@@ -54,7 +52,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
for (supertypeEntry in declaration.superTypeRefs) {
if (supertypeEntry.toRegularClassSymbol(context.session)?.isInterface != true) {
reporter.reportOnWithSuppression(supertypeEntry, FirErrors.VALUE_CLASS_CANNOT_EXTEND_CLASSES, context)
reporter.reportOn(supertypeEntry.source, FirErrors.VALUE_CLASS_CANNOT_EXTEND_CLASSES, context)
}
}
@@ -80,25 +78,23 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
innerDeclaration.body != null -> {
val body = innerDeclaration.body!!
withSuppressedDiagnostics(innerDeclaration, context) { context ->
reporter.reportOnWithSuppression(
body, FirErrors.SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_VALUE_CLASS, context
)
}
reporter.reportOn(
body.source, FirErrors.SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_VALUE_CLASS, context
)
}
}
}
is FirRegularClass -> {
if (innerDeclaration.isInner) {
reporter.reportOnWithSuppression(innerDeclaration, FirErrors.INNER_CLASS_INSIDE_VALUE_CLASS, context)
reporter.reportOn(innerDeclaration.source, FirErrors.INNER_CLASS_INSIDE_VALUE_CLASS, context)
}
}
is FirSimpleFunction -> {
val functionName = innerDeclaration.name.asString()
if (functionName in reservedFunctionNames) {
reporter.reportOnWithSuppression(
innerDeclaration, FirErrors.RESERVED_MEMBER_INSIDE_VALUE_CLASS, functionName, context
reporter.reportOn(
innerDeclaration.source, FirErrors.RESERVED_MEMBER_INSIDE_VALUE_CLASS, functionName, context
)
}
}
@@ -111,13 +107,11 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
continue
}
val delegatedTypeRefSource = (innerDeclaration.returnTypeRef as FirResolvedTypeRef).delegatedTypeRef?.source
withSuppressedDiagnostics(innerDeclaration, context) { context ->
reporter.reportOn(
delegatedTypeRefSource,
FirErrors.VALUE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION,
context
)
}
reporter.reportOn(
delegatedTypeRefSource,
FirErrors.VALUE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION,
context
)
}
}
is FirProperty -> {
@@ -126,21 +120,19 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
} else {
when {
innerDeclaration.delegate != null ->
withSuppressedDiagnostics(innerDeclaration, context) { context ->
reporter.reportOn(
innerDeclaration.delegate!!.source,
FirErrors.DELEGATED_PROPERTY_INSIDE_VALUE_CLASS,
context
)
}
innerDeclaration.hasBackingField &&
innerDeclaration.source?.kind !is KtFakeSourceElementKind ->
reporter.reportOnWithSuppression(
innerDeclaration,
FirErrors.PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS,
reporter.reportOn(
innerDeclaration.delegate!!.source,
FirErrors.DELEGATED_PROPERTY_INSIDE_VALUE_CLASS,
context
)
innerDeclaration.hasBackingField &&
innerDeclaration.source?.kind !is KtFakeSourceElementKind -> {
reporter.reportOn(
innerDeclaration.source, FirErrors.PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS,
context
)
}
}
}
}
@@ -155,48 +147,44 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses)) {
if (primaryConstructorParametersByName.isEmpty()) {
reporter.reportOnWithSuppression(primaryConstructor, FirErrors.VALUE_CLASS_EMPTY_CONSTRUCTOR, context)
reporter.reportOn(primaryConstructor.source, FirErrors.VALUE_CLASS_EMPTY_CONSTRUCTOR, context)
return
}
} else if (primaryConstructorParametersByName.size != 1) {
reporter.reportOnWithSuppression(primaryConstructor, FirErrors.INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, context)
reporter.reportOn(primaryConstructor.source, FirErrors.INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, context)
return
}
for ((name, primaryConstructorParameter) in primaryConstructorParametersByName) {
withSuppressedDiagnostics(primaryConstructor, context) { context ->
withSuppressedDiagnostics(primaryConstructorParameter, context) { context ->
when {
primaryConstructorParameter.isNotFinalReadOnly(primaryConstructorPropertiesByName[name]) ->
reporter.reportOn(
primaryConstructorParameter.source,
FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER,
context
)
when {
primaryConstructorParameter.isNotFinalReadOnly(primaryConstructorPropertiesByName[name]) ->
reporter.reportOn(
primaryConstructorParameter.source,
FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER,
context
)
primaryConstructorParameter.returnTypeRef.isInapplicableParameterType() -> {
val inlineClassHasGenericUnderlyingType = primaryConstructorParameter.returnTypeRef.coneType.let {
(it is ConeTypeParameterType || it.isGenericArrayOfTypeParameter())
}
if (!(context.languageVersionSettings.supportsFeature(LanguageFeature.GenericInlineClassParameter) &&
inlineClassHasGenericUnderlyingType)
) {
reporter.reportOn(
primaryConstructorParameter.returnTypeRef.source,
FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE,
primaryConstructorParameter.returnTypeRef.coneType,
context
)
}
}
primaryConstructorParameter.returnTypeRef.coneType.isRecursiveInlineClassType(context.session) ->
reporter.reportOnWithSuppression(
primaryConstructorParameter.returnTypeRef,
FirErrors.VALUE_CLASS_CANNOT_BE_RECURSIVE,
context
)
primaryConstructorParameter.returnTypeRef.isInapplicableParameterType() -> {
val inlineClassHasGenericUnderlyingType = primaryConstructorParameter.returnTypeRef.coneType.let {
(it is ConeTypeParameterType || it.isGenericArrayOfTypeParameter())
}
if (!(context.languageVersionSettings.supportsFeature(LanguageFeature.GenericInlineClassParameter) &&
inlineClassHasGenericUnderlyingType)
) {
reporter.reportOn(
primaryConstructorParameter.returnTypeRef.source,
FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE,
primaryConstructorParameter.returnTypeRef.coneType,
context
)
}
}
primaryConstructorParameter.returnTypeRef.coneType.isRecursiveInlineClassType(context.session) -> {
reporter.reportOn(
primaryConstructorParameter.returnTypeRef.source, FirErrors.VALUE_CLASS_CANNOT_BE_RECURSIVE,
context
)
}
}
}
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.getModifier
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
@@ -54,10 +53,8 @@ abstract class FirInlineDeclarationChecker : FirFunctionChecker() {
if (declaration !is FirPropertyAccessor && declaration !is FirSimpleFunction) return
val effectiveVisibility = declaration.effectiveVisibility
withSuppressedDiagnostics(declaration, context) { ctx ->
checkInlineFunctionBody(declaration, effectiveVisibility, ctx, reporter)
checkCallableDeclaration(declaration, ctx, reporter)
}
checkInlineFunctionBody(declaration, effectiveVisibility, context, reporter)
checkCallableDeclaration(declaration, context, reporter)
}
protected fun checkInlineFunctionBody(
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getModifierList
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.*
@@ -169,61 +168,59 @@ object FirMemberPropertiesChecker : FirClassChecker() {
// So, our source of truth should be the full modifier list retrieved from the source.
val modifierList = property.source.getModifierList()
withSuppressedDiagnostics(property, context) { ctx ->
checkPropertyInitializer(
containingDeclaration,
property,
modifierList,
isInitialized,
reporter,
ctx,
reachable
)
checkExpectDeclarationVisibilityAndBody(property, source, reporter, ctx)
checkPropertyInitializer(
containingDeclaration,
property,
modifierList,
isInitialized,
reporter,
context,
reachable
)
checkExpectDeclarationVisibilityAndBody(property, source, reporter, context)
val hasAbstractModifier = KtTokens.ABSTRACT_KEYWORD in modifierList
val isAbstract = property.isAbstract || hasAbstractModifier
if (containingDeclaration.isInterface &&
Visibilities.isPrivate(property.visibility) &&
!isAbstract &&
(property.getter == null || property.getter is FirDefaultPropertyAccessor)
) {
val hasAbstractModifier = KtTokens.ABSTRACT_KEYWORD in modifierList
val isAbstract = property.isAbstract || hasAbstractModifier
if (containingDeclaration.isInterface &&
Visibilities.isPrivate(property.visibility) &&
!isAbstract &&
(property.getter == null || property.getter is FirDefaultPropertyAccessor)
) {
property.source?.let {
reporter.reportOn(it, FirErrors.PRIVATE_PROPERTY_IN_INTERFACE, context)
}
}
if (isAbstract) {
if (containingDeclaration is FirRegularClass && !containingDeclaration.canHaveAbstractDeclaration) {
property.source?.let {
reporter.reportOn(it, FirErrors.PRIVATE_PROPERTY_IN_INTERFACE, ctx)
reporter.reportOn(
it,
FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS,
property.symbol,
containingDeclaration.symbol,
context
)
return
}
}
if (isAbstract) {
if (containingDeclaration is FirRegularClass && !containingDeclaration.canHaveAbstractDeclaration) {
property.source?.let {
reporter.reportOn(
it,
FirErrors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS,
property.symbol,
containingDeclaration.symbol,
ctx
)
return
}
}
property.initializer?.source?.let {
reporter.reportOn(it, FirErrors.ABSTRACT_PROPERTY_WITH_INITIALIZER, ctx)
}
property.delegate?.source?.let {
reporter.reportOn(it, FirErrors.ABSTRACT_DELEGATED_PROPERTY, ctx)
}
property.initializer?.source?.let {
reporter.reportOn(it, FirErrors.ABSTRACT_PROPERTY_WITH_INITIALIZER, context)
}
property.delegate?.source?.let {
reporter.reportOn(it, FirErrors.ABSTRACT_DELEGATED_PROPERTY, context)
}
}
val hasOpenModifier = KtTokens.OPEN_KEYWORD in modifierList
if (hasOpenModifier &&
containingDeclaration.isInterface &&
!hasAbstractModifier &&
property.isAbstract &&
!isInsideExpectClass(containingDeclaration, ctx)
) {
property.source?.let {
reporter.reportOn(it, FirErrors.REDUNDANT_OPEN_IN_INTERFACE, ctx)
}
val hasOpenModifier = KtTokens.OPEN_KEYWORD in modifierList
if (hasOpenModifier &&
containingDeclaration.isInterface &&
!hasAbstractModifier &&
property.isAbstract &&
!isInsideExpectClass(containingDeclaration, context)
) {
property.source?.let {
reporter.reportOn(it, FirErrors.REDUNDANT_OPEN_IN_INTERFACE, context)
}
}
}
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.utils.hasBody
@@ -49,9 +48,7 @@ object FirMethodOfAnyImplementedInInterfaceChecker : FirRegularClassChecker(), F
}
if (methodOfAny) {
withSuppressedDiagnostics(function, context) {
reporter.reportOn(function.source, FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE, it)
}
reporter.reportOn(function.source, FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE, context)
}
}
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets
import org.jetbrains.kotlin.fir.analysis.checkers.getAnnotationClassForOptInMarker
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
@@ -23,23 +22,21 @@ object FirOptInMarkedDeclarationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
for (annotation in declaration.annotations) {
val annotationClass = annotation.getAnnotationClassForOptInMarker(context.session) ?: continue
withSuppressedDiagnostics(annotation, context) { ctx ->
val useSiteTarget = annotation.useSiteTarget
if ((declaration is FirPropertyAccessor && declaration.isGetter) || useSiteTarget == PROPERTY_GETTER) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "getter", ctx)
}
if (useSiteTarget == SETTER_PARAMETER ||
(useSiteTarget != PROPERTY && useSiteTarget != PROPERTY_SETTER && declaration is FirValueParameter &&
KotlinTarget.VALUE_PARAMETER in annotationClass.getAllowedAnnotationTargets())
) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "parameter", ctx)
}
if (declaration is FirProperty && declaration.isLocal) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "variable", ctx)
}
if (useSiteTarget == FIELD || useSiteTarget == PROPERTY_DELEGATE_FIELD) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "field", ctx)
}
val useSiteTarget = annotation.useSiteTarget
if ((declaration is FirPropertyAccessor && declaration.isGetter) || useSiteTarget == PROPERTY_GETTER) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "getter", context)
}
if (useSiteTarget == SETTER_PARAMETER ||
(useSiteTarget != PROPERTY && useSiteTarget != PROPERTY_SETTER && declaration is FirValueParameter &&
KotlinTarget.VALUE_PARAMETER in annotationClass.getAllowedAnnotationTargets())
) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "parameter", context)
}
if (declaration is FirProperty && declaration.isLocal) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "variable", context)
}
if (useSiteTarget == FIELD || useSiteTarget == PROPERTY_DELEGATE_FIELD) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "field", context)
}
}
}
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseCh
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirOptInUsageBaseChecker.Experimentality
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.analysis.overridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.*
@@ -52,9 +51,7 @@ object FirOverrideChecker : FirClassChecker() {
for (it in declaration.declarations) {
if (it is FirSimpleFunction || it is FirProperty) {
val callable = it as FirCallableDeclaration
withSuppressedDiagnostics(callable, context) {
checkMember(callable.symbol, declaration, reporter, typeCheckerState, firTypeScope, it)
}
checkMember(callable.symbol, declaration, reporter, typeCheckerState, firTypeScope, context)
}
}
}
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
@@ -34,86 +33,73 @@ object FirPropertyAccessorsTypesChecker : FirPropertyChecker() {
val getter = property.getter ?: return
val propertyType = property.returnTypeRef.coneType
withSuppressedDiagnostics(getter, context) { ctx ->
checkAccessorForDelegatedProperty(property, getter, ctx, reporter)
if (getter.visibility != property.visibility) {
reporter.reportOn(getter.source, FirErrors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, ctx)
}
if (property.symbol.callableId.classId != null && getter.body != null && property.delegate == null) {
if (isLegallyAbstract(property, ctx)) {
reporter.reportOn(getter.source, FirErrors.ABSTRACT_PROPERTY_WITH_GETTER, ctx)
}
}
val getterReturnTypeRef = getter.returnTypeRef
if (getterReturnTypeRef.source?.kind is KtFakeSourceElementKind) {
return
}
val getterReturnType = getterReturnTypeRef.coneType
if (propertyType is ConeErrorType || getterReturnType is ConeErrorType) {
return
}
if (getterReturnType != property.returnTypeRef.coneType) {
val getterReturnTypeSource = getterReturnTypeRef.source
withSuppressedDiagnostics(getterReturnTypeRef, ctx) {
reporter.reportOn(getterReturnTypeSource, FirErrors.WRONG_GETTER_RETURN_TYPE, propertyType, getterReturnType, it)
}
checkAccessorForDelegatedProperty(property, getter, context, reporter)
if (getter.visibility != property.visibility) {
reporter.reportOn(getter.source, FirErrors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, context)
}
if (property.symbol.callableId.classId != null && getter.body != null && property.delegate == null) {
if (isLegallyAbstract(property, context)) {
reporter.reportOn(getter.source, FirErrors.ABSTRACT_PROPERTY_WITH_GETTER, context)
}
}
val getterReturnTypeRef = getter.returnTypeRef
if (getterReturnTypeRef.source?.kind is KtFakeSourceElementKind) {
return
}
val getterReturnType = getterReturnTypeRef.coneType
if (propertyType is ConeErrorType || getterReturnType is ConeErrorType) {
return
}
if (getterReturnType != property.returnTypeRef.coneType) {
val getterReturnTypeSource = getterReturnTypeRef.source
reporter.reportOn(getterReturnTypeSource, FirErrors.WRONG_GETTER_RETURN_TYPE, propertyType, getterReturnType, context)
}
}
private fun checkSetter(property: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
val setter = property.setter ?: return
val propertyType = property.returnTypeRef.coneType
withSuppressedDiagnostics(setter, context) { ctx ->
if (property.isVal) {
reporter.reportOn(setter.source, FirErrors.VAL_WITH_SETTER, ctx)
}
checkAccessorForDelegatedProperty(property, setter, ctx, reporter)
val visibilityCompareResult = setter.visibility.compareTo(property.visibility)
if (visibilityCompareResult == null || visibilityCompareResult > 0) {
reporter.reportOn(setter.source, FirErrors.SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY, ctx)
}
if (property.symbol.callableId.classId != null && property.delegate == null) {
val isLegallyAbstract = isLegallyAbstract(property, ctx)
if (setter.visibility == Visibilities.Private && property.visibility != Visibilities.Private) {
if (isLegallyAbstract) {
reporter.reportOn(setter.source, FirErrors.PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY, ctx)
} else if (property.isOpen) {
reporter.reportOn(setter.source, FirErrors.PRIVATE_SETTER_FOR_OPEN_PROPERTY, ctx)
}
}
if (isLegallyAbstract && setter.body != null) {
reporter.reportOn(setter.source, FirErrors.ABSTRACT_PROPERTY_WITH_SETTER, ctx)
if (property.isVal) {
reporter.reportOn(setter.source, FirErrors.VAL_WITH_SETTER, context)
}
checkAccessorForDelegatedProperty(property, setter, context, reporter)
val visibilityCompareResult = setter.visibility.compareTo(property.visibility)
if (visibilityCompareResult == null || visibilityCompareResult > 0) {
reporter.reportOn(setter.source, FirErrors.SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY, context)
}
if (property.symbol.callableId.classId != null && property.delegate == null) {
val isLegallyAbstract = isLegallyAbstract(property, context)
if (setter.visibility == Visibilities.Private && property.visibility != Visibilities.Private) {
if (isLegallyAbstract) {
reporter.reportOn(setter.source, FirErrors.PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY, context)
} else if (property.isOpen) {
reporter.reportOn(setter.source, FirErrors.PRIVATE_SETTER_FOR_OPEN_PROPERTY, context)
}
}
if (isLegallyAbstract && setter.body != null) {
reporter.reportOn(setter.source, FirErrors.ABSTRACT_PROPERTY_WITH_SETTER, context)
}
}
val valueSetterParameter = setter.valueParameters.first()
if (valueSetterParameter.isVararg) {
return
}
val valueSetterType = valueSetterParameter.returnTypeRef.coneType
val valueSetterTypeSource = valueSetterParameter.returnTypeRef.source
if (propertyType is ConeErrorType || valueSetterType is ConeErrorType) {
return
}
val valueSetterParameter = setter.valueParameters.first()
if (valueSetterParameter.isVararg) {
return
}
val valueSetterType = valueSetterParameter.returnTypeRef.coneType
val valueSetterTypeSource = valueSetterParameter.returnTypeRef.source
if (propertyType is ConeErrorType || valueSetterType is ConeErrorType) {
return
}
if (valueSetterType != propertyType) {
withSuppressedDiagnostics(valueSetterParameter, ctx) {
reporter.reportOn(valueSetterTypeSource, FirErrors.WRONG_SETTER_PARAMETER_TYPE, propertyType, valueSetterType, ctx)
}
}
if (valueSetterType != propertyType) {
reporter.reportOn(valueSetterTypeSource, FirErrors.WRONG_SETTER_PARAMETER_TYPE, propertyType, valueSetterType, context)
}
val setterReturnType = setter.returnTypeRef.coneType
if (propertyType is ConeErrorType || valueSetterType is ConeErrorType) {
return
}
val setterReturnType = setter.returnTypeRef.coneType
if (!setterReturnType.isUnit) {
withSuppressedDiagnostics(setter.returnTypeRef, ctx) {
reporter.reportOn(setter.returnTypeRef.source, FirErrors.WRONG_SETTER_RETURN_TYPE, ctx)
}
}
if (!setterReturnType.isUnit) {
reporter.reportOn(setter.returnTypeRef.source, FirErrors.WRONG_SETTER_RETURN_TYPE, context)
}
}
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirField
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
@@ -41,59 +40,57 @@ object FirSupertypesChecker : FirClassChecker() {
var classAppeared = false
val superClassSymbols = hashSetOf<FirRegularClassSymbol>()
for (superTypeRef in declaration.superTypeRefs) {
withSuppressedDiagnostics(superTypeRef, context) { ctx ->
val coneType = superTypeRef.coneType
if (!nullableSupertypeReported && coneType.nullability == ConeNullability.NULLABLE) {
reporter.reportOn(superTypeRef.source, FirErrors.NULLABLE_SUPERTYPE, ctx)
nullableSupertypeReported = true
}
if (!extensionFunctionSupertypeReported && coneType.isExtensionFunctionType &&
!ctx.session.languageVersionSettings.supportsFeature(LanguageFeature.FunctionalTypeWithExtensionAsSupertype)
) {
reporter.reportOn(superTypeRef.source, FirErrors.SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE, ctx)
extensionFunctionSupertypeReported = true
}
val lookupTag = coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: return@withSuppressedDiagnostics
val superTypeSymbol = lookupTag.toSymbol(ctx.session)
val coneType = superTypeRef.coneType
if (!nullableSupertypeReported && coneType.nullability == ConeNullability.NULLABLE) {
reporter.reportOn(superTypeRef.source, FirErrors.NULLABLE_SUPERTYPE, context)
nullableSupertypeReported = true
}
if (!extensionFunctionSupertypeReported && coneType.isExtensionFunctionType &&
!context.session.languageVersionSettings.supportsFeature(LanguageFeature.FunctionalTypeWithExtensionAsSupertype)
) {
reporter.reportOn(superTypeRef.source, FirErrors.SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE, context)
extensionFunctionSupertypeReported = true
}
val lookupTag = coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: continue
val superTypeSymbol = lookupTag.toSymbol(context.session)
if (superTypeSymbol is FirRegularClassSymbol) {
if (!superClassSymbols.add(superTypeSymbol)) {
reporter.reportOn(superTypeRef.source, FirErrors.SUPERTYPE_APPEARS_TWICE, ctx)
if (superTypeSymbol is FirRegularClassSymbol) {
if (!superClassSymbols.add(superTypeSymbol)) {
reporter.reportOn(superTypeRef.source, FirErrors.SUPERTYPE_APPEARS_TWICE, context)
}
if (superTypeSymbol.classKind != ClassKind.INTERFACE) {
if (classAppeared) {
reporter.reportOn(superTypeRef.source, FirErrors.MANY_CLASSES_IN_SUPERTYPE_LIST, context)
} else {
classAppeared = true
}
if (superTypeSymbol.classKind != ClassKind.INTERFACE) {
if (classAppeared) {
reporter.reportOn(superTypeRef.source, FirErrors.MANY_CLASSES_IN_SUPERTYPE_LIST, ctx)
} else {
classAppeared = true
}
if (!interfaceWithSuperclassReported) {
reporter.reportOn(superTypeRef.source, FirErrors.INTERFACE_WITH_SUPERCLASS, ctx)
interfaceWithSuperclassReported = true
}
}
val isObject = superTypeSymbol.classKind == ClassKind.OBJECT
if (!finalSupertypeReported && !isObject && superTypeSymbol.modality == Modality.FINAL) {
reporter.reportOn(superTypeRef.source, FirErrors.FINAL_SUPERTYPE, ctx)
finalSupertypeReported = true
}
if (!singletonInSupertypeReported && isObject) {
reporter.reportOn(superTypeRef.source, FirErrors.SINGLETON_IN_SUPERTYPE, ctx)
singletonInSupertypeReported = true
if (!interfaceWithSuperclassReported) {
reporter.reportOn(superTypeRef.source, FirErrors.INTERFACE_WITH_SUPERCLASS, context)
interfaceWithSuperclassReported = true
}
}
checkAnnotationOnSuperclass(superTypeRef, ctx, reporter)
val fullyExpandedType = coneType.fullyExpandedType(ctx.session)
val symbol = fullyExpandedType.toSymbol(ctx.session)
checkClassCannotBeExtendedDirectly(symbol, reporter, superTypeRef, ctx)
if (coneType.typeArguments.isNotEmpty()) {
checkProjectionInImmediateArgumentToSupertype(coneType, superTypeRef, reporter, ctx)
} else {
checkExpandedTypeCannotBeInherited(symbol, fullyExpandedType, reporter, superTypeRef, coneType, ctx)
val isObject = superTypeSymbol.classKind == ClassKind.OBJECT
if (!finalSupertypeReported && !isObject && superTypeSymbol.modality == Modality.FINAL) {
reporter.reportOn(superTypeRef.source, FirErrors.FINAL_SUPERTYPE, context)
finalSupertypeReported = true
}
if (!singletonInSupertypeReported && isObject) {
reporter.reportOn(superTypeRef.source, FirErrors.SINGLETON_IN_SUPERTYPE, context)
singletonInSupertypeReported = true
}
}
checkAnnotationOnSuperclass(superTypeRef, context, reporter)
val fullyExpandedType = coneType.fullyExpandedType(context.session)
val symbol = fullyExpandedType.toSymbol(context.session)
checkClassCannotBeExtendedDirectly(symbol, reporter, superTypeRef, context)
if (coneType.typeArguments.isNotEmpty()) {
checkProjectionInImmediateArgumentToSupertype(coneType, superTypeRef, reporter, context)
} else {
checkExpandedTypeCannotBeInherited(symbol, fullyExpandedType, reporter, superTypeRef, coneType, context)
}
}
@@ -110,10 +107,8 @@ object FirSupertypesChecker : FirClassChecker() {
reporter: DiagnosticReporter
) {
for (annotation in superTypeRef.annotations) {
withSuppressedDiagnostics(annotation, context) {
if (annotation.useSiteTarget != null) {
reporter.reportOn(annotation.source, FirErrors.ANNOTATION_ON_SUPERCLASS, it)
}
if (annotation.useSiteTarget != null) {
reporter.reportOn(annotation.source, FirErrors.ANNOTATION_ON_SUPERCLASS, context)
}
}
}
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.contains
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getModifierList
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.FirProperty
@@ -39,17 +38,15 @@ object FirTopLevelPropertiesChecker : FirPropertyChecker() {
// So, our source of truth should be the full modifier list retrieved from the source.
val modifierList = source.getModifierList()
withSuppressedDiagnostics(declaration, context) { ctx ->
checkPropertyInitializer(
containingClass = null,
declaration,
modifierList,
isInitialized = declaration.initializer != null,
reporter,
ctx
)
checkExpectDeclarationVisibilityAndBody(declaration, source, reporter, ctx)
}
checkPropertyInitializer(
containingClass = null,
declaration,
modifierList,
isInitialized = declaration.initializer != null,
reporter,
context
)
checkExpectDeclarationVisibilityAndBody(declaration, source, reporter, context)
}
}
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getDefaultUseSiteTarget
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.expressions.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -43,14 +42,12 @@ object FirExpressionAnnotationChecker : FirBasicExpressionChecker() {
val useSiteTarget = annotation.useSiteTarget ?: expression.getDefaultUseSiteTarget(annotation, context)
val existingTargetsForAnnotation = annotationsMap.getOrPut(annotation.annotationTypeRef.coneType) { arrayListOf() }
withSuppressedDiagnostics(annotation, context) { ctx ->
if (KotlinTarget.EXPRESSION !in annotation.getAllowedAnnotationTargets(ctx.session)) {
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "expression", ctx)
}
checkRepeatedAnnotation(useSiteTarget, existingTargetsForAnnotation, annotation, ctx, reporter)
if (KotlinTarget.EXPRESSION !in annotation.getAllowedAnnotationTargets(context.session)) {
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "expression", context)
}
checkRepeatedAnnotation(useSiteTarget, existingTargetsForAnnotation, annotation, context, reporter)
existingTargetsForAnnotation.add(useSiteTarget)
}
}
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.checkCondition
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.expressions.FirErrorLoop
import org.jetbrains.kotlin.fir.expressions.FirLoop
@@ -16,8 +15,6 @@ object FirLoopConditionChecker : FirLoopExpressionChecker() {
override fun check(expression: FirLoop, context: CheckerContext, reporter: DiagnosticReporter) {
if (expression is FirErrorLoop) return
val condition = expression.condition
withSuppressedDiagnostics(condition, context) {
checkCondition(condition, it, reporter)
}
checkCondition(condition, context, reporter)
}
}
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
@@ -24,9 +23,7 @@ object FirWhenConditionChecker : FirWhenExpressionChecker() {
for (branch in expression.branches) {
val condition = branch.condition
if (condition is FirElseIfTrueCondition) continue
withSuppressedDiagnostics(condition, context) {
checkCondition(condition, it, reporter)
}
checkCondition(condition, context, reporter)
}
if (expression.subject != null) {
checkDuplicatedLabels(expression, context, reporter)
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPT_IN_CAN_ONLY_BE_USED_AS_ANNOTATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPT_IN_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION_OR_ARGUMENT_IN_OPT_IN
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
@@ -39,9 +38,7 @@ object FirOptInUsageTypeRefChecker : FirTypeRefChecker() {
for (annotation in typeRef.annotations) {
if (annotation.getAnnotationClassForOptInMarker(context.session) != null) {
if (annotation.useSiteTarget == AnnotationUseSiteTarget.RECEIVER) {
withSuppressedDiagnostics(annotation, context) {
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "parameter", it)
}
reporter.reportOn(annotation.source, FirErrors.OPT_IN_MARKER_ON_WRONG_TARGET, "parameter", context)
}
}
}
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.getAllowedAnnotationTargets
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.expressions.classId
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
@@ -24,13 +23,11 @@ object FirTypeAnnotationChecker : FirTypeRefChecker() {
if (typeRef !is FirResolvedTypeRef) return
for (annotation in typeRef.annotations) {
withSuppressedDiagnostics(annotation, context) {
val annotationTargets = annotation.getAllowedAnnotationTargets(context.session)
if (KotlinTarget.TYPE !in annotationTargets) {
val useSiteTarget = annotation.useSiteTarget
if (useSiteTarget == null || KotlinTarget.USE_SITE_MAPPING[useSiteTarget] !in annotationTargets) {
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "type usage", it)
}
val annotationTargets = annotation.getAllowedAnnotationTargets(context.session)
if (KotlinTarget.TYPE !in annotationTargets) {
val useSiteTarget = annotation.useSiteTarget
if (useSiteTarget == null || KotlinTarget.USE_SITE_MAPPING[useSiteTarget] !in annotationTargets) {
reporter.reportOn(annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, "type usage", context)
}
}
if (annotation.classId == StandardClassIds.Annotations.ExtensionFunctionType) {
@@ -1,96 +0,0 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.diagnostics.*
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
fun DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory0,
context: MutableDiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, it, positioningStrategy)
}
}
fun <A : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory1<A>,
a: A,
context: MutableDiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, it, positioningStrategy)
}
}
fun <A : Any, B : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory2<A, B>,
a: A,
b: B,
context: MutableDiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, it, positioningStrategy)
}
}
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory3<A, B, C>,
a: A,
b: B,
c: C,
context: MutableDiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, it, positioningStrategy)
}
}
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOnWithSuppression(
element: FirAnnotationContainer,
factory: KtDiagnosticFactory4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: MutableDiagnosticContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
withSuppressedDiagnostics(element, context) {
reportOn(element.source, factory, a, b, c, d, it, positioningStrategy)
}
}
inline fun <reified C : MutableDiagnosticContext> withSuppressedDiagnostics(
annotationContainer: FirAnnotationContainer,
context: C,
f: (C) -> Unit
) {
val arguments = AbstractDiagnosticCollector.getDiagnosticsSuppressedForContainer(annotationContainer)
if (arguments != null) {
f(
context.addSuppressedDiagnostics(
arguments,
allInfosSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_INFOS in arguments,
allWarningsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_WARNINGS in arguments,
allErrorsSuppressed = AbstractDiagnosticCollector.SUPPRESS_ALL_ERRORS in arguments
) as C
)
return
}
f(context)
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChec
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.InternalDiagnosticFactoryMethod
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.argumentMapping
import org.jetbrains.kotlin.fir.plugin.types.ConeNumberSignAttribute
@@ -25,9 +24,9 @@ object SignedNumberCallChecker : FirFunctionCallChecker() {
val expectedSign = parameter.returnTypeRef.coneType.attributes.numberSign ?: continue
val actualSign = argument.typeRef.coneType.attributes.numberSign
if (expectedSign != actualSign) {
withSuppressedDiagnostics(argument, context) {
reporter.reportOn(argument.source, PluginErrors.ILLEGAL_NUMBER_SIGN, expectedSign.asString(), actualSign.asString(), it)
}
reporter.reportOn(
argument.source, PluginErrors.ILLEGAL_NUMBER_SIGN, expectedSign.asString(), actualSign.asString(), context
)
}
}
}
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirClassChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.constructors
@@ -105,15 +104,13 @@ object FirParcelizeClassChecker : FirClassChecker() {
private fun checkParcelerClass(klass: FirClass, context: CheckerContext, reporter: DiagnosticReporter) {
if (klass !is FirRegularClass || klass.isCompanion) return
for (superTypeRef in klass.superTypeRefs) {
withSuppressedDiagnostics(superTypeRef, context) {
if (superTypeRef.coneType.classId == OLD_PARCELER_ID) {
val strategy = if (klass.name == SpecialNames.NO_NAME_PROVIDED) {
SourceElementPositioningStrategies.OBJECT_KEYWORD
} else {
SourceElementPositioningStrategies.NAME_IDENTIFIER
}
reporter.reportOn(klass.source, KtErrorsParcelize.DEPRECATED_PARCELER, it, positioningStrategy = strategy)
if (superTypeRef.coneType.classId == OLD_PARCELER_ID) {
val strategy = if (klass.name == SpecialNames.NO_NAME_PROVIDED) {
SourceElementPositioningStrategies.OBJECT_KEYWORD
} else {
SourceElementPositioningStrategies.NAME_IDENTIFIER
}
reporter.reportOn(klass.source, KtErrorsParcelize.DEPRECATED_PARCELER, context, positioningStrategy = strategy)
}
}
}