Provide diagnostic for typealias using deprecated class or constructor
#KT-19205 Fixed Target versions 1.1.5
This commit is contained in:
@@ -99,6 +99,8 @@ public interface Errors {
|
||||
|
||||
DiagnosticFactory2<PsiElement, DeclarationDescriptor, String> DEPRECATION = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, DeclarationDescriptor, String> DEPRECATION_ERROR = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory3<PsiElement, TypeAliasDescriptor, DeclarationDescriptor, String> TYPEALIAS_EXPANSION_DEPRECATION = DiagnosticFactory3.create(WARNING);
|
||||
DiagnosticFactory3<PsiElement, TypeAliasDescriptor, DeclarationDescriptor, String> TYPEALIAS_EXPANSION_DEPRECATION_ERROR = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<PsiElement, DeclarationDescriptor, SinceKotlinInfo.Version, Pair<LanguageVersion, String>> SINCE_KOTLIN_INFO_DEPRECATION = DiagnosticFactory3.create(WARNING);
|
||||
DiagnosticFactory3<PsiElement, DeclarationDescriptor, SinceKotlinInfo.Version, Pair<LanguageVersion, String>> SINCE_KOTLIN_INFO_DEPRECATION_ERROR = DiagnosticFactory3.create(ERROR);
|
||||
|
||||
|
||||
+7
-2
@@ -322,14 +322,19 @@ public class DefaultErrorMessages {
|
||||
MAP.put(DEPRECATION, "''{0}'' is deprecated. {1}", DEPRECATION_RENDERER, STRING);
|
||||
MAP.put(DEPRECATION_ERROR, "Using ''{0}'' is an error. {1}", DEPRECATION_RENDERER, STRING);
|
||||
|
||||
MAP.put(TYPEALIAS_EXPANSION_DEPRECATION, "''{0}'' uses ''{1}'', which is deprecated. {2}", DEPRECATION_RENDERER, DEPRECATION_RENDERER, STRING);
|
||||
MAP.put(TYPEALIAS_EXPANSION_DEPRECATION_ERROR, "''{0}'' uses ''{1}'', which is an error. {2}", DEPRECATION_RENDERER, DEPRECATION_RENDERER, STRING);
|
||||
|
||||
DiagnosticParameterRenderer<Pair<LanguageVersion, String>> sinceKotlinInfoMessage = (pair, renderingContext) -> {
|
||||
String message = pair.getSecond();
|
||||
return pair.getFirst().getVersionString() + (message != null ? ". " + message : "");
|
||||
};
|
||||
MAP.put(SINCE_KOTLIN_INFO_DEPRECATION, "''{0}''{1} should not be used in Kotlin {2}", DEPRECATION_RENDERER,
|
||||
(obj, renderingContext) -> obj.equals(SinceKotlinInfo.Version.INFINITY) ? "" : " is only supported since Kotlin " + obj.asString() + " and", sinceKotlinInfoMessage);
|
||||
(obj, renderingContext) -> obj.equals(SinceKotlinInfo.Version.INFINITY) ? "" : " is only supported since Kotlin " + obj.asString() + " and",
|
||||
sinceKotlinInfoMessage);
|
||||
MAP.put(SINCE_KOTLIN_INFO_DEPRECATION_ERROR, "''{0}''{1} cannot be used in Kotlin {2}", DEPRECATION_RENDERER,
|
||||
(obj, renderingContext) -> obj.equals(SinceKotlinInfo.Version.INFINITY) ? "" : " is only available since Kotlin " + obj.asString() + " and", sinceKotlinInfoMessage);
|
||||
(obj, renderingContext) -> obj.equals(SinceKotlinInfo.Version.INFINITY) ? "" : " is only available since Kotlin " + obj.asString() + " and",
|
||||
sinceKotlinInfoMessage);
|
||||
|
||||
MAP.put(API_NOT_AVAILABLE, "This declaration is only available since Kotlin {0} and cannot be used with the specified API version {1}", STRING, STRING);
|
||||
|
||||
|
||||
@@ -131,6 +131,20 @@ private data class DeprecatedBySinceKotlinInfo(
|
||||
get() = sinceKotlinInfo.version
|
||||
}
|
||||
|
||||
private data class DeprecatedTypealiasByAnnotation(
|
||||
val typeAliasTarget: TypeAliasDescriptor,
|
||||
val nested: DeprecatedByAnnotation
|
||||
) : Deprecation {
|
||||
override val target get() = typeAliasTarget
|
||||
override val deprecationLevel get() = nested.deprecationLevel
|
||||
override val message get() = nested.message
|
||||
}
|
||||
|
||||
private fun Deprecation.wrapInTypeAliasExpansion(typeAliasDescriptor: TypeAliasDescriptor) = when {
|
||||
this is DeprecatedByAnnotation -> DeprecatedTypealiasByAnnotation(typeAliasDescriptor, this)
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun DeclarationDescriptor.getDeprecations(languageVersionSettings: LanguageVersionSettings): List<Deprecation> {
|
||||
val deprecations = this.getOwnDeprecations(languageVersionSettings)
|
||||
if (deprecations.isNotEmpty()) {
|
||||
@@ -201,7 +215,12 @@ private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: La
|
||||
val annotation = target.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecated)
|
||||
?: target.annotations.findAnnotation(JAVA_DEPRECATED)
|
||||
if (annotation != null) {
|
||||
result.add(DeprecatedByAnnotation(annotation, target))
|
||||
val deprecatedByAnnotation = DeprecatedByAnnotation(annotation, target)
|
||||
val deprecation = when (target) {
|
||||
is TypeAliasConstructorDescriptor -> DeprecatedTypealiasByAnnotation(target.typeAliasDescriptor, deprecatedByAnnotation)
|
||||
else -> deprecatedByAnnotation
|
||||
}
|
||||
result.add(deprecation)
|
||||
}
|
||||
|
||||
val sinceKotlinInfo =
|
||||
@@ -232,7 +251,7 @@ private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: La
|
||||
|
||||
when (this) {
|
||||
is TypeAliasDescriptor -> {
|
||||
result.addAll(expandedType.deprecationsByConstituentTypes(languageVersionSettings))
|
||||
expandedType.deprecationsByConstituentTypes(languageVersionSettings).mapTo(result) { it.wrapInTypeAliasExpansion(this) }
|
||||
}
|
||||
is TypeAliasConstructorDescriptor -> {
|
||||
result.addAll(typeAliasDescriptor.getOwnDeprecations(languageVersionSettings))
|
||||
@@ -257,20 +276,32 @@ internal fun createDeprecationDiagnostic(
|
||||
element: PsiElement, deprecation: Deprecation, languageVersionSettings: LanguageVersionSettings
|
||||
): Diagnostic {
|
||||
val targetOriginal = deprecation.target.original
|
||||
if (deprecation is DeprecatedBySinceKotlinInfo) {
|
||||
val factory = when (deprecation.deprecationLevel) {
|
||||
WARNING -> Errors.SINCE_KOTLIN_INFO_DEPRECATION
|
||||
ERROR, HIDDEN -> Errors.SINCE_KOTLIN_INFO_DEPRECATION_ERROR
|
||||
return when (deprecation) {
|
||||
is DeprecatedBySinceKotlinInfo -> {
|
||||
val factory = when (deprecation.deprecationLevel) {
|
||||
WARNING -> Errors.SINCE_KOTLIN_INFO_DEPRECATION
|
||||
ERROR, HIDDEN -> Errors.SINCE_KOTLIN_INFO_DEPRECATION_ERROR
|
||||
}
|
||||
factory.on(element, targetOriginal, deprecation.sinceKotlinVersion,
|
||||
languageVersionSettings.languageVersion to deprecation.message)
|
||||
}
|
||||
return factory.on(element, targetOriginal, deprecation.sinceKotlinVersion,
|
||||
languageVersionSettings.languageVersion to deprecation.message)
|
||||
}
|
||||
|
||||
val factory = when (deprecation.deprecationLevel) {
|
||||
WARNING -> Errors.DEPRECATION
|
||||
ERROR, HIDDEN -> Errors.DEPRECATION_ERROR
|
||||
is DeprecatedTypealiasByAnnotation -> {
|
||||
val factory = when (deprecation.deprecationLevel) {
|
||||
WARNING -> Errors.TYPEALIAS_EXPANSION_DEPRECATION
|
||||
ERROR, HIDDEN -> Errors.TYPEALIAS_EXPANSION_DEPRECATION_ERROR
|
||||
}
|
||||
factory.on(element, deprecation.typeAliasTarget.original, deprecation.nested.target.original, deprecation.nested.message ?: "")
|
||||
}
|
||||
|
||||
else -> {
|
||||
val factory = when (deprecation.deprecationLevel) {
|
||||
WARNING -> Errors.DEPRECATION
|
||||
ERROR, HIDDEN -> Errors.DEPRECATION_ERROR
|
||||
}
|
||||
factory.on(element, targetOriginal, deprecation.message ?: "")
|
||||
}
|
||||
}
|
||||
return factory.on(element, targetOriginal, deprecation.message ?: "")
|
||||
}
|
||||
|
||||
// values from kotlin.DeprecationLevel
|
||||
|
||||
@@ -10,8 +10,8 @@ typealias DeprecatedClassAlias = <!DEPRECATION!>DeprecatedClass<!>
|
||||
typealias WithDeprecatedCtorAlias = WithDeprecatedCtor
|
||||
typealias ArrayListOfDeprecatedClass = ArrayList<<!DEPRECATION!>DeprecatedClass<!>>
|
||||
|
||||
class Test1 : <!DEPRECATION!>DeprecatedClassAlias<!>()
|
||||
class Test1 : <!TYPEALIAS_EXPANSION_DEPRECATION!>DeprecatedClassAlias<!>()
|
||||
|
||||
class Test2 : <!DEPRECATION!>WithDeprecatedCtorAlias<!>()
|
||||
class Test2 : <!TYPEALIAS_EXPANSION_DEPRECATION!>WithDeprecatedCtorAlias<!>()
|
||||
|
||||
val test3 = <!DEPRECATION!>ArrayListOfDeprecatedClass<!>()
|
||||
val test3 = <!TYPEALIAS_EXPANSION_DEPRECATION!>ArrayListOfDeprecatedClass<!>()
|
||||
+15
-4
@@ -1,10 +1,21 @@
|
||||
@Deprecated("")
|
||||
class Foo
|
||||
|
||||
@Deprecated("", level = DeprecationLevel.ERROR)
|
||||
class Err
|
||||
|
||||
typealias Test1 = <!DEPRECATION!>Foo<!>
|
||||
typealias Test2 = List<<!DEPRECATION!>Foo<!>>
|
||||
typealias Test3 = List<<!DEPRECATION!>Test2<!>>
|
||||
typealias Test3 = List<<!TYPEALIAS_EXPANSION_DEPRECATION!>Test2<!>>
|
||||
|
||||
fun use1(b: <!DEPRECATION!>Test1<!>) = b
|
||||
fun use2(b: <!DEPRECATION!>Test2<!>) = b
|
||||
fun use3(b: <!DEPRECATION!>Test3<!>) = b
|
||||
typealias TestErr1 = <!DEPRECATION_ERROR!>Err<!>
|
||||
typealias TestErr2 = List<<!DEPRECATION_ERROR!>Err<!>>
|
||||
typealias TestErr3 = List<<!TYPEALIAS_EXPANSION_DEPRECATION_ERROR!>TestErr2<!>>
|
||||
|
||||
fun use1(b: <!TYPEALIAS_EXPANSION_DEPRECATION!>Test1<!>) = b
|
||||
fun use2(b: <!TYPEALIAS_EXPANSION_DEPRECATION!>Test2<!>) = b
|
||||
fun use3(b: <!TYPEALIAS_EXPANSION_DEPRECATION!>Test3<!>) = b
|
||||
|
||||
fun useErr1(b: <!TYPEALIAS_EXPANSION_DEPRECATION_ERROR!>TestErr1<!>) = b
|
||||
fun useErr2(b: <!TYPEALIAS_EXPANSION_DEPRECATION_ERROR!>TestErr2<!>) = b
|
||||
fun useErr3(b: <!TYPEALIAS_EXPANSION_DEPRECATION_ERROR!>TestErr3<!>) = b
|
||||
+13
@@ -3,6 +3,16 @@ package
|
||||
public fun use1(/*0*/ b: Test1 /* = Foo */): Test1 /* = Foo */
|
||||
public fun use2(/*0*/ b: Test2 /* = kotlin.collections.List<Foo> */): Test2 /* = kotlin.collections.List<Foo> */
|
||||
public fun use3(/*0*/ b: Test3 /* = kotlin.collections.List<Test2 /* = kotlin.collections.List<Foo> */> */): Test3 /* = kotlin.collections.List<Test2 /* = kotlin.collections.List<Foo> */> */
|
||||
public fun useErr1(/*0*/ b: TestErr1 /* = Err */): TestErr1 /* = Err */
|
||||
public fun useErr2(/*0*/ b: TestErr2 /* = kotlin.collections.List<Err> */): TestErr2 /* = kotlin.collections.List<Err> */
|
||||
public fun useErr3(/*0*/ b: TestErr3 /* = kotlin.collections.List<TestErr2 /* = kotlin.collections.List<Err> */> */): TestErr3 /* = kotlin.collections.List<TestErr2 /* = kotlin.collections.List<Err> */> */
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "") public final class Err {
|
||||
public constructor Err()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.Deprecated(message = "") public final class Foo {
|
||||
public constructor Foo()
|
||||
@@ -13,3 +23,6 @@ public fun use3(/*0*/ b: Test3 /* = kotlin.collections.List<Test2 /* = kotlin.co
|
||||
public typealias Test1 = Foo
|
||||
public typealias Test2 = kotlin.collections.List<Foo>
|
||||
public typealias Test3 = kotlin.collections.List<Test2>
|
||||
public typealias TestErr1 = Err
|
||||
public typealias TestErr2 = kotlin.collections.List<Err>
|
||||
public typealias TestErr3 = kotlin.collections.List<TestErr2>
|
||||
|
||||
Reference in New Issue
Block a user