Refactoring: Use modifier list in CallableInfo where possible

This commit is contained in:
Alexey Sedunov
2017-12-22 14:59:04 +03:00
parent ba0a91d74c
commit 99be75cbfc
14 changed files with 120 additions and 40 deletions
@@ -501,9 +501,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
@Suppress("USELESS_CAST") // KT-10755
if (callableInfo is FunctionInfo) {
val operatorModifier = if (callableInfo.isOperator) "operator " else ""
val infixModifier = if (callableInfo.isInfix) "infix " else ""
psiFactory.createFunction("$modifiers$infixModifier${operatorModifier}fun<> $header $body") as KtNamedDeclaration
psiFactory.createFunction("${modifiers}fun<> $header $body") as KtNamedDeclaration
}
else if ((callableInfo as ConstructorInfo).isPrimary) {
val constructorText = if (modifiers.isNotEmpty()) "${modifiers}constructor$paramList" else paramList
@@ -646,6 +644,13 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
if (TypeUtils.isNullableType(returnType) || KotlinBuiltIns.isPrimitiveType(returnType)) return
declaration.addModifier(KtTokens.LATEINIT_KEYWORD)
}
if (callableInfo.isAbstract) {
val containingClass = declaration.containingClassOrObject
if (containingClass is KtClass && containingClass.isInterface()) {
declaration.removeModifier(KtTokens.ABSTRACT_KEYWORD)
}
}
}
private fun setupDeclarationBody(func: KtDeclarationWithBody) {
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassInfo
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.idea.util.getResolvableApproximations
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -177,16 +178,17 @@ abstract class CallableInfo (
val returnTypeInfo: TypeInfo,
val possibleContainers: List<KtElement>,
val typeParameterInfos: List<TypeInfo>,
val isAbstract: Boolean = false,
val isForCompanion: Boolean = false,
val modifierList: KtModifierList? = null
) {
abstract val kind: CallableKind
abstract val parameterInfos: List<ParameterInfo>
val isAbstract get() = modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) == true
abstract fun copy(receiverTypeInfo: TypeInfo = this.receiverTypeInfo,
possibleContainers: List<KtElement> = this.possibleContainers,
isAbstract: Boolean = this.isAbstract): CallableInfo
modifierList: KtModifierList? = this.modifierList): CallableInfo
}
class FunctionInfo(name: String,
@@ -195,25 +197,25 @@ class FunctionInfo(name: String,
possibleContainers: List<KtElement> = Collections.emptyList(),
override val parameterInfos: List<ParameterInfo> = Collections.emptyList(),
typeParameterInfos: List<TypeInfo> = Collections.emptyList(),
val isOperator: Boolean = false,
val isInfix: Boolean = false,
isAbstract: Boolean = false,
isForCompanion: Boolean = false,
modifierList: KtModifierList? = null,
val preferEmptyBody: Boolean = false
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isAbstract, isForCompanion, modifierList) {
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isForCompanion, modifierList) {
override val kind: CallableKind get() = CallableKind.FUNCTION
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) = FunctionInfo(
override fun copy(
receiverTypeInfo: TypeInfo,
possibleContainers: List<KtElement>,
modifierList: KtModifierList?
) = FunctionInfo(
name,
receiverTypeInfo,
returnTypeInfo,
possibleContainers,
parameterInfos,
typeParameterInfos,
isOperator,
isInfix,
isAbstract
isForCompanion,
modifierList
)
}
@@ -227,7 +229,11 @@ class ClassWithPrimaryConstructorInfo(
override val kind: CallableKind get() = CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR
override val parameterInfos: List<ParameterInfo> get() = classInfo.parameterInfos
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) = throw UnsupportedOperationException()
override fun copy(
receiverTypeInfo: TypeInfo,
possibleContainers: List<KtElement>,
modifierList: KtModifierList?
) = throw UnsupportedOperationException()
}
class ConstructorInfo(
@@ -239,7 +245,11 @@ class ConstructorInfo(
): CallableInfo("", TypeInfo.Empty, TypeInfo.Empty, Collections.emptyList(), Collections.emptyList(), false, modifierList = modifierList) {
override val kind: CallableKind get() = CallableKind.CONSTRUCTOR
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) = throw UnsupportedOperationException()
override fun copy(
receiverTypeInfo: TypeInfo,
possibleContainers: List<KtElement>,
modifierList: KtModifierList?
) = throw UnsupportedOperationException()
}
class PropertyInfo(name: String,
@@ -248,22 +258,24 @@ class PropertyInfo(name: String,
val writable: Boolean,
possibleContainers: List<KtElement> = Collections.emptyList(),
typeParameterInfos: List<TypeInfo> = Collections.emptyList(),
isAbstract: Boolean = false,
val isLateinitPreferred: Boolean = false,
isForCompanion: Boolean = false,
modifierList: KtModifierList? = null,
val withInitializer: Boolean = false
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isAbstract, isForCompanion, modifierList) {
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isForCompanion, modifierList) {
override val kind: CallableKind get() = CallableKind.PROPERTY
override val parameterInfos: List<ParameterInfo> get() = Collections.emptyList()
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) =
copyProperty(receiverTypeInfo, possibleContainers, isAbstract)
override fun copy(
receiverTypeInfo: TypeInfo,
possibleContainers: List<KtElement>,
modifierList: KtModifierList?
) = copyProperty(receiverTypeInfo, possibleContainers, modifierList)
fun copyProperty(
receiverTypeInfo: TypeInfo = this.receiverTypeInfo,
possibleContainers: List<KtElement> = this.possibleContainers,
isAbstract: Boolean = this.isAbstract,
modifierList: KtModifierList? = this.modifierList,
isLateinitPreferred: Boolean = this.isLateinitPreferred
) = PropertyInfo(
name,
@@ -272,7 +284,6 @@ class PropertyInfo(name: String,
writable,
possibleContainers,
typeParameterInfos,
isAbstract,
isLateinitPreferred,
isForCompanion,
modifierList,
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import java.util.*
@@ -55,8 +56,12 @@ object CreateBinaryOperationActionFactory : CreateCallableMemberFromUsageFactory
}
val parameters = Collections.singletonList(ParameterInfo(TypeInfo(argumentExpr, Variance.IN_VARIANCE)))
val isOperator = token != KtTokens.IDENTIFIER
return FunctionInfo(operationName, receiverType, returnType, parameterInfos = parameters,
isOperator = isOperator,
isInfix = !isOperator)
return FunctionInfo(
operationName,
receiverType,
returnType,
parameterInfos = parameters,
modifierList = KtPsiFactory(element).createModifierList(if (isOperator) KtTokens.OPERATOR_KEYWORD else KtTokens.INFIX_KEYWORD)
)
}
}
@@ -153,7 +153,10 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
if (!receiverType.isAbstract() && TypeUtils.getAllSupertypes(receiverType).all { !it.isAbstract() }) return null
return mainCallable.copy(receiverTypeInfo = receiverTypeInfo, possibleContainers = emptyList(), isAbstract = true)
return mainCallable.copy(
receiverTypeInfo = receiverTypeInfo,
possibleContainers = emptyList(),
modifierList = KtPsiFactory(originalExpression).createModifierList(KtTokens.ABSTRACT_KEYWORD))
}
protected fun getCallableWithReceiverInsideExtension(
@@ -23,8 +23,10 @@ import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallableInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
import org.jetbrains.kotlin.types.Variance
@@ -52,6 +54,11 @@ object CreateComponentFunctionActionFactory : CreateCallableMemberFromUsageFacto
val entry = entries[componentNumber]
val returnTypeInfo = TypeInfo(entry, Variance.OUT_VARIANCE)
return FunctionInfo(name.identifier, ownerTypeInfo, returnTypeInfo, isOperator = true)
return FunctionInfo(
name.identifier,
ownerTypeInfo,
returnTypeInfo,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.Callab
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.*
@@ -34,7 +36,12 @@ object CreateGetFunctionActionFactory : CreateGetSetFunctionActionFactory(isGet
val parameters = element.indexExpressions.map { ParameterInfo(TypeInfo(it, Variance.IN_VARIANCE)) }
val returnType = TypeInfo(element, Variance.OUT_VARIANCE)
return FunctionInfo(
OperatorNameConventions.GET.asString(), arrayType, returnType, Collections.emptyList(), parameters, isOperator = true
OperatorNameConventions.GET.asString(),
arrayType,
returnType,
Collections.emptyList(),
parameters,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -24,7 +24,9 @@ import org.jetbrains.kotlin.idea.project.builtIns
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallableInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -38,6 +40,11 @@ object CreateHasNextFunctionActionFactory : CreateCallableMemberFromUsageFactory
DiagnosticFactory.cast(diagnostic, Errors.HAS_NEXT_MISSING, Errors.HAS_NEXT_FUNCTION_NONE_APPLICABLE)
val ownerType = TypeInfo(diagnosticWithParameters.a, Variance.IN_VARIANCE)
val returnType = TypeInfo(element.builtIns.booleanType, Variance.OUT_VARIANCE)
return FunctionInfo(OperatorNameConventions.HAS_NEXT.asString(), ownerType, returnType, isOperator = true)
return FunctionInfo(
OperatorNameConventions.HAS_NEXT.asString(),
ownerType,
returnType,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.Callab
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -48,6 +50,12 @@ object CreateInvokeFunctionActionFactory : CreateCallableMemberFromUsageFactory<
}
val returnType = TypeInfo(element, Variance.OUT_VARIANCE)
return FunctionInfo(OperatorNameConventions.INVOKE.asString(), receiverType, returnType, parameterInfos = parameters, isOperator = true)
return FunctionInfo(
OperatorNameConventions.INVOKE.asString(),
receiverType,
returnType,
parameterInfos = parameters,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -23,9 +23,11 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.Callab
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.guessTypes
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.Variance
@@ -57,6 +59,11 @@ object CreateIteratorFunctionActionFactory : CreateCallableMemberFromUsageFactor
returnJetType.isMarkedNullable,
returnJetType.memberScope)
val returnType = TypeInfo(newReturnJetType, Variance.OUT_VARIANCE)
return FunctionInfo(OperatorNameConventions.ITERATOR.asString(), iterableType, returnType, isOperator = true)
return FunctionInfo(
OperatorNameConventions.ITERATOR.asString(),
iterableType,
returnType,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -23,8 +23,10 @@ import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallableInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.util.OperatorNameConventions
@@ -39,6 +41,11 @@ object CreateNextFunctionActionFactory : CreateCallableMemberFromUsageFactory<Kt
val variableExpr = element.loopParameter ?: element.destructuringDeclaration ?: return null
val returnType = TypeInfo(variableExpr as KtExpression, Variance.OUT_VARIANCE)
return FunctionInfo(OperatorNameConventions.NEXT.asString(), ownerType, returnType, isOperator = true)
return FunctionInfo(
OperatorNameConventions.NEXT.asString(),
ownerType,
returnType,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -26,8 +26,10 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.Callab
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
@@ -61,13 +63,15 @@ object CreatePropertyDelegateAccessorsActionFactory : CreateCallableMemberFromUs
val callableInfos = SmartList<CallableInfo>()
val psiFactory = KtPsiFactory(element)
if (isApplicableForAccessor(propertyDescriptor.getter)) {
val getterInfo = FunctionInfo(
name = OperatorNameConventions.GET_VALUE.asString(),
receiverTypeInfo = accessorReceiverType,
returnTypeInfo = TypeInfo(propertyType, Variance.OUT_VARIANCE),
parameterInfos = listOf(thisRefParam, metadataParam),
isOperator = true
modifierList = psiFactory.createModifierList(KtTokens.OPERATOR_KEYWORD)
)
callableInfos.add(getterInfo)
}
@@ -79,7 +83,7 @@ object CreatePropertyDelegateAccessorsActionFactory : CreateCallableMemberFromUs
receiverTypeInfo = accessorReceiverType,
returnTypeInfo = TypeInfo(builtIns.unitType, Variance.OUT_VARIANCE),
parameterInfos = listOf(thisRefParam, metadataParam, newValueParam),
isOperator = true
modifierList = psiFactory.createModifierList(KtTokens.OPERATOR_KEYWORD)
)
callableInfos.add(setterInfo)
}
@@ -24,10 +24,8 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.Callab
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtOperationExpression
import org.jetbrains.kotlin.psi.KtUnaryExpression
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.Variance
@@ -63,7 +61,12 @@ object CreateSetFunctionActionFactory : CreateGetSetFunctionActionFactory(isGet
val returnType = TypeInfo(builtIns.unitType, Variance.OUT_VARIANCE)
return FunctionInfo(
OperatorNameConventions.SET.asString(), arrayType, returnType, Collections.emptyList(), parameters, isOperator = true
OperatorNameConventions.SET.asString(),
arrayType,
returnType,
Collections.emptyList(),
parameters,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.Callab
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtUnaryExpression
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.OperatorConventions
@@ -39,6 +41,11 @@ object CreateUnaryOperationActionFactory: CreateCallableMemberFromUsageFactory<K
val receiverType = TypeInfo(receiverExpr, Variance.IN_VARIANCE)
val returnType = if (incDec) TypeInfo.ByReceiverType(Variance.OUT_VARIANCE) else TypeInfo(element, Variance.OUT_VARIANCE)
return FunctionInfo(operationName.asString(), receiverType, returnType, isOperator = true)
return FunctionInfo(
operationName.asString(),
receiverType,
returnType,
modifierList = KtPsiFactory(element).createModifierList(KtTokens.OPERATOR_KEYWORD)
)
}
}
@@ -376,7 +376,6 @@ class KotlinElementActionsFactory : JvmElementActionsFactory() {
returnTypeInfo,
listOf(targetContainer),
parameterInfos,
isAbstract = JvmModifier.ABSTRACT in request.modifiers,
isForCompanion = JvmModifier.STATIC in request.modifiers,
modifierList = modifierBuilder.modifierList,
preferEmptyBody = true