Deprecate decapitalized annotations

This commit is contained in:
Denis Zharkov
2015-09-08 16:24:16 +03:00
parent 1dee922861
commit 297e9484ba
7 changed files with 87 additions and 1 deletions
@@ -223,6 +223,7 @@ public interface Errors {
DiagnosticFactory1<PsiElement, DeclarationDescriptor> DEPRECATED_SYMBOL = DiagnosticFactory1.create(WARNING);
DiagnosticFactory2<PsiElement, DeclarationDescriptor, String> DEPRECATED_SYMBOL_WITH_MESSAGE = DiagnosticFactory2.create(WARNING);
DiagnosticFactory1<JetSimpleNameExpression, ClassDescriptor> DEPRECATED_DECAPITALIZED_ANNOTATION = DiagnosticFactory1.create(WARNING);
// Objects
@@ -273,6 +273,7 @@ public class DefaultErrorMessages {
MAP.put(DEPRECATED_SYMBOL, "''{0}'' is deprecated.", DEPRECATION_RENDERER);
MAP.put(DEPRECATED_SYMBOL_WITH_MESSAGE, "''{0}'' is deprecated. {1}", DEPRECATION_RENDERER, STRING);
MAP.put(DEPRECATED_DECAPITALIZED_ANNOTATION, "Decapitalized annotations are deprecated. Use ''{0}'' instead", DEPRECATION_RENDERER);
MAP.put(LOCAL_OBJECT_NOT_ALLOWED, "Named object ''{0}'' is a singleton and cannot be local. Try to use anonymous object instead", NAME);
MAP.put(ENUM_CLASS_CONSTRUCTOR_CALL, "Enum types cannot be instantiated");
@@ -33,6 +33,10 @@ import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_GETTER
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_SETTER
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.scopes.DECAPITALIZED_DEPRECATED_ANNOTATIONS
import org.jetbrains.kotlin.resolve.scopes.DECAPITALIZED_SHORT_NAMES
public class DeprecatedSymbolValidator : SymbolUsageValidator {
private val JAVA_DEPRECATED = FqName(java.lang.Deprecated::class.java.name)
@@ -46,6 +50,9 @@ public class DeprecatedSymbolValidator : SymbolUsageValidator {
else if (targetDescriptor is PropertyDescriptor) {
propertyGetterWorkaround(targetDescriptor, trace, element)
}
else {
checkDecapitalizedAnnotation(element, targetDescriptor, trace)
}
}
override fun validateTypeUsage(targetDescriptor: ClassifierDescriptor, trace: BindingTrace, element: PsiElement) {
@@ -64,6 +71,32 @@ public class DeprecatedSymbolValidator : SymbolUsageValidator {
val (annotation, target) = deprecated
trace.report(createDeprecationDiagnostic(element, target, annotation))
}
else {
checkDecapitalizedAnnotation(element, targetDescriptor, trace)
}
}
private fun checkDecapitalizedAnnotation(element: PsiElement, targetDescriptor: DeclarationDescriptor, trace: BindingTrace) {
val effectiveTargetDescriptor = when (targetDescriptor) {
is ConstructorDescriptor -> targetDescriptor.containingDeclaration
else -> targetDescriptor
} as? ClassDescriptor ?: return
val unsafeFqName = effectiveTargetDescriptor.fqNameUnsafe
if (!unsafeFqName.isSafe) return
val simpleName = unwrapSimpleName(element) ?: return
if (unsafeFqName.toSafe() in DECAPITALIZED_DEPRECATED_ANNOTATIONS && simpleName.getReferencedName() in DECAPITALIZED_SHORT_NAMES) {
trace.report(Errors.DEPRECATED_DECAPITALIZED_ANNOTATION.on(simpleName, effectiveTargetDescriptor))
}
}
private fun unwrapSimpleName(element: PsiElement): JetSimpleNameExpression? {
return when (element) {
is JetConstructorCalleeExpression -> (element.typeReference?.typeElement as? JetUserType)?.referenceExpression
is JetSimpleNameExpression -> element
else -> null
}
}
private fun DeclarationDescriptor.getDeprecatedAnnotation(): Pair<AnnotationDescriptor, DeclarationDescriptor>? {
@@ -0,0 +1,23 @@
// !DIAGNOSTICS: -DEPRECATED_UNESCAPED_ANNOTATION -UNUSED_PARAMETER
import kotlin.Extension as extension
import kotlin.jvm.<!DEPRECATED_DECAPITALIZED_ANNOTATION!>strictfp<!> as sfp
class A {
@<!DEPRECATED_DECAPITALIZED_ANNOTATION!>deprecated<!>("") fun foo() {}
companion object {
@<!DEPRECATED_DECAPITALIZED_ANNOTATION!>jvmStatic<!> fun bar() {}
}
<!DEPRECATED_DECAPITALIZED_ANNOTATION!>throws<!>(java.lang.RuntimeException::class)
<!DEPRECATED_DECAPITALIZED_ANNOTATION!>synchronized<!> fun <T> baz() {
@<!DEPRECATED_DECAPITALIZED_ANNOTATION!>suppress<!>("UNCHECKED_CAST")
(1 as T)
}
kotlin.jvm.<!DEPRECATED_DECAPITALIZED_ANNOTATION!>jvmName<!>("y")
<!DEPRECATED_DECAPITALIZED_ANNOTATION!>jvmOverloads<!>()
fun x(x: Int = 1) {}
}
sfp fun bar(
x: <!DEPRECATED_DECAPITALIZED_ANNOTATION!>deprecated<!>
): @<!DEPRECATED_DECAPITALIZED_ANNOTATION!>extension<!> String.() -> Int = null!!
@@ -0,0 +1,21 @@
package
kotlin.jvm.Strictfp() public fun bar(/*0*/ x: kotlin.Deprecated): @[kotlin.Extension()] kotlin.String.() -> kotlin.Int
public final class A {
public constructor A()
kotlin.Throws(exceptionClasses = {java.lang.RuntimeException::class}) kotlin.jvm.Synchronized() public final fun </*0*/ T> baz(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
kotlin.Deprecated(value = "") public final fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
kotlin.jvm.JvmName(name = "y") kotlin.jvm.JvmOverloads() public final fun x(/*0*/ x: kotlin.Int = ...): kotlin.Unit
public companion object Companion {
private constructor Companion()
kotlin.jvm.JvmStatic() public final fun bar(): kotlin.Unit
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
}
}
@@ -91,6 +91,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
doTest(fileName);
}
@TestMetadata("decapitalized.kt")
public void testDecapitalized() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/decapitalized.kt");
doTest(fileName);
}
@TestMetadata("defaultValueMustBeConstant.kt")
public void testDefaultValueMustBeConstant() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/defaultValueMustBeConstant.kt");
@@ -153,7 +153,8 @@ public open class JetPsiChecker : Annotator, HighlightRangeExtension {
when (factory) {
Errors.DEPRECATED_SYMBOL,
Errors.DEPRECATED_SYMBOL_WITH_MESSAGE,
Errors.DEPRECATED_TRAIT_KEYWORD
Errors.DEPRECATED_TRAIT_KEYWORD,
Errors.DEPRECATED_DECAPITALIZED_ANNOTATION
-> annotation.setTextAttributes(CodeInsightColors.DEPRECATED_ATTRIBUTES)
}