FIR IDE: introduce package symbol
This commit is contained in:
+12
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* 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.frontend.api.symbols
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
abstract class KtPackageSymbol : KtSymbol {
|
||||||
|
abstract val fqName: FqName
|
||||||
|
}
|
||||||
+1
@@ -40,6 +40,7 @@ class KtFirAnalysisSession(
|
|||||||
internal val firSymbolBuilder = KtSymbolByFirBuilder(
|
internal val firSymbolBuilder = KtSymbolByFirBuilder(
|
||||||
element.session.firSymbolProvider,
|
element.session.firSymbolProvider,
|
||||||
ConeTypeCheckerContext(isErrorTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true, element.session),
|
ConeTypeCheckerContext(isErrorTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true, element.session),
|
||||||
|
element.project,
|
||||||
validityToken
|
validityToken
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.frontend.api.fir
|
package org.jetbrains.kotlin.idea.frontend.api.fir
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
@@ -28,6 +30,10 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtVariableSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
internal class KtSymbolByFirBuilder(
|
internal class KtSymbolByFirBuilder(
|
||||||
firProvider: FirSymbolProvider,
|
firProvider: FirSymbolProvider,
|
||||||
@@ -99,7 +105,7 @@ internal class KtSymbolByFirBuilder(
|
|||||||
|
|
||||||
|
|
||||||
fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? {
|
fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? {
|
||||||
val exists = firProvider.getPackage(packageFqName) != null
|
val exists = PackageIndexUtil.packageExists(packageFqName, GlobalSearchScope.allScope(project), project)
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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.frontend.api.fir.symbols
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.impl.file.PsiPackageImpl
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwner
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.ValidityOwnerByValidityToken
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.cached
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPackageSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolOrigin
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbolPointer
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.symbolPointer
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
class KtFirPackageSymbol(
|
||||||
|
override val fqName: FqName,
|
||||||
|
private val project: Project,
|
||||||
|
override val token: ValidityOwner
|
||||||
|
) : KtPackageSymbol(), ValidityOwnerByValidityToken {
|
||||||
|
override val psi: PsiElement by cached {
|
||||||
|
KtPackage(PsiManager.getInstance(project), fqName, GlobalSearchScope.allScope(project))
|
||||||
|
}
|
||||||
|
|
||||||
|
override val origin: KtSymbolOrigin
|
||||||
|
get() = KtSymbolOrigin.SOURCE // TODO
|
||||||
|
|
||||||
|
override fun createPointer(): KtSymbolPointer<KtPackageSymbol> = symbolPointer { session ->
|
||||||
|
check(session is KtFirAnalysisSession)
|
||||||
|
session.firSymbolBuilder.createPackageSymbolIfOneExists(fqName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KtPackage(
|
||||||
|
manager: PsiManager,
|
||||||
|
private val fqName: FqName,
|
||||||
|
private val scope: GlobalSearchScope
|
||||||
|
) : PsiPackageImpl(manager, fqName.asString()) {
|
||||||
|
override fun copy() = KtPackage(manager, fqName, scope)
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = PackageIndexUtil.packageExists(fqName, scope, project)
|
||||||
|
}
|
||||||
+22
-5
@@ -20,10 +20,15 @@ import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
|||||||
import org.jetbrains.kotlin.idea.fir.*
|
import org.jetbrains.kotlin.idea.fir.*
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.buildSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.fir.buildSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPackageSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||||
|
|
||||||
internal object FirReferenceResolveHelper {
|
internal object FirReferenceResolveHelper {
|
||||||
fun FirResolvedTypeRef.toTargetSymbol(session: FirSession, symbolBuilder: KtSymbolByFirBuilder): KtSymbol? {
|
fun FirResolvedTypeRef.toTargetSymbol(session: FirSession, symbolBuilder: KtSymbolByFirBuilder): KtSymbol? {
|
||||||
@@ -81,6 +86,20 @@ internal object FirReferenceResolveHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getPackageSymbolFor(expression: KtSimpleNameExpression, symbolBuilder: KtSymbolByFirBuilder): KtFirPackageSymbol? {
|
||||||
|
val fqName = when (val qualified = expression.getQualifiedExpressionForSelector()) {
|
||||||
|
null -> FqName(expression.getReferencedName())
|
||||||
|
else -> {
|
||||||
|
qualified
|
||||||
|
.collectDescendantsOfType<KtSimpleNameExpression>()
|
||||||
|
.joinToString(separator = ".") { it.getReferencedName() }
|
||||||
|
.let(::FqName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbolBuilder.createPackageSymbolIfOneExists(fqName)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun resolveSimpleNameReference(
|
internal fun resolveSimpleNameReference(
|
||||||
ref: KtFirSimpleNameReference,
|
ref: KtFirSimpleNameReference,
|
||||||
symbolBuilder: KtSymbolByFirBuilder
|
symbolBuilder: KtSymbolByFirBuilder
|
||||||
@@ -135,12 +154,11 @@ internal object FirReferenceResolveHelper {
|
|||||||
if (parent.selectorExpression !== expression) {
|
if (parent.selectorExpression !== expression) {
|
||||||
// Special: package reference in the middle of import directive
|
// Special: package reference in the middle of import directive
|
||||||
// import a.<caret>b.c.SomeClass
|
// import a.<caret>b.c.SomeClass
|
||||||
// TODO: return reference to PsiPackage
|
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder)?.let { return listOf(it) })
|
||||||
// return listOf(expression)
|
|
||||||
return emptyList()
|
|
||||||
}
|
}
|
||||||
parent = parent.parent
|
parent = parent.parent
|
||||||
}
|
}
|
||||||
|
|
||||||
val classId = fir.resolvedClassId
|
val classId = fir.resolvedClassId
|
||||||
if (classId != null) {
|
if (classId != null) {
|
||||||
return listOfNotNull(classId.toTargetPsi(session, symbolBuilder))
|
return listOfNotNull(classId.toTargetPsi(session, symbolBuilder))
|
||||||
@@ -162,8 +180,7 @@ internal object FirReferenceResolveHelper {
|
|||||||
is FirFile -> {
|
is FirFile -> {
|
||||||
if (expression.getNonStrictParentOfType<KtPackageDirective>() != null) {
|
if (expression.getNonStrictParentOfType<KtPackageDirective>() != null) {
|
||||||
// Special: package reference in the middle of package directive
|
// Special: package reference in the middle of package directive
|
||||||
return emptyList()
|
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder))
|
||||||
// return listOf(expression)
|
|
||||||
}
|
}
|
||||||
return listOf(symbolBuilder.buildSymbol(fir))
|
return listOf(symbolBuilder.buildSymbol(fir))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user