diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/intentions/SelfTargetingIntention.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/intentions/SelfTargetingIntention.kt index c7b8dc44c20..814ee9e4481 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/intentions/SelfTargetingIntention.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/intentions/SelfTargetingIntention.kt @@ -29,7 +29,6 @@ abstract class SelfTargetingIntention( @Nls private var textGetter: () -> String, @Nls private val familyNameGetter: () -> String = textGetter, ) : IntentionAction { - @Deprecated("Replace with primary constructor", ReplaceWith("SelfTargetingIntention(elementType, { text }, { familyName })")) constructor( elementType: Class, @@ -38,7 +37,7 @@ abstract class SelfTargetingIntention( ) : 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( val commonParent = if (leaf1 != null && leaf2 != null) PsiTreeUtil.findCommonParent(leaf1, leaf2) else null var elementsToCheck: Sequence = 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( @Nls familyNameGetter: () -> String = textGetter, ) : SelfTargetingIntention(elementType, textGetter, familyNameGetter) { - @Deprecated("Replace with primary constructor", ReplaceWith("SelfTargetingRangeIntention(elementType, { text }, { familyName })")) + @Deprecated( + "Replace with primary constructor", + ReplaceWith("SelfTargetingRangeIntention(elementType, { text }, { familyName })") + ) constructor( elementType: Class, @Nls text: String, diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveSuspiciousCallableReferenceIntoParenthesesInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveSuspiciousCallableReferenceIntoParenthesesInspection.kt index 8f02279422a..95d2f1532bd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MoveSuspiciousCallableReferenceIntoParenthesesInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MoveSuspiciousCallableReferenceIntoParenthesesInspection.kt @@ -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}" } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddNamesToCallArgumentsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddNamesToCallArgumentsIntention.kt index f1e176481ff..16aecccdb88 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AddNamesToCallArgumentsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AddNamesToCallArgumentsIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt index 86931199327..ea1d6e5ee81 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AddValVarToConstructorParameterAction.kt @@ -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::class.java, actionFamily), - AddValVarToConstructorParameterAction { + class Intention : SelfTargetingRangeIntention( + 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()?.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(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) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AnonymousFunctionToLambdaIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AnonymousFunctionToLambdaIntention.kt index 9d056b615e5..71d5c04929d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/AnonymousFunctionToLambdaIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AnonymousFunctionToLambdaIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt index e4f006d5ae1..ef5502e9d7d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ChangeVisibilityModifierIntention.kt @@ -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::class.java, KotlinBundle.message("make.0", modifier.value)) { +open class ChangeVisibilityModifierIntention protected constructor(val modifier: KtModifierKeywordToken) : + SelfTargetingRangeIntention(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 } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt index aa9bbaf75e5..6cdb7ccab50 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt @@ -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( - private val listClass: Class, + listClass: Class, private val elementClass: Class, - text: String -) : SelfTargetingOffsetIndependentIntention(listClass, text) { - + textGetter: () -> String +) : SelfTargetingOffsetIndependentIntention(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 { - return allChildren - .filter { elementClass.isInstance(it) } - .map { - @Suppress("UNCHECKED_CAST") - it as TElement - } - .toList() - } + protected fun TList.elements(): List = allChildren.filter { elementClass.isInstance(it) } + .map { + @Suppress("UNCHECKED_CAST") + it as TElement + } + .toList() } class ChopParameterListIntention : AbstractChopListIntention( 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( KtValueArgumentList::class.java, KtValueArgument::class.java, - KotlinBundle.message("put.arguments.on.separate.lines") + KotlinBundle.lazyMessage("put.arguments.on.separate.lines") ) \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertArrayParameterToVarargIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertArrayParameterToVarargIntention.kt index b5fa276a92e..52f1e71eccd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertArrayParameterToVarargIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertArrayParameterToVarargIntention.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getChildOfType class ConvertArrayParameterToVarargIntention : SelfTargetingIntention( - 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() ?: return false @@ -25,7 +25,7 @@ class ConvertArrayParameterToVarargIntention : SelfTargetingIntention { - setTextGetter(DEFAULT_TEXT) + setTextGetter(defaultTextGetter) true } KotlinBuiltIns.isArray(type) -> { @@ -33,12 +33,15 @@ class ConvertArrayParameterToVarargIntention : SelfTargetingIntention String get() = KotlinBundle.lazyMessage("convert.to.vararg.parameter") - - private val BREAKING_TEXT: () -> String get() = { KotlinBundle.message("0.may.break.code", DEFAULT_TEXT()) } - } - } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertBinaryExpressionWithDemorgansLawIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertBinaryExpressionWithDemorgansLawIntention.kt index aa9e1984427..c9be836abdd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertBinaryExpressionWithDemorgansLawIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertBinaryExpressionWithDemorgansLawIntention.kt @@ -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::class.java, KotlinBundle.message("demorgan.law")) { +class ConvertBinaryExpressionWithDemorgansLawIntention : SelfTargetingOffsetIndependentIntention( + 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) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertEnumToSealedClassIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertEnumToSealedClassIntention.kt index f3e9e9ff97f..5fcabfb0732 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertEnumToSealedClassIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertEnumToSealedClassIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertForEachToForLoopIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertForEachToForLoopIntention.kt index a71810327d2..0609cb5a660 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertForEachToForLoopIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertForEachToForLoopIntention.kt @@ -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::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" diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt index 2b7bcc9e3d1..c2ff03d4f98 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeParameterToReceiverIntention.kt @@ -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::class.java, - KotlinBundle.message("convert.function.type.parameter.to.receiver") + KotlinBundle.lazyMessage("convert.function.type.parameter.to.receiver") ) { class FunctionDefinitionInfo(element: KtFunction) : AbstractProcessableUsageInfo(element) { override fun process(data: ConversionData, elementsToShorten: MutableList) { @@ -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 } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt index d7e70c3488e..5a828c09e0f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertFunctionTypeReceiverToParameterIntention.kt @@ -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::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 } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt index f1e1efc9b4a..eb25b1cc18b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt @@ -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(ConvertLambdaToReferenceIntention::class) -open class ConvertLambdaToReferenceIntention(text: String) : - SelfTargetingOffsetIndependentIntention(KtLambdaExpression::class.java, text) { - +open class ConvertLambdaToReferenceIntention(textGetter: () -> String) : SelfTargetingOffsetIndependentIntention( + 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 -> { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt index 10b2b04ace0..1b2ffd0b793 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertObjectLiteralToClassIntention.kt @@ -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::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()?.takeIf { it.text == "// TARGET_BLOCK:" } + val target = containers.firstOrNull { it == targetComment?.parent } ?: containers.last() return doApply(editor, element, target) } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyInitializerToGetterIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyInitializerToGetterIntention.kt index edfa9d7578a..8ece60bcd21 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyInitializerToGetterIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertPropertyInitializerToGetterIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertRangeCheckToTwoComparisonsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertRangeCheckToTwoComparisonsIntention.kt index c2193f6b6e8..eef244372ce 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertRangeCheckToTwoComparisonsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertRangeCheckToTwoComparisonsIntention.kt @@ -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::class.java, - KotlinBundle.message("convert.to.comparisons") + KotlinBundle.lazyMessage("convert.to.comparisons") ) { private fun KtExpression?.isSimple() = this is KtConstantExpression || this is KtNameReferenceExpression diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReceiverToParameterIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReceiverToParameterIntention.kt index 2d8c197c9e0..0573dd9faf3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReceiverToParameterIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReceiverToParameterIntention.kt @@ -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::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::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) = true } - } override fun startInWriteAction() = false diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt index 0a9a8da99e6..7469e885483 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt @@ -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(ConvertReferenceToLambdaIntention::class) class ConvertReferenceToLambdaIntention : SelfTargetingOffsetIndependentIntention( - 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 } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt index da7aeff1716..282f2bf5904 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSealedClassToEnumIntention.kt @@ -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::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( } 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( 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) { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt index 6bd6237d257..dec834668d3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertSecondaryConstructorToPrimaryIntention.kt @@ -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::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 = 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 } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTestFunctionToSpacedIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTestFunctionToSpacedIntention.kt index 4fe1e52e069..20a124ea51f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTestFunctionToSpacedIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTestFunctionToSpacedIntention.kt @@ -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::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() 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToConcatenatedStringIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToConcatenatedStringIntention.kt index d4a4d65bf97..2ceba826e9d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToConcatenatedStringIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToConcatenatedStringIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt index 8cddfa00d4f..eea56c1d6ae 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt @@ -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( 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 -> { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTryFinallyToUseCallIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTryFinallyToUseCallIntention.kt index ddc6a5dd7a9..bfa688a70bf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTryFinallyToUseCallIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertTryFinallyToUseCallIntention.kt @@ -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( - 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 result else -> return } + val lambda = call.lambdaArguments.firstOrNull() ?: return val lambdaParameter = lambda.getLambdaExpression()?.valueParameters?.firstOrNull() ?: return editor?.selectionModel?.setSelection(lambdaParameter.startOffset, lambdaParameter.endOffset) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/CreateKotlinSubClassIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/CreateKotlinSubClassIntention.kt index 760ad033c27..1d87ba653db 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/CreateKotlinSubClassIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/CreateKotlinSubClassIntention.kt @@ -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::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( 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt index 5702738ef38..dbb84538d46 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/DestructureIntention.kt @@ -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( class DestructureIntention : SelfTargetingRangeIntention( 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() val underscoreSupported = element.languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName) // For all unused we generate normal names, not underscores @@ -373,6 +373,7 @@ class DestructureIntention : SelfTargetingRangeIntention( name = name ?: newData.declarationToDrop?.name declarationToDrop = declarationToDrop ?: newData.declarationToDrop } + newData.usageToReplace?.let { usagesToReplace.add(it) } return true } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt index 545fc9d7e72..27e84b8c542 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt @@ -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::class.java, "", KotlinBundle.message("implement.abstract.member")) { +abstract class ImplementAbstractMemberIntentionBase : SelfTargetingRangeIntention( + 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 { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ImportMemberIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ImportMemberIntention.kt index ba910921c00..176abe18857 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ImportMemberIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ImportMemberIntention.kt @@ -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::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( - 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/InsertCurlyBracesToTemplateIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/InsertCurlyBracesToTemplateIntention.kt index 88dd4d1f1d8..e41f1cb29b2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/InsertCurlyBracesToTemplateIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/InsertCurlyBracesToTemplateIntention.kt @@ -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::class.java, KotlinBundle.message("insert.curly.braces.around.variable") - ), - LowPriorityAction { +class InsertCurlyBracesToTemplateIntention : SelfTargetingOffsetIndependentIntention( + KtSimpleNameStringTemplateEntry::class.java, KotlinBundle.lazyMessage("insert.curly.braces.around.variable") +), LowPriorityAction { override fun isApplicableTo(element: KtSimpleNameStringTemplateEntry): Boolean = true diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/InsertExplicitTypeArgumentsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/InsertExplicitTypeArgumentsIntention.kt index 5246b884890..659f45cd464 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/InsertExplicitTypeArgumentsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/InsertExplicitTypeArgumentsIntention.kt @@ -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::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::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) { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceImportAliasIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceImportAliasIntention.kt index c0346d81a32..a06955002f0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceImportAliasIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceImportAliasIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceVariableIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceVariableIntention.kt index bc05b703627..ab2529a65b0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceVariableIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/IntroduceVariableIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt index f09bd2b28e2..8c19de5dd9b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt @@ -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( 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 { child -> + private fun hasNoLocalDependencies(element: KtElement, localContext: PsiElement): Boolean = + !element.anyDescendantOfType { child -> child.resolveAllReferences().any { it != null && PsiTreeUtil.isAncestor(localContext, it, false) } } - } } -private fun PsiElement.resolveAllReferences(): Sequence { - return PsiReferenceService.getService().getReferences(this, PsiReferenceService.Hints.NO_HINTS) +private fun PsiElement.resolveAllReferences(): Sequence = + PsiReferenceService.getService().getReferences(this, PsiReferenceService.Hints.NO_HINTS) .asSequence() .map { it.resolve() } -} diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/JoinParameterListIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/JoinParameterListIntention.kt index 6051e8dbe3b..926c52eb75a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/JoinParameterListIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/JoinParameterListIntention.kt @@ -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( listClass: Class, elementClass: Class, - text: String -) : AbstractChopListIntention(listClass, elementClass, text) { - + textGetter: () -> String +) : AbstractChopListIntention(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( 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( KtValueArgumentList::class.java, KtValueArgument::class.java, - KotlinBundle.message("put.arguments.on.one.line") + KotlinBundle.lazyMessage("put.arguments.on.one.line") ) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfCompanionObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfCompanionObjectIntention.kt index b8e260db226..5d31d354c70 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfCompanionObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfCompanionObjectIntention.kt @@ -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) { - - val targetClass = element.containingClassOrObject!!.containingClassOrObject!! + val targetClass = element.containingClassOrObject?.containingClassOrObject ?: return val targetClassDescriptor = runReadAction { targetClass.unsafeResolveToDescriptor() as ClassDescriptor } val refsRequiringClassInstance = diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt index bfd31d640aa..7809c0f55ae 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberOutOfObjectIntention.kt @@ -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::class.java, text) { +abstract class MoveMemberOutOfObjectIntention(textGetter: () -> String) : SelfTargetingRangeIntention( + 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 { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt index 7d797464cc1..da9c930196f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt @@ -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::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) { val packageViewDescriptor = element.findModuleDescriptor().getPackage(element.containingKtFile.packageFqName) val packageDescriptor = packageViewDescriptor.fragments.firstIsInstance() @@ -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 } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt index b4bd253b6e3..653a20a914e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ObjectLiteralToLambdaIntention.kt @@ -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( 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt index 09acc5e1fad..82c16bf31a1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReconstructTypeInCastOrIsIntention.kt @@ -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::class.java, - KotlinBundle.message("replace.by.reconstructed.type") - ), - LowPriorityAction { +class ReconstructTypeInCastOrIsIntention : SelfTargetingOffsetIndependentIntention( + 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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt index e007143289a..284cb507f7c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.resolve.calls.components.isVararg class RemoveArgumentNameIntention : SelfTargetingRangeIntention( 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 .map { psiFactory.createArgument(it) } .reversed() .forEach { argumentList.addArgumentAfter(it, element) } + argumentList.removeArgument(element) } else { val newArgument = psiFactory.createArgument(argumentExpr, null, element.getSpreadElement() != null) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyClassBodyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyClassBodyIntention.kt index bbf304a5bbd..0dda5bf5b46 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyClassBodyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyClassBodyIntention.kt @@ -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(RemoveEmptyClassBodyIntention::class), CleanupLocalInspectionTool { - override fun problemHighlightType(element: KtClassBody): ProblemHighlightType = - ProblemHighlightType.LIKE_UNUSED_SYMBOL +class RemoveEmptyClassBodyInspection : IntentionBasedInspection(RemoveEmptyClassBodyIntention::class), + CleanupLocalInspectionTool { + override fun problemHighlightType(element: KtClassBody): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL } -class RemoveEmptyClassBodyIntention : - SelfTargetingOffsetIndependentIntention(KtClassBody::class.java, KotlinBundle.message("redundant.empty.class.body")) { - +class RemoveEmptyClassBodyIntention : SelfTargetingOffsetIndependentIntention( + KtClassBody::class.java, + KotlinBundle.lazyMessage("redundant.empty.class.body") +) { override fun applyTo(element: KtClassBody, editor: Editor?) { val parent = element.parent element.delete() diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyParenthesesFromLambdaCallIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyParenthesesFromLambdaCallIntention.kt index 9b5c6cc35ab..beb51dfae92 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyParenthesesFromLambdaCallIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyParenthesesFromLambdaCallIntention.kt @@ -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( 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::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() } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyPrimaryConstructorIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyPrimaryConstructorIntention.kt index fa87b34cdcf..716fe71be0d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyPrimaryConstructorIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptyPrimaryConstructorIntention.kt @@ -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( - KtPrimaryConstructor::class.java, - KotlinBundle.message("remove.empty.primary.constructor") - ) { +class RemoveEmptyPrimaryConstructorIntention : SelfTargetingOffsetIndependentIntention( + KtPrimaryConstructor::class.java, + KotlinBundle.lazyMessage("remove.empty.primary.constructor") +) { override fun applyTo(element: KtPrimaryConstructor, editor: Editor?) = element.delete() diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptySecondaryConstructorBodyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptySecondaryConstructorBodyIntention.kt index c3b4945d9cb..24784ca1641 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptySecondaryConstructorBodyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveEmptySecondaryConstructorBodyIntention.kt @@ -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( 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::class.java, - KotlinBundle.message("remove.empty.constructor.body") - ) { - +class RemoveEmptySecondaryConstructorBodyIntention : SelfTargetingOffsetIndependentIntention( + KtBlockExpression::class.java, + KotlinBundle.lazyMessage("remove.empty.constructor.body") +) { override fun applyTo(element: KtBlockExpression, editor: Editor?) = element.delete() override fun isApplicableTo(element: KtBlockExpression): Boolean { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt index 024b32baaed..16d9eaddafc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitSuperQualifierIntention.kt @@ -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( 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::class.java, - KotlinBundle.message("remove.explicit.supertype.qualification") - ) { +class RemoveExplicitSuperQualifierIntention : SelfTargetingRangeIntention( + 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeArgumentsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeArgumentsIntention.kt index 972d8583267..c72e467c993 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeArgumentsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeArgumentsIntention.kt @@ -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(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::class.java, - KotlinBundle.message("remove.explicit.type.arguments") - ) { +class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndependentIntention( + 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() } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt index 8df6bd13a73..7f241c3cca0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt @@ -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::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) { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveForLoopIndicesIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveForLoopIndicesIntention.kt index db7d27afff7..b99d67bf279 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveForLoopIndicesIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveForLoopIndicesIntention.kt @@ -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 override fun problemHighlightType(element: KtForExpression): ProblemHighlightType = ProblemHighlightType.LIKE_UNUSED_SYMBOL } -class RemoveForLoopIndicesIntention : - SelfTargetingRangeIntention(KtForExpression::class.java, KotlinBundle.message("remove.indices.in.for.loop")) { +class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention( + KtForExpression::class.java, + KotlinBundle.lazyMessage("remove.indices.in.for.loop") +) { private val WITH_INDEX_NAME = "withIndex" private val WITH_INDEX_FQ_NAMES: Set by lazy { sequenceOf("collections", "sequences", "text", "ranges").map { "kotlin.$it.$WITH_INDEX_NAME" }.toSet() diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt index 15f41bf77bb..c1bf9ba9a64 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveRedundantCallsOfConversionMethodsIntention.kt @@ -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::class.java, - KotlinBundle.message("remove.redundant.calls.of.the.conversion.method") + KotlinBundle.lazyMessage("remove.redundant.calls.of.the.conversion.method") ) { private val targetClassMap: Map 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 } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveSingleExpressionStringTemplateIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveSingleExpressionStringTemplateIntention.kt index ebaf209dcaa..084e853e816 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveSingleExpressionStringTemplateIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveSingleExpressionStringTemplateIntention.kt @@ -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( RemoveSingleExpressionStringTemplateIntention::class, @@ -32,10 +31,9 @@ class RemoveSingleExpressionStringTemplateInspection : IntentionBasedInspection< class RemoveSingleExpressionStringTemplateIntention : SelfTargetingOffsetIndependentIntention( 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) } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveUnnecessaryParenthesesIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveUnnecessaryParenthesesIntention.kt index 71b1b18d9cb..8c1ac6ff6df 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveUnnecessaryParenthesesIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveUnnecessaryParenthesesIntention.kt @@ -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::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( - 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( - KtClassOrObject::class.java, "", - KotlinBundle.message("rename.file.to.match.top.level.class.name") - ) { +class RenameFileToMatchClassIntention : SelfTargetingRangeIntention( + 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 } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceAddWithPlusAssignIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceAddWithPlusAssignIntention.kt index a00577385f0..686ee5e797d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceAddWithPlusAssignIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceAddWithPlusAssignIntention.kt @@ -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::class.java, - KotlinBundle.message("replace.with1") + KotlinBundle.lazyMessage("replace.with1") ) { private val compatibleNames: Set 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 { diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt index ba3c5a470bc..59afa0434f7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt @@ -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::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() diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceMapGetOrDefaultIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceMapGetOrDefaultIntention.kt index 2d5c7040369..deaf835035a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceMapGetOrDefaultIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceMapGetOrDefaultIntention.kt @@ -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::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()?.leftBracket?.startOffset?.let { editor?.caretModel?.moveToOffset(it) } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckIntention.kt index 180f1cf2e29..58eb32c2f50 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckIntention.kt @@ -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::class.java, text +abstract class ReplaceSizeCheckIntention(textGetter: () -> String) : SelfTargetingOffsetIndependentIntention( + KtBinaryExpression::class.java, textGetter ) { - override fun applyTo(element: KtBinaryExpression, editor: Editor?) { val target = getTargetExpression(element) if (target !is KtDotQualifiedExpression) return diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckWithIsNotEmptyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckWithIsNotEmptyIntention.kt index a2342da83b5..5aa6a8576f3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckWithIsNotEmptyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeCheckWithIsNotEmptyIntention.kt @@ -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(ReplaceSizeCheckWithIsNotEmptyIntention::class) - -class ReplaceSizeCheckWithIsNotEmptyIntention : ReplaceSizeCheckIntention(KotlinBundle.message("replace.size.check.with.isnotempty")) { +class ReplaceSizeCheckWithIsNotEmptyInspection : IntentionBasedInspection( + 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 } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeZeroCheckWithIsEmptyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeZeroCheckWithIsEmptyIntention.kt index ee6be19c35f..e20d54b9641 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeZeroCheckWithIsEmptyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceSizeZeroCheckWithIsEmptyIntention.kt @@ -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(ReplaceSizeZeroCheckWithIsEmptyIntention::class) - -class ReplaceSizeZeroCheckWithIsEmptyIntention : ReplaceSizeCheckIntention(KotlinBundle.message("replace.size.zero.check.with.isempty")) { +class ReplaceSizeZeroCheckWithIsEmptyInspection : IntentionBasedInspection( + 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 } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceUnderscoreWithParameterNameIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceUnderscoreWithParameterNameIntention.kt index ebb1b05bc23..66c7707a2fa 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceUnderscoreWithParameterNameIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceUnderscoreWithParameterNameIntention.kt @@ -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::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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SamConversionToAnonymousObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SamConversionToAnonymousObjectIntention.kt index c0edec37075..a39bfb28325 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/SamConversionToAnonymousObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/SamConversionToAnonymousObjectIntention.kt @@ -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::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(SimplifyBooleanWithConstantsIntention::class) -class SimplifyBooleanWithConstantsIntention : - SelfTargetingOffsetIndependentIntention( - KtBinaryExpression::class.java, - KotlinBundle.message("simplify.boolean.expression") - ) { +class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentIntention( + 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) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt index 9f115dc60d3..297105eebd1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyExplicitLambdaSignatureIntention.kt @@ -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::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) } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyInDestructuringAssignmentIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyInDestructuringAssignmentIntention.kt index 77acbeaa615..9f3962b7886 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyInDestructuringAssignmentIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyInDestructuringAssignmentIntention.kt @@ -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::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() diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt index 71a0311517a..44f442b979e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/SpecifyTypeExplicitlyIntention.kt @@ -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::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(KtDotQualifiedExpression::class.java, KotlinBundle.message("flip.equals")), - LowPriorityAction { - +class SwapStringEqualsIgnoreCaseIntention : SelfTargetingRangeIntention( + 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) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt index 96a2159e0b1..3857abc18a0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt @@ -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::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, diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt index c03b9c72c55..48be05b9877 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ToRawStringLiteralIntention.kt @@ -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::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 replaced.endOffset else -> minOf(currentOffset + 2, replaced.endOffset) } + editor?.caretModel?.moveToOffset(offset) } @@ -79,6 +69,7 @@ class ToRawStringLiteralIntention : SelfTargetingOffsetIndependentIntention( - KtCallExpression::class.java, - KotlinBundle.message("use.property.access.syntax") - ) { - override fun isApplicableTo(element: KtCallExpression): Boolean { - return detectPropertyNameToUse(element) != null - } +class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention( + 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(), facade.frontendService() ) + val callResolver = facade.frontendService() 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, diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/DoubleBangToIfThenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/DoubleBangToIfThenIntention.kt index 6a43c9f3d6e..b622d4513c8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/DoubleBangToIfThenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/DoubleBangToIfThenIntention.kt @@ -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::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::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()" diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt index cb94751f7d0..baa15251169 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/ElvisToIfThenIntention.kt @@ -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::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::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(".") diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.kt index db206790d55..0ada9ca109f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.kt @@ -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::class.java, KotlinBundle.message("replace.if.expression.with.return")) { +class FoldIfToReturnAsymmetricallyIntention : SelfTargetingRangeIntention( + 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnIntention.kt index 4263ce2ae6f..4325ccb2fa6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/FoldIfToReturnIntention.kt @@ -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::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) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt index e2429c5621e..792166638d0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/IfToWhenIntention.kt @@ -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::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( } nextSibling = nextSibling.nextSibling } + return result } @@ -94,7 +83,6 @@ class IfToWhenIntention : SelfTargetingRangeIntention( } var labelRequired = false - fun KtExpressionWithLabel.addLabelIfNecessary(): KtExpressionWithLabel { if (this.getLabelName() != null) return this if (this.getStrictParentOfType() != nearestLoopIfAny) return this diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/SafeAccessToIfThenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/SafeAccessToIfThenIntention.kt index 424fb364f29..e8c087df816 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/SafeAccessToIfThenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/SafeAccessToIfThenIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.kt index 9606fa0c1e7..b980eccc9ff 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.kt @@ -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::class.java, - KotlinBundle.message("replace.assignment.with.if.expression") - ), - LowPriorityAction { +class UnfoldAssignmentToIfIntention : SelfTargetingRangeIntention( + 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) } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.kt index 453b551e74b..f648080ce5a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.kt @@ -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::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) } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToIfIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToIfIntention.kt index f645f489b9d..16ed56d8070 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToIfIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToIfIntention.kt @@ -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::class.java, - KotlinBundle.message("replace.property.initializer.with.if.expression") - ), - LowPriorityAction { +class UnfoldPropertyToIfIntention : SelfTargetingRangeIntention( + 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToWhenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToWhenIntention.kt index dc84ee6bbf1..bfbed6d04c8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToWhenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldPropertyToWhenIntention.kt @@ -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::class.java, - KotlinBundle.message("replace.property.initializer.with.when.expression") - ), - LowPriorityAction { +class UnfoldPropertyToWhenIntention : SelfTargetingRangeIntention( + 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToIfIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToIfIntention.kt index 09fd4fe10c4..f4c29459da2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToIfIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToIfIntention.kt @@ -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::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) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToWhenIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToWhenIntention.kt index c1c474e05b6..b0d45315404 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToWhenIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/UnfoldReturnToWhenIntention.kt @@ -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::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) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/WhenToIfIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/WhenToIfIntention.kt index 0ec76e373be..fe5f8799377 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/WhenToIfIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/intentions/WhenToIfIntention.kt @@ -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::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( if (branch is KtIfExpression) { appendFixedText("{ ") } + appendExpression(branch) if (branch is KtIfExpression) { appendFixedText(" }") } } + if (i != entries.lastIndex) { appendFixedText("\n") } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceCallWithUnaryOperatorIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceCallWithUnaryOperatorIntention.kt index 86ec3defe10..4bf3b256f72 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceCallWithUnaryOperatorIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceCallWithUnaryOperatorIntention.kt @@ -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::class.java, - KotlinBundle.message("replace.call.with.unary.operator") - ), - HighPriorityAction { +class ReplaceCallWithUnaryOperatorIntention : SelfTargetingRangeIntention( + 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)] + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceContainsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceContainsIntention.kt index cd67c4122cb..a7546458e45 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceContainsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceContainsIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceInvokeIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceInvokeIntention.kt index 4029663d06e..a4002c49876 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceInvokeIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/conventionNameCalls/ReplaceInvokeIntention.kt @@ -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::class.java, - KotlinBundle.message("replace.invoke.with.direct.call") - ), - HighPriorityAction { +class ReplaceInvokeIntention : SelfTargetingRangeIntention( + 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) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/copyConcatenatedStringToClipboard/CopyConcatenatedStringToClipboardIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/copyConcatenatedStringToClipboard/CopyConcatenatedStringToClipboardIntention.kt index 852b906f489..09d91e59899 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/copyConcatenatedStringToClipboard/CopyConcatenatedStringToClipboardIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/copyConcatenatedStringToClipboard/CopyConcatenatedStringToClipboardIntention.kt @@ -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::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) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/ConvertMemberToExtensionIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/ConvertMemberToExtensionIntention.kt index b88b7ccf1c1..a4011ee863d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/ConvertMemberToExtensionIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/ConvertMemberToExtensionIntention.kt @@ -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::class.java, - KotlinBundle.message("convert.member.to.extension") - ), - LowPriorityAction { +class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention( + 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 } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/SplitPropertyDeclarationIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/SplitPropertyDeclarationIntention.kt index 0accb661078..743de91f1db 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/SplitPropertyDeclarationIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/declarations/SplitPropertyDeclarationIntention.kt @@ -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::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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/LoopToCallChainInspection.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/LoopToCallChainInspection.kt index 2b3cc6767b9..866e4f81ea1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/LoopToCallChainInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/LoopToCallChainInspection.kt @@ -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::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, 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 diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/UseWithIndexIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/UseWithIndexIntention.kt index 55159d7f741..d799140434d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/UseWithIndexIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/UseWithIndexIntention.kt @@ -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(UseWith class UseWithIndexIntention : SelfTargetingRangeIntention( 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)!! diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineCallableProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineCallableProcessor.kt index b56a405341d..8435e35f815 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineCallableProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineCallableProcessor.kt @@ -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 ), diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/ChangePackageIntention.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/ChangePackageIntention.kt index 3e5c16461bb..daf6e7100c9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/ChangePackageIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/changePackage/ChangePackageIntention.kt @@ -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::class.java, - KotlinBundle.message("intention.change.package.text") - ) { +class ChangePackageIntention : SelfTargetingOffsetIndependentIntention( + KtPackageDirective::class.java, + KotlinBundle.lazyMessage("intention.change.package.text") +) { companion object { private const val PACKAGE_NAME_VAR = "PACKAGE_NAME" } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt index 469bde2d3ac..6b12ec6c8fd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/move/moveDeclarations/ExtractDeclarationFromCurrentFileIntention.kt @@ -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::class.java, - KotlinBundle.message("intention.extract.declarations.from.file.text") - ), - LowPriorityAction { - +class ExtractDeclarationFromCurrentFileIntention : SelfTargetingRangeIntention( + KtClassOrObject::class.java, + KotlinBundle.lazyMessage("intention.extract.declarations.from.file.text") +), LowPriorityAction { private fun KtClassOrObject.tryGetExtraClassesToMove(): List? { 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) diff --git a/idea/src/org/jetbrains/kotlin/idea/testIntegration/KotlinCreateTestIntention.kt b/idea/src/org/jetbrains/kotlin/idea/testIntegration/KotlinCreateTestIntention.kt index d82932e1d92..b1c725a3756 100644 --- a/idea/src/org/jetbrains/kotlin/idea/testIntegration/KotlinCreateTestIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/testIntegration/KotlinCreateTestIntention.kt @@ -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::class.java, - KotlinBundle.message("create.test") + KotlinBundle.lazyMessage("create.test") ) { override fun applicabilityRange(element: KtNamedDeclaration): TextRange? { if (element.hasExpectModifier() || element.nameIdentifier == null) return null