From 4f8c0653c512660c43efebad2c6a3f85bb9f561a Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Thu, 6 Jun 2019 13:33:52 +0700 Subject: [PATCH] Change API in AbstractApplicabilityBasedInspection Replace all inspectionTarget with inspectionHighlightRangeInElement & change type of element in applyTo from PsiElement to TElement --- .../AbstractApplicabilityBasedInspection.kt | 10 ++--- .../AddOperatorModifierInspection.kt | 10 ++--- ...recatedCallableAddReplaceWithInspection.kt | 27 ++++++------- .../FoldInitializerAndIfToElvisInspection.kt | 12 +++--- .../inspections/JavaMapForEachInspection.kt | 13 +++---- .../MoveLambdaOutsideParenthesesInspection.kt | 18 ++++----- .../NullableBooleanElvisInspection.kt | 2 +- ...RemoveCurlyBracesFromTemplateInspection.kt | 5 +-- ...rayEqualityOpWithArraysEqualsInspection.kt | 20 +++++----- ...sertBooleanWithAssertEqualityInspection.kt | 18 ++++----- .../ReplacePutWithAssignmentInspection.kt | 16 ++++---- ...aceToStringWithStringTemplateInspection.kt | 9 +---- ...ReplaceWithOperatorAssignmentInspection.kt | 5 +-- .../SimplifyAssertNotNullInspection.kt | 38 +++++++++---------- ...mplifyNegatedBinaryExpressionInspection.kt | 15 +++----- .../UnnecessaryVariableInspection.kt | 12 +++--- .../IfThenToElvisInspection.kt | 12 ++---- .../IfThenToSafeAccessInspection.kt | 8 ++-- .../IntroduceWhenSubjectInspection.kt | 9 ++--- ...ReplaceCallWithBinaryOperatorInspection.kt | 21 +++++----- .../ReplaceGetOrSetInspection.kt | 34 ++++++++--------- .../substring/ReplaceSubstringInspection.kt | 11 +++--- .../ReplaceSubstringWithDropLastInspection.kt | 8 ++-- ...ubstringWithIndexingOperationInspection.kt | 7 +--- ...tringWithSubstringBeforeAfterIntentions.kt | 7 +--- .../ReplaceSubstringWithTakeInspection.kt | 6 +-- .../branchedTransformations/IfThenUtils.kt | 7 ++-- .../j2k/J2KPostProcessingRegistrarImpl.kt | 2 +- .../kotlin/idea/util/expressionExt.kt | 12 +++++- .../inspectionLikePostProcessings.kt | 2 +- 30 files changed, 164 insertions(+), 212 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/inspections/AbstractApplicabilityBasedInspection.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/inspections/AbstractApplicabilityBasedInspection.kt index 5052dabec93..b13177dfd5a 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/inspections/AbstractApplicabilityBasedInspection.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/inspections/AbstractApplicabilityBasedInspection.kt @@ -20,7 +20,6 @@ import com.intellij.codeInspection.* import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.openapi.util.TextRange -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtVisitorVoid @@ -44,7 +43,7 @@ abstract class AbstractApplicabilityBasedInspection( if (!isApplicable(element)) return holder.registerProblemWithoutOfflineInformation( - inspectionTarget(element), + element, inspectionText(element), isOnTheFly, inspectionHighlightType(element), @@ -55,8 +54,6 @@ abstract class AbstractApplicabilityBasedInspection( open fun inspectionHighlightRangeInElement(element: TElement): TextRange? = null - open fun inspectionTarget(element: TElement): PsiElement = element - open fun inspectionHighlightType(element: TElement): ProblemHighlightType = ProblemHighlightType.GENERIC_ERROR_OR_WARNING abstract fun inspectionText(element: TElement): String @@ -67,7 +64,7 @@ abstract class AbstractApplicabilityBasedInspection( abstract fun isApplicable(element: TElement): Boolean - abstract fun applyTo(element: PsiElement, project: Project = element.project, editor: Editor? = null) + abstract fun applyTo(element: TElement, project: Project = element.project, editor: Editor? = null) open val startFixInWriteAction = true @@ -75,7 +72,8 @@ abstract class AbstractApplicabilityBasedInspection( override fun startInWriteAction() = startFixInWriteAction override fun applyFix(project: Project, descriptor: ProblemDescriptor) { - val element = descriptor.psiElement + @Suppress("UNCHECKED_CAST") + val element = descriptor.psiElement as TElement applyTo(element, project, element.findExistingEditor()) } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt index dde9e590730..be54c84dd32 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/AddOperatorModifierInspection.kt @@ -7,17 +7,15 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.refactoring.withExpectedActuals +import org.jetbrains.kotlin.idea.util.nameIdentifierTextRangeInThis import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.util.OperatorChecks class AddOperatorModifierInspection : AbstractApplicabilityBasedInspection(KtNamedFunction::class.java) { - override fun inspectionHighlightRangeInElement(element: KtNamedFunction) = - element.nameIdentifier?.textRange?.shiftLeft(element.startOffset) + override fun inspectionHighlightRangeInElement(element: KtNamedFunction) = element.nameIdentifierTextRangeInThis() override fun inspectionText(element: KtNamedFunction) = "Function should have 'operator' modifier" @@ -29,8 +27,8 @@ class AddOperatorModifierInspection : AbstractApplicabilityBasedInspection( KtCallableDeclaration::class.java ) { - override fun inspectionText(element: KtCallableDeclaration) = - "@Deprecated annotation without 'replaceWith' argument" + override fun inspectionText(element: KtCallableDeclaration) = "@Deprecated annotation without 'replaceWith' argument" - override fun inspectionTarget(element: KtCallableDeclaration): KtAnnotationEntry = - element.annotationEntries.first { it.shortName == DEPRECATED_NAME } + override fun inspectionHighlightRangeInElement(element: KtCallableDeclaration) = element.annotationEntries.first { + it.shortName == DEPRECATED_NAME + }.textRangeIn(element) - override val defaultFixText = - "Add 'replaceWith' argument to specify replacement pattern" + override val defaultFixText = "Add 'replaceWith' argument to specify replacement pattern" private class ReplaceWith(val expression: String, vararg val imports: String) @@ -54,14 +52,13 @@ class DeprecatedCallableAddReplaceWithInspection : AbstractApplicabilityBasedIns return element.suggestReplaceWith() != null } - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val declaration = element.getParentOfType(strict = true) ?: return - val replaceWith = declaration.suggestReplaceWith()!! + override fun applyTo(element: KtCallableDeclaration, project: Project, editor: Editor?) { + val replaceWith = element.suggestReplaceWith()!! assert('\n' !in replaceWith.expression && '\r' !in replaceWith.expression) { "Formatted expression text should not contain \\n or \\r" } - val annotationEntry = declaration.deprecatedAnnotationWithNoReplaceWith()!! - val psiFactory = KtPsiFactory(declaration) + val annotationEntry = element.deprecatedAnnotationWithNoReplaceWith()!! + val psiFactory = KtPsiFactory(element) var escapedText = replaceWith.expression.replace("\\", "\\\\").replace("\"", "\\\"") @@ -212,8 +209,8 @@ class DeprecatedCallableAddReplaceWithInspection : AbstractApplicabilityBasedIns override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { val bindingContext = expression.analyze() val target = bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, expression] - ?: bindingContext[BindingContext.REFERENCE_TARGET, expression] - ?: return + ?: bindingContext[BindingContext.REFERENCE_TARGET, expression] + ?: return if (target.isExtension || expression.getReceiverExpression() == null) { val fqName = target.importableFqName ?: return if (!importHelper.isImportedWithDefault(ImportPath(fqName, false), file) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/FoldInitializerAndIfToElvisInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/FoldInitializerAndIfToElvisInspection.kt index 5da9321c4a5..20792291833 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/FoldInitializerAndIfToElvisInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/FoldInitializerAndIfToElvisInspection.kt @@ -22,14 +22,13 @@ import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.setType import org.jetbrains.kotlin.idea.intentions.branchedTransformations.elvisPattern import org.jetbrains.kotlin.idea.intentions.branchedTransformations.expressionComparedToNull +import org.jetbrains.kotlin.idea.intentions.branchedTransformations.fromIfKeywordToRightParenthesisTextRangeInThis import org.jetbrains.kotlin.idea.intentions.branchedTransformations.shouldBeTransformed -import org.jetbrains.kotlin.idea.intentions.branchedTransformations.textRange import org.jetbrains.kotlin.idea.util.CommentSaver import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange import org.jetbrains.kotlin.psi.psiUtil.siblings -import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.isError @@ -43,16 +42,15 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti override val defaultFixText: String = "Replace 'if' with elvis operator" - override fun inspectionHighlightRangeInElement(element: KtIfExpression): TextRange? = element.textRange().shiftLeft(element.startOffset) + override fun inspectionHighlightRangeInElement(element: KtIfExpression) = element.fromIfKeywordToRightParenthesisTextRangeInThis() override fun inspectionHighlightType(element: KtIfExpression): ProblemHighlightType = if (element.shouldBeTransformed()) ProblemHighlightType.GENERIC_ERROR_OR_WARNING else ProblemHighlightType.INFORMATION override fun isApplicable(element: KtIfExpression): Boolean = Companion.isApplicable(element) - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val newElvis = Companion.applyTo(element as KtIfExpression) - editor?.caretModel?.moveToOffset(newElvis.right!!.textOffset) + override fun applyTo(element: KtIfExpression, project: Project, editor: Editor?) { + Companion.applyTo(element).right?.textOffset?.let { editor?.caretModel?.moveToOffset(it) } } companion object { @@ -62,7 +60,7 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti val type = data.ifNullExpression.analyze().getType(data.ifNullExpression) ?: return null if (!type.isNothing()) return null - return element.textRange() + return element.fromIfKeywordToRightParenthesisTextRangeInThis() } fun isApplicable(element: KtIfExpression): Boolean = applicabilityRange(element) != null diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/JavaMapForEachInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/JavaMapForEachInspection.kt index 5d360098e63..1e211b781f4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/JavaMapForEachInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/JavaMapForEachInspection.kt @@ -5,20 +5,19 @@ package org.jetbrains.kotlin.idea.inspections -import com.intellij.codeInspection.ProblemHighlightType import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement +import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.getLastLambdaExpression import org.jetbrains.kotlin.idea.inspections.collections.isMap import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.idea.util.calleeTextRangeInThis import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtLambdaExpression import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getType import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -41,16 +40,14 @@ class JavaMapForEachInspection : AbstractApplicabilityBasedInspection() ?: return + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { + val call = element.callExpression ?: return val lambda = call.lambda() ?: return val valueParameters = lambda.valueParameters lambda.functionLiteral.valueParameterList?.replace( diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveLambdaOutsideParenthesesInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveLambdaOutsideParenthesesInspection.kt index 95437e4191e..10750a52dea 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveLambdaOutsideParenthesesInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveLambdaOutsideParenthesesInspection.kt @@ -8,14 +8,12 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.codeInspection.ProblemHighlightType import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.core.canMoveLambdaOutsideParentheses import org.jetbrains.kotlin.idea.core.getLastLambdaExpression import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses +import org.jetbrains.kotlin.idea.util.textRangeIn import org.jetbrains.kotlin.psi.KtCallExpression -import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtValueArgument -import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.unpackFunctionLiteral @@ -36,19 +34,17 @@ class MoveLambdaOutsideParenthesesInspection : AbstractApplicabilityBasedInspect override fun isApplicable(element: KtCallExpression) = element.canMoveLambdaOutsideParentheses() - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val expression = element.getParentOfType(strict = false) ?: return - - if (expression.canMoveLambdaOutsideParentheses()) { - expression.moveFunctionLiteralOutsideParentheses() + override fun applyTo(element: KtCallExpression, project: Project, editor: Editor?) { + if (element.canMoveLambdaOutsideParentheses()) { + element.moveFunctionLiteralOutsideParentheses() } } override fun inspectionText(element: KtCallExpression) = "Lambda argument ${element.verb} be moved out of parentheses" - override fun inspectionTarget(element: KtCallExpression): KtElement { - return element.getLastLambdaExpression()?.getStrictParentOfType()?.asElement() ?: element - } + override fun inspectionHighlightRangeInElement(element: KtCallExpression) = element.getLastLambdaExpression() + ?.getStrictParentOfType()?.asElement() + ?.textRangeIn(element) override val defaultFixText = "Move lambda argument out of parentheses" } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/NullableBooleanElvisInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/NullableBooleanElvisInspection.kt index 5b952d245d2..820640ab193 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/NullableBooleanElvisInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/NullableBooleanElvisInspection.kt @@ -75,7 +75,7 @@ class NullableBooleanElvisInspection : AbstractKotlinInspection(), CleanupLocalI val prefixExpression = equalityCheckExpression.getParentOfType(strict = true) ?: return val simplifier = SimplifyNegatedBinaryExpressionInspection() if (simplifier.isApplicable(prefixExpression)) { - simplifier.applyTo(prefixExpression.operationReference) + simplifier.applyTo(prefixExpression) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveCurlyBracesFromTemplateInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveCurlyBracesFromTemplateInspection.kt index 805d8f3fec7..2623394cf5f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveCurlyBracesFromTemplateInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveCurlyBracesFromTemplateInspection.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.core.canDropBraces import org.jetbrains.kotlin.idea.core.dropBraces import org.jetbrains.kotlin.psi.KtBlockStringTemplateEntry @@ -20,7 +19,7 @@ class RemoveCurlyBracesFromTemplateInspection : override fun isApplicable(element: KtBlockStringTemplateEntry): Boolean = element.canDropBraces() - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - (element as KtBlockStringTemplateEntry).dropBraces() + override fun applyTo(element: KtBlockStringTemplateEntry, project: Project, editor: Editor?) { + element.dropBraces() } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceArrayEqualityOpWithArraysEqualsInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceArrayEqualityOpWithArraysEqualsInspection.kt index 828d5db9b58..2d6a6e2d24f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceArrayEqualityOpWithArraysEqualsInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceArrayEqualityOpWithArraysEqualsInspection.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.intentions.resolvedToArrayType import org.jetbrains.kotlin.lexer.KtTokens @@ -28,24 +27,23 @@ import org.jetbrains.kotlin.psi.createExpressionByPattern import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall class ReplaceArrayEqualityOpWithArraysEqualsInspection : AbstractApplicabilityBasedInspection( - KtBinaryExpression::class.java + KtBinaryExpression::class.java ) { - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val expression = element as? KtBinaryExpression ?: return - val right = expression.right ?: return - val left = expression.left ?: return + override fun applyTo(element: KtBinaryExpression, project: Project, editor: Editor?) { + val right = element.right ?: return + val left = element.left ?: return val factory = KtPsiFactory(project) val template = buildString { - if (expression.operationToken == KtTokens.EXCLEQ) append("!") + if (element.operationToken == KtTokens.EXCLEQ) append("!") append("$0.contentEquals($1)") } - expression.replace(factory.createExpressionByPattern(template, left, right)) + element.replace(factory.createExpressionByPattern(template, left, right)) } override fun isApplicable(element: KtBinaryExpression): Boolean { - val operationToken = element.operationToken - when (operationToken) { - KtTokens.EQEQ, KtTokens.EXCLEQ -> {} + when (element.operationToken) { + KtTokens.EQEQ, KtTokens.EXCLEQ -> { + } else -> return false } val right = element.right diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceAssertBooleanWithAssertEqualityInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceAssertBooleanWithAssertEqualityInspection.kt index 76a371ead18..a30b7c427e4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceAssertBooleanWithAssertEqualityInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceAssertBooleanWithAssertEqualityInspection.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.codeInsight.actions.OptimizeImportsProcessor import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.ShortenReferences @@ -39,21 +38,20 @@ class ReplaceAssertBooleanWithAssertEqualityInspection : AbstractApplicabilityBa return (element.replaceableAssertion() != null) } - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val expression = element as? KtCallExpression ?: return - val valueArguments = expression.valueArguments + override fun applyTo(element: KtCallExpression, project: Project, editor: Editor?) { + val valueArguments = element.valueArguments val condition = valueArguments.firstOrNull()?.getArgumentExpression() as? KtBinaryExpression ?: return val left = condition.left ?: return val right = condition.right ?: return - val assertion = expression.replaceableAssertion() ?: return + val assertion = element.replaceableAssertion() ?: return - val file = expression.containingKtFile + val file = element.containingKtFile val factory = KtPsiFactory(project) val replaced = if (valueArguments.size == 2) { val message = valueArguments[1].getArgumentExpression() ?: return - expression.replaced(factory.createExpressionByPattern("$assertion($0, $1, $2)", left, right, message)) + element.replaced(factory.createExpressionByPattern("$assertion($0, $1, $2)", left, right, message)) } else { - expression.replaced(factory.createExpressionByPattern("$assertion($0, $1)", left, right)) + element.replaced(factory.createExpressionByPattern("$assertion($0, $1)", left, right)) } ShortenReferences.DEFAULT.process(replaced) OptimizeImportsProcessor(project, file).run() @@ -79,11 +77,11 @@ class ReplaceAssertBooleanWithAssertEqualityInspection : AbstractApplicabilityBa return assertionMap[Pair(referencedName, operationToken)] } - + private fun KtExpression.descriptor(context: BindingContext): CallableDescriptor? { return getResolvedCall(context)?.resultingDescriptor } - + private fun KtExpression.type(context: BindingContext): KotlinType? { return descriptor(context)?.returnType } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt index 7f6c93e2cbd..c72f32c1896 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt @@ -18,15 +18,14 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.intentions.callExpression +import org.jetbrains.kotlin.idea.util.calleeTextRangeInThis import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType -import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall @@ -63,26 +62,25 @@ class ReplacePutWithAssignmentInspection : AbstractApplicabilityBasedInspection< return receiverClass.isSubclassOf(DefaultBuiltIns.Instance.mutableMap) } - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val expression = element.getParentOfType(strict = false) ?: return - val valueArguments = expression.callExpression?.valueArguments ?: return + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { + val valueArguments = element.callExpression?.valueArguments ?: return val firstArg = valueArguments[0]?.getArgumentExpression() ?: return val secondArg = valueArguments[1]?.getArgumentExpression() ?: return val label = if (secondArg is KtLambdaExpression) { val returnLabel = secondArg.findDescendantOfType()?.getLabelName() compatibleNames.firstOrNull { it == returnLabel }?.plus("@") ?: "" } else "" - expression.replace( - KtPsiFactory(expression).createExpressionByPattern( + element.replace( + KtPsiFactory(element).createExpressionByPattern( "$0[$1] = $label$2", - expression.receiverExpression, + element.receiverExpression, firstArg, secondArg ) ) } - override fun inspectionTarget(element: KtDotQualifiedExpression) = element.callExpression?.calleeExpression ?: element + override fun inspectionHighlightRangeInElement(element: KtDotQualifiedExpression) = element.calleeTextRangeInThis() override fun inspectionText(element: KtDotQualifiedExpression): String = "map.put() should be converted to assignment" diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceToStringWithStringTemplateInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceToStringWithStringTemplateInspection.kt index 0404754e388..837a6b44246 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceToStringWithStringTemplateInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceToStringWithStringTemplateInspection.kt @@ -7,13 +7,11 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.intentions.isToString import org.jetbrains.kotlin.psi.KtBlockStringTemplateEntry import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtReferenceExpression -import org.jetbrains.kotlin.psi.psiUtil.getParentOfType class ReplaceToStringWithStringTemplateInspection : AbstractApplicabilityBasedInspection( KtDotQualifiedExpression::class.java @@ -24,15 +22,12 @@ class ReplaceToStringWithStringTemplateInspection : AbstractApplicabilityBasedIn return element.isToString() } - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val expression = element.getParentOfType(strict = false) ?: return - val variable = expression.receiverExpression.text + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { + val variable = element.receiverExpression.text element.replace(KtPsiFactory(element).createExpression("\"$$variable\"")) } override fun inspectionText(element: KtDotQualifiedExpression) = "Call of 'toString' could be replaced with string template" - override fun inspectionTarget(element: KtDotQualifiedExpression) = element - override val defaultFixText = "Replace 'toString' with string template" } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceWithOperatorAssignmentInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceWithOperatorAssignmentInspection.kt index a7959f9beb4..23e160d6409 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceWithOperatorAssignmentInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceWithOperatorAssignmentInspection.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.codeInspection.ProblemHighlightType import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor @@ -115,8 +114,8 @@ class ReplaceWithOperatorAssignmentInspection : AbstractApplicabilityBasedInspec operationToken == KtTokens.DIV || operationToken == KtTokens.PERC - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - (element as? KtBinaryExpression)?.replace(buildOperatorAssignment(element)) + override fun applyTo(element: KtBinaryExpression, project: Project, editor: Editor?) { + element.replace(buildOperatorAssignment(element)) } private fun buildOperatorAssignment(element: KtBinaryExpression): KtBinaryExpression { diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/SimplifyAssertNotNullInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/SimplifyAssertNotNullInspection.kt index 9b7868f7193..dd3b7faa356 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/SimplifyAssertNotNullInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/SimplifyAssertNotNullInspection.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.codeInsight.CodeInsightUtilCore import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.core.ShortenReferences @@ -69,35 +68,34 @@ class SimplifyAssertNotNullInspection : AbstractApplicabilityBasedInspection( - KtPrefixExpression::class.java -) { +class SimplifyNegatedBinaryExpressionInspection : AbstractApplicabilityBasedInspection(KtPrefixExpression::class.java) { private fun IElementType.negate(): KtSingleValueToken? = when (this) { KtTokens.IN_KEYWORD -> KtTokens.NOT_IN @@ -47,7 +45,7 @@ class SimplifyNegatedBinaryExpressionInspection : AbstractApplicabilityBasedInsp else -> null } - override fun inspectionTarget(element: KtPrefixExpression) = element.operationReference + override fun inspectionHighlightRangeInElement(element: KtPrefixExpression) = element.operationReference.textRangeIn(element) override fun inspectionText(element: KtPrefixExpression) = "Negated operation should be simplified" @@ -73,9 +71,8 @@ class SimplifyNegatedBinaryExpressionInspection : AbstractApplicabilityBasedInsp return (expression.operationReference.getReferencedNameElementType() as? KtSingleValueToken)?.negate() != null } - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val prefixExpression = element.parent as? KtPrefixExpression ?: return - val expression = KtPsiUtil.deparenthesize(prefixExpression.baseExpression) ?: return + override fun applyTo(element: KtPrefixExpression, project: Project, editor: Editor?) { + val expression = KtPsiUtil.deparenthesize(element.baseExpression) ?: return val operation = (expression as KtOperationExpression).operationReference.getReferencedNameElementType().negate()?.value ?: return val psiFactory = KtPsiFactory(expression) @@ -87,6 +84,6 @@ class SimplifyNegatedBinaryExpressionInspection : AbstractApplicabilityBasedInsp else -> throw IllegalArgumentException() } - prefixExpression.replace(newExpression) + element.replace(newExpression) } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnnecessaryVariableInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnnecessaryVariableInspection.kt index 4f905d13d8c..fc502ef7654 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnnecessaryVariableInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnnecessaryVariableInspection.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import com.intellij.psi.search.LocalSearchScope import com.intellij.psi.search.searches.ReferencesSearch import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -27,9 +26,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator import org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineValHandler +import org.jetbrains.kotlin.idea.util.nameIdentifierTextRangeInThis import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments -import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET @@ -40,7 +39,7 @@ class UnnecessaryVariableInspection : AbstractApplicabilityBasedInspection @@ -54,9 +53,8 @@ class UnnecessaryVariableInspection : AbstractApplicabilityBasedInspection(strict = false) ?: return - KotlinInlineValHandler(withPrompt = false).inlineElement(project, editor, property) + override fun applyTo(element: KtProperty, project: Project, editor: Editor?) { + KotlinInlineValHandler(withPrompt = false).inlineElement(project, editor, element) } companion object { @@ -72,7 +70,7 @@ class UnnecessaryVariableInspection : AbstractApplicabilityBasedInspection(KtWhenExpression::class.java) { override fun isApplicable(element: KtWhenExpression) = element.getSubjectToIntroduce() != null - override fun inspectionTarget(element: KtWhenExpression) = element.whenKeyword + override fun inspectionHighlightRangeInElement(element: KtWhenExpression) = element.whenKeyword.textRangeIn(element) override fun inspectionText(element: KtWhenExpression) = "'when' with subject should be used" @@ -40,7 +39,7 @@ class IntroduceWhenSubjectInspection : AbstractApplicabilityBasedInspection(strict = true)?.introduceSubject() + override fun applyTo(element: KtWhenExpression, project: Project, editor: Editor?) { + element.introduceSubject() } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceCallWithBinaryOperatorInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceCallWithBinaryOperatorInspection.kt index cb379acc7b8..494936194bb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceCallWithBinaryOperatorInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceCallWithBinaryOperatorInspection.kt @@ -35,11 +35,12 @@ import org.jetbrains.kotlin.idea.intentions.isReceiverExpressionWithValue import org.jetbrains.kotlin.idea.intentions.toResolvedCall import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.platform +import org.jetbrains.kotlin.idea.util.calleeTextRangeInThis import org.jetbrains.kotlin.lexer.KtSingleValueToken import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.platform.js.isJs import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRow -import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.resolve.calls.callUtil.getFirstArgumentExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getReceiverExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getType @@ -47,7 +48,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.smartcasts.getKotlinTypeWithPossibleSmartCastToFP -import org.jetbrains.kotlin.platform.js.isJs import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.expressions.OperatorConventions @@ -82,7 +82,7 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec return element.isReceiverExpressionWithValue() } - override fun inspectionTarget(element: KtDotQualifiedExpression) = element.callExpression?.calleeExpression ?: element + override fun inspectionHighlightRangeInElement(element: KtDotQualifiedExpression) = element.calleeTextRangeInThis() override fun inspectionHighlightType(element: KtDotQualifiedExpression): ProblemHighlightType { val calleeExpression = element.callExpression?.calleeExpression as? KtSimpleNameExpression @@ -118,28 +118,27 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec return "Replace with '${operation.value}'" } - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - val qualifiedExpression = element.getParentOfType(strict = false) ?: return - val callExpression = qualifiedExpression.callExpression ?: return + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { + val callExpression = element.callExpression ?: return val operation = operation(callExpression.calleeExpression as? KtSimpleNameExpression ?: return) ?: return val argument = callExpression.valueArguments.single().getArgumentExpression() ?: return - val receiver = qualifiedExpression.receiverExpression + val receiver = element.receiverExpression - val factory = KtPsiFactory(qualifiedExpression) + val factory = KtPsiFactory(element) when (operation) { KtTokens.EXCLEQ -> { - val prefixExpression = qualifiedExpression.getWrappingPrefixExpressionIfAny() ?: return + val prefixExpression = element.getWrappingPrefixExpressionIfAny() ?: return val newExpression = factory.createExpressionByPattern("$0 != $1", receiver, argument) prefixExpression.replace(newExpression) } in OperatorConventions.COMPARISON_OPERATIONS -> { - val binaryParent = qualifiedExpression.parent as? KtBinaryExpression ?: return + val binaryParent = element.parent as? KtBinaryExpression ?: return val newExpression = factory.createExpressionByPattern("$0 ${operation.value} $1", receiver, argument) binaryParent.replace(newExpression) } else -> { val newExpression = factory.createExpressionByPattern("$0 ${operation.value} $1", receiver, argument) - qualifiedExpression.replace(newExpression) + element.replace(newExpression) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceGetOrSetInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceGetOrSetInspection.kt index 4cca4afe837..22b5ac087f1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceGetOrSetInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/conventionNameCalls/ReplaceGetOrSetInspection.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspectio import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.intentions.isReceiverExpressionWithValue import org.jetbrains.kotlin.idea.intentions.toResolvedCall +import org.jetbrains.kotlin.idea.util.calleeTextRangeInThis import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getChildOfType @@ -39,7 +40,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.isValidOperator class ReplaceGetOrSetInspection : AbstractApplicabilityBasedInspection( - KtDotQualifiedExpression::class.java + KtDotQualifiedExpression::class.java ) { private fun FunctionDescriptor.isExplicitOperator(): Boolean { return if (overriddenDescriptors.isEmpty()) @@ -75,10 +76,9 @@ class ReplaceGetOrSetInspection : AbstractApplicabilityBasedInspection()!! - } - else { - newElement as KtArrayAccessExpression - } + newElement.getChildOfType() + } else { + newElement as? KtArrayAccessExpression + } ?: return - editor.caretModel.moveToOffset(arrayAccessExpression.leftBracket!!.startOffset) + arrayAccessExpression.leftBracket?.startOffset?.let { editor.caretModel.moveToOffset(it) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringInspection.kt index 9700574fe99..8eaaa80c43f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringInspection.kt @@ -5,22 +5,22 @@ package org.jetbrains.kotlin.idea.inspections.substring -import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isStableSimpleExpression import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.intentions.toResolvedCall +import org.jetbrains.kotlin.idea.util.calleeTextRangeInThis import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -abstract class ReplaceSubstringInspection : - AbstractApplicabilityBasedInspection(KtDotQualifiedExpression::class.java) { +abstract class ReplaceSubstringInspection : AbstractApplicabilityBasedInspection( + KtDotQualifiedExpression::class.java +) { protected abstract fun isApplicableInner(element: KtDotQualifiedExpression): Boolean protected open val isAlwaysStable: Boolean = false @@ -30,8 +30,7 @@ abstract class ReplaceSubstringInspection : } else false - override fun inspectionHighlightRangeInElement(element: KtDotQualifiedExpression): TextRange? = - element.callExpression?.calleeExpression?.textRange?.shiftLeft(element.startOffset) + override fun inspectionHighlightRangeInElement(element: KtDotQualifiedExpression) = element.calleeTextRangeInThis() protected fun isIndexOfCall(expression: KtExpression?, expectedReceiver: KtExpression): Boolean { return expression is KtDotQualifiedExpression diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithDropLastInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithDropLastInspection.kt index 04d78558746..d48bbfd946c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithDropLastInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithDropLastInspection.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.inspections.substring import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.lexer.KtTokens @@ -20,10 +19,9 @@ class ReplaceSubstringWithDropLastInspection : ReplaceSubstringInspection() { override fun inspectionText(element: KtDotQualifiedExpression): String = "Replace 'substring' call with 'dropLast' call" override val defaultFixText: String = "Replace 'substring' call with 'dropLast' call" - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - if (element !is KtDotQualifiedExpression) return - val argument = element.callExpression!!.valueArguments[1].getArgumentExpression()!! - val rightExpression = (argument as KtBinaryExpression).right!! + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { + val argument = element.callExpression?.valueArguments?.elementAtOrNull(1)?.getArgumentExpression() ?: return + val rightExpression = (argument as? KtBinaryExpression)?.right ?: return element.replaceWith("$0.dropLast($1)", rightExpression) } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithIndexingOperationInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithIndexingOperationInspection.kt index 47ecc0c7122..d83985b39f1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithIndexingOperationInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithIndexingOperationInspection.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.inspections.substring import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.psi.KtConstantExpression @@ -15,14 +14,12 @@ import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator -class ReplaceSubstringWithIndexingOperationInspection : - ReplaceSubstringInspection() { +class ReplaceSubstringWithIndexingOperationInspection : ReplaceSubstringInspection() { override fun inspectionText(element: KtDotQualifiedExpression): String = "Replace 'substring' call with indexing operation call" override val defaultFixText: String = "Replace 'substring' call with indexing operation call" override val isAlwaysStable: Boolean = true - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - if (element !is KtDotQualifiedExpression) return + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { val expression = element.callExpression?.valueArguments?.firstOrNull()?.getArgumentExpression() ?: return element.replaceWith("$0[$1]", expression) } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithSubstringBeforeAfterIntentions.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithSubstringBeforeAfterIntentions.kt index 335fd66cb77..6583eac32ab 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithSubstringBeforeAfterIntentions.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithSubstringBeforeAfterIntentions.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.inspections.substring import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtExpression @@ -17,8 +16,7 @@ class ReplaceSubstringWithSubstringAfterInspection : ReplaceSubstringInspection( override val defaultFixText: String = "Replace 'substring' call with 'substringAfter' call" - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - if (element !is KtDotQualifiedExpression) return + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { element.replaceWith( "$0.substringAfter($1)", (element.getArgumentExpression(0) as KtDotQualifiedExpression).getArgumentExpression(0) @@ -36,8 +34,7 @@ class ReplaceSubstringWithSubstringBeforeInspection : ReplaceSubstringInspection override val defaultFixText: String = "Replace 'substring' call with 'substringBefore' call" - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - if (element !is KtDotQualifiedExpression) return + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { element.replaceWith( "$0.substringBefore($1)", (element.getArgumentExpression(1) as KtDotQualifiedExpression).getArgumentExpression(0) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithTakeInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithTakeInspection.kt index 5eebe57fcbe..03ffa5692bf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithTakeInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/substring/ReplaceSubstringWithTakeInspection.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.inspections.substring import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression @@ -16,9 +15,8 @@ class ReplaceSubstringWithTakeInspection : ReplaceSubstringInspection() { override val defaultFixText: String = "Replace 'substring' call with 'take' call" - override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { - if (element !is KtDotQualifiedExpression) return - val argument = element.callExpression!!.valueArguments[1].getArgumentExpression()!! + override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { + val argument = element.callExpression?.valueArguments?.elementAtOrNull(1)?.getArgumentExpression() ?: return element.replaceWith("$0.take($1)", argument) } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/IfThenUtils.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/IfThenUtils.kt index dcba8442c6a..eeac629565f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/IfThenUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/IfThenUtils.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinI import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.resolve.frontendService import org.jetbrains.kotlin.idea.util.getResolutionScope +import org.jetbrains.kotlin.idea.util.textRangeIn import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name @@ -317,9 +318,9 @@ internal fun KtIfExpression.shouldBeTransformed(): Boolean = when (val condition else -> false } -fun KtIfExpression.textRange(): TextRange { - val rightOffset = rightParenthesis?.endOffset ?: return ifKeyword.textRange - return TextRange(ifKeyword.startOffset, rightOffset) +fun KtIfExpression.fromIfKeywordToRightParenthesisTextRangeInThis(): TextRange { + val rightOffset = rightParenthesis?.endOffset ?: return ifKeyword.textRangeIn(this) + return TextRange(ifKeyword.startOffset, rightOffset).shiftLeft(startOffset) } private fun KtExpression.checkedExpression() = when (this) { diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt index 2e4d3e88cde..bc6b1fb877c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt @@ -198,7 +198,7 @@ object J2KPostProcessingRegistrarImpl : J2KPostProcessingRegistrar { if (!isApplicable(tElement)) return null return { if (isApplicable(tElement)) { // check availability of the inspection again because something could change - inspection.applyTo(inspection.inspectionTarget(tElement)) + inspection.applyTo(tElement) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt b/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt index 33824188bba..0ac1ba98f38 100644 --- a/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt +++ b/idea/src/org/jetbrains/kotlin/idea/util/expressionExt.kt @@ -5,10 +5,14 @@ package org.jetbrains.kotlin.idea.util +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClass +import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -32,4 +36,10 @@ fun KtExpression.hasNoSideEffects(): Boolean = when (this) { is KtStringTemplateExpression -> !hasInterpolation() is KtConstantExpression -> true else -> ConstantExpressionEvaluator.getConstant(this, analyze(BodyResolveMode.PARTIAL)) != null -} \ No newline at end of file +} + +fun PsiElement.textRangeIn(other: PsiElement): TextRange = textRange.shiftLeft(other.startOffset) + +fun KtDotQualifiedExpression.calleeTextRangeInThis(): TextRange? = callExpression?.calleeExpression?.textRangeIn(this) + +fun KtNamedDeclaration.nameIdentifierTextRangeInThis(): TextRange? = nameIdentifier?.textRangeIn(this) \ No newline at end of file diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt index a6f82007f11..97f2149875a 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/inspectionLikePostProcessings.kt @@ -287,7 +287,7 @@ inline fun