Deprecate decapitalized annotations
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
+1
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
+6
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user