Reformat & cleanup: CreateCallableFromCallActionFactory

This commit is contained in:
Mikhail Glukhikh
2018-08-15 16:19:07 +03:00
parent 9a9e703e80
commit d67dea4619
@@ -49,18 +49,16 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import java.lang.AssertionError
import java.util.*
sealed class CreateCallableFromCallActionFactory<E : KtExpression>( sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
extensionsEnabled: Boolean = true extensionsEnabled: Boolean = true
) : CreateCallableMemberFromUsageFactory<E>(extensionsEnabled) { ) : CreateCallableMemberFromUsageFactory<E>(extensionsEnabled) {
protected abstract fun doCreateCallableInfo( protected abstract fun doCreateCallableInfo(
expression: E, expression: E,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
): CallableInfo? ): CallableInfo?
protected fun getExpressionOfInterest(diagnostic: Diagnostic): KtExpression? { protected fun getExpressionOfInterest(diagnostic: Diagnostic): KtExpression? {
@@ -68,7 +66,8 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
if (PsiTreeUtil.getParentOfType( if (PsiTreeUtil.getParentOfType(
diagElement, diagElement,
KtTypeReference::class.java, KtAnnotationEntry::class.java, KtImportDirective::class.java KtTypeReference::class.java, KtAnnotationEntry::class.java, KtImportDirective::class.java
) != null) return null ) != null
) return null
return when (diagnostic.factory) { return when (diagnostic.factory) {
in Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS, Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND -> { in Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS, Errors.EXPRESSION_EXPECTED_PACKAGE_FOUND -> {
@@ -90,10 +89,10 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
val project = element.project val project = element.project
val calleeExpr = when (element) { val calleeExpr = when (element) {
is KtCallExpression -> element.calleeExpression is KtCallExpression -> element.calleeExpression
is KtSimpleNameExpression -> element is KtSimpleNameExpression -> element
else -> null else -> null
} as? KtSimpleNameExpression ?: return null } as? KtSimpleNameExpression ?: return null
if (calleeExpr.getReferencedNameElementType() != KtTokens.IDENTIFIER) return null if (calleeExpr.getReferencedNameElementType() != KtTokens.IDENTIFIER) return null
@@ -102,13 +101,12 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
val receiverType = getReceiverTypeInfo(analysisResult.bindingContext, project, receiver) ?: return null val receiverType = getReceiverTypeInfo(analysisResult.bindingContext, project, receiver) ?: return null
val possibleContainers = val possibleContainers =
if (receiverType is TypeInfo.Empty) { if (receiverType is TypeInfo.Empty) {
val containers = with(element.getQualifiedExpressionForSelectorOrThis().getExtractionContainers()) { val containers = with(element.getQualifiedExpressionForSelectorOrThis().getExtractionContainers()) {
if (element is KtCallExpression) this else filter { it is KtClassBody || it is KtFile } if (element is KtCallExpression) this else filter { it is KtClassBody || it is KtFile }
}
if (containers.isNotEmpty()) containers else return null
} }
else Collections.emptyList() if (containers.isNotEmpty()) containers else return null
} else listOf()
return doCreateCallableInfo(element, analysisResult, calleeExpr.getReferencedName(), receiverType, possibleContainers) return doCreateCallableInfo(element, analysisResult, calleeExpr.getReferencedName(), receiverType, possibleContainers)
} }
@@ -159,21 +157,22 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
if (!receiverType.isAbstract() && TypeUtils.getAllSupertypes(receiverType).all { !it.isAbstract() }) return null if (!receiverType.isAbstract() && TypeUtils.getAllSupertypes(receiverType).all { !it.isAbstract() }) return null
return mainCallable.copy( return mainCallable.copy(
receiverTypeInfo = receiverTypeInfo, receiverTypeInfo = receiverTypeInfo,
possibleContainers = emptyList(), possibleContainers = emptyList(),
modifierList = KtPsiFactory(originalExpression).createModifierList(KtTokens.ABSTRACT_KEYWORD)) modifierList = KtPsiFactory(originalExpression).createModifierList(KtTokens.ABSTRACT_KEYWORD)
)
} }
protected fun getCallableWithReceiverInsideExtension( protected fun getCallableWithReceiverInsideExtension(
mainCallable: CallableInfo, mainCallable: CallableInfo,
originalExpression: KtExpression, originalExpression: KtExpression,
context: BindingContext, context: BindingContext,
receiverType: TypeInfo receiverType: TypeInfo
): CallableInfo? { ): CallableInfo? {
if (receiverType != TypeInfo.Empty) return null if (receiverType != TypeInfo.Empty) return null
val callable = (originalExpression.getParentOfTypeAndBranch<KtFunction> { bodyExpression } val callable = (originalExpression.getParentOfTypeAndBranch<KtFunction> { bodyExpression }
?: originalExpression.getParentOfTypeAndBranches<KtProperty> { listOf(getter, setter) }) ?: originalExpression.getParentOfTypeAndBranches<KtProperty> { listOf(getter, setter) })
?: return null ?: return null
if (callable !is KtFunctionLiteral && callable.receiverTypeReference == null) return null if (callable !is KtFunctionLiteral && callable.receiverTypeReference == null) return null
val callableDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, callable] as? CallableDescriptor ?: return null val callableDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, callable] as? CallableDescriptor ?: return null
val extensionReceiverType = callableDescriptor.extensionReceiverParameter?.type ?: return null val extensionReceiverType = callableDescriptor.extensionReceiverParameter?.type ?: return null
@@ -181,7 +180,7 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
return mainCallable.copy(receiverTypeInfo = newReceiverTypeInfo, possibleContainers = emptyList()) return mainCallable.copy(receiverTypeInfo = newReceiverTypeInfo, possibleContainers = emptyList())
} }
sealed class Property: CreateCallableFromCallActionFactory<KtSimpleNameExpression>() { sealed class Property : CreateCallableFromCallActionFactory<KtSimpleNameExpression>() {
override fun getElementOfInterest(diagnostic: Diagnostic): KtSimpleNameExpression? { override fun getElementOfInterest(diagnostic: Diagnostic): KtSimpleNameExpression? {
val refExpr = getExpressionOfInterest(diagnostic) as? KtNameReferenceExpression ?: return null val refExpr = getExpressionOfInterest(diagnostic) as? KtNameReferenceExpression ?: return null
if (refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression> { callableReference } != null) return null if (refExpr.getParentOfTypeAndBranch<KtCallableReferenceExpression> { callableReference } != null) return null
@@ -189,11 +188,11 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
} }
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtSimpleNameExpression, expression: KtSimpleNameExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
): CallableInfo? { ): CallableInfo? {
val fullCallExpr = expression.getQualifiedExpressionForSelectorOrThis() val fullCallExpr = expression.getQualifiedExpressionForSelectorOrThis()
val varExpected = fullCallExpr.getAssignmentByLHS() != null val varExpected = fullCallExpr.getAssignmentByLHS() != null
@@ -201,37 +200,37 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
val returnTypes = expressionForTypeGuess.guessTypes(analysisResult.bindingContext, analysisResult.moduleDescriptor) val returnTypes = expressionForTypeGuess.guessTypes(analysisResult.bindingContext, analysisResult.moduleDescriptor)
val returnTypeInfo = TypeInfo(expressionForTypeGuess, if (varExpected) Variance.INVARIANT else Variance.OUT_VARIANCE) val returnTypeInfo = TypeInfo(expressionForTypeGuess, if (varExpected) Variance.INVARIANT else Variance.OUT_VARIANCE)
val canBeLateinit = val canBeLateinit =
varExpected varExpected
&& returnTypes.any { !it.isMarkedNullable && !KotlinBuiltIns.isPrimitiveType(it) } && returnTypes.any { !it.isMarkedNullable && !KotlinBuiltIns.isPrimitiveType(it) }
&& fullCallExpr.parents.firstOrNull { it is KtDeclarationWithBody || it is KtClassInitializer } is KtDeclarationWithBody && fullCallExpr.parents.firstOrNull { it is KtDeclarationWithBody || it is KtClassInitializer } is KtDeclarationWithBody
return PropertyInfo(name, receiverType, returnTypeInfo, varExpected, possibleContainers, isLateinitPreferred = canBeLateinit) return PropertyInfo(name, receiverType, returnTypeInfo, varExpected, possibleContainers, isLateinitPreferred = canBeLateinit)
} }
object Default : Property() { object Default : Property() {
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtSimpleNameExpression, expression: KtSimpleNameExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
): CallableInfo? { ): CallableInfo? {
return super.doCreateCallableInfo( return super.doCreateCallableInfo(
expression, expression,
analysisResult, analysisResult,
name, name,
receiverType, receiverType,
possibleContainers.filterNot { it is KtClassBody && (it.parent as KtClassOrObject).isInterfaceClass() } possibleContainers.filterNot { it is KtClassBody && (it.parent as KtClassOrObject).isInterfaceClass() }
) )
} }
} }
object Abstract : Property() { object Abstract : Property() {
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtSimpleNameExpression, expression: KtSimpleNameExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let { ) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let {
getAbstractCallableInfo(it, expression) getAbstractCallableInfo(it, expression)
} }
@@ -239,28 +238,33 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
object ByImplicitExtensionReceiver : Property() { object ByImplicitExtensionReceiver : Property() {
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtSimpleNameExpression, expression: KtSimpleNameExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let { ) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let {
ByImplicitExtensionReceiver.getCallableWithReceiverInsideExtension(it, expression, analysisResult.bindingContext, receiverType) ByImplicitExtensionReceiver.getCallableWithReceiverInsideExtension(
it,
expression,
analysisResult.bindingContext,
receiverType
)
} }
} }
} }
sealed class Function: CreateCallableFromCallActionFactory<KtCallExpression>() { sealed class Function : CreateCallableFromCallActionFactory<KtCallExpression>() {
override fun getElementOfInterest(diagnostic: Diagnostic): KtCallExpression? { override fun getElementOfInterest(diagnostic: Diagnostic): KtCallExpression? {
return getExpressionOfInterest(diagnostic) as? KtCallExpression return getExpressionOfInterest(diagnostic) as? KtCallExpression
} }
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtCallExpression, expression: KtCallExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
): CallableInfo? { ): CallableInfo? {
val parameters = expression.getParameterInfos() val parameters = expression.getParameterInfos()
val typeParameters = expression.getTypeInfoForTypeArguments() val typeParameters = expression.getTypeInfoForTypeArguments()
@@ -278,11 +282,11 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
object Abstract : Function() { object Abstract : Function() {
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtCallExpression, expression: KtCallExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let { ) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let {
getAbstractCallableInfo(it, expression) getAbstractCallableInfo(it, expression)
} }
@@ -290,42 +294,43 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
object ByImplicitExtensionReceiver : Function() { object ByImplicitExtensionReceiver : Function() {
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtCallExpression, expression: KtCallExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let { ) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let {
getCallableWithReceiverInsideExtension(it, expression, analysisResult.bindingContext, receiverType) getCallableWithReceiverInsideExtension(it, expression, analysisResult.bindingContext, receiverType)
} }
} }
} }
object Constructor: CreateCallableFromCallActionFactory<KtCallExpression>() { object Constructor : CreateCallableFromCallActionFactory<KtCallExpression>() {
override fun getElementOfInterest(diagnostic: Diagnostic): KtCallExpression? { override fun getElementOfInterest(diagnostic: Diagnostic): KtCallExpression? {
return getExpressionOfInterest(diagnostic) as? KtCallExpression return getExpressionOfInterest(diagnostic) as? KtCallExpression
} }
override fun doCreateCallableInfo( override fun doCreateCallableInfo(
expression: KtCallExpression, expression: KtCallExpression,
analysisResult: AnalysisResult, analysisResult: AnalysisResult,
name: String, name: String,
receiverType: TypeInfo, receiverType: TypeInfo,
possibleContainers: List<KtElement> possibleContainers: List<KtElement>
): CallableInfo? { ): CallableInfo? {
if (expression.typeArguments.isNotEmpty()) return null if (expression.typeArguments.isNotEmpty()) return null
val classDescriptor = expression val classDescriptor = expression
.calleeExpression .calleeExpression
?.getReferenceTargets(analysisResult.bindingContext) ?.getReferenceTargets(analysisResult.bindingContext)
?.mapNotNull { (it as? ConstructorDescriptor)?.containingDeclaration } ?.mapNotNull { (it as? ConstructorDescriptor)?.containingDeclaration }
?.distinct() ?.distinct()
?.singleOrNull() as? ClassDescriptor ?.singleOrNull() as? ClassDescriptor
val klass = classDescriptor?.source?.getPsi() val klass = classDescriptor?.source?.getPsi()
if ((klass !is KtClass && klass !is PsiClass) || !klass.canRefactor()) return null if ((klass !is KtClass && klass !is PsiClass) || !klass.canRefactor()) return null
val expectedType = analysisResult.bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expression.getQualifiedExpressionForSelectorOrThis()] val expectedType =
?: classDescriptor.builtIns.nullableAnyType analysisResult.bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expression.getQualifiedExpressionForSelectorOrThis()]
?: classDescriptor.builtIns.nullableAnyType
if (!classDescriptor.defaultType.isSubtypeOf(expectedType)) return null if (!classDescriptor.defaultType.isSubtypeOf(expectedType)) return null
val parameters = expression.getParameterInfos() val parameters = expression.getParameterInfos()
@@ -335,16 +340,20 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
} }
companion object { companion object {
val FUNCTIONS = arrayOf(Function.Default, val FUNCTIONS = arrayOf(
Function.Abstract, Function.Default,
Function.ByImplicitExtensionReceiver, Function.Abstract,
Constructor) Function.ByImplicitExtensionReceiver,
val INSTANCES = arrayOf(Function.Default, Constructor
Function.Abstract, )
Function.ByImplicitExtensionReceiver, val INSTANCES = arrayOf(
Constructor, Function.Default,
Property.Default, Function.Abstract,
Property.Abstract, Function.ByImplicitExtensionReceiver,
Property.ByImplicitExtensionReceiver) Constructor,
Property.Default,
Property.Abstract,
Property.ByImplicitExtensionReceiver
)
} }
} }