i18n: make text from intention lazy

#KT-37483
This commit is contained in:
Dmitry Gridin
2020-04-04 00:44:13 +07:00
parent f451cb93da
commit 423a9dd70d
97 changed files with 673 additions and 1155 deletions
@@ -29,7 +29,6 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
@Nls private var textGetter: () -> String,
@Nls private val familyNameGetter: () -> String = textGetter,
) : IntentionAction {
@Deprecated("Replace with primary constructor", ReplaceWith("SelfTargetingIntention<TElement>(elementType, { text }, { familyName })"))
constructor(
elementType: Class<TElement>,
@@ -38,7 +37,7 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
) : this(elementType, { text }, { familyName })
protected val defaultText: String get() = defaultTextGetter()
private val defaultTextGetter: () -> String = textGetter
protected val defaultTextGetter: () -> String = textGetter
@Deprecated("Replace with `setTextGetter`", ReplaceWith("setTextGetter { text }"))
protected fun setText(@Nls text: String) {
@@ -62,15 +61,9 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
val commonParent = if (leaf1 != null && leaf2 != null) PsiTreeUtil.findCommonParent(leaf1, leaf2) else null
var elementsToCheck: Sequence<PsiElement> = emptySequence()
if (leaf1 != null) {
elementsToCheck += leaf1.parentsWithSelf.takeWhile { it != commonParent }
}
if (leaf2 != null) {
elementsToCheck += leaf2.parentsWithSelf.takeWhile { it != commonParent }
}
if (commonParent != null && commonParent !is PsiFile) {
elementsToCheck += commonParent.parentsWithSelf
}
if (leaf1 != null) elementsToCheck += leaf1.parentsWithSelf.takeWhile { it != commonParent }
if (leaf2 != null) elementsToCheck += leaf2.parentsWithSelf.takeWhile { it != commonParent }
if (commonParent != null && commonParent !is PsiFile) elementsToCheck += commonParent.parentsWithSelf
for (element in elementsToCheck) {
@Suppress("UNCHECKED_CAST")
@@ -130,7 +123,10 @@ abstract class SelfTargetingRangeIntention<TElement : PsiElement>(
@Nls familyNameGetter: () -> String = textGetter,
) : SelfTargetingIntention<TElement>(elementType, textGetter, familyNameGetter) {
@Deprecated("Replace with primary constructor", ReplaceWith("SelfTargetingRangeIntention<TElement>(elementType, { text }, { familyName })"))
@Deprecated(
"Replace with primary constructor",
ReplaceWith("SelfTargetingRangeIntention<TElement>(elementType, { text }, { familyName })")
)
constructor(
elementType: Class<TElement>,
@Nls text: String,
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2018 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.
*/
@@ -36,8 +36,8 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class MoveSuspiciousCallableReferenceIntoParenthesesInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return lambdaExpressionVisitor(fun(lambdaExpression) {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor =
lambdaExpressionVisitor(fun(lambdaExpression) {
val callableReference = lambdaExpression.bodyExpression?.statements?.singleOrNull() as? KtCallableReferenceExpression
if (callableReference != null) {
val context = lambdaExpression.analyze()
@@ -54,10 +54,12 @@ class MoveSuspiciousCallableReferenceIntoParenthesesInspection : AbstractKotlinI
}
}
}
val quickFix = if (canMove(lambdaExpression, callableReference, context))
IntentionWrapper(MoveIntoParenthesesIntention(), lambdaExpression.containingFile)
else
null
holder.registerProblem(
lambdaExpression,
KotlinBundle.message("suspicious.callable.reference.as.the.only.lambda.element"),
@@ -66,7 +68,6 @@ class MoveSuspiciousCallableReferenceIntoParenthesesInspection : AbstractKotlinI
)
}
})
}
private fun canMove(
lambdaExpression: KtLambdaExpression,
@@ -90,7 +91,7 @@ class MoveSuspiciousCallableReferenceIntoParenthesesInspection : AbstractKotlinI
}
class MoveIntoParenthesesIntention : ConvertLambdaToReferenceIntention(
KotlinBundle.message("move.suspicious.callable.reference.into.parentheses")
KotlinBundle.lazyMessage("move.suspicious.callable.reference.into.parentheses")
) {
override fun buildReferenceText(element: KtLambdaExpression): String? {
val callableReferenceExpression =
@@ -112,6 +113,7 @@ class MoveSuspiciousCallableReferenceIntoParenthesesInspection : AbstractKotlinI
receiverExpression.text
}
}
return "$receiver::${callableReference.text}"
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -30,7 +19,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class AddNamesToCallArgumentsIntention : SelfTargetingRangeIntention<KtCallElement>(
KtCallElement::class.java,
KotlinBundle.message("add.names.to.call.arguments")
KotlinBundle.lazyMessage("add.names.to.call.arguments")
) {
override fun applicabilityRange(element: KtCallElement): TextRange? {
val arguments = element.valueArguments
@@ -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.
*/
@@ -25,16 +25,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
interface AddValVarToConstructorParameterAction {
companion object {
val actionFamily: String get() = KotlinBundle.message("add.val.var.to.primary.constructor.parameter")
}
fun getActionText(element: KtParameter) = KotlinBundle.message("add.val.var.to.parameter.0", element.name ?: "")
fun canInvoke(element: KtParameter): Boolean {
return element.valOrVarKeyword == null && ((element.parent as? KtParameterList)?.parent as? KtPrimaryConstructor)
?.takeIf { it.mustHaveValOrVar() || !it.isExpectDeclaration() } != null
}
fun canInvoke(element: KtParameter): Boolean =
element.valOrVarKeyword == null && ((element.parent as? KtParameterList)?.parent as? KtPrimaryConstructor)?.takeIf { it.mustHaveValOrVar() || !it.isExpectDeclaration() } != null
operator fun invoke(element: KtParameter, editor: Editor?) {
val project = element.project
@@ -57,13 +49,14 @@ interface AddValVarToConstructorParameterAction {
.let { TemplateManager.getInstance(project).startTemplate(editor, it) }
}
class Intention :
SelfTargetingRangeIntention<KtParameter>(KtParameter::class.java, actionFamily),
AddValVarToConstructorParameterAction {
class Intention : SelfTargetingRangeIntention<KtParameter>(
KtParameter::class.java,
KotlinBundle.lazyMessage("add.val.var.to.primary.constructor.parameter")
), AddValVarToConstructorParameterAction {
override fun applicabilityRange(element: KtParameter): TextRange? {
if (!canInvoke(element)) return null
if (element.getStrictParentOfType<KtClass>()?.isData() == true) return null
text = getActionText(element)
setTextGetter(KotlinBundle.lazyMessage("add.val.var.to.parameter.0", element.name ?: ""))
return element.nameIdentifier?.textRange
}
@@ -73,9 +66,9 @@ interface AddValVarToConstructorParameterAction {
class QuickFix(parameter: KtParameter) :
KotlinQuickFixAction<KtParameter>(parameter),
AddValVarToConstructorParameterAction {
override fun getText() = element?.let { getActionText(it) } ?: ""
override fun getText() = element?.let { KotlinBundle.message("add.val.var.to.parameter.0", it.name ?: "") } ?: ""
override fun getFamilyName() = actionFamily
override fun getFamilyName() = KotlinBundle.message("add.val.var.to.primary.constructor.parameter")
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
invoke(element ?: return, editor)
@@ -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.
*/
@@ -23,8 +23,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
class AnonymousFunctionToLambdaIntention : SelfTargetingRangeIntention<KtNamedFunction>(
KtNamedFunction::class.java,
KotlinBundle.message("convert.to.lambda.expression"),
KotlinBundle.message("convert.anonymous.function.to.lambda.expression")
KotlinBundle.lazyMessage("convert.to.lambda.expression"),
KotlinBundle.lazyMessage("convert.anonymous.function.to.lambda.expression")
) {
override fun applicabilityRange(element: KtNamedFunction): TextRange? {
if (element.name != null) return null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -33,9 +22,8 @@ import org.jetbrains.kotlin.psi.psiUtil.toVisibility
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
open class ChangeVisibilityModifierIntention protected constructor(
val modifier: KtModifierKeywordToken
) : SelfTargetingRangeIntention<KtDeclaration>(KtDeclaration::class.java, KotlinBundle.message("make.0", modifier.value)) {
open class ChangeVisibilityModifierIntention protected constructor(val modifier: KtModifierKeywordToken) :
SelfTargetingRangeIntention<KtDeclaration>(KtDeclaration::class.java, KotlinBundle.lazyMessage("make.0", modifier.value)) {
override fun startInWriteAction(): Boolean = false
override fun applicabilityRange(element: KtDeclaration): TextRange? {
@@ -57,13 +45,13 @@ open class ChangeVisibilityModifierIntention protected constructor(
) return null
}
text = defaultText
setTextGetter(defaultTextGetter)
if (element is KtPropertyAccessor) {
if (element.isGetter) return null
if (targetVisibility == Visibilities.PUBLIC) {
val explicitVisibility = element.modifierList?.visibilityModifierType()?.value ?: return null
text = KotlinBundle.message("remove.0.modifier", explicitVisibility)
setTextGetter(KotlinBundle.lazyMessage("remove.0.modifier", explicitVisibility))
} else {
val propVisibility = (element.property.toDescriptor() as? DeclarationDescriptorWithVisibility)?.visibility ?: return null
if (propVisibility == targetVisibility) return null
@@ -74,7 +62,7 @@ open class ChangeVisibilityModifierIntention protected constructor(
val defaultRange = noModifierYetApplicabilityRange(element) ?: return null
if (element is KtPrimaryConstructor && defaultRange.isEmpty && element.visibilityModifier() == null) {
text = KotlinBundle.message("make.primary.constructor.0", modifier.value) // otherwise it may be confusing
setTextGetter(KotlinBundle.lazyMessage("make.primary.constructor.0", modifier.value)) // otherwise it may be confusing
}
return if (modifierList != null)
@@ -93,41 +81,36 @@ open class ChangeVisibilityModifierIntention protected constructor(
}
}
private fun noModifierYetApplicabilityRange(declaration: KtDeclaration): TextRange? {
return when (declaration) {
is KtNamedFunction -> declaration.funKeyword?.textRange
is KtProperty -> declaration.valOrVarKeyword.textRange
is KtPropertyAccessor -> declaration.namePlaceholder.textRange
is KtClass -> declaration.getClassOrInterfaceKeyword()?.textRange
is KtObjectDeclaration -> declaration.getObjectKeyword()?.textRange
is KtPrimaryConstructor -> declaration.valueParameterList?.let {
//TODO: use constructor keyword if exist
TextRange.from(it.startOffset, 0)
}
is KtSecondaryConstructor -> declaration.getConstructorKeyword().textRange
is KtParameter -> declaration.valOrVarKeyword?.textRange
is KtTypeAlias -> declaration.getTypeAliasKeyword()?.textRange
else -> null
private fun noModifierYetApplicabilityRange(declaration: KtDeclaration): TextRange? = when (declaration) {
is KtNamedFunction -> declaration.funKeyword?.textRange
is KtProperty -> declaration.valOrVarKeyword.textRange
is KtPropertyAccessor -> declaration.namePlaceholder.textRange
is KtClass -> declaration.getClassOrInterfaceKeyword()?.textRange
is KtObjectDeclaration -> declaration.getObjectKeyword()?.textRange
is KtPrimaryConstructor -> declaration.valueParameterList?.let {
//TODO: use constructor keyword if exist
TextRange.from(it.startOffset, 0)
}
is KtSecondaryConstructor -> declaration.getConstructorKeyword().textRange
is KtParameter -> declaration.valOrVarKeyword?.textRange
is KtTypeAlias -> declaration.getTypeAliasKeyword()?.textRange
else -> null
}
class Public : ChangeVisibilityModifierIntention(KtTokens.PUBLIC_KEYWORD), HighPriorityAction
class Private : ChangeVisibilityModifierIntention(KtTokens.PRIVATE_KEYWORD), HighPriorityAction {
override fun applicabilityRange(element: KtDeclaration): TextRange? {
return if (element.canBePrivate()) super.applicabilityRange(element) else null
}
override fun applicabilityRange(element: KtDeclaration): TextRange? =
if (element.canBePrivate()) super.applicabilityRange(element) else null
}
class Protected : ChangeVisibilityModifierIntention(KtTokens.PROTECTED_KEYWORD) {
override fun applicabilityRange(element: KtDeclaration): TextRange? {
return if (element.canBeProtected()) super.applicabilityRange(element) else null
}
override fun applicabilityRange(element: KtDeclaration): TextRange? =
if (element.canBeProtected()) super.applicabilityRange(element) else null
}
class Internal : ChangeVisibilityModifierIntention(KtTokens.INTERNAL_KEYWORD) {
override fun applicabilityRange(element: KtDeclaration): TextRange? {
return if (element.canBeInternal()) super.applicabilityRange(element) else null
}
override fun applicabilityRange(element: KtDeclaration): TextRange? =
if (element.canBeInternal()) super.applicabilityRange(element) else null
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -20,7 +9,6 @@ import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -30,11 +18,10 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.psi.psiUtil.startOffset
abstract class AbstractChopListIntention<TList : KtElement, TElement : KtElement>(
private val listClass: Class<TList>,
listClass: Class<TList>,
private val elementClass: Class<TElement>,
text: String
) : SelfTargetingOffsetIndependentIntention<TList>(listClass, text) {
textGetter: () -> String
) : SelfTargetingOffsetIndependentIntention<TList>(listClass, textGetter) {
override fun isApplicableTo(element: TList): Boolean {
val elements = element.elements()
if (elements.size <= 1) return false
@@ -63,43 +50,30 @@ abstract class AbstractChopListIntention<TList : KtElement, TElement : KtElement
pointer.element?.let { CodeStyleManager.getInstance(project).reformat(it) }
}
protected fun hasLineBreakAfter(element: TElement): Boolean {
return nextBreak(element) != null
}
protected fun hasLineBreakAfter(element: TElement): Boolean = nextBreak(element) != null
protected fun nextBreak(element: TElement): PsiWhiteSpace? {
return element
.siblings(withItself = false)
.takeWhile { !elementClass.isInstance(it) }
.firstOrNull { it is PsiWhiteSpace && it.textContains('\n') } as? PsiWhiteSpace
}
protected fun nextBreak(element: TElement): PsiWhiteSpace? = element.siblings(withItself = false)
.takeWhile { !elementClass.isInstance(it) }
.firstOrNull { it is PsiWhiteSpace && it.textContains('\n') } as? PsiWhiteSpace
protected fun hasLineBreakBefore(element: TElement): Boolean {
return prevBreak(element) != null
}
protected fun hasLineBreakBefore(element: TElement): Boolean = prevBreak(element) != null
protected fun prevBreak(element: TElement): PsiWhiteSpace? {
return element
.siblings(withItself = false, forward = false)
.takeWhile { !elementClass.isInstance(it) }
.firstOrNull { it is PsiWhiteSpace && it.textContains('\n') } as? PsiWhiteSpace
}
protected fun prevBreak(element: TElement): PsiWhiteSpace? = element.siblings(withItself = false, forward = false)
.takeWhile { !elementClass.isInstance(it) }
.firstOrNull { it is PsiWhiteSpace && it.textContains('\n') } as? PsiWhiteSpace
protected fun TList.elements(): List<TElement> {
return allChildren
.filter { elementClass.isInstance(it) }
.map {
@Suppress("UNCHECKED_CAST")
it as TElement
}
.toList()
}
protected fun TList.elements(): List<TElement> = allChildren.filter { elementClass.isInstance(it) }
.map {
@Suppress("UNCHECKED_CAST")
it as TElement
}
.toList()
}
class ChopParameterListIntention : AbstractChopListIntention<KtParameterList, KtParameter>(
KtParameterList::class.java,
KtParameter::class.java,
KotlinBundle.message("put.parameters.on.separate.lines")
KotlinBundle.lazyMessage("put.parameters.on.separate.lines")
) {
override fun isApplicableTo(element: KtParameterList): Boolean {
if (element.parent is KtFunctionLiteral) return false
@@ -110,5 +84,5 @@ class ChopParameterListIntention : AbstractChopListIntention<KtParameterList, Kt
class ChopArgumentListIntention : AbstractChopListIntention<KtValueArgumentList, KtValueArgument>(
KtValueArgumentList::class.java,
KtValueArgument::class.java,
KotlinBundle.message("put.arguments.on.separate.lines")
KotlinBundle.lazyMessage("put.arguments.on.separate.lines")
)
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
class ConvertArrayParameterToVarargIntention : SelfTargetingIntention<KtParameter>(
KtParameter::class.java, DEFAULT_TEXT
KtParameter::class.java, KotlinBundle.lazyMessage("convert.to.vararg.parameter")
) {
override fun isApplicableTo(element: KtParameter, caretOffset: Int): Boolean {
val typeReference = element.getChildOfType<KtTypeReference>() ?: return false
@@ -25,7 +25,7 @@ class ConvertArrayParameterToVarargIntention : SelfTargetingIntention<KtParamete
val type = element.descriptor?.type ?: return false
return when {
KotlinBuiltIns.isPrimitiveArray(type) -> {
setTextGetter(DEFAULT_TEXT)
setTextGetter(defaultTextGetter)
true
}
KotlinBuiltIns.isArray(type) -> {
@@ -33,12 +33,15 @@ class ConvertArrayParameterToVarargIntention : SelfTargetingIntention<KtParamete
val typeProjection = typeArgument?.parent as? KtTypeProjection
if (typeProjection?.hasModifier(KtTokens.IN_KEYWORD) == false) {
setTextGetter(
if (!typeProjection.hasModifier(KtTokens.OUT_KEYWORD)
&& !KotlinBuiltIns.isPrimitiveType(element.builtIns.getArrayElementType(type))
if (!typeProjection.hasModifier(KtTokens.OUT_KEYWORD) && !KotlinBuiltIns.isPrimitiveType(
element.builtIns.getArrayElementType(
type
)
)
) {
BREAKING_TEXT
{ KotlinBundle.message("0.may.break.code", defaultText) }
} else {
DEFAULT_TEXT
defaultTextGetter
}
)
true
@@ -57,14 +60,8 @@ class ConvertArrayParameterToVarargIntention : SelfTargetingIntention<KtParamete
val newType = KotlinBuiltIns.getPrimitiveArrayElementType(type)?.typeName?.asString()
?: typeReference.typeElement?.typeArgumentsAsTypes?.firstOrNull()?.text
?: return
typeReference.replace(KtPsiFactory(element).createType(newType))
element.addModifier(KtTokens.VARARG_KEYWORD)
}
companion object {
private val DEFAULT_TEXT: () -> String get() = KotlinBundle.lazyMessage("convert.to.vararg.parameter")
private val BREAKING_TEXT: () -> String get() = { KotlinBundle.message("0.may.break.code", DEFAULT_TEXT()) }
}
}
@@ -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.
*/
@@ -12,23 +12,25 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import java.util.*
class ConvertBinaryExpressionWithDemorgansLawIntention :
SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(KtBinaryExpression::class.java, KotlinBundle.message("demorgan.law")) {
class ConvertBinaryExpressionWithDemorgansLawIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.lazyMessage("demorgan.law")
) {
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
val expr = element.parentsWithSelf.takeWhile { it is KtBinaryExpression }.last() as KtBinaryExpression
text = when (expr.operationToken) {
KtTokens.ANDAND -> KotlinBundle.message("replace.with2")
KtTokens.OROR -> KotlinBundle.message("replace.with")
else -> return false
}
setTextGetter(
when (expr.operationToken) {
KtTokens.ANDAND -> KotlinBundle.lazyMessage("replace.with2")
KtTokens.OROR -> KotlinBundle.lazyMessage("replace.with")
else -> return false
}
)
return splitBooleanSequence(expr) != null
}
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
applyTo(element)
}
override fun applyTo(element: KtBinaryExpression, editor: Editor?) = applyTo(element)
fun applyTo(element: KtBinaryExpression) {
val expr = element.parentsWithSelf.takeWhile { it is KtBinaryExpression }.last() as KtBinaryExpression
@@ -39,7 +41,7 @@ class ConvertBinaryExpressionWithDemorgansLawIntention :
else -> throw IllegalArgumentException()
}
val operands = splitBooleanSequence(expr)!!.asReversed()
val operands = splitBooleanSequence(expr)?.asReversed() ?: return
val newExpression = KtPsiFactory(expr).buildExpression {
appendExpressions(operands.map { it.negate() }, separator = operatorText)
@@ -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.
*/
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class ConvertEnumToSealedClassIntention : SelfTargetingRangeIntention<KtClass>(
KtClass::class.java,
KotlinBundle.message("convert.to.sealed.class")
KotlinBundle.lazyMessage("convert.to.sealed.class")
) {
override fun applicabilityRange(element: KtClass): TextRange? {
if (element.getClassKeyword() == null) return null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -30,7 +19,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
class ConvertForEachToForLoopIntention : SelfTargetingOffsetIndependentIntention<KtSimpleNameExpression>(
KtSimpleNameExpression::class.java, KotlinBundle.message("replace.with.a.for.loop")
KtSimpleNameExpression::class.java, KotlinBundle.lazyMessage("replace.with.a.for.loop")
) {
companion object {
private const val FOR_EACH_NAME = "forEach"
@@ -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.
*/
@@ -46,7 +46,7 @@ import org.jetbrains.kotlin.types.KotlinType
class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntention<KtTypeReference>(
KtTypeReference::class.java,
KotlinBundle.message("convert.function.type.parameter.to.receiver")
KotlinBundle.lazyMessage("convert.function.type.parameter.to.receiver")
) {
class FunctionDefinitionInfo(element: KtFunction) : AbstractProcessableUsageInfo<KtFunction, ConversionData>(element) {
override fun process(data: ConversionData, elementsToShorten: MutableList<KtElement>) {
@@ -82,15 +82,15 @@ class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntent
val parameterNames = lambdaType.arguments
.dropLast(1)
.map { KotlinNameSuggester.suggestNamesByType(it.type, validator, "p").first() }
val receiver = parameterNames.getOrNull(data.typeParameterIndex) ?: return
val arguments = parameterNames.filter { it != receiver }
val adapterLambda = KtPsiFactory(expression).createLambdaExpression(
parameterNames.joinToString(),
"$receiver.${expression.text}(${arguments.joinToString()})"
)
expression.replaced(adapterLambda).let {
it.moveFunctionLiteralOutsideParenthesesIfPossible()
}
expression.replaced(adapterLambda).moveFunctionLiteralOutsideParenthesesIfPossible()
}
}
@@ -151,9 +151,7 @@ class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntent
appendFixedText(" }")
} as KtLambdaExpression
expression.replaced(replacingLambda).let {
it.moveFunctionLiteralOutsideParenthesesIfPossible()
}
expression.replaced(replacingLambda).moveFunctionLiteralOutsideParenthesesIfPossible()
}
private fun generateVariable(expression: KtExpression): String {
@@ -161,6 +159,7 @@ class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntent
KotlinIntroduceVariableHandler.doRefactoring(project, null, expression, false, emptyList()) {
baseCallee = it.name!!
}
return baseCallee
}
}
@@ -307,6 +306,7 @@ class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntent
is KtConstructor<*> -> callable.containingClassOrObject?.body
else -> callable.bodyExpression
}
if (body != null) {
val functionParameter = callable.valueParameters.getOrNull(data.functionParameterIndex) ?: return
for (ref in ReferencesSearch.search(functionParameter, LocalSearchScope(body))) {
@@ -354,8 +354,8 @@ class ConvertFunctionTypeParameterToReceiverIntention : SelfTargetingRangeIntent
setReceiverTypeReference(element)
parameterList!!.removeParameter(data.typeParameterIndex)
}
text = KotlinBundle.message("convert.0.to.1", elementBefore.text, elementAfter.text)
setTextGetter(KotlinBundle.lazyMessage("convert.0.to.1", elementBefore.text, elementAfter.text))
return element.textRange
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -51,7 +40,7 @@ import org.jetbrains.kotlin.types.KotlinType
class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntention<KtTypeReference>(
KtTypeReference::class.java,
KotlinBundle.message("convert.function.type.receiver.to.parameter")
KotlinBundle.lazyMessage("convert.function.type.receiver.to.parameter")
) {
class ConversionData(
val functionParameterIndex: Int,
@@ -91,11 +80,11 @@ class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntent
val context = lambda.analyze(BodyResolveMode.PARTIAL)
val psiFactory = KtPsiFactory(project)
val validator = CollectingNameValidator(
lambda.valueParameters.mapNotNull { it.name },
NewDeclarationNameValidator(lambda.bodyExpression!!, null, NewDeclarationNameValidator.Target.VARIABLES)
)
val newParameterName = KotlinNameSuggester.suggestNamesByType(data.lambdaReceiverType, validator, "p").first()
val newParameterRefExpression = psiFactory.createExpression(newParameterName)
@@ -168,6 +157,7 @@ class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntent
?.getArgumentExpression()
?.let { KtPsiUtil.safeDeparenthesize(it) }
?: return
if (expressionToProcess is KtLambdaExpression) {
usages += LambdaInfo(expressionToProcess)
}
@@ -181,6 +171,7 @@ class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntent
is KtConstructor<*> -> callable.containingClassOrObject?.body
else -> callable.bodyExpression
}
if (body != null) {
val functionParameter = callable.valueParameters.getOrNull(data.functionParameterIndex) ?: return
for (ref in ReferencesSearch.search(functionParameter, LocalSearchScope(body))) {
@@ -199,6 +190,7 @@ class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntent
.getAbbreviatedTypeOrType(functionType.analyze(BodyResolveMode.PARTIAL))
?.getReceiverTypeFromFunctionType()
?: return null
val containingParameter = (functionType.parent as? KtTypeReference)?.parent as? KtParameter ?: return null
val ownerFunction = containingParameter.ownerFunction as? KtFunction ?: return null
val functionParameterIndex = ownerFunction.valueParameters.indexOf(containingParameter)
@@ -218,8 +210,8 @@ class ConvertFunctionTypeReceiverToParameterIntention : SelfTargetingRangeIntent
)
setReceiverTypeReference(null)
}
text = KotlinBundle.message("convert.0.to.1", elementBefore.text, elementAfter.text)
setTextGetter(KotlinBundle.lazyMessage("convert.0.to.1", elementBefore.text, elementAfter.text))
return element.textRange
}
@@ -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.
*/
@@ -41,11 +41,12 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
@Suppress("DEPRECATION")
class ConvertLambdaToReferenceInspection : IntentionBasedInspection<KtLambdaExpression>(ConvertLambdaToReferenceIntention::class)
open class ConvertLambdaToReferenceIntention(text: String) :
SelfTargetingOffsetIndependentIntention<KtLambdaExpression>(KtLambdaExpression::class.java, text) {
open class ConvertLambdaToReferenceIntention(textGetter: () -> String) : SelfTargetingOffsetIndependentIntention<KtLambdaExpression>(
KtLambdaExpression::class.java,
textGetter
) {
@Suppress("unused")
constructor() : this(KotlinBundle.message("convert.lambda.to.reference"))
constructor() : this(KotlinBundle.lazyMessage("convert.lambda.to.reference"))
open fun buildReferenceText(element: KtLambdaExpression) = buildReferenceText(lambdaExpression = element, shortTypes = false)
@@ -220,7 +221,6 @@ open class ConvertLambdaToReferenceIntention(text: String) :
}
companion object {
private fun buildReferenceText(lambdaExpression: KtLambdaExpression, shortTypes: Boolean): String? {
return when (val singleStatement = lambdaExpression.singleStatementOrNull()) {
is KtCallExpression -> {
@@ -234,6 +234,7 @@ open class ConvertLambdaToReferenceIntention(text: String) :
lambdaExpression.getResolutionScope().getImplicitReceiversHierarchy().size == 1 -> "this"
else -> descriptor?.name?.let { "this@$it" } ?: return null
}
"$receiverText::${singleStatement.getCallReferencedName()}"
}
is KtDotQualifiedExpression -> {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -44,7 +33,7 @@ import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier
class ConvertObjectLiteralToClassIntention : SelfTargetingRangeIntention<KtObjectLiteralExpression>(
KtObjectLiteralExpression::class.java,
KotlinBundle.message("convert.object.literal.to.class")
KotlinBundle.lazyMessage("convert.object.literal.to.class")
) {
override fun applicabilityRange(element: KtObjectLiteralExpression) = element.objectDeclaration.getObjectKeyword()?.textRange
@@ -79,6 +68,7 @@ class ConvertObjectLiteralToClassIntention : SelfTargetingRangeIntention<KtObjec
newClass.add(psiFactory.createColon())
newClass.add(it)
}
objectDeclaration.body?.let {
newClass.add(it)
}
@@ -142,6 +132,7 @@ class ConvertObjectLiteralToClassIntention : SelfTargetingRangeIntention<KtObjec
val targetComment = element.containingKtFile.findDescendantOfType<PsiComment>()?.takeIf {
it.text == "// TARGET_BLOCK:"
}
val target = containers.firstOrNull { it == targetComment?.parent } ?: containers.last()
return doApply(editor, element, target)
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -33,7 +22,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.types.isError
class ConvertPropertyInitializerToGetterIntention : SelfTargetingRangeIntention<KtProperty>(
KtProperty::class.java, KotlinBundle.message("convert.property.initializer.to.getter")
KtProperty::class.java, KotlinBundle.lazyMessage("convert.property.initializer.to.getter")
) {
override fun applicabilityRange(element: KtProperty): TextRange? {
val initializer = element.initializer ?: return null
@@ -68,15 +57,15 @@ class ConvertPropertyInitializerToGetterIntention : SelfTargetingRangeIntention<
val getter = KtPsiFactory(property).createPropertyGetter(initializer)
val setter = property.setter
if (setter != null) {
property.addBefore(getter, setter)
} else if (property.isVar) {
property.add(getter)
val notImplemented = KtPsiFactory(property).createExpression("TODO()")
val notImplementedSetter = KtPsiFactory(property).createPropertySetter(notImplemented)
property.add(notImplementedSetter)
} else {
property.add(getter)
when {
setter != null -> property.addBefore(getter, setter)
property.isVar -> {
property.add(getter)
val notImplemented = KtPsiFactory(property).createExpression("TODO()")
val notImplementedSetter = KtPsiFactory(property).createPropertySetter(notImplemented)
property.add(notImplementedSetter)
}
else -> property.add(getter)
}
property.initializer = null
@@ -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.
*/
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.psi.*
class ConvertRangeCheckToTwoComparisonsIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.message("convert.to.comparisons")
KotlinBundle.lazyMessage("convert.to.comparisons")
) {
private fun KtExpression?.isSimple() = this is KtConstantExpression || this is KtNameReferenceExpression
@@ -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.
*/
@@ -27,30 +27,23 @@ import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
class ConvertReceiverToParameterIntention :
SelfTargetingOffsetIndependentIntention<KtTypeReference>(
KtTypeReference::class.java,
KotlinBundle.message("convert.receiver.to.parameter")
),
LowPriorityAction {
override fun isApplicableTo(element: KtTypeReference): Boolean {
return (element.parent as? KtNamedFunction)?.receiverTypeReference == element
}
class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntention<KtTypeReference>(
KtTypeReference::class.java,
KotlinBundle.lazyMessage("convert.receiver.to.parameter")
), LowPriorityAction {
override fun isApplicableTo(element: KtTypeReference): Boolean = (element.parent as? KtNamedFunction)?.receiverTypeReference == element
private fun configureChangeSignature(newName: String? = null): KotlinChangeSignatureConfiguration {
return object : KotlinChangeSignatureConfiguration {
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
return originalDescriptor.modify {
it.receiver = null
if (newName != null) {
it.parameters.first().name = newName
}
private fun configureChangeSignature(newName: String? = null): KotlinChangeSignatureConfiguration =
object : KotlinChangeSignatureConfiguration {
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor = originalDescriptor.modify {
it.receiver = null
if (newName != null) {
it.parameters.first().name = newName
}
}
override fun performSilently(affectedFunctions: Collection<PsiElement>) = true
}
}
override fun startInWriteAction() = false
@@ -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.
*/
@@ -31,9 +31,8 @@ import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
class ConvertReferenceToLambdaInspection : IntentionBasedInspection<KtCallableReferenceExpression>(ConvertReferenceToLambdaIntention::class)
class ConvertReferenceToLambdaIntention : SelfTargetingOffsetIndependentIntention<KtCallableReferenceExpression>(
KtCallableReferenceExpression::class.java, KotlinBundle.message("convert.reference.to.lambda")
KtCallableReferenceExpression::class.java, KotlinBundle.lazyMessage("convert.reference.to.lambda")
) {
override fun applyTo(element: KtCallableReferenceExpression, editor: Editor?) {
val context = element.analyze(BodyResolveMode.PARTIAL)
val reference = element.callableReference
@@ -43,6 +42,7 @@ class ConvertReferenceToLambdaIntention : SelfTargetingOffsetIndependentIntentio
val receiverType = receiverExpression?.let {
(context[DOUBLE_COLON_LHS, it] as? DoubleColonLHS.Type)?.type
}
val receiverNameAndType = receiverType?.let {
KotlinNameSuggester.suggestNamesByType(it, validator = { name ->
name !in parameterNamesAndTypes.map { pair -> pair.first }
@@ -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.
*/
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
class ConvertSealedClassToEnumIntention : SelfTargetingRangeIntention<KtClass>(
KtClass::class.java,
KotlinBundle.message("convert.to.enum.class")
KotlinBundle.lazyMessage("convert.to.enum.class")
) {
override fun applicabilityRange(element: KtClass): TextRange? {
val nameIdentifier = element.nameIdentifier ?: return null
@@ -83,7 +83,7 @@ class ConvertSealedClassToEnumIntention : SelfTargetingRangeIntention<KtClass>(
}
if (subclassesByContainer.isNotEmpty()) {
subclassesByContainer.forEach { currentClass, currentSubclasses -> processClass(currentClass!!, currentSubclasses, project) }
subclassesByContainer.forEach { (currentClass, currentSubclasses) -> processClass(currentClass!!, currentSubclasses, project) }
} else {
processClass(klass, emptyList(), project)
}
@@ -116,8 +116,8 @@ class ConvertSealedClassToEnumIntention : SelfTargetingRangeIntention<KtClass>(
append((subclass.superTypeListEntries.firstOrNull() as? KtSuperTypeCallEntry)?.valueArgumentList?.text ?: "()")
}
}
val entry = psiFactory.createEnumEntry(entryText)
val entry = psiFactory.createEnumEntry(entryText)
subclass.body?.let { body -> entry.add(body) }
if (i < subclasses.lastIndex) {
@@ -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.
*/
@@ -32,7 +32,7 @@ class ConvertSecondaryConstructorToPrimaryInspection : IntentionBasedInspection<
class ConvertSecondaryConstructorToPrimaryIntention : SelfTargetingRangeIntention<KtSecondaryConstructor>(
KtSecondaryConstructor::class.java,
KotlinBundle.message("convert.to.primary.constructor")
KotlinBundle.lazyMessage("convert.to.primary.constructor")
) {
private tailrec fun ConstructorDescriptor.isReachableByDelegationFrom(
constructor: ConstructorDescriptor, context: BindingContext, visited: Set<ConstructorDescriptor> = emptySet()
@@ -69,8 +69,7 @@ class ConvertSecondaryConstructorToPrimaryIntention : SelfTargetingRangeIntentio
val rightReference = right as? KtReferenceExpression ?: return null
val rightDescriptor = context[BindingContext.REFERENCE_TARGET, rightReference] as? ValueParameterDescriptor ?: return null
if (rightDescriptor.containingDeclaration != constructorDescriptor) return null
val left = left
val leftReference = when (left) {
val leftReference = when (val left = left) {
is KtReferenceExpression ->
left
is KtDotQualifiedExpression ->
@@ -78,6 +77,7 @@ class ConvertSecondaryConstructorToPrimaryIntention : SelfTargetingRangeIntentio
else ->
null
}
val leftDescriptor = context[BindingContext.REFERENCE_TARGET, leftReference] as? PropertyDescriptor ?: return null
return rightDescriptor to leftDescriptor
}
@@ -98,6 +98,7 @@ class ConvertSecondaryConstructorToPrimaryIntention : SelfTargetingRangeIntentio
}
null to null
}
if (rightDescriptor == null || leftDescriptor == null) continue
parameterToPropertyMap[rightDescriptor] = leftDescriptor
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -39,7 +28,7 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.decapitalizeSmart
import org.jetbrains.kotlin.utils.SmartList
sealed class ConvertTestFunctionToSpacedIntention(case: String) : SelfTargetingRangeIntention<KtNamedFunction>(
KtNamedFunction::class.java, KotlinBundle.message("replace.0.name.with.spaces", case)
KtNamedFunction::class.java, KotlinBundle.lazyMessage("replace.0.name.with.spaces", case)
) {
companion object {
private val SNAKE_CASE_REGEX = ".+_.+".toRegex()
@@ -49,9 +38,7 @@ sealed class ConvertTestFunctionToSpacedIntention(case: String) : SelfTargetingR
abstract fun isApplicableName(name: String): Boolean
protected fun isSnakeCase(name: String): Boolean {
return name.contains(SNAKE_CASE_REGEX)
}
protected fun isSnakeCase(name: String): Boolean = name.contains(SNAKE_CASE_REGEX)
override fun applicabilityRange(element: KtNamedFunction): TextRange? {
val platform = element.platform
@@ -66,7 +53,7 @@ sealed class ConvertTestFunctionToSpacedIntention(case: String) : SelfTargetingR
val lightMethod = element.toLightMethods().firstOrNull() ?: return null
if (!TestFrameworks.getInstance().isTestMethod(lightMethod)) return null
text = KotlinBundle.message("rename.to.01", newName)
setTextGetter(KotlinBundle.lazyMessage("rename.to.01", newName))
return range
}
@@ -137,7 +124,7 @@ class ConvertCamelCaseTestFunctionToSpacedIntention : ConvertTestFunctionToSpace
val result = SmartList<String>()
var previousCase = Case.OTHER
var from = 0
for (i in 0 until name.length) {
for (i in name.indices) {
val c = name[i]
val currentCase = when {
Character.isUpperCase(c) -> Case.UPPER
@@ -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.
*/
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.psi.*
class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndependentIntention<KtStringTemplateExpression>(
KtStringTemplateExpression::class.java,
KotlinBundle.message("convert.template.to.concatenated.string")
KotlinBundle.lazyMessage("convert.template.to.concatenated.string")
), LowPriorityAction {
override fun isApplicableTo(element: KtStringTemplateExpression): Boolean {
if (element.lastChild.node.elementType != KtTokens.CLOSING_QUOTE) return false // not available for unclosed literal
@@ -27,8 +27,7 @@ class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndependentInten
val quote = if (tripleQuoted) "\"\"\"" else "\""
val entries = element.entries
val text = entries
.filterNot { it is KtStringTemplateEntryWithExpression && it.expression == null }
val text = entries.filterNot { it is KtStringTemplateEntryWithExpression && it.expression == null }
.mapIndexed { index, entry ->
entry.toSeparateString(quote, convertExplicitly = (index == 0), isFinalEntry = (index == entries.lastIndex))
}
@@ -42,9 +41,7 @@ class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndependentInten
private fun isTripleQuoted(str: String) = str.startsWith("\"\"\"") && str.endsWith("\"\"\"")
private fun KtStringTemplateEntry.toSeparateString(quote: String, convertExplicitly: Boolean, isFinalEntry: Boolean): String {
if (this !is KtStringTemplateEntryWithExpression) {
return text.quote(quote)
}
if (this !is KtStringTemplateEntryWithExpression) return text.quote(quote)
val expression = expression!! // checked before
@@ -59,12 +56,10 @@ class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndependentInten
text
}
private fun needsParenthesis(expression: KtExpression, isFinalEntry: Boolean): Boolean {
return when (expression) {
is KtBinaryExpression -> true
is KtIfExpression -> expression.`else` !is KtBlockExpression && !isFinalEntry
else -> false
}
private fun needsParenthesis(expression: KtExpression, isFinalEntry: Boolean): Boolean = when (expression) {
is KtBinaryExpression -> true
is KtIfExpression -> expression.`else` !is KtBlockExpression && !isFinalEntry
else -> false
}
private fun String.quote(quote: String) = quote + this + quote
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -37,7 +26,7 @@ class ConvertToStringTemplateInspection : IntentionBasedInspection<KtBinaryExpre
open class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.message("convert.concatenation.to.template")
KotlinBundle.lazyMessage("convert.concatenation.to.template")
) {
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
if (!isApplicableToNoParentCheck(element)) return false
@@ -71,7 +60,7 @@ open class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentInte
}
private fun fold(left: KtExpression?, right: String, factory: KtPsiFactory): KtStringTemplateExpression {
val forceBraces = !right.isEmpty() && right.first() != '$' && right.first().isJavaIdentifierPart()
val forceBraces = right.isNotEmpty() && right.first() != '$' && right.first().isJavaIdentifierPart()
return if (left is KtBinaryExpression && isApplicableToNoParentCheck(left)) {
val leftRight = buildText(left.right, forceBraces)
@@ -87,6 +76,7 @@ open class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentInte
val expression = KtPsiUtil.safeDeparenthesize(expr).let {
if ((it as? KtDotQualifiedExpression)?.isToString() == true) it.receiverExpression else it
}
val expressionText = expression.text
when (expression) {
is KtConstantExpression -> {
@@ -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.
*/
@@ -28,10 +28,10 @@ class ConvertTryFinallyToUseCallInspection : IntentionBasedInspection<KtTryExpre
}
class ConvertTryFinallyToUseCallIntention : SelfTargetingRangeIntention<KtTryExpression>(
KtTryExpression::class.java, KotlinBundle.message("convert.try.finally.to.use")
KtTryExpression::class.java, KotlinBundle.lazyMessage("convert.try.finally.to.use")
) {
override fun applyTo(element: KtTryExpression, editor: Editor?) {
val finallySection = element.finallyBlock!!
val finallySection = element.finallyBlock ?: return
val finallyExpression = finallySection.finalExpression.statements.single()
val finallyExpressionReceiver = (finallyExpression as? KtQualifiedExpression)?.receiverExpression
val resourceReference = finallyExpressionReceiver as? KtNameReferenceExpression
@@ -64,6 +64,7 @@ class ConvertTryFinallyToUseCallIntention : SelfTargetingRangeIntention<KtTryExp
is KtCallExpression -> result
else -> return
}
val lambda = call.lambdaArguments.firstOrNull() ?: return
val lambdaParameter = lambda.getLambdaExpression()?.valueParameters?.firstOrNull() ?: return
editor?.selectionModel?.setSelection(lambdaParameter.startOffset, lambdaParameter.endOffset)
@@ -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.
*/
@@ -33,7 +33,7 @@ private const val IMPL_SUFFIX = "Impl"
class CreateKotlinSubClassIntention : SelfTargetingRangeIntention<KtClass>(
KtClass::class.java,
KotlinBundle.message("create.kotlin.subclass")
KotlinBundle.lazyMessage("create.kotlin.subclass")
) {
override fun applicabilityRange(element: KtClass): TextRange? {
@@ -56,15 +56,16 @@ class CreateKotlinSubClassIntention : SelfTargetingRangeIntention<KtClass>(
return null
}
}
text = getImplementTitle(element)
setTextGetter(getImplementTitle(element))
return TextRange(element.startOffset, element.body?.lBrace?.startOffset ?: element.endOffset)
}
private fun getImplementTitle(baseClass: KtClass) = when {
baseClass.isInterface() -> KotlinBundle.message("implement.interface")
baseClass.isAbstract() -> KotlinBundle.message("implement.abstract.class")
baseClass.isSealed() -> KotlinBundle.message("implement.sealed.class")
else /* open class */ -> KotlinBundle.message("create.subclass")
baseClass.isInterface() -> KotlinBundle.lazyMessage("implement.interface")
baseClass.isAbstract() -> KotlinBundle.lazyMessage("implement.abstract.class")
baseClass.isSealed() -> KotlinBundle.lazyMessage("implement.sealed.class")
else /* open class */ -> KotlinBundle.lazyMessage("create.subclass")
}
override fun startInWriteAction() = false
@@ -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.
*/
@@ -54,16 +54,16 @@ class DestructureInspection : IntentionBasedInspection<KtDeclaration>(
class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
KtDeclaration::class.java,
KotlinBundle.message("use.destructuring.declaration")
KotlinBundle.lazyMessage("use.destructuring.declaration")
) {
override fun applyTo(element: KtDeclaration, editor: Editor?) {
val (usagesToRemove, removeSelectorInLoopRange) = collectUsagesToRemove(element)!!
val (usagesToRemove, removeSelectorInLoopRange) = collectUsagesToRemove(element) ?: return
val factory = KtPsiFactory(element)
val validator = NewDeclarationNameValidator(
container = element.parent, anchor = element, target = NewDeclarationNameValidator.Target.VARIABLES,
excludedDeclarations = usagesToRemove.map { listOfNotNull(it.declarationToDrop) }.flatten()
)
val names = ArrayList<String>()
val underscoreSupported = element.languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)
// For all unused we generate normal names, not underscores
@@ -373,6 +373,7 @@ class DestructureIntention : SelfTargetingRangeIntention<KtDeclaration>(
name = name ?: newData.declarationToDrop?.name
declarationToDrop = declarationToDrop ?: newData.declarationToDrop
}
newData.usageToReplace?.let { usagesToReplace.add(it) }
return true
}
@@ -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.
*/
@@ -47,8 +47,10 @@ import org.jetbrains.kotlin.util.findCallableMemberBySignature
import java.util.*
import javax.swing.ListSelectionModel
abstract class ImplementAbstractMemberIntentionBase :
SelfTargetingRangeIntention<KtNamedDeclaration>(KtNamedDeclaration::class.java, "", KotlinBundle.message("implement.abstract.member")) {
abstract class ImplementAbstractMemberIntentionBase : SelfTargetingRangeIntention<KtNamedDeclaration>(
KtNamedDeclaration::class.java,
KotlinBundle.lazyMessage("implement.abstract.member")
) {
companion object {
private val LOG = Logger.getInstance("#${ImplementAbstractMemberIntentionBase::class.java.canonicalName}")
}
@@ -93,12 +95,12 @@ abstract class ImplementAbstractMemberIntentionBase :
.filter(::acceptSubClass)
}
protected abstract fun computeText(element: KtNamedDeclaration): String?
protected abstract fun computeText(element: KtNamedDeclaration): (() -> String)?
override fun applicabilityRange(element: KtNamedDeclaration): TextRange? {
if (!element.isAbstract()) return null
text = computeText(element) ?: return null
setTextGetter(computeText(element) ?: return null)
if (!findClassesToProcess(element).any()) return null
@@ -221,9 +223,9 @@ abstract class ImplementAbstractMemberIntentionBase :
}
class ImplementAbstractMemberIntention : ImplementAbstractMemberIntentionBase() {
override fun computeText(element: KtNamedDeclaration): String? = when (element) {
is KtProperty -> KotlinBundle.message("implement.abstract.property")
is KtNamedFunction -> KotlinBundle.message("implement.abstract.function")
override fun computeText(element: KtNamedDeclaration): (() -> String)? = when (element) {
is KtProperty -> KotlinBundle.lazyMessage("implement.abstract.property")
is KtNamedFunction -> KotlinBundle.lazyMessage("implement.abstract.function")
else -> null
}
@@ -236,9 +238,9 @@ class ImplementAbstractMemberIntention : ImplementAbstractMemberIntentionBase()
}
class ImplementAbstractMemberAsConstructorParameterIntention : ImplementAbstractMemberIntentionBase() {
override fun computeText(element: KtNamedDeclaration): String? {
override fun computeText(element: KtNamedDeclaration): (() -> String)? {
if (element !is KtProperty) return null
return KotlinBundle.message("implement.as.constructor.parameter")
return KotlinBundle.lazyMessage("implement.as.constructor.parameter")
}
override fun acceptSubClass(subClassDescriptor: ClassDescriptor, memberDescriptor: CallableMemberDescriptor): Boolean {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -35,7 +24,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameReferenceExpression>(
KtNameReferenceExpression::class.java,
KotlinBundle.message("add.import.for.member")
KotlinBundle.lazyMessage("add.import.for.member")
), HighPriorityAction {
override fun isApplicableTo(element: KtNameReferenceExpression): Boolean {
if (element.getQualifiedElement() == element) return false //Ignore simple name expressions
@@ -46,7 +35,7 @@ class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameRefe
val fqName = targetFqName(qualifiedExpression) ?: return false
text = KotlinBundle.message("add.import.for.0", fqName.asString())
setTextGetter(KotlinBundle.lazyMessage("add.import.for.0", fqName.asString()))
return true
}
@@ -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.
*/
@@ -19,14 +19,11 @@ import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class IndentRawStringIntention : SelfTargetingOffsetIndependentIntention<KtStringTemplateExpression>(
KtStringTemplateExpression::class.java, KotlinBundle.message("indent.raw.string")
KtStringTemplateExpression::class.java, KotlinBundle.lazyMessage("indent.raw.string")
) {
override fun isApplicableTo(element: KtStringTemplateExpression): Boolean {
if (!element.text.startsWith("\"\"\"")) return false
if (element.parents
.any { it is KtAnnotationEntry || (it as? KtProperty)?.hasModifier(KtTokens.CONST_KEYWORD) == true }
) return false
if (element.parents.any { it is KtAnnotationEntry || (it as? KtProperty)?.hasModifier(KtTokens.CONST_KEYWORD) == true }) return false
if (element.getQualifiedExpressionForReceiver() != null) return false
val entries = element.entries
if (entries.size <= 1 || entries.any { it.text.startsWith(" ") || it.text.startsWith("\t") }) return false
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -25,11 +14,9 @@ import org.jetbrains.kotlin.psi.KtSimpleNameStringTemplateEntry
import org.jetbrains.kotlin.psi.KtStringTemplateEntryWithExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
class InsertCurlyBracesToTemplateIntention :
SelfTargetingOffsetIndependentIntention<KtSimpleNameStringTemplateEntry>(
KtSimpleNameStringTemplateEntry::class.java, KotlinBundle.message("insert.curly.braces.around.variable")
),
LowPriorityAction {
class InsertCurlyBracesToTemplateIntention : SelfTargetingOffsetIndependentIntention<KtSimpleNameStringTemplateEntry>(
KtSimpleNameStringTemplateEntry::class.java, KotlinBundle.lazyMessage("insert.curly.braces.around.variable")
), LowPriorityAction {
override fun isApplicableTo(element: KtSimpleNameStringTemplateEntry): Boolean = true
@@ -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.
*/
@@ -24,12 +24,12 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.checker.NewCapturedType
class InsertExplicitTypeArgumentsIntention :
SelfTargetingRangeIntention<KtCallExpression>(KtCallExpression::class.java, KotlinBundle.message("add.explicit.type.arguments")),
LowPriorityAction {
override fun applicabilityRange(element: KtCallExpression): TextRange? {
return if (isApplicableTo(element, element.analyze())) element.calleeExpression?.textRange else null
}
class InsertExplicitTypeArgumentsIntention : SelfTargetingRangeIntention<KtCallExpression>(
KtCallExpression::class.java,
KotlinBundle.lazyMessage("add.explicit.type.arguments")
), LowPriorityAction {
override fun applicabilityRange(element: KtCallExpression): TextRange? =
if (isApplicableTo(element, element.analyze())) element.calleeExpression?.textRange else null
override fun applyTo(element: KtCallExpression, editor: Editor?) = applyTo(element)
@@ -47,8 +47,7 @@ class InsertExplicitTypeArgumentsIntention :
}
}
return typeArgs.isNotEmpty() && typeArgs.values
.none { ErrorUtils.containsErrorType(it) || it is CapturedType || it is NewCapturedType }
return typeArgs.isNotEmpty() && typeArgs.values.none { ErrorUtils.containsErrorType(it) || it is CapturedType || it is NewCapturedType }
}
fun applyTo(element: KtCallElement, shortenReferences: Boolean = true) {
@@ -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.
*/
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.psi.KtNameReferenceExpression
class IntroduceImportAliasIntention : SelfTargetingRangeIntention<KtNameReferenceExpression>(
KtNameReferenceExpression::class.java,
KotlinBundle.message("introduce.import.alias")
KotlinBundle.lazyMessage("introduce.import.alias")
) {
override fun applicabilityRange(element: KtNameReferenceExpression): TextRange? {
if (element.parent is KtInstanceExpressionWithLabel) return null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -34,7 +23,7 @@ import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit
class IntroduceVariableIntention : SelfTargetingRangeIntention<PsiElement>(
PsiElement::class.java, CodeInsightBundle.message("intention.introduce.variable.text")
PsiElement::class.java, { CodeInsightBundle.message("intention.introduce.variable.text") }
), HighPriorityAction {
private fun getExpressionToProcess(element: PsiElement): KtExpression? {
if (element is PsiFileSystemItem) return null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -46,7 +35,7 @@ class JoinDeclarationAndAssignmentInspection : IntentionBasedInspection<KtProper
class JoinDeclarationAndAssignmentIntention : SelfTargetingRangeIntention<KtProperty>(
KtProperty::class.java,
KotlinBundle.message("join.declaration.and.assignment")
KotlinBundle.lazyMessage("join.declaration.and.assignment")
) {
private fun equalNullableTypes(type1: KotlinType?, type2: KotlinType?): Boolean {
@@ -166,15 +155,13 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingRangeIntention<KtProp
// a block that only contains comments is not empty
private fun KtBlockExpression.isEmpty() = contentRange().isEmpty
private fun hasNoLocalDependencies(element: KtElement, localContext: PsiElement): Boolean {
return !element.anyDescendantOfType<PsiElement> { child ->
private fun hasNoLocalDependencies(element: KtElement, localContext: PsiElement): Boolean =
!element.anyDescendantOfType<PsiElement> { child ->
child.resolveAllReferences().any { it != null && PsiTreeUtil.isAncestor(localContext, it, false) }
}
}
}
private fun PsiElement.resolveAllReferences(): Sequence<PsiElement?> {
return PsiReferenceService.getService().getReferences(this, PsiReferenceService.Hints.NO_HINTS)
private fun PsiElement.resolveAllReferences(): Sequence<PsiElement?> =
PsiReferenceService.getService().getReferences(this, PsiReferenceService.Hints.NO_HINTS)
.asSequence()
.map { it.resolve() }
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 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.
*/
@@ -17,9 +17,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
abstract class AbstractJoinListIntention<TList : KtElement, TElement : KtElement>(
listClass: Class<TList>,
elementClass: Class<TElement>,
text: String
) : AbstractChopListIntention<TList, TElement>(listClass, elementClass, text) {
textGetter: () -> String
) : AbstractChopListIntention<TList, TElement>(listClass, elementClass, textGetter) {
override fun isApplicableTo(element: TList): Boolean {
val elements = element.elements()
if (elements.isEmpty()) return false
@@ -48,7 +47,7 @@ abstract class AbstractJoinListIntention<TList : KtElement, TElement : KtElement
class JoinParameterListIntention : AbstractJoinListIntention<KtParameterList, KtParameter>(
KtParameterList::class.java,
KtParameter::class.java,
KotlinBundle.message("put.parameters.on.one.line")
KotlinBundle.lazyMessage("put.parameters.on.one.line")
) {
override fun isApplicableTo(element: KtParameterList): Boolean {
if (element.parent is KtFunctionLiteral) return false
@@ -59,5 +58,5 @@ class JoinParameterListIntention : AbstractJoinListIntention<KtParameterList, Kt
class JoinArgumentListIntention : AbstractJoinListIntention<KtValueArgumentList, KtValueArgument>(
KtValueArgumentList::class.java,
KtValueArgument::class.java,
KotlinBundle.message("put.arguments.on.one.line")
KotlinBundle.lazyMessage("put.arguments.on.one.line")
)
@@ -40,10 +40,9 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
import org.jetbrains.kotlin.util.findCallableMemberBySignature
class MoveMemberOutOfCompanionObjectIntention : MoveMemberOutOfObjectIntention(KotlinBundle.message("move.out.of.companion.object")) {
class MoveMemberOutOfCompanionObjectIntention : MoveMemberOutOfObjectIntention(KotlinBundle.lazyMessage("move.out.of.companion.object")) {
override fun addConflicts(element: KtNamedDeclaration, conflicts: MultiMap<PsiElement, String>) {
val targetClass = element.containingClassOrObject!!.containingClassOrObject!!
val targetClass = element.containingClassOrObject?.containingClassOrObject ?: return
val targetClassDescriptor = runReadAction { targetClass.unsafeResolveToDescriptor() as ClassDescriptor }
val refsRequiringClassInstance =
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -30,8 +19,10 @@ import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.isPrivate
abstract class MoveMemberOutOfObjectIntention(text: String) :
SelfTargetingRangeIntention<KtNamedDeclaration>(KtNamedDeclaration::class.java, text) {
abstract class MoveMemberOutOfObjectIntention(textGetter: () -> String) : SelfTargetingRangeIntention<KtNamedDeclaration>(
KtNamedDeclaration::class.java,
textGetter
) {
override fun startInWriteAction() = false
abstract fun getDestination(element: KtNamedDeclaration): KtElement
@@ -57,10 +48,12 @@ abstract class MoveMemberOutOfObjectIntention(text: String) :
KotlinMoveTargetForExistingElement(destination),
MoveDeclarationsDelegate.NestedClass()
)
val compositeRefactoringRunner = object : CompositeRefactoringRunner(project, MoveKotlinDeclarationsProcessor.REFACTORING_ID) {
override fun runRefactoring() = MoveKotlinDeclarationsProcessor(moveDescriptor).run()
override fun onExit() = runWriteAction { deleteClassOrObjectIfEmpty() }
}
if (element is KtClassOrObject) {
compositeRefactoringRunner.run()
} else {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -73,7 +62,7 @@ import org.jetbrains.kotlin.util.findCallableMemberBySignature
class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention<KtNamedDeclaration>(
KtNamedDeclaration::class.java,
KotlinBundle.message("move.to.companion.object")
KotlinBundle.lazyMessage("move.to.companion.object")
) {
override fun applicabilityRange(element: KtNamedDeclaration): TextRange? {
if (element !is KtNamedFunction && element !is KtProperty && element !is KtClassOrObject) return null
@@ -106,6 +95,7 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention<KtNamed
val validator = CollectingNameValidator(element.getValueParameters().mapNotNull { it.name }) {
companionMemberScope.getContributedVariables(Name.identifier(it), NoLookupLocation.FROM_IDE).isEmpty()
}
return KotlinNameSuggester.suggestNamesByType(containingClassDescriptor.defaultType, validator, "receiver")
}
@@ -377,8 +367,6 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention<KtNamed
}
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
return MoveMemberToCompanionObjectIntention()
}
override fun createAction(diagnostic: Diagnostic): IntentionAction? = MoveMemberToCompanionObjectIntention()
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -31,7 +20,7 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor
import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
class MoveMemberToTopLevelIntention : MoveMemberOutOfObjectIntention(KotlinBundle.message("move.to.top.level")) {
class MoveMemberToTopLevelIntention : MoveMemberOutOfObjectIntention(KotlinBundle.lazyMessage("move.to.top.level")) {
override fun addConflicts(element: KtNamedDeclaration, conflicts: MultiMap<PsiElement, String>) {
val packageViewDescriptor = element.findModuleDescriptor().getPackage(element.containingKtFile.packageFqName)
val packageDescriptor = packageViewDescriptor.fragments.firstIsInstance<LazyPackageDescriptor>()
@@ -42,13 +31,11 @@ class MoveMemberToTopLevelIntention : MoveMemberOutOfObjectIntention(KotlinBundl
val isRedeclaration = when (element) {
is KtProperty -> memberScope.getVariableNames().any { name == it.identifier }
is KtFunction -> {
memberScope.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_IDE).filter {
memberScope.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_IDE).any {
descriptorsEqualWithSubstitution(element.descriptor, it, false)
}.isNotEmpty()
}
}
else -> false
}
@@ -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.
*/
@@ -60,8 +60,8 @@ class ObjectLiteralToLambdaInspection : IntentionBasedInspection<KtObjectLiteral
class ObjectLiteralToLambdaIntention : SelfTargetingRangeIntention<KtObjectLiteralExpression>(
KtObjectLiteralExpression::class.java,
KotlinBundle.message("convert.to.lambda"),
KotlinBundle.message("convert.object.literal.to.lambda")
KotlinBundle.lazyMessage("convert.to.lambda"),
KotlinBundle.lazyMessage("convert.object.literal.to.lambda")
) {
override fun applicabilityRange(element: KtObjectLiteralExpression): TextRange? {
val (baseTypeRef, baseType, singleFunction) = extractData(element) ?: return null
@@ -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.
*/
@@ -18,12 +18,10 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isError
class ReconstructTypeInCastOrIsIntention :
SelfTargetingOffsetIndependentIntention<KtTypeReference>(
KtTypeReference::class.java,
KotlinBundle.message("replace.by.reconstructed.type")
),
LowPriorityAction {
class ReconstructTypeInCastOrIsIntention : SelfTargetingOffsetIndependentIntention<KtTypeReference>(
KtTypeReference::class.java,
KotlinBundle.lazyMessage("replace.by.reconstructed.type")
), LowPriorityAction {
override fun isApplicableTo(element: KtTypeReference): Boolean {
// Only user types (like Foo) are interesting
val typeElement = element.typeElement as? KtUserType ?: return false
@@ -42,7 +40,7 @@ class ReconstructTypeInCastOrIsIntention :
if (type.constructor.parameters.isEmpty()) return false
val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(type)
text = KotlinBundle.message("replace.by.0", typePresentation)
setTextGetter(KotlinBundle.lazyMessage("replace.by.0", typePresentation))
return true
}
@@ -53,7 +51,5 @@ class ReconstructTypeInCastOrIsIntention :
ShortenReferences.DEFAULT.process(element.replaced(newType))
}
private fun getReconstructedType(typeRef: KtTypeReference): KotlinType? {
return typeRef.analyze().get(BindingContext.TYPE, typeRef)
}
private fun getReconstructedType(typeRef: KtTypeReference): KotlinType? = typeRef.analyze().get(BindingContext.TYPE, typeRef)
}
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.resolve.calls.components.isVararg
class RemoveArgumentNameIntention : SelfTargetingRangeIntention<KtValueArgument>(
KtValueArgument::class.java,
KotlinBundle.message("remove.argument.name")
KotlinBundle.lazyMessage("remove.argument.name")
) {
override fun applicabilityRange(element: KtValueArgument): TextRange? {
if (!element.isNamed()) return null
@@ -42,6 +42,7 @@ class RemoveArgumentNameIntention : SelfTargetingRangeIntention<KtValueArgument>
.map { psiFactory.createArgument(it) }
.reversed()
.forEach { argumentList.addArgumentAfter(it, element) }
argumentList.removeArgument(element)
} else {
val newArgument = psiFactory.createArgument(argumentExpr, null, element.getSpreadElement() != null)
@@ -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.
*/
@@ -18,15 +18,15 @@ import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComme
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
@Suppress("DEPRECATION")
class RemoveEmptyClassBodyInspection :
IntentionBasedInspection<KtClassBody>(RemoveEmptyClassBodyIntention::class), CleanupLocalInspectionTool {
override fun problemHighlightType(element: KtClassBody): ProblemHighlightType =
ProblemHighlightType.LIKE_UNUSED_SYMBOL
class RemoveEmptyClassBodyInspection : IntentionBasedInspection<KtClassBody>(RemoveEmptyClassBodyIntention::class),
CleanupLocalInspectionTool {
override fun problemHighlightType(element: KtClassBody): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL
}
class RemoveEmptyClassBodyIntention :
SelfTargetingOffsetIndependentIntention<KtClassBody>(KtClassBody::class.java, KotlinBundle.message("redundant.empty.class.body")) {
class RemoveEmptyClassBodyIntention : SelfTargetingOffsetIndependentIntention<KtClassBody>(
KtClassBody::class.java,
KotlinBundle.lazyMessage("redundant.empty.class.body")
) {
override fun applyTo(element: KtClassBody, editor: Editor?) {
val parent = element.parent
element.delete()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -33,14 +22,12 @@ import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComme
class RemoveEmptyParenthesesFromLambdaCallInspection : IntentionBasedInspection<KtValueArgumentList>(
RemoveEmptyParenthesesFromLambdaCallIntention::class
), CleanupLocalInspectionTool {
override fun problemHighlightType(element: KtValueArgumentList): ProblemHighlightType =
ProblemHighlightType.LIKE_UNUSED_SYMBOL
override fun problemHighlightType(element: KtValueArgumentList): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL
}
class RemoveEmptyParenthesesFromLambdaCallIntention : SelfTargetingRangeIntention<KtValueArgumentList>(
KtValueArgumentList::class.java, KotlinBundle.message("remove.unnecessary.parentheses.from.function.call.with.lambda")
KtValueArgumentList::class.java, KotlinBundle.lazyMessage("remove.unnecessary.parentheses.from.function.call.with.lambda")
) {
override fun applicabilityRange(element: KtValueArgumentList): TextRange? {
if (element.arguments.isNotEmpty()) return null
val parent = element.parent as? KtCallExpression ?: return null
@@ -51,7 +38,5 @@ class RemoveEmptyParenthesesFromLambdaCallIntention : SelfTargetingRangeIntentio
return element.range
}
override fun applyTo(element: KtValueArgumentList, editor: Editor?) {
element.delete()
}
override fun applyTo(element: KtValueArgumentList, editor: Editor?) = element.delete()
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -32,11 +21,10 @@ class RemoveEmptyPrimaryConstructorInspection : IntentionBasedInspection<KtPrima
override fun problemHighlightType(element: KtPrimaryConstructor): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL
}
class RemoveEmptyPrimaryConstructorIntention :
SelfTargetingOffsetIndependentIntention<KtPrimaryConstructor>(
KtPrimaryConstructor::class.java,
KotlinBundle.message("remove.empty.primary.constructor")
) {
class RemoveEmptyPrimaryConstructorIntention : SelfTargetingOffsetIndependentIntention<KtPrimaryConstructor>(
KtPrimaryConstructor::class.java,
KotlinBundle.lazyMessage("remove.empty.primary.constructor")
) {
override fun applyTo(element: KtPrimaryConstructor, editor: Editor?) = element.delete()
@@ -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.
*/
@@ -17,16 +17,13 @@ import org.jetbrains.kotlin.psi.KtSecondaryConstructor
class RemoveEmptySecondaryConstructorBodyInspection : IntentionBasedInspection<KtBlockExpression>(
RemoveEmptySecondaryConstructorBodyIntention::class
), CleanupLocalInspectionTool {
override fun problemHighlightType(element: KtBlockExpression): ProblemHighlightType =
ProblemHighlightType.LIKE_UNUSED_SYMBOL
override fun problemHighlightType(element: KtBlockExpression): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL
}
class RemoveEmptySecondaryConstructorBodyIntention :
SelfTargetingOffsetIndependentIntention<KtBlockExpression>(
KtBlockExpression::class.java,
KotlinBundle.message("remove.empty.constructor.body")
) {
class RemoveEmptySecondaryConstructorBodyIntention : SelfTargetingOffsetIndependentIntention<KtBlockExpression>(
KtBlockExpression::class.java,
KotlinBundle.lazyMessage("remove.empty.constructor.body")
) {
override fun applyTo(element: KtBlockExpression, editor: Editor?) = element.delete()
override fun isApplicableTo(element: KtBlockExpression): Boolean {
@@ -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.
*/
@@ -28,15 +28,13 @@ import org.jetbrains.kotlin.types.ErrorUtils
class RemoveExplicitSuperQualifierInspection : IntentionBasedInspection<KtSuperExpression>(
RemoveExplicitSuperQualifierIntention::class
), CleanupLocalInspectionTool {
override fun problemHighlightType(element: KtSuperExpression): ProblemHighlightType =
ProblemHighlightType.LIKE_UNUSED_SYMBOL
override fun problemHighlightType(element: KtSuperExpression): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL
}
class RemoveExplicitSuperQualifierIntention :
SelfTargetingRangeIntention<KtSuperExpression>(
KtSuperExpression::class.java,
KotlinBundle.message("remove.explicit.supertype.qualification")
) {
class RemoveExplicitSuperQualifierIntention : SelfTargetingRangeIntention<KtSuperExpression>(
KtSuperExpression::class.java,
KotlinBundle.lazyMessage("remove.explicit.supertype.qualification")
) {
override fun applicabilityRange(element: KtSuperExpression): TextRange? {
if (element.superTypeQualifier == null) return null
@@ -50,6 +48,7 @@ class RemoveExplicitSuperQualifierIntention :
"$0.$1", toNonQualified(element, reformat = false), selector,
reformat = false
) as KtQualifiedExpression
val newBindingContext = newQualifiedExpression.analyzeAsReplacement(qualifiedExpression, bindingContext)
val newResolvedCall = newQualifiedExpression.selectorExpression.getResolvedCall(newBindingContext) ?: return null
if (ErrorUtils.isError(newResolvedCall.resultingDescriptor)) return null
@@ -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.
*/
@@ -34,17 +34,14 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@Suppress("DEPRECATION")
class RemoveExplicitTypeArgumentsInspection : IntentionBasedInspection<KtTypeArgumentList>(RemoveExplicitTypeArgumentsIntention::class) {
override fun problemHighlightType(element: KtTypeArgumentList): ProblemHighlightType =
ProblemHighlightType.LIKE_UNUSED_SYMBOL
override fun problemHighlightType(element: KtTypeArgumentList): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL
}
class RemoveExplicitTypeArgumentsIntention :
SelfTargetingOffsetIndependentIntention<KtTypeArgumentList>(
KtTypeArgumentList::class.java,
KotlinBundle.message("remove.explicit.type.arguments")
) {
class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndependentIntention<KtTypeArgumentList>(
KtTypeArgumentList::class.java,
KotlinBundle.lazyMessage("remove.explicit.type.arguments")
) {
companion object {
fun isApplicableTo(element: KtTypeArgumentList, approximateFlexible: Boolean): Boolean {
val callExpression = element.parent as? KtCallExpression ?: return false
if (callExpression.typeArguments.isEmpty()) return false
@@ -141,11 +138,7 @@ class RemoveExplicitTypeArgumentsIntention :
}
}
override fun isApplicableTo(element: KtTypeArgumentList): Boolean {
return isApplicableTo(element, approximateFlexible = false)
}
override fun isApplicableTo(element: KtTypeArgumentList): Boolean = isApplicableTo(element, approximateFlexible = false)
override fun applyTo(element: KtTypeArgumentList, editor: Editor?) {
element.delete()
}
override fun applyTo(element: KtTypeArgumentList, editor: Editor?) = element.delete()
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -32,16 +21,12 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
class RemoveExplicitTypeIntention : SelfTargetingRangeIntention<KtCallableDeclaration>(
KtCallableDeclaration::class.java,
KotlinBundle.message("remove.explicit.type.specification")
KotlinBundle.lazyMessage("remove.explicit.type.specification")
), HighPriorityAction {
override fun applicabilityRange(element: KtCallableDeclaration): TextRange? {
return getRange(element)
}
override fun applicabilityRange(element: KtCallableDeclaration): TextRange? = getRange(element)
override fun applyTo(element: KtCallableDeclaration, editor: Editor?) {
removeExplicitType(element)
}
override fun applyTo(element: KtCallableDeclaration, editor: Editor?) = removeExplicitType(element)
companion object {
fun removeExplicitType(element: KtCallableDeclaration) {
@@ -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.
*/
@@ -27,8 +27,10 @@ class RemoveForLoopIndicesInspection : IntentionBasedInspection<KtForExpression>
override fun problemHighlightType(element: KtForExpression): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL
}
class RemoveForLoopIndicesIntention :
SelfTargetingRangeIntention<KtForExpression>(KtForExpression::class.java, KotlinBundle.message("remove.indices.in.for.loop")) {
class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(
KtForExpression::class.java,
KotlinBundle.lazyMessage("remove.indices.in.for.loop")
) {
private val WITH_INDEX_NAME = "withIndex"
private val WITH_INDEX_FQ_NAMES: Set<String> by lazy {
sequenceOf("collections", "sequences", "text", "ranges").map { "kotlin.$it.$WITH_INDEX_NAME" }.toSet()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -40,7 +29,7 @@ class RemoveRedundantCallsOfConversionMethodsInspection : IntentionBasedInspecti
class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingRangeIntention<KtQualifiedExpression>(
KtQualifiedExpression::class.java,
KotlinBundle.message("remove.redundant.calls.of.the.conversion.method")
KotlinBundle.lazyMessage("remove.redundant.calls.of.the.conversion.method")
) {
private val targetClassMap: Map<String, String?> by lazy {
@@ -72,28 +61,27 @@ class RemoveRedundantCallsOfConversionMethodsIntention : SelfTargetingRangeInten
}
}
private fun KotlinType.getFqNameAsString(): String? =
constructor.declarationDescriptor?.let { DescriptorUtils.getFqName(it).asString() }
private fun KotlinType.getFqNameAsString(): String? = constructor.declarationDescriptor?.let {
DescriptorUtils.getFqName(it).asString()
}
private fun KtExpression.isApplicableReceiverExpression(qualifiedName: String): Boolean {
return when (this) {
is KtStringTemplateExpression -> String::class.qualifiedName
is KtConstantExpression -> getType(analyze())?.getFqNameAsString()
else -> {
val resolvedCall = resolveToCall()
if ((resolvedCall?.call?.callElement as? KtBinaryExpression)?.operationToken in OperatorConventions.COMPARISON_OPERATIONS) {
// Special case here because compareTo returns Int
Boolean::class.qualifiedName
} else {
resolvedCall?.candidateDescriptor?.returnType?.let {
when {
it.isFlexible() -> null
parent !is KtSafeQualifiedExpression && (this is KtSafeQualifiedExpression || it.isMarkedNullable) -> null
else -> it.getFqNameAsString()
}
private fun KtExpression.isApplicableReceiverExpression(qualifiedName: String): Boolean = when (this) {
is KtStringTemplateExpression -> String::class.qualifiedName
is KtConstantExpression -> getType(analyze())?.getFqNameAsString()
else -> {
val resolvedCall = resolveToCall()
if ((resolvedCall?.call?.callElement as? KtBinaryExpression)?.operationToken in OperatorConventions.COMPARISON_OPERATIONS) {
// Special case here because compareTo returns Int
Boolean::class.qualifiedName
} else {
resolvedCall?.candidateDescriptor?.returnType?.let {
when {
it.isFlexible() -> null
parent !is KtSafeQualifiedExpression && (this is KtSafeQualifiedExpression || it.isMarkedNullable) -> null
else -> it.getFqNameAsString()
}
}
}
} == qualifiedName
}
}
} == qualifiedName
}
@@ -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.
*/
@@ -16,8 +16,7 @@ import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.createExpressionByPattern
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
private fun KtStringTemplateExpression.singleExpressionOrNull() =
children.singleOrNull()?.children?.firstOrNull() as? KtExpression
private fun KtStringTemplateExpression.singleExpressionOrNull() = children.singleOrNull()?.children?.firstOrNull() as? KtExpression
class RemoveSingleExpressionStringTemplateInspection : IntentionBasedInspection<KtStringTemplateExpression>(
RemoveSingleExpressionStringTemplateIntention::class,
@@ -32,10 +31,9 @@ class RemoveSingleExpressionStringTemplateInspection : IntentionBasedInspection<
class RemoveSingleExpressionStringTemplateIntention : SelfTargetingOffsetIndependentIntention<KtStringTemplateExpression>(
KtStringTemplateExpression::class.java,
KotlinBundle.message("remove.single.expression.string.template")
KotlinBundle.lazyMessage("remove.single.expression.string.template")
) {
override fun isApplicableTo(element: KtStringTemplateExpression) =
element.singleExpressionOrNull() != null
override fun isApplicableTo(element: KtStringTemplateExpression) = element.singleExpressionOrNull() != null
override fun applyTo(element: KtStringTemplateExpression, editor: Editor?) {
val expression = element.singleExpressionOrNull() ?: return
@@ -44,6 +42,7 @@ class RemoveSingleExpressionStringTemplateIntention : SelfTargetingOffsetIndepen
expression
else
KtPsiFactory(element).createExpressionByPattern("$0.$1()", expression, "toString")
element.replace(newElement)
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -26,7 +15,7 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtPsiUtil
class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention<KtParenthesizedExpression>(
KtParenthesizedExpression::class.java, KotlinBundle.message("remove.unnecessary.parentheses")
KtParenthesizedExpression::class.java, KotlinBundle.lazyMessage("remove.unnecessary.parentheses")
) {
override fun applicabilityRange(element: KtParenthesizedExpression): TextRange? {
element.expression ?: return null
@@ -41,6 +30,7 @@ class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention<KtPare
if (innerExpression.firstChild is KtLambdaExpression) {
KtPsiFactory(element).appendSemicolonBeforeLambdaContainingElement(replaced)
}
commentSaver.restore(replaced)
}
}
@@ -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.
*/
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.renderer.render
class RenameClassToContainingFileNameIntention : SelfTargetingRangeIntention<KtClassOrObject>(
KtClassOrObject::class.java, KotlinBundle.message("rename.class.to.containing.file.name")
KtClassOrObject::class.java, KotlinBundle.lazyMessage("rename.class.to.containing.file.name")
) {
override fun startInWriteAction() = false
@@ -29,7 +29,7 @@ class RenameClassToContainingFileNameIntention : SelfTargetingRangeIntention<KtC
|| Name.identifier(fileName).render() != fileName
|| element.containingKtFile.declarations.any { it is KtClassOrObject && it.name == fileName }
) return null
text = KotlinBundle.message("rename.class.to.0", fileName)
setTextGetter(KotlinBundle.lazyMessage("rename.class.to.0", fileName))
return element.nameIdentifier?.textRange
}
@@ -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.
*/
@@ -14,16 +14,15 @@ import com.intellij.refactoring.rename.RenameProcessor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.psi.KtClassOrObject
class RenameFileToMatchClassIntention :
SelfTargetingRangeIntention<KtClassOrObject>(
KtClassOrObject::class.java, "",
KotlinBundle.message("rename.file.to.match.top.level.class.name")
) {
class RenameFileToMatchClassIntention : SelfTargetingRangeIntention<KtClassOrObject>(
KtClassOrObject::class.java,
KotlinBundle.lazyMessage("rename.file.to.match.top.level.class.name")
) {
override fun applicabilityRange(element: KtClassOrObject): TextRange? {
if (!element.isTopLevel()) return null
val fileName = element.containingKtFile.name
if (FileUtil.getNameWithoutExtension(fileName) == element.name) return null
text = KotlinBundle.message("rename.file.to.0.1", element.name.toString(), FileUtilRt.getExtension(fileName))
setTextGetter(KotlinBundle.lazyMessage("rename.file.to.0.1", element.name.toString(), FileUtilRt.getExtension(fileName)))
return element.nameIdentifier?.textRange
}
@@ -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.
*/
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ReplaceAddWithPlusAssignIntention : SelfTargetingOffsetIndependentIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
KotlinBundle.message("replace.with1")
KotlinBundle.lazyMessage("replace.with1")
) {
private val compatibleNames: Set<String> by lazy { setOf("add", "addAll") }
@@ -29,7 +29,7 @@ class ReplaceAddWithPlusAssignIntention : SelfTargetingOffsetIndependentIntentio
if (element.callExpression?.valueArguments?.size != 1) return false
if (element.calleeName !in compatibleNames) return false
text = KotlinBundle.message("replace.0.with", element.calleeName.toString())
setTextGetter(KotlinBundle.lazyMessage("replace.0.with", element.calleeName.toString()))
val context = element.analyze(BodyResolveMode.PARTIAL)
BindingContextUtils.extractVariableDescriptorFromReference(context, element.receiverExpression)?.let {
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -29,7 +18,7 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
class ReplaceItWithExplicitFunctionLiteralParamIntention : SelfTargetingOffsetIndependentIntention<KtNameReferenceExpression>(
KtNameReferenceExpression::class.java, KotlinBundle.message("replace.it.with.explicit.parameter")
KtNameReferenceExpression::class.java, KotlinBundle.lazyMessage("replace.it.with.explicit.parameter")
) {
override fun isApplicableTo(element: KtNameReferenceExpression) = isAutoCreatedItUsage(element)
@@ -45,6 +34,7 @@ class ReplaceItWithExplicitFunctionLiteralParamIntention : SelfTargetingOffsetIn
newExpr.functionLiteral.arrow ?: return,
functionLiteral.lBrace
)
PsiDocumentManager.getInstance(element.project).doPostponedOperationsAndUnblockDocument(editor.document)
val paramToRename = functionLiteral.valueParameters.single()
@@ -1,6 +1,6 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.isNullable
class ReplaceMapGetOrDefaultIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java, KotlinBundle.message("replace.with.indexing.and.elvis.operator")
KtDotQualifiedExpression::class.java, KotlinBundle.lazyMessage("replace.with.indexing.and.elvis.operator")
) {
companion object {
private val getOrDefaultFqName = FqName("kotlin.collections.Map.getOrDefault")
@@ -35,7 +35,7 @@ class ReplaceMapGetOrDefaultIntention : SelfTargetingRangeIntention<KtDotQualifi
val context = element.analyze(BodyResolveMode.PARTIAL)
if (callExpression.getResolvedCall(context)?.isCalling(getOrDefaultFqName) != true) return null
if (element.receiverExpression.getType(context)?.arguments?.lastOrNull()?.type?.isNullable() == true) return null
text = KotlinBundle.message("replace.with.0.1.2", element.receiverExpression.text, firstArg.text, secondArg.text)
setTextGetter(KotlinBundle.lazyMessage("replace.with.0.1.2", element.receiverExpression.text, firstArg.text, secondArg.text))
return calleeExpression.textRange
}
@@ -45,6 +45,7 @@ class ReplaceMapGetOrDefaultIntention : SelfTargetingRangeIntention<KtDotQualifi
val replaced = element.replaced(
KtPsiFactory(element).createExpressionByPattern("$0[$1] ?: $2", element.receiverExpression, firstArg, secondArg)
)
replaced.findDescendantOfType<KtArrayAccessExpression>()?.leftBracket?.startOffset?.let {
editor?.caretModel?.moveToOffset(it)
}
@@ -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.
*/
@@ -12,10 +12,9 @@ import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
abstract class ReplaceSizeCheckIntention(text: String) : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java, text
abstract class ReplaceSizeCheckIntention(textGetter: () -> String) : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java, textGetter
) {
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val target = getTargetExpression(element)
if (target !is KtDotQualifiedExpression) return
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -23,25 +12,23 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtExpression
@Suppress("DEPRECATION")
class ReplaceSizeCheckWithIsNotEmptyInspection :
IntentionBasedInspection<KtBinaryExpression>(ReplaceSizeCheckWithIsNotEmptyIntention::class)
class ReplaceSizeCheckWithIsNotEmptyIntention : ReplaceSizeCheckIntention(KotlinBundle.message("replace.size.check.with.isnotempty")) {
class ReplaceSizeCheckWithIsNotEmptyInspection : IntentionBasedInspection<KtBinaryExpression>(
ReplaceSizeCheckWithIsNotEmptyIntention::class
)
class ReplaceSizeCheckWithIsNotEmptyIntention : ReplaceSizeCheckIntention(KotlinBundle.lazyMessage("replace.size.check.with.isnotempty")) {
override fun getGenerateMethodSymbol() = "isNotEmpty()"
override fun getTargetExpression(element: KtBinaryExpression): KtExpression? {
return when (element.operationToken) {
KtTokens.EXCLEQ -> when {
element.right.isZero() -> element.left
element.left.isZero() -> element.right
else -> null
}
KtTokens.GT -> if (element.right.isZero()) element.left else null
KtTokens.LT -> if (element.left.isZero()) element.right else null
KtTokens.GTEQ -> if (element.right.isOne()) element.left else null
KtTokens.LTEQ -> if (element.left.isOne()) element.right else null
override fun getTargetExpression(element: KtBinaryExpression): KtExpression? = when (element.operationToken) {
KtTokens.EXCLEQ -> when {
element.right.isZero() -> element.left
element.left.isZero() -> element.right
else -> null
}
KtTokens.GT -> if (element.right.isZero()) element.left else null
KtTokens.LT -> if (element.left.isZero()) element.right else null
KtTokens.GTEQ -> if (element.right.isOne()) element.left else null
KtTokens.LTEQ -> if (element.left.isOne()) element.right else null
else -> null
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -23,25 +12,25 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtExpression
@Suppress("DEPRECATION")
class ReplaceSizeZeroCheckWithIsEmptyInspection :
IntentionBasedInspection<KtBinaryExpression>(ReplaceSizeZeroCheckWithIsEmptyIntention::class)
class ReplaceSizeZeroCheckWithIsEmptyIntention : ReplaceSizeCheckIntention(KotlinBundle.message("replace.size.zero.check.with.isempty")) {
class ReplaceSizeZeroCheckWithIsEmptyInspection : IntentionBasedInspection<KtBinaryExpression>(
ReplaceSizeZeroCheckWithIsEmptyIntention::class
)
class ReplaceSizeZeroCheckWithIsEmptyIntention : ReplaceSizeCheckIntention(
KotlinBundle.lazyMessage("replace.size.zero.check.with.isempty")
) {
override fun getGenerateMethodSymbol() = "isEmpty()"
override fun getTargetExpression(element: KtBinaryExpression): KtExpression? {
return when (element.operationToken) {
KtTokens.EQEQ -> when {
element.right.isZero() -> element.left
element.left.isZero() -> element.right
else -> null
}
KtTokens.GT -> if (element.left.isOne()) element.right else null
KtTokens.LT -> if (element.right.isOne()) element.left else null
KtTokens.GTEQ -> if (element.left.isZero()) element.right else null
KtTokens.LTEQ -> if (element.right.isZero()) element.left else null
override fun getTargetExpression(element: KtBinaryExpression): KtExpression? = when (element.operationToken) {
KtTokens.EQEQ -> when {
element.right.isZero() -> element.left
element.left.isZero() -> element.right
else -> null
}
KtTokens.GT -> if (element.left.isOne()) element.right else null
KtTokens.LT -> if (element.right.isOne()) element.left else null
KtTokens.GTEQ -> if (element.left.isZero()) element.right else null
KtTokens.LTEQ -> if (element.right.isZero()) element.left else null
else -> null
}
}
@@ -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.
*/
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ReplaceUnderscoreWithParameterNameIntention : SelfTargetingOffsetIndependentIntention<KtCallableDeclaration>(
KtCallableDeclaration::class.java,
KotlinBundle.message("replace.with.parameter.name")
KotlinBundle.lazyMessage("replace.with.parameter.name")
) {
override fun isApplicableTo(element: KtCallableDeclaration) =
element.name == "_" && (element is KtDestructuringDeclarationEntry || element is KtParameter)
@@ -37,12 +37,14 @@ class ReplaceUnderscoreWithParameterNameIntention : SelfTargetingOffsetIndepende
val validator = CollectingNameValidator(
filter = NewDeclarationNameValidator(element.parent.parent, null, NewDeclarationNameValidator.Target.VARIABLES)
)
val name = suggestedParameterName?.let {
KotlinNameSuggester.suggestNameByName(it, validator)
} ?: run {
val elementDescriptor = element.resolveToDescriptorIfAny() as? CallableDescriptor
elementDescriptor?.returnType?.let { KotlinNameSuggester.suggestNamesByType(it, validator).firstOrNull() }
} ?: return
element.setName(name)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 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.
*/
@@ -31,9 +31,8 @@ import org.jetbrains.kotlin.resolve.sam.getSingleAbstractMethodOrNull
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
class SamConversionToAnonymousObjectIntention : SelfTargetingRangeIntention<KtCallExpression>(
KtCallExpression::class.java, KotlinBundle.message("convert.to.anonymous.object")
KtCallExpression::class.java, KotlinBundle.lazyMessage("convert.to.anonymous.object")
), LowPriorityAction {
override fun applicabilityRange(element: KtCallExpression): TextRange? {
val callee = element.calleeExpression ?: return null
val lambda = getLambdaExpression(element) ?: return null
@@ -92,9 +91,13 @@ class SamConversionToAnonymousObjectIntention : SelfTargetingRangeIntention<KtCa
} else {
call.calleeExpression?.text
} ?: return
val typeArguments = call.typeArguments.mapNotNull { it.typeReference }
val typeArgumentsText =
if (typeArguments.isEmpty()) "" else typeArguments.joinToString(prefix = "<", postfix = ">", separator = ", ") { it.text }
val typeArgumentsText = if (typeArguments.isEmpty())
""
else
typeArguments.joinToString(prefix = "<", postfix = ">", separator = ", ") { it.text }
val classDescriptor = functionDescriptor.containingDeclaration as? ClassDescriptor
val typeParameters = classDescriptor?.declaredTypeParameters?.map { it.name.asString() }?.zip(typeArguments)?.toMap().orEmpty()
LambdaToAnonymousFunctionIntention.convertLambdaToFunction(lambda, functionDescriptor, functionName, typeParameters) {
@@ -105,9 +108,8 @@ class SamConversionToAnonymousObjectIntention : SelfTargetingRangeIntention<KtCa
}
}
fun getLambdaExpression(element: KtCallExpression): KtLambdaExpression? {
return element.lambdaArguments.firstOrNull()?.getLambdaExpression()
fun getLambdaExpression(element: KtCallExpression): KtLambdaExpression? =
element.lambdaArguments.firstOrNull()?.getLambdaExpression()
?: element.valueArguments.firstOrNull()?.getArgumentExpression() as? KtLambdaExpression
}
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -38,19 +27,14 @@ import org.jetbrains.kotlin.types.isFlexible
@Suppress("DEPRECATION")
class SimplifyBooleanWithConstantsInspection : IntentionBasedInspection<KtBinaryExpression>(SimplifyBooleanWithConstantsIntention::class)
class SimplifyBooleanWithConstantsIntention :
SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.message("simplify.boolean.expression")
) {
class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.lazyMessage("simplify.boolean.expression")
) {
override fun isApplicableTo(element: KtBinaryExpression): Boolean = areThereExpressionsToBeSimplified(element.topBinary())
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
return areThereExpressionsToBeSimplified(element.topBinary())
}
private fun KtBinaryExpression.topBinary(): KtBinaryExpression {
return this.parentsWithSelf.takeWhile { it is KtBinaryExpression }.lastOrNull() as? KtBinaryExpression ?: this
}
private fun KtBinaryExpression.topBinary(): KtBinaryExpression =
this.parentsWithSelf.takeWhile { it is KtBinaryExpression }.lastOrNull() as? KtBinaryExpression ?: this
private fun areThereExpressionsToBeSimplified(element: KtExpression?): Boolean {
if (element == null) return false
@@ -65,6 +49,7 @@ class SimplifyBooleanWithConstantsIntention :
}
}
}
return element.canBeReducedToBooleanConstant()
}
@@ -157,6 +142,7 @@ class SimplifyBooleanWithConstantsIntention :
else factory.createExpressionByPattern("!$0", it)
}
}
return toSimplifiedExpression(otherOperand)
}
@@ -167,9 +153,8 @@ class SimplifyBooleanWithConstantsIntention :
return KotlinBuiltIns.isBoolean(type) && !type.isFlexible()
}
private fun KtExpression.canBeReducedToBooleanConstant(constant: Boolean? = null): Boolean {
return CompileTimeConstantUtils.canBeReducedToBooleanConstant(this, this.analyze(PARTIAL), constant)
}
private fun KtExpression.canBeReducedToBooleanConstant(constant: Boolean? = null): Boolean =
CompileTimeConstantUtils.canBeReducedToBooleanConstant(this, this.analyze(PARTIAL), constant)
private fun KtExpression.canBeReducedToTrue() = canBeReducedToBooleanConstant(true)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -34,9 +23,8 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.isError
open class SpecifyExplicitLambdaSignatureIntention : SelfTargetingOffsetIndependentIntention<KtLambdaExpression>(
KtLambdaExpression::class.java, KotlinBundle.message("specify.explicit.lambda.signature")
KtLambdaExpression::class.java, KotlinBundle.lazyMessage("specify.explicit.lambda.signature")
), LowPriorityAction {
override fun isApplicableTo(element: KtLambdaExpression): Boolean {
if (element.functionLiteral.arrow != null && element.valueParameters.all { it.typeReference != null }) return false
val functionDescriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.FUNCTION, element.functionLiteral] ?: return false
@@ -51,19 +39,17 @@ open class SpecifyExplicitLambdaSignatureIntention : SelfTargetingOffsetIndepend
val functionLiteral = element.functionLiteral
val functionDescriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.FUNCTION, functionLiteral]!!
val parameterString = functionDescriptor.valueParameters
applyWithParameters(element, functionDescriptor.valueParameters
.asSequence()
.mapIndexed { index, parameterDescriptor ->
parameterDescriptor.render(psiName = functionLiteral.valueParameters.getOrNull(index)?.let {
it.name ?: it.destructuringDeclaration?.text
})
}
.joinToString()
applyWithParameters(element, parameterString)
.joinToString())
}
companion object {
fun KtFunctionLiteral.setParameterListIfAny(psiFactory: KtPsiFactory, newParameterList: KtParameterList?) {
val oldParameterList = valueParameterList
if (oldParameterList != null && newParameterList != null) {
@@ -77,6 +63,7 @@ open class SpecifyExplicitLambdaSignatureIntention : SelfTargetingOffsetIndepend
if (newParameterList != null) {
addAfter(newParameterList, openBraceElement)
}
if (addNewline) {
addAfter(psiFactory.createNewLine(), openBraceElement)
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2000-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.
*/
@@ -19,9 +19,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.types.isError
class SpecifyTypeExplicitlyInDestructuringAssignmentIntention : SelfTargetingRangeIntention<KtDestructuringDeclaration>(
KtDestructuringDeclaration::class.java, KotlinBundle.message("specify.all.types.explicitly.in.destructuring.declaration")
KtDestructuringDeclaration::class.java, KotlinBundle.lazyMessage("specify.all.types.explicitly.in.destructuring.declaration")
), LowPriorityAction {
override fun applicabilityRange(element: KtDestructuringDeclaration): TextRange? {
if (element.containingFile is KtCodeFragment) return null
val entries = element.noTypeReferenceEntries()
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -48,16 +37,16 @@ import org.jetbrains.kotlin.utils.ifEmpty
class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDeclaration>(
KtCallableDeclaration::class.java,
KotlinBundle.message("specify.type.explicitly")
KotlinBundle.lazyMessage("specify.type.explicitly")
), HighPriorityAction {
override fun applicabilityRange(element: KtCallableDeclaration): TextRange? {
if (!ExplicitApiDeclarationChecker.returnTypeCheckIsApplicable(element)) return null
text = if (element is KtFunction)
KotlinBundle.message("specify.return.type.explicitly")
else
KotlinBundle.message("specify.type.explicitly")
setTextGetter(
if (element is KtFunction)
KotlinBundle.lazyMessage("specify.return.type.explicitly")
else
defaultTextGetter
)
val initializer = (element as? KtDeclarationWithInitializer)?.initializer
return if (initializer != null) {
@@ -103,6 +92,7 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDec
} else {
if (!type.isFlexible()) return null
}
return type
}
@@ -114,9 +104,11 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDec
else
it.returnType
}
if (type != null && type.isError && descriptor is PropertyDescriptor) {
return descriptor.setterType ?: ErrorUtils.createErrorType("null type")
}
return type ?: ErrorUtils.createErrorType("null type")
}
@@ -145,6 +137,7 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDec
val declarationDescriptor = contextElement.resolveToDescriptorIfAny() as? CallableDescriptor
declarationDescriptor?.overriddenDescriptors?.mapNotNull { it.returnType }
} ?: emptyList()
val types = (listOf(exprType) + overriddenTypes).distinct().flatMap {
it.toResolvableApproximations()
}.ifEmpty { return null }
@@ -164,7 +157,6 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDec
val targetType = types.firstOrNull { !KotlinBuiltIns.isNothingOrNullableNothing(it) } ?: types.first()
return TypeChooseValueExpression(listOf(targetType), targetType)
}
}
return TypeChooseValueExpression(types, types.first())
@@ -186,16 +178,15 @@ class SpecifyTypeExplicitlyIntention : SelfTargetingRangeIntention<KtCallableDec
return className
}
}
return renderType
}
}
fun addTypeAnnotation(editor: Editor?, declaration: KtCallableDeclaration, exprType: KotlinType) {
if (editor != null) {
addTypeAnnotationWithTemplate(editor, declaration, exprType)
} else {
declaration.setType(exprType)
}
fun addTypeAnnotation(editor: Editor?, declaration: KtCallableDeclaration, exprType: KotlinType) = if (editor != null) {
addTypeAnnotationWithTemplate(editor, declaration, exprType)
} else {
declaration.setType(exprType)
}
@JvmOverloads
@@ -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.
*/
@@ -19,10 +19,10 @@ import org.jetbrains.kotlin.psi.createExpressionByPattern
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
class SwapStringEqualsIgnoreCaseIntention :
SelfTargetingRangeIntention<KtDotQualifiedExpression>(KtDotQualifiedExpression::class.java, KotlinBundle.message("flip.equals")),
LowPriorityAction {
class SwapStringEqualsIgnoreCaseIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
KotlinBundle.lazyMessage("flip.equals")
), LowPriorityAction {
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
val descriptor = element.getCallableDescriptor() ?: return null
@@ -47,6 +47,7 @@ class SwapStringEqualsIgnoreCaseIntention :
receiverExpression,
valueArguments[1].text
)
val replacedElement = element.replaced(newElement) as? KtDotQualifiedExpression
replacedElement?.callExpression?.calleeExpression?.startOffset?.let {
editor?.moveCaret(it + offset)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -30,7 +19,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class ToOrdinaryStringLiteralIntention : SelfTargetingOffsetIndependentIntention<KtStringTemplateExpression>(
KtStringTemplateExpression::class.java,
KotlinBundle.message("to.ordinary.string.literal")
KotlinBundle.lazyMessage("to.ordinary.string.literal")
), LowPriorityAction {
companion object {
private val TRIM_INDENT_FUNCTIONS = listOf(FqName("kotlin.text.trimIndent"), FqName("kotlin.text.trimMargin"))
@@ -56,10 +45,11 @@ class ToOrdinaryStringLiteralIntention : SelfTargetingOffsetIndependentIntention
if (it is KtLiteralStringTemplateEntry) it.text.escape() else it.text
}
}
append("\"")
}
val replaced = (trimIndentCall?.qualifiedExpression ?: element).replaced(KtPsiFactory(element).createExpression(text))
val replaced = (trimIndentCall?.qualifiedExpression ?: element).replaced(KtPsiFactory(element).createExpression(text))
val offset = when {
currentOffset - startOffset < 2 -> startOffset
endOffset - currentOffset < 2 -> replaced.endOffset
@@ -68,12 +58,10 @@ class ToOrdinaryStringLiteralIntention : SelfTargetingOffsetIndependentIntention
editor?.caretModel?.moveToOffset(offset)
}
private fun String.escape(): String {
var text = this
text = text.replace("\\", "\\\\")
text = text.replace("\"", "\\\"")
return StringUtil.convertLineSeparators(text, "\\n")
}
private fun String.escape(): String = StringUtil.convertLineSeparators(
replace("\\", "\\\\").replace("\"", "\\\""),
"\\n"
)
private fun getTrimIndentCall(
element: KtStringTemplateExpression,
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions
@@ -30,7 +19,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class ToRawStringLiteralIntention : SelfTargetingOffsetIndependentIntention<KtStringTemplateExpression>(
KtStringTemplateExpression::class.java,
KotlinBundle.message("to.raw.string.literal")
KotlinBundle.lazyMessage("to.raw.string.literal")
), LowPriorityAction {
override fun isApplicableTo(element: KtStringTemplateExpression): Boolean {
val text = element.text
@@ -59,6 +48,7 @@ class ToRawStringLiteralIntention : SelfTargetingOffsetIndependentIntention<KtSt
endOffset == currentOffset -> replaced.endOffset
else -> minOf(currentOffset + 2, replaced.endOffset)
}
editor?.caretModel?.moveToOffset(offset)
}
@@ -79,6 +69,7 @@ class ToRawStringLiteralIntention : SelfTargetingOffsetIndependentIntention<KtSt
append(value)
}
}
return StringUtilRt.convertLineSeparators(text, "\n")
}
@@ -88,6 +79,7 @@ class ToRawStringLiteralIntention : SelfTargetingOffsetIndependentIntention<KtSt
if ((c == '\n' || c == '\r') && afterSpace) return true
afterSpace = c == ' ' || c == '\t'
}
return false
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2000-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.
*/
@@ -106,7 +106,6 @@ class NotPropertiesServiceImpl(private val project: Project) : NotPropertiesServ
}
companion object {
private val atomicMethods = listOf(
"getAndIncrement", "getAndDecrement", "getAcquire", "getOpaque", "getPlain"
)
@@ -126,14 +125,11 @@ class NotPropertiesServiceImpl(private val project: Project) : NotPropertiesServ
}
}
class UsePropertyAccessSyntaxIntention :
SelfTargetingOffsetIndependentIntention<KtCallExpression>(
KtCallExpression::class.java,
KotlinBundle.message("use.property.access.syntax")
) {
override fun isApplicableTo(element: KtCallExpression): Boolean {
return detectPropertyNameToUse(element) != null
}
class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention<KtCallExpression>(
KtCallExpression::class.java,
KotlinBundle.lazyMessage("use.property.access.syntax")
) {
override fun isApplicableTo(element: KtCallExpression): Boolean = detectPropertyNameToUse(element) != null
override fun applyTo(element: KtCallExpression, editor: Editor?) {
val propertyName = detectPropertyNameToUse(element) ?: return
@@ -142,13 +138,10 @@ class UsePropertyAccessSyntaxIntention :
}
}
fun applyTo(element: KtCallExpression, propertyName: Name, reformat: Boolean): KtExpression {
val arguments = element.valueArguments
return when (arguments.size) {
0 -> replaceWithPropertyGet(element, propertyName)
1 -> replaceWithPropertySet(element, propertyName, reformat)
else -> error("More than one argument in call to accessor")
}
fun applyTo(element: KtCallExpression, propertyName: Name, reformat: Boolean): KtExpression = when (element.valueArguments.size) {
0 -> replaceWithPropertyGet(element, propertyName)
1 -> replaceWithPropertySet(element, propertyName, reformat)
else -> error("More than one argument in call to accessor")
}
fun detectPropertyNameToUse(callExpression: KtCallExpression): Name? {
@@ -195,6 +188,7 @@ class UsePropertyAccessSyntaxIntention :
val valueArgumentExpression = callExpression.valueArguments.firstOrNull()?.getArgumentExpression()?.takeUnless {
it is KtLambdaExpression || it is KtNamedFunction || it is KtCallableReferenceExpression
}
if (isSetUsage && valueArgumentExpression == null) {
return null
}
@@ -220,6 +214,7 @@ class UsePropertyAccessSyntaxIntention :
expectedType = expectedType,
isStatement = true
)
if (newBindingContext.diagnostics.any { it.severity == Severity.ERROR }) return null
}
@@ -252,6 +247,7 @@ class UsePropertyAccessSyntaxIntention :
false, facade.frontendService<LanguageVersionSettings>(),
facade.frontendService<DataFlowValueFactory>()
)
val callResolver = facade.frontendService<CallResolver>()
val result = callResolver.resolveSimpleProperty(context)
return result.isSuccess && result.resultingDescriptor.original == property
@@ -292,6 +288,7 @@ class UsePropertyAccessSyntaxIntention :
is KtSafeQualifiedExpression -> "$0?.$1=$2"
else -> error(qualifiedExpression) //TODO: make it sealed?
}
val newExpression = KtPsiFactory(callToConvert).createExpressionByPattern(
pattern,
qualifiedExpression.receiverExpression,
@@ -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.
*/
@@ -27,18 +27,15 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
class DoubleBangToIfThenIntention :
SelfTargetingRangeIntention<KtPostfixExpression>(
KtPostfixExpression::class.java,
KotlinBundle.message("replace.expression.with.if.expression")
),
LowPriorityAction {
override fun applicabilityRange(element: KtPostfixExpression): TextRange? {
return if (element.operationToken == KtTokens.EXCLEXCL && element.baseExpression != null)
class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfixExpression>(
KtPostfixExpression::class.java,
KotlinBundle.lazyMessage("replace.expression.with.if.expression")
), LowPriorityAction {
override fun applicabilityRange(element: KtPostfixExpression): TextRange? =
if (element.operationToken == KtTokens.EXCLEXCL && element.baseExpression != null)
element.operationReference.textRange
else
null
}
override fun applyTo(element: KtPostfixExpression, editor: Editor?) {
if (editor == null) throw IllegalArgumentException("This intention requires an editor")
@@ -62,8 +59,7 @@ class DoubleBangToIfThenIntention :
(qualifiedExpressionForReceiver ?: element).convertToIfNotNullExpression(base, thenClause, defaultException)
}
val thrownExpression =
((if (isStatement) ifStatement.then else ifStatement.`else`) as KtThrowExpression).thrownExpression!!
val thrownExpression = ((if (isStatement) ifStatement.then else ifStatement.`else`) as KtThrowExpression).thrownExpression ?: return
val message = StringUtil.escapeStringCharacters("Expression '$expressionText' must not be null")
val nullPtrExceptionText = "NullPointerException(\"$message\")"
val kotlinNullPtrExceptionText = "KotlinNullPointerException()"
@@ -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.
*/
@@ -22,18 +22,15 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.TypeUtils
class ElvisToIfThenIntention :
SelfTargetingRangeIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.message("replace.elvis.expression.with.if.expression")
),
LowPriorityAction {
override fun applicabilityRange(element: KtBinaryExpression): TextRange? {
return if (element.operationToken == KtTokens.ELVIS && element.left != null && element.right != null)
class ElvisToIfThenIntention : SelfTargetingRangeIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.lazyMessage("replace.elvis.expression.with.if.expression")
), LowPriorityAction {
override fun applicabilityRange(element: KtBinaryExpression): TextRange? =
if (element.operationToken == KtTokens.ELVIS && element.left != null && element.right != null)
element.operationReference.textRange
else
null
}
private fun KtExpression.findSafeCastReceiver(context: BindingContext): KtBinaryExpressionWithTypeRHS? {
var current = this
@@ -45,10 +42,10 @@ class ElvisToIfThenIntention :
}
current = current.receiverExpression
}
current = KtPsiUtil.safeDeparenthesize(current)
return (current as? KtBinaryExpressionWithTypeRHS)?.takeIf {
it.operationReference.getReferencedNameElementType() === KtTokens.AS_SAFE &&
it.right != null
it.operationReference.getReferencedNameElementType() === KtTokens.AS_SAFE && it.right != null
}
}
@@ -57,9 +54,7 @@ class ElvisToIfThenIntention :
newReceiver: KtExpression,
topLevel: Boolean = true
): KtExpression {
if (this !is KtQualifiedExpression) {
return newReceiver
}
if (this !is KtQualifiedExpression) return newReceiver
return factory.buildExpression(reformat = topLevel) {
appendExpression(receiverExpression.buildExpressionWithReplacedReceiver(factory, newReceiver, topLevel = false))
appendFixedText(".")
@@ -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.
*/
@@ -12,8 +12,10 @@ import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFoldingUtils
import org.jetbrains.kotlin.psi.*
class FoldIfToReturnAsymmetricallyIntention :
SelfTargetingRangeIntention<KtIfExpression>(KtIfExpression::class.java, KotlinBundle.message("replace.if.expression.with.return")) {
class FoldIfToReturnAsymmetricallyIntention : SelfTargetingRangeIntention<KtIfExpression>(
KtIfExpression::class.java,
KotlinBundle.lazyMessage("replace.if.expression.with.return")
) {
override fun applicabilityRange(element: KtIfExpression): TextRange? {
if (BranchedFoldingUtils.getFoldableBranchedReturn(element.then) == null || element.`else` != null) {
return null
@@ -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.
*/
@@ -14,12 +14,11 @@ import org.jetbrains.kotlin.psi.KtIfExpression
class FoldIfToReturnIntention : SelfTargetingRangeIntention<KtIfExpression>(
KtIfExpression::class.java,
KotlinBundle.message("lift.return.out.of.if.expression")
KotlinBundle.lazyMessage("lift.return.out.of.if.expression")
) {
override fun applicabilityRange(element: KtIfExpression): TextRange? {
return if (BranchedFoldingUtils.canFoldToReturn(element)) element.ifKeyword.textRange else null
}
override fun applicabilityRange(element: KtIfExpression): TextRange? =
if (BranchedFoldingUtils.canFoldToReturn(element)) element.ifKeyword.textRange else null
override fun applyTo(element: KtIfExpression, editor: Editor?) {
BranchedFoldingUtils.foldToReturn(element)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
@@ -37,24 +26,23 @@ import java.util.*
class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(
KtIfExpression::class.java,
KotlinBundle.message("replace.if.with.when")
KotlinBundle.lazyMessage("replace.if.with.when")
) {
override fun applicabilityRange(element: KtIfExpression): TextRange? {
if (element.then == null) return null
return element.ifKeyword.textRange
}
private fun canPassThrough(expression: KtExpression?): Boolean =
when (expression) {
is KtReturnExpression, is KtThrowExpression ->
false
is KtBlockExpression ->
expression.statements.all { canPassThrough(it) }
is KtIfExpression ->
canPassThrough(expression.then) || canPassThrough(expression.`else`)
else ->
true
}
private fun canPassThrough(expression: KtExpression?): Boolean = when (expression) {
is KtReturnExpression, is KtThrowExpression ->
false
is KtBlockExpression ->
expression.statements.all { canPassThrough(it) }
is KtIfExpression ->
canPassThrough(expression.then) || canPassThrough(expression.`else`)
else ->
true
}
private fun buildNextBranch(ifExpression: KtIfExpression): KtExpression? {
var nextSibling = ifExpression.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
@@ -83,6 +71,7 @@ class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(
}
nextSibling = nextSibling.nextSibling
}
return result
}
@@ -94,7 +83,6 @@ class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(
}
var labelRequired = false
fun KtExpressionWithLabel.addLabelIfNecessary(): KtExpressionWithLabel {
if (this.getLabelName() != null) return this
if (this.getStrictParentOfType<KtLoopExpression>() != nearestLoopIfAny) return this
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
@@ -37,7 +26,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class SafeAccessToIfThenIntention : SelfTargetingRangeIntention<KtSafeQualifiedExpression>(
KtSafeQualifiedExpression::class.java,
KotlinBundle.message("replace.safe.access.expression.with.if.expression")
KotlinBundle.lazyMessage("replace.safe.access.expression.with.if.expression")
), LowPriorityAction {
override fun applicabilityRange(element: KtSafeQualifiedExpression): TextRange? {
if (element.selectorExpression == null) return null
@@ -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.
*/
@@ -17,12 +17,10 @@ import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class UnfoldAssignmentToIfIntention :
SelfTargetingRangeIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.message("replace.assignment.with.if.expression")
),
LowPriorityAction {
class UnfoldAssignmentToIfIntention : SelfTargetingRangeIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.lazyMessage("replace.assignment.with.if.expression")
), LowPriorityAction {
override fun applicabilityRange(element: KtBinaryExpression): TextRange? {
if (element.operationToken !in KtTokens.ALL_ASSIGNMENTS) return null
if (element.left == null) return null
@@ -30,7 +28,5 @@ class UnfoldAssignmentToIfIntention :
return TextRange(element.startOffset, right.ifKeyword.endOffset)
}
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
BranchedUnfoldingUtils.unfoldAssignmentToIf(element, editor)
}
override fun applyTo(element: KtBinaryExpression, editor: Editor?) = BranchedUnfoldingUtils.unfoldAssignmentToIf(element, editor)
}
@@ -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.
*/
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class UnfoldAssignmentToWhenIntention :
SelfTargetingRangeIntention<KtBinaryExpression>(
KtBinaryExpression::class.java,
KotlinBundle.message("replace.assignment.with.when.expression")
KotlinBundle.lazyMessage("replace.assignment.with.when.expression")
),
LowPriorityAction {
override fun applicabilityRange(element: KtBinaryExpression): TextRange? {
@@ -33,7 +33,5 @@ class UnfoldAssignmentToWhenIntention :
return TextRange(element.startOffset, right.whenKeyword.endOffset)
}
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
BranchedUnfoldingUtils.unfoldAssignmentToWhen(element, editor)
}
override fun applyTo(element: KtBinaryExpression, editor: Editor?) = BranchedUnfoldingUtils.unfoldAssignmentToWhen(element, editor)
}
@@ -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.
*/
@@ -17,12 +17,10 @@ import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class UnfoldPropertyToIfIntention :
SelfTargetingRangeIntention<KtProperty>(
KtProperty::class.java,
KotlinBundle.message("replace.property.initializer.with.if.expression")
),
LowPriorityAction {
class UnfoldPropertyToIfIntention : SelfTargetingRangeIntention<KtProperty>(
KtProperty::class.java,
KotlinBundle.lazyMessage("replace.property.initializer.with.if.expression")
), LowPriorityAction {
override fun applicabilityRange(element: KtProperty): TextRange? {
if (!element.isLocal) return null
val initializer = element.initializer as? KtIfExpression ?: return null
@@ -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.
*/
@@ -18,12 +18,10 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class UnfoldPropertyToWhenIntention :
SelfTargetingRangeIntention<KtProperty>(
KtProperty::class.java,
KotlinBundle.message("replace.property.initializer.with.when.expression")
),
LowPriorityAction {
class UnfoldPropertyToWhenIntention : SelfTargetingRangeIntention<KtProperty>(
KtProperty::class.java,
KotlinBundle.lazyMessage("replace.property.initializer.with.when.expression")
), LowPriorityAction {
override fun applicabilityRange(element: KtProperty): TextRange? {
if (!element.isLocal) return null
val initializer = element.initializer as? KtWhenExpression ?: return null
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
@@ -32,7 +21,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.types.typeUtil.isNothing
class UnfoldReturnToIfIntention : LowPriorityAction, SelfTargetingRangeIntention<KtReturnExpression>(
KtReturnExpression::class.java, KotlinBundle.message("replace.return.with.if.expression")
KtReturnExpression::class.java, KotlinBundle.lazyMessage("replace.return.with.if.expression")
) {
override fun applicabilityRange(element: KtReturnExpression): TextRange? {
val ifExpression = element.returnedExpression as? KtIfExpression ?: return null
@@ -69,6 +58,7 @@ class UnfoldReturnToIfIntention : LowPriorityAction, SelfTargetingRangeIntention
is KtBreakExpression, is KtContinueExpression, is KtReturnExpression, is KtThrowExpression -> ""
else -> if (expr.getResolvedCall(context)?.resultingDescriptor?.returnType?.isNothing() == true) "" else "return$label "
}
return psiFactory.createExpressionByPattern("$returnText$0", expr)
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
@@ -32,7 +21,7 @@ import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class UnfoldReturnToWhenIntention : LowPriorityAction, SelfTargetingRangeIntention<KtReturnExpression>(
KtReturnExpression::class.java, KotlinBundle.message("replace.return.with.when.expression")
KtReturnExpression::class.java, KotlinBundle.lazyMessage("replace.return.with.when.expression")
) {
override fun applicabilityRange(element: KtReturnExpression): TextRange? {
val whenExpr = element.returnedExpression as? KtWhenExpression ?: return null
@@ -47,13 +36,13 @@ class UnfoldReturnToWhenIntention : LowPriorityAction, SelfTargetingRangeIntenti
val whenExpression = element.returnedExpression as KtWhenExpression
val newWhenExpression = whenExpression.copied()
val labelName = element.getLabelName()
whenExpression.entries.zip(newWhenExpression.entries).forEach { (entry, newEntry) ->
val expr = entry.expression!!.lastBlockStatementOrThis()
val newExpr = newEntry.expression!!.lastBlockStatementOrThis()
newExpr.replace(UnfoldReturnToIfIntention.createReturnExpression(expr, labelName, psiFactory, context))
}
element.replace(newWhenExpression)
}
}
@@ -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.
*/
@@ -16,9 +16,8 @@ import org.jetbrains.kotlin.psi.*
class WhenToIfIntention : SelfTargetingRangeIntention<KtWhenExpression>(
KtWhenExpression::class.java,
KotlinBundle.message("replace.when.with.if")
),
LowPriorityAction {
KotlinBundle.lazyMessage("replace.when.with.if")
), LowPriorityAction {
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
val entries = element.entries
if (entries.isEmpty()) return null
@@ -50,11 +49,13 @@ class WhenToIfIntention : SelfTargetingRangeIntention<KtWhenExpression>(
if (branch is KtIfExpression) {
appendFixedText("{ ")
}
appendExpression(branch)
if (branch is KtIfExpression) {
appendFixedText(" }")
}
}
if (i != entries.lastIndex) {
appendFixedText("\n")
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions.conventionNameCalls
@@ -31,24 +20,22 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.createExpressionByPattern
import org.jetbrains.kotlin.types.expressions.OperatorConventions
class ReplaceCallWithUnaryOperatorIntention :
SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
KotlinBundle.message("replace.call.with.unary.operator")
),
HighPriorityAction {
class ReplaceCallWithUnaryOperatorIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
KotlinBundle.lazyMessage("replace.call.with.unary.operator")
), HighPriorityAction {
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
val operation = operation(element.calleeName) ?: return null
if (!isApplicableOperation(operation)) return null
val call = element.callExpression ?: return null
if (call.typeArgumentList != null) return null
if (!call.valueArguments.isEmpty()) return null
if (call.valueArguments.isNotEmpty()) return null
if (!element.isReceiverExpressionWithValue()) return null
text = KotlinBundle.message("replace.with.0.operator", operation.value)
return call.calleeExpression!!.textRange
setTextGetter(KotlinBundle.lazyMessage("replace.with.0.operator", operation.value))
return call.calleeExpression?.textRange
}
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
@@ -59,6 +46,7 @@ class ReplaceCallWithUnaryOperatorIntention :
private fun isApplicableOperation(operation: KtSingleValueToken): Boolean = operation !in OperatorConventions.INCREMENT_OPERATIONS
private fun operation(functionName: String?): KtSingleValueToken? =
functionName?.let { OperatorConventions.UNARY_OPERATION_NAMES.inverse()[Name.identifier(it)] }
private fun operation(functionName: String?): KtSingleValueToken? = functionName?.let {
OperatorConventions.UNARY_OPERATION_NAMES.inverse()[Name.identifier(it)]
}
}
@@ -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.
*/
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.util.OperatorNameConventions
class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java, KotlinBundle.message("replace.contains.call.with.in.operator")
KtDotQualifiedExpression::class.java, KotlinBundle.lazyMessage("replace.contains.call.with.in.operator")
), HighPriorityAction {
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
if (element.calleeName != OperatorNameConventions.CONTAINS.asString()) return null
@@ -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.
*/
@@ -16,21 +16,19 @@ import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.util.OperatorNameConventions
class ReplaceInvokeIntention :
SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
KotlinBundle.message("replace.invoke.with.direct.call")
),
HighPriorityAction {
class ReplaceInvokeIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
KotlinBundle.lazyMessage("replace.invoke.with.direct.call")
), HighPriorityAction {
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
if (element.calleeName != OperatorNameConventions.INVOKE.asString() || element.callExpression?.typeArgumentList != null) return null
return element.callExpression!!.calleeExpression!!.textRange
return element.callExpression?.calleeExpression?.textRange
}
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
val receiver = element.receiverExpression
val callExpression = element.callExpression!!.copy() as KtCallExpression
callExpression.calleeExpression!!.replace(receiver)
val callExpression = element.callExpression?.copy() as? KtCallExpression ?: return
callExpression.calleeExpression?.replace(receiver)
element.replace(callExpression)
}
}
@@ -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.
*/
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.psi.KtBinaryExpression
import java.awt.datatransfer.StringSelection
class CopyConcatenatedStringToClipboardIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
KtBinaryExpression::class.java, KotlinBundle.message("copy.concatenation.text.to.clipboard")
KtBinaryExpression::class.java, KotlinBundle.lazyMessage("copy.concatenation.text.to.clipboard")
) {
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
val text = ConcatenatedStringGenerator().create(element)
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.intentions.declarations
@@ -51,12 +40,10 @@ import org.jetbrains.kotlin.utils.addIfNotNull
private val LOG = Logger.getInstance(ConvertMemberToExtensionIntention::class.java)
class ConvertMemberToExtensionIntention :
SelfTargetingRangeIntention<KtCallableDeclaration>(
KtCallableDeclaration::class.java,
KotlinBundle.message("convert.member.to.extension")
),
LowPriorityAction {
class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallableDeclaration>(
KtCallableDeclaration::class.java,
KotlinBundle.lazyMessage("convert.member.to.extension")
), LowPriorityAction {
private fun isApplicable(element: KtCallableDeclaration): Boolean {
val classBody = element.parent as? KtClassBody ?: return false
if (classBody.parent !is KtClass) return false
@@ -66,6 +53,7 @@ class ConvertMemberToExtensionIntention :
is KtProperty -> if (element.hasInitializer()) return false
is KtSecondaryConstructor -> return false
}
return true
}
@@ -314,6 +302,7 @@ class ConvertMemberToExtensionIntention :
if (classVisibility != null && extension.visibilityModifier() == null) {
extension.addModifier(classVisibility)
}
return extension to bodyTypeToSelect
}
@@ -327,8 +316,7 @@ class ConvertMemberToExtensionIntention :
}
companion object {
fun convert(element: KtCallableDeclaration): KtCallableDeclaration {
return ConvertMemberToExtensionIntention().createExtensionCallableAndPrepareBodyToSelect(element).first
}
fun convert(element: KtCallableDeclaration): KtCallableDeclaration =
ConvertMemberToExtensionIntention().createExtensionCallableAndPrepareBodyToSelect(element).first
}
}
@@ -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.
*/
@@ -12,15 +12,13 @@ import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.intentions.splitPropertyDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtWhenEntry
import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.psi.psiUtil.startOffset
class SplitPropertyDeclarationIntention : SelfTargetingRangeIntention<KtProperty>(
KtProperty::class.java,
KotlinBundle.message("split.property.declaration")
),
LowPriorityAction {
KotlinBundle.lazyMessage("split.property.declaration")
), LowPriorityAction {
override fun applicabilityRange(element: KtProperty): TextRange? {
if (!element.isLocal || element.parent is KtWhenExpression) return null
val initializer = element.initializer ?: return null
@@ -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.
*/
@@ -83,30 +83,35 @@ class LoopToCallChainInspection : AbstractKotlinInspection() {
class LoopToCallChainIntention : AbstractLoopToCallChainIntention(
lazy = false,
text = KotlinBundle.message("replace.with.stdlib.operations")
textGetter = KotlinBundle.lazyMessage("replace.with.stdlib.operations")
)
class LoopToLazyCallChainIntention : AbstractLoopToCallChainIntention(
lazy = true,
text = KotlinBundle.message("replace.with.stdlib.operations.with.use.of.assequence")
textGetter = KotlinBundle.lazyMessage("replace.with.stdlib.operations.with.use.of.assequence")
)
abstract class AbstractLoopToCallChainIntention(
private val lazy: Boolean,
text: String
textGetter: () -> String
) : SelfTargetingRangeIntention<KtForExpression>(
KtForExpression::class.java,
text
textGetter
) {
override fun applicabilityRange(element: KtForExpression): TextRange? {
val match = match(element, lazy, false)
text = if (match != null) KotlinBundle.message("replace.with.0", match.transformationMatch.buildPresentation()) else defaultText
setTextGetter(
if (match != null)
KotlinBundle.lazyMessage("replace.with.0", match.transformationMatch.buildPresentation())
else
defaultTextGetter
)
return if (match != null) element.forKeyword.textRange else null
}
private fun TransformationMatch.Result.buildPresentation(): String {
return buildPresentation(sequenceTransformations + resultTransformation, null)
}
private fun TransformationMatch.Result.buildPresentation(): String =
buildPresentation(sequenceTransformations + resultTransformation, null)
private fun buildPresentation(transformations: List<Transformation>, prevPresentation: String?): String {
if (transformations.size > MAX) {
@@ -121,12 +126,11 @@ abstract class AbstractLoopToCallChainIntention(
for (transformation in transformations) {
result = transformation.buildPresentation(result)
}
return result!!
}
override fun applyTo(element: KtForExpression, editor: Editor?) {
LoopToCallChainInspection.Fix(lazy).applyFix(element, editor)
}
override fun applyTo(element: KtForExpression, editor: Editor?) = LoopToCallChainInspection.Fix(lazy).applyFix(element, editor)
companion object {
const val MAX = 3
@@ -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.
*/
@@ -20,11 +20,10 @@ class UseWithIndexInspection : IntentionBasedInspection<KtForExpression>(UseWith
class UseWithIndexIntention : SelfTargetingRangeIntention<KtForExpression>(
KtForExpression::class.java,
KotlinBundle.message("use.withindex.instead.of.manual.index.increment")
KotlinBundle.lazyMessage("use.withindex.instead.of.manual.index.increment")
) {
override fun applicabilityRange(element: KtForExpression): TextRange? {
return if (matchIndexToIntroduce(element, reformat = false) != null) element.forKeyword.textRange else null
}
override fun applicabilityRange(element: KtForExpression): TextRange? =
if (matchIndexToIntroduce(element, reformat = false) != null) element.forKeyword.textRange else null
override fun applyTo(element: KtForExpression, editor: Editor?) {
val (indexVariable, initializationStatement, incrementExpression) = matchIndexToIntroduce(element, reformat = true)!!
@@ -25,10 +25,10 @@ import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.usageView.UsageInfo
import com.intellij.usageView.UsageViewBundle
import com.intellij.usageView.UsageViewDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.codeInliner.UsageReplacementStrategy
import org.jetbrains.kotlin.idea.codeInliner.replaceUsages
import org.jetbrains.kotlin.idea.findUsages.ReferencesSearchScopeHelper
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.refactoring.pullUp.deleteWithCompanion
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.util.application.runReadAction
@@ -54,7 +54,8 @@ class KotlinInlineCallableProcessor(
else -> KotlinBundle.message("text.declaration")
}
private val commandName = KotlinBundle.message("text.inlining.0.1",
private val commandName = KotlinBundle.message(
"text.inlining.0.1",
kind,
DescriptiveNameUtil.getDescriptiveName(declaration)
)
@@ -84,7 +85,8 @@ class KotlinInlineCallableProcessor(
CommonRefactoringUtil.showErrorHint(
declaration.project,
null,
KotlinBundle.message("text.cannot.inline.0.1.usages",
KotlinBundle.message(
"text.cannot.inline.0.1.usages",
usages.size - simpleNameUsages.size,
usages.size
),
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* 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.
*/
package org.jetbrains.kotlin.idea.refactoring.move.changePackage
@@ -33,11 +22,10 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.psi.KtPackageDirective
class ChangePackageIntention :
SelfTargetingOffsetIndependentIntention<KtPackageDirective>(
KtPackageDirective::class.java,
KotlinBundle.message("intention.change.package.text")
) {
class ChangePackageIntention : SelfTargetingOffsetIndependentIntention<KtPackageDirective>(
KtPackageDirective::class.java,
KotlinBundle.lazyMessage("intention.change.package.text")
) {
companion object {
private const val PACKAGE_NAME_VAR = "PACKAGE_NAME"
}
@@ -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.
*/
@@ -39,13 +39,10 @@ import org.jetbrains.kotlin.resolve.source.getPsi
private const val TIMEOUT_FOR_IMPORT_OPTIMIZING_MS: Long = 700L
class ExtractDeclarationFromCurrentFileIntention :
SelfTargetingRangeIntention<KtClassOrObject>(
KtClassOrObject::class.java,
KotlinBundle.message("intention.extract.declarations.from.file.text")
),
LowPriorityAction {
class ExtractDeclarationFromCurrentFileIntention : SelfTargetingRangeIntention<KtClassOrObject>(
KtClassOrObject::class.java,
KotlinBundle.lazyMessage("intention.extract.declarations.from.file.text")
), LowPriorityAction {
private fun KtClassOrObject.tryGetExtraClassesToMove(): List<KtNamedDeclaration>? {
val descriptor = resolveToDescriptorIfAny() ?: return null
@@ -71,10 +68,12 @@ class ExtractDeclarationFromCurrentFileIntention :
val endOffset = element.nameIdentifier?.endOffset ?: return null
text = KotlinBundle.message(
"intention.extract.declarations.from.file.text.details",
element.name.toString(),
extraClassesToMove.size
setTextGetter(
KotlinBundle.lazyMessage(
"intention.extract.declarations.from.file.text.details",
element.name.toString(),
extraClassesToMove.size
)
)
return TextRange(startOffset, endOffset)
@@ -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.
*/
@@ -43,7 +43,7 @@ import java.util.*
class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtNamedDeclaration>(
KtNamedDeclaration::class.java,
KotlinBundle.message("create.test")
KotlinBundle.lazyMessage("create.test")
) {
override fun applicabilityRange(element: KtNamedDeclaration): TextRange? {
if (element.hasExpectModifier() || element.nameIdentifier == null) return null