Functions to objects

This commit is contained in:
Valentin Kipyatkov
2016-03-28 19:17:00 +03:00
parent 3f022377f3
commit d5a8d8c393
2 changed files with 43 additions and 50 deletions
@@ -73,67 +73,60 @@ class ChangeVariableTypeFix(element: KtVariableDeclaration, private val type: Ko
ShortenReferences.DEFAULT.process(toShorten) ShortenReferences.DEFAULT.process(toShorten)
} }
companion object { object ComponentFunctionReturnTypeMismatchFactory : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
fun createFactoryForComponentFunctionReturnTypeMismatch(): KotlinSingleIntentionActionFactory { val entry = ChangeFunctionReturnTypeFix.getDestructuringDeclarationEntryThatTypeMismatchComponentFunction(diagnostic)
return object : KotlinSingleIntentionActionFactory() { val context = entry.analyze()
public override fun createAction(diagnostic: Diagnostic): IntentionAction? { val resolvedCall = context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry) ?: return null
val entry = ChangeFunctionReturnTypeFix.getDestructuringDeclarationEntryThatTypeMismatchComponentFunction(diagnostic) if (DescriptorToSourceUtils.descriptorToDeclaration(resolvedCall.candidateDescriptor) == null) return null
val context = entry.analyze() val expectedType = resolvedCall.candidateDescriptor.returnType ?: return null
val resolvedCall = context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry) ?: return null return ChangeVariableTypeFix(entry, expectedType)
if (DescriptorToSourceUtils.descriptorToDeclaration(resolvedCall.candidateDescriptor) == null) return null
val expectedType = resolvedCall.candidateDescriptor.returnType ?: return null
return ChangeVariableTypeFix(entry, expectedType)
}
}
} }
}
fun createFactoryForPropertyOrReturnTypeMismatchOnOverride(): KotlinIntentionActionsFactory { object PropertyOrReturnTypeMismatchOnOverrideFactory : KotlinIntentionActionsFactory() {
return object : KotlinIntentionActionsFactory() { override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> { val actions = LinkedList<IntentionAction>()
val actions = LinkedList<IntentionAction>()
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() as? PropertyDescriptor ?: return actions val descriptor = property.resolveToDescriptor() as? 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 mismatches 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)) {
canChangeOverriddenPropertyType = false
}
if (overriddenProperty.isVar && lowerBoundOfOverriddenPropertiesTypes != null &&
!KotlinTypeChecker.DEFAULT.equalTypes(lowerBoundOfOverriddenPropertiesTypes, overriddenPropertyType)) {
lowerBoundOfOverriddenPropertiesTypes = null
}
}
} }
else if (overriddenProperty.isVar && !KotlinTypeChecker.DEFAULT.equalTypes(overriddenPropertyType, propertyType)) {
if (lowerBoundOfOverriddenPropertiesTypes != null) { canChangeOverriddenPropertyType = false
actions.add(ChangeVariableTypeFix(property, lowerBoundOfOverriddenPropertiesTypes))
} }
if (overriddenProperty.isVar && lowerBoundOfOverriddenPropertiesTypes != null &&
if (overriddenMismatchingProperties.size == 1 && canChangeOverriddenPropertyType) { !KotlinTypeChecker.DEFAULT.equalTypes(lowerBoundOfOverriddenPropertiesTypes, overriddenPropertyType)) {
val overriddenProperty = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingProperties.single()) lowerBoundOfOverriddenPropertiesTypes = null
if (overriddenProperty is KtProperty) {
actions.add(ChangeVariableTypeFix(overriddenProperty, propertyType))
}
} }
} }
}
return actions if (lowerBoundOfOverriddenPropertiesTypes != null) {
actions.add(ChangeVariableTypeFix(property, lowerBoundOfOverriddenPropertiesTypes))
}
if (overriddenMismatchingProperties.size == 1 && canChangeOverriddenPropertyType) {
val overriddenProperty = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingProperties.single())
if (overriddenProperty is KtProperty) {
actions.add(ChangeVariableTypeFix(overriddenProperty, propertyType))
}
} }
} }
return actions
} }
} }
} }
@@ -219,11 +219,11 @@ class QuickFixRegistrar : QuickFixContributor {
NOT_AN_ANNOTATION_CLASS.registerFactory(MakeClassAnAnnotationClassFix) NOT_AN_ANNOTATION_CLASS.registerFactory(MakeClassAnAnnotationClassFix)
val changeVariableTypeFix = ChangeVariableTypeFix.createFactoryForPropertyOrReturnTypeMismatchOnOverride() val changeVariableTypeFix = ChangeVariableTypeFix.PropertyOrReturnTypeMismatchOnOverrideFactory
RETURN_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix) RETURN_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix)
PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix) PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix)
VAR_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix) VAR_TYPE_MISMATCH_ON_OVERRIDE.registerFactory(changeVariableTypeFix)
COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.registerFactory(ChangeVariableTypeFix.createFactoryForComponentFunctionReturnTypeMismatch()) COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.registerFactory(ChangeVariableTypeFix.ComponentFunctionReturnTypeMismatchFactory)
val changeFunctionReturnTypeFix = ChangeFunctionReturnTypeFix.createFactoryForChangingReturnTypeToUnit() val changeFunctionReturnTypeFix = ChangeFunctionReturnTypeFix.createFactoryForChangingReturnTypeToUnit()
RETURN_TYPE_MISMATCH.registerFactory(changeFunctionReturnTypeFix) RETURN_TYPE_MISMATCH.registerFactory(changeFunctionReturnTypeFix)