Prohibit using kotlin.Result as a return type in most cases
#KT-26659 In Progress
This commit is contained in:
@@ -334,6 +334,10 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, String> RESERVED_MEMBER_INSIDE_INLINE_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Result class
|
||||
|
||||
DiagnosticFactory0<PsiElement> RESULT_CLASS_IN_RETURN_TYPE = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Secondary constructors
|
||||
|
||||
DiagnosticFactory0<KtConstructorDelegationReferenceExpression> CYCLIC_CONSTRUCTOR_DELEGATION_CALL = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
+2
@@ -665,6 +665,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", STRING);
|
||||
MAP.put(SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS, "Secondary constructors with bodies are reserved for for future releases");
|
||||
|
||||
MAP.put(RESULT_CLASS_IN_RETURN_TYPE, "'kotlin.Result' cannot be used as a return type");
|
||||
|
||||
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");
|
||||
|
||||
|
||||
@@ -120,7 +120,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
InlineClassDeclarationChecker,
|
||||
PropertiesWithBackingFieldsInsideInlineClass(),
|
||||
AnnotationClassTargetAndRetentionChecker(),
|
||||
ReservedMembersAndConstructsForInlineClass()
|
||||
ReservedMembersAndConstructsForInlineClass(),
|
||||
ResultClassInReturnTypeChecker()
|
||||
)
|
||||
|
||||
private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class ResultClassInReturnTypeChecker : DeclarationChecker {
|
||||
companion object {
|
||||
private const val RESULT_NAME = "Result"
|
||||
}
|
||||
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (declaration !is KtCallableDeclaration || descriptor !is CallableMemberDescriptor) return
|
||||
|
||||
val returnType = descriptor.returnType ?: return
|
||||
if (isForbiddenReturnType(returnType, descriptor)) {
|
||||
val typeReferenceOrDeclarationName = declaration.typeReference ?: declaration.nameIdentifier ?: return
|
||||
context.trace.reportDiagnosticOnce(Errors.RESULT_CLASS_IN_RETURN_TYPE.on(typeReferenceOrDeclarationName))
|
||||
}
|
||||
}
|
||||
|
||||
private fun isForbiddenReturnType(returnType: KotlinType, declarationDescriptor: DeclarationDescriptor): Boolean {
|
||||
val descriptor = returnType.constructor.declarationDescriptor ?: return false
|
||||
if (!descriptor.isResultClass()) return false
|
||||
|
||||
if (declarationDescriptor is PropertyDescriptor || declarationDescriptor is PropertyGetterDescriptor) {
|
||||
val visibility = (declarationDescriptor as DeclarationDescriptorWithVisibility).effectiveVisibility()
|
||||
return when (visibility) {
|
||||
is EffectiveVisibility.Private, is EffectiveVisibility.Local,
|
||||
is EffectiveVisibility.InternalOrPackage, is EffectiveVisibility.InternalProtected,
|
||||
is EffectiveVisibility.InternalProtectedBound -> false
|
||||
|
||||
is EffectiveVisibility.Public, is EffectiveVisibility.Protected,
|
||||
is EffectiveVisibility.ProtectedBound -> true
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.isResultClass(): Boolean {
|
||||
val container = containingDeclaration ?: return false
|
||||
return container is PackageFragmentDescriptor &&
|
||||
container.fqName == KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME &&
|
||||
name.asString() == RESULT_NAME
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user