Reforma ReplaceCallFix

This commit is contained in:
Toshiaki Kameyama
2019-09-19 23:55:20 +09:00
committed by Dmitry Gridin
parent 78affdd2b4
commit 7b56733bda
@@ -30,9 +30,9 @@ import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverVa
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
abstract class ReplaceCallFix( abstract class ReplaceCallFix(
expression: KtQualifiedExpression, expression: KtQualifiedExpression,
private val operation: String, private val operation: String,
private val notNullNeeded: Boolean = false private val notNullNeeded: Boolean = false
) : KotlinQuickFixAction<KtQualifiedExpression>(expression) { ) : KotlinQuickFixAction<KtQualifiedExpression>(expression) {
override fun getFamilyName() = text override fun getFamilyName() = text
@@ -45,8 +45,10 @@ abstract class ReplaceCallFix(
override fun invoke(project: Project, editor: Editor?, file: KtFile) { override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val element = element ?: return val element = element ?: return
val elvis = elvisOrEmpty(notNullNeeded) val elvis = elvisOrEmpty(notNullNeeded)
val newExpression = KtPsiFactory(element).createExpressionByPattern("$0$operation$1$elvis", val newExpression = KtPsiFactory(element).createExpressionByPattern(
element.receiverExpression, element.selectorExpression!!) "$0$operation$1$elvis",
element.receiverExpression, element.selectorExpression!!
)
val replacement = element.replace(newExpression) val replacement = element.replace(newExpression)
if (notNullNeeded) { if (notNullNeeded) {
replacement.moveCaretToEnd(editor, project) replacement.moveCaretToEnd(editor, project)
@@ -55,8 +57,8 @@ abstract class ReplaceCallFix(
} }
class ReplaceImplicitReceiverCallFix( class ReplaceImplicitReceiverCallFix(
expression: KtExpression, expression: KtExpression,
private val notNullNeeded: Boolean private val notNullNeeded: Boolean
) : KotlinQuickFixAction<KtExpression>(expression) { ) : KotlinQuickFixAction<KtExpression>(expression) {
override fun getFamilyName() = text override fun getFamilyName() = text
@@ -74,8 +76,8 @@ class ReplaceImplicitReceiverCallFix(
} }
class ReplaceWithSafeCallFix( class ReplaceWithSafeCallFix(
expression: KtDotQualifiedExpression, expression: KtDotQualifiedExpression,
notNullNeeded: Boolean notNullNeeded: Boolean
) : ReplaceCallFix(expression, "?.", notNullNeeded) { ) : ReplaceCallFix(expression, "?.", notNullNeeded) {
override fun getText() = "Replace with safe (?.) call" override fun getText() = "Replace with safe (?.) call"
@@ -86,8 +88,7 @@ class ReplaceWithSafeCallFix(
val qualifiedExpression = psiElement.parent as? KtDotQualifiedExpression val qualifiedExpression = psiElement.parent as? KtDotQualifiedExpression
if (qualifiedExpression != null) { if (qualifiedExpression != null) {
return ReplaceWithSafeCallFix(qualifiedExpression, qualifiedExpression.shouldHaveNotNullType()) return ReplaceWithSafeCallFix(qualifiedExpression, qualifiedExpression.shouldHaveNotNullType())
} } else {
else {
if (psiElement !is KtNameReferenceExpression) return null if (psiElement !is KtNameReferenceExpression) return null
if (psiElement.getResolvedCall(psiElement.analyze())?.getImplicitReceiverValue() != null) { if (psiElement.getResolvedCall(psiElement.analyze())?.getImplicitReceiverValue() != null) {
val expressionToReplace: KtExpression = psiElement.parent as? KtCallExpression ?: psiElement val expressionToReplace: KtExpression = psiElement.parent as? KtCallExpression ?: psiElement
@@ -100,8 +101,8 @@ class ReplaceWithSafeCallFix(
} }
class ReplaceWithSafeCallForScopeFunctionFix( class ReplaceWithSafeCallForScopeFunctionFix(
expression: KtDotQualifiedExpression, expression: KtDotQualifiedExpression,
notNullNeeded: Boolean notNullNeeded: Boolean
) : ReplaceCallFix(expression, "?.", notNullNeeded) { ) : ReplaceCallFix(expression, "?.", notNullNeeded) {
override fun getText() = "Replace scope function with safe (?.) call" override fun getText() = "Replace scope function with safe (?.) call"
@@ -120,7 +121,7 @@ class ReplaceWithSafeCallForScopeFunctionFix(
val internalReceiver = (element.parent as? KtDotQualifiedExpression)?.receiverExpression val internalReceiver = (element.parent as? KtDotQualifiedExpression)?.receiverExpression
val internalReceiverDescriptor = internalReceiver.getResolvedCall(context)?.candidateDescriptor val internalReceiverDescriptor = internalReceiver.getResolvedCall(context)?.candidateDescriptor
val internalResolvedCall = (element.getParentOfType<KtElement>(strict = false))?.getResolvedCall(context) val internalResolvedCall = (element.getParentOfType<KtElement>(strict = false))?.getResolvedCall(context)
?: return null ?: return null
when (scopeFunctionKind) { when (scopeFunctionKind) {
ScopeFunctionKind.WITH_PARAMETER -> { ScopeFunctionKind.WITH_PARAMETER -> {
@@ -130,14 +131,16 @@ class ReplaceWithSafeCallForScopeFunctionFix(
} }
ScopeFunctionKind.WITH_RECEIVER -> { ScopeFunctionKind.WITH_RECEIVER -> {
if (internalReceiverDescriptor != scopeFunctionLiteralDescriptor.extensionReceiverParameter && if (internalReceiverDescriptor != scopeFunctionLiteralDescriptor.extensionReceiverParameter &&
internalResolvedCall.getImplicitReceiverValue() == null) { internalResolvedCall.getImplicitReceiverValue() == null
) {
return null return null
} }
} }
} }
return ReplaceWithSafeCallForScopeFunctionFix( return ReplaceWithSafeCallForScopeFunctionFix(
scopeDotQualifiedExpression, scopeDotQualifiedExpression.shouldHaveNotNullType()) scopeDotQualifiedExpression, scopeDotQualifiedExpression.shouldHaveNotNullType()
)
} }
private fun KtCallExpression.scopeFunctionKind(context: BindingContext): ScopeFunctionKind? { private fun KtCallExpression.scopeFunctionKind(context: BindingContext): ScopeFunctionKind? {