Report deprecation on usage of type alias expanded to a deprecated class

#KT-15243 Fixed
This commit is contained in:
Dmitry Petrov
2017-05-17 16:04:29 +03:00
parent a2db4dc0d5
commit c1ef0bfcdb
6 changed files with 56 additions and 8 deletions
@@ -37,6 +37,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.SmartList
private val JAVA_DEPRECATED = FqName("java.lang.Deprecated")
@@ -143,6 +145,16 @@ fun DeclarationDescriptor.getDeprecations(languageVersionSettings: LanguageVersi
return emptyList()
}
private fun KotlinType.deprecationsByConstituentTypes(languageVersionSettings: LanguageVersionSettings): List<Deprecation> =
SmartList<Deprecation>().also { deprecations ->
TypeUtils.contains(this) { type ->
type.constructor.declarationDescriptor?.run {
deprecations.addAll(getDeprecations(languageVersionSettings))
}
false
}
}
private fun deprecationByOverridden(root: CallableMemberDescriptor, languageVersionSettings: LanguageVersionSettings): Deprecation? {
val visited = HashSet<CallableMemberDescriptor>()
val deprecations = LinkedHashSet<Deprecation>()
@@ -177,13 +189,6 @@ private fun deprecationByOverridden(root: CallableMemberDescriptor, languageVers
}
private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: LanguageVersionSettings): List<Deprecation> {
if (this is TypeAliasConstructorDescriptor) {
// Constructor of type alias has no annotations by itself, all its annotations come from the aliased constructor
// and from the typealias declaration
return underlyingConstructorDescriptor.getOwnDeprecations(languageVersionSettings) +
typeAliasDescriptor.getOwnDeprecations(languageVersionSettings)
}
// The problem is that declaration `mod` in built-ins has @Deprecated annotation but actually it was deprecated only in version 1.1
if (this is FunctionDescriptor && this.isOperatorMod() && this.hasSubpackageOfKotlin()) {
if (!shouldWarnAboutDeprecatedModFromBuiltIns(languageVersionSettings)) {
@@ -227,6 +232,12 @@ private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: La
addUseSiteTargetedDeprecationIfPresent(this, AnnotationUseSiteTarget.getAssociatedUseSiteTarget(this))
when (this) {
is TypeAliasDescriptor -> {
result.addAll(expandedType.deprecationsByConstituentTypes(languageVersionSettings))
}
is TypeAliasConstructorDescriptor -> {
result.addAll(typeAliasDescriptor.getOwnDeprecations(languageVersionSettings))
}
is ConstructorDescriptor -> {
addDeprecationIfPresent(containingDeclaration)
}
@@ -8,7 +8,10 @@ open class WithDeprecatedCtor(val x: Int) {
typealias DeprecatedClassAlias = <!DEPRECATION!>DeprecatedClass<!>
typealias WithDeprecatedCtorAlias = WithDeprecatedCtor
typealias ArrayListOfDeprecatedClass = ArrayList<<!DEPRECATION!>DeprecatedClass<!>>
class Test1 : <!DEPRECATION!>DeprecatedClassAlias<!>()
class Test2 : <!DEPRECATION!>WithDeprecatedCtorAlias<!>()
class Test2 : <!DEPRECATION!>WithDeprecatedCtorAlias<!>()
val test3 = <!DEPRECATION!>ArrayListOfDeprecatedClass<!>()
@@ -1,5 +1,7 @@
package
public val test3: ArrayListOfDeprecatedClass /* = java.util.ArrayList<DeprecatedClass> */
@kotlin.Deprecated(message = "Deprecated class") public open class DeprecatedClass {
public constructor DeprecatedClass()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -30,5 +32,6 @@ public open class WithDeprecatedCtor {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public typealias ArrayListOfDeprecatedClass = kotlin.collections.ArrayList<DeprecatedClass>
public typealias DeprecatedClassAlias = DeprecatedClass
public typealias WithDeprecatedCtorAlias = WithDeprecatedCtor
@@ -0,0 +1,10 @@
@Deprecated("")
class Foo
typealias Test1 = <!DEPRECATION!>Foo<!>
typealias Test2 = List<<!DEPRECATION!>Foo<!>>
typealias Test3 = List<<!DEPRECATION!>Test2<!>>
fun use1(b: <!DEPRECATION!>Test1<!>) = b
fun use2(b: <!DEPRECATION!>Test2<!>) = b
fun use3(b: <!DEPRECATION!>Test3<!>) = b
@@ -0,0 +1,15 @@
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> */> */
@kotlin.Deprecated(message = "") public final class Foo {
public constructor Foo()
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
}
public typealias Test1 = Foo
public typealias Test2 = kotlin.collections.List<Foo>
public typealias Test3 = kotlin.collections.List<Test2>
@@ -6607,6 +6607,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("typealiasForDeprecatedClass.kt")
public void testTypealiasForDeprecatedClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typealiasForDeprecatedClass.kt");
doTest(fileName);
}
@TestMetadata("typealiasUsage.kt")
public void testTypealiasUsage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typealiasUsage.kt");