i18n: add bundle for idea/inspections/*

This commit is contained in:
Dmitry Gridin
2020-03-04 13:59:00 +07:00
parent 3035477e0c
commit 76ac4ffb96
32 changed files with 191 additions and 76 deletions
@@ -1245,4 +1245,68 @@ step.2.0.of.1=Step 2: {0} of {1}
step.3.0.of.1=Step 3: {0} of {1} step.3.0.of.1=Step 3: {0} of {1}
title.done=Done title.done=Done
revert.applied.imports=revert applied imports revert.applied.imports=revert applied imports
delete.0=delete {0} delete.0=delete {0}
replace.if.expression.with.elvis.expression=Replace 'if' expression with elvis expression
report.also.on.statement=Report also on statement
if.then.foldable.to=If-Then foldable to '?:'
replace.if.expression.with.safe.access.expression=Replace 'if' expression with safe access expression
remove.redundant.if.expression=Remove redundant 'if' expression
replace.if.expression.with.safe.cast.expression=Replace 'if' expression with safe cast expression
simplify.foldable.if.then=Simplify foldable if-then
foldable.if.then=Foldable if-then
introduce.when.subject=Introduce 'when' subject
when.with.subject.should.be.used='when' with subject should be used
introduce.0.as.subject.0.when=Introduce ''{0}'' as subject of ''when''
convert.call.chain.into.sequence.fix.text=Convert call chain into 'Sequence'
call.chain.length.to.transform=Call chain length to transform:
call.chain.on.collection.could.be.converted.into.sequence.to.improve.performance=Call chain on collection could be converted into 'Sequence' to improve performance
remove.useless.call.fix.text=Remove useless call
rename.useless.call.fix.text=Change call to ''{0}''
call.chain.on.collection.type.may.be.simplified=Call chain on collection type may be simplified
0.call.could.be.simplified.to.1={0} call could be simplified to {1}
simplify.call.fix.text=Convert ''{0}'' call to ''{1}''
simplify.call.chain.fix.text=Merge call chain to ''{0}''
call.on.collection.type.may.be.reduced=Call on collection type may be reduced
useless.call.on.collection.type=Useless call on collection type
this.call.is.useless.with=This call is useless with ?.
useless.call.on.not.null.type=Useless call on not-null type
call.on.not.null.type.may.be.reduced=Call on not-null type may be reduced
replace.total.order.equality.with.ieee.754.equality=Replace total order equality with IEEE 754 equality
replace.with.binary.operator=Replace with binary operator
call.replaceable.with.binary.operator=Call replaceable with binary operator
replace.get.or.set.call.with.indexing.operator=Replace get or set call with indexing operator
should.be.replaced.with.indexing=Should be replaced with indexing
replace.0.call.with.indexing.operator=Replace ''{0}'' call with indexing operator
function.returning.0.with.a.name.that.does.not.end.with.1=Function returning {0} with a name that does not end with {1}
add.call.or.unwrap.type.fix.text=Add ''.{0}()'' to function result (breaks use-sites!)
add.call.or.unwrap.type.fix.text1=Unwrap ''{0}'' return type (breaks use-sites!)
reports.only.function.calls.from.kotlinx.coroutines=Reports only function calls from kotlinx.coroutines
deferred.result.is.never.used=Deferred result is never used
function.0.returning.1.without.the.corresponding=Function ''{0}'' returning ''{1}'' without the corresponding function ''{2}'' returning ''{3}''
redundant.async.call.may.be.reduced.to.0=Redundant ''async'' call may be reduced to ''{0}''
redundant.runcatching.call.may.be.reduced.to.0=Redundant 'runCatching' call may be reduced to ''{0}''
rename.to.fix.text=Rename to ''{0}''
wrap.with.coroutine.scope.fix.text=Wrap function body with 'coroutineScope { ... }'
wrap.with.coroutine.scope.fix.text2=Wrap call with 'coroutineScope { ... }'
wrap.with.coroutine.scope.fix.text3=Remove receiver & wrap with 'coroutineScope { ... }'
wrap.with.coroutine.scope.fix.family.name=Wrap with coroutineScope
ambiguous.coroutinecontext.due.to.coroutinescope.receiver.of.suspend.function=Ambiguous coroutineContext due to CoroutineScope receiver of suspend function
replace.with.kotlin.analog.function.family.name=Replace with Kotlin analog
should.be.replaced.with.kotlin.function=Should be replaced with Kotlin function
replace.with.kotlin.analog.function.text=Replace with `'{0}`' function
add.documentation.fix.text=Add documentation
missing.documentation=Missing documentation
0.is.missing.documentation={0} is missing documentation
library.should.be.updated.to.be.compatible.with.kotlin.1.3=Library should be updated to be compatible with Kotlin 1.3
it.s.prohibited.to.call.0.with.min.value.step.since.1.3=It's prohibited to call {0} with MIN_VALUE step since 1.3
obsolete.coroutine.usage.in.whole.fix.family.name=Fix experimental coroutines usages in the project
apply.in.the.project.0=Apply in the project: {0}
obsolete.coroutine.usage.fix.family.name=Fix experimental coroutines usage
0.is.expected.to.be.used.since.kotlin.1.3=`'{0}`' is expected to be used since Kotlin 1.3
methods.are.absent.in.coroutines.class.since.1.3=Methods are absent in coroutines class since 1.3
experimental.coroutines.usages.are.obsolete.since.1.3=Experimental coroutines usages are obsolete since 1.3
replace.substring.call.with.droplast.call=Replace 'substring' call with 'dropLast' call
replace.substring.call.with.indexing.operation.call=Replace 'substring' call with indexing operation call
replace.substring.call.with.substringbefore.call=Replace 'substring' call with 'substringBefore' call
replace.substring.call.with.substringafter.call=Replace 'substring' call with 'substringAfter' call
replace.substring.call.with.take.call=Replace 'substring' call with 'take' call
@@ -12,6 +12,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
@@ -27,7 +28,7 @@ import javax.swing.JComponent
class IfThenToElvisInspection( class IfThenToElvisInspection(
@JvmField var highlightStatement: Boolean = false @JvmField var highlightStatement: Boolean = false
) : AbstractApplicabilityBasedInspection<KtIfExpression>(KtIfExpression::class.java) { ) : AbstractApplicabilityBasedInspection<KtIfExpression>(KtIfExpression::class.java) {
override fun inspectionText(element: KtIfExpression): String = "If-Then foldable to '?:'" override fun inspectionText(element: KtIfExpression): String = KotlinBundle.message("if.then.foldable.to")
override val defaultFixText: String = INTENTION_TEXT override val defaultFixText: String = INTENTION_TEXT
@@ -46,11 +47,11 @@ class IfThenToElvisInspection(
override fun inspectionHighlightRangeInElement(element: KtIfExpression) = element.fromIfKeywordToRightParenthesisTextRangeInThis() override fun inspectionHighlightRangeInElement(element: KtIfExpression) = element.fromIfKeywordToRightParenthesisTextRangeInThis()
override fun createOptionsPanel(): JComponent? = MultipleCheckboxOptionsPanel(this).also { override fun createOptionsPanel(): JComponent? = MultipleCheckboxOptionsPanel(this).also {
it.addCheckbox("Report also on statement", "highlightStatement") it.addCheckbox(KotlinBundle.message("report.also.on.statement"), "highlightStatement")
} }
companion object { companion object {
const val INTENTION_TEXT = "Replace 'if' expression with elvis expression" val INTENTION_TEXT get() = KotlinBundle.message("replace.if.expression.with.elvis.expression")
fun convert(element: KtIfExpression, editor: Editor?) { fun convert(element: KtIfExpression, editor: Editor?) {
val ifThenToSelectData = element.buildSelectTransformationData() ?: return val ifThenToSelectData = element.buildSelectTransformationData() ?: return
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -9,6 +9,7 @@ import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
@@ -29,12 +30,12 @@ class IfThenToSafeAccessInspection : AbstractApplicabilityBasedInspection<KtIfEx
override fun inspectionHighlightRangeInElement(element: KtIfExpression) = element.fromIfKeywordToRightParenthesisTextRangeInThis() override fun inspectionHighlightRangeInElement(element: KtIfExpression) = element.fromIfKeywordToRightParenthesisTextRangeInThis()
override fun inspectionText(element: KtIfExpression) = "Foldable if-then" override fun inspectionText(element: KtIfExpression) = KotlinBundle.message("foldable.if.then")
override fun inspectionHighlightType(element: KtIfExpression): ProblemHighlightType = override fun inspectionHighlightType(element: KtIfExpression): ProblemHighlightType =
if (element.shouldBeTransformed()) ProblemHighlightType.GENERIC_ERROR_OR_WARNING else ProblemHighlightType.INFORMATION if (element.shouldBeTransformed()) ProblemHighlightType.GENERIC_ERROR_OR_WARNING else ProblemHighlightType.INFORMATION
override val defaultFixText = "Simplify foldable if-then" override val defaultFixText = KotlinBundle.message("simplify.foldable.if.then")
override fun fixText(element: KtIfExpression): String = fixTextFor(element) override fun fixText(element: KtIfExpression): String = fixTextFor(element)
@@ -49,12 +50,12 @@ class IfThenToSafeAccessInspection : AbstractApplicabilityBasedInspection<KtIfEx
val ifThenToSelectData = element.buildSelectTransformationData() val ifThenToSelectData = element.buildSelectTransformationData()
return if (ifThenToSelectData?.baseClauseEvaluatesToReceiver() == true) { return if (ifThenToSelectData?.baseClauseEvaluatesToReceiver() == true) {
if (ifThenToSelectData.condition is KtIsExpression) { if (ifThenToSelectData.condition is KtIsExpression) {
"Replace 'if' expression with safe cast expression" KotlinBundle.message("replace.if.expression.with.safe.cast.expression")
} else { } else {
"Remove redundant 'if' expression" KotlinBundle.message("remove.redundant.if.expression")
} }
} else { } else {
"Replace 'if' expression with safe access expression" KotlinBundle.message("replace.if.expression.with.safe.access.expression")
} }
} }
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.inspections.branchedTransformations
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.getSubjectToIntroduce import org.jetbrains.kotlin.idea.intentions.branchedTransformations.getSubjectToIntroduce
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceSubject import org.jetbrains.kotlin.idea.intentions.branchedTransformations.introduceSubject
@@ -30,13 +31,13 @@ class IntroduceWhenSubjectInspection : AbstractApplicabilityBasedInspection<KtWh
override fun inspectionHighlightRangeInElement(element: KtWhenExpression) = element.whenKeyword.textRangeIn(element) override fun inspectionHighlightRangeInElement(element: KtWhenExpression) = element.whenKeyword.textRangeIn(element)
override fun inspectionText(element: KtWhenExpression) = "'when' with subject should be used" override fun inspectionText(element: KtWhenExpression) = KotlinBundle.message("when.with.subject.should.be.used")
override val defaultFixText = "Introduce 'when' subject" override val defaultFixText = KotlinBundle.message("introduce.when.subject")
override fun fixText(element: KtWhenExpression): String { override fun fixText(element: KtWhenExpression): String {
val subject = element.getSubjectToIntroduce() ?: return "" val subject = element.getSubjectToIntroduce() ?: return ""
return "Introduce '${subject.text}' as subject of 'when'" return KotlinBundle.message("introduce.0.as.subject.0.when", subject.text)
} }
override fun applyTo(element: KtWhenExpression, project: Project, editor: Editor?) { override fun applyTo(element: KtWhenExpression, project: Project, editor: Editor?) {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.inspections.collections package org.jetbrains.kotlin.idea.inspections.collections
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -63,10 +64,10 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
} }
data class Conversion( data class Conversion(
val firstFqName: String, @NonNls val firstFqName: String,
val secondFqName: String, @NonNls val secondFqName: String,
val replacement: String, @NonNls val replacement: String,
val additionalArgument: String? = null, @NonNls val additionalArgument: String? = null,
val withNotNullAssertion: Boolean = false val withNotNullAssertion: Boolean = false
) { ) {
private fun String.convertToShort() = takeLastWhile { it != '.' } private fun String.convertToShort() = takeLastWhile { it != '.' }
@@ -15,7 +15,9 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.LabeledComponent import com.intellij.openapi.ui.LabeledComponent
import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.PsiWhiteSpace
import com.intellij.ui.EditorTextField import com.intellij.ui.EditorTextField
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
@@ -55,7 +57,7 @@ class ConvertCallChainIntoSequenceInspection : AbstractKotlinInspection() {
holder.registerProblemWithoutOfflineInformation( holder.registerProblemWithoutOfflineInformation(
qualified, qualified,
"Call chain on collection could be converted into 'Sequence' to improve performance", KotlinBundle.message("call.chain.on.collection.could.be.converted.into.sequence.to.improve.performance"),
isOnTheFly, isOnTheFly,
highlightType, highlightType,
rangeInElement, rangeInElement,
@@ -74,14 +76,14 @@ class ConvertCallChainIntoSequenceInspection : AbstractKotlinInspection() {
owner.callChainLengthText = regexField.text owner.callChainLengthText = regexField.text
} }
}) })
val labeledComponent = LabeledComponent.create(regexField, "Call chain length to transform:", BorderLayout.WEST) val labeledComponent = LabeledComponent.create(regexField, KotlinBundle.message("call.chain.length.to.transform"), BorderLayout.WEST)
add(labeledComponent, BorderLayout.NORTH) add(labeledComponent, BorderLayout.NORTH)
} }
} }
} }
private class ConvertCallChainIntoSequenceFix : LocalQuickFix { private class ConvertCallChainIntoSequenceFix : LocalQuickFix {
override fun getName() = "Convert call chain into 'Sequence'" override fun getName() = KotlinBundle.message("convert.call.chain.into.sequence.fix.text")
override fun getFamilyName() = name override fun getFamilyName() = name
@@ -207,6 +209,7 @@ private fun KtCallExpression.isLazyTermination(context: BindingContext): Boolean
return isCalling(fqName, context) return isCalling(fqName, context)
} }
@NonNls
private val transformations = listOf( private val transformations = listOf(
"chunked", "chunked",
"distinct", "distinct",
@@ -241,6 +244,7 @@ private val transformations = listOf(
"zipWithNext" "zipWithNext"
).associate { it to FqName("kotlin.collections.$it") } ).associate { it to FqName("kotlin.collections.$it") }
@NonNls
private val terminations = listOf( private val terminations = listOf(
"all", "all",
"any", "any",
@@ -19,12 +19,13 @@ package org.jetbrains.kotlin.idea.inspections.collections
import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtQualifiedExpression
class RemoveUselessCallFix : LocalQuickFix { class RemoveUselessCallFix : LocalQuickFix {
override fun getName() = "Remove useless call" override fun getName() = KotlinBundle.message("remove.useless.call.fix.text")
override fun getFamilyName() = name override fun getFamilyName() = name
@@ -19,12 +19,13 @@ package org.jetbrains.kotlin.idea.inspections.collections
import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
class RenameUselessCallFix(val newName: String) : LocalQuickFix { class RenameUselessCallFix(val newName: String) : LocalQuickFix {
override fun getName() = "Change call to '$newName'" override fun getName() = KotlinBundle.message("rename.useless.call.fix.text", newName)
override fun getFamilyName() = name override fun getFamilyName() = name
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.inspections.collections
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -42,7 +43,7 @@ class SimplifiableCallChainInspection : AbstractCallChainChecker() {
val descriptor = holder.manager.createProblemDescriptor( val descriptor = holder.manager.createProblemDescriptor(
expression, expression,
expression.firstCalleeExpression()!!.textRange.shiftRight(-expression.startOffset), expression.firstCalleeExpression()!!.textRange.shiftRight(-expression.startOffset),
"Call chain on collection type may be simplified", KotlinBundle.message("call.chain.on.collection.type.may.be.simplified"),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly, isOnTheFly,
SimplifyCallChainFix(conversion) { callExpression -> SimplifyCallChainFix(conversion) { callExpression ->
@@ -12,6 +12,7 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.debugger.sequence.psi.receiverType import org.jetbrains.kotlin.idea.debugger.sequence.psi.receiverType
@@ -36,7 +37,7 @@ class SimplifiableCallInspection : AbstractKotlinInspection() {
holder.registerProblem( holder.registerProblem(
calleeExpression, calleeExpression,
"${conversion.shortName} call could be simplified to $replacement", KotlinBundle.message("0.call.could.be.simplified.to.1", conversion.shortName, replacement),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
SimplifyCallFix(conversion, replacement) SimplifyCallFix(conversion, replacement)
) )
@@ -140,7 +141,7 @@ class SimplifiableCallInspection : AbstractKotlinInspection() {
} }
private class SimplifyCallFix(val conversion: Conversion, val replacement: String) : LocalQuickFix { private class SimplifyCallFix(val conversion: Conversion, val replacement: String) : LocalQuickFix {
override fun getName() = "Convert '${conversion.shortName}' call to '$replacement'" override fun getName() = KotlinBundle.message("simplify.call.fix.text", conversion.shortName, replacement)
override fun getFamilyName() = name override fun getFamilyName() = name
@@ -21,6 +21,7 @@ import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
@@ -38,7 +39,7 @@ class SimplifyCallChainFix(
) : LocalQuickFix { ) : LocalQuickFix {
private val shortenedText = conversion.replacement.substringAfterLast(".") private val shortenedText = conversion.replacement.substringAfterLast(".")
override fun getName() = "Merge call chain to '$shortenedText'" override fun getName() = KotlinBundle.message("simplify.call.chain.fix.text", shortenedText)
override fun getFamilyName() = name override fun getFamilyName() = name
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.inspections.collections
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -60,7 +61,7 @@ class UselessCallOnCollectionInspection : AbstractUselessCallInspection() {
expression.operationTokenNode.startOffset - expression.startOffset, expression.operationTokenNode.startOffset - expression.startOffset,
calleeExpression.endOffset - expression.startOffset calleeExpression.endOffset - expression.startOffset
), ),
"Call on collection type may be reduced", KotlinBundle.message("call.on.collection.type.may.be.reduced"),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly, isOnTheFly,
RenameUselessCallFix(newName) RenameUselessCallFix(newName)
@@ -73,7 +74,7 @@ class UselessCallOnCollectionInspection : AbstractUselessCallInspection() {
expression.operationTokenNode.startOffset - expression.startOffset, expression.operationTokenNode.startOffset - expression.startOffset,
calleeExpression.endOffset - expression.startOffset calleeExpression.endOffset - expression.startOffset
), ),
"Useless call on collection type", KotlinBundle.message("useless.call.on.collection.type"),
ProblemHighlightType.LIKE_UNUSED_SYMBOL, ProblemHighlightType.LIKE_UNUSED_SYMBOL,
isOnTheFly, isOnTheFly,
RemoveUselessCallFix() RemoveUselessCallFix()
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.inspections.collections
import com.intellij.codeInspection.IntentionWrapper import com.intellij.codeInspection.IntentionWrapper
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.quickfix.ReplaceWithDotCallFix import org.jetbrains.kotlin.idea.quickfix.ReplaceWithDotCallFix
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtQualifiedExpression
@@ -48,7 +49,7 @@ class UselessCallOnNotNullInspection : AbstractUselessCallInspection() {
val descriptor = holder.manager.createProblemDescriptor( val descriptor = holder.manager.createProblemDescriptor(
expression, expression,
defaultRange, defaultRange,
"Call on not-null type may be reduced", KotlinBundle.message("call.on.not.null.type.may.be.reduced"),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly, isOnTheFly,
*fixes.toTypedArray() *fixes.toTypedArray()
@@ -58,7 +59,7 @@ class UselessCallOnNotNullInspection : AbstractUselessCallInspection() {
val descriptor = holder.manager.createProblemDescriptor( val descriptor = holder.manager.createProblemDescriptor(
expression, expression,
defaultRange, defaultRange,
"Useless call on not-null type", KotlinBundle.message("useless.call.on.not.null.type"),
ProblemHighlightType.LIKE_UNUSED_SYMBOL, ProblemHighlightType.LIKE_UNUSED_SYMBOL,
isOnTheFly, isOnTheFly,
RemoveUselessCallFix() RemoveUselessCallFix()
@@ -67,7 +68,7 @@ class UselessCallOnNotNullInspection : AbstractUselessCallInspection() {
} else if (safeExpression != null) { } else if (safeExpression != null) {
holder.registerProblem( holder.registerProblem(
safeExpression.operationTokenNode.psi, safeExpression.operationTokenNode.psi,
"This call is useless with ?.", KotlinBundle.message("this.call.is.useless.with"),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
IntentionWrapper(ReplaceWithDotCallFix(safeExpression), safeExpression.containingKtFile) IntentionWrapper(ReplaceWithDotCallFix(safeExpression), safeExpression.containingKtFile)
) )
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
@@ -104,19 +105,19 @@ class ReplaceCallWithBinaryOperatorInspection : AbstractApplicabilityBasedInspec
} }
} }
override fun inspectionText(element: KtDotQualifiedExpression) = "Call replaceable with binary operator" override fun inspectionText(element: KtDotQualifiedExpression) = KotlinBundle.message("call.replaceable.with.binary.operator")
override val defaultFixText: String override val defaultFixText: String
get() = "Replace with binary operator" get() = KotlinBundle.message("replace.with.binary.operator")
override fun fixText(element: KtDotQualifiedExpression): String { override fun fixText(element: KtDotQualifiedExpression): String {
val calleeExpression = element.callExpression?.calleeExpression as? KtSimpleNameExpression ?: return defaultFixText val calleeExpression = element.callExpression?.calleeExpression as? KtSimpleNameExpression ?: return defaultFixText
if (calleeExpression.isFloatingPointNumberEquals()) { if (calleeExpression.isFloatingPointNumberEquals()) {
return "Replace total order equality with IEEE 754 equality" return KotlinBundle.message("replace.total.order.equality.with.ieee.754.equality")
} }
val operation = operation(calleeExpression) ?: return defaultFixText val operation = operation(calleeExpression) ?: return defaultFixText
return "Replace with '${operation.value}'" return "${KotlinBundle.message("replace.with.0", operation.value)}"
} }
override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) {
@@ -10,6 +10,7 @@ import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection import org.jetbrains.kotlin.idea.inspections.AbstractApplicabilityBasedInspection
@@ -62,7 +63,7 @@ class ReplaceGetOrSetInspection : AbstractApplicabilityBasedInspection<KtDotQual
return target.name != OperatorNameConventions.SET || !element.isUsedAsExpression(bindingContext) return target.name != OperatorNameConventions.SET || !element.isUsedAsExpression(bindingContext)
} }
override fun inspectionText(element: KtDotQualifiedExpression) = "Should be replaced with indexing" override fun inspectionText(element: KtDotQualifiedExpression) = KotlinBundle.message("should.be.replaced.with.indexing")
override fun inspectionHighlightType(element: KtDotQualifiedExpression): ProblemHighlightType = override fun inspectionHighlightType(element: KtDotQualifiedExpression): ProblemHighlightType =
if ((element.toResolvedCall(BodyResolveMode.PARTIAL)?.resultingDescriptor as? FunctionDescriptor)?.isExplicitOperator() == true) { if ((element.toResolvedCall(BodyResolveMode.PARTIAL)?.resultingDescriptor as? FunctionDescriptor)?.isExplicitOperator() == true) {
@@ -72,12 +73,12 @@ class ReplaceGetOrSetInspection : AbstractApplicabilityBasedInspection<KtDotQual
} }
override val defaultFixText: String override val defaultFixText: String
get() = "Replace get or set call with indexing operator" get() = KotlinBundle.message("replace.get.or.set.call.with.indexing.operator")
override fun fixText(element: KtDotQualifiedExpression): String { override fun fixText(element: KtDotQualifiedExpression): String {
val callExpression = element.callExpression ?: return defaultFixText val callExpression = element.callExpression ?: return defaultFixText
val resolvedCall = callExpression.resolveToCall() ?: return defaultFixText val resolvedCall = callExpression.resolveToCall() ?: return defaultFixText
return "Replace '${resolvedCall.resultingDescriptor.name.asString()}' call with indexing operator" return KotlinBundle.message("replace.0.call.with.indexing.operator", resolvedCall.resultingDescriptor.name.asString())
} }
override fun inspectionHighlightRangeInElement(element: KtDotQualifiedExpression) = element.calleeTextRangeInThis() override fun inspectionHighlightRangeInElement(element: KtDotQualifiedExpression) = element.calleeTextRangeInThis()
@@ -11,6 +11,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference
@@ -55,7 +56,7 @@ abstract class AbstractIsResultInspection(
} else { } else {
holder.registerProblem( holder.registerProblem(
toReport, toReport,
"Function returning $typeShortName with a name that does not end with $allowedSuffix", KotlinBundle.message("function.returning.0.with.a.name.that.does.not.end.with.1", typeShortName, allowedSuffix),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
*listOf( *listOf(
RenameToFix("$name$allowedSuffix"), RenameToFix("$name$allowedSuffix"),
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.inspections.coroutines
import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.core.setType import org.jetbrains.kotlin.idea.core.setType
@@ -27,8 +28,8 @@ class AddCallOrUnwrapTypeFix(
val simplify: (KtExpression) -> Unit val simplify: (KtExpression) -> Unit
) : LocalQuickFix { ) : LocalQuickFix {
override fun getName(): String = override fun getName(): String =
if (withBody) "Add '.$functionName()' to function result (breaks use-sites!)" if (withBody) KotlinBundle.message("add.call.or.unwrap.type.fix.text", functionName)
else "Unwrap '$typeName' return type (breaks use-sites!)" else KotlinBundle.message("add.call.or.unwrap.type.fix.text1", typeName)
override fun getFamilyName(): String = name override fun getFamilyName(): String = name
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.inspections.coroutines
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.inspections.AbstractResultUnusedChecker import org.jetbrains.kotlin.idea.inspections.AbstractResultUnusedChecker
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -34,12 +35,12 @@ class DeferredResultUnusedInspection(@JvmField var standardOnly: Boolean = false
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
callExpressionVisitor(fun(expression) { callExpressionVisitor(fun(expression) {
if (!check(expression)) return if (!check(expression)) return
holder.registerProblem(expression.calleeExpression ?: expression, "Deferred result is never used") holder.registerProblem(expression.calleeExpression ?: expression, KotlinBundle.message("deferred.result.is.never.used"))
}) })
override fun createOptionsPanel(): JComponent? { override fun createOptionsPanel(): JComponent? {
val panel = MultipleCheckboxOptionsPanel(this) val panel = MultipleCheckboxOptionsPanel(this)
panel.addCheckbox("Reports only function calls from kotlinx.coroutines", "standardOnly") panel.addCheckbox(KotlinBundle.message("reports.only.function.calls.from.kotlinx.coroutines"), "standardOnly")
return panel return panel
} }
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -79,8 +80,13 @@ class DirectUseOfResultTypeInspection : AbstractIsResultInspection(
val typeName = returnTypeArgument?.constructor?.declarationDescriptor?.name?.asString() ?: "T" val typeName = returnTypeArgument?.constructor?.declarationDescriptor?.name?.asString() ?: "T"
holder.registerProblem( holder.registerProblem(
toReport, toReport,
"Function '$name' returning '$SHORT_NAME<$typeName>' without the corresponding " + KotlinBundle.message(
"function '$nameWithoutCatching' returning '$typeName'", "function.0.returning.1.without.the.corresponding",
name,
"$SHORT_NAME<$typeName>",
nameWithoutCatching,
typeName
),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING ProblemHighlightType.GENERIC_ERROR_OR_WARNING
) )
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.inspections.coroutines
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.inspections.collections.AbstractCallChainChecker import org.jetbrains.kotlin.idea.inspections.collections.AbstractCallChainChecker
@@ -95,7 +96,7 @@ class RedundantAsyncInspection : AbstractCallChainChecker() {
val descriptor = holder.manager.createProblemDescriptor( val descriptor = holder.manager.createProblemDescriptor(
expression, expression,
expression.firstCalleeExpression()!!.textRange.shiftRight(-expression.startOffset), expression.firstCalleeExpression()!!.textRange.shiftRight(-expression.startOffset),
"Redundant 'async' call may be reduced to '${conversion.replacement}'", "${KotlinBundle.message("redundant.async.call.may.be.reduced.to.0", conversion.replacement)}",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly, isOnTheFly,
generateFix(conversion) generateFix(conversion)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.inspections.coroutines
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.inspections.collections.AbstractCallChainChecker import org.jetbrains.kotlin.idea.inspections.collections.AbstractCallChainChecker
import org.jetbrains.kotlin.idea.inspections.collections.SimplifyCallChainFix import org.jetbrains.kotlin.idea.inspections.collections.SimplifyCallChainFix
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -21,7 +22,7 @@ class RedundantRunCatchingInspection : AbstractCallChainChecker() {
val descriptor = holder.manager.createProblemDescriptor( val descriptor = holder.manager.createProblemDescriptor(
expression, expression,
expression.firstCalleeExpression()!!.textRange.shiftRight(-expression.startOffset), expression.firstCalleeExpression()!!.textRange.shiftRight(-expression.startOffset),
"Redundant 'runCatching' call may be reduced to '$replacement'", KotlinBundle.message("redundant.runcatching.call.may.be.reduced.to.0", replacement),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly, isOnTheFly,
SimplifyCallChainFix(conversion) SimplifyCallChainFix(conversion)
@@ -9,11 +9,12 @@ import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.refactoring.rename.RenameProcessor import com.intellij.refactoring.rename.RenameProcessor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
class RenameToFix(val newName: String) : LocalQuickFix { class RenameToFix(val newName: String) : LocalQuickFix {
override fun getName(): String = "Rename to '$newName'" override fun getName(): String = KotlinBundle.message("rename.to.fix.text", newName)
override fun getFamilyName(): String = name override fun getFamilyName(): String = name
@@ -16,6 +16,7 @@ import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.ShortenReferences
@@ -119,13 +120,13 @@ class SuspendFunctionOnCoroutineScopeInspection : AbstractKotlinInspection() {
private val removeReceiver: Boolean, private val removeReceiver: Boolean,
private val wrapCallOnly: Boolean private val wrapCallOnly: Boolean
) : LocalQuickFix { ) : LocalQuickFix {
override fun getFamilyName(): String = "Wrap with coroutineScope" override fun getFamilyName(): String = KotlinBundle.message("wrap.with.coroutine.scope.fix.family.name")
override fun getName(): String = override fun getName(): String =
when { when {
removeReceiver && !wrapCallOnly -> "Remove receiver & wrap with 'coroutineScope { ... }'" removeReceiver && !wrapCallOnly -> KotlinBundle.message("wrap.with.coroutine.scope.fix.text3")
wrapCallOnly -> "Wrap call with 'coroutineScope { ... }'" wrapCallOnly -> KotlinBundle.message("wrap.with.coroutine.scope.fix.text2")
else -> "Wrap function body with 'coroutineScope { ... }'" else -> KotlinBundle.message("wrap.with.coroutine.scope.fix.text")
} }
override fun startInWriteAction() = false override fun startInWriteAction() = false
@@ -205,7 +206,7 @@ class SuspendFunctionOnCoroutineScopeInspection : AbstractKotlinInspection() {
private const val COROUTINE_CONTEXT = "coroutineContext" private const val COROUTINE_CONTEXT = "coroutineContext"
private const val MESSAGE = "Ambiguous coroutineContext due to CoroutineScope receiver of suspend function" private val MESSAGE get() = KotlinBundle.message("ambiguous.coroutinecontext.due.to.coroutinescope.receiver.of.suspend.function")
private fun KotlinType.isCoroutineScope(): Boolean = private fun KotlinType.isCoroutineScope(): Boolean =
constructor.declarationDescriptor?.fqNameSafe?.asString() == COROUTINE_SCOPE constructor.declarationDescriptor?.fqNameSafe?.asString() == COROUTINE_SCOPE
@@ -9,6 +9,7 @@ import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
@@ -45,15 +46,15 @@ class ReplaceJavaStaticMethodWithKotlinAnalogInspection : AbstractKotlinInspecti
holder.registerProblem( holder.registerProblem(
call, call,
callee.textRangeIn(call), callee.textRangeIn(call),
"Should be replaced with Kotlin function", KotlinBundle.message("should.be.replaced.with.kotlin.function"),
*replacements *replacements
) )
}) })
private class ReplaceWithKotlinAnalogFunction(private val replacement: Replacement) : LocalQuickFix { private class ReplaceWithKotlinAnalogFunction(private val replacement: Replacement) : LocalQuickFix {
override fun getName() = "Replace with `${replacement.kotlinFunctionShortName}` function" override fun getName() = "${KotlinBundle.message("replace.with.kotlin.analog.function.text")}${replacement.kotlinFunctionShortName}"
override fun getFamilyName() = "Replace with Kotlin analog" override fun getFamilyName() = KotlinBundle.message("replace.with.kotlin.analog.function.family.name")
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val callExpression = descriptor.psiElement as? KtCallExpression ?: return val callExpression = descriptor.psiElement as? KtCallExpression ?: return
@@ -14,6 +14,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiElementVisitor
import com.siyeh.ig.psiutils.TestUtils import com.siyeh.ig.psiutils.TestUtils
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.core.unblockDocument import org.jetbrains.kotlin.idea.core.unblockDocument
@@ -42,7 +43,8 @@ class KDocMissingDocumentationInspection : AbstractKotlinInspection() {
val descriptor = val descriptor =
element.resolveToDescriptorIfAny() as? DeclarationDescriptorWithVisibility ?: return@namedDeclarationVisitor element.resolveToDescriptorIfAny() as? DeclarationDescriptorWithVisibility ?: return@namedDeclarationVisitor
if (descriptor.isEffectivelyPublicApi) { if (descriptor.isEffectivelyPublicApi) {
val message = element.describe()?.let { "$it is missing documentation" } ?: "Missing documentation" val message = element.describe()?.let { KotlinBundle.message("0.is.missing.documentation", it) }
?: KotlinBundle.message("missing.documentation")
holder.registerProblem(nameIdentifier, message, AddDocumentationFix()) holder.registerProblem(nameIdentifier, message, AddDocumentationFix())
} }
} }
@@ -53,7 +55,7 @@ class KDocMissingDocumentationInspection : AbstractKotlinInspection() {
override fun runForWholeFile(): Boolean = true override fun runForWholeFile(): Boolean = true
class AddDocumentationFix : LocalQuickFix { class AddDocumentationFix : LocalQuickFix {
override fun getName(): String = "Add documentation" override fun getName(): String = KotlinBundle.message("add.documentation.fix.text")
override fun getFamilyName(): String = name override fun getFamilyName(): String = name
@@ -11,6 +11,7 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.configuration.MigrationInfo import org.jetbrains.kotlin.idea.configuration.MigrationInfo
@@ -95,7 +96,7 @@ class FromClosedRangeMigrationInspection : AbstractKotlinInspection(), Migration
val problemDescriptor = holder.manager.createProblemDescriptor( val problemDescriptor = holder.manager.createProblemDescriptor(
simpleNameExpression, simpleNameExpression,
simpleNameExpression, simpleNameExpression,
"It's prohibited to call $desc with MIN_VALUE step since 1.3", KotlinBundle.message("it.s.prohibited.to.call.0.with.min.value.step.since.1.3", desc),
if (isError) ProblemHighlightType.ERROR else ProblemHighlightType.GENERIC_ERROR_OR_WARNING, if (isError) ProblemHighlightType.ERROR else ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly isOnTheFly
) )
@@ -17,6 +17,7 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests import org.jetbrains.kotlin.idea.codeInsight.shorten.performDelayedRefactoringRequests
import org.jetbrains.kotlin.idea.configuration.MigrationInfo import org.jetbrains.kotlin.idea.configuration.MigrationInfo
@@ -92,7 +93,7 @@ private interface CoroutineMigrationProblem {
// Shortcut quick fix for running inspection in the project scope. // Shortcut quick fix for running inspection in the project scope.
// Should work like RunInspectionAction.runInspection. // Should work like RunInspectionAction.runInspection.
private class ObsoleteCoroutineUsageInWholeFix : LocalQuickFix { private class ObsoleteCoroutineUsageInWholeFix : LocalQuickFix {
override fun getFamilyName(): String = "Fix experimental coroutines usages in the project" override fun getFamilyName(): String = KotlinBundle.message("obsolete.coroutine.usage.in.whole.fix.family.name")
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val toolWrapper = InspectionProjectProfileManager.getInstance(project).currentProfile.getInspectionTool( val toolWrapper = InspectionProjectProfileManager.getInstance(project).currentProfile.getInspectionTool(
@@ -115,7 +116,13 @@ private class ObsoleteCoroutineUsageInWholeFix : LocalQuickFix {
val cleanupToolProfile = runInInspectionProfileInitMode { RunInspectionIntention.createProfile(toolWrapper, managerEx, null) } val cleanupToolProfile = runInInspectionProfileInitMode { RunInspectionIntention.createProfile(toolWrapper, managerEx, null) }
managerEx.createNewGlobalContext(false) managerEx.createNewGlobalContext(false)
.codeCleanup(cleanupScope, cleanupToolProfile, "Apply in the project: " + toolWrapper.displayName, null, false) .codeCleanup(
cleanupScope,
cleanupToolProfile,
KotlinBundle.message("apply.in.the.project.0", toolWrapper.displayName),
null,
false
)
} }
// Overcome failure during profile creating because of absent tools in tests // Overcome failure during profile creating because of absent tools in tests
@@ -139,7 +146,7 @@ private class ObsoleteCoroutineUsageInWholeFix : LocalQuickFix {
* There should be a single fix class with the same family name, this way it can be executed for all found coroutines problems from UI. * There should be a single fix class with the same family name, this way it can be executed for all found coroutines problems from UI.
*/ */
private class ObsoleteCoroutineUsageFix(val delegate: CoroutineFix) : LocalQuickFix { private class ObsoleteCoroutineUsageFix(val delegate: CoroutineFix) : LocalQuickFix {
override fun getFamilyName(): String = "Fix experimental coroutines usage" override fun getFamilyName(): String = KotlinBundle.message("obsolete.coroutine.usage.fix.family.name")
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
delegate.applyFix(project, descriptor) delegate.applyFix(project, descriptor)
@@ -190,7 +197,7 @@ private class ObsoleteTopLevelFunctionUsage(
holder.registerProblem( holder.registerProblem(
simpleNameExpression, simpleNameExpression,
"`$newFqName` is expected to be used since Kotlin 1.3", KotlinBundle.message("0.is.expected.to.be.used.since.kotlin.1.3", newFqName),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
*fixesWithWholeProject(isOnTheFly, ObsoleteCoroutineUsageFix(fix)) *fixesWithWholeProject(isOnTheFly, ObsoleteCoroutineUsageFix(fix))
) )
@@ -226,7 +233,7 @@ private class ObsoleteExtensionFunctionUsage(
holder.registerProblem( holder.registerProblem(
simpleNameExpression, simpleNameExpression,
"Methods are absent in coroutines class since 1.3", KotlinBundle.message("methods.are.absent.in.coroutines.class.since.1.3"),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
*fixesWithWholeProject(isOnTheFly, ObsoleteCoroutineUsageFix(fix)) *fixesWithWholeProject(isOnTheFly, ObsoleteCoroutineUsageFix(fix))
) )
@@ -266,7 +273,7 @@ private class ExperimentalImportUsage : CoroutineMigrationProblem {
holder.registerProblem( holder.registerProblem(
reportExpression, reportExpression,
"Experimental coroutines usages are obsolete since 1.3", KotlinBundle.message("experimental.coroutines.usages.are.obsolete.since.1.3"),
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
*fixesWithWholeProject(isOnTheFly, ObsoleteCoroutineUsageFix(ObsoleteCoroutineImportFix)) *fixesWithWholeProject(isOnTheFly, ObsoleteCoroutineUsageFix(ObsoleteCoroutineImportFix))
) )
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.inspections.migration
import com.intellij.util.text.VersionComparatorUtil import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.versions.LibInfo import org.jetbrains.kotlin.idea.versions.LibInfo
interface VersionUpdater { interface VersionUpdater {
@@ -38,7 +39,7 @@ private fun kotlinxCoroutinesDeprecation(name: String): DeprecatedForKotlinLibIn
lib = LibInfo("org.jetbrains.kotlinx", name), lib = LibInfo("org.jetbrains.kotlinx", name),
sinceKotlinLanguageVersion = LanguageVersion.KOTLIN_1_3, sinceKotlinLanguageVersion = LanguageVersion.KOTLIN_1_3,
versionUpdater = KotlinxVersionUpdater, versionUpdater = KotlinxVersionUpdater,
message = "Library should be updated to be compatible with Kotlin 1.3" message = KotlinBundle.message("library.should.be.updated.to.be.compatible.with.kotlin.1.3")
) )
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.inspections.substring
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo import org.jetbrains.kotlin.idea.intentions.branchedTransformations.evaluatesTo
import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
@@ -16,8 +17,10 @@ import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtNameReferenceExpression
class ReplaceSubstringWithDropLastInspection : ReplaceSubstringInspection() { class ReplaceSubstringWithDropLastInspection : ReplaceSubstringInspection() {
override fun inspectionText(element: KtDotQualifiedExpression): String = "Replace 'substring' call with 'dropLast' call" override fun inspectionText(element: KtDotQualifiedExpression): String =
override val defaultFixText: String = "Replace 'substring' call with 'dropLast' call" KotlinBundle.message("replace.substring.call.with.droplast.call")
override val defaultFixText: String = KotlinBundle.message("replace.substring.call.with.droplast.call")
override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) {
val argument = element.callExpression?.valueArguments?.elementAtOrNull(1)?.getArgumentExpression() ?: return val argument = element.callExpression?.valueArguments?.elementAtOrNull(1)?.getArgumentExpression() ?: return
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.inspections.substring
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.psi.KtConstantExpression import org.jetbrains.kotlin.psi.KtConstantExpression
@@ -15,8 +16,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator 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 fun inspectionText(element: KtDotQualifiedExpression): String =
override val defaultFixText: String = "Replace 'substring' call with indexing operation call" KotlinBundle.message("replace.substring.call.with.indexing.operation.call")
override val defaultFixText: String = KotlinBundle.message("replace.substring.call.with.indexing.operation.call")
override val isAlwaysStable: Boolean = true override val isAlwaysStable: Boolean = true
override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) {
@@ -7,14 +7,16 @@ package org.jetbrains.kotlin.idea.inspections.substring
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
class ReplaceSubstringWithSubstringAfterInspection : ReplaceSubstringInspection() { class ReplaceSubstringWithSubstringAfterInspection : ReplaceSubstringInspection() {
override fun inspectionText(element: KtDotQualifiedExpression): String = "Replace 'substring' call with 'substringAfter' call" override fun inspectionText(element: KtDotQualifiedExpression): String =
KotlinBundle.message("replace.substring.call.with.substringafter.call")
override val defaultFixText: String = "Replace 'substring' call with 'substringAfter' call" override val defaultFixText: String = KotlinBundle.message("replace.substring.call.with.substringafter.call")
override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) {
element.replaceWith( element.replaceWith(
@@ -30,9 +32,10 @@ class ReplaceSubstringWithSubstringAfterInspection : ReplaceSubstringInspection(
} }
class ReplaceSubstringWithSubstringBeforeInspection : ReplaceSubstringInspection() { class ReplaceSubstringWithSubstringBeforeInspection : ReplaceSubstringInspection() {
override fun inspectionText(element: KtDotQualifiedExpression): String = "Replace 'substring' call with 'substringBefore' call" override fun inspectionText(element: KtDotQualifiedExpression): String =
KotlinBundle.message("replace.substring.call.with.substringbefore.call")
override val defaultFixText: String = "Replace 'substring' call with 'substringBefore' call" override val defaultFixText: String = KotlinBundle.message("replace.substring.call.with.substringbefore.call")
override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) {
element.replaceWith( element.replaceWith(
@@ -7,13 +7,14 @@ package org.jetbrains.kotlin.idea.inspections.substring
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
class ReplaceSubstringWithTakeInspection : ReplaceSubstringInspection() { class ReplaceSubstringWithTakeInspection : ReplaceSubstringInspection() {
override fun inspectionText(element: KtDotQualifiedExpression): String = "Replace 'substring' call with 'take' call" override fun inspectionText(element: KtDotQualifiedExpression): String = KotlinBundle.message("replace.substring.call.with.take.call")
override val defaultFixText: String = "Replace 'substring' call with 'take' call" override val defaultFixText: String = KotlinBundle.message("replace.substring.call.with.take.call")
override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) { override fun applyTo(element: KtDotQualifiedExpression, project: Project, editor: Editor?) {
val argument = element.callExpression?.valueArguments?.elementAtOrNull(1)?.getArgumentExpression() ?: return val argument = element.callExpression?.valueArguments?.elementAtOrNull(1)?.getArgumentExpression() ?: return