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.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||||
@@ -89,12 +90,27 @@ object KtDeclarationAndFirDeclarationEqualityChecker {
|
|||||||
else -> error("Invalid type reference $this")
|
else -> error("Invalid type reference $this")
|
||||||
}
|
}
|
||||||
return if (isVararg) {
|
return if (isVararg) {
|
||||||
"kotlin.Array<out $rendered>"
|
rendered.asArrayType()
|
||||||
} else {
|
} else {
|
||||||
rendered
|
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) {
|
private fun FirTypeProjection.renderTypeAsKotlinType() = when (this) {
|
||||||
is FirStarProjection -> "*"
|
is FirStarProjection -> "*"
|
||||||
is FirTypeProjectionWithVariance -> buildString {
|
is FirTypeProjectionWithVariance -> buildString {
|
||||||
|
|||||||
+1
@@ -15,6 +15,7 @@ class KotlinFirReferenceContributor : KotlinReferenceProviderContributor {
|
|||||||
registerProvider(factory = ::KtFirDestructuringDeclarationReference)
|
registerProvider(factory = ::KtFirDestructuringDeclarationReference)
|
||||||
registerProvider(factory = ::KtFirArrayAccessReference)
|
registerProvider(factory = ::KtFirArrayAccessReference)
|
||||||
registerProvider(factory = ::KtFirConstructorDelegationReference)
|
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]
|
val abc = <caret>[1, 2, 3]
|
||||||
|
|
||||||
// REF: (kotlin).arrayOf(vararg T)
|
// REF: (kotlin).arrayOf(vararg T)
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
// IGNORE_FIR
|
|
||||||
|
|
||||||
val abc: IntArray = [1, 2, 3<caret>]
|
val abc: IntArray = [1, 2, 3<caret>]
|
||||||
|
|
||||||
// REF: (kotlin).intArrayOf(vararg kotlin.Int)
|
// REF: (kotlin).intArrayOf(vararg kotlin.Int)
|
||||||
Reference in New Issue
Block a user