mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
FIR IDE: refactor hasRedundantTypeSpecification
No logic change. GitOrigin-RevId: f578f7977765daa940307aa94e4ad175446ff9f6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
8fea63479f
commit
759acce996
+9
-9
@@ -12,7 +12,7 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||
import org.jetbrains.kotlin.idea.util.hasRedundantTypeSpecification
|
||||
import org.jetbrains.kotlin.idea.util.isExplicitTypeReferenceNeededForTypeInference
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
@@ -67,23 +67,23 @@ open class RemovePsiElementSimpleFix private constructor(element: PsiElement, @N
|
||||
object RemoveVariableFactory : QuickFixesPsiBasedFactory<PsiElement>(PsiElement::class, PsiElementSuitabilityCheckers.ALWAYS_SUITABLE) {
|
||||
public override fun doCreateQuickFix(psiElement: PsiElement): List<IntentionAction> {
|
||||
if (psiElement is KtDestructuringDeclarationEntry) return emptyList()
|
||||
val expression = psiElement.getNonStrictParentOfType<KtProperty>() ?: return emptyList()
|
||||
if (!hasRedundantTypeSpecification(expression.typeReference, expression.initializer)) return emptyList()
|
||||
val ktProperty = psiElement.getNonStrictParentOfType<KtProperty>() ?: return emptyList()
|
||||
if (ktProperty.isExplicitTypeReferenceNeededForTypeInference()) return emptyList()
|
||||
return listOf(RemoveVariableFix(expression))
|
||||
}
|
||||
}
|
||||
|
||||
class RemoveVariableFix(expression: KtProperty) :
|
||||
RemovePsiElementSimpleFix(expression, KotlinBundle.message("remove.variable.0", expression.name.toString())) {
|
||||
RemovePsiElementSimpleFix(expression, KotlinBundle.message("remove.variable.0", ktProperty.name.toString())) {
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val expression = element as? KtProperty ?: return
|
||||
val initializer = expression.initializer
|
||||
val ktProperty = element as? KtProperty ?: return
|
||||
val initializer = ktProperty.initializer
|
||||
if (initializer != null && initializer !is KtConstantExpression) {
|
||||
val commentSaver = CommentSaver(expression)
|
||||
val replaced = expression.replace(initializer)
|
||||
val commentSaver = CommentSaver(ktProperty)
|
||||
val replaced = ktProperty.replace(initializer)
|
||||
commentSaver.restore(replaced)
|
||||
} else {
|
||||
expression.delete()
|
||||
ktProperty.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -180,26 +180,32 @@ fun generateWhenBranches(element: KtWhenExpression, missingCases: List<WhenMissi
|
||||
}
|
||||
}
|
||||
|
||||
tailrec fun hasRedundantTypeSpecification(typeReference: KtTypeReference?, initializer: KtExpression?): Boolean {
|
||||
if (initializer == null || typeReference == null) return true
|
||||
if (initializer !is KtLambdaExpression && initializer !is KtNamedFunction) return true
|
||||
val typeElement = typeReference.typeElement ?: return true
|
||||
if (typeReference.hasModifier(KtTokens.SUSPEND_KEYWORD)) return false
|
||||
/**
|
||||
* Consider a property initialization `val f: (Int) -> Unit = { println(it) }`. The type annotation `(Int) -> Unit` in this case is required
|
||||
* in order for the code to type check because otherwise the compiler cannot infer the type of `it`.
|
||||
*/
|
||||
tailrec fun KtCallableDeclaration.isExplicitTypeReferenceNeededForTypeInference(typeRef: KtTypeReference? = typeReference): Boolean {
|
||||
if (this !is KtDeclarationWithInitializer) return false
|
||||
val initializer = initializer
|
||||
if (initializer == null || typeRef == null) return false
|
||||
if (initializer !is KtLambdaExpression && initializer !is KtNamedFunction) return false
|
||||
val typeElement = typeRef.typeElement ?: return false
|
||||
if (typeRef.hasModifier(KtTokens.SUSPEND_KEYWORD)) return true
|
||||
return when (typeElement) {
|
||||
is KtFunctionType -> {
|
||||
if (typeElement.receiver != null) return false
|
||||
if (typeElement.parameters.isEmpty()) return true
|
||||
if (typeElement.receiver != null) return true
|
||||
if (typeElement.parameters.isEmpty()) return false
|
||||
val valueParameters = when (initializer) {
|
||||
is KtLambdaExpression -> initializer.valueParameters
|
||||
is KtNamedFunction -> initializer.valueParameters
|
||||
else -> emptyList()
|
||||
}
|
||||
valueParameters.isNotEmpty() && valueParameters.none { it.typeReference == null }
|
||||
valueParameters.isEmpty() || valueParameters.any { it.typeReference == null }
|
||||
}
|
||||
is KtUserType -> {
|
||||
val typeAlias = typeElement.referenceExpression?.mainReference?.resolve() as? KtTypeAlias ?: return true
|
||||
return hasRedundantTypeSpecification(typeAlias.getTypeReference(), initializer)
|
||||
val typeAlias = typeElement.referenceExpression?.mainReference?.resolve() as? KtTypeAlias ?: return false
|
||||
return isExplicitTypeReferenceNeededForTypeInference(typeAlias.getTypeReference())
|
||||
}
|
||||
else -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.refactoring.addTypeArgumentsIfNeeded
|
||||
import org.jetbrains.kotlin.idea.refactoring.getQualifiedTypeArgumentList
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.idea.util.hasRedundantTypeSpecification
|
||||
import org.jetbrains.kotlin.idea.util.isExplicitTypeReferenceNeededForTypeInference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
@@ -68,7 +68,7 @@ class RemoveExplicitTypeIntention : SelfTargetingRangeIntention<KtCallableDeclar
|
||||
element.resolveToDescriptorIfAny()
|
||||
)
|
||||
) return null
|
||||
if (!hasRedundantTypeSpecification(element.typeReference, initializer)) return null
|
||||
if (element.isExplicitTypeReferenceNeededForTypeInference()) return null
|
||||
|
||||
return when {
|
||||
initializer != null -> TextRange(element.startOffset, initializer.startOffset - 1)
|
||||
|
||||
Reference in New Issue
Block a user