From df38c70278ba3e6501146a30abb3963851f21290 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 1 Nov 2016 20:09:12 +0300 Subject: [PATCH] Quick Fixes: Replace strong references to PSI elements with smart pointers #KT-14552 Fixed --- .../idea/inspections/AddKotlinLibQuickFix.kt | 1 + .../ConflictingExtensionPropertyInspection.kt | 3 +- .../kotlin/idea/inspections/InfixCallFix.kt | 2 +- .../inspections/KotlinCleanupInspection.kt | 2 +- .../AddValVarToConstructorParameterAction.kt | 6 +- .../kotlin/idea/quickfix/AddArrayOfTypeFix.kt | 1 + .../kotlin/idea/quickfix/AddCrossinlineFix.kt | 3 +- .../idea/quickfix/AddFunctionBodyFix.kt | 2 + .../idea/quickfix/AddFunctionParametersFix.kt | 10 ++- .../idea/quickfix/AddGenericUpperBoundFix.kt | 4 +- .../kotlin/idea/quickfix/AddLoopLabelFix.kt | 1 + .../kotlin/idea/quickfix/AddModifierFix.kt | 4 +- .../idea/quickfix/AddNameToArgumentFix.kt | 15 +++-- .../quickfix/AddNewLineAfterAnnotationsFix.kt | 1 + .../AddReifiedToTypeParameterOfFunctionFix.kt | 2 +- .../kotlin/idea/quickfix/AddRunToLambdaFix.kt | 1 + .../idea/quickfix/AddStarProjectionsFix.kt | 1 + .../kotlin/idea/quickfix/AddToStringFix.kt | 1 + .../AddTypeAnnotationToValueParameterFix.kt | 5 +- .../AddTypeToLHSOfCallableReferenceFix.kt | 1 + .../idea/quickfix/AddWhenElseBranchFix.kt | 2 + .../quickfix/AddWhenRemainingBranchesFix.kt | 11 ++-- .../kotlin/idea/quickfix/CastExpressionFix.kt | 3 +- .../idea/quickfix/ChangeAccessorTypeFix.kt | 4 +- .../ChangeFunctionLiteralReturnTypeFix.kt | 7 +- .../ChangeFunctionLiteralSignatureFix.kt | 3 +- .../quickfix/ChangeFunctionReturnTypeFix.kt | 5 ++ .../quickfix/ChangeFunctionSignatureFix.kt | 11 ++-- .../ChangeMemberFunctionSignatureFix.kt | 1 + .../idea/quickfix/ChangeParameterTypeFix.kt | 2 + .../quickfix/ChangeToFunctionInvocationFix.kt | 1 + .../quickfix/ChangeToPropertyAccessFix.kt | 1 + .../quickfix/ChangeToStarProjectionFix.kt | 3 +- .../kotlin/idea/quickfix/ChangeTypeFix.kt | 3 +- .../quickfix/ChangeVariableMutabilityFix.kt | 2 + .../idea/quickfix/ChangeVariableTypeFix.kt | 4 ++ .../idea/quickfix/ChangeVisibilityFix.kt | 14 ++-- .../quickfix/ChangeVisibilityModifierFix.kt | 1 + .../idea/quickfix/ConvertClassToKClassFix.kt | 3 +- ...ExtensionPropertyInitializerToGetterFix.kt | 1 + .../ConvertExtensionToFunctionTypeFix.kt | 1 + .../kotlin/idea/quickfix/ExclExclCallFixes.kt | 13 ++-- .../kotlin/idea/quickfix/ImportFix.kt | 64 +++++++++++-------- .../InitializePropertyQuickFixFactory.kt | 17 +++-- .../quickfix/InsertDelegationCallQuickfix.kt | 2 + .../idea/quickfix/KotlinQuickFixAction.kt | 9 ++- .../idea/quickfix/LetImplementInterfaceFix.kt | 1 + .../quickfix/LiftAssignmentOutOfTryFix.kt | 1 + .../quickfix/MakeClassAnAnnotationClassFix.kt | 3 +- .../MakeConstructorParameterPropertyFix.kt | 2 + .../quickfix/MakeOverriddenMemberOpenFix.kt | 12 +++- .../quickfix/MissingConstructorKeywordFix.kt | 2 +- .../MoveTypeParameterConstraintFix.kt | 1 + .../idea/quickfix/MoveWhenElseBranchFix.kt | 2 + .../idea/quickfix/NumberConversionFix.kt | 1 + .../idea/quickfix/RemoveFunctionBodyFix.kt | 2 + .../kotlin/idea/quickfix/RemoveModifierFix.kt | 3 +- .../RemoveNameFromFunctionExpressionFix.kt | 4 +- .../kotlin/idea/quickfix/RemoveNullableFix.kt | 1 + .../quickfix/RemovePsiElementSimpleFix.kt | 2 +- .../RemoveSingleLambdaParameterFix.kt | 1 + .../idea/quickfix/RemoveSupertypeFix.kt | 1 + .../RemoveUnusedFunctionParameterFix.kt | 3 +- .../idea/quickfix/RemoveUnusedValueFix.kt | 1 + .../idea/quickfix/RemoveUselessCastFix.kt | 2 +- .../idea/quickfix/RemoveUselessElvisFix.kt | 1 + .../quickfix/RemoveValVarFromParameterFix.kt | 3 +- ...nameParameterToMatchOverriddenMethodFix.kt | 4 +- .../idea/quickfix/RenameToUnderscoreFix.kt | 2 +- .../quickfix/RenameUnresolvedReferenceFix.kt | 2 + .../kotlin/idea/quickfix/ReplaceCallFix.kt | 2 + .../quickfix/ReplaceInfixOrOperatorCallFix.kt | 1 + ...aceJavaAnnotationPositionedArgumentsFix.kt | 1 + .../quickfix/ReplaceObsoleteLabelSyntaxFix.kt | 6 +- .../idea/quickfix/SimplifyComparisonFix.kt | 1 + .../idea/quickfix/SuperClassNotInitialized.kt | 11 +++- .../idea/quickfix/SurroundWithNullCheckFix.kt | 6 +- .../quickfix/TooLongCharLiteralToStringFix.kt | 1 + .../idea/quickfix/WrapWithSafeLetCallFix.kt | 6 +- .../idea/quickfix/WrongLongSuffixFix.kt | 3 +- .../idea/quickfix/WrongPrimitiveLiteralFix.kt | 1 + .../CreateCallableFromUsageFix.kt | 5 +- .../CreateTypeAliasFromUsageFix.kt | 1 + .../migration/MigrateTypeParameterListFix.kt | 1 + .../replaceWith/DeprecatedSymbolUsageFix.kt | 1 + .../DeprecatedSymbolUsageFixBase.kt | 2 + .../DeprecatedSymbolUsageInWholeProjectFix.kt | 2 +- 87 files changed, 255 insertions(+), 107 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt index b61ce723365..a58bda23040 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/AddKotlinLibQuickFix.kt @@ -135,6 +135,7 @@ abstract class AddKotlinLibQuickFix(element: KtElement) : KotlinQuickFixAction(expression), CleanupFix { override fun invoke(project: Project, editor: Editor?, file: KtFile) { - InfixCallToOrdinaryIntention.convert(element) + InfixCallToOrdinaryIntention.convert(element ?: return) } override fun getFamilyName(): String = text diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt index 04e50708c6c..ac83beb1345 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/KotlinCleanupInspection.kt @@ -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() } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt index 18049e36dcb..2c41fecf815 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt @@ -80,11 +80,13 @@ interface AddValVarToConstructorParameterAction { class QuickFix(parameter: KtParameter) : KotlinQuickFixAction(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() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddArrayOfTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddArrayOfTypeFix.kt index 60165a2ed96..fd6fddfab92 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddArrayOfTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddArrayOfTypeFix.kt @@ -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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddCrossinlineFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddCrossinlineFix.kt index 376172dd805..436fdf5cd72 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddCrossinlineFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddCrossinlineFix.kt @@ -30,10 +30,11 @@ class AddInlineModifierFix( element: KtNameReferenceExpression, private val modifier: KtModifierKeywordToken ) : KotlinQuickFixAction(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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionBodyFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionBodyFix.kt index 8863ceec5e4..f4855931df1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionBodyFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionBodyFix.kt @@ -30,10 +30,12 @@ class AddFunctionBodyFix(element: KtFunction) : KotlinQuickFixAction 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()) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.kt index edd20d7fea4..3a3147c0231 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddFunctionParametersFix.kt @@ -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() 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() diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt index d5c7f561149..8f24e87e825 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddGenericUpperBoundFix.kt @@ -43,16 +43,18 @@ class AddGenericUpperBoundFix( ) : KotlinQuickFixAction(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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddLoopLabelFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddLoopLabelFix.kt index cc15b67bba9..218e5b844e6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddLoopLabelFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddLoopLabelFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt index 35614fb36b5..246d591a0d5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt @@ -41,6 +41,7 @@ open class AddModifierFix( ) : KotlinQuickFixAction(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() } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNameToArgumentFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNameToArgumentFix.kt index 29bed7237d4..61955302056 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNameToArgumentFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNameToArgumentFix.kt @@ -39,14 +39,15 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class AddNameToArgumentFix(argument: KtValueArgument) : KotlinQuickFixAction(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 { - val callElement = element.getParentOfType(true) ?: return emptyList() + val callElement = element!!.getParentOfType(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): ListPopupStep { return object : BaseListPopupStep("Choose parameter name", names) { override fun onChosen(selectedValue: Name, finalChoice: Boolean): PopupStep<*>? { - addName(project, element, selectedValue) + addName(project, element!!, selectedValue) return PopupStep.FINAL_CHOICE } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNewLineAfterAnnotationsFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNewLineAfterAnnotationsFix.kt index 5da8ae93e1a..f23b9f9bf86 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNewLineAfterAnnotationsFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddNewLineAfterAnnotationsFix.kt @@ -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] diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddReifiedToTypeParameterOfFunctionFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddReifiedToTypeParameterOfFunctionFix.kt index 56fb3c33a1b..e6774d0589a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddReifiedToTypeParameterOfFunctionFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddReifiedToTypeParameterOfFunctionFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddRunToLambdaFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddRunToLambdaFix.kt index 7768628d011..ab14cd26121 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddRunToLambdaFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddRunToLambdaFix.kt @@ -30,6 +30,7 @@ class AddRunToLambdaFix(element: KtLambdaExpression) : KotlinQuickFixAction(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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddTypeToLHSOfCallableReferenceFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddTypeToLHSOfCallableReferenceFix.kt index 5abbc713420..b898ccc67d0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddTypeToLHSOfCallableReferenceFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddTypeToLHSOfCallableReferenceFix.kt @@ -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 diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenElseBranchFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenElseBranchFix.kt index e657c7aa012..0b5bc19495e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenElseBranchFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenElseBranchFix.kt @@ -30,10 +30,12 @@ class AddWhenElseBranchFix(element: KtWhenExpression) : KotlinQuickFixAction {}") val whenCloseBrace = element.closeBrace ?: error("isAvailable should check if close brace exist") diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt index f41befac058..535095f836e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt @@ -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") diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.kt index 9ebcbfa2b25..cb6dd46c569 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.kt @@ -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!!) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeAccessorTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeAccessorTypeFix.kt index 716df75cd36..38a914b2736 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeAccessorTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeAccessorTypeFix.kt @@ -33,7 +33,7 @@ import org.jetbrains.kotlin.types.KotlinType class ChangeAccessorTypeFix(element: KtPropertyAccessor) : KotlinQuickFixAction(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)) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralReturnTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralReturnTypeFix.kt index 340f02433f3..185787c21dd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralReturnTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralReturnTypeFix.kt @@ -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)) { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.kt index fe9ccdcf24c..02b5bdf3715 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionLiteralSignatureFix.kt @@ -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) = false override fun forcePerformForSelectedFunctionOnly() = false }, - context, + element, text) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionReturnTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionReturnTypeFix.kt index 3e125ce8411..2fa645054f1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionReturnTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionReturnTypeFix.kt @@ -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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.kt index 54fb4057820..57104e9e5ae 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeFunctionSignatureFix.kt @@ -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(context) { - +) : KotlinQuickFixAction(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) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt index 063d9adc1b2..0158c03a087 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeMemberFunctionSignatureFix.kt @@ -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() } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeParameterTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeParameterTypeFix.kt index f51756f89e3..126b3ed1b7b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeParameterTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeParameterTypeFix.kt @@ -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() ?: return val parameterIndex = function.valueParameters.indexOf(element) val context = function.analyze() diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToFunctionInvocationFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToFunctionInvocationFix.kt index 6bf2b5d9891..1cff9bbc1c8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToFunctionInvocationFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToFunctionInvocationFix.kt @@ -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)) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToPropertyAccessFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToPropertyAccessFix.kt index d65c3185b7b..e40e5077425 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToPropertyAccessFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToPropertyAccessFix.kt @@ -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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToStarProjectionFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToStarProjectionFix.kt index 02601eb0851..60b9edc5d7e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToStarProjectionFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeToStarProjectionFix.kt @@ -26,9 +26,10 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType class ChangeToStarProjectionFix(element: KtTypeElement) : KotlinQuickFixAction(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) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeTypeFix.kt index 8ea8470e8c3..3689793e047 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeTypeFix.kt @@ -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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt index a98978ef6c2..47bcd5669c7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableTypeFix.kt index ae19792bc87..614fa9ff972 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableTypeFix.kt @@ -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" } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt index 17a0b349dd2..f76bff3a216 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt @@ -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 { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityModifierFix.kt index c64a3024bc6..a3a199c6e6c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityModifierFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityModifierFix.kt @@ -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()!!) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertClassToKClassFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertClassToKClassFix.kt index bdcd9ef42a4..f1033efa568 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertClassToKClassFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertClassToKClassFix.kt @@ -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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionPropertyInitializerToGetterFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionPropertyInitializerToGetterFix.kt index 9f779db5d3a..2dfe7fe2fe9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionPropertyInitializerToGetterFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionPropertyInitializerToGetterFix.kt @@ -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(true) ?: return ConvertPropertyInitializerToGetterIntention.convertPropertyInitializerToGetter(property, editor) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionToFunctionTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionToFunctionTypeFix.kt index b00ed7da103..82cf6729917 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionToFunctionTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ConvertExtensionToFunctionTypeFix.kt @@ -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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt index 1a6eb753a17..62695c43fbc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt @@ -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) { 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) { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt index 344323db231..bb143ff4029 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt @@ -86,27 +86,30 @@ internal abstract class ImportFixBase protected constructor( expression: T, private val factory: Factory ) : KotlinQuickFixAction(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 - 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 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 { - 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 protected constructor( } private fun computeSuggestionsForName(name: Name, callTypeAndReceiver: CallTypeAndReceiver<*, *>): Collection { + val element = element ?: return emptyList() val nameStr = name.asString() if (nameStr.isEmpty()) return emptyList() @@ -192,7 +198,7 @@ internal abstract class ImportFixBase protected constructor( .any { diagnostic -> diagnostic.factory in getSupportedErrors() } } - protected open fun elementsToCheckDiagnostics(): Collection = listOf(element) + protected open fun elementsToCheckDiagnostics(): Collection = element.singletonOrEmptyList() abstract fun fillCandidates( name: String, @@ -225,9 +231,9 @@ internal abstract class OrdinaryImportFixBase(expression: T, f bindingContext: BindingContext, indicesHelper: KotlinIndicesHelper ): List { - val result = ArrayList() + val expression = element ?: return emptyList() - val expression = element + val result = ArrayList() if (expression is KtSimpleNameExpression) { if (!expression.isImportDirectiveExpression() && !isSelectorInQualified(expression)) { @@ -252,9 +258,9 @@ internal abstract class OrdinaryImportFixBase(expression: T, f } internal class ImportFix(expression: KtSimpleNameExpression) : OrdinaryImportFixBase(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(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(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(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 { + val element = element ?: return emptyList() + val result = ArrayList() 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 = 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(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 { + 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 { + val element = element ?: return emptyList() + if (!Name.isValidIdentifier(name)) return emptyList() val identifier = Name.identifier(name) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt index dcef55c2c26..48f24695796 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/InitializePropertyQuickFixFactory.kt @@ -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, visitedElements: MutableSet = 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/InsertDelegationCallQuickfix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/InsertDelegationCallQuickfix.kt index d17b64cb7f3..552ad7ce769 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/InsertDelegationCallQuickfix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/InsertDelegationCallQuickfix.kt @@ -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() } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinQuickFixAction.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinQuickFixAction.kt index 9fe851eba65..b7f6517dd88 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinQuickFixAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinQuickFixAction.kt @@ -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(protected val element: T) : IntentionAction { +abstract class KotlinQuickFixAction(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(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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/LetImplementInterfaceFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/LetImplementInterfaceFix.kt index ffa0af415b0..67ff73107c6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/LetImplementInterfaceFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/LetImplementInterfaceFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/LiftAssignmentOutOfTryFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/LiftAssignmentOutOfTryFix.kt index f6d99ae5896..9e4896fe5cc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/LiftAssignmentOutOfTryFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/LiftAssignmentOutOfTryFix.kt @@ -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 diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeClassAnAnnotationClassFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeClassAnAnnotationClassFix.kt index d8669d70ed7..a3701d1ba21 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeClassAnAnnotationClassFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeClassAnAnnotationClassFix.kt @@ -35,9 +35,10 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class MakeClassAnAnnotationClassFix(annotationClass: KtClass) : KotlinQuickFixAction(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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeConstructorParameterPropertyFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeConstructorParameterPropertyFix.kt index 90501f01404..d7a0e6d2068 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeConstructorParameterPropertyFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeConstructorParameterPropertyFix.kt @@ -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 -> diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeOverriddenMemberOpenFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeOverriddenMemberOpenFix.kt index 798ded95f82..a5afbd47a49 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeOverriddenMemberOpenFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MakeOverriddenMemberOpenFix.kt @@ -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(declaration) { - private val overriddenNonOverridableMembers = ArrayList() + private val overriddenNonOverridableMembers = ArrayList>() private val containingDeclarationsNames = ArrayList() 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) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MissingConstructorKeywordFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MissingConstructorKeywordFix.kt index f734b3159c2..72173f9eb9b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MissingConstructorKeywordFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MissingConstructorKeywordFix.kt @@ -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() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeParameterConstraintFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeParameterConstraintFix.kt index e7b14b19dc8..6ba0f5af822 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeParameterConstraintFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveTypeParameterConstraintFix.kt @@ -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 { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveWhenElseBranchFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveWhenElseBranchFix.kt index 9d0dfa89e09..d869f049744 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveWhenElseBranchFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MoveWhenElseBranchFix.kt @@ -33,10 +33,12 @@ class MoveWhenElseBranchFix(element: KtWhenExpression) : KotlinQuickFixAction()?.removeSuperTypeListEntry(element) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedFunctionParameterFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedFunctionParameterFix.kt index 326ee29668c..d8417191969 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedFunctionParameterFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedFunctionParameterFix.kt @@ -30,11 +30,12 @@ import org.jetbrains.kotlin.psi.KtParameter class RemoveUnusedFunctionParameterFix(parameter: KtParameter) : KotlinQuickFixAction(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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedValueFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedValueFix.kt index 332334d2720..0d73ffbf2df 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedValueFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUnusedValueFix.kt @@ -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 diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessCastFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessCastFix.kt index aeb1c3a49c5..2245804c11c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessCastFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessCastFix.kt @@ -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() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessElvisFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessElvisFix.kt index 8cf890b48a0..af17ac3af2b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessElvisFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveUselessElvisFix.kt @@ -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!!)) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveValVarFromParameterFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveValVarFromParameterFix.kt index 6f084030f79..10a98469b55 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveValVarFromParameterFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveValVarFromParameterFix.kt @@ -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() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameParameterToMatchOverriddenMethodFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameParameterToMatchOverriddenMethodFix.kt index d39af4809dc..781804518b0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameParameterToMatchOverriddenMethodFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameParameterToMatchOverriddenMethodFix.kt @@ -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(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() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameToUnderscoreFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameToUnderscoreFix.kt index c4003d3f069..b780bdbc5c4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameToUnderscoreFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameToUnderscoreFix.kt @@ -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() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt index 1a8520375bd..d8275076df8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RenameUnresolvedReferenceFix.kt @@ -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() == null @@ -83,6 +84,7 @@ class RenameUnresolvedReferenceFix(element: KtNameReferenceExpression): KotlinQu private fun KtExpression.isCallee() = getParentOfTypeAndBranch { 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceCallFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceCallFix.kt index d437de0d7ac..03eddbb72f5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceCallFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceCallFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceInfixOrOperatorCallFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceInfixOrOperatorCallFix.kt index 6709570b369..f0dcb9275a6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceInfixOrOperatorCallFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceInfixOrOperatorCallFix.kt @@ -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 -> { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceJavaAnnotationPositionedArgumentsFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceJavaAnnotationPositionedArgumentsFix.kt index d614d056401..f00a9eb5860 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceJavaAnnotationPositionedArgumentsFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceJavaAnnotationPositionedArgumentsFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceObsoleteLabelSyntaxFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceObsoleteLabelSyntaxFix.kt index e64bb47e70e..2693ad5a11f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceObsoleteLabelSyntaxFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ReplaceObsoleteLabelSyntaxFix.kt @@ -31,9 +31,11 @@ import org.jetbrains.kotlin.resolve.BindingContext class ReplaceObsoleteLabelSyntaxFix(element: KtAnnotationEntry) : KotlinQuickFixAction(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? { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/SimplifyComparisonFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/SimplifyComparisonFix.kt index c9b822faa23..84de5c4e90c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/SimplifyComparisonFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/SimplifyComparisonFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt index 4f23a93824e..3bdfcae8154 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/SuperClassNotInitialized.kt @@ -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, + classDeclaration: KtClass, + parametersToAdd: Collection, private val argumentText: String, private val text: String ) : KotlinQuickFixAction(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() diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/SurroundWithNullCheckFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/SurroundWithNullCheckFix.kt index ef4eb8889eb..9669b317ec2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/SurroundWithNullCheckFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/SurroundWithNullCheckFix.kt @@ -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(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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt index f0c4b8ae837..7053feb43e8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt @@ -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 diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt index 97750809bf1..96074c0b36e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt @@ -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(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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongLongSuffixFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongLongSuffixFix.kt index 615d410541d..f8b65517abd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongLongSuffixFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongLongSuffixFix.kt @@ -26,14 +26,13 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtPsiFactory class WrongLongSuffixFix(element: KtConstantExpression) : KotlinQuickFixAction(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() { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongPrimitiveLiteralFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongPrimitiveLiteralFix.kt index 2f1eb4ebd4c..c53b22dd5a0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongPrimitiveLiteralFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/WrongPrimitiveLiteralFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt index e7bc42a4622..bf46ed891d5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createCallable/CreateCallableFromUsageFix.kt @@ -65,7 +65,7 @@ abstract class CreateCallableFromUsageFixBase( 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( } override fun getText(): String { + val element = element ?: return "" val renderedCallables = callableInfos.map { buildString { if (it.isAbstract) { @@ -138,6 +139,7 @@ abstract class CreateCallableFromUsageFixBase( 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( } override fun invoke(project: Project, editor: Editor?, file: KtFile) { + val element = element ?: return val callableInfo = callableInfos.first() val callableBuilder = diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createTypeAlias/CreateTypeAliasFromUsageFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createTypeAlias/CreateTypeAliasFromUsageFix.kt index 62a6e1863ec..032af91c095 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createTypeAlias/CreateTypeAliasFromUsageFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/createFromUsage/createTypeAlias/CreateTypeAliasFromUsageFix.kt @@ -46,6 +46,7 @@ class CreateTypeAliasFromUsageFix( 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") diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateTypeParameterListFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateTypeParameterListFix.kt index dd4a765cc0d..bd785cc9d4a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateTypeParameterListFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrateTypeParameterListFix.kt @@ -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() ?: return function.addBefore(element, function.receiverTypeReference ?: function.nameIdentifier) element.delete() diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFix.kt index ea188120b79..86f5c1f8e42 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFix.kt @@ -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) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt index 7c2e656be28..b154afd2cc5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageFixBase.kt @@ -44,12 +44,14 @@ abstract class DeprecatedSymbolUsageFixBase( ) : KotlinQuickFixAction(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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageInWholeProjectFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageInWholeProjectFix.kt index f6043b20219..75048a7ed14 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageInWholeProjectFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/replaceWith/DeprecatedSymbolUsageInWholeProjectFix.kt @@ -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