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.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
)
}
}