Quick Fixes: Replace strong references to PSI elements with smart pointers
#KT-14552 Fixed
This commit is contained in:
@@ -135,6 +135,7 @@ abstract class AddKotlinLibQuickFix(element: KtElement) : KotlinQuickFixAction<K
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val module = ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(element.containingFile.virtualFile)
|
||||
if (module != null) {
|
||||
if (KotlinPluginUtil.isMavenModule(module)) {
|
||||
|
||||
+2
-1
@@ -190,7 +190,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val declaration = element
|
||||
val declaration = element ?: return
|
||||
val fqName = declaration.resolveToDescriptor(BodyResolveMode.PARTIAL).importableFqName
|
||||
if (fqName != null) {
|
||||
ProgressManager.getInstance().run(
|
||||
@@ -231,6 +231,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val factory = KtPsiFactory(project)
|
||||
val name = element.nameAsName!!.render()
|
||||
element.addAnnotationWithLineBreak(factory.createAnnotationEntry("@Deprecated(\"Is replaced with automatic synthetic extension\", ReplaceWith(\"$name\"), level = DeprecationLevel.HIDDEN)"))
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.psi.KtOperationReferenceExpression
|
||||
|
||||
class InfixCallFix(expression: KtBinaryExpression) : KotlinQuickFixAction<KtBinaryExpression>(expression), CleanupFix {
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
InfixCallToOrdinaryIntention.convert(element)
|
||||
InfixCallToOrdinaryIntention.convert(element ?: return)
|
||||
}
|
||||
|
||||
override fun getFamilyName(): String = text
|
||||
|
||||
@@ -133,7 +133,7 @@ class KotlinCleanupInspection(): LocalInspectionTool(), CleanupLocalInspectionTo
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.delete()
|
||||
element?.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -80,11 +80,13 @@ interface AddValVarToConstructorParameterAction {
|
||||
class QuickFix(parameter: KtParameter) :
|
||||
KotlinQuickFixAction<KtParameter>(parameter),
|
||||
AddValVarToConstructorParameterAction {
|
||||
override fun getText() = getActionText(element)
|
||||
override fun getText() = element?.let { getActionText(it) } ?: ""
|
||||
|
||||
override fun getFamilyName() = actionFamily
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) = invoke(element, editor)
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
invoke(element ?: return, editor)
|
||||
}
|
||||
}
|
||||
|
||||
object QuickFixFactory : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
@@ -41,6 +41,7 @@ class AddArrayOfTypeFix(expression: KtExpression, expectedType: KotlinType) : Ko
|
||||
override fun getFamilyName() = "Add arrayOf wrapper"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val arrayOfExpression = KtPsiFactory(project).createExpressionByPattern("$0($1)", prefix, element)
|
||||
element.replace(arrayOfExpression)
|
||||
}
|
||||
|
||||
@@ -30,10 +30,11 @@ class AddInlineModifierFix(
|
||||
element: KtNameReferenceExpression,
|
||||
private val modifier: KtModifierKeywordToken
|
||||
) : KotlinQuickFixAction<KtNameReferenceExpression>(element) {
|
||||
override fun getText() = "Add '${modifier.value}' to parameter '${element.getReferencedName()}'"
|
||||
override fun getText() = element?.let { "Add '${modifier.value}' to parameter '${it.getReferencedName()}'" } ?: ""
|
||||
override fun getFamilyName() = "Add '${modifier.value}' to parameter"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val parameter = element.findParameterWithName(element.getReferencedName()) ?: return
|
||||
if (!parameter.hasModifier(modifier)) {
|
||||
parameter.addModifier(modifier)
|
||||
|
||||
@@ -30,10 +30,12 @@ class AddFunctionBodyFix(element: KtFunction) : KotlinQuickFixAction<KtFunction>
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && !element.hasBody()
|
||||
}
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
if (!element.hasBody()) {
|
||||
element.add(KtPsiFactory(project).createEmptyBody())
|
||||
}
|
||||
|
||||
@@ -37,12 +37,17 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import java.util.*
|
||||
|
||||
class AddFunctionParametersFix(
|
||||
private val callElement: KtCallElement,
|
||||
callElement: KtCallElement,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val hasTypeMismatches: Boolean) : ChangeFunctionSignatureFix(callElement, functionDescriptor) {
|
||||
private val callElement: KtCallElement?
|
||||
get() = element as? KtCallElement
|
||||
|
||||
private val typesToShorten = ArrayList<KotlinType>()
|
||||
|
||||
override fun getText(): String {
|
||||
val callElement = callElement ?: return ""
|
||||
|
||||
val parameters = functionDescriptor.valueParameters
|
||||
val arguments = callElement.valueArguments
|
||||
val newParametersCnt = arguments.size - parameters.size
|
||||
@@ -66,6 +71,7 @@ class AddFunctionParametersFix(
|
||||
}
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val callElement = callElement ?: return false
|
||||
if (!super.isAvailable(project, editor, file)) return false
|
||||
|
||||
// newParametersCnt <= 0: psi for this quickfix is no longer valid
|
||||
@@ -74,6 +80,7 @@ class AddFunctionParametersFix(
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val callElement = callElement ?: return
|
||||
runChangeSignature(project, functionDescriptor, addParameterConfiguration(), callElement, text)
|
||||
}
|
||||
|
||||
@@ -81,6 +88,7 @@ class AddFunctionParametersFix(
|
||||
return object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify {
|
||||
val callElement = callElement ?: return@modify
|
||||
val parameters = functionDescriptor.valueParameters
|
||||
val arguments = callElement.valueArguments
|
||||
val validator = CollectingNameValidator()
|
||||
|
||||
@@ -43,16 +43,18 @@ class AddGenericUpperBoundFix(
|
||||
) : KotlinQuickFixAction<KtTypeParameter>(typeParameter) {
|
||||
private val renderedUpperBound: String = IdeDescriptorRenderers.SOURCE_CODE.renderType(upperBound)
|
||||
|
||||
override fun getText() = "Add '$renderedUpperBound' as upper bound for ${element.name}"
|
||||
override fun getText() = element?.let { "Add '$renderedUpperBound' as upper bound for ${it.name}" } ?: ""
|
||||
override fun getFamilyName() = "Add generic upper bound"
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
if (!super.isAvailable(project, editor, file)) return false
|
||||
// TODO: replacing existing upper bounds
|
||||
return (element.name != null && element.extendsBound == null)
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
assert(element.extendsBound == null) { "Don't know what to do with existing bounds" }
|
||||
|
||||
val typeReference = KtPsiFactory(project).createType(renderedUpperBound)
|
||||
|
||||
@@ -34,6 +34,7 @@ class AddLoopLabelFix(loop: KtLoopExpression, val jumpExpression: KtElement): Ko
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val usedLabels = collectUsedLabels(element)
|
||||
val labelName = getUniqueLabelName(usedLabels)
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ open class AddModifierFix(
|
||||
) : KotlinQuickFixAction<KtModifierListOwner>(element) {
|
||||
|
||||
override fun getText(): String {
|
||||
val element = element ?: return ""
|
||||
if (modifier in modalityModifiers) {
|
||||
return "Make ${getElementName(element)} ${modifier.value}"
|
||||
}
|
||||
@@ -50,10 +51,11 @@ open class AddModifierFix(
|
||||
override fun getFamilyName() = "Add modifier"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.addModifier(modifier)
|
||||
element?.addModifier(modifier)
|
||||
}
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.canRefactor()
|
||||
}
|
||||
|
||||
|
||||
@@ -39,14 +39,15 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class AddNameToArgumentFix(argument: KtValueArgument) : KotlinQuickFixAction<KtValueArgument>(argument) {
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
if (!super.isAvailable(project, editor, file)) return false
|
||||
if (element.getArgumentExpression() == null) return false
|
||||
return calculatePossibleArgumentNames().isNotEmpty()
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val possibleNames = calculatePossibleArgumentNames()
|
||||
assert(possibleNames.isNotEmpty()) { "isAvailable() should be checked before invoke()" }
|
||||
if (possibleNames.size == 1 || editor == null || !editor.component.isShowing) {
|
||||
@@ -67,12 +68,12 @@ class AddNameToArgumentFix(argument: KtValueArgument) : KotlinQuickFixAction<KtV
|
||||
override fun getFamilyName() = "Add name to argument"
|
||||
|
||||
private fun calculatePossibleArgumentNames(): List<Name> {
|
||||
val callElement = element.getParentOfType<KtCallElement>(true) ?: return emptyList()
|
||||
val callElement = element!!.getParentOfType<KtCallElement>(true) ?: return emptyList()
|
||||
|
||||
val context = element.analyze(BodyResolveMode.PARTIAL)
|
||||
val context = element!!.analyze(BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = callElement.getResolvedCall(context) ?: return emptyList()
|
||||
|
||||
val argumentType = element.getArgumentExpression()?.let { context.getType(it) }
|
||||
val argumentType = element!!.getArgumentExpression()?.let { context.getType(it) }
|
||||
|
||||
val usedParameters = resolvedCall.call.valueArguments
|
||||
.map { resolvedCall.getArgumentMapping(it) }
|
||||
@@ -93,8 +94,8 @@ class AddNameToArgumentFix(argument: KtValueArgument) : KotlinQuickFixAction<KtV
|
||||
}
|
||||
|
||||
private fun createArgumentWithName(name: Name): KtValueArgument {
|
||||
val argumentExpression = element.getArgumentExpression()!!
|
||||
val newArgument = KtPsiFactory(element).createArgument(argumentExpression, name, element.getSpreadElement() != null)
|
||||
val argumentExpression = element!!.getArgumentExpression()!!
|
||||
val newArgument = KtPsiFactory(element!!).createArgument(argumentExpression, name, element!!.getSpreadElement() != null)
|
||||
return newArgument
|
||||
}
|
||||
|
||||
@@ -105,7 +106,7 @@ class AddNameToArgumentFix(argument: KtValueArgument) : KotlinQuickFixAction<KtV
|
||||
private fun getNamePopup(project: Project, names: List<Name>): ListPopupStep<Name> {
|
||||
return object : BaseListPopupStep<Name>("Choose parameter name", names) {
|
||||
override fun onChosen(selectedValue: Name, finalChoice: Boolean): PopupStep<*>? {
|
||||
addName(project, element, selectedValue)
|
||||
addName(project, element!!, selectedValue)
|
||||
return PopupStep.FINAL_CHOICE
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class AddNewLineAfterAnnotationsFix(element: KtAnnotatedExpression) : KotlinQuic
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val baseExpression = element.baseExpression ?: return
|
||||
val annotationsText = element.text.substring(0, baseExpression.startOffsetInParent)
|
||||
val newExpression = KtPsiFactory(project).createBlock(annotationsText + "\n" + baseExpression.text).statements[0]
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ class AddReifiedToTypeParameterOfFunctionFix(
|
||||
|
||||
val inlineFix = AddInlineToFunctionWithReifiedFix(function)
|
||||
|
||||
override fun getText() = "Make ${getElementName(element)} reified and ${getElementName(function)} inline"
|
||||
override fun getText() = element?.let { "Make ${getElementName(it)} reified and ${getElementName(function)} inline" } ?: ""
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
super.invoke(project, editor, file)
|
||||
|
||||
@@ -30,6 +30,7 @@ class AddRunToLambdaFix(element: KtLambdaExpression) : KotlinQuickFixAction<KtLa
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val factory = KtPsiFactory(project)
|
||||
element.replace(factory.createExpression("run ${element.text}"))
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ open class AddStarProjectionsFix private constructor(element: KtUserType,
|
||||
override fun getText() = "Add '${TypeReconstructionUtil.getTypeNameAndStarProjectionsString("", argumentCount)}'"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
assert(element.typeArguments.isEmpty())
|
||||
|
||||
val typeString = TypeReconstructionUtil.getTypeNameAndStarProjectionsString(element.text, argumentCount)
|
||||
|
||||
@@ -31,6 +31,7 @@ class AddToStringFix(element: KtExpression, private val nullable: Boolean) : Kot
|
||||
override fun getText() = if (nullable) "Add safe '?.toString()' call" else "Add 'toString()' call"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val pattern = if (nullable) "$0?.toString()" else "$0.toString()"
|
||||
val expressionToInsert = KtPsiFactory(file).createExpressionByPattern(pattern, element)
|
||||
val newExpression = element.replaced(expressionToInsert)
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class AddTypeAnnotationToValueParameterFix(element: KtParameter) : KotlinQuickFixAction<KtParameter>(element) {
|
||||
|
||||
val typeNameShort : String?
|
||||
val typeName: String?
|
||||
|
||||
@@ -44,13 +43,15 @@ class AddTypeAnnotationToValueParameterFix(element: KtParameter) : KotlinQuickFi
|
||||
}
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return element.typeReference == null && typeNameShort != null
|
||||
}
|
||||
|
||||
override fun getFamilyName() = "Add type annotation"
|
||||
override fun getText() = "Add type '$typeNameShort' to parameter '${element.name}'"
|
||||
override fun getText() = element?.let { "Add type '$typeNameShort' to parameter '${it.name}'" } ?: ""
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
if (typeName != null) {
|
||||
element.typeReference = KtPsiFactory(element).createType(typeName)
|
||||
ShortenReferences.DEFAULT.process(element)
|
||||
|
||||
@@ -36,6 +36,7 @@ class AddTypeToLHSOfCallableReferenceFix(
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val resolvedCall = element.callableReference.getResolvedCall(element.analyze(BodyResolveMode.PARTIAL)) ?: return
|
||||
val receiver = with(resolvedCall) {
|
||||
dispatchReceiver ?: extensionReceiver ?: return
|
||||
|
||||
@@ -30,10 +30,12 @@ class AddWhenElseBranchFix(element: KtWhenExpression) : KotlinQuickFixAction<KtW
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.closeBrace != null
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val psiFactory = KtPsiFactory(file)
|
||||
val entry = psiFactory.createWhenEntry("else -> {}")
|
||||
val whenCloseBrace = element.closeBrace ?: error("isAvailable should check if close brace exist")
|
||||
|
||||
@@ -35,13 +35,14 @@ class AddWhenRemainingBranchesFix(expression: KtWhenExpression) : KotlinQuickFix
|
||||
|
||||
override fun getText() = "Add remaining branches"
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean =
|
||||
super.isAvailable(project, editor, file) && element.closeBrace != null &&
|
||||
with(WhenChecker.getMissingCases(element, element.analyze())) {
|
||||
isNotEmpty() && !hasUnknown
|
||||
}
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.closeBrace != null &&
|
||||
with(WhenChecker.getMissingCases(element, element.analyze())) { isNotEmpty() && !hasUnknown }
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val missingCases = WhenChecker.getMissingCases(element, element.analyze())
|
||||
|
||||
val whenCloseBrace = element.closeBrace ?: throw AssertionError("isAvailable should check if close brace exist")
|
||||
|
||||
@@ -42,12 +42,13 @@ class CastExpressionFix(element: KtExpression, type: KotlinType) : KotlinQuickFi
|
||||
}
|
||||
|
||||
override fun getFamilyName() = "Cast expression"
|
||||
override fun getText() = "Cast expression '${element.text}' to '$typePresentation'"
|
||||
override fun getText() = element?.let { "Cast expression '${it.text}' to '$typePresentation'" } ?: ""
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
|
||||
= upOrDownCast && super.isAvailable(project, editor, file)
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val expressionToInsert = KtPsiFactory(file).createExpressionByPattern("$0 as $1", element, typeSourceCode)
|
||||
val newExpression = element.replaced(expressionToInsert)
|
||||
ShortenReferences.DEFAULT.process((KtPsiUtil.safeDeparenthesize(newExpression) as KtBinaryExpressionWithTypeRHS).right!!)
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class ChangeAccessorTypeFix(element: KtPropertyAccessor) : KotlinQuickFixAction<KtPropertyAccessor>(element) {
|
||||
private fun getType(): KotlinType? {
|
||||
val type = (element.property.resolveToDescriptor() as VariableDescriptor).type
|
||||
val type = (element!!.property.resolveToDescriptor() as VariableDescriptor).type
|
||||
if (type.isError) return null
|
||||
return type
|
||||
}
|
||||
@@ -43,6 +43,7 @@ class ChangeAccessorTypeFix(element: KtPropertyAccessor) : KotlinQuickFixAction<
|
||||
override fun getFamilyName() = "Change accessor type"
|
||||
|
||||
override fun getText(): String {
|
||||
val element = element ?: return ""
|
||||
val type = getType() ?: return familyName
|
||||
val renderedType = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
|
||||
val target = if (element.isGetter) "getter" else "setter parameter"
|
||||
@@ -50,6 +51,7 @@ class ChangeAccessorTypeFix(element: KtPropertyAccessor) : KotlinQuickFixAction<
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val type = getType()!!
|
||||
val newTypeReference = KtPsiFactory(file).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type))
|
||||
|
||||
|
||||
@@ -44,7 +44,8 @@ class ChangeFunctionLiteralReturnTypeFix(
|
||||
|
||||
private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
|
||||
private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||
private val functionLiteralReturnTypeRef = functionLiteralExpression.functionLiteral.typeReference
|
||||
private val functionLiteralReturnTypeRef: KtTypeReference?
|
||||
get() = element?.functionLiteral?.typeReference
|
||||
private val appropriateQuickFix = createAppropriateQuickFix(functionLiteralExpression, type)
|
||||
|
||||
private fun createAppropriateQuickFix(functionLiteralExpression: KtLambdaExpression, type: KotlinType): IntentionAction? {
|
||||
@@ -113,8 +114,8 @@ class ChangeFunctionLiteralReturnTypeFix(
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
if (functionLiteralReturnTypeRef != null) {
|
||||
val newTypeRef = functionLiteralReturnTypeRef.replace(KtPsiFactory(file).createType(typeSourceCode)) as KtTypeReference
|
||||
functionLiteralReturnTypeRef?.let {
|
||||
val newTypeRef = it.replace(KtPsiFactory(file).createType(typeSourceCode)) as KtTypeReference
|
||||
ShortenReferences.DEFAULT.process(newTypeRef)
|
||||
}
|
||||
if (appropriateQuickFix != null && appropriateQuickFix.isAvailable(project, editor!!, file)) {
|
||||
|
||||
@@ -40,6 +40,7 @@ class ChangeFunctionLiteralSignatureFix private constructor(
|
||||
override fun getText() = "Change the signature of lambda expression"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
runChangeSignature(
|
||||
project,
|
||||
functionDescriptor,
|
||||
@@ -58,7 +59,7 @@ class ChangeFunctionLiteralSignatureFix private constructor(
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>) = false
|
||||
override fun forcePerformForSelectedFunctionOnly() = false
|
||||
},
|
||||
context,
|
||||
element,
|
||||
text)
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ abstract class ChangeFunctionReturnTypeFix(element: KtFunction, type: KotlinType
|
||||
}
|
||||
|
||||
open fun functionPresentation(): String? {
|
||||
val element = element!!
|
||||
val name = element.name
|
||||
if (name != null) {
|
||||
val container = element.resolveToDescriptor().containingDeclaration as? ClassDescriptor
|
||||
@@ -105,6 +106,8 @@ abstract class ChangeFunctionReturnTypeFix(element: KtFunction, type: KotlinType
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
val element = element ?: return ""
|
||||
|
||||
if (changeFunctionLiteralReturnTypeFix != null) {
|
||||
return changeFunctionLiteralReturnTypeFix.text
|
||||
}
|
||||
@@ -133,6 +136,8 @@ abstract class ChangeFunctionReturnTypeFix(element: KtFunction, type: KotlinType
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
|
||||
if (changeFunctionLiteralReturnTypeFix != null) {
|
||||
changeFunctionLiteralReturnTypeFix.invoke(project, editor!!, file)
|
||||
}
|
||||
|
||||
@@ -45,10 +45,9 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
|
||||
abstract class ChangeFunctionSignatureFix(
|
||||
protected val context: PsiElement,
|
||||
element: PsiElement,
|
||||
protected val functionDescriptor: FunctionDescriptor
|
||||
) : KotlinQuickFixAction<PsiElement>(context) {
|
||||
|
||||
) : KotlinQuickFixAction<PsiElement>(element) {
|
||||
override fun getFamilyName() = FAMILY_NAME
|
||||
|
||||
override fun startInWriteAction() = false
|
||||
@@ -116,15 +115,15 @@ abstract class ChangeFunctionSignatureFix(
|
||||
}
|
||||
|
||||
private class RemoveParameterFix(
|
||||
context: PsiElement,
|
||||
element: PsiElement,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
private val parameterToRemove: ValueParameterDescriptor
|
||||
) : ChangeFunctionSignatureFix(context, functionDescriptor) {
|
||||
) : ChangeFunctionSignatureFix(element, functionDescriptor) {
|
||||
|
||||
override fun getText() = "Remove parameter '${parameterToRemove.name.asString()}'"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
runRemoveParameter(parameterToRemove, context)
|
||||
runRemoveParameter(parameterToRemove, element ?: return)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +235,7 @@ class ChangeMemberFunctionSignatureFix private constructor(
|
||||
override fun getFamilyName() = "Change function signature"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
MyAction(project, editor, element, signatures).execute()
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ class ChangeParameterTypeFix(element: KtParameter, type: KotlinType) : KotlinQui
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
val element = element ?: return ""
|
||||
return if (isPrimaryConstructorParameter)
|
||||
"Change parameter '${element.name}' type of primary constructor of class '$containingDeclarationName' to '$typePresentation'"
|
||||
else
|
||||
@@ -63,6 +64,7 @@ class ChangeParameterTypeFix(element: KtParameter, type: KotlinType) : KotlinQui
|
||||
override fun getFamilyName() = KotlinBundle.message("change.type.family")
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val function = element.getStrictParentOfType<KtFunction>() ?: return
|
||||
val parameterIndex = function.valueParameters.indexOf(element)
|
||||
val context = function.analyze()
|
||||
|
||||
@@ -30,6 +30,7 @@ class ChangeToFunctionInvocationFix(element: KtExpression) : KotlinQuickFixActio
|
||||
override fun getText() = familyName
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
element.replace(KtPsiFactory(file).createExpressionByPattern("$0()", element))
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ class ChangeToPropertyAccessFix(element: KtCallExpression) : KotlinQuickFixActio
|
||||
override fun getText() = familyName
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
element.replace(element.calleeExpression as KtExpression)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,10 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
class ChangeToStarProjectionFix(element: KtTypeElement) : KotlinQuickFixAction<KtTypeElement>(element) {
|
||||
override fun getFamilyName() = "Change to star projection"
|
||||
|
||||
override fun getText() = "Change type arguments to <${element.typeArgumentsAsTypes.joinToString { "*" }}>"
|
||||
override fun getText() = element?.let { "Change type arguments to <${it.typeArgumentsAsTypes.joinToString { "*" }}>" } ?: ""
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val star = KtPsiFactory(file).createStar()
|
||||
element.typeArgumentsAsTypes.forEach { it?.replace(star) }
|
||||
}
|
||||
|
||||
@@ -33,11 +33,12 @@ class ChangeTypeFix(element: KtTypeReference, private val type: KotlinType) : Ko
|
||||
override fun getFamilyName() = "Change type"
|
||||
|
||||
override fun getText(): String {
|
||||
val currentTypeText = element.text
|
||||
val currentTypeText = element?.text ?: return ""
|
||||
return "Change type from '$currentTypeText' to '${QuickFixUtil.renderTypeWithFqNameOnClash(type, currentTypeText)}'"
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val newTypeRef = element.replaced(KtPsiFactory(file).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)))
|
||||
ShortenReferences.DEFAULT.process(newTypeRef)
|
||||
}
|
||||
|
||||
@@ -36,11 +36,13 @@ class ChangeVariableMutabilityFix(element: KtValVarKeywordOwner, private val mak
|
||||
override fun getFamilyName(): String = text
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
val valOrVar = element.valOrVarKeyword?.node?.elementType ?: return false
|
||||
return (valOrVar == KtTokens.VAR_KEYWORD) != makeVar
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val factory = KtPsiFactory(project)
|
||||
val newKeyword = if (makeVar) factory.createVarKeyword() else factory.createValKeyword()
|
||||
element.valOrVarKeyword!!.replace(newKeyword)
|
||||
|
||||
@@ -45,6 +45,7 @@ open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinTyp
|
||||
private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||
|
||||
open fun variablePresentation(): String? {
|
||||
val element = element!!
|
||||
val name = element.name
|
||||
if (name != null) {
|
||||
val container = element.resolveToDescriptor().containingDeclaration as? ClassDescriptor
|
||||
@@ -57,6 +58,8 @@ open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinTyp
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
if (element == null) return ""
|
||||
|
||||
val variablePresentation = variablePresentation()
|
||||
if (variablePresentation != null) {
|
||||
return "Change type of $variablePresentation to '$typePresentation'"
|
||||
@@ -84,6 +87,7 @@ open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinTyp
|
||||
= !typeContainsError && super.isAvailable(project, editor, file)
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val psiFactory = KtPsiFactory(file)
|
||||
|
||||
assert(element.nameIdentifier != null) { "ChangeVariableTypeFix applied to variable without name" }
|
||||
|
||||
@@ -43,7 +43,7 @@ open class ChangeVisibilityFix(
|
||||
override fun getFamilyName() = "Make $visibilityModifier"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.setVisibility(visibilityModifier)
|
||||
element?.setVisibility(visibilityModifier)
|
||||
}
|
||||
|
||||
protected class ChangeToPublicFix(element: KtModifierListOwner, elementName: String) :
|
||||
@@ -52,8 +52,10 @@ open class ChangeVisibilityFix(
|
||||
protected class ChangeToProtectedFix(element: KtModifierListOwner, elementName: String) :
|
||||
ChangeVisibilityFix(element, elementName, KtTokens.PROTECTED_KEYWORD) {
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile) =
|
||||
super.isAvailable(project, editor, file) && element.canBeProtected()
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.canBeProtected()
|
||||
}
|
||||
}
|
||||
|
||||
protected class ChangeToInternalFix(element: KtModifierListOwner, elementName: String) :
|
||||
@@ -62,8 +64,10 @@ open class ChangeVisibilityFix(
|
||||
protected class ChangeToPrivateFix(element: KtModifierListOwner, elementName: String) :
|
||||
ChangeVisibilityFix(element, elementName, KtTokens.PRIVATE_KEYWORD), HighPriorityAction {
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile) =
|
||||
super.isAvailable(project, editor, file) && element.canBePrivate()
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.canBePrivate()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -29,6 +29,7 @@ class ChangeVisibilityModifierFix(element: KtDeclaration) : KotlinQuickFixAction
|
||||
override fun getText() = familyName
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
element.removeModifier(element.visibilityModifierType()!!)
|
||||
}
|
||||
|
||||
|
||||
@@ -56,13 +56,14 @@ class ConvertClassToKClassFix(element: KtDotQualifiedExpression, type: KotlinTyp
|
||||
return@run firstChildType.isSubtypeOf(type)
|
||||
}
|
||||
|
||||
override fun getText() = "Remove '.${element.children.lastOrNull()?.text}'"
|
||||
override fun getText() = element?.let { "Remove '.${it.children.lastOrNull()?.text}'" } ?: ""
|
||||
override fun getFamilyName() = "Remove conversion from 'KClass' to 'Class'"
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
|
||||
= isApplicable && super.isAvailable(project, editor, file)
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
element.replace(element.firstChild)
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -32,6 +32,7 @@ class ConvertExtensionPropertyInitializerToGetterFix(element: KtExpression) : Ko
|
||||
override fun getFamilyName(): String = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val property = element.getParentOfType<KtProperty>(true) ?: return
|
||||
ConvertPropertyInitializerToGetterIntention.convertPropertyInitializerToGetter(property, editor)
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ class ConvertExtensionToFunctionTypeFix(element: KtTypeReference, type: KotlinTy
|
||||
override fun getFamilyName() = "Convert extension function type to regular function type"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val replaced = element.replaced(KtPsiFactory(project).createType(targetTypeStringLong))
|
||||
ShortenReferences.DEFAULT.process(replaced)
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.util.isValidOperator
|
||||
|
||||
abstract class ExclExclCallFix : IntentionAction {
|
||||
abstract class ExclExclCallFix(psiElement: PsiElement) : KotlinQuickFixAction<PsiElement>(psiElement) {
|
||||
override fun getFamilyName(): String = text
|
||||
|
||||
override fun startInWriteAction(): Boolean = true
|
||||
@@ -47,13 +47,13 @@ abstract class ExclExclCallFix : IntentionAction {
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile) = file is KtFile
|
||||
}
|
||||
|
||||
class RemoveExclExclCallFix(val psiElement: PsiElement) : ExclExclCallFix(), CleanupFix {
|
||||
class RemoveExclExclCallFix(psiElement: PsiElement) : ExclExclCallFix(psiElement), CleanupFix {
|
||||
override fun getText(): String = KotlinBundle.message("remove.unnecessary.non.null.assertion")
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean
|
||||
= super.isAvailable(project, editor, file) && getExclExclPostfixExpression() != null
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return
|
||||
|
||||
val postfixExpression = getExclExclPostfixExpression() ?: return
|
||||
@@ -62,7 +62,7 @@ class RemoveExclExclCallFix(val psiElement: PsiElement) : ExclExclCallFix(), Cle
|
||||
}
|
||||
|
||||
private fun getExclExclPostfixExpression(): KtPostfixExpression? {
|
||||
val operationParent = psiElement.parent
|
||||
val operationParent = element?.parent
|
||||
if (operationParent is KtPostfixExpression && operationParent.baseExpression != null) {
|
||||
return operationParent
|
||||
}
|
||||
@@ -75,14 +75,14 @@ class RemoveExclExclCallFix(val psiElement: PsiElement) : ExclExclCallFix(), Cle
|
||||
}
|
||||
}
|
||||
|
||||
class AddExclExclCallFix(val psiElement: PsiElement) : ExclExclCallFix() {
|
||||
class AddExclExclCallFix(psiElement: PsiElement) : ExclExclCallFix(psiElement) {
|
||||
override fun getText() = KotlinBundle.message("introduce.non.null.assertion")
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean
|
||||
= super.isAvailable(project, editor, file) &&
|
||||
getExpressionForIntroduceCall() != null
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return
|
||||
|
||||
val modifiedExpression = getExpressionForIntroduceCall() ?: return
|
||||
@@ -91,6 +91,7 @@ class AddExclExclCallFix(val psiElement: PsiElement) : ExclExclCallFix() {
|
||||
}
|
||||
|
||||
private fun getExpressionForIntroduceCall(): KtExpression? {
|
||||
val psiElement = element ?: return null
|
||||
if (psiElement is LeafPsiElement && psiElement.elementType == KtTokens.DOT) {
|
||||
val sibling = psiElement.prevSibling
|
||||
if (sibling is KtExpression) {
|
||||
|
||||
@@ -86,27 +86,30 @@ internal abstract class ImportFixBase<T : KtExpression> protected constructor(
|
||||
expression: T,
|
||||
private val factory: Factory
|
||||
) : KotlinQuickFixAction<T>(expression), HighPriorityAction, HintAction {
|
||||
private val project = expression.project
|
||||
|
||||
private val modificationCountOnCreate = PsiModificationTracker.SERVICE.getInstance(element.project).modificationCount
|
||||
private val modificationCountOnCreate = PsiModificationTracker.SERVICE.getInstance(project).modificationCount
|
||||
|
||||
private val suggestionCount: Int by CachedValueProperty(
|
||||
calculator = { computeSuggestions().size },
|
||||
timestampCalculator = { PsiModificationTracker.SERVICE.getInstance(element.project).modificationCount }
|
||||
timestampCalculator = { PsiModificationTracker.SERVICE.getInstance(project).modificationCount }
|
||||
)
|
||||
|
||||
protected open fun getSupportedErrors() = factory.supportedErrors
|
||||
|
||||
protected abstract val importNames: Collection<Name>
|
||||
protected abstract fun getCallTypeAndReceiver(): CallTypeAndReceiver<*, *>
|
||||
protected abstract fun getCallTypeAndReceiver(): CallTypeAndReceiver<*, *>?
|
||||
|
||||
override fun showHint(editor: Editor): Boolean {
|
||||
val element = element ?: return false
|
||||
|
||||
if (!element.isValid || isOutdated()) return false
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode && HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)) return false
|
||||
|
||||
if (suggestionCount == 0) return false
|
||||
|
||||
return createAction(element.project, editor).showHint()
|
||||
return createAction(project, editor, element).showHint()
|
||||
}
|
||||
|
||||
override fun getText() = KotlinBundle.message("import.fix")
|
||||
@@ -114,27 +117,29 @@ internal abstract class ImportFixBase<T : KtExpression> protected constructor(
|
||||
override fun getFamilyName() = KotlinBundle.message("import.fix")
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
|
||||
= super.isAvailable(project, editor, file) && suggestionCount > 0
|
||||
= element != null && super.isAvailable(project, editor, file) && suggestionCount > 0
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
createAction(project, editor!!).execute()
|
||||
createAction(project, editor!!, element).execute()
|
||||
}
|
||||
}
|
||||
|
||||
override fun startInWriteAction() = true
|
||||
|
||||
private fun isOutdated() = modificationCountOnCreate != PsiModificationTracker.SERVICE.getInstance(element.project).modificationCount
|
||||
private fun isOutdated() = modificationCountOnCreate != PsiModificationTracker.SERVICE.getInstance(project).modificationCount
|
||||
|
||||
protected open fun createAction(project: Project, editor: Editor): KotlinAddImportAction {
|
||||
protected open fun createAction(project: Project, editor: Editor, element: KtExpression): KotlinAddImportAction {
|
||||
return createSingleImportAction(project, editor, element, computeSuggestions())
|
||||
}
|
||||
|
||||
fun computeSuggestions(): Collection<DeclarationDescriptor> {
|
||||
if (!element.isValid) return listOf()
|
||||
val element = element ?: return emptyList()
|
||||
if (!element.isValid) return emptyList()
|
||||
if (element.containingFile !is KtFile) return emptyList()
|
||||
|
||||
val callTypeAndReceiver = getCallTypeAndReceiver()
|
||||
val callTypeAndReceiver = getCallTypeAndReceiver() ?: return emptyList()
|
||||
|
||||
if (callTypeAndReceiver is CallTypeAndReceiver.UNKNOWN) return emptyList()
|
||||
|
||||
@@ -146,6 +151,7 @@ internal abstract class ImportFixBase<T : KtExpression> protected constructor(
|
||||
}
|
||||
|
||||
private fun computeSuggestionsForName(name: Name, callTypeAndReceiver: CallTypeAndReceiver<*, *>): Collection<DeclarationDescriptor> {
|
||||
val element = element ?: return emptyList()
|
||||
val nameStr = name.asString()
|
||||
if (nameStr.isEmpty()) return emptyList()
|
||||
|
||||
@@ -192,7 +198,7 @@ internal abstract class ImportFixBase<T : KtExpression> protected constructor(
|
||||
.any { diagnostic -> diagnostic.factory in getSupportedErrors() }
|
||||
}
|
||||
|
||||
protected open fun elementsToCheckDiagnostics(): Collection<PsiElement> = listOf(element)
|
||||
protected open fun elementsToCheckDiagnostics(): Collection<PsiElement> = element.singletonOrEmptyList()
|
||||
|
||||
abstract fun fillCandidates(
|
||||
name: String,
|
||||
@@ -225,9 +231,9 @@ internal abstract class OrdinaryImportFixBase<T : KtExpression>(expression: T, f
|
||||
bindingContext: BindingContext,
|
||||
indicesHelper: KotlinIndicesHelper
|
||||
): List<DeclarationDescriptor> {
|
||||
val result = ArrayList<DeclarationDescriptor>()
|
||||
val expression = element ?: return emptyList()
|
||||
|
||||
val expression = element
|
||||
val result = ArrayList<DeclarationDescriptor>()
|
||||
|
||||
if (expression is KtSimpleNameExpression) {
|
||||
if (!expression.isImportDirectiveExpression() && !isSelectorInQualified(expression)) {
|
||||
@@ -252,9 +258,9 @@ internal abstract class OrdinaryImportFixBase<T : KtExpression>(expression: T, f
|
||||
}
|
||||
|
||||
internal class ImportFix(expression: KtSimpleNameExpression) : OrdinaryImportFixBase<KtSimpleNameExpression>(expression, MyFactory) {
|
||||
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.detect(element)
|
||||
override fun getCallTypeAndReceiver() = element?.let { CallTypeAndReceiver.detect(it) }
|
||||
|
||||
override val importNames = element.mainReference.resolvesByNames
|
||||
override val importNames = element?.mainReference?.resolvesByNames ?: emptyList()
|
||||
|
||||
companion object MyFactory : Factory() {
|
||||
override fun createAction(diagnostic: Diagnostic) =
|
||||
@@ -265,7 +271,7 @@ internal class ImportFix(expression: KtSimpleNameExpression) : OrdinaryImportFix
|
||||
internal class InvokeImportFix(expression: KtExpression) : OrdinaryImportFixBase<KtExpression>(expression, MyFactory) {
|
||||
override val importNames = OperatorNameConventions.INVOKE.singletonList()
|
||||
|
||||
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.OPERATOR(element)
|
||||
override fun getCallTypeAndReceiver() = element?.let { CallTypeAndReceiver.OPERATOR(it) }
|
||||
|
||||
companion object MyFactory : Factory() {
|
||||
override fun createAction(diagnostic: Diagnostic) =
|
||||
@@ -279,8 +285,7 @@ internal open class ArrayAccessorImportFix(
|
||||
private val showHint: Boolean
|
||||
) : OrdinaryImportFixBase<KtArrayAccessExpression>(element, MyFactory) {
|
||||
|
||||
override fun getCallTypeAndReceiver() =
|
||||
CallTypeAndReceiver.OPERATOR(element.arrayExpression!!)
|
||||
override fun getCallTypeAndReceiver() = element?.let { CallTypeAndReceiver.OPERATOR(it.arrayExpression!!) }
|
||||
|
||||
override fun showHint(editor: Editor) = showHint && super.showHint(editor)
|
||||
|
||||
@@ -315,12 +320,12 @@ internal class DelegateAccessorsImportFix(
|
||||
|
||||
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.DELEGATE(element)
|
||||
|
||||
override fun createAction(project: Project, editor: Editor): KotlinAddImportAction {
|
||||
override fun createAction(project: Project, editor: Editor, element: KtExpression): KotlinAddImportAction {
|
||||
if (solveSeveralProblems) {
|
||||
return createGroupedImportsAction(project, editor, element, "Delegate accessors", computeSuggestions())
|
||||
}
|
||||
|
||||
return super.createAction(project, editor)
|
||||
return super.createAction(project, editor, element)
|
||||
}
|
||||
|
||||
companion object MyFactory : Factory() {
|
||||
@@ -354,14 +359,14 @@ internal class ComponentsImportFix(
|
||||
private val solveSeveralProblems: Boolean
|
||||
) : OrdinaryImportFixBase<KtExpression>(element, MyFactory) {
|
||||
|
||||
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.OPERATOR(element)
|
||||
override fun getCallTypeAndReceiver() = element?.let { CallTypeAndReceiver.OPERATOR(it) }
|
||||
|
||||
override fun createAction(project: Project, editor: Editor): KotlinAddImportAction {
|
||||
override fun createAction(project: Project, editor: Editor, element: KtExpression): KotlinAddImportAction {
|
||||
if (solveSeveralProblems) {
|
||||
return createGroupedImportsAction(project, editor, element, "Component functions", computeSuggestions())
|
||||
}
|
||||
|
||||
return super.createAction(project, editor)
|
||||
return super.createAction(project, editor, element)
|
||||
}
|
||||
|
||||
companion object MyFactory : Factory() {
|
||||
@@ -393,6 +398,8 @@ internal class ImportMemberFix(expression: KtSimpleNameExpression) : ImportFixBa
|
||||
bindingContext: BindingContext,
|
||||
indicesHelper: KotlinIndicesHelper
|
||||
): List<DeclarationDescriptor> {
|
||||
val element = element ?: return emptyList()
|
||||
|
||||
val result = ArrayList<DeclarationDescriptor>()
|
||||
if (!element.isImportDirectiveExpression() && !isSelectorInQualified(element)) {
|
||||
val filterByCallType = { descriptor: DeclarationDescriptor -> callTypeAndReceiver.callType.descriptorKindFilter.accepts(descriptor) }
|
||||
@@ -420,9 +427,11 @@ internal class ImportMemberFix(expression: KtSimpleNameExpression) : ImportFixBa
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.detect(element)
|
||||
override fun getCallTypeAndReceiver() = element?.let { CallTypeAndReceiver.detect(it) }
|
||||
|
||||
override val importNames: Collection<Name> = run {
|
||||
val element = element ?: return@run emptyList()
|
||||
|
||||
if (element.getIdentifier() != null) {
|
||||
val name = element.getReferencedName()
|
||||
if (Name.isValidIdentifier(name)) {
|
||||
@@ -440,11 +449,12 @@ internal class ImportMemberFix(expression: KtSimpleNameExpression) : ImportFixBa
|
||||
internal class ImportForMismatchingArgumentsFix(
|
||||
expression: KtSimpleNameExpression
|
||||
) : ImportFixBase<KtSimpleNameExpression>(expression, MyFactory) {
|
||||
override fun getCallTypeAndReceiver() = CallTypeAndReceiver.detect(element)
|
||||
override fun getCallTypeAndReceiver() = element?.let { CallTypeAndReceiver.detect(it) }
|
||||
|
||||
override val importNames = element.mainReference.resolvesByNames
|
||||
override val importNames = element?.mainReference?.resolvesByNames ?: emptyList()
|
||||
|
||||
override fun elementsToCheckDiagnostics(): Collection<PsiElement> {
|
||||
val element = element ?: return emptyList()
|
||||
val callExpression = element.parent as? KtCallExpression ?: return emptyList()
|
||||
return callExpression.valueArguments +
|
||||
callExpression.valueArguments.mapNotNull { it.getArgumentExpression() } +
|
||||
@@ -458,6 +468,8 @@ internal class ImportForMismatchingArgumentsFix(
|
||||
bindingContext: BindingContext,
|
||||
indicesHelper: KotlinIndicesHelper
|
||||
): List<DeclarationDescriptor> {
|
||||
val element = element ?: return emptyList()
|
||||
|
||||
if (!Name.isValidIdentifier(name)) return emptyList()
|
||||
val identifier = Name.identifier(name)
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val descriptor = element.resolveToDescriptorIfAny() as? PropertyDescriptor ?: return
|
||||
val initializerText = CodeInsightUtils.defaultInitializer(descriptor.type) ?: "null"
|
||||
val initializer = element.setInitializer(KtPsiFactory(project).createExpression(initializerText))!!
|
||||
@@ -72,7 +73,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
private fun configureChangeSignature(propertyDescriptor: PropertyDescriptor): KotlinChangeSignatureConfiguration {
|
||||
private fun configureChangeSignature(property: KtProperty, propertyDescriptor: PropertyDescriptor): KotlinChangeSignatureConfiguration {
|
||||
return object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify {
|
||||
@@ -81,9 +82,9 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
callableDescriptor = originalDescriptor.baseDescriptor,
|
||||
name = propertyDescriptor.name.asString(),
|
||||
originalTypeInfo = KotlinTypeInfo(false, propertyDescriptor.type),
|
||||
valOrVar = element.valOrVarKeyword.toValVar(),
|
||||
modifierList = element.modifierList,
|
||||
defaultValueForCall = KtPsiFactory(element.project).createExpression(initializerText)
|
||||
valOrVar = property.valOrVarKeyword.toValVar(),
|
||||
modifierList = property.modifierList,
|
||||
defaultValueForCall = KtPsiFactory(property.project).createExpression(initializerText)
|
||||
)
|
||||
it.addParameter(newParam)
|
||||
}
|
||||
@@ -94,6 +95,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val klass = element.containingClassOrObject ?: return
|
||||
val propertyDescriptor = element.resolveToDescriptorIfAny() as? PropertyDescriptor ?: return
|
||||
|
||||
@@ -108,7 +110,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
val constructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return
|
||||
val contextElement = constructorDescriptor.source.getPsi() ?: return
|
||||
val constructorPointer = contextElement.createSmartPointer()
|
||||
val config = configureChangeSignature(propertyDescriptor)
|
||||
val config = configureChangeSignature(element, propertyDescriptor)
|
||||
val changeSignature = { runChangeSignature(project, constructorDescriptor, config, contextElement, text) }
|
||||
changeSignature.runRefactoringWithPostprocessing(project, "refactoring.changeSignature") {
|
||||
val constructorOrClass = constructorPointer.element
|
||||
@@ -142,7 +144,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
callableDescriptor = originalDescriptor.baseDescriptor,
|
||||
name = KotlinNameSuggester.suggestNameByName(propertyDescriptor.name.asString(), validator),
|
||||
originalTypeInfo = KotlinTypeInfo(false, propertyDescriptor.type),
|
||||
defaultValueForCall = KtPsiFactory(element.project).createExpression(initializerText)
|
||||
defaultValueForCall = KtPsiFactory(element!!.project).createExpression(initializerText)
|
||||
)
|
||||
it.addParameter(newParam)
|
||||
}
|
||||
@@ -159,6 +161,8 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
descriptorsToProcess: Iterator<ConstructorDescriptor>,
|
||||
visitedElements: MutableSet<PsiElement> = HashSet()
|
||||
) {
|
||||
val element = element!!
|
||||
|
||||
if (!descriptorsToProcess.hasNext()) return
|
||||
val descriptor = descriptorsToProcess.next()
|
||||
val constructorPointer = descriptor.source.getPsi()?.createSmartPointer()
|
||||
@@ -180,6 +184,7 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val propertyDescriptor = element.resolveToDescriptorIfAny() as? PropertyDescriptor ?: return
|
||||
val classDescriptor = propertyDescriptor.containingDeclaration as? ClassDescriptorWithResolutionScopes ?: return
|
||||
val klass = element.containingClassOrObject ?: return
|
||||
|
||||
@@ -44,6 +44,7 @@ class InsertDelegationCallQuickfix(val isThis: Boolean, element: KtSecondaryCons
|
||||
private val keywordToUse = if (isThis) "this" else "super"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val newDelegationCall = element.replaceImplicitDelegationCallWithExplicit(isThis)
|
||||
|
||||
val resolvedCall = newDelegationCall.getResolvedCall(newDelegationCall.analyze())
|
||||
@@ -58,6 +59,7 @@ class InsertDelegationCallQuickfix(val isThis: Boolean, element: KtSecondaryCons
|
||||
}
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.hasImplicitDelegationCall()
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,16 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
|
||||
abstract class KotlinQuickFixAction<out T : PsiElement>(protected val element: T) : IntentionAction {
|
||||
abstract class KotlinQuickFixAction<out T : PsiElement>(element: T) : IntentionAction {
|
||||
private val elementPointer = element.createSmartPointer()
|
||||
|
||||
protected val element: T?
|
||||
get() = elementPointer.element
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return element.isValid &&
|
||||
!element.project.isDisposed &&
|
||||
(file.manager.isInProject(file) || file is KtCodeFragment) &&
|
||||
@@ -35,6 +41,7 @@ abstract class KotlinQuickFixAction<out T : PsiElement>(protected val element: T
|
||||
}
|
||||
|
||||
override final fun invoke(project: Project, editor: Editor?, file: PsiFile) {
|
||||
val element = element ?: return
|
||||
if (file is KtFile && FileModificationService.getInstance().prepareFileForWrite(element.containingFile)) {
|
||||
invoke(project, editor, file)
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ class LetImplementInterfaceFix(
|
||||
super.isAvailable(project, editor, file) && validExpectedType
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val superTypeEntry = KtPsiFactory(element).createSuperTypeEntry(expectedTypeNameSourceCode)
|
||||
val entryElement = element.addSuperTypeListEntry(superTypeEntry)
|
||||
ShortenReferences.DEFAULT.process(entryElement)
|
||||
|
||||
@@ -29,6 +29,7 @@ class LiftAssignmentOutOfTryFix(element: KtTryExpression): KotlinQuickFixAction<
|
||||
override fun getText() = "Lift assignment out of 'try' expression"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val tryAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.tryBlock) ?: return
|
||||
|
||||
val op = tryAssignment.operationReference.text
|
||||
|
||||
@@ -35,9 +35,10 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
class MakeClassAnAnnotationClassFix(annotationClass: KtClass) : KotlinQuickFixAction<KtClass>(annotationClass) {
|
||||
override fun getFamilyName() = "Make class an annotation class"
|
||||
|
||||
override fun getText() = "Make '${element.name}' an annotation class"
|
||||
override fun getText() = element?.let { "Make '${it.name}' an annotation class" } ?: ""
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
element.addModifier(KtTokens.ANNOTATION_KEYWORD)
|
||||
}
|
||||
|
||||
|
||||
@@ -41,10 +41,12 @@ class MakeConstructorParameterPropertyFix(
|
||||
"Make constructor parameter a property$suffix"
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && !element.hasValOrVar()
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
element.addBefore(kotlinValVar.createKeyword(KtPsiFactory(project))!!, element.firstChild)
|
||||
element.addModifier(KtTokens.PRIVATE_KEYWORD)
|
||||
element.visibilityModifier()?.let { private ->
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.*
|
||||
import org.jetbrains.kotlin.descriptors.isOverridable
|
||||
@@ -30,15 +31,18 @@ import org.jetbrains.kotlin.lexer.KtTokens.OPEN_KEYWORD
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import java.util.*
|
||||
|
||||
class MakeOverriddenMemberOpenFix(declaration: KtDeclaration) : KotlinQuickFixAction<KtDeclaration>(declaration) {
|
||||
private val overriddenNonOverridableMembers = ArrayList<KtCallableDeclaration>()
|
||||
private val overriddenNonOverridableMembers = ArrayList<SmartPsiElementPointer<KtCallableDeclaration>>()
|
||||
private val containingDeclarationsNames = ArrayList<String>()
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
|
||||
if (!super.isAvailable(project, editor, file) || file !is KtFile) {
|
||||
return false
|
||||
}
|
||||
@@ -58,13 +62,15 @@ class MakeOverriddenMemberOpenFix(declaration: KtDeclaration) : KotlinQuickFixAc
|
||||
return false
|
||||
}
|
||||
val containingDeclarationName = overriddenDescriptor.containingDeclaration.name.asString()
|
||||
overriddenNonOverridableMembers.add(overriddenMember)
|
||||
overriddenNonOverridableMembers.add(overriddenMember.createSmartPointer())
|
||||
containingDeclarationsNames.add(containingDeclarationName)
|
||||
}
|
||||
return overriddenNonOverridableMembers.size > 0
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
val element = element ?: return ""
|
||||
|
||||
if (overriddenNonOverridableMembers.size == 1) {
|
||||
val name = containingDeclarationsNames[0] + "." + element.name
|
||||
return "Make $name $OPEN_KEYWORD"
|
||||
@@ -80,7 +86,7 @@ class MakeOverriddenMemberOpenFix(declaration: KtDeclaration) : KotlinQuickFixAc
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
for (overriddenMember in overriddenNonOverridableMembers) {
|
||||
overriddenMember.addModifier(OPEN_KEYWORD)
|
||||
overriddenMember.element?.addModifier(OPEN_KEYWORD)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class MissingConstructorKeywordFix(element: KtPrimaryConstructor) : KotlinQuickF
|
||||
override fun getText(): String = "Add 'constructor' keyword"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.addConstructorKeyword()
|
||||
element?.addConstructorKeyword()
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
@@ -29,6 +29,7 @@ class MoveTypeParameterConstraintFix(element: KtTypeParameter) : KotlinQuickFixA
|
||||
override fun getFamilyName(): String = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val typeParameterName = element.nameAsName ?: return
|
||||
val psiFactory = KtPsiFactory(file)
|
||||
val templateClass = psiFactory.buildDeclaration {
|
||||
|
||||
@@ -33,10 +33,12 @@ class MoveWhenElseBranchFix(element: KtWhenExpression) : KotlinQuickFixAction<Kt
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && KtPsiUtil.checkWhenExpressionHasSingleElse(element)
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val entries = element.entries
|
||||
val lastEntry = entries.lastOrNull() ?: return
|
||||
val elseEntry = entries.singleOrNull { it.isElse } ?: return
|
||||
|
||||
@@ -52,6 +52,7 @@ class NumberConversionFix(
|
||||
override fun getText() = "Convert expression to '$typePresentation'"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val expressionToInsert = KtPsiFactory(file).createExpressionByPattern("$0.to$1()", element, typePresentation)
|
||||
val newExpression = element.replaced(expressionToInsert)
|
||||
editor?.caretModel?.moveToOffset(newExpression.endOffset)
|
||||
|
||||
@@ -32,10 +32,12 @@ class RemoveFunctionBodyFix(element: KtFunction) : KotlinQuickFixAction<KtFuncti
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.hasBody()
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val bodyExpression = element.bodyExpression!!
|
||||
val equalsToken = element.equalsToken
|
||||
if (equalsToken != null) {
|
||||
|
||||
@@ -53,13 +53,14 @@ class RemoveModifierFix(
|
||||
override fun getText() = text
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
|
||||
= super.isAvailable(project, editor, file) && element.hasModifier(modifier)
|
||||
= super.isAvailable(project, editor, file) && (element?.hasModifier(modifier) ?: false)
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
invoke()
|
||||
}
|
||||
|
||||
fun invoke() {
|
||||
val element = element ?: return
|
||||
//TODO: without this copy&replace we get bad formatting on removing last modifier
|
||||
val newElement = element.copy() as KtModifierListOwner
|
||||
newElement.removeModifier(modifier)
|
||||
|
||||
@@ -29,7 +29,9 @@ class RemoveNameFromFunctionExpressionFix(element: KtNamedFunction) : KotlinQuic
|
||||
override fun getText(): String = "Remove identifier from anonymous function"
|
||||
override fun getFamilyName(): String = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) = removeNameFromFunction(element)
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
removeNameFromFunction(element ?: return)
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ class RemoveNullableFix(element: KtNullableType,
|
||||
override fun getText() = typeOfError.message
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val type = element.innerType ?: error("No inner type " + element.text + ", should have been rejected in createFactory()")
|
||||
element.replace(type)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ open class RemovePsiElementSimpleFix(element: PsiElement, private val text: Stri
|
||||
override fun getText() = text
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.delete()
|
||||
element?.delete()
|
||||
}
|
||||
|
||||
object RemoveImportFactory : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
@@ -31,6 +31,7 @@ class RemoveSingleLambdaParameterFix(element: KtParameter) : KotlinQuickFixActio
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val parameterList = element.parent as? KtParameterList ?: return
|
||||
val ownerFunction = parameterList.ownerFunction ?: return
|
||||
val arrow = ownerFunction.node.findChildByType(KtTokens.ARROW) ?: return
|
||||
|
||||
@@ -31,6 +31,7 @@ class RemoveSupertypeFix(superClass: KtSuperTypeListEntry) : KotlinQuickFixActio
|
||||
override fun getText() = familyName
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
element.getStrictParentOfType<KtClassOrObject>()?.removeSuperTypeListEntry(element)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,11 +30,12 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
class RemoveUnusedFunctionParameterFix(parameter: KtParameter) : KotlinQuickFixAction<KtParameter>(parameter) {
|
||||
override fun getFamilyName() = ChangeFunctionSignatureFix.FAMILY_NAME
|
||||
|
||||
override fun getText() = "Remove parameter '${element.name}'"
|
||||
override fun getText() = element?.let { "Remove parameter '${it.name}'" } ?: ""
|
||||
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val parameterDescriptor = element.resolveToDescriptor() as ValueParameterDescriptor
|
||||
ChangeFunctionSignatureFix.runRemoveParameter(parameterDescriptor, element)
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ class RemoveUnusedValueFix(expression: KtBinaryExpression) : KotlinQuickFixActio
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val lhs = element.left as? KtSimpleNameExpression ?: return
|
||||
val rhs = element.right ?: return
|
||||
val variable = lhs.mainReference.resolve() as? KtProperty ?: return
|
||||
|
||||
@@ -31,7 +31,7 @@ class RemoveUselessCastFix(element: KtBinaryExpressionWithTypeRHS) : KotlinQuick
|
||||
override fun getText(): String = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
invoke(element)
|
||||
invoke(element ?: return)
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
@@ -30,6 +30,7 @@ class RemoveUselessElvisFix(element: KtBinaryExpression) : KotlinQuickFixAction<
|
||||
override fun getText(): String = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
dropEnclosingParenthesesIfPossible(element.replaced(element.left!!))
|
||||
}
|
||||
|
||||
|
||||
@@ -35,12 +35,13 @@ class RemoveValVarFromParameterFix(element: KtValVarKeywordOwner) : KotlinQuickF
|
||||
override fun getFamilyName() = "Remove 'val/var' from parameter"
|
||||
|
||||
override fun getText(): String {
|
||||
val element = element ?: return ""
|
||||
val varOrVal = element.valOrVarKeyword?.text ?: return familyName
|
||||
return "Remove '$varOrVal' from parameter"
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.valOrVarKeyword?.delete()
|
||||
element?.valOrVarKeyword?.delete()
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
|
||||
class RenameParameterToMatchOverriddenMethodFix(
|
||||
private val parameter: KtParameter,
|
||||
parameter: KtParameter,
|
||||
private val newName: String
|
||||
) : KotlinQuickFixAction<KtParameter>(parameter) {
|
||||
override fun getFamilyName() = "Rename"
|
||||
@@ -38,7 +38,7 @@ class RenameParameterToMatchOverriddenMethodFix(
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
public override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
RenameProcessor(project, parameter, newName, false, false).run()
|
||||
RenameProcessor(project, element ?: return, newName, false, false).run()
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
@@ -28,7 +28,7 @@ class RenameToUnderscoreFix(element: KtCallableDeclaration) : KotlinQuickFixActi
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.nameIdentifier?.replace(KtPsiFactory(project).createIdentifier("_"))
|
||||
element?.nameIdentifier?.replace(KtPsiFactory(project).createIdentifier("_"))
|
||||
}
|
||||
|
||||
companion object Factory : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
@@ -75,6 +75,7 @@ class RenameUnresolvedReferenceFix(element: KtNameReferenceExpression): KotlinQu
|
||||
override fun getFamilyName() = QuickFixBundle.message("rename.wrong.reference.family")
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file)
|
||||
&& editor != null
|
||||
&& element.getStrictParentOfType<KtTypeReference>() == null
|
||||
@@ -83,6 +84,7 @@ class RenameUnresolvedReferenceFix(element: KtNameReferenceExpression): KotlinQu
|
||||
private fun KtExpression.isCallee() = getParentOfTypeAndBranch<KtCallElement> { calleeExpression } != null
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
if (editor == null) return
|
||||
val patternExpression = element.getQualifiedElement() as? KtExpression ?: return
|
||||
|
||||
|
||||
@@ -32,10 +32,12 @@ abstract class ReplaceCallFix(
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return super.isAvailable(project, editor, file) && element.selectorExpression != null
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val newExpression = KtPsiFactory(element).createExpressionByPattern("$0$operation$1",
|
||||
element.receiverExpression, element.selectorExpression!!)
|
||||
element.replace(newExpression)
|
||||
|
||||
@@ -36,6 +36,7 @@ class ReplaceInfixOrOperatorCallFix(element: KtExpression) : KotlinQuickFixActio
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val psiFactory = KtPsiFactory(file)
|
||||
when (element) {
|
||||
is KtArrayAccessExpression -> {
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ class ReplaceJavaAnnotationPositionedArgumentsFix(element: KtAnnotationEntry)
|
||||
override fun getFamilyName(): String = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
|
||||
|
||||
@@ -31,9 +31,11 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class ReplaceObsoleteLabelSyntaxFix(element: KtAnnotationEntry) : KotlinQuickFixAction<KtAnnotationEntry>(element), CleanupFix {
|
||||
override fun getFamilyName(): String = "Update obsolete label syntax"
|
||||
override fun getText(): String = "Replace with label ${element.calleeExpression?.text ?: ""}@"
|
||||
override fun getText(): String = element?.let { "Replace with label ${it.calleeExpression?.text ?: ""}@" } ?: ""
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) = replaceWithLabel(element)
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
replaceWithLabel(element ?: return)
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||
|
||||
@@ -34,6 +34,7 @@ class SimplifyComparisonFix(element: KtExpression, val value: Boolean) : KotlinQ
|
||||
override fun getText() = "Simplify comparison"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val parent = element.parent
|
||||
val replacement = KtPsiFactory(element).createExpression("$value")
|
||||
element.replace(replacement)
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.core.moveCaret
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
@@ -111,6 +112,7 @@ object SuperClassNotInitialized : KotlinIntentionActionsFactory() {
|
||||
override fun getText() = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val newSpecifier = element.replaced(KtPsiFactory(project).createSuperTypeCallEntry(element.text + "()"))
|
||||
|
||||
if (putCaretIntoParenthesis) {
|
||||
@@ -127,11 +129,13 @@ object SuperClassNotInitialized : KotlinIntentionActionsFactory() {
|
||||
|
||||
private class AddParametersFix(
|
||||
element: KtSuperTypeEntry,
|
||||
private val classDeclaration: KtClass,
|
||||
private val parametersToAdd: Collection<KtParameter>,
|
||||
classDeclaration: KtClass,
|
||||
parametersToAdd: Collection<KtParameter>,
|
||||
private val argumentText: String,
|
||||
private val text: String
|
||||
) : KotlinQuickFixAction<KtSuperTypeEntry>(element) {
|
||||
private val classDeclarationPointer = classDeclaration.createSmartPointer()
|
||||
private val parametersToAddPointers = parametersToAdd.map { it.createSmartPointer() }
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
@@ -180,6 +184,9 @@ object SuperClassNotInitialized : KotlinIntentionActionsFactory() {
|
||||
override fun getText() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val classDeclaration = classDeclarationPointer.element ?: return
|
||||
val parametersToAdd = parametersToAddPointers.map { it.element ?: return }
|
||||
val factory = KtPsiFactory(project)
|
||||
|
||||
val typeRefsToShorten = ArrayList<KtTypeReference>()
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRow
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
||||
@@ -38,14 +39,17 @@ import org.jetbrains.kotlin.types.typeUtil.isNullabilityMismatch
|
||||
|
||||
class SurroundWithNullCheckFix(
|
||||
expression: KtExpression,
|
||||
val nullableExpression: KtExpression
|
||||
nullableExpression: KtExpression
|
||||
) : KotlinQuickFixAction<KtExpression>(expression), HighPriorityAction {
|
||||
private val nullableExpressionPointer = nullableExpression.createSmartPointer()
|
||||
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun getText() = "Surround with null check"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val nullableExpression = nullableExpressionPointer.element ?: return
|
||||
val factory = KtPsiFactory(element)
|
||||
val surrounded = factory.createExpressionByPattern("if ($0 != null) { $1 }", nullableExpression, element)
|
||||
element.replace(surrounded)
|
||||
|
||||
@@ -15,6 +15,7 @@ class TooLongCharLiteralToStringFix(
|
||||
override fun getText(): String = "Convert too long character literal to string"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val text = element.text
|
||||
if (!(text.startsWith("'") && text.endsWith("'") && text.length >= 2)) {
|
||||
return
|
||||
|
||||
@@ -24,20 +24,24 @@ import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRow
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNullabilityMismatch
|
||||
|
||||
class WrapWithSafeLetCallFix(
|
||||
expression: KtExpression,
|
||||
val nullableExpression: KtExpression
|
||||
nullableExpression: KtExpression
|
||||
) : KotlinQuickFixAction<KtExpression>(expression) {
|
||||
private val nullableExpressionPointer = nullableExpression.createSmartPointer()
|
||||
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun getText() = "Wrap with '?.let { ... }' call"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val nullableExpression = nullableExpressionPointer.element ?: return
|
||||
val factory = KtPsiFactory(element)
|
||||
val nullableText = nullableExpression.text
|
||||
val validator = NewDeclarationNameValidator(element, nullableExpression, NewDeclarationNameValidator.Target.VARIABLES)
|
||||
|
||||
@@ -26,14 +26,13 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
|
||||
class WrongLongSuffixFix(element: KtConstantExpression) : KotlinQuickFixAction<KtConstantExpression>(element) {
|
||||
|
||||
private val corrected = element.text.trimEnd('l') + 'L'
|
||||
|
||||
override fun getText() = "Change to '$corrected'"
|
||||
override fun getFamilyName() = "Change to correct long suffix 'L'"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
element.replace(KtPsiFactory(project).createExpression(corrected))
|
||||
element?.replace(KtPsiFactory(project).createExpression(corrected))
|
||||
}
|
||||
|
||||
companion object Factory: KotlinSingleIntentionActionFactory() {
|
||||
|
||||
@@ -89,6 +89,7 @@ class WrongPrimitiveLiteralFix(element: KtConstantExpression, type: KotlinType)
|
||||
override fun getText() = "Change to '$fixedExpression'"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val expressionToInsert = KtPsiFactory(file).createExpression(fixedExpression)
|
||||
val newExpression = element.replaced(expressionToInsert)
|
||||
editor?.caretModel?.moveToOffset(newExpression.endOffset)
|
||||
|
||||
+4
-1
@@ -65,7 +65,7 @@ abstract class CreateCallableFromUsageFixBase<E : KtElement>(
|
||||
if (descriptor is FunctionClassDescriptor) {
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
val syntheticClass = psiFactory.createClass(IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(descriptor))
|
||||
return psiFactory.createAnalyzableFile("${descriptor.name.asString()}.kt", "", element).add(syntheticClass)
|
||||
return psiFactory.createAnalyzableFile("${descriptor.name.asString()}.kt", "", element!!).add(syntheticClass)
|
||||
}
|
||||
return DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor)
|
||||
}
|
||||
@@ -78,6 +78,7 @@ abstract class CreateCallableFromUsageFixBase<E : KtElement>(
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
val element = element ?: return ""
|
||||
val renderedCallables = callableInfos.map {
|
||||
buildString {
|
||||
if (it.isAbstract) {
|
||||
@@ -138,6 +139,7 @@ abstract class CreateCallableFromUsageFixBase<E : KtElement>(
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
if (!super.isAvailable(project, editor, file)) return false
|
||||
if (file !is KtFile) return false
|
||||
val element = element ?: return false
|
||||
|
||||
val receiverInfo = callableInfos.first().receiverTypeInfo
|
||||
|
||||
@@ -169,6 +171,7 @@ abstract class CreateCallableFromUsageFixBase<E : KtElement>(
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val callableInfo = callableInfos.first()
|
||||
|
||||
val callableBuilder =
|
||||
|
||||
+1
@@ -46,6 +46,7 @@ class CreateTypeAliasFromUsageFix<E : KtElement>(
|
||||
override fun getText() = "Create type alias '${aliasInfo.name}'"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
if (editor == null) return
|
||||
|
||||
val typeAliasProto = KtPsiFactory(project).createTypeAlias(aliasInfo.name, aliasInfo.typeParameterNames, "Dummy")
|
||||
|
||||
@@ -35,6 +35,7 @@ class MigrateTypeParameterListFix(typeParameterList: KtTypeParameterList)
|
||||
override fun getText(): String = familyName
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return
|
||||
function.addBefore(element, function.receiverTypeReference ?: function.nameIdentifier)
|
||||
element.delete()
|
||||
|
||||
@@ -39,6 +39,7 @@ class DeprecatedSymbolUsageFix(
|
||||
override fun getText() = "Replace with '${replaceWith.pattern}'" //TODO: substitute?
|
||||
|
||||
override fun invoke(replacementStrategy: UsageReplacementStrategy, project: Project, editor: Editor?) {
|
||||
val element = element ?: return
|
||||
val result = replacementStrategy.createReplacer(element)!!.invoke()
|
||||
val offset = (result.getCalleeExpressionIfAny() ?: result).textOffset
|
||||
editor?.moveCaret(offset)
|
||||
|
||||
+2
@@ -44,12 +44,14 @@ abstract class DeprecatedSymbolUsageFixBase(
|
||||
) : KotlinQuickFixAction<KtSimpleNameExpression>(element) {
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val element = element ?: return false
|
||||
if (!super.isAvailable(project, editor, file)) return false
|
||||
val strategy = UsageReplacementStrategy.build(element, replaceWith, recheckAnnotation = true)
|
||||
return strategy != null && strategy.createReplacer(element) != null
|
||||
}
|
||||
|
||||
final override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val strategy = UsageReplacementStrategy.build(element, replaceWith, recheckAnnotation = false)!!
|
||||
invoke(strategy, project, editor)
|
||||
}
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ class DeprecatedSymbolUsageInWholeProjectFix(
|
||||
}
|
||||
|
||||
private fun targetPsiElement(): KtDeclaration? {
|
||||
val referenceTarget = element.mainReference.resolve()
|
||||
val referenceTarget = element?.mainReference?.resolve()
|
||||
return when (referenceTarget) {
|
||||
is KtNamedFunction -> referenceTarget
|
||||
is KtProperty -> referenceTarget
|
||||
|
||||
Reference in New Issue
Block a user