Minor code simplifications

This commit is contained in:
Valentin Kipyatkov
2015-09-04 19:09:51 +03:00
parent 955a0c2281
commit 720dad5207
3 changed files with 29 additions and 47 deletions
@@ -200,7 +200,6 @@ change.function.signature.action.multiple=Change function signature...
change.function.signature.family=Change function signature change.function.signature.family=Change function signature
change.function.signature.chooser.title=Choose signature change.function.signature.chooser.title=Choose signature
change.function.signature.action=Change function signature change.function.signature.action=Change function signature
add.name.to.parameter.name.chooser.title=Choose parameter name
replace.java.class.argument=Replace javaClass<T>() with T::class replace.java.class.argument=Replace javaClass<T>() with T::class
replace.java.class.argument.family=Replace javaClass<T>() with T::class replace.java.class.argument.family=Replace javaClass<T>() with T::class
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.idea.quickfix package org.jetbrains.kotlin.idea.quickfix
import com.google.common.collect.Lists
import com.intellij.codeInsight.intention.IntentionAction import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.popup.JBPopupFactory import com.intellij.openapi.ui.popup.JBPopupFactory
@@ -27,26 +24,27 @@ import com.intellij.openapi.ui.popup.ListPopupStep
import com.intellij.openapi.ui.popup.PopupStep import com.intellij.openapi.ui.popup.PopupStep
import com.intellij.openapi.ui.popup.util.BaseListPopupStep import com.intellij.openapi.ui.popup.util.BaseListPopupStep
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.idea.JetIcons import org.jetbrains.kotlin.idea.JetIcons
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetCallElement import org.jetbrains.kotlin.psi.JetCallElement
import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.psi.JetValueArgument import org.jetbrains.kotlin.psi.JetValueArgument
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.types.checker.JetTypeChecker
import java.util.*
public class AddNameToArgumentFix(argument: JetValueArgument, private val possibleNames: List<String>) : JetIntentionAction<JetValueArgument>(argument) { public class AddNameToArgumentFix(argument: JetValueArgument, private val possibleNames: List<String>) : JetIntentionAction<JetValueArgument>(argument) {
override fun invoke(project: Project, editor: Editor?, file: JetFile) { override fun invoke(project: Project, editor: Editor?, file: JetFile) {
if (possibleNames.size() == 1 || editor == null || !editor.component.isShowing) { if (possibleNames.size() == 1 || editor == null || !editor.component.isShowing) {
addName(project, element, possibleNames.get(0)) addName(project, element, possibleNames.first())
} }
else { else {
chooseNameAndAdd(project, editor) chooseNameAndAdd(project, editor)
@@ -58,7 +56,7 @@ public class AddNameToArgumentFix(argument: JetValueArgument, private val possib
} }
private fun getNamePopup(project: Project): ListPopupStep<String> { private fun getNamePopup(project: Project): ListPopupStep<String> {
return object : BaseListPopupStep<String>(JetBundle.message("add.name.to.parameter.name.chooser.title"), possibleNames) { return object : BaseListPopupStep<String>("Choose parameter name", possibleNames) {
override fun onChosen(selectedName: String, finalChoice: Boolean): PopupStep<Any> { override fun onChosen(selectedName: String, finalChoice: Boolean): PopupStep<Any> {
if (finalChoice) { if (finalChoice) {
addName(project, element, selectedName) addName(project, element, selectedName)
@@ -81,21 +79,27 @@ public class AddNameToArgumentFix(argument: JetValueArgument, private val possib
override fun getFamilyName() = "Add Name to Argument" override fun getFamilyName() = "Add Name to Argument"
companion object { companion object : JetSingleIntentionActionFactory() {
private fun generatePossibleNames(argument: JetValueArgument): List<String> { override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val callElement = PsiTreeUtil.getParentOfType(argument, JetCallElement::class.java) val argument = diagnostic.psiElement.getParentOfType<JetValueArgument>(false) ?: return null
assert(callElement != null, "The argument has to be inside a function or constructor call") val possibleNames = generatePossibleNames(argument)
if (possibleNames.isEmpty()) return null
return AddNameToArgumentFix(argument, possibleNames)
}
val context = argument.analyze() private fun generatePossibleNames(argument: JetValueArgument): List<String> {
val resolvedCall = callElement!!.getResolvedCall(context) ?: return emptyList() val callElement = argument.getParentOfType<JetCallElement>(true) ?: return emptyList()
val context = argument.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = callElement.getResolvedCall(context) ?: return emptyList()
val callableDescriptor = resolvedCall.resultingDescriptor val callableDescriptor = resolvedCall.resultingDescriptor
val argExpression = argument.getArgumentExpression() val argumentExpression = argument.getArgumentExpression()
val type = if (argExpression != null) context.getType(argExpression) else null val argumentType = argumentExpression?.let { context.getType(it) }
val usedParameters = resolvedCall.call.mapArgumentsToParameters(callableDescriptor).values().toSet() val usedParameters = resolvedCall.call.mapArgumentsToParameters(callableDescriptor).values().toSet()
val names = Lists.newArrayList<String>() val names = ArrayList<String>()
for (parameter in callableDescriptor.valueParameters) { for (parameter in callableDescriptor.valueParameters) {
if (!usedParameters.contains(parameter) && (type == null || JetTypeChecker.DEFAULT.isSubtypeOf(type, parameter.type))) { if (parameter !in usedParameters && (argumentType == null || JetTypeChecker.DEFAULT.isSubtypeOf(argumentType, parameter.type))) {
names.add(parameter.name.asString()) names.add(parameter.name.asString())
} }
} }
@@ -105,37 +109,16 @@ public class AddNameToArgumentFix(argument: JetValueArgument, private val possib
private fun addName(project: Project, argument: JetValueArgument, name: String) { private fun addName(project: Project, argument: JetValueArgument, name: String) {
PsiDocumentManager.getInstance(project).commitAllDocuments() PsiDocumentManager.getInstance(project).commitAllDocuments()
CommandProcessor.getInstance().executeCommand( project.executeWriteCommand("Add name to argument...") {
project, val newArgument = getParsedArgumentWithName(name, argument)
object : Runnable { argument.replace(newArgument)
override fun run() { }
ApplicationManager.getApplication().runWriteAction(object : Runnable {
override fun run() {
val newArgument = getParsedArgumentWithName(name, argument)
argument.replace(newArgument)
}
})
}
},
"Add name to argument...",
null)
} }
private fun getParsedArgumentWithName(name: String, argument: JetValueArgument): JetValueArgument { private fun getParsedArgumentWithName(name: String, argument: JetValueArgument): JetValueArgument {
val argumentExpression = argument.getArgumentExpression() val argumentExpression = argument.getArgumentExpression()
assert(argumentExpression != null, "Argument should be already parsed.") ?: error("Argument should be already parsed.")
return JetPsiFactory(argument).createArgument(argumentExpression!!, Name.identifier(name), argument.getSpreadElement() != null) return JetPsiFactory(argument).createArgument(argumentExpression, Name.identifier(name), argument.getSpreadElement() != null)
}
public fun createFactory(): JetIntentionActionsFactory {
return object : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val argument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument::class.java) ?: return null
val possibleNames = generatePossibleNames(argument)
if (possibleNames.isEmpty()) return null
return AddNameToArgumentFix(argument, possibleNames)
}
}
} }
} }
} }
@@ -81,7 +81,7 @@ public class QuickFixRegistrar : QuickFixContributor {
NON_VARARG_SPREAD.registerFactory(RemovePsiElementSimpleFix.createRemoveSpreadFactory()) NON_VARARG_SPREAD.registerFactory(RemovePsiElementSimpleFix.createRemoveSpreadFactory())
MIXING_NAMED_AND_POSITIONED_ARGUMENTS.registerFactory(AddNameToArgumentFix.createFactory()) MIXING_NAMED_AND_POSITIONED_ARGUMENTS.registerFactory(AddNameToArgumentFix)
NON_MEMBER_FUNCTION_NO_BODY.registerFactory(addFunctionBodyFactory) NON_MEMBER_FUNCTION_NO_BODY.registerFactory(addFunctionBodyFactory)