[AA FIR] support symbol restoring for static members

^KT-55487 Fixed
This commit is contained in:
Dmitrii Gridin
2022-12-14 23:33:36 +01:00
committed by Space Team
parent f3c7972d20
commit e476150025
34 changed files with 581 additions and 18 deletions
@@ -117,6 +117,7 @@ internal class KtFirFunctionSymbol(
requireOwnerPointer(),
firSymbol.name,
FirCallableSignature.createSignature(firSymbol),
isStatic = firSymbol.isStatic,
)
KtSymbolKind.LOCAL -> throw CanNotCreateSymbolPointerForLocalLibraryDeclarationException(
@@ -55,7 +55,7 @@ internal class KtFirJavaFieldSymbol(
context(KtAnalysisSession)
override fun createPointer(): KtSymbolPointer<KtJavaFieldSymbol> = withValidityAssertion {
KtFirJavaFieldSymbolPointer(requireOwnerPointer(), name)
KtFirJavaFieldSymbolPointer(requireOwnerPointer(), name, firSymbol.isStatic)
}
override fun equals(other: Any?): Boolean = symbolEquals(other)
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.isOverride
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirSyntheticPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.isExtension
import org.jetbrains.kotlin.name.CallableId
@@ -97,7 +98,11 @@ internal class KtFirSyntheticJavaPropertySymbol(
context(KtAnalysisSession)
override fun createPointer(): KtSymbolPointer<KtSyntheticJavaPropertySymbol> = withValidityAssertion {
KtFirJavaSyntheticPropertySymbolPointer(requireOwnerPointer(), name)
KtFirJavaSyntheticPropertySymbolPointer(
ownerPointer = requireOwnerPointer(),
propertyName = name,
isSynthetic = firSymbol is SyntheticSymbol,
)
}
override fun equals(other: Any?): Boolean = symbolEquals(other)
@@ -18,7 +18,8 @@ import org.jetbrains.kotlin.name.Name
internal class KtFirJavaFieldSymbolPointer(
ownerPointer: KtSymbolPointer<KtSymbolWithMembers>,
private val fieldName: Name,
) : KtFirMemberSymbolPointer<KtJavaFieldSymbol>(ownerPointer) {
isStatic: Boolean,
) : KtFirMemberSymbolPointer<KtJavaFieldSymbol>(ownerPointer, isStatic) {
override fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: FirScope,
firSession: FirSession,
@@ -11,13 +11,18 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertiesScope
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.getProperties
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.name.Name
internal class KtFirJavaSyntheticPropertySymbolPointer(
ownerPointer: KtSymbolPointer<KtSymbolWithMembers>,
private val propertyName: Name,
private val isSynthetic: Boolean,
) : KtFirMemberSymbolPointer<KtSyntheticJavaPropertySymbol>(ownerPointer) {
override fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: FirScope,
@@ -30,4 +35,18 @@ internal class KtFirJavaSyntheticPropertySymbolPointer(
return firSymbolBuilder.variableLikeBuilder.buildSyntheticJavaPropertySymbol(syntheticProperty.symbol)
}
context(KtFirAnalysisSession)
override fun getSearchScope(owner: FirClassSymbol<*>): FirScope? {
val baseScope = super.getSearchScope(owner) as? FirTypeScope ?: return null
return if (isSynthetic) {
FirSyntheticPropertiesScope.createIfSyntheticNamesProviderIsDefined(
session = useSiteSession,
dispatchReceiverType = owner.defaultType(),
baseScope = baseScope,
)
} else {
baseScope
}
}
}
@@ -18,7 +18,8 @@ internal class KtFirMemberFunctionSymbolPointer(
ownerPointer: KtSymbolPointer<KtSymbolWithMembers>,
private val name: Name,
private val signature: FirCallableSignature,
) : KtFirMemberSymbolPointer<KtFunctionSymbol>(ownerPointer) {
isStatic: Boolean,
) : KtFirMemberSymbolPointer<KtFunctionSymbol>(ownerPointer, isStatic) {
override fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(
candidates: FirScope,
firSession: FirSession
@@ -6,41 +6,51 @@
package org.jetbrains.kotlin.analysis.api.fir.symbols.pointers
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol
import org.jetbrains.kotlin.analysis.api.fir.utils.firSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
internal abstract class KtFirMemberSymbolPointer<S : KtSymbol>(
private val ownerPointer: KtSymbolPointer<KtSymbolWithMembers>,
private val isStatic: Boolean = false,
) : KtSymbolPointer<S>() {
@Deprecated("Consider using org.jetbrains.kotlin.analysis.api.KtAnalysisSession.restoreSymbol")
final override fun restoreSymbol(analysisSession: KtAnalysisSession): S? {
require(analysisSession is KtFirAnalysisSession)
val ownerSymbol = with(analysisSession) {
ownerPointer.restoreSymbol()
}
val scope = with(analysisSession) {
val ownerSymbol = ownerPointer.restoreSymbol() ?: return null
val owner = ownerSymbol.firSymbol as? FirClassSymbol ?: return null
getSearchScope(owner)
} ?: return null
val owner = ownerSymbol?.firSymbol as? FirClassSymbol ?: return null
val firSession = analysisSession.useSiteSession
val scope = owner.unsubstitutedScope(
firSession,
analysisSession.getScopeSessionFor(firSession),
withForcedTypeCalculator = false,
)
return analysisSession.chooseCandidateAndCreateSymbol(scope, firSession)
return analysisSession.chooseCandidateAndCreateSymbol(scope, analysisSession.useSiteSession)
}
protected abstract fun KtFirAnalysisSession.chooseCandidateAndCreateSymbol(candidates: FirScope, firSession: FirSession): S?
context(KtFirAnalysisSession)
protected open fun getSearchScope(owner: FirClassSymbol<*>): FirScope? {
val firSession = useSiteSession
val scopeSession = getScopeSessionFor(firSession)
return if (isStatic) {
val firClass = owner.fir as? FirClass ?: return null
firClass.scopeProvider.getStaticMemberScopeForCallables(firClass, firSession, scopeSession)
} else {
owner.unsubstitutedScope(
useSiteSession = firSession,
scopeSession = scopeSession,
withForcedTypeCalculator = false,
)
}
}
}
context(KtAnalysisSession)
@@ -64,6 +64,18 @@ public class FirIdeNormalAnalysisSourceModuleSymbolByReferenceTestGenerated exte
runTest("analysis/analysis-api/testData/symbols/symbolByReference/constructorViaTypeAlias.kt");
}
@Test
@TestMetadata("enumValueOf.kt")
public void testEnumValueOf() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/enumValueOf.kt");
}
@Test
@TestMetadata("enumValues.kt")
public void testEnumValues() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/enumValues.kt");
}
@Test
@TestMetadata("explicitLambdaParameter.kt")
public void testExplicitLambdaParameter() throws Exception {
@@ -106,6 +118,30 @@ public class FirIdeNormalAnalysisSourceModuleSymbolByReferenceTestGenerated exte
runTest("analysis/analysis-api/testData/symbols/symbolByReference/javaField.kt");
}
@Test
@TestMetadata("javaMethod.kt")
public void testJavaMethod() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/javaMethod.kt");
}
@Test
@TestMetadata("javaStaticField.kt")
public void testJavaStaticField() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/javaStaticField.kt");
}
@Test
@TestMetadata("javaStaticMethod.kt")
public void testJavaStaticMethod() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/javaStaticMethod.kt");
}
@Test
@TestMetadata("javaSyntheticAccessor.kt")
public void testJavaSyntheticAccessor() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/javaSyntheticAccessor.kt");
}
@Test
@TestMetadata("primaryConstructorValueParameter.kt")
public void testPrimaryConstructorValueParameter() throws Exception {