Minor code improvements

This commit is contained in:
Valentin Kipyatkov
2016-03-28 19:13:01 +03:00
parent eb918db3af
commit 3f022377f3
@@ -20,7 +20,6 @@ import com.intellij.codeInsight.intention.IntentionAction
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.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
@@ -44,34 +43,28 @@ class ChangeVariableTypeFix(element: KtVariableDeclaration, private val type: Ko
return KotlinBundle.message("change.element.type", propertyName, IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)) return KotlinBundle.message("change.element.type", propertyName, IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type))
} }
override fun getFamilyName(): String { override fun getFamilyName()
return KotlinBundle.message("change.type.family") = KotlinBundle.message("change.type.family")
}
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { override fun isAvailable(project: Project, editor: Editor?, file: PsiFile)
return super.isAvailable(project, editor, file) && !ErrorUtils.containsErrorType(type) = super.isAvailable(project, editor, file) && !ErrorUtils.containsErrorType(type)
}
@Throws(IncorrectOperationException::class) override fun invoke(project: Project, editor: Editor?, file: KtFile) {
public override operator fun invoke(project: Project, editor: Editor?, file: KtFile) {
val psiFactory = KtPsiFactory(file) val psiFactory = KtPsiFactory(file)
val nameIdentifier = element.nameIdentifier ?: error("ChangeVariableTypeFix applied to variable without name") assert(element.nameIdentifier != null) { "ChangeVariableTypeFix applied to variable without name" }
val replacingTypeReference = psiFactory.createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)) val replacingTypeReference = psiFactory.createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type))
val toShorten = ArrayList<KtTypeReference>() val toShorten = ArrayList<KtTypeReference>()
toShorten.add(element.setTypeReference(replacingTypeReference)!!) toShorten.add(element.setTypeReference(replacingTypeReference)!!)
if (element is KtProperty) { if (element is KtProperty) {
val getter = element.getter val getterReturnTypeRef = element.getter?.returnTypeReference
val getterReturnTypeRef = getter?.returnTypeReference
if (getterReturnTypeRef != null) { if (getterReturnTypeRef != null) {
toShorten.add(getterReturnTypeRef.replace(replacingTypeReference) as KtTypeReference) toShorten.add(getterReturnTypeRef.replace(replacingTypeReference) as KtTypeReference)
} }
val setter = element.setter val setterParameterTypeRef = element.setter?.parameter?.typeReference
val setterParameter = setter?.parameter
val setterParameterTypeRef = setterParameter?.typeReference
if (setterParameterTypeRef != null) { if (setterParameterTypeRef != null) {
toShorten.add(setterParameterTypeRef.replace(replacingTypeReference) as KtTypeReference) toShorten.add(setterParameterTypeRef.replace(replacingTypeReference) as KtTypeReference)
} }
@@ -88,9 +81,9 @@ class ChangeVariableTypeFix(element: KtVariableDeclaration, private val type: Ko
val entry = ChangeFunctionReturnTypeFix.getDestructuringDeclarationEntryThatTypeMismatchComponentFunction(diagnostic) val entry = ChangeFunctionReturnTypeFix.getDestructuringDeclarationEntryThatTypeMismatchComponentFunction(diagnostic)
val context = entry.analyze() val context = entry.analyze()
val resolvedCall = context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry) ?: return null val resolvedCall = context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry) ?: return null
val componentFunction = DescriptorToSourceUtils.descriptorToDeclaration(resolvedCall.candidateDescriptor) as KtFunction? ?: return null if (DescriptorToSourceUtils.descriptorToDeclaration(resolvedCall.candidateDescriptor) == null) return null
val expectedType = resolvedCall.candidateDescriptor.returnType val expectedType = resolvedCall.candidateDescriptor.returnType ?: return null
return if (expectedType == null) null else ChangeVariableTypeFix(entry, expectedType) return ChangeVariableTypeFix(entry, expectedType)
} }
} }
} }
@@ -102,19 +95,18 @@ class ChangeVariableTypeFix(element: KtVariableDeclaration, private val type: Ko
if (diagnostic.psiElement is KtProperty) { if (diagnostic.psiElement is KtProperty) {
val property = diagnostic.psiElement as KtProperty val property = diagnostic.psiElement as KtProperty
val descriptor = property.resolveToDescriptor() val descriptor = property.resolveToDescriptor() as? PropertyDescriptor ?: return actions
if (descriptor !is PropertyDescriptor) return actions
var lowerBoundOfOverriddenPropertiesTypes = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(descriptor) var lowerBoundOfOverriddenPropertiesTypes = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(descriptor)
val propertyType = descriptor.returnType ?: error("Property type cannot be null if it mismatch something") val propertyType = descriptor.returnType ?: error("Property type cannot be null if it mismatches something")
val overriddenMismatchingProperties = LinkedList<PropertyDescriptor>() val overriddenMismatchingProperties = LinkedList<PropertyDescriptor>()
var canChangeOverriddenPropertyType = true var canChangeOverriddenPropertyType = true
for (overriddenProperty in descriptor.overriddenDescriptors) { for (overriddenProperty in descriptor.overriddenDescriptors) {
val overriddenPropertyType = overriddenProperty.returnType val overriddenPropertyType = overriddenProperty.returnType
if (overriddenPropertyType != null) { if (overriddenPropertyType != null) {
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(propertyType!!, overriddenPropertyType)) { if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(propertyType, overriddenPropertyType)) {
overriddenMismatchingProperties.add(overriddenProperty) overriddenMismatchingProperties.add(overriddenProperty)
} }
else if (overriddenProperty.isVar && !KotlinTypeChecker.DEFAULT.equalTypes(overriddenPropertyType, propertyType)) { else if (overriddenProperty.isVar && !KotlinTypeChecker.DEFAULT.equalTypes(overriddenPropertyType, propertyType)) {
@@ -132,9 +124,9 @@ class ChangeVariableTypeFix(element: KtVariableDeclaration, private val type: Ko
} }
if (overriddenMismatchingProperties.size == 1 && canChangeOverriddenPropertyType) { if (overriddenMismatchingProperties.size == 1 && canChangeOverriddenPropertyType) {
val overriddenProperty = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingProperties[0]) val overriddenProperty = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingProperties.single())
if (overriddenProperty is KtProperty) { if (overriddenProperty is KtProperty) {
actions.add(ChangeVariableTypeFix(overriddenProperty, propertyType!!)) actions.add(ChangeVariableTypeFix(overriddenProperty, propertyType))
} }
} }
} }