Add explicit return type check for API mode

It will use the same SpecifyTypeExplicitlyIntention as in other places; to reuse check logic, some parts of code were moved from corresponding inspection (PublicApiImplicitTypeInspection) into ApiModeDeclarationChecker.

Also disable RedundantVisibilityModifierInspection when API mode is on.
This commit is contained in:
Leonid Startsev
2019-09-09 20:19:32 +03:00
parent 7058492b55
commit 2b708093c0
7 changed files with 111 additions and 33 deletions
@@ -6,13 +6,12 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.config.ApiMode
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.effectiveVisibility
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.resolve.checkers.ApiModeDeclarationChecker
import javax.swing.JComponent
class PublicApiImplicitTypeInspection(
@@ -20,20 +19,11 @@ class PublicApiImplicitTypeInspection(
@JvmField var reportPrivate: Boolean = false
) : AbstractImplicitTypeInspection(
{ element, inspection ->
element.containingClassOrObject?.isLocal != true &&
when (element) {
is KtFunction -> !element.isLocal
is KtProperty -> !element.isLocal
else -> false
} && run {
val callableMemberDescriptor = element.resolveToDescriptorIfAny() as? CallableMemberDescriptor
val forInternal = (inspection as PublicApiImplicitTypeInspection).reportInternal
val forPrivate = inspection.reportPrivate
val visibility = callableMemberDescriptor?.effectiveVisibility()?.toVisibility()
visibility?.isPublicAPI == true || (forInternal && visibility == Visibilities.INTERNAL) ||
(forPrivate && visibility == Visibilities.PRIVATE)
}
val shouldCheckForPublic = element.languageVersionSettings.getFlag(AnalysisFlags.apiMode) == ApiMode.DISABLED
val callableMemberDescriptor = element.resolveToDescriptorIfAny() as? CallableMemberDescriptor
val forInternal = (inspection as PublicApiImplicitTypeInspection).reportInternal
val forPrivate = inspection.reportPrivate
ApiModeDeclarationChecker.returnTypeRequired(element, callableMemberDescriptor, shouldCheckForPublic, forInternal, forPrivate)
}
) {
@@ -7,11 +7,14 @@ package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.*
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.config.AnalysisFlags
import org.jetbrains.kotlin.config.ApiMode
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.idea.core.implicitVisibility
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.lexer.KtTokens
@@ -26,6 +29,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
class RedundantVisibilityModifierInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return declarationVisitor(fun(declaration: KtDeclaration) {
val isInApiMode = declaration.languageVersionSettings.getFlag(AnalysisFlags.apiMode) != ApiMode.DISABLED
if (isInApiMode) return@declarationVisitor
if (declaration is KtPropertyAccessor && declaration.isGetter) return // There is a quick fix for REDUNDANT_MODIFIER_IN_GETTER
val visibilityModifier = declaration.visibilityModifier() ?: return
val implicitVisibility = declaration.implicitVisibility()
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.util.getResolvableApproximations
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.checkers.ApiModeDeclarationChecker
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
@@ -50,12 +51,7 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDec
), HighPriorityAction {
override fun applicabilityRange(element: KtCallableDeclaration): TextRange? {
if (element.containingFile is KtCodeFragment) return null
if (element is KtFunctionLiteral) return null // TODO: should KtFunctionLiteral be KtCallableDeclaration at all?
if (element is KtConstructor<*>) return null
if (element.typeReference != null) return null
if (element is KtNamedFunction && element.hasBlockBody()) return null
if (!ApiModeDeclarationChecker.returnTypeCheckIsApplicable(element)) return null
text = if (element is KtFunction) "Specify return type explicitly" else "Specify type explicitly"
@@ -25,10 +25,7 @@ import org.jetbrains.kotlin.idea.inspections.AddModifierFixFactory
import org.jetbrains.kotlin.idea.inspections.InfixCallFixActionFactory
import org.jetbrains.kotlin.idea.inspections.PlatformUnresolvedProvider
import org.jetbrains.kotlin.idea.inspections.RemoveAnnotationFix
import org.jetbrains.kotlin.idea.intentions.AbstractAddAccessorsIntention
import org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction
import org.jetbrains.kotlin.idea.intentions.ConvertPropertyInitializerToGetterIntention
import org.jetbrains.kotlin.idea.intentions.MoveMemberToCompanionObjectIntention
import org.jetbrains.kotlin.idea.intentions.*
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.*
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromConstructorCallActionFactory
@@ -154,6 +151,9 @@ class QuickFixRegistrar : QuickFixContributor {
FORBIDDEN_BINARY_MOD.registerFactory(removeModifierFactory)
FORBIDDEN_BINARY_MOD.registerFactory(RenameModToRemFix.Factory)
NO_EXPLICIT_RETURN_TYPE_IN_API_MODE.registerActions(SpecifyTypeExplicitlyFix())
NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_MIGRATION.registerActions(SpecifyTypeExplicitlyFix())
UNRESOLVED_REFERENCE.registerFactory(ImportFix)
UNRESOLVED_REFERENCE.registerFactory(ImportConstructorReferenceFix)