[Analysis API] support creating KtSymbol by K/JS dynamic scope

^KT-61257 fixed
This commit is contained in:
Ilya Kirillov
2023-10-23 17:08:09 +02:00
committed by Space Team
parent 91edbeb747
commit a90562c0da
25 changed files with 441 additions and 18 deletions
@@ -76,7 +76,16 @@ internal class KtFirSymbolContainingDeclarationProvider(
is KtCallableSymbol -> {
val outerFirClassifier = symbol.firSymbol.getContainingClassSymbol(symbol.firSymbol.llFirSession)
?: return getParentSymbolByPsi()
if (outerFirClassifier == null) {
return when (firSymbol.origin) {
FirDeclarationOrigin.DynamicScope -> {
// A callable declaration from dynamic scope has no containing declaration as it comes from a dynamic type
// which is not based on a specific classifier
null
}
else -> getParentSymbolByPsi()
}
}
firSymbolBuilder.buildSymbol(outerFirClassifier) as? KtDeclarationSymbol
}
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.isExtension
@@ -92,6 +93,7 @@ internal class KtFirFunctionSymbol(
override val symbolKind: KtSymbolKind
get() = withValidityAssertion {
when {
firSymbol.origin == FirDeclarationOrigin.DynamicScope -> KtSymbolKind.CLASS_MEMBER
firSymbol.isLocal -> KtSymbolKind.LOCAL
firSymbol.containingClassLookupTag()?.classId == null -> KtSymbolKind.TOP_LEVEL
else -> KtSymbolKind.CLASS_MEMBER
@@ -68,6 +68,9 @@ internal class KtFirKotlinPropertySymbol(
override val symbolKind: KtSymbolKind
get() = withValidityAssertion {
if (firSymbol.origin == FirDeclarationOrigin.DynamicScope) {
return@withValidityAssertion KtSymbolKind.CLASS_MEMBER
}
when (firSymbol.containingClassLookupTag()?.classId) {
null -> KtSymbolKind.TOP_LEVEL
else -> KtSymbolKind.CLASS_MEMBER
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
import org.jetbrains.kotlin.fir.containingClassForLocalAttr
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
@@ -27,7 +26,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectOrStaticData
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
internal interface KtFirSymbol<out S : FirBasedSymbol<*>> : KtSymbol, KtLifetimeOwner {
val firSymbol: S
@@ -98,9 +96,7 @@ internal tailrec fun FirDeclaration.ktSymbolOrigin(): KtSymbolOrigin = when (ori
is FirDeclarationOrigin.Plugin -> KtSymbolOrigin.PLUGIN
FirDeclarationOrigin.RenamedForOverride -> KtSymbolOrigin.JAVA
is FirDeclarationOrigin.SubstitutionOverride -> KtSymbolOrigin.SUBSTITUTION_OVERRIDE
FirDeclarationOrigin.DynamicScope -> errorWithAttachment("Invalid FirDeclarationOrigin ${origin::class.simpleName}") {
withFirEntry("firToGetOrigin", this@ktSymbolOrigin)
}
FirDeclarationOrigin.DynamicScope -> KtSymbolOrigin.JS_DYNAMIC
is FirDeclarationOrigin.ScriptCustomization -> KtSymbolOrigin.PLUGIN
}
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.fir.references.impl.FirPropertyFromParameterResolved
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeDynamicType
import org.jetbrains.kotlin.fir.types.create
import org.jetbrains.kotlin.fir.types.toRegularClassSymbol
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.name.CallableId
@@ -79,8 +81,13 @@ private fun createContextReceiver(
builder.token
)
internal fun FirCallableSymbol<*>.getCallableIdIfNonLocal(): CallableId? =
callableId.takeUnless { it.isLocal }
internal fun FirCallableSymbol<*>.getCallableIdIfNonLocal(): CallableId? {
return when {
origin == FirDeclarationOrigin.DynamicScope -> null
callableId.isLocal -> null
else -> callableId
}
}
internal fun FirClassLikeSymbol<*>.getClassIdIfNonLocal(): ClassId? =
classId.takeUnless { it.isLocal }
@@ -88,7 +95,15 @@ internal fun FirClassLikeSymbol<*>.getClassIdIfNonLocal(): ClassId? =
internal fun FirCallableSymbol<*>.dispatchReceiverType(
builder: KtSymbolByFirBuilder,
): KtType? {
return dispatchReceiverType?.let { builder.typeBuilder.buildKtType(it) }
val type = if (
origin == FirDeclarationOrigin.DynamicScope
&& (this is FirPropertySymbol || this is FirFunctionSymbol)
) {
ConeDynamicType.create(builder.rootSession)
} else {
dispatchReceiverType
}
return type?.let { builder.typeBuilder.buildKtType(it) }
}
internal fun FirVariableSymbol<*>.getKtConstantInitializer(resolveSession: LLFirResolveSession): KtInitializerValue? {
@@ -58,6 +58,16 @@ public class FirIdeNormalAnalysisScriptSourceModuleSymbolByReferenceTestGenerate
runTest("analysis/analysis-api/testData/symbols/symbolByReference/scriptResult.kts");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/symbolByReference/js")
@TestDataPath("$PROJECT_ROOT")
public class Js {
@Test
public void testAllFilesPresentInJs() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/symbolByReference/js"), Pattern.compile("^(.+)\\.kts$"), null, true);
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/symbolByReference/withTestCompilerPluginEnabled")
@TestDataPath("$PROJECT_ROOT")
@@ -220,6 +220,34 @@ public class FirIdeNormalAnalysisSourceModuleSymbolByReferenceTestGenerated exte
runTest("analysis/analysis-api/testData/symbols/symbolByReference/valueParameter.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/symbolByReference/js")
@TestDataPath("$PROJECT_ROOT")
public class Js {
@Test
public void testAllFilesPresentInJs() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/symbolByReference/js"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("functionFromJsDynamicScopeNoArguments.kt")
public void testFunctionFromJsDynamicScopeNoArguments() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/js/functionFromJsDynamicScopeNoArguments.kt");
}
@Test
@TestMetadata("functionFromJsDynamicScopeWithArguments.kt")
public void testFunctionFromJsDynamicScopeWithArguments() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/js/functionFromJsDynamicScopeWithArguments.kt");
}
@Test
@TestMetadata("propertyFromJsDynamicScope.kt")
public void testPropertyFromJsDynamicScope() throws Exception {
runTest("analysis/analysis-api/testData/symbols/symbolByReference/js/propertyFromJsDynamicScope.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/symbolByReference/withTestCompilerPluginEnabled")
@TestDataPath("$PROJECT_ROOT")