Minor code improvements

This commit is contained in:
Valentin Kipyatkov
2016-03-29 16:34:03 +03:00
parent 74f9f89728
commit 9bbeaa3c03
2 changed files with 30 additions and 42 deletions
@@ -38,16 +38,10 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import java.util.* import java.util.*
class ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression: KtLambdaExpression, private val type: KotlinType) : KotlinQuickFixAction<KtLambdaExpression>(functionLiteralExpression) { class ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression: KtLambdaExpression, private val type: KotlinType) : KotlinQuickFixAction<KtLambdaExpression>(functionLiteralExpression) {
private val functionLiteralReturnTypeRef: KtTypeReference? private val functionLiteralReturnTypeRef = functionLiteralExpression.functionLiteral.typeReference
private var appropriateQuickFix: IntentionAction? = null private val appropriateQuickFix = createAppropriateQuickFix(functionLiteralExpression)
init { private fun createAppropriateQuickFix(functionLiteralExpression: KtLambdaExpression): IntentionAction? {
functionLiteralReturnTypeRef = functionLiteralExpression.functionLiteral.typeReference
doInit(functionLiteralExpression)
}
private fun doInit(functionLiteralExpression: KtLambdaExpression) {
val analysisResult = functionLiteralExpression.getContainingKtFile().analyzeFullyAndGetResult() val analysisResult = functionLiteralExpression.getContainingKtFile().analyzeFullyAndGetResult()
val context = analysisResult.bindingContext val context = analysisResult.bindingContext
val functionLiteralType = context.getType(functionLiteralExpression) ?: error("Type of function literal not available in binding context") val functionLiteralType = context.getType(functionLiteralExpression) ?: error("Type of function literal not available in binding context")
@@ -67,10 +61,10 @@ class ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression: KtLambdaExpr
if (correspondingProperty != null && QuickFixUtil.canEvaluateTo(correspondingProperty.initializer!!, functionLiteralExpression)) { if (correspondingProperty != null && QuickFixUtil.canEvaluateTo(correspondingProperty.initializer!!, functionLiteralExpression)) {
val correspondingPropertyTypeRef = correspondingProperty.typeReference val correspondingPropertyTypeRef = correspondingProperty.typeReference
val propertyType = context.get(BindingContext.TYPE, correspondingPropertyTypeRef) val propertyType = context.get(BindingContext.TYPE, correspondingPropertyTypeRef)
if (propertyType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(eventualFunctionLiteralType, propertyType)) { return if (propertyType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(eventualFunctionLiteralType, propertyType))
appropriateQuickFix = ChangeVariableTypeFix(correspondingProperty, eventualFunctionLiteralType) ChangeVariableTypeFix(correspondingProperty, eventualFunctionLiteralType)
} else
return null
} }
val resolvedCall = functionLiteralExpression.getParentResolvedCall(context, true) val resolvedCall = functionLiteralExpression.getParentResolvedCall(context, true)
@@ -80,10 +74,10 @@ class ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression: KtLambdaExpr
if (correspondingParameter != null) { if (correspondingParameter != null) {
val correspondingParameterTypeRef = correspondingParameter.typeReference val correspondingParameterTypeRef = correspondingParameter.typeReference
val parameterType = context.get(BindingContext.TYPE, correspondingParameterTypeRef) val parameterType = context.get(BindingContext.TYPE, correspondingParameterTypeRef)
if (parameterType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(eventualFunctionLiteralType, parameterType)) { return if (parameterType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(eventualFunctionLiteralType, parameterType))
appropriateQuickFix = ChangeParameterTypeFix(correspondingParameter, eventualFunctionLiteralType) ChangeParameterTypeFix(correspondingParameter, eventualFunctionLiteralType)
} else
return null
} }
} }
@@ -92,26 +86,25 @@ class ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression: KtLambdaExpr
if (parentFunction != null && QuickFixUtil.canFunctionOrGetterReturnExpression(parentFunction, functionLiteralExpression)) { if (parentFunction != null && QuickFixUtil.canFunctionOrGetterReturnExpression(parentFunction, functionLiteralExpression)) {
val parentFunctionReturnTypeRef = parentFunction.typeReference val parentFunctionReturnTypeRef = parentFunction.typeReference
val parentFunctionReturnType = context.get(BindingContext.TYPE, parentFunctionReturnTypeRef) val parentFunctionReturnType = context.get(BindingContext.TYPE, parentFunctionReturnTypeRef)
if (parentFunctionReturnType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(eventualFunctionLiteralType, parentFunctionReturnType)) { return if (parentFunctionReturnType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(eventualFunctionLiteralType, parentFunctionReturnType))
appropriateQuickFix = ChangeFunctionReturnTypeFix(parentFunction, eventualFunctionLiteralType) ChangeFunctionReturnTypeFix(parentFunction, eventualFunctionLiteralType)
} else
null
} }
return null
} }
override fun getText(): String { override fun getText(): String {
if (appropriateQuickFix != null) { appropriateQuickFix?.let { return it.text }
return appropriateQuickFix!!.text return "Change lambda expression return type to '${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)}'"
}
return String.format("Change lambda expression return type to '%s'",
IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type))
} }
override fun getFamilyName(): String { override fun getFamilyName() = KotlinBundle.message("change.type.family")
return KotlinBundle.message("change.type.family")
}
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
return super.isAvailable(project, editor, file) && (functionLiteralReturnTypeRef != null || appropriateQuickFix != null && appropriateQuickFix!!.isAvailable(project, editor!!, file)) return super.isAvailable(project, editor, file)
&& (functionLiteralReturnTypeRef != null || appropriateQuickFix != null && appropriateQuickFix.isAvailable(project, editor!!, file))
} }
override fun invoke(project: Project, editor: Editor?, file: KtFile) { override fun invoke(project: Project, editor: Editor?, file: KtFile) {
@@ -120,19 +113,15 @@ class ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression: KtLambdaExpr
newTypeRef = functionLiteralReturnTypeRef.replace(newTypeRef) as KtTypeReference newTypeRef = functionLiteralReturnTypeRef.replace(newTypeRef) as KtTypeReference
ShortenReferences.DEFAULT.process(newTypeRef) ShortenReferences.DEFAULT.process(newTypeRef)
} }
if (appropriateQuickFix != null && appropriateQuickFix!!.isAvailable(project, editor!!, file)) { if (appropriateQuickFix != null && appropriateQuickFix.isAvailable(project, editor!!, file)) {
appropriateQuickFix!!.invoke(project, editor, file) appropriateQuickFix.invoke(project, editor, file)
} }
} }
companion object { companion object : KotlinSingleIntentionActionFactory() {
fun createFactoryForExpectedOrAssignmentTypeMismatch(): KotlinSingleIntentionActionFactory { override fun createAction(diagnostic: Diagnostic): IntentionAction? {
return object : KotlinSingleIntentionActionFactory() { val functionLiteralExpression = QuickFixUtil.getParentElementOfType(diagnostic, KtLambdaExpression::class.java) ?: return null
public override fun createAction(diagnostic: Diagnostic): IntentionAction? { return ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression, functionLiteralExpression.platform.builtIns.unitType)
val functionLiteralExpression = QuickFixUtil.getParentElementOfType(diagnostic, KtLambdaExpression::class.java) ?: return null
return ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression, functionLiteralExpression.platform.builtIns.getUnitType())
}
}
} }
} }
} }
@@ -243,9 +243,8 @@ class QuickFixRegistrar : QuickFixContributor {
EXTENSION_PROPERTY_WITH_BACKING_FIELD.registerFactory(ConvertExtensionPropertyInitializerToGetterFix) EXTENSION_PROPERTY_WITH_BACKING_FIELD.registerFactory(ConvertExtensionPropertyInitializerToGetterFix)
val changeFunctionLiteralReturnTypeFix = ChangeFunctionLiteralReturnTypeFix.createFactoryForExpectedOrAssignmentTypeMismatch() EXPECTED_TYPE_MISMATCH.registerFactory(ChangeFunctionLiteralReturnTypeFix)
EXPECTED_TYPE_MISMATCH.registerFactory(changeFunctionLiteralReturnTypeFix) ASSIGNMENT_TYPE_MISMATCH.registerFactory(ChangeFunctionLiteralReturnTypeFix)
ASSIGNMENT_TYPE_MISMATCH.registerFactory(changeFunctionLiteralReturnTypeFix)
UNRESOLVED_REFERENCE.registerFactory(CreateUnaryOperationActionFactory) UNRESOLVED_REFERENCE.registerFactory(CreateUnaryOperationActionFactory)
UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(CreateUnaryOperationActionFactory) UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(CreateUnaryOperationActionFactory)