Introduce new type renderers (no parameters & built-in annotations)

This commit is contained in:
Mikhail Glukhikh
2018-05-15 13:09:49 +03:00
parent 1ba99fde56
commit 06f7e77006
6 changed files with 25 additions and 26 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.util package org.jetbrains.kotlin.idea.util
import org.jetbrains.kotlin.descriptors.annotations.BuiltInAnnotationDescriptor
import org.jetbrains.kotlin.renderer.* import org.jetbrains.kotlin.renderer.*
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isDynamic import org.jetbrains.kotlin.types.isDynamic
@@ -57,6 +58,20 @@ object IdeDescriptorRenderers {
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) } typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) }
} }
@JvmField val SOURCE_CODE_TYPES: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) }
annotationFilter = { it !is BuiltInAnnotationDescriptor }
parameterNamesInFunctionalTypes = false
}
@JvmField val SOURCE_CODE_TYPES_WITH_SHORT_NAMES: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SHORT
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES(unwrapAnonymousType(it)) }
modifiers -= DescriptorRendererModifier.ANNOTATIONS
parameterNamesInFunctionalTypes = false
}
@JvmField val SOURCE_CODE_NOT_NULL_TYPE_APPROXIMATION: DescriptorRenderer = BASE.withOptions { @JvmField val SOURCE_CODE_NOT_NULL_TYPE_APPROXIMATION: DescriptorRenderer = BASE.withOptions {
classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED
typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES_NOT_NULL(unwrapAnonymousType(it)) } typeNormalizer = { APPROXIMATE_FLEXIBLE_TYPES_NOT_NULL(unwrapAnonymousType(it)) }
@@ -34,8 +34,8 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.makeNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable
class CastExpressionFix(element: KtExpression, type: KotlinType) : KotlinQuickFixAction<KtExpression>(element) { class CastExpressionFix(element: KtExpression, type: KotlinType) : KotlinQuickFixAction<KtExpression>(element) {
private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE.renderType(type) private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_TYPES_WITH_SHORT_NAMES.renderType(type)
private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type) private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE_TYPES.renderType(type)
private val upOrDownCast: Boolean = run { private val upOrDownCast: Boolean = run {
val expressionType = element.analyze(BodyResolveMode.PARTIAL).getType(element) val expressionType = element.analyze(BodyResolveMode.PARTIAL).getType(element)
expressionType != null && (type.isSubtypeOf(expressionType) || expressionType.isSubtypeOf(type)) expressionType != null && (type.isSubtypeOf(expressionType) || expressionType.isSubtypeOf(type))
@@ -55,8 +55,8 @@ abstract class ChangeCallableReturnTypeFix(
private val changeFunctionLiteralReturnTypeFix: ChangeFunctionLiteralReturnTypeFix? private val changeFunctionLiteralReturnTypeFix: ChangeFunctionLiteralReturnTypeFix?
private val typeContainsError = ErrorUtils.containsErrorType(type) private val typeContainsError = ErrorUtils.containsErrorType(type)
private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type) private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_TYPES_WITH_SHORT_NAMES.renderType(type)
private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE.renderType(type) private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE_TYPES.renderType(type)
private val isUnitType = type.isUnit() private val isUnitType = type.isUnit()
init { init {
@@ -41,8 +41,8 @@ class ChangeFunctionLiteralReturnTypeFix(
type: KotlinType type: KotlinType
) : KotlinQuickFixAction<KtLambdaExpression>(functionLiteralExpression) { ) : KotlinQuickFixAction<KtLambdaExpression>(functionLiteralExpression) {
private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type) private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_TYPES_WITH_SHORT_NAMES.renderType(type)
private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE.renderType(type) private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE_TYPES.renderType(type)
private val functionLiteralReturnTypeRef: KtTypeReference? private val functionLiteralReturnTypeRef: KtTypeReference?
get() = element?.functionLiteral?.typeReference get() = element?.functionLiteral?.typeReference
private val appropriateQuickFix = createAppropriateQuickFix(functionLiteralExpression, type) private val appropriateQuickFix = createAppropriateQuickFix(functionLiteralExpression, type)
@@ -41,8 +41,8 @@ import java.util.*
open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinType) : KotlinQuickFixAction<KtVariableDeclaration>(element) { open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinType) : KotlinQuickFixAction<KtVariableDeclaration>(element) {
private val typeContainsError = ErrorUtils.containsErrorType(type) private val typeContainsError = ErrorUtils.containsErrorType(type)
private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type) private val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_TYPES_WITH_SHORT_NAMES.renderType(type)
private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE.renderType(type) private val typeSourceCode = IdeDescriptorRenderers.SOURCE_CODE_TYPES.renderType(type)
open fun variablePresentation(): String? { open fun variablePresentation(): String? {
val element = element!! val element = element!!
@@ -21,9 +21,6 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.annotations.BuiltInAnnotationDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
@@ -46,22 +43,12 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.KotlinTypeFactory import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.typeUtil.* import org.jetbrains.kotlin.types.typeUtil.*
import java.util.* import java.util.*
//TODO: should use change signature to deal with cases of multiple overridden descriptors //TODO: should use change signature to deal with cases of multiple overridden descriptors
class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() { class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
private fun KotlinType.dropParameterNameAnnotations(): KotlinType {
return KotlinTypeFactory.simpleNotNullType(annotations, constructor.declarationDescriptor as ClassDescriptor, arguments.map {
TypeProjectionImpl(
it.projectionKind,
it.type.replaceAnnotations(AnnotationsImpl(it.type.annotations.filter { it !is BuiltInAnnotationDescriptor }))
)
})
}
private fun KotlinType.reflectToRegularFunctionType(): KotlinType { private fun KotlinType.reflectToRegularFunctionType(): KotlinType {
val isTypeAnnotatedWithExtensionFunctionType = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.extensionFunctionType) != null val isTypeAnnotatedWithExtensionFunctionType = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.extensionFunctionType) != null
val parameterCount = if (isTypeAnnotatedWithExtensionFunctionType) arguments.size - 2 else arguments.size - 1 val parameterCount = if (isTypeAnnotatedWithExtensionFunctionType) arguments.size - 2 else arguments.size - 1
@@ -168,12 +155,9 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
val scope = callable.getResolutionScope(context, callable.getResolutionFacade()) val scope = callable.getResolutionScope(context, callable.getResolutionFacade())
val typeToInsert = expressionType.approximateWithResolvableType(scope, false) val typeToInsert = expressionType.approximateWithResolvableType(scope, false)
if (typeToInsert.constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.KFunction) { if (typeToInsert.constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.KFunction) {
val reflectType = typeToInsert.dropParameterNameAnnotations() actions.add(createFix(callable, typeToInsert.reflectToRegularFunctionType()))
actions.add(createFix(callable, reflectType.reflectToRegularFunctionType()))
actions.add(createFix(callable, reflectType))
} else {
actions.add(createFix(callable, typeToInsert))
} }
actions.add(createFix(callable, typeToInsert))
} }
// Property initializer type mismatch property type: // Property initializer type mismatch property type: