From f15f5bccc8239558d4bd674e1568c343ee5a7f3c Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 5 Aug 2020 09:35:10 +0300 Subject: [PATCH] [FIR] Add more diagnostic messages --- .../FirLocalEntityNotAllowedChecker.kt | 13 +- ...upertypeExtendedByOtherSupertypeChecker.kt | 17 ++- .../FirUpperBoundViolatedChecker.kt | 10 +- .../ErrorNodeDiagnosticCollectorComponent.kt | 3 +- .../diagnostics/FirDefaultErrorMessages.kt | 112 ++++++++++++++++-- .../fir/analysis/diagnostics/FirErrors.kt | 27 +++-- .../fir/resolve/diagnostics/FirDiagnostics.kt | 5 + .../providers/impl/FirTypeResolverImpl.kt | 5 +- .../fir/diagnostics/ConeSimpleDiagnostic.kt | 1 - 9 files changed, 151 insertions(+), 42 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt index 80bdbed971c..a84c00ea908 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirLocalEntityNotAllowedChecker.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.name.Name object FirLocalEntityNotAllowedChecker : FirBasicDeclarationChecker() { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { @@ -20,18 +21,18 @@ object FirLocalEntityNotAllowedChecker : FirBasicDeclarationChecker() { } when { - declaration.classKind == ClassKind.OBJECT && !declaration.isCompanion -> reporter.reportLocalObjectNotAllowed(declaration.source) - declaration.classKind == ClassKind.INTERFACE -> reporter.reportLocalInterfaceNotAllowed(declaration.source) + declaration.classKind == ClassKind.OBJECT && !declaration.isCompanion -> reporter.reportLocalObjectNotAllowed(declaration.source, declaration.name) + declaration.classKind == ClassKind.INTERFACE -> reporter.reportLocalInterfaceNotAllowed(declaration.source, declaration.name) else -> { } } } - private fun DiagnosticReporter.reportLocalObjectNotAllowed(source: FirSourceElement?) { - source?.let { report(FirErrors.LOCAL_OBJECT_NOT_ALLOWED.on(it)) } + private fun DiagnosticReporter.reportLocalObjectNotAllowed(source: FirSourceElement?, name: Name) { + source?.let { report(FirErrors.LOCAL_OBJECT_NOT_ALLOWED.on(it, name)) } } - private fun DiagnosticReporter.reportLocalInterfaceNotAllowed(source: FirSourceElement?) { - source?.let { report(FirErrors.LOCAL_INTERFACE_NOT_ALLOWED.on(it)) } + private fun DiagnosticReporter.reportLocalInterfaceNotAllowed(source: FirSourceElement?, name: Name) { + source?.let { report(FirErrors.LOCAL_INTERFACE_NOT_ALLOWED.on(it, name)) } } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt index 2de17d7c3d4..0e75cba0538 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt @@ -38,13 +38,20 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess // have `explicitType` as their supertype or // equal to it var count = 0 + var candidate: FirClass<*>? = null for (it in surroundingType.superTypeRefs) { val that = it.firClassLike(context.session) ?.followAllAlias(context.session).safeAs>() ?: continue - if (explicitType == that || explicitType.isSupertypeOf(that)) { + val isSupertype = explicitType.isSupertypeOf(that) + + if (explicitType == that || isSupertype) { + if (isSupertype) { + candidate = that + } + count += 1 if (count >= 2) { @@ -53,14 +60,14 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess } } - if (count >= 2) { - reporter.report(superReference.superTypeRef.source) + if (count >= 2 && candidate != null) { + reporter.report(superReference.superTypeRef.source, candidate) } } - private fun DiagnosticReporter.report(source: FirSourceElement?) { + private fun DiagnosticReporter.report(source: FirSourceElement?, candidate: FirClass<*>) { source?.let { - report(FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE.on(it)) + report(FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE.on(it, candidate)) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt index e1faa222081..d237593645a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt @@ -68,7 +68,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { } if (!satisfiesBounds(proto, actual.type, substitutor, typeCheckerContext)) { - reporter.report(actual.source) + reporter.report(actual.source, proto, actual.type) return } @@ -158,7 +158,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { val satisfiesBounds = AbstractTypeChecker.isSubtypeOf(typeCheckerContext, target, intersection) if (!satisfiesBounds) { - reporter.report(functionCall.source) + reporter.report(functionCall.source, proto, actual) return } } @@ -203,7 +203,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { parameterPairs.forEach { (proto, actual) -> if (!satisfiesBounds(proto, actual.type, substitutor, typeCheckerContext)) { // should report on the parameter instead! - reporter.report(reportTarget) + reporter.report(reportTarget, proto, actual) return true } @@ -235,9 +235,9 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { return AbstractTypeChecker.isSubtypeOf(typeCheckerContext, target, intersection) } - private fun DiagnosticReporter.report(source: FirSourceElement?) { + private fun DiagnosticReporter.report(source: FirSourceElement?, proto: FirTypeParameterSymbol, actual: ConeKotlinType) { source?.let { - report(FirErrors.UPPER_BOUND_VIOLATED.on(it)) + report(FirErrors.UPPER_BOUND_VIOLATED.on(it, proto, actual)) } } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index 2bcd71f1201..f7f5d61e037 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -88,6 +88,8 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.on(source, diagnostic.expectedType, diagnostic.actualType) is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(diagnostic.source.safeAs() ?: source) is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.on(source, diagnostic.name.asString()) + is ConeWrongNumberOfTypeArgumentsError -> + FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(source, diagnostic.desiredCount, diagnostic.type) is ConeSimpleDiagnostic -> if (source.kind is FirFakeSourceElementKind) { null } else if (diagnostic.kind == SymbolNotFound) { @@ -118,7 +120,6 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect RecursionInImplicitTypes -> FirErrors.RECURSION_IN_IMPLICIT_TYPES Java -> FirErrors.ERROR_FROM_JAVA_RESOLUTION SuperNotAllowed -> FirErrors.SUPER_IS_NOT_AN_EXPRESSION - WrongNumberOfTypeArguments -> FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS ExpressionRequired -> FirErrors.EXPRESSION_REQUIRED JumpOutsideLoop -> FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP NotLoopLabel -> FirErrors.NOT_A_LOOP_LABEL diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 0d9dab0c32e..45de071791f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -7,44 +7,81 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.PROPERTY_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_SUPER_CALL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUITY +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_CLASS_MEMBER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_OBJECT +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DEPRECATED_MODIFIER_PAIR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ENUM_AS_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ERROR_FROM_JAVA_RESOLUTION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPLICIT_DELEGATION_CALL_REQUIRED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_FUNCTION_RETURN_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PARAMETER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_PROPERTY_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_RECEIVER_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_CLASS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXPRESSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CANDIDATE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_INFIX_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODIFIERS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_INTERFACE_NOT_ALLOWED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_OBJECT_NOT_ALLOWED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_COMPANION_OBJECTS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NONE_APPLICABLE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_SEALED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_SUPERTYPE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_TYPE_FOR_TYPE_PARAMETER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_IMPLICIT_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_SUPERTYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_MODIFIER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_NOT_ALLOWED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_IS_NOT_AN_EXPRESSION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPER_NOT_AVAILABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SYNTAX_ERROR +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VARIABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_REFERENCE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_EXPECTED +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAR_ANNOTATION_PARAMETER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS @Suppress("unused") class FirDefaultErrorMessages : DefaultErrorMessages.Extension { @@ -53,6 +90,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { } companion object { + // * - The old FE reports these diagnostics with additional parameters + // & - New diagnostic that has no analogues in the old FE + // + - Better message required val MAP = FirDiagnosticFactoryToRendererMap("FIR").also { map -> // Miscellaneous map.put(SYNTAX_ERROR, "Syntax error") @@ -61,6 +101,11 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { // General syntax map.put(ILLEGAL_CONST_EXPRESSION, "Illegal const expression") map.put(ILLEGAL_UNDERSCORE, "Illegal underscore") +// map.put(EXPRESSION_REQUIRED, ...) // & + map.put(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP, "'break' and 'continue' are only allowed inside a loop") + map.put(NOT_A_LOOP_LABEL, "The label does not denote a loop") // * + map.put(VARIABLE_EXPECTED, "Variable expected") + map.put(RETURN_NOT_ALLOWED, "'return' is not allowed here") // Unresolved map.put(HIDDEN, "Symbol {0} is invisible", SYMBOL) @@ -68,29 +113,56 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(UNRESOLVED_LABEL, "Unresolved label") map.put(DESERIALIZATION_ERROR, "Deserialization error") map.put(ERROR_FROM_JAVA_RESOLUTION, "Java resolution error") +// map.put(UNKNOWN_CALLABLE_KIND, ...) // & +// map.put(MISSING_STDLIB_CLASS, ...) // & // Super map.put(SUPER_IS_NOT_AN_EXPRESSION, "Super cannot be a callee") + map.put(SUPER_NOT_AVAILABLE, "No supertypes are accessible in this context") + map.put(ABSTRACT_SUPER_CALL, "Abstract member cannot be accessed directly") // Supertypes map.put(TYPE_PARAMETER_AS_SUPERTYPE, "Type parameter as supertype") map.put(ENUM_AS_SUPERTYPE, "Enum as supertype") map.put(RECURSION_IN_SUPERTYPES, "Recursion in supertypes") + map.put(NOT_A_SUPERTYPE, "Not an immediate supertype") + map.put(SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE, "Superclass is not accessible from interface") + map.put(QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE, "Explicitly qualified supertype is extended by another supertype ''{0}''", TO_STRING) // Constructor problems + map.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects") + map.put(CONSTRUCTOR_IN_INTERFACE, "An interface may not have a constructor") + map.put(NON_PRIVATE_CONSTRUCTOR_IN_ENUM, "Constructor must be private in enum class") + map.put(NON_PRIVATE_CONSTRUCTOR_IN_SEALED, "Constructor must be private in sealed class") + map.put(CYCLIC_CONSTRUCTOR_DELEGATION_CALL, "There's a cycle in the delegation calls chain") + map.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED, "Primary constructor call expected") + map.put(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, "Supertype initialization is impossible without primary constructor") + map.put(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR, "Call to super is not allowed in enum constructor") + map.put(PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, "Primary constructor required for data class") + map.put(EXPLICIT_DELEGATION_CALL_REQUIRED, "Explicit 'this' or 'super' call is required. There is no constructor in superclass that can be called without arguments") // Annotations + map.put(ANNOTATION_CLASS_MEMBER, "Members are not allowed in annotation class") + map.put(ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT, "Default value of annotation parameter must be a compile-time constant") + map.put(LOCAL_ANNOTATION_CLASS_ERROR, "Annotation class cannot be local") + map.put(MISSING_VAL_ON_ANNOTATION_PARAMETER, "'val' keyword is missing on annotation parameter") + map.put(NULLABLE_TYPE_OF_ANNOTATION_MEMBER, "An annotation parameter cannot be nullable") + map.put(INVALID_TYPE_OF_ANNOTATION_MEMBER, "Invalid type of annotation member") + map.put(VAR_ANNOTATION_PARAMETER, "An annotation parameter cannot be 'var'") map.put(NOT_AN_ANNOTATION_CLASS, "Illegal annotation class: {0}", NULLABLE_STRING) // Exposed visibility group - map.put(EXPOSED_TYPEALIAS_EXPANDED_TYPE, "{0} typealias exposes {2} in expanded type {1}", TO_STRING, DECLARATION_NAME, TO_STRING) - map.put(EXPOSED_FUNCTION_RETURN_TYPE, "{0} function exposes its {2} return type {1}", TO_STRING, DECLARATION_NAME, TO_STRING) - map.put(EXPOSED_RECEIVER_TYPE, "{0} member exposes its {2} receiver type {1}", TO_STRING, DECLARATION_NAME, TO_STRING) - map.put(EXPOSED_PROPERTY_TYPE, "{0} property exposes its {2} type {1}", TO_STRING, DECLARATION_NAME, TO_STRING) - map.put(EXPOSED_PARAMETER_TYPE, "{0} function exposes its {2} parameter type {1}", TO_STRING, DECLARATION_NAME, TO_STRING) - map.put(EXPOSED_SUPER_CLASS, "{0} subclass exposes its {2} supertype {1}", TO_STRING, DECLARATION_NAME, TO_STRING) + map.put(EXPOSED_TYPEALIAS_EXPANDED_TYPE, "{0} typealias exposes {2} in expanded type{1}", TO_STRING, TO_STRING, TO_STRING) + map.put(EXPOSED_FUNCTION_RETURN_TYPE, "{0} function exposes its {2} return type{1}", TO_STRING, TO_STRING, TO_STRING) + map.put(EXPOSED_RECEIVER_TYPE, "{0} member exposes its {2} receiver type{1}", TO_STRING, TO_STRING, TO_STRING) + map.put(EXPOSED_PROPERTY_TYPE, "{0} property exposes its {2} type{1}", TO_STRING, TO_STRING, TO_STRING) + map.put(EXPOSED_PARAMETER_TYPE, "{0} function exposes its {2} parameter type{1}", TO_STRING, TO_STRING, TO_STRING) + map.put(EXPOSED_SUPER_INTERFACE, "''{0}'' sub-interface exposes its ''{2}'' supertype{1}", TO_STRING, TO_STRING, TO_STRING) + map.put(EXPOSED_SUPER_CLASS, "''{0}'' subclass exposes its ''{2}'' supertype{1}", TO_STRING, TO_STRING, TO_STRING) + map.put(EXPOSED_TYPE_PARAMETER_BOUND, "''{0}'' generic exposes its ''{2}'' parameter bound type{1}", TO_STRING, TO_STRING, TO_STRING) // Modifiers + map.put(INAPPLICABLE_INFIX_MODIFIER, "''infix'' modifier is inapplicable on this function: {0}", TO_STRING) map.put(REPEATED_MODIFIER, "Repeated ''{0}''", TO_STRING) map.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING) map.put(DEPRECATED_MODIFIER_PAIR, "Modifier ''{0}'' is deprecated in presence of ''{1}''", TO_STRING, TO_STRING) @@ -105,17 +177,39 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(ASSIGN_OPERATOR_AMBIGUITY, "Ambiguity between assign operator candidates: {0}", SYMBOLS) // Types & type parameters + map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING) map.put(RECURSION_IN_IMPLICIT_TYPES, "Recursion in implicit types") map.put(INFERENCE_ERROR, "Inference error") + map.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties") + map.put(UPPER_BOUND_VIOLATED, "Type argument is not within its bounds: should be subtype of ''{0}''", TO_STRING, TO_STRING) + map.put(TYPE_ARGUMENTS_NOT_ALLOWED, "Type arguments are not allowed for type parameters") // * + map.put(WRONG_NUMBER_OF_TYPE_ARGUMENTS, "{0,choice,0#No type arguments|1#One type argument|1<{0,number,integer} type arguments} expected for {1}", null, TO_STRING) + map.put(NO_TYPE_FOR_TYPE_PARAMETER, "There're no types suitable for this type parameter") // & + map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects") +// map.put(ILLEGAL_PROJECTION_USAGE, ...) // & // Redeclarations + map.put(MANY_COMPANION_OBJECTS, "Only one companion object is allowed per class") // Invalid local declarations + map.put(LOCAL_OBJECT_NOT_ALLOWED, "Named object ''{0}'' is a singleton and cannot be local. Try to use anonymous object instead", TO_STRING) // + + map.put(LOCAL_INTERFACE_NOT_ALLOWED, "''{0}'' is an interface so it cannot be local. Try to use anonymous object or abstract class instead", TO_STRING) // Control flow diagnostics map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME) // Extended checkers group +// map.put(REDUNDANT_VISIBILITY_MODIFIER, ...) // & +// map.put(REDUNDANT_MODALITY_MODIFIER, ...) // & +// map.put(REDUNDANT_RETURN_UNIT_TYPE, ...) // & +// map.put(REDUNDANT_EXPLICIT_TYPE, ...) // & +// map.put(REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE, ...) // & +// map.put(CAN_BE_VAL, ...) // & +// map.put(CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT, ...) // & +// map.put(REDUNDANT_CALL_OF_CONVERSION_METHOD, ...) // & +// map.put(ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS, ...) // & +// map.put(EMPTY_RANGE, ...) // & +// map.put(REDUNDANT_SETTER_PARAMETER_TYPE, ...) // & } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 3a1ad482f76..c763a1e2f40 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -10,11 +10,15 @@ import com.intellij.psi.PsiTypeElement import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.fir.FirEffectiveVisibility import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtModifierKeywordToken +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* object FirErrors { @@ -51,13 +55,19 @@ object FirErrors { val RECURSION_IN_SUPERTYPES by error0() val NOT_A_SUPERTYPE by error0() val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0() - val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error0() + val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error1>() // Constructor problems val CONSTRUCTOR_IN_OBJECT by existing(Errors.CONSTRUCTOR_IN_OBJECT) val CONSTRUCTOR_IN_INTERFACE by existing(Errors.CONSTRUCTOR_IN_INTERFACE) val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by existing(Errors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM) val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by existing(Errors.NON_PRIVATE_CONSTRUCTOR_IN_SEALED) + val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning0() + val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0() + val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0() + val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0() + val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning0() + val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0() // Annotations val ANNOTATION_CLASS_MEMBER by existing(Errors.ANNOTATION_CLASS_MEMBER) @@ -69,13 +79,6 @@ object FirErrors { val VAR_ANNOTATION_PARAMETER by existing(Errors.VAR_ANNOTATION_PARAMETER) val NOT_AN_ANNOTATION_CLASS by error1() - val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning0() - val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0() - val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0() - val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0() - val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning0() - val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0() - // Exposed visibility group val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3() val EXPOSED_FUNCTION_RETURN_TYPE by error3() @@ -106,9 +109,9 @@ object FirErrors { val RECURSION_IN_IMPLICIT_TYPES by error0() val INFERENCE_ERROR by error0() val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error0() - val UPPER_BOUND_VIOLATED by error0() + val UPPER_BOUND_VIOLATED by error2() val TYPE_ARGUMENTS_NOT_ALLOWED by error0() - val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error0() + val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2() val NO_TYPE_FOR_TYPE_PARAMETER by error0() val TYPE_PARAMETERS_IN_OBJECT by error0() val ILLEGAL_PROJECTION_USAGE by error0() @@ -117,8 +120,8 @@ object FirErrors { val MANY_COMPANION_OBJECTS by error0() // Invalid local declarations - val LOCAL_OBJECT_NOT_ALLOWED by error0() - val LOCAL_INTERFACE_NOT_ALLOWED by error0() + val LOCAL_OBJECT_NOT_ALLOWED by error1() + val LOCAL_INTERFACE_NOT_ALLOWED by error1() // Control flow diagnostics val UNINITIALIZED_VARIABLE by error1() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index bf6e50341e9..c8084e97cd5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.CandidateApplicability import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -71,6 +72,10 @@ class ConeIllegalAnnotationError(val name: Name) : ConeDiagnostic() { override val reason: String get() = "Not a legal annotation: $name" } +class ConeWrongNumberOfTypeArgumentsError(val desiredCount: Int, val type: FirRegularClassSymbol) : ConeDiagnostic() { + override val reason: String get() = "Wrong number of type arguments" +} + private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String { return when (symbol) { is FirClassLikeSymbol<*> -> symbol.classId.asString() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index 4ebae6b324d..de558423482 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.* +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeWrongNumberOfTypeArgumentsError import org.jetbrains.kotlin.fir.resolve.providers.bindSymbolToLookupTag import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.scopes.FirScope @@ -115,9 +116,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver { val n = symbol.fir.typeParameters.size - typeArguments.size if (n < 0) { typeArguments = (1..symbol.fir.typeParameters.size).map { - ConeClassErrorType( - ConeSimpleDiagnostic("Type arguments number mismatch", DiagnosticKind.WrongNumberOfTypeArguments) - ) + ConeClassErrorType(ConeWrongNumberOfTypeArgumentsError(typeArguments.size, symbol)) }.toTypedArray() } else { val argumentsFromOuterClassesAndParents = symbol.fir.typeParameters.takeLast(n).map { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt index c5c7172bf94..1a374267361 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt @@ -26,7 +26,6 @@ enum class DiagnosticKind { RecursionInImplicitTypes, Java, SuperNotAllowed, - WrongNumberOfTypeArguments, NoTypeForTypeParameter, UnknownCallableKind, SymbolNotFound,