FIR IDE: introduce KtFirCollectionLiteralReference
This commit is contained in:
+17
-1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
@@ -89,12 +90,27 @@ object KtDeclarationAndFirDeclarationEqualityChecker {
|
||||
else -> error("Invalid type reference $this")
|
||||
}
|
||||
return if (isVararg) {
|
||||
"kotlin.Array<out $rendered>"
|
||||
rendered.asArrayType()
|
||||
} else {
|
||||
rendered
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.asArrayType(): String {
|
||||
classIdToName[this]?.let { return it }
|
||||
return "kotlin.Array<out $this>"
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private val classIdToName: Map<String, String> = buildList {
|
||||
StandardClassIds.primitiveArrayTypeByElementType.mapTo(this) { (classId, arrayClassId) ->
|
||||
classId.asString().replace('/', '.') to arrayClassId.asString().replace('/', '.')
|
||||
}
|
||||
StandardClassIds.unsignedArrayTypeByElementType.mapTo(this) { (classId, arrayClassId) ->
|
||||
classId.asString().replace('/', '.') to arrayClassId.asString().replace('/', '.')
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
private fun FirTypeProjection.renderTypeAsKotlinType() = when (this) {
|
||||
is FirStarProjection -> "*"
|
||||
is FirTypeProjectionWithVariance -> buildString {
|
||||
|
||||
+1
@@ -15,6 +15,7 @@ class KotlinFirReferenceContributor : KotlinReferenceProviderContributor {
|
||||
registerProvider(factory = ::KtFirDestructuringDeclarationReference)
|
||||
registerProvider(factory = ::KtFirArrayAccessReference)
|
||||
registerProvider(factory = ::KtFirConstructorDelegationReference)
|
||||
registerProvider(factory = ::KtFirCollectionLiteralReference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.references
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirSafe
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
|
||||
|
||||
class KtFirCollectionLiteralReference(
|
||||
expression: KtCollectionLiteralExpression
|
||||
) : KtCollectionLiteralReference(expression), KtFirReference {
|
||||
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
|
||||
check(this is KtFirAnalysisSession)
|
||||
val fir = element.getOrBuildFirSafe<FirArrayOfCall>(firResolveState) ?: return emptyList()
|
||||
val type = fir.typeRef.coneTypeSafe<ConeClassLikeType>() ?: return listOfNotNull(arrayOfSymbol(arrayOf))
|
||||
val call = arrayTypeToArrayOfCall[type.lookupTag.classId] ?: arrayOf
|
||||
return listOfNotNull(arrayOfSymbol(call))
|
||||
}
|
||||
|
||||
private fun KtFirAnalysisSession.arrayOfSymbol(identifier: Name): KtSymbol? {
|
||||
val fir = firResolveState.rootModuleSession.firSymbolProvider.getTopLevelCallableSymbols(kotlinPackage, identifier).firstOrNull {
|
||||
/* choose (for byte array)
|
||||
* public fun byteArrayOf(vararg elements: kotlin.Byte): kotlin.ByteArray
|
||||
*/
|
||||
(it as? FirFunctionSymbol<*>)?.fir?.valueParameters?.singleOrNull()?.isVararg == true
|
||||
}?.fir as? FirSimpleFunction ?: return null
|
||||
return firSymbolBuilder.buildFunctionSymbol(fir)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val kotlinPackage = FqName("kotlin")
|
||||
private val arrayOf = Name.identifier("arrayOf")
|
||||
private val arrayTypeToArrayOfCall = run {
|
||||
StandardClassIds.primitiveArrayTypeByElementType.values + StandardClassIds.unsignedArrayTypeByElementType.values
|
||||
}.associateWith { it.correspondingArrayOfCallFqName() }
|
||||
|
||||
private fun ClassId.correspondingArrayOfCallFqName(): Name =
|
||||
Name.identifier("${shortClassName.identifier.decapitalize()}Of")
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
val abc = <caret>[1, 2, 3]
|
||||
|
||||
// REF: (kotlin).arrayOf(vararg T)
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_FIR
|
||||
|
||||
val abc: IntArray = [1, 2, 3<caret>]
|
||||
|
||||
// REF: (kotlin).intArrayOf(vararg kotlin.Int)
|
||||
Reference in New Issue
Block a user