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(
|
||||
element.session.firSymbolProvider,
|
||||
ConeTypeCheckerContext(isErrorTypeEqualsToAnything = true, isStubTypeEqualsToAnything = true, element.session),
|
||||
element.project,
|
||||
validityToken
|
||||
)
|
||||
|
||||
|
||||
+7
-1
@@ -5,6 +5,8 @@
|
||||
|
||||
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 org.jetbrains.kotlin.fir.FirElement
|
||||
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.KtSymbol
|
||||
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(
|
||||
firProvider: FirSymbolProvider,
|
||||
@@ -99,7 +105,7 @@ internal class KtSymbolByFirBuilder(
|
||||
|
||||
|
||||
fun createPackageSymbolIfOneExists(packageFqName: FqName): KtFirPackageSymbol? {
|
||||
val exists = firProvider.getPackage(packageFqName) != null
|
||||
val exists = PackageIndexUtil.packageExists(packageFqName, GlobalSearchScope.allScope(project), project)
|
||||
if (!exists) {
|
||||
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.frontend.api.fir.KtSymbolByFirBuilder
|
||||
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.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
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.getQualifiedExpressionForSelector
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
|
||||
internal object FirReferenceResolveHelper {
|
||||
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(
|
||||
ref: KtFirSimpleNameReference,
|
||||
symbolBuilder: KtSymbolByFirBuilder
|
||||
@@ -135,12 +154,11 @@ internal object FirReferenceResolveHelper {
|
||||
if (parent.selectorExpression !== expression) {
|
||||
// Special: package reference in the middle of import directive
|
||||
// import a.<caret>b.c.SomeClass
|
||||
// TODO: return reference to PsiPackage
|
||||
// return listOf(expression)
|
||||
return emptyList()
|
||||
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder)?.let { return listOf(it) })
|
||||
}
|
||||
parent = parent.parent
|
||||
}
|
||||
|
||||
val classId = fir.resolvedClassId
|
||||
if (classId != null) {
|
||||
return listOfNotNull(classId.toTargetPsi(session, symbolBuilder))
|
||||
@@ -162,8 +180,7 @@ internal object FirReferenceResolveHelper {
|
||||
is FirFile -> {
|
||||
if (expression.getNonStrictParentOfType<KtPackageDirective>() != null) {
|
||||
// Special: package reference in the middle of package directive
|
||||
return emptyList()
|
||||
// return listOf(expression)
|
||||
return listOfNotNull(getPackageSymbolFor(expression, symbolBuilder))
|
||||
}
|
||||
return listOf(symbolBuilder.buildSymbol(fir))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user