Skip to content

Commit

Permalink
Support fill in non-empty constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
shiraji committed Aug 26, 2018
1 parent 67c46fc commit cbc04b4
Showing 1 changed file with 22 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,42 @@ import org.jetbrains.kotlin.util.constructors

class FillClassIntention : SelfTargetingIntention<KtValueArgumentList>(KtValueArgumentList::class.java, "Fill class constructor") {
override fun isApplicableTo(element: KtValueArgumentList, caretOffset: Int): Boolean {
val callExpression = element.getStrictParentOfType<KtCallExpression>() ?: return false
val calleeExpression = callExpression.calleeExpression ?: return false
val analysisResult = calleeExpression.analyzeAndGetResult()
val classDescriptor = calleeExpression
.getReferenceTargets(analysisResult.bindingContext)
.mapNotNull { (it as? ConstructorDescriptor)?.containingDeclaration }
.distinct()
.singleOrNull() ?: return false
val parameters = classDescriptor.constructors.first().valueParameters
val parameters = element.getValueParameters() ?: return false
return element.arguments.size != parameters.size
}

override fun applyTo(element: KtValueArgumentList, editor: Editor?) {
val callExpression = element.getStrictParentOfType<KtCallExpression>() ?: return
val calleeExpression = callExpression.calleeExpression ?: return
val parameters = element.getValueParameters() ?: return
createParameterSetterExpression(element, parameters)
}

private fun KtValueArgumentList.getValueParameters(): MutableList<ValueParameterDescriptor>? {
val callExpression = getStrictParentOfType<KtCallExpression>() ?: return null
val calleeExpression = callExpression.calleeExpression ?: return null
val analysisResult = calleeExpression.analyzeAndGetResult()
val classDescriptor = calleeExpression
.getReferenceTargets(analysisResult.bindingContext)
.mapNotNull { (it as? ConstructorDescriptor)?.containingDeclaration }
.distinct()
.singleOrNull() ?: return
val parameters = classDescriptor.constructors.first().valueParameters

val factory = KtPsiFactory(project = element.project)
val argument = factory.createExpression("""${classDescriptor.name.identifier}(
${createParameterSetterExpression(parameters)}
)""".trimMargin())
callExpression.replace(argument)
return
.singleOrNull() ?: return null
return classDescriptor.constructors.first().valueParameters
}

override fun startInWriteAction() = true

private fun createParameterSetterExpression(parameters: List<ValueParameterDescriptor>): String {
var result = ""
parameters.forEach { parameter ->
var parameterString = "${parameter.name.identifier} = ${createDefaultValueFromParameter(parameter)},\n".let {
if(parameters.last() == parameter) return@let it.replace(",\n","")
it
}
result = "$result$parameterString"
private fun createParameterSetterExpression(element: KtValueArgumentList, parameters: List<ValueParameterDescriptor>) {
val arguments = element.arguments
val argumentNames = arguments.map { it.getArgumentName()?.asName?.identifier }.filterNotNull()
val factory = KtPsiFactory(element.project)
parameters.forEachIndexed { index, parameter ->
if(arguments.size > index && !arguments[index].isNamed()) return@forEachIndexed
if(argumentNames.contains(parameter.name.identifier)) return@forEachIndexed
val newArgument = factory.createArgument(
expression = factory.createExpression(createDefaultValueFromParameter(parameter)),
name = parameter.name
)
element.addArgument(newArgument)
}
return result
}

private fun createDefaultValueFromParameter(parameter: ValueParameterDescriptor): String {
Expand Down

0 comments on commit cbc04b4

Please sign in to comment.