Extract Function: Make compliant with PublicApiImplicitTypeInspection
This commit is contained in:
@@ -23,6 +23,8 @@ import com.intellij.psi.*
|
|||||||
import com.intellij.psi.stubs.StubElement
|
import com.intellij.psi.stubs.StubElement
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.lexer.KotlinLexer
|
import org.jetbrains.kotlin.lexer.KotlinLexer
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
@@ -33,6 +35,7 @@ import org.jetbrains.kotlin.name.SpecialNames
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
|
import java.lang.IllegalArgumentException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
// NOTE: in this file we collect only Kotlin-specific methods working with PSI and not modifying it
|
// NOTE: in this file we collect only Kotlin-specific methods working with PSI and not modifying it
|
||||||
@@ -593,4 +596,14 @@ fun isTopLevelInFileOrScript(element: PsiElement): Boolean {
|
|||||||
is KtBlockExpression -> parent.parent is KtScript
|
is KtBlockExpression -> parent.parent is KtScript
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KtModifierKeywordToken.toVisibility(): Visibility {
|
||||||
|
return when (this) {
|
||||||
|
KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
|
||||||
|
KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE
|
||||||
|
KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED
|
||||||
|
KtTokens.INTERNAL_KEYWORD -> Visibilities.INTERNAL
|
||||||
|
else -> throw IllegalArgumentException("Unknown visibility modifier:$this")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.TextRange
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
|
||||||
import org.jetbrains.kotlin.idea.core.canBePrivate
|
import org.jetbrains.kotlin.idea.core.canBePrivate
|
||||||
import org.jetbrains.kotlin.idea.core.canBeProtected
|
import org.jetbrains.kotlin.idea.core.canBeProtected
|
||||||
import org.jetbrains.kotlin.idea.core.setVisibility
|
import org.jetbrains.kotlin.idea.core.setVisibility
|
||||||
@@ -31,9 +30,9 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.toVisibility
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||||
import java.lang.IllegalArgumentException
|
|
||||||
|
|
||||||
open class ChangeVisibilityModifierIntention protected constructor(
|
open class ChangeVisibilityModifierIntention protected constructor(
|
||||||
val modifier: KtModifierKeywordToken
|
val modifier: KtModifierKeywordToken
|
||||||
@@ -88,16 +87,6 @@ open class ChangeVisibilityModifierIntention protected constructor(
|
|||||||
if (element is KtPropertyAccessor) element.modifierList?.nextSibling?.replace(KtPsiFactory(element).createWhiteSpace())
|
if (element is KtPropertyAccessor) element.modifierList?.nextSibling?.replace(KtPsiFactory(element).createWhiteSpace())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtModifierKeywordToken.toVisibility(): Visibility {
|
|
||||||
return when (this) {
|
|
||||||
KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
|
|
||||||
KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE
|
|
||||||
KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED
|
|
||||||
KtTokens.INTERNAL_KEYWORD -> Visibilities.INTERNAL
|
|
||||||
else -> throw IllegalArgumentException("Unknown visibility modifier:$this")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun noModifierYetApplicabilityRange(declaration: KtDeclaration): TextRange? {
|
private fun noModifierYetApplicabilityRange(declaration: KtDeclaration): TextRange? {
|
||||||
return when (declaration) {
|
return when (declaration) {
|
||||||
is KtNamedFunction -> declaration.funKeyword?.textRange
|
is KtNamedFunction -> declaration.funKeyword?.textRange
|
||||||
|
|||||||
+6
-2
@@ -607,9 +607,13 @@ private fun ExtractionData.getLocalInstructions(pseudocode: Pseudocode): List<In
|
|||||||
return instructions
|
return instructions
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ExtractionData.isVisibilityApplicable(): Boolean {
|
fun ExtractionData.isLocal(): Boolean {
|
||||||
val parent = targetSibling.parent
|
val parent = targetSibling.parent
|
||||||
if (parent !is KtClassBody && (parent !is KtFile || parent.isScript())) return false
|
return parent !is KtClassBody && (parent !is KtFile || parent.isScript())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ExtractionData.isVisibilityApplicable(): Boolean {
|
||||||
|
if (isLocal()) return false
|
||||||
if (commonParent.parentsWithSelf.any { it is KtNamedFunction && it.hasModifier(KtTokens.INLINE_KEYWORD) && it.isPublic }) return false
|
if (commonParent.parentsWithSelf.any { it is KtNamedFunction && it.hasModifier(KtTokens.INLINE_KEYWORD) && it.isPublic }) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-1
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine
|
package org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine
|
||||||
|
|
||||||
|
import com.intellij.codeHighlighting.HighlightDisplayLevel
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
|
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||||
import com.intellij.psi.search.LocalSearchScope
|
import com.intellij.psi.search.LocalSearchScope
|
||||||
@@ -24,7 +26,9 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
|||||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.idea.core.*
|
import org.jetbrains.kotlin.idea.core.*
|
||||||
|
import org.jetbrains.kotlin.idea.inspections.PublicApiImplicitTypeInspection
|
||||||
import org.jetbrains.kotlin.idea.inspections.UseExpressionBodyInspection
|
import org.jetbrains.kotlin.idea.inspections.UseExpressionBodyInspection
|
||||||
import org.jetbrains.kotlin.idea.intentions.InfixCallToOrdinaryIntention
|
import org.jetbrains.kotlin.idea.intentions.InfixCallToOrdinaryIntention
|
||||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||||
@@ -38,6 +42,7 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.*
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.*
|
||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.UnificationResult.StronglyMatched
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.UnificationResult.StronglyMatched
|
||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.UnificationResult.WeaklyMatched
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.UnificationResult.WeaklyMatched
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory.CallableBuilder
|
import org.jetbrains.kotlin.psi.KtPsiFactory.CallableBuilder
|
||||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.DEBUG_TYPE_REFERENCE_STRING
|
import org.jetbrains.kotlin.psi.codeFragmentUtil.DEBUG_TYPE_REFERENCE_STRING
|
||||||
@@ -456,6 +461,29 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getPublicApiInspectionIfEnabled(): PublicApiImplicitTypeInspection? {
|
||||||
|
val project = descriptor.extractionData.project
|
||||||
|
val inspectionProfileManager = ProjectInspectionProfileManager.getInstance(project)
|
||||||
|
val inspectionProfile = inspectionProfileManager.currentProfile
|
||||||
|
val state = inspectionProfile.getToolsOrNull("PublicApiImplicitType", project)?.defaultState ?: return null
|
||||||
|
if (!state.isEnabled || state.level == HighlightDisplayLevel.DO_NOT_SHOW) return null
|
||||||
|
return state.tool.tool as? PublicApiImplicitTypeInspection
|
||||||
|
}
|
||||||
|
|
||||||
|
fun useExplicitReturnType(): Boolean {
|
||||||
|
if (descriptor.returnType.isFlexible()) return true
|
||||||
|
val inspection = getPublicApiInspectionIfEnabled() ?: return false
|
||||||
|
val targetClass = (descriptor.extractionData.targetSibling.parent as? KtClassBody)?.parent as? KtClassOrObject
|
||||||
|
if ((targetClass != null && targetClass.isLocal) || descriptor.extractionData.isLocal()) return false
|
||||||
|
val visibility = (descriptor.visibility ?: KtTokens.DEFAULT_VISIBILITY_KEYWORD).toVisibility()
|
||||||
|
return when {
|
||||||
|
visibility.isPublicAPI -> true
|
||||||
|
inspection.reportInternal && visibility == Visibilities.INTERNAL -> true
|
||||||
|
inspection.reportPrivate && visibility == Visibilities.PRIVATE -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun adjustDeclarationBody(declaration: KtNamedDeclaration) {
|
fun adjustDeclarationBody(declaration: KtNamedDeclaration) {
|
||||||
val body = declaration.getGeneratedBody()
|
val body = declaration.getGeneratedBody()
|
||||||
|
|
||||||
@@ -554,7 +582,7 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
|||||||
val bodyOwner = body.parent as KtDeclarationWithBody
|
val bodyOwner = body.parent as KtDeclarationWithBody
|
||||||
val useExpressionBodyInspection = UseExpressionBodyInspection()
|
val useExpressionBodyInspection = UseExpressionBodyInspection()
|
||||||
if (bodyExpression != null && !bodyExpression.isMultiLine() && useExpressionBodyInspection.isActiveFor(bodyOwner)) {
|
if (bodyExpression != null && !bodyExpression.isMultiLine() && useExpressionBodyInspection.isActiveFor(bodyOwner)) {
|
||||||
useExpressionBodyInspection.simplify(bodyOwner, !descriptor.returnType.isFlexible())
|
useExpressionBodyInspection.simplify(bodyOwner, !useExplicitReturnType())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user