Not holding descriptor in SuperClassNotInitialized.AddParametersFix
This commit is contained in:
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
@@ -38,10 +37,12 @@ import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.util.*
|
||||
|
||||
public object SuperClassNotInitialized : JetIntentionActionsFactory() {
|
||||
@@ -92,7 +93,7 @@ public object SuperClassNotInitialized : JetIntentionActionsFactory() {
|
||||
val typesRendered = types.take(maxParamsToDisplay).map { DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(it) }
|
||||
val parameterString = typesRendered.joinToString(", ", "(", if (types.size() <= maxParamsToDisplay) ")" else ",...)")
|
||||
val text = "Add constructor parameters from " + superClass.getName().asString() + parameterString
|
||||
fixes.add(AddParametersFix(delegator, classOrObjectDeclaration, constructor, text))
|
||||
fixes.addIfNotNull(AddParametersFix.create(delegator, classOrObjectDeclaration, constructor, text))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,56 +128,70 @@ public object SuperClassNotInitialized : JetIntentionActionsFactory() {
|
||||
|
||||
private class AddParametersFix(
|
||||
element: JetDelegatorToSuperClass,
|
||||
val classDeclaration: JetClass,
|
||||
val superConstructor: ConstructorDescriptor, //TODO: do not hold descriptor!
|
||||
private val classDeclaration: JetClass,
|
||||
private val parametersToAdd: Collection<JetParameter>,
|
||||
private val argumentText: String,
|
||||
private val text: String
|
||||
) : KotlinQuickFixAction<JetDelegatorToSuperClass>(element) {
|
||||
|
||||
override fun getFamilyName() = "Add constructor parameters from superclass"
|
||||
companion object {
|
||||
fun create(
|
||||
element: JetDelegatorToSuperClass,
|
||||
classDeclaration: JetClass,
|
||||
superConstructor: ConstructorDescriptor,
|
||||
text: String
|
||||
): AddParametersFix? {
|
||||
val superParameters = superConstructor.getValueParameters()
|
||||
assert(superParameters.isNotEmpty())
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
return super.isAvailable(project, editor, file) && superConstructor.getValueParameters().none { it.getType().isError() }
|
||||
if (superParameters.any { it.type.isError }) return null
|
||||
|
||||
val argumentText = StringBuilder()
|
||||
val oldParameters = classDeclaration.getPrimaryConstructorParameters()
|
||||
val parametersToAdd = ArrayList<JetParameter>()
|
||||
for (parameter in superParameters) {
|
||||
val nameRendered = parameter.name.render()
|
||||
val varargElementType = parameter.varargElementType
|
||||
|
||||
if (argumentText.length > 0) {
|
||||
argumentText.append(", ")
|
||||
}
|
||||
argumentText.append(if (varargElementType != null) "*$nameRendered" else nameRendered)
|
||||
|
||||
val nameString = parameter.getName().asString()
|
||||
val existingParameter = oldParameters.firstOrNull { it.getName() == nameString }
|
||||
if (existingParameter != null) {
|
||||
val type = (existingParameter.resolveToDescriptor() as ValueParameterDescriptor).getType()
|
||||
if (type.isSubtypeOf(parameter.getType())) continue // use existing parameter
|
||||
}
|
||||
|
||||
val parameterText = if (varargElementType != null)
|
||||
"vararg " + nameRendered + ":" + IdeDescriptorRenderers.SOURCE_CODE.renderType(varargElementType)
|
||||
else
|
||||
nameRendered + ":" + IdeDescriptorRenderers.SOURCE_CODE.renderType(parameter.type)
|
||||
parametersToAdd.add(JetPsiFactory(element).createParameter(parameterText))
|
||||
}
|
||||
|
||||
return AddParametersFix(element, classDeclaration, parametersToAdd, argumentText.toString(), text)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getText()= text
|
||||
override fun getFamilyName() = "Add constructor parameters from superclass"
|
||||
|
||||
override fun getText() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: JetFile) {
|
||||
val factory = JetPsiFactory(project)
|
||||
val renderer = IdeDescriptorRenderers.SOURCE_CODE
|
||||
|
||||
val superParameters = superConstructor.getValueParameters()
|
||||
assert(superParameters.isNotEmpty())
|
||||
val parameterNames = ArrayList<String>()
|
||||
val typeRefsToShorten = ArrayList<JetTypeReference>()
|
||||
val parameterList = classDeclaration.createPrimaryConstructorParameterListIfAbsent()
|
||||
val oldParameters = parameterList.getParameters()
|
||||
val parametersToAdd = ArrayList<JetParameter>()
|
||||
for (parameter in superParameters) {
|
||||
val name = renderer.renderName(parameter.getName())
|
||||
val varargElementType = parameter.getVarargElementType()
|
||||
|
||||
parameterNames.add(if (varargElementType != null) "*$name" else name)
|
||||
|
||||
val nameString = parameter.getName().asString()
|
||||
val existingParameter = oldParameters.firstOrNull { it.getName() == nameString }
|
||||
if (existingParameter != null) {
|
||||
val type = (existingParameter.resolveToDescriptor() as ValueParameterDescriptor).getType()
|
||||
if (type.isSubtypeOf(parameter.getType())) continue // use existing parameter
|
||||
}
|
||||
|
||||
val parameterText = if (varargElementType != null)
|
||||
"vararg " + name + ":" + renderer.renderType(varargElementType)
|
||||
else
|
||||
name + ":" + renderer.renderType(parameter.getType())
|
||||
parametersToAdd.add(factory.createParameter(parameterText))
|
||||
}
|
||||
|
||||
for (parameter in parametersToAdd) {
|
||||
val newParameter = parameterList.addParameter(parameter)
|
||||
typeRefsToShorten.add(newParameter.getTypeReference()!!)
|
||||
typeRefsToShorten.add(newParameter.typeReference!!)
|
||||
}
|
||||
|
||||
val delegatorCall = factory.createDelegatorToSuperCall(element.getText() + "(" + parameterNames.joinToString(",") + ")")
|
||||
val delegatorCall = factory.createDelegatorToSuperCall(element.text + "(" + argumentText + ")")
|
||||
element.replace(delegatorCall)
|
||||
|
||||
ShortenReferences.DEFAULT.process(typeRefsToShorten)
|
||||
|
||||
Reference in New Issue
Block a user