[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.load.java.components.JavaDeprecationSettings
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
@@ -68,6 +69,8 @@ class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) :
override val isReleasedCoroutine
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 =
ResolveEvaluator(moduleDescriptor, languageVersionSettings, expression.project)
@@ -20,7 +20,8 @@ interface KtUltraLightSupport {
val typeMapper: KotlinTypeMapper
val moduleDescriptor: ModuleDescriptor
val isReleasedCoroutine: Boolean
fun hasAlias(file: KtFile, shortName: Name?): Boolean = false
fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean
fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator
companion object {
@@ -52,6 +53,9 @@ class UltraLightSupportViaService(private val ktElement: KtElement) : KtUltraLig
override val isReleasedCoroutine: Boolean
get() = serviceProvidedSupport.isReleasedCoroutine
override fun possiblyHasAlias(file: KtFile, shortName: Name): Boolean =
serviceProvidedSupport.possiblyHasAlias(file, shortName)
override fun getConstantEvaluator(expression: KtExpression): ConstantExpressionEvaluator =
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.StubBuildingVisitor
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.util.BitUtil.isSet
import com.intellij.util.IncorrectOperationException
import com.intellij.util.containers.ConcurrentFactoryMap
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
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.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
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.org.objectweb.asm.Opcodes
import java.text.StringCharacterIterator
import java.util.concurrent.ConcurrentMap
private interface TypeParametersSupport<D, 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 }
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) {
val descriptor = entry.analyzeAnnotation()
if (descriptor?.fqName == fqName) {
@@ -68,6 +68,17 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
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)
override val deprecationResolver: DeprecationResolver
get() = resolutionFacade.getFrontendService(DeprecationResolver::class.java)
@@ -132,19 +143,6 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
override fun getUltraLightClassSupport(element: KtElement): KtUltraLightSupport =
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))
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {