From 8434806f567311d1b5481499f7d999d46b5e8551 Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Thu, 14 May 2020 16:49:24 +0300 Subject: [PATCH] Ide-common: `resolveToKotlinType` moved to TypeUtils.kt in the *ide-common* --- .../jetbrains/kotlin/idea/util/TypeUtils.kt | 80 ++++++++++++++++++- .../crossLanguage/ChangeMethodParameters.kt | 1 + .../ChangeMethodParameters.kt.191 | 1 + .../KotlinElementActionsFactory.kt | 74 +---------------- .../KotlinElementActionsFactory.kt.191 | 57 +------------ 5 files changed, 82 insertions(+), 131 deletions(-) diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt index 4716d2042ba..c71b07cc15e 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/TypeUtils.kt @@ -7,19 +7,35 @@ package org.jetbrains.kotlin.idea.util +import com.intellij.psi.* import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.builtins.replaceReturnType -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport +import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.load.java.components.TypeUsage +import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents +import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext +import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver +import org.jetbrains.kotlin.load.java.lazy.child +import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor +import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeAttributes +import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver +import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter +import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl +import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeParameterImpl +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier +import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.* import org.jetbrains.kotlin.utils.SmartSet @@ -183,3 +199,61 @@ fun KotlinType.isAbstract(): Boolean { val modality = (constructor.declarationDescriptor as? ClassDescriptor)?.modality return modality == Modality.ABSTRACT || modality == Modality.SEALED } + +/** + * NOTE: this is a very shaky implementation of [PsiType] to [KotlinType] conversion, + * produced types are fakes and are usable only for code generation. Please be careful using this method. + */ +fun PsiType.resolveToKotlinType(resolutionFacade: ResolutionFacade): KotlinType { + if (this == PsiType.NULL) { + return resolutionFacade.moduleDescriptor.builtIns.nullableAnyType + } + + val typeParameters = collectTypeParameters() + val components = resolutionFacade.getFrontendService(JavaResolverComponents::class.java) + val rootContext = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null } + val dummyPackageDescriptor = MutablePackageFragmentDescriptor(resolutionFacade.moduleDescriptor, FqName("dummy")) + val dummyClassDescriptor = ClassDescriptorImpl( + dummyPackageDescriptor, + Name.identifier("Dummy"), + Modality.FINAL, + ClassKind.CLASS, + emptyList(), + SourceElement.NO_SOURCE, + false, + LockBasedStorageManager.NO_LOCKS + ) + val typeParameterResolver = object : TypeParameterResolver { + override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? { + val psiTypeParameter = (javaTypeParameter as JavaTypeParameterImpl).psi + val index = typeParameters.indexOf(psiTypeParameter) + if (index < 0) return null + return LazyJavaTypeParameterDescriptor(rootContext.child(this), javaTypeParameter, index, dummyClassDescriptor) + } + } + val typeResolver = JavaTypeResolver(rootContext, typeParameterResolver) + val attributes = JavaTypeAttributes(TypeUsage.COMMON) + return typeResolver.transformJavaType(JavaTypeImpl.create(this), attributes).approximateFlexibleTypes(preferNotNull = true) +} + + +private fun PsiType.collectTypeParameters(): List { + val results = ArrayList() + accept( + object : PsiTypeVisitor() { + override fun visitArrayType(arrayType: PsiArrayType) { + arrayType.componentType.accept(this) + } + + override fun visitClassType(classType: PsiClassType) { + (classType.resolve() as? PsiTypeParameter)?.let { results += it } + classType.parameters.forEach { it.accept(this) } + } + + override fun visitWildcardType(wildcardType: PsiWildcardType) { + wildcardType.bound?.accept(this) + } + } + ) + return results +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt index bc23f15d618..c830cc7110c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.resolveToKotlinType import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS import org.jetbrains.kotlin.name.FqName diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt.191 b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt.191 index 5a45f0d31b8..f817dddc5f4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt.191 +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/ChangeMethodParameters.kt.191 @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.resolveToKotlinType import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS import org.jetbrains.kotlin.name.FqName diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt index fa7ec39b38f..99fb330c1bd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt @@ -25,11 +25,9 @@ import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.caches.resolve.KotlinCacheService -import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget -import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl -import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.resolveClassByFqName import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade @@ -41,23 +39,11 @@ import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.CreateCallableFromUsageFix import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes +import org.jetbrains.kotlin.idea.util.resolveToKotlinType import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME -import org.jetbrains.kotlin.load.java.components.TypeUsage -import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents -import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext -import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver -import org.jetbrains.kotlin.load.java.lazy.child -import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor -import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeAttributes -import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver -import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter -import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl -import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeParameterImpl import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer @@ -65,7 +51,6 @@ import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType import org.jetbrains.kotlin.resolve.AnnotationChecker import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.supertypes @@ -478,58 +463,3 @@ private fun renderAttributeValue(annotationAttributeRequest: AnnotationAttribute is AnnotationAttributeValueRequest.PrimitiveValue -> annotationAttributeRequest.value is AnnotationAttributeValueRequest.StringValue -> "\"" + annotationAttributeRequest.value + "\"" } - - -private fun PsiType.collectTypeParameters(): List { - val results = ArrayList() - accept( - object : PsiTypeVisitor() { - override fun visitArrayType(arrayType: PsiArrayType) { - arrayType.componentType.accept(this) - } - - override fun visitClassType(classType: PsiClassType) { - (classType.resolve() as? PsiTypeParameter)?.let { results += it } - classType.parameters.forEach { it.accept(this) } - } - - override fun visitWildcardType(wildcardType: PsiWildcardType) { - wildcardType.bound?.accept(this) - } - } - ) - return results -} - - -internal fun PsiType.resolveToKotlinType(resolutionFacade: ResolutionFacade): KotlinType? { - if (this == PsiType.NULL) { - return resolutionFacade.moduleDescriptor.builtIns.nullableAnyType - } - - val typeParameters = collectTypeParameters() - val components = resolutionFacade.getFrontendService(JavaResolverComponents::class.java) - val rootContext = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null } - val dummyPackageDescriptor = MutablePackageFragmentDescriptor(resolutionFacade.moduleDescriptor, FqName("dummy")) - val dummyClassDescriptor = ClassDescriptorImpl( - dummyPackageDescriptor, - Name.identifier("Dummy"), - Modality.FINAL, - ClassKind.CLASS, - emptyList(), - SourceElement.NO_SOURCE, - false, - LockBasedStorageManager.NO_LOCKS - ) - val typeParameterResolver = object : TypeParameterResolver { - override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? { - val psiTypeParameter = (javaTypeParameter as JavaTypeParameterImpl).psi - val index = typeParameters.indexOf(psiTypeParameter) - if (index < 0) return null - return LazyJavaTypeParameterDescriptor(rootContext.child(this), javaTypeParameter, index, dummyClassDescriptor) - } - } - val typeResolver = JavaTypeResolver(rootContext, typeParameterResolver) - val attributes = JavaTypeAttributes(TypeUsage.COMMON) - return typeResolver.transformJavaType(JavaTypeImpl.create(this), attributes).approximateFlexibleTypes(preferNotNull = true) -} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt.191 b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt.191 index a669434e61b..9e64013fb82 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt.191 +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/crossLanguage/KotlinElementActionsFactory.kt.191 @@ -42,7 +42,7 @@ import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.* import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.CreateCallableFromUsageFix import org.jetbrains.kotlin.idea.resolve.ResolutionFacade -import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes +import org.jetbrains.kotlin.idea.util.resolveToKotlinType import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME @@ -495,60 +495,5 @@ private fun renderAttributeValue(annotationAttributeRequest: AnnotationAttribute } -private fun PsiType.collectTypeParameters(): List { - val results = ArrayList() - accept( - object : PsiTypeVisitor() { - override fun visitArrayType(arrayType: PsiArrayType) { - arrayType.componentType.accept(this) - } - - override fun visitClassType(classType: PsiClassType) { - (classType.resolve() as? PsiTypeParameter)?.let { results += it } - classType.parameters.forEach { it.accept(this) } - } - - override fun visitWildcardType(wildcardType: PsiWildcardType) { - wildcardType.bound?.accept(this) - } - } - ) - return results -} - - -internal fun PsiType.resolveToKotlinType(resolutionFacade: ResolutionFacade): KotlinType? { - if (this == PsiType.NULL) { - return resolutionFacade.moduleDescriptor.builtIns.nullableAnyType - } - - val typeParameters = collectTypeParameters() - val components = resolutionFacade.getFrontendService(JavaResolverComponents::class.java) - val rootContext = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null } - val dummyPackageDescriptor = MutablePackageFragmentDescriptor(resolutionFacade.moduleDescriptor, FqName("dummy")) - val dummyClassDescriptor = ClassDescriptorImpl( - dummyPackageDescriptor, - Name.identifier("Dummy"), - Modality.FINAL, - ClassKind.CLASS, - emptyList(), - SourceElement.NO_SOURCE, - false, - LockBasedStorageManager.NO_LOCKS - ) - val typeParameterResolver = object : TypeParameterResolver { - override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? { - val psiTypeParameter = (javaTypeParameter as JavaTypeParameterImpl).psi - val index = typeParameters.indexOf(psiTypeParameter) - if (index < 0) return null - return LazyJavaTypeParameterDescriptor(rootContext.child(this), javaTypeParameter, index, dummyClassDescriptor) - } - } - val typeResolver = JavaTypeResolver(rootContext, typeParameterResolver) - val attributes = JavaTypeAttributes(TypeUsage.COMMON) - return typeResolver.transformJavaType(JavaTypeImpl.create(this), attributes).approximateFlexibleTypes(preferNotNull = true) -} - - private fun JvmPsiConversionHelper.asPsiType(param: Pair>): PsiType? = param.second.firstOrNull()?.theType?.let { convertType(it) }