From 674d30cd76c5a24e15d6dd0412d599bf8e0649a3 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 9 Aug 2017 17:31:39 +0300 Subject: [PATCH] Report deprecation on typealias companion object for deprecated alias --- .../checkers/ClassifierUsageChecker.kt | 16 +++++++------ .../kotlin/resolve/deprecationUtil.kt | 3 ++- ...akeCallableDescriptorForTypeAliasObject.kt | 7 ++++-- .../deprecated/typealiasCompanionObject.kt | 12 ++++++++++ .../deprecated/typealiasCompanionObject.txt | 21 +++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 +++++ .../impl/DescriptorDerivedFromTypeAlias.kt | 23 +++++++++++++++++++ .../impl/TypeAliasConstructorDescriptor.kt | 3 +-- 8 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.kt create mode 100644 compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.txt create mode 100644 core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/DescriptorDerivedFromTypeAlias.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt index f8f04e3f00d..7179f44f78c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ClassifierUsageChecker.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource +import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtReferenceExpression @@ -28,6 +29,7 @@ import org.jetbrains.kotlin.psi.KtTreeVisitorVoid import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.utils.addToStdlib.safeAs interface ClassifierUsageChecker { fun check( @@ -58,9 +60,12 @@ interface ClassifierUsageChecker { runCheckersWithTarget(target, expression) - if (isReferenceToCompanionViaOuterClass(expression, target)) { + getReferenceToCompanionViaClassifier(expression, target)?.let { referenceClassifier -> val outerClass = target.containingDeclaration as ClassDescriptor runCheckersWithTarget(outerClass, expression) + if (referenceClassifier is TypeAliasDescriptor) { + runCheckersWithTarget(referenceClassifier, expression) + } } } @@ -84,12 +89,9 @@ interface ClassifierUsageChecker { return targets.filterIsInstance().singleOrNull() } - /** - * @return true iff [expression] references the companion of a class Foo via the name Foo, e.g. in `Foo.bar()` - */ - private fun isReferenceToCompanionViaOuterClass(expression: KtReferenceExpression, target: ClassifierDescriptor?): Boolean { - return DescriptorUtils.isCompanionObject(target) && - trace.get(BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, expression) != null + private fun getReferenceToCompanionViaClassifier(expression: KtReferenceExpression, target: ClassifierDescriptor): ClassifierDescriptor? { + if (!DescriptorUtils.isCompanionObject(target)) return null + return trace.get(BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, expression) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt index a5936c30985..bdd92c66b18 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecationUtil.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.DescriptorDerivedFromTypeAlias import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Errors @@ -253,7 +254,7 @@ private fun DeclarationDescriptor.getOwnDeprecations(languageVersionSettings: La is TypeAliasDescriptor -> { expandedType.deprecationsByConstituentTypes(languageVersionSettings).mapTo(result) { it.wrapInTypeAliasExpansion(this) } } - is TypeAliasConstructorDescriptor -> { + is DescriptorDerivedFromTypeAlias -> { result.addAll(typeAliasDescriptor.getOwnDeprecations(languageVersionSettings)) } is ConstructorDescriptor -> { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt index 66da11a0b54..4387613f6d5 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/util/FakeCallableDescriptorForTypeAliasObject.kt @@ -17,9 +17,12 @@ package org.jetbrains.kotlin.resolve.calls.util import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor +import org.jetbrains.kotlin.descriptors.impl.DescriptorDerivedFromTypeAlias -class FakeCallableDescriptorForTypeAliasObject(val typeAliasDescriptor: TypeAliasDescriptor) : - FakeCallableDescriptorForObject(typeAliasDescriptor.classDescriptor!!) { +class FakeCallableDescriptorForTypeAliasObject(override val typeAliasDescriptor: TypeAliasDescriptor) : + FakeCallableDescriptorForObject(typeAliasDescriptor.classDescriptor!!), + DescriptorDerivedFromTypeAlias +{ override fun getReferencedDescriptor() = typeAliasDescriptor diff --git a/compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.kt b/compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.kt new file mode 100644 index 00000000000..823a2bdaa06 --- /dev/null +++ b/compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.kt @@ -0,0 +1,12 @@ +class Relevant { + companion object { + val value = "" + } +} + +@Deprecated("Use Relevant") +typealias Obsolete = Relevant + +fun test1() = Obsolete +fun test2() = Obsolete.value +fun test3() = Obsolete.toString() diff --git a/compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.txt b/compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.txt new file mode 100644 index 00000000000..6100d3a5308 --- /dev/null +++ b/compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.txt @@ -0,0 +1,21 @@ +package + +public fun test1(): Relevant.Companion +public fun test2(): kotlin.String +public fun test3(): kotlin.String + +public final class Relevant { + public constructor Relevant() + 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 companion object Companion { + private constructor Companion() + public final val value: kotlin.String = "" + 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 = "Use Relevant") public typealias Obsolete = Relevant diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 42dd94c9217..21f4f576c0e 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -6619,6 +6619,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("typealiasCompanionObject.kt") + public void testTypealiasCompanionObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typealiasCompanionObject.kt"); + doTest(fileName); + } + @TestMetadata("typealiasConstructor.kt") public void testTypealiasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typealiasConstructor.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/DescriptorDerivedFromTypeAlias.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/DescriptorDerivedFromTypeAlias.kt new file mode 100644 index 00000000000..74786901410 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/DescriptorDerivedFromTypeAlias.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.descriptors.impl + +import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor + +interface DescriptorDerivedFromTypeAlias { + val typeAliasDescriptor: TypeAliasDescriptor +} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt index 34b19756edd..b01bb4a6255 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt @@ -24,9 +24,8 @@ import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.types.* -interface TypeAliasConstructorDescriptor : ConstructorDescriptor { +interface TypeAliasConstructorDescriptor : ConstructorDescriptor, DescriptorDerivedFromTypeAlias { val underlyingConstructorDescriptor: ClassConstructorDescriptor - val typeAliasDescriptor: TypeAliasDescriptor override fun getContainingDeclaration(): TypeAliasDescriptor