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