Skip to content

Commit c1ef0bf

Browse files
committed
Report deprecation on usage of type alias expanded to a deprecated class
#KT-15243 Fixed
1 parent a2db4dc commit c1ef0bf

File tree

6 files changed

+56
-8
lines changed

6 files changed

+56
-8
lines changed

compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
3737
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
3838
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
3939
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo
40+
import org.jetbrains.kotlin.types.KotlinType
41+
import org.jetbrains.kotlin.types.TypeUtils
4042
import org.jetbrains.kotlin.utils.SmartList
4143

4244
private val JAVA_DEPRECATED = FqName("java.lang.Deprecated")
@@ -143,6 +145,16 @@ fun DeclarationDescriptor.getDeprecations(languageVersionSettings: LanguageVersi
143145
return emptyList()
144146
}
145147

148+
private fun KotlinType.deprecationsByConstituentTypes(languageVersionSettings: LanguageVersionSettings): List<Deprecation> =
149+
SmartList<Deprecation>().also { deprecations ->
150+
TypeUtils.contains(this) { type ->
151+
type.constructor.declarationDescriptor?.run {
152+
deprecations.addAll(getDeprecations(languageVersionSettings))
153+
}
154+
false
155+
}
156+
}
157+
146158
private fun deprecationByOverridden(root: CallableMemberDescriptor, languageVersionSettings: LanguageVersionSettings): Deprecation? {
147159
val visited = HashSet<CallableMemberDescriptor>()
148160
val deprecations = LinkedHashSet<Deprecation>()
@@ -177,13 +189,6 @@ private fun deprecationByOverridden(root: CallableMemberDescriptor, languageVers
177189
}
178190

179191
private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: LanguageVersionSettings): List<Deprecation> {
180-
if (this is TypeAliasConstructorDescriptor) {
181-
// Constructor of type alias has no annotations by itself, all its annotations come from the aliased constructor
182-
// and from the typealias declaration
183-
return underlyingConstructorDescriptor.getOwnDeprecations(languageVersionSettings) +
184-
typeAliasDescriptor.getOwnDeprecations(languageVersionSettings)
185-
}
186-
187192
// The problem is that declaration `mod` in built-ins has @Deprecated annotation but actually it was deprecated only in version 1.1
188193
if (this is FunctionDescriptor && this.isOperatorMod() && this.hasSubpackageOfKotlin()) {
189194
if (!shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
@@ -227,6 +232,12 @@ private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: La
227232
addUseSiteTargetedDeprecationIfPresent(this, AnnotationUseSiteTarget.getAssociatedUseSiteTarget(this))
228233

229234
when (this) {
235+
is TypeAliasDescriptor -> {
236+
result.addAll(expandedType.deprecationsByConstituentTypes(languageVersionSettings))
237+
}
238+
is TypeAliasConstructorDescriptor -> {
239+
result.addAll(typeAliasDescriptor.getOwnDeprecations(languageVersionSettings))
240+
}
230241
is ConstructorDescriptor -> {
231242
addDeprecationIfPresent(containingDeclaration)
232243
}

compiler/testData/diagnostics/tests/deprecated/typealiasConstructor.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ open class WithDeprecatedCtor(val x: Int) {
88

99
typealias DeprecatedClassAlias = <!DEPRECATION!>DeprecatedClass<!>
1010
typealias WithDeprecatedCtorAlias = WithDeprecatedCtor
11+
typealias ArrayListOfDeprecatedClass = ArrayList<<!DEPRECATION!>DeprecatedClass<!>>
1112

1213
class Test1 : <!DEPRECATION!>DeprecatedClassAlias<!>()
1314

14-
class Test2 : <!DEPRECATION!>WithDeprecatedCtorAlias<!>()
15+
class Test2 : <!DEPRECATION!>WithDeprecatedCtorAlias<!>()
16+
17+
val test3 = <!DEPRECATION!>ArrayListOfDeprecatedClass<!>()

compiler/testData/diagnostics/tests/deprecated/typealiasConstructor.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package
22

3+
public val test3: ArrayListOfDeprecatedClass /* = java.util.ArrayList<DeprecatedClass> */
4+
35
@kotlin.Deprecated(message = "Deprecated class") public open class DeprecatedClass {
46
public constructor DeprecatedClass()
57
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -30,5 +32,6 @@ public open class WithDeprecatedCtor {
3032
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
3133
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
3234
}
35+
public typealias ArrayListOfDeprecatedClass = kotlin.collections.ArrayList<DeprecatedClass>
3336
public typealias DeprecatedClassAlias = DeprecatedClass
3437
public typealias WithDeprecatedCtorAlias = WithDeprecatedCtor
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@Deprecated("")
2+
class Foo
3+
4+
typealias Test1 = <!DEPRECATION!>Foo<!>
5+
typealias Test2 = List<<!DEPRECATION!>Foo<!>>
6+
typealias Test3 = List<<!DEPRECATION!>Test2<!>>
7+
8+
fun use1(b: <!DEPRECATION!>Test1<!>) = b
9+
fun use2(b: <!DEPRECATION!>Test2<!>) = b
10+
fun use3(b: <!DEPRECATION!>Test3<!>) = b
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package
2+
3+
public fun use1(/*0*/ b: Test1 /* = Foo */): Test1 /* = Foo */
4+
public fun use2(/*0*/ b: Test2 /* = kotlin.collections.List<Foo> */): Test2 /* = kotlin.collections.List<Foo> */
5+
public fun use3(/*0*/ b: Test3 /* = kotlin.collections.List<Test2 /* = kotlin.collections.List<Foo> */> */): Test3 /* = kotlin.collections.List<Test2 /* = kotlin.collections.List<Foo> */> */
6+
7+
@kotlin.Deprecated(message = "") public final class Foo {
8+
public constructor Foo()
9+
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
10+
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
11+
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
12+
}
13+
public typealias Test1 = Foo
14+
public typealias Test2 = kotlin.collections.List<Foo>
15+
public typealias Test3 = kotlin.collections.List<Test2>

compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6607,6 +6607,12 @@ public void testTypealiasConstructor() throws Exception {
66076607
doTest(fileName);
66086608
}
66096609

6610+
@TestMetadata("typealiasForDeprecatedClass.kt")
6611+
public void testTypealiasForDeprecatedClass() throws Exception {
6612+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typealiasForDeprecatedClass.kt");
6613+
doTest(fileName);
6614+
}
6615+
66106616
@TestMetadata("typealiasUsage.kt")
66116617
public void testTypealiasUsage() throws Exception {
66126618
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typealiasUsage.kt");

0 commit comments

Comments
 (0)