[FIR] Deprecate using typealias as callable qualifier in import
^KT-64350 Fixed
This commit is contained in:
committed by
Space Team
parent
802366064d
commit
3994e3f63a
+16
@@ -4889,6 +4889,22 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT.errorFactory) { firDiagnostic ->
|
||||
TypealiasAsCallableQualifierInImportErrorImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT.warningFactory) { firDiagnostic ->
|
||||
TypealiasAsCallableQualifierInImportWarningImpl(
|
||||
firDiagnostic.a,
|
||||
firDiagnostic.b,
|
||||
firDiagnostic as KtPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
}
|
||||
add(FirErrors.ILLEGAL_SUSPEND_FUNCTION_CALL) { firDiagnostic ->
|
||||
IllegalSuspendFunctionCallImpl(
|
||||
firSymbolBuilder.buildSymbol(firDiagnostic.a),
|
||||
|
||||
+12
@@ -3406,6 +3406,18 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = OperatorRenamedOnImport::class
|
||||
}
|
||||
|
||||
interface TypealiasAsCallableQualifierInImportError : KtFirDiagnostic<KtImportDirective> {
|
||||
override val diagnosticClass get() = TypealiasAsCallableQualifierInImportError::class
|
||||
val typealiasName: Name
|
||||
val originalClassName: Name
|
||||
}
|
||||
|
||||
interface TypealiasAsCallableQualifierInImportWarning : KtFirDiagnostic<KtImportDirective> {
|
||||
override val diagnosticClass get() = TypealiasAsCallableQualifierInImportWarning::class
|
||||
val typealiasName: Name
|
||||
val originalClassName: Name
|
||||
}
|
||||
|
||||
interface IllegalSuspendFunctionCall : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = IllegalSuspendFunctionCall::class
|
||||
val suspendCallable: KtSymbol
|
||||
|
||||
+14
@@ -4106,6 +4106,20 @@ internal class OperatorRenamedOnImportImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtImportDirective>(firDiagnostic, token), KtFirDiagnostic.OperatorRenamedOnImport
|
||||
|
||||
internal class TypealiasAsCallableQualifierInImportErrorImpl(
|
||||
override val typealiasName: Name,
|
||||
override val originalClassName: Name,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtImportDirective>(firDiagnostic, token), KtFirDiagnostic.TypealiasAsCallableQualifierInImportError
|
||||
|
||||
internal class TypealiasAsCallableQualifierInImportWarningImpl(
|
||||
override val typealiasName: Name,
|
||||
override val originalClassName: Name,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<KtImportDirective>(firDiagnostic, token), KtFirDiagnostic.TypealiasAsCallableQualifierInImportWarning
|
||||
|
||||
internal class IllegalSuspendFunctionCallImpl(
|
||||
override val suspendCallable: KtSymbol,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
|
||||
+8
@@ -1732,6 +1732,14 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
}
|
||||
|
||||
val OPERATOR_RENAMED_ON_IMPORT by error<KtImportDirective>(PositioningStrategy.IMPORT_LAST_NAME)
|
||||
|
||||
val TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT by deprecationError<KtImportDirective>(
|
||||
LanguageFeature.ProhibitTypealiasAsCallableQualifierInImport,
|
||||
PositioningStrategy.IMPORT_LAST_BUT_ONE_NAME,
|
||||
) {
|
||||
parameter<Name>("typealiasName")
|
||||
parameter<Name>("originalClassName")
|
||||
}
|
||||
}
|
||||
|
||||
val SUSPEND by object : DiagnosticGroup("Suspend errors") {
|
||||
|
||||
+1
@@ -93,6 +93,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
|
||||
QUESTION_MARK_BY_TYPE,
|
||||
ANNOTATION_USE_SITE,
|
||||
IMPORT_LAST_NAME,
|
||||
IMPORT_LAST_BUT_ONE_NAME,
|
||||
DATA_MODIFIER,
|
||||
SPREAD_OPERATOR,
|
||||
DECLARATION_WITH_BODY,
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.config.LanguageFeature.ProhibitInvisibleAbstractMeth
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitNonReifiedArraysAsReifiedTypeArguments
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitScriptTopLevelInnerClasses
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitSingleNamedFunctionAsExpression
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitTypealiasAsCallableQualifierInImport
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.RestrictRetentionForExpressionAnnotations
|
||||
import org.jetbrains.kotlin.config.LanguageFeature.RestrictionOfValReassignmentViaBackingField
|
||||
@@ -858,6 +859,7 @@ object FirErrors {
|
||||
val CANNOT_BE_IMPORTED: KtDiagnosticFactory1<Name> by error1<KtImportDirective, Name>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
|
||||
val CONFLICTING_IMPORT: KtDiagnosticFactory1<Name> by error1<KtImportDirective, Name>(SourceElementPositioningStrategies.IMPORT_ALIAS)
|
||||
val OPERATOR_RENAMED_ON_IMPORT: KtDiagnosticFactory0 by error0<KtImportDirective>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
|
||||
val TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT: KtDiagnosticFactoryForDeprecation2<Name, Name> by deprecationError2<KtImportDirective, Name, Name>(ProhibitTypealiasAsCallableQualifierInImport, SourceElementPositioningStrategies.IMPORT_LAST_BUT_ONE_NAME)
|
||||
|
||||
// Suspend errors
|
||||
val ILLEGAL_SUSPEND_FUNCTION_CALL: KtDiagnosticFactory1<FirBasedSymbol<*>> by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||
|
||||
+15
-3
@@ -95,7 +95,8 @@ object FirImportsChecker : FirFileChecker(MppCheckerKind.Common) {
|
||||
val symbolProvider = context.session.symbolProvider
|
||||
val parentClassId = (import as? FirResolvedImport)?.resolvedParentClassId
|
||||
if (parentClassId != null) {
|
||||
val parentClassSymbol = parentClassId.resolveToClass(context) ?: return
|
||||
val parentClassLikeSymbol = parentClassId.resolveToClassLike(context) ?: return
|
||||
val parentClassSymbol = parentClassLikeSymbol.fullyExpandedClass(context.session) ?: return
|
||||
|
||||
fun reportInvisibleParentClasses(classSymbol: FirRegularClassSymbol, depth: Int) {
|
||||
if (!classSymbol.isVisible(context)) {
|
||||
@@ -109,7 +110,14 @@ object FirImportsChecker : FirFileChecker(MppCheckerKind.Common) {
|
||||
reportInvisibleParentClasses(parentClassSymbol, 1)
|
||||
|
||||
when (val status = parentClassSymbol.getImportStatusOfCallableMembers(context, importedName)) {
|
||||
ImportStatus.OK -> return
|
||||
ImportStatus.OK -> {
|
||||
if (parentClassLikeSymbol is FirTypeAliasSymbol) {
|
||||
reporter.reportOn(
|
||||
import.source, FirErrors.TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT,
|
||||
parentClassLikeSymbol.name, parentClassSymbol.name, context
|
||||
)
|
||||
}
|
||||
}
|
||||
is ImportStatus.Invisible -> {
|
||||
val source = import.getSourceForImportSegment(0)
|
||||
reporter.report(status.symbol.toInvisibleReferenceDiagnostic(source), context)
|
||||
@@ -237,8 +245,12 @@ object FirImportsChecker : FirFileChecker(MppCheckerKind.Common) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassId.resolveToClassLike(context: CheckerContext): FirClassLikeSymbol<*>? {
|
||||
return context.session.symbolProvider.getClassLikeSymbolByClassId(this)
|
||||
}
|
||||
|
||||
private fun ClassId.resolveToClass(context: CheckerContext): FirRegularClassSymbol? {
|
||||
val classSymbol = context.session.symbolProvider.getClassLikeSymbolByClassId(this) ?: return null
|
||||
val classSymbol = resolveToClassLike(context) ?: return null
|
||||
return when (classSymbol) {
|
||||
is FirRegularClassSymbol -> classSymbol
|
||||
is FirTypeAliasSymbol -> classSymbol.fullyExpandedClass(context.session)
|
||||
|
||||
+8
@@ -611,6 +611,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.THROWABLE_TYPE_MI
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOO_MANY_ARGUMENTS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TOPLEVEL_TYPEALIASES_ONLY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPEALIAS_EXPANDS_TO_ARRAY_OF_NOTHINGS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPEALIAS_EXPANSION_DEPRECATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPEALIAS_EXPANSION_DEPRECATION_ERROR
|
||||
@@ -2511,6 +2512,13 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
TO_STRING
|
||||
)
|
||||
map.put(OPERATOR_RENAMED_ON_IMPORT, "Operator renamed to a different operator on import.")
|
||||
map.put(
|
||||
TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT,
|
||||
"Cannot use typealias ''{0}'' as a callable qualifier in import. " +
|
||||
"Use original class ''{1}'' instead or rewrite calls with ''{0}'' as a qualifier. " +
|
||||
"See https://youtrack.jetbrains.com/issue/KT-64431.",
|
||||
NAME, NAME
|
||||
)
|
||||
|
||||
// Suspend
|
||||
map.put(
|
||||
|
||||
+13
@@ -1048,6 +1048,19 @@ object LightTreePositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
val IMPORT_LAST_BUT_ONE_NAME: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
val references = tree.collectDescendantsOfType(node, KtNodeTypes.REFERENCE_EXPRESSION)
|
||||
val nodeToMark = references.elementAtOrNull(references.size - 2) ?: node
|
||||
return markElement(nodeToMark, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
|
||||
val IMPORT_ALIAS: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
|
||||
override fun mark(
|
||||
node: LighterASTNode,
|
||||
|
||||
+16
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.VISIBILITY_MODIFIERS
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.UnsafeCastFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
object PositioningStrategies {
|
||||
@@ -1013,6 +1015,20 @@ object PositioningStrategies {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(UnsafeCastFunction::class)
|
||||
val IMPORT_LAST_BUT_ONE_NAME: PositioningStrategy<KtImportDirective> = object : PositioningStrategy<KtImportDirective>() {
|
||||
override fun mark(element: KtImportDirective): List<TextRange> {
|
||||
element.importedReference
|
||||
?.safeAs<KtDotQualifiedExpression>()
|
||||
?.receiverExpression
|
||||
?.safeAs<KtDotQualifiedExpression>()
|
||||
?.selectorExpression
|
||||
?.let { return markElement(it) }
|
||||
|
||||
return super.mark(element)
|
||||
}
|
||||
}
|
||||
|
||||
val LABEL: PositioningStrategy<KtElement> = object : PositioningStrategy<KtElement>() {
|
||||
override fun mark(element: KtElement): List<TextRange> {
|
||||
return super.mark((element as? KtExpressionWithLabel)?.labelQualifier ?: element)
|
||||
|
||||
+5
@@ -286,6 +286,11 @@ object SourceElementPositioningStrategies {
|
||||
PositioningStrategies.IMPORT_LAST_NAME
|
||||
)
|
||||
|
||||
val IMPORT_LAST_BUT_ONE_NAME = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.IMPORT_LAST_BUT_ONE_NAME,
|
||||
PositioningStrategies.IMPORT_LAST_BUT_ONE_NAME,
|
||||
)
|
||||
|
||||
val SPREAD_OPERATOR = SourceElementPositioningStrategy(
|
||||
LightTreePositioningStrategies.SPREAD_OPERATOR,
|
||||
PositioningStrategies.SPREAD_OPERATOR
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// FILE: 1.kt
|
||||
package bar
|
||||
|
||||
typealias HostAlias = Host
|
||||
|
||||
object Host {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
import bar.<!TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT_WARNING("HostAlias; Host")!>HostAlias<!>.foo
|
||||
|
||||
fun test() {
|
||||
foo()
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: 1.kt
|
||||
package bar
|
||||
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: 1.kt
|
||||
package bar
|
||||
|
||||
@@ -9,7 +8,7 @@ object Host {
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
import bar.HostAlias.foo
|
||||
import bar.<!TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT_WARNING("HostAlias; Host")!>HostAlias<!>.foo
|
||||
|
||||
fun test() {
|
||||
<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
|
||||
// FILE: test/jv/JavaSample.java
|
||||
|
||||
package test.jv;
|
||||
|
||||
public class JavaSample {
|
||||
public static void member() {}
|
||||
}
|
||||
|
||||
// FILE: foo.kt
|
||||
|
||||
package test.kot
|
||||
|
||||
typealias JavaAlias = test.jv.JavaSample
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import test.kot.JavaAlias
|
||||
import test.kot.<!TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT_WARNING!>JavaAlias<!>.member
|
||||
|
||||
fun foo(
|
||||
sample: <!UNRESOLVED_REFERENCE!>JavaSample<!>,
|
||||
alias: JavaAlias
|
||||
) {
|
||||
member()
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
|
||||
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// SKIP_JAVAC
|
||||
|
||||
@@ -19,7 +18,7 @@ typealias JavaAlias = test.jv.JavaSample
|
||||
// FILE: test.kt
|
||||
|
||||
import test.kot.JavaAlias
|
||||
import test.kot.JavaAlias.member
|
||||
import test.kot.<!TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT_WARNING!>JavaAlias<!>.member
|
||||
|
||||
fun foo(
|
||||
sample: <!UNRESOLVED_REFERENCE!>JavaSample<!>,
|
||||
|
||||
+1
-1
@@ -42,6 +42,6 @@ import test.EnumAlias.Nested3
|
||||
import test.EnumSample.Nested3.*
|
||||
import test.EnumAlias.<!UNRESOLVED_IMPORT!>Nested3<!>.*
|
||||
|
||||
import test.EnumAlias.Entry
|
||||
import test.<!TYPEALIAS_AS_CALLABLE_QUALIFIER_IN_IMPORT_WARNING!>EnumAlias<!>.Entry
|
||||
|
||||
fun f() {}
|
||||
|
||||
@@ -323,6 +323,7 @@ enum class LanguageFeature(
|
||||
JsAllowInvalidCharsIdentifiersEscaping(KOTLIN_2_1, kind = OTHER), // KT-31799
|
||||
SupportJavaErrorEnhancementOfArgumentsOfWarningLevelEnhanced(KOTLIN_2_1, kind = BUG_FIX), // KT-63209
|
||||
ProhibitPrivateOperatorCallInInline(KOTLIN_2_1, kind = BUG_FIX), // KT-65494
|
||||
ProhibitTypealiasAsCallableQualifierInImport(KOTLIN_2_1, kind = BUG_FIX), // KT-64350
|
||||
|
||||
// End of 2.* language features --------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user