Reserve box/unbox/equals/hashCode methods inside inline classes

#KT-26573 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2018-08-31 17:23:23 +03:00
parent 7f8863bfd0
commit 002a66fec1
10 changed files with 130 additions and 2 deletions
@@ -330,6 +330,7 @@ public interface Errors {
DiagnosticFactory0<PsiElement> INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtTypeReference> INLINE_CLASS_CANNOT_EXTEND_CLASSES = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtTypeReference> INLINE_CLASS_CANNOT_BE_RECURSIVE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> RESERVED_MEMBER_INSIDE_INLINE_CLASS = DiagnosticFactory1.create(ERROR);
// Secondary constructors
@@ -661,6 +661,7 @@ public class DefaultErrorMessages {
MAP.put(INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION, "Inline class cannot implement an interface by delegation");
MAP.put(INLINE_CLASS_CANNOT_EXTEND_CLASSES, "Inline class cannot extend classes");
MAP.put(INLINE_CLASS_CANNOT_BE_RECURSIVE, "Inline class cannot be recursive");
MAP.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", STRING);
MAP.put(VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED, "Variance annotations are only allowed for type parameters of classes and interfaces");
MAP.put(BOUND_ON_TYPE_ALIAS_PARAMETER_NOT_ALLOWED, "Bounds are not allowed on type alias parameters");
@@ -119,7 +119,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
SuspendOperatorsCheckers,
InlineClassDeclarationChecker,
PropertiesWithBackingFieldsInsideInlineClass(),
AnnotationClassTargetAndRetentionChecker()
AnnotationClassTargetAndRetentionChecker(),
ReservedMembersAndConstructsForInlineClass()
)
private val DEFAULT_CALL_CHECKERS = listOf(
@@ -139,4 +139,24 @@ class PropertiesWithBackingFieldsInsideInlineClass : DeclarationChecker {
context.trace.report(Errors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS.on(it))
}
}
}
class ReservedMembersAndConstructsForInlineClass : DeclarationChecker {
companion object {
private val reservedFunctions = setOf("box", "unbox", "equals", "hashCode")
}
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
val containingDeclaration = descriptor.containingDeclaration ?: return
if (!containingDeclaration.isInlineClass()) return
if (declaration is KtFunction && descriptor is FunctionDescriptor) {
val functionName = descriptor.name.asString()
if (functionName in reservedFunctions) {
val nameIdentifier = declaration.nameIdentifier ?: return
context.trace.report(Errors.RESERVED_MEMBER_INSIDE_INLINE_CLASS.on(nameIdentifier, functionName))
}
}
}
}