Minor: clean up some quickfixes & refactorings

This commit is contained in:
Dmitry Gridin
2019-07-05 15:12:46 +07:00
parent 9ba7907b81
commit 795dcfa8ff
6 changed files with 269 additions and 329 deletions
@@ -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-2019 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.quickfix
@@ -25,7 +14,8 @@ import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
class RemoveUselessCastFix(element: KtBinaryExpressionWithTypeRHS) : KotlinQuickFixAction<KtBinaryExpressionWithTypeRHS>(element), CleanupFix {
class RemoveUselessCastFix(element: KtBinaryExpressionWithTypeRHS) : KotlinQuickFixAction<KtBinaryExpressionWithTypeRHS>(element),
CleanupFix {
override fun getFamilyName() = "Remove useless cast"
override fun getText(): String = familyName
@@ -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-2019 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.quickfix.replaceWith
@@ -51,9 +40,7 @@ class DeprecatedSymbolUsageInWholeProjectFix(
replacementStrategy.replaceUsagesInWholeProject(psiElement, progressTitle = "Applying '$text'", commandName = text)
}
private fun targetPsiElement(): KtDeclaration? {
val referenceTarget = element?.mainReference?.resolve()
return when (referenceTarget) {
private fun targetPsiElement(): KtDeclaration? = when (val referenceTarget = element?.mainReference?.resolve()) {
is KtNamedFunction -> referenceTarget
is KtProperty -> referenceTarget
is KtTypeAlias -> referenceTarget
@@ -61,7 +48,6 @@ class DeprecatedSymbolUsageInWholeProjectFix(
is KtClass -> referenceTarget.takeIf { it.isAnnotation() }
else -> null
}
}
companion object : KotlinSingleIntentionActionFactory() {
//TODO: better rendering needed
@@ -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-2019 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
@@ -43,7 +32,8 @@ abstract class AbstractPullPushMembersHandler(
CommonRefactoringUtil.showErrorHint(project, editor, message, refactoringName, helpId)
}
private fun KtParameter.getContainingClass() = if (hasValOrVar()) (ownerFunction as? KtPrimaryConstructor)?.containingClassOrObject else null
private fun KtParameter.getContainingClass() =
if (hasValOrVar()) (ownerFunction as? KtPrimaryConstructor)?.containingClassOrObject else null
protected fun reportWrongContext(project: Project, editor: Editor?) {
val message = RefactoringBundle.getCannotRefactorMessage(
@@ -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-2019 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.introduce.introduceParameter
@@ -81,8 +70,7 @@ data class IntroduceParameterDescriptor(
val newArgumentValue: KtExpression by lazy {
if (argumentValue.mustBeParenthesizedInInitializerPosition()) {
KtPsiFactory(callable).createExpressionByPattern("($0)", argumentValue)
}
else {
} else {
argumentValue
}
}
@@ -95,7 +83,7 @@ data class IntroduceParameterDescriptor(
valVar = if (callable is KtClass) {
val modifierIsUnnecessary: (PsiElement) -> Boolean = {
when {
it.parent != callable.getBody() ->
it.parent != callable.body ->
false
it is KtAnonymousInitializer ->
true
@@ -106,10 +94,9 @@ data class IntroduceParameterDescriptor(
}
}
if (occurrencesToReplace.all {
PsiTreeUtil.findCommonParent(it.elements)?.parentsWithSelf?.any(modifierIsUnnecessary) ?: false
PsiTreeUtil.findCommonParent(it.elements)?.parentsWithSelf?.any(modifierIsUnnecessary) == true
}) KotlinValVar.None else KotlinValVar.Val
}
else KotlinValVar.None
} else KotlinValVar.None
}
}
@@ -150,11 +137,13 @@ fun IntroduceParameterDescriptor.performRefactoring(onExit: (() -> Unit)? = null
}
val defaultValue = if (newArgumentValue is KtProperty) (newArgumentValue as KtProperty).initializer else newArgumentValue
val parameterInfo = KotlinParameterInfo(callableDescriptor = callableDescriptor,
val parameterInfo = KotlinParameterInfo(
callableDescriptor = callableDescriptor,
name = newParameterName,
defaultValueForCall = if (withDefaultValue) null else defaultValue,
defaultValueForParameter = if (withDefaultValue) defaultValue else null,
valOrVar = valVar)
valOrVar = valVar
)
parameterInfo.currentTypeInfo = KotlinTypeInfo(false, null, newParameterTypeText)
methodDescriptor.addParameter(parameterInfo)
}
@@ -228,8 +217,7 @@ open class KotlinIntroduceParameterHandler(
val expressionType = if (physicalExpression is KtProperty && physicalExpression.isLocal) {
context[BindingContext.VARIABLE, physicalExpression]?.type
}
else {
} else {
expression.extractableSubstringInfo?.type ?: context.getType(physicalExpression)
}
@@ -249,11 +237,14 @@ open class KotlinIntroduceParameterHandler(
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, targetParent]
val functionDescriptor = descriptor.toFunctionDescriptor(targetParent)
val replacementType = expressionType.approximateWithResolvableType(targetParent.getResolutionScope(context, targetParent.getResolutionFacade()), false)
val replacementType = expressionType.approximateWithResolvableType(
targetParent.getResolutionScope(context, targetParent.getResolutionFacade()),
false
)
val body = when (targetParent) {
is KtFunction -> targetParent.bodyExpression
is KtClass -> targetParent.getBody()
is KtClass -> targetParent.body
else -> null
}
val bodyValidator: ((String) -> Boolean)? =
@@ -277,18 +268,16 @@ open class KotlinIntroduceParameterHandler(
val occurrencesToReplace = if (expression is KtProperty) {
ReferencesSearch.search(expression).mapNotNullTo(SmartList(expression.toRange())) { it.element.toRange() }
}
else {
} else {
expression.toRange()
.match(targetParent, KotlinPsiUnifier.DEFAULT)
.asSequence()
.filterNot {
val textRange = it.range.getPhysicalTextRange()
forbiddenRanges.any { it.intersects(textRange) }
forbiddenRanges.any { range -> range.intersects(textRange) }
}
.mapNotNull {
val matchedElement = it.range.elements.singleOrNull()
val matchedExpr = when (matchedElement) {
val matchedExpr = when (val matchedElement = it.range.elements.singleOrNull()) {
is KtExpression -> matchedElement
is KtStringTemplateEntryWithExpression -> matchedElement.expression
else -> null
@@ -303,8 +292,8 @@ open class KotlinIntroduceParameterHandler(
null,
fun() {
val isTestMode = ApplicationManager.getApplication().isUnitTestMode
val haveLambdaArgumentsToReplace = occurrencesToReplace.any {
it.elements.any { it is KtLambdaExpression && it.parent is KtLambdaArgument }
val haveLambdaArgumentsToReplace = occurrencesToReplace.any { range ->
range.elements.any { it is KtLambdaExpression && it.parent is KtLambdaArgument }
}
val inplaceIsAvailable = editor.settings.isVariableInplaceRenameEnabled
&& !isTestMode
@@ -355,11 +344,13 @@ open class KotlinIntroduceParameterHandler(
doPostponedOperationsAndUnblockDocument(editor.document)
}
val introducer = KotlinInplaceParameterIntroducer(introduceParameterDescriptor,
val introducer = KotlinInplaceParameterIntroducer(
introduceParameterDescriptor,
replacementType,
suggestedNames.toTypedArray(),
project,
editor)
editor
)
if (introducer.startInplaceIntroduceTemplate()) return
}
@@ -398,8 +389,7 @@ open class KotlinIntroduceParameterHandler(
val expression = ((elements.singleOrNull() as? KtBlockExpression)?.statements ?: elements).singleOrNull()
if (expression is KtExpression) {
invoke(project, editor, expression, targetParent as KtNamedDeclaration)
}
else {
} else {
showErrorHintByKey(project, editor, "cannot.refactor.no.expression", INTRODUCE_PARAMETER)
}
}
@@ -430,7 +420,7 @@ private fun findInternalUsagesOfParametersAndReceiver(
targetParent.getValueParameters()
.filter { !it.hasValOrVar() }
.forEach {
val paramUsages = ReferencesSearch.search(it).map { it.element as KtElement }
val paramUsages = ReferencesSearch.search(it).map { reference -> reference.element as KtElement }
if (paramUsages.isNotEmpty()) {
usages.put(it, paramUsages)
}
@@ -456,7 +446,8 @@ private fun findInternalUsagesOfParametersAndReceiver(
val resolvedCall = element.resolveToCall() ?: return
if ((resolvedCall.extensionReceiver as? ImplicitReceiver)?.declarationDescriptor == targetDescriptor ||
(resolvedCall.dispatchReceiver as? ImplicitReceiver)?.declarationDescriptor == targetDescriptor) {
(resolvedCall.dispatchReceiver as? ImplicitReceiver)?.declarationDescriptor == targetDescriptor
) {
usages.putValue(receiverTypeRef, resolvedCall.call.callElement)
}
}
@@ -517,8 +508,7 @@ open class KotlinIntroduceLambdaParameterHandler(
val dialog = createDialog(project, editor, lambdaExtractionDescriptor) ?: return
if (ApplicationManager.getApplication()!!.isUnitTestMode) {
dialog.performRefactoring()
}
else {
} else {
dialog.showWithTransaction()
}
}
@@ -528,19 +518,21 @@ open class KotlinIntroduceLambdaParameterHandler(
val duplicateContainer =
when (targetParent) {
is KtFunction -> targetParent.bodyExpression
is KtClass -> targetParent.getBody()
is KtClass -> targetParent.body
else -> null
} ?: throw AssertionError("Body element is not found: ${targetParent.getElementTextWithContext()}")
val extractionData = ExtractionData(targetParent.containingKtFile,
val extractionData = ExtractionData(
targetParent.containingKtFile,
expression.toRange(),
targetParent,
duplicateContainer,
ExtractionOptions.DEFAULT)
ExtractionOptions.DEFAULT
)
ExtractionEngine(extractLambdaHelper).run(editor, extractionData)
}
}
val INTRODUCE_PARAMETER_REFACTORING_ID: String = "kotlin.refactoring.introduceParameter"
const val INTRODUCE_PARAMETER_REFACTORING_ID: String = "kotlin.refactoring.introduceParameter"
val INTRODUCE_PARAMETER: String = "Introduce Parameter"
val INTRODUCE_LAMBDA_PARAMETER: String = "Introduce Lambda Parameter"
const val INTRODUCE_PARAMETER: String = "Introduce Parameter"
const val INTRODUCE_LAMBDA_PARAMETER: String = "Introduce Lambda Parameter"
@@ -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-2019 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.pullUp
@@ -21,7 +10,6 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiNamedElement
import com.intellij.refactoring.HelpID
@@ -49,7 +37,7 @@ class KotlinPullUpHandler : AbstractPullPushMembersHandler(
wrongPositionMessage = RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.pull.members.from")
) {
companion object {
val PULL_UP_TEST_HELPER_KEY = "PULL_UP_TEST_HELPER_KEY"
const val PULL_UP_TEST_HELPER_KEY = "PULL_UP_TEST_HELPER_KEY"
}
interface TestHelper {
@@ -59,17 +47,21 @@ class KotlinPullUpHandler : AbstractPullPushMembersHandler(
private fun reportNoSuperClasses(project: Project, editor: Editor?, classOrObject: KtClassOrObject) {
val message = RefactoringBundle.getCannotRefactorMessage(
RefactoringBundle.message("class.does.not.have.base.classes.interfaces.in.current.project",
classOrObject.qualifiedClassNameForRendering())
RefactoringBundle.message(
"class.does.not.have.base.classes.interfaces.in.current.project",
classOrObject.qualifiedClassNameForRendering()
)
)
CommonRefactoringUtil.showErrorHint(project, editor, message, PULL_MEMBERS_UP, HelpID.MEMBERS_PULL_UP)
}
override fun invoke(project: Project,
override fun invoke(
project: Project,
editor: Editor?,
classOrObject: KtClassOrObject?,
member: KtNamedDeclaration?,
dataContext: DataContext?) {
dataContext: DataContext?
) {
if (classOrObject == null) {
reportWrongContext(project, editor)
return
@@ -80,9 +72,12 @@ class KotlinPullUpHandler : AbstractPullPushMembersHandler(
.supertypes()
.mapNotNull {
val descriptor = it.constructor.declarationDescriptor
val declaration = descriptor?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
val declaration = descriptor?.let { classifierDescriptor ->
DescriptorToSourceUtilsIde.getAnyDeclaration(project, classifierDescriptor)
}
if ((declaration is KtClass || declaration is PsiClass)
&& declaration.canRefactor()) declaration as PsiNamedElement else null
&& declaration.canRefactor()
) declaration as PsiNamedElement else null
}
.sortedBy { it.qualifiedClassNameForRendering() }
@@ -90,8 +85,7 @@ class KotlinPullUpHandler : AbstractPullPushMembersHandler(
val containingClass = classOrObject.getStrictParentOfType<KtClassOrObject>()
if (containingClass != null) {
invoke(project, editor, containingClass, classOrObject, dataContext)
}
else {
} else {
reportNoSuperClasses(project, editor, classOrObject)
}
return
@@ -107,8 +101,7 @@ class KotlinPullUpHandler : AbstractPullPushMembersHandler(
checkConflicts(project, classOrObject, targetClass, selectedMembers) {
KotlinPullUpDialog.createProcessor(classOrObject, targetClass, selectedMembers).run()
}
}
else {
} else {
val manager = classOrObject.manager
members.filter { manager.areElementsEquivalent(it.member, member) }.forEach { it.isChecked = true }
@@ -122,4 +115,4 @@ class KotlinPullUpHandler : AbstractPullPushMembersHandler(
}
}
val PULL_MEMBERS_UP = "Pull Members Up"
const val PULL_MEMBERS_UP = "Pull Members Up"
@@ -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-2019 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.pushDown
@@ -20,7 +9,6 @@ import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.refactoring.HelpID
@@ -39,7 +27,7 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtParameter
val PUSH_MEMBERS_DOWN = "Push Members Down"
const val PUSH_MEMBERS_DOWN = "Push Members Down"
class KotlinPushDownHandler : AbstractPullPushMembersHandler(
refactoringName = PUSH_MEMBERS_DOWN,
@@ -47,7 +35,7 @@ class KotlinPushDownHandler : AbstractPullPushMembersHandler(
wrongPositionMessage = RefactoringBundle.message("the.caret.should.be.positioned.inside.a.class.to.push.members.from")
) {
companion object {
val PUSH_DOWN_TEST_HELPER_KEY = "PUSH_DOWN_TEST_HELPER_KEY"
const val PUSH_DOWN_TEST_HELPER_KEY = "PUSH_DOWN_TEST_HELPER_KEY"
}
interface TestHelper {
@@ -61,11 +49,13 @@ class KotlinPushDownHandler : AbstractPullPushMembersHandler(
CommonRefactoringUtil.showErrorHint(project, editor, message, PULL_MEMBERS_UP, HelpID.MEMBERS_PULL_UP)
}
override fun invoke(project: Project,
override fun invoke(
project: Project,
editor: Editor?,
classOrObject: KtClassOrObject?,
member: KtNamedDeclaration?,
dataContext: DataContext?) {
dataContext: DataContext?
) {
if (classOrObject == null) {
reportWrongContext(project, editor)
return
@@ -81,8 +71,7 @@ class KotlinPushDownHandler : AbstractPullPushMembersHandler(
val helper = dataContext?.getData(PUSH_DOWN_TEST_HELPER_KEY) as TestHelper
val selectedMembers = helper.adjustMembers(members)
KotlinPushDownProcessor(project, classOrObject, selectedMembers).run()
}
else {
} else {
val manager = PsiManager.getInstance(project)
members.filter { manager.areElementsEquivalent(it.member, member) }.forEach { it.isChecked = true }
KotlinPushDownDialog(project, members, classOrObject).show()