[ULC] Fix invalid alias search for UL classes

This commit is contained in:
Igor Yakovlev
2020-07-16 02:00:26 +03:00
parent 2c16ae968d
commit 131c14626c
4 changed files with 27 additions and 24 deletions
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings import org.jetbrains.kotlin.load.java.components.JavaDeprecationSettings
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
@@ -68,6 +69,8 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
override val isReleasedCoroutine override val isReleasedCoroutine
get() = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) get() = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
override fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean = true
override fun getConstantEvaluator(expression: KtExpression): org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator = override fun getConstantEvaluator(expression: KtExpression): org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator =
ResolveEvaluator(moduleDescriptor, languageVersionSettings, expression.project) ResolveEvaluator(moduleDescriptor, languageVersionSettings, expression.project)
@@ -20,7 +20,8 @@ interface KtUltraLightSupport {
val typeMapper: KotlinTypeMapper val typeMapper: KotlinTypeMapper
val moduleDescriptor: ModuleDescriptor val moduleDescriptor: ModuleDescriptor
val isReleasedCoroutine: Boolean val isReleasedCoroutine: Boolean
fun hasAlias(file: KtFile, shortName: Name?): Boolean = false fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean
fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator
companion object { companion object {
@@ -52,6 +53,9 @@ class UltraLightSupportViaService(private val ktElement: KtElement) : KtUltraLig
override val isReleasedCoroutine: Boolean override val isReleasedCoroutine: Boolean
get() = serviceProvidedSupport.isReleasedCoroutine get() = serviceProvidedSupport.isReleasedCoroutine
override fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean =
serviceProvidedSupport.possiblyHasAlias(file, shortName)
override fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator = override fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator =
serviceProvidedSupport.getConstantEvaluator(expression) serviceProvidedSupport.getConstantEvaluator(expression)
} }
@@ -16,13 +16,9 @@ import com.intellij.psi.impl.compiled.ClsTypeElementImpl
import com.intellij.psi.impl.compiled.SignatureParsing import com.intellij.psi.impl.compiled.SignatureParsing
import com.intellij.psi.impl.compiled.StubBuildingVisitor import com.intellij.psi.impl.compiled.StubBuildingVisitor
import com.intellij.psi.impl.light.* import com.intellij.psi.impl.light.*
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.psi.util.TypeConversionUtil import com.intellij.psi.util.TypeConversionUtil
import com.intellij.util.BitUtil.isSet import com.intellij.util.BitUtil.isSet
import com.intellij.util.IncorrectOperationException import com.intellij.util.IncorrectOperationException
import com.intellij.util.containers.ConcurrentFactoryMap
import com.intellij.util.containers.ContainerUtil import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.UltraLightClassModifierExtension import org.jetbrains.kotlin.asJava.UltraLightClassModifierExtension
@@ -46,10 +42,8 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
@@ -66,7 +60,6 @@ import org.jetbrains.kotlin.types.replace
import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import java.text.StringCharacterIterator import java.text.StringCharacterIterator
import java.util.concurrent.ConcurrentMap
private interface TypeParametersSupport<D, T> { private interface TypeParametersSupport<D, T> {
fun parameters(declaration: D): List<T> fun parameters(declaration: D): List<T>
@@ -493,9 +486,14 @@ inline fun KtFile.safeIsScript() = runReadAction { this.isScript() }
inline fun KtFile.safeScript() = runReadAction { this.script } inline fun KtFile.safeScript() = runReadAction { this.script }
internal fun KtUltraLightSupport.findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>? { internal fun KtUltraLightSupport.findAnnotation(owner: KtAnnotated, fqName: FqName): Pair<KtAnnotationEntry, AnnotationDescriptor>? {
val candidates = owner.annotationEntries.filter {
it.shortName == fqName.shortName() || hasAlias(owner.containingKtFile, it.shortName) val candidates = owner.annotationEntries
} .filter {
it.shortName?.let { name ->
name == fqName.shortName() || possiblyHasAlias(owner.containingKtFile, name)
} ?: false
}
for (entry in candidates) { for (entry in candidates) {
val descriptor = entry.analyzeAnnotation() val descriptor = entry.analyzeAnnotation()
if (descriptor?.fqName == fqName) { if (descriptor?.fqName == fqName) {
@@ -68,6 +68,17 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
JvmCodegenUtil.getModuleName(moduleDescriptor) JvmCodegenUtil.getModuleName(moduleDescriptor)
} }
override fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean =
allAliases(file)[shortName.asString()] == true
private fun allAliases(file: KtFile): ConcurrentMap<String, Boolean> = CachedValuesManager.getCachedValue(file) {
val importAliases = file.importDirectives.mapNotNull { it.aliasName }.toSet()
val map = ConcurrentFactoryMap.createMap<String, Boolean> { s ->
s in importAliases || KotlinTypeAliasShortNameIndex.getInstance().get(s, file.project, file.resolveScope).isNotEmpty()
}
CachedValueProvider.Result.create<ConcurrentMap<String, Boolean>>(map, PsiModificationTracker.MODIFICATION_COUNT)
}
@OptIn(FrontendInternals::class) @OptIn(FrontendInternals::class)
override val deprecationResolver: DeprecationResolver override val deprecationResolver: DeprecationResolver
get() = resolutionFacade.getFrontendService(DeprecationResolver::class.java) get() = resolutionFacade.getFrontendService(DeprecationResolver::class.java)
@@ -132,19 +143,6 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport = override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport =
KtUltraLightSupportImpl(element) KtUltraLightSupportImpl(element)
private fun KtFile.hasAlias(shortName: Name?): Boolean {
if (shortName == null) return false
return allAliases(this)[shortName.asString()] == true
}
private fun allAliases(file: KtFile): ConcurrentMap<String, Boolean> = CachedValuesManager.getCachedValue(file) {
val importAliases = file.importDirectives.mapNotNull { it.aliasName }.toSet()
val map = ConcurrentFactoryMap.createMap<String, Boolean> { s ->
s in importAliases || KotlinTypeAliasShortNameIndex.getInstance().get(s, project, file.resolveScope).isNotEmpty()
}
CachedValueProvider.Result.create<ConcurrentMap<String, Boolean>>(map, PsiModificationTracker.MODIFICATION_COUNT)
}
private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project)) private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project))
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass { override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {