[Analysis API] Add API for obtaining scope with synthetic properties

^KTIJ-22359 Fixed
This commit is contained in:
aleksandrina-streltsova
2022-12-21 18:18:38 +02:00
committed by teamcity
parent e517df1533
commit f3cbc1b2d4
3 changed files with 44 additions and 23 deletions
@@ -72,7 +72,7 @@ internal class KtFe10ScopeProvider(
return KtFe10ScopeMember(DeclaredMemberScope(descriptor), descriptor.constructors, analysisContext)
}
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtScope {
val descriptor = getDescriptor<ClassDescriptor>(classSymbol)
?: return getEmptyScope()
@@ -191,6 +191,11 @@ internal class KtFe10ScopeProvider(
TODO()
}
override fun getSyntheticJavaPropertiesScope(type: KtType): KtTypeScope {
require(type is KtFe10Type)
TODO()
}
override fun getScopeContextForPosition(originalFile: KtFile, positionInFakeFile: KtElement): KtScopeContext {
val elementToAnalyze = positionInFakeFile.containingNonLocalDeclaration() ?: originalFile
val bindingContext = analysisContext.analyze(elementToAnalyze)
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.analysis.api.fir.components
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.components.KtImplicitReceiver
import org.jetbrains.kotlin.analysis.api.components.KtScopeContext
import org.jetbrains.kotlin.analysis.api.components.KtScopeProvider
@@ -19,7 +18,6 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFileSymbol
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtCompositeScope
import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtCompositeTypeScope
import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtEmptyScope
import org.jetbrains.kotlin.analysis.api.scopes.KtScope
import org.jetbrains.kotlin.analysis.api.scopes.KtTypeScope
@@ -38,11 +36,8 @@ import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.*
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.name.FqName
@@ -165,23 +160,16 @@ internal class KtFirScopeProvider(
return KtCompositeScope(subScopes, token)
}
@OptIn(KtAnalysisApiInternals::class)
override fun getTypeScope(type: KtType): KtTypeScope? {
override fun getTypeScope(type: KtType): KtTypeScope? = getFirTypeScope(type)?.let { convertToKtTypeScope(it) }
override fun getSyntheticJavaPropertiesScope(type: KtType): KtTypeScope? {
check(type is KtFirType) { "KtFirScopeProvider can only work with KtFirType, but ${type::class} was provided" }
val firSession = firResolveSession.useSiteFirSession
val firTypeScope = type.coneType.scope(
firSession,
scopeSession,
FakeOverrideTypeCalculator.Forced,
requiredPhase = FirResolvePhase.STATUS,
) ?: return null
return KtCompositeTypeScope(
listOfNotNull(
convertToKtTypeScope(firTypeScope),
FirSyntheticPropertiesScope.createIfSyntheticNamesProviderIsDefined(firSession, type.coneType, firTypeScope)?.let { convertToKtTypeScope(it) }
),
token
)
val firTypeScope = getFirTypeScope(type) ?: return null
return FirSyntheticPropertiesScope.createIfSyntheticNamesProviderIsDefined(
firResolveSession.useSiteFirSession,
type.coneType,
firTypeScope
)?.let { convertToKtTypeScope(it) }
}
override fun getScopeContextForPosition(
@@ -246,6 +234,16 @@ internal class KtFirScopeProvider(
else -> TODO(firScope::class.toString())
}
}
private fun getFirTypeScope(type: KtType): FirTypeScope? {
check(type is KtFirType) { "KtFirScopeProvider can only work with KtFirType, but ${type::class} was provided" }
return type.coneType.scope(
firResolveSession.useSiteFirSession,
scopeSession,
FakeOverrideTypeCalculator.Forced,
requiredPhase = FirResolvePhase.STATUS,
)
}
}
private class EnumEntryContainingNamesAwareScope(private val originalScope: FirContainingNamesAwareScope) : FirContainingNamesAwareScope() {
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
@@ -37,6 +38,8 @@ public abstract class KtScopeProvider : KtAnalysisSessionComponent() {
public abstract fun getTypeScope(type: KtType): KtTypeScope?
public abstract fun getSyntheticJavaPropertiesScope(type: KtType): KtTypeScope?
public abstract fun getScopeContextForPosition(
originalFile: KtFile,
positionInFakeFile: KtElement
@@ -44,6 +47,10 @@ public abstract class KtScopeProvider : KtAnalysisSessionComponent() {
}
public interface KtScopeProviderMixIn : KtAnalysisSessionMixIn {
/**
* Creates [KtScope] containing members of [KtDeclaration].
* Returned [KtScope] doesn't include synthetic Java properties. To get such properties use [getSyntheticJavaPropertiesScope].
*/
public fun KtSymbolWithMembers.getMemberScope(): KtScope =
withValidityAssertion { analysisSession.scopeProvider.getMemberScope(this) }
@@ -81,6 +88,7 @@ public interface KtScopeProviderMixIn : KtAnalysisSessionMixIn {
* Inside the `LIST_KT_ELEMENT.getKtType().getTypeScope()` would contain the `get(i: Int): String` method with substituted type `T = String`
*
* @return type scope for the given type if given `KtType` is not error type, `null` otherwise.
* Returned [KtTypeScope] doesn't include synthetic Java properties. To get such properties use [getSyntheticJavaPropertiesScope].
*
* @see KtTypeScope
* @see KtTypeProviderMixIn.getKtType
@@ -88,6 +96,16 @@ public interface KtScopeProviderMixIn : KtAnalysisSessionMixIn {
public fun KtType.getTypeScope(): KtTypeScope? =
withValidityAssertion { analysisSession.scopeProvider.getTypeScope(this) }
/**
* Returns a [KtTypeScope] with synthetic Java properties created for a given [KtType].
*/
public fun KtType.getSyntheticJavaPropertiesScope(): KtTypeScope? =
withValidityAssertion { analysisSession.scopeProvider.getSyntheticJavaPropertiesScope(this) }
/**
* Scopes in returned [KtScopeContext] don't include synthetic Java properties.
* To get such properties use [getSyntheticJavaPropertiesScope].
*/
public fun KtFile.getScopeContextForPosition(positionInFakeFile: KtElement): KtScopeContext =
withValidityAssertion { analysisSession.scopeProvider.getScopeContextForPosition(this, positionInFakeFile) }