Code simplifications + no i18n

This commit is contained in:
Valentin Kipyatkov
2015-10-15 20:07:17 +03:00
parent cd6450e1a1
commit 8dcc0096a8
3 changed files with 70 additions and 110 deletions
@@ -185,11 +185,6 @@ transform.if.statement.with.assignments.to.expression=Transform 'if' statement w
transform.assignment.with.if.expression.to.statement=Transform assignment with 'if' expression to statement transform.assignment.with.if.expression.to.statement=Transform assignment with 'if' expression to statement
transform.if.statement.with.assignments.to.expression.family=Transform 'if' Statement with Assignments to Expression transform.if.statement.with.assignments.to.expression.family=Transform 'if' Statement with Assignments to Expression
transform.assignment.with.if.expression.to.statement.family=Transform Assignment with 'if' Expression to Statement transform.assignment.with.if.expression.to.statement.family=Transform Assignment with 'if' Expression to Statement
change.function.signature.action.single=Change function signature to ''{0}''
change.function.signature.action.multiple=Change function signature...
change.function.signature.family=Change function signature
change.function.signature.chooser.title=Choose signature
change.function.signature.action=Change function signature
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.base.Function
import com.google.common.collect.Collections2
import com.google.common.collect.Lists import com.google.common.collect.Lists
import com.google.common.collect.Maps
import com.google.common.collect.Queues import com.google.common.collect.Queues
import com.intellij.codeInsight.hint.HintManager import com.intellij.codeInsight.hint.HintManager
import com.intellij.codeInsight.intention.IntentionAction import com.intellij.codeInsight.intention.IntentionAction
@@ -34,9 +31,7 @@ import com.intellij.psi.PsiFile
import com.intellij.util.PlatformIcons import com.intellij.util.PlatformIcons
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
@@ -50,17 +45,22 @@ import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
import org.jetbrains.kotlin.renderer.NameShortness import org.jetbrains.kotlin.renderer.NameShortness
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
import org.jetbrains.kotlin.resolve.VisibilityUtil import org.jetbrains.kotlin.resolve.VisibilityUtil
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.* import java.util.*
import javax.swing.Icon
/** /**
* Fix that changes member function's signature to match one of super functions' signatures. * Fix that changes member function's signature to match one of super functions' signatures.
*/ */
class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintAction<JetNamedFunction>(element) { class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintAction<JetNamedFunction>(element) {
companion object { companion object : JetSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val function = diagnostic.psiElement as? JetNamedFunction ?: return null
return ChangeMemberFunctionSignatureFix(function)
}
private val SIGNATURE_SOURCE_RENDERER = IdeDescriptorRenderers.SOURCE_CODE.withOptions { private val SIGNATURE_SOURCE_RENDERER = IdeDescriptorRenderers.SOURCE_CODE.withOptions {
renderDefaultValues = false renderDefaultValues = false
} }
@@ -85,19 +85,15 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
val functionDescriptor = functionElement.resolveToDescriptor() as FunctionDescriptor val functionDescriptor = functionElement.resolveToDescriptor() as FunctionDescriptor
val superFunctions = getPossibleSuperFunctionsDescriptors(functionDescriptor) val superFunctions = getPossibleSuperFunctionsDescriptors(functionDescriptor)
val possibleSignatures = Maps.newHashMap<String, FunctionDescriptor>()
for (superFunction in superFunctions) { val possibleSignatures: Map<String, FunctionDescriptor> = superFunctions
if (!superFunction.kind.isReal) continue .filter { it.kind.isReal }
val signature = changeSignatureToMatch(functionDescriptor, superFunction) .map { changeSignatureToMatch(functionDescriptor, it) }
possibleSignatures.put(SIGNATURE_PREVIEW_RENDERER.render(signature), signature) .toMapBy { SIGNATURE_PREVIEW_RENDERER.render(it) }
}
val keys = ArrayList(possibleSignatures.keys) return possibleSignatures.keys
Collections.sort(keys) .sorted()
return ArrayList(Collections2.transform(keys, object : Function<String, FunctionDescriptor> { .map { possibleSignatures[it]!! }
override fun apply(key: String?): FunctionDescriptor? {
return possibleSignatures.get(key)
}
}))
} }
/** /**
@@ -113,8 +109,8 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
// Parameters in this function, which are used in new function signature: // Parameters in this function, which are used in new function signature:
val used = BitSet(superParameters.size) val used = BitSet(superParameters.size)
matchParameters(MATCH_NAMES, superParameters, parameters, newParameters, matched, used) matchParameters(ParameterChooser.MatchNames, superParameters, parameters, newParameters, matched, used)
matchParameters(MATCH_TYPES, superParameters, parameters, newParameters, matched, used) matchParameters(ParameterChooser.MatchTypes, superParameters, parameters, newParameters, matched, used)
val newFunction = FunctionDescriptorUtil.replaceFunctionParameters( val newFunction = FunctionDescriptorUtil.replaceFunctionParameters(
superFunction.copy( superFunction.copy(
@@ -132,32 +128,10 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
* Returns new visibility for 'function' modified to override 'superFunction'. * Returns new visibility for 'function' modified to override 'superFunction'.
*/ */
private fun getVisibility(function: FunctionDescriptor, superFunction: FunctionDescriptor): Visibility { private fun getVisibility(function: FunctionDescriptor, superFunction: FunctionDescriptor): Visibility {
val descriptors = Queues.newArrayDeque<CallableMemberDescriptor>(Arrays.asList(superFunction, function)) val descriptors = Queues.newArrayDeque<CallableMemberDescriptor>(listOf(superFunction, function))
return VisibilityUtil.findMemberWithMaxVisibility(descriptors).visibility return VisibilityUtil.findMemberWithMaxVisibility(descriptors).visibility
} }
private val MATCH_NAMES = object : ParameterChooser {
override fun choose(
parameter: ValueParameterDescriptor,
superParameter: ValueParameterDescriptor): ValueParameterDescriptor? {
return if (parameter.name == superParameter.name) superParameter else null
}
}
private val MATCH_TYPES = object : ParameterChooser {
override fun choose(
parameter: ValueParameterDescriptor,
superParameter: ValueParameterDescriptor): ValueParameterDescriptor? {
// TODO: support for generic functions
if (JetTypeChecker.DEFAULT.equalTypes(parameter.type, superParameter.type)) {
return superParameter.copy(parameter.containingDeclaration, parameter.name)
}
else {
return null
}
}
}
/** /**
* Match function's parameters with super function's parameters using parameterChooser. * Match function's parameters with super function's parameters using parameterChooser.
* Doesn't have to preserve ordering, parameter names or types. * Doesn't have to preserve ordering, parameter names or types.
@@ -177,15 +151,16 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
parameters: List<ValueParameterDescriptor>, parameters: List<ValueParameterDescriptor>,
newParameters: MutableList<ValueParameterDescriptor>, newParameters: MutableList<ValueParameterDescriptor>,
matched: BitSet, matched: BitSet,
used: BitSet) { used: BitSet
) {
for (superParameter in superParameters) { for (superParameter in superParameters) {
if (!matched.get(superParameter.index)) { if (!matched[superParameter.index]) {
for (parameter in parameters) { for (parameter in parameters) {
val choice = parameterChooser.choose(parameter, superParameter) val choice = parameterChooser.choose(parameter, superParameter)
if (!used.get(parameter.index) && choice != null) { if (choice != null && !used[parameter.index]) {
used.set(parameter.index, true) used[parameter.index] = true
matched.set(superParameter.index, true) matched[superParameter.index] = true
newParameters.set(superParameter.index, choice) newParameters[superParameter.index] = choice
break break
} }
} }
@@ -198,29 +173,12 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
* different parameters/return type). * different parameters/return type).
*/ */
private fun getPossibleSuperFunctionsDescriptors(functionDescriptor: FunctionDescriptor): List<FunctionDescriptor> { private fun getPossibleSuperFunctionsDescriptors(functionDescriptor: FunctionDescriptor): List<FunctionDescriptor> {
val containingDeclaration = functionDescriptor.containingDeclaration val containingClass = functionDescriptor.containingDeclaration as? ClassDescriptor ?: return emptyList()
val superFunctions = Lists.newArrayList<FunctionDescriptor>()
if (containingDeclaration !is ClassDescriptor) return superFunctions
val name = functionDescriptor.name val name = functionDescriptor.name
for (type in TypeUtils.getAllSupertypes(containingDeclaration.defaultType)) { return containingClass.defaultType.supertypes()
val scope = type.memberScope .flatMap { supertype -> supertype.memberScope.getFunctions(name, NoLookupLocation.FROM_IDE) }
for (function in scope.getFunctions(name, NoLookupLocation.FROM_IDE)) { .filter { it.kind.isReal && it.modality.isOverridable }
if (!function.kind.isReal) continue
if (function.modality.isOverridable)
superFunctions.add(function)
}
}
return superFunctions
}
fun createFactory(): JetSingleIntentionActionFactory {
return object : JetSingleIntentionActionFactory() {
public override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val function = QuickFixUtil.getParentElementOfType(diagnostic, JetNamedFunction::class.java)
return if (function == null) null else ChangeMemberFunctionSignatureFix(function)
}
}
} }
} }
@@ -231,24 +189,21 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
} }
override fun getText(): String { override fun getText(): String {
if (possibleSignatures.size == 1) { val single = possibleSignatures.singleOrNull()
return JetBundle.message("change.function.signature.action.single", SIGNATURE_PREVIEW_RENDERER.render(possibleSignatures.get(0))) if (single != null) {
return "Change function signature to '${SIGNATURE_PREVIEW_RENDERER.render(single)}'"
} }
else { else {
return JetBundle.message("change.function.signature.action.multiple") return "Change function signature..."
} }
} }
override fun getFamilyName(): String { override fun getFamilyName() = "Change function signature"
return JetBundle.message("change.function.signature.family")
}
override fun invoke(project: Project, editor: Editor?, file: JetFile) { override fun invoke(project: Project, editor: Editor?, file: JetFile) {
CommandProcessor.getInstance().runUndoTransparentAction(object : Runnable { CommandProcessor.getInstance().runUndoTransparentAction {
override fun run() { MyAction(project, editor, element, possibleSignatures).execute()
MyAction(project, editor, element, possibleSignatures).execute() }
}
})
} }
/** Helper interface for matchParameters(..) method. */ /** Helper interface for matchParameters(..) method. */
@@ -259,6 +214,25 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
* If not, returns null. * If not, returns null.
*/ */
fun choose(parameter: ValueParameterDescriptor, superParameter: ValueParameterDescriptor): ValueParameterDescriptor? fun choose(parameter: ValueParameterDescriptor, superParameter: ValueParameterDescriptor): ValueParameterDescriptor?
object MatchNames : ParameterChooser {
override fun choose(parameter: ValueParameterDescriptor, superParameter: ValueParameterDescriptor): ValueParameterDescriptor? {
return superParameter.check { parameter.name == superParameter.name }
}
}
object MatchTypes : ParameterChooser {
override fun choose(parameter: ValueParameterDescriptor, superParameter: ValueParameterDescriptor): ValueParameterDescriptor? {
// TODO: support for generic functions
if (JetTypeChecker.DEFAULT.equalTypes(parameter.type, superParameter.type)) {
return superParameter.copy(parameter.containingDeclaration, parameter.name)
}
else {
return null
}
}
}
} }
override fun showHint(editor: Editor): Boolean { override fun showHint(editor: Editor): Boolean {
@@ -269,29 +243,25 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
private val project: Project, private val project: Project,
private val editor: Editor?, private val editor: Editor?,
private val function: JetNamedFunction, private val function: JetNamedFunction,
private val signatures: List<FunctionDescriptor>) { private val signatures: List<FunctionDescriptor>
) {
fun execute(): Boolean { fun execute() {
PsiDocumentManager.getInstance(project).commitAllDocuments() PsiDocumentManager.getInstance(project).commitAllDocuments()
if (!function.isValid || signatures.isEmpty()) return false if (!function.isValid || signatures.isEmpty()) return
if (signatures.size == 1 || editor == null || !editor.component.isShowing) { if (signatures.size == 1 || editor == null || !editor.component.isShowing) {
changeSignature(signatures.get(0)) changeSignature(signatures.first())
} }
else { else {
chooseSignatureAndChange() chooseSignatureAndChange()
} }
return true
} }
private val signaturePopup: BaseListPopupStep<FunctionDescriptor> private val signaturePopup: BaseListPopupStep<FunctionDescriptor>
get() { get() {
return object : BaseListPopupStep<FunctionDescriptor>(JetBundle.message("change.function.signature.chooser.title"), signatures) { return object : BaseListPopupStep<FunctionDescriptor>("Choose Signature", signatures) {
override fun isAutoSelectionEnabled(): Boolean { override fun isAutoSelectionEnabled() = false
return false
}
override fun onChosen(selectedValue: FunctionDescriptor, finalChoice: Boolean): PopupStep<Any>? { override fun onChosen(selectedValue: FunctionDescriptor, finalChoice: Boolean): PopupStep<Any>? {
if (finalChoice) { if (finalChoice) {
@@ -300,13 +270,9 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
return PopupStep.FINAL_CHOICE return PopupStep.FINAL_CHOICE
} }
override fun getIconFor(aValue: FunctionDescriptor): Icon? { override fun getIconFor(aValue: FunctionDescriptor) = PlatformIcons.FUNCTION_ICON
return PlatformIcons.FUNCTION_ICON
}
override fun getTextFor(aValue: FunctionDescriptor): String { override fun getTextFor(aValue: FunctionDescriptor) = SIGNATURE_PREVIEW_RENDERER.render(aValue)
return SIGNATURE_PREVIEW_RENDERER.render(aValue)
}
} }
} }
@@ -315,9 +281,8 @@ class ChangeMemberFunctionSignatureFix(element: JetNamedFunction) : JetHintActio
PsiDocumentManager.getInstance(project).commitAllDocuments() PsiDocumentManager.getInstance(project).commitAllDocuments()
val psiFactory = JetPsiFactory(project) project.executeWriteCommand("Change Function Signature") {
project.executeWriteCommand(JetBundle.message("change.function.signature.action")) { val patternFunction = JetPsiFactory(project).createFunction(signatureString)
val patternFunction = psiFactory.createFunction(signatureString)
val newTypeRef = function.setTypeReference(patternFunction.typeReference) val newTypeRef = function.setTypeReference(patternFunction.typeReference)
if (newTypeRef != null) { if (newTypeRef != null) {
@@ -90,7 +90,7 @@ public class QuickFixRegistrar : QuickFixContributor {
NON_MEMBER_FUNCTION_NO_BODY.registerFactory(addFunctionBodyFactory) NON_MEMBER_FUNCTION_NO_BODY.registerFactory(addFunctionBodyFactory)
NOTHING_TO_OVERRIDE.registerFactory( RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OVERRIDE_KEYWORD), NOTHING_TO_OVERRIDE.registerFactory( RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OVERRIDE_KEYWORD),
ChangeMemberFunctionSignatureFix.createFactory(), ChangeMemberFunctionSignatureFix,
AddFunctionToSupertypeFix.createFactory()) AddFunctionToSupertypeFix.createFactory())
VIRTUAL_MEMBER_HIDDEN.registerFactory(AddModifierFix.createFactory(OVERRIDE_KEYWORD)) VIRTUAL_MEMBER_HIDDEN.registerFactory(AddModifierFix.createFactory(OVERRIDE_KEYWORD))