FIR: resolve constructors via type-aliases
This commit is contained in:
committed by
Mikhail Glukhikh
parent
aa077b42e9
commit
e6ab38a583
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.fir.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||
import org.jetbrains.kotlin.fir.declarations.superConeTypes
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
@@ -59,6 +56,13 @@ fun FirRegularClass.buildUseSiteScope(useSiteSession: FirSession, builder: Scope
|
||||
return symbolProvider.getClassUseSiteMemberScope(this.classId, useSiteSession, builder)!!
|
||||
}
|
||||
|
||||
fun FirTypeAlias.buildUseSiteScope(useSiteSession: FirSession, builder: ScopeSession): FirScope? {
|
||||
val type = expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()
|
||||
return type.scope(useSiteSession, builder)?.let {
|
||||
type.wrapSubstitutionScopeIfNeed(useSiteSession, it, this, builder)
|
||||
}
|
||||
}
|
||||
|
||||
fun FirRegularClass.buildDefaultUseSiteScope(useSiteSession: FirSession, builder: ScopeSession): FirScope {
|
||||
return builder.getOrBuild(symbol, USE_SITE) {
|
||||
val superTypeScope = FirCompositeScope(mutableListOf())
|
||||
@@ -81,13 +85,13 @@ fun FirRegularClass.buildDefaultUseSiteScope(useSiteSession: FirSession, builder
|
||||
private fun ConeClassLikeType.wrapSubstitutionScopeIfNeed(
|
||||
session: FirSession,
|
||||
useSiteScope: FirScope,
|
||||
regularClass: FirRegularClass,
|
||||
declaration: FirClassLikeDeclaration,
|
||||
builder: ScopeSession
|
||||
): FirScope {
|
||||
if (this.typeArguments.isEmpty()) return useSiteScope
|
||||
return builder.getOrBuild(regularClass.symbol, SubstitutionScopeKey(this)) {
|
||||
return builder.getOrBuild(declaration.symbol, SubstitutionScopeKey(this)) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val substitution = regularClass.typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
|
||||
val substitution = declaration.typeParameters.zip(this.typeArguments) { typeParameter, typeArgument ->
|
||||
typeParameter.symbol to (typeArgument as? ConeTypedProjection)?.type
|
||||
}.filter { (_, type) -> type != null }.toMap() as Map<ConeTypeParameterSymbol, ConeKotlinType>
|
||||
|
||||
|
||||
@@ -7,7 +7,19 @@ package org.jetbrains.kotlin.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeAbbreviatedType
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
fun MutableList<FirScope>.addImportingScopes(file: FirFile, session: FirSession) {
|
||||
this += listOf(
|
||||
@@ -24,3 +36,51 @@ fun MutableList<FirScope>.addImportingScopes(file: FirFile, session: FirSession)
|
||||
fun FirCompositeScope.addImportingScopes(file: FirFile, session: FirSession) {
|
||||
scopes.addImportingScopes(file, session)
|
||||
}
|
||||
|
||||
private fun finalExpansionName(symbol: FirTypeAliasSymbol, session: FirSession): Name? {
|
||||
val expandedType = symbol.fir.expandedTypeRef.coneTypeUnsafe<ConeClassLikeType>()
|
||||
return when (expandedType) {
|
||||
is ConeAbbreviatedType ->
|
||||
expandedType.abbreviationLookupTag.toSymbol(session)?.safeAs<FirTypeAliasSymbol>()?.let {
|
||||
finalExpansionName(it, session)
|
||||
}
|
||||
else -> expandedType.lookupTag.classId.shortClassName
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun processConstructors(
|
||||
matchedSymbol: ConeClassLikeSymbol?,
|
||||
processor: (ConeFunctionSymbol) -> ProcessorAction,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
name: Name
|
||||
): ProcessorAction {
|
||||
try {
|
||||
if (matchedSymbol != null) {
|
||||
val scope = when (matchedSymbol) {
|
||||
is FirTypeAliasSymbol -> matchedSymbol.fir.buildUseSiteScope(session, scopeSession)
|
||||
is FirClassSymbol -> matchedSymbol.fir.buildUseSiteScope(session, scopeSession)
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
||||
val constructorName = when (matchedSymbol) {
|
||||
is FirTypeAliasSymbol -> finalExpansionName(matchedSymbol, session) ?: return ProcessorAction.NEXT
|
||||
else -> name
|
||||
}
|
||||
|
||||
//TODO: why don't we use declared member scope at this point?
|
||||
if (scope != null && scope.processFunctionsByName(
|
||||
constructorName,
|
||||
processor
|
||||
) == ProcessorAction.STOP
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
}
|
||||
return ProcessorAction.NEXT
|
||||
} catch (e: Throwable) {
|
||||
throw RuntimeException("While processing constructors", e)
|
||||
}
|
||||
}
|
||||
+12
-16
@@ -8,14 +8,10 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.TowerScopeLevel
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.processConstructors
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
@@ -55,18 +51,18 @@ abstract class FirAbstractImportingScope(session: FirSession, lookupInFir: Boole
|
||||
}
|
||||
} else {
|
||||
val matchedClass = provider.getClassLikeSymbolByFqName(ClassId(import.packageFqName, name))
|
||||
|
||||
if (matchedClass != null && matchedClass is FirClassSymbol) {
|
||||
//TODO: why don't we use declared member scope at this point?
|
||||
if (matchedClass.fir.buildUseSiteScope(session, scopeCache).processFunctionsByName(
|
||||
name,
|
||||
processor
|
||||
) == ProcessorAction.STOP
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
if (processConstructors(
|
||||
matchedClass,
|
||||
processor,
|
||||
session,
|
||||
scopeCache,
|
||||
name
|
||||
).stop()
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
|
||||
|
||||
val symbols = provider.getTopLevelCallableSymbols(callableId.packageName, callableId.callableName)
|
||||
|
||||
for (symbol in symbols) {
|
||||
|
||||
+10
-7
@@ -8,14 +8,13 @@ package org.jetbrains.kotlin.fir.scopes.impl
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.buildUseSiteScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.NEXT
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction.STOP
|
||||
import org.jetbrains.kotlin.fir.scopes.processConstructors
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConePropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -29,11 +28,15 @@ class FirTopLevelDeclaredMemberScope(
|
||||
override fun processFunctionsByName(name: Name, processor: (ConeFunctionSymbol) -> ProcessorAction): ProcessorAction {
|
||||
val matchedClass = provider.getClassLikeSymbolByFqName(ClassId(packageFqName, name))
|
||||
|
||||
if (matchedClass != null && matchedClass is FirClassSymbol) {
|
||||
// TODO: why don't we use declared member scope at this point?
|
||||
if (matchedClass.fir.buildUseSiteScope(session, ScopeSession()).processFunctionsByName(name, processor) == STOP) {
|
||||
return STOP
|
||||
}
|
||||
if (processConstructors(
|
||||
matchedClass,
|
||||
processor,
|
||||
session,
|
||||
ScopeSession(),
|
||||
name
|
||||
).stop()
|
||||
) {
|
||||
return ProcessorAction.STOP
|
||||
}
|
||||
val symbols = provider.getTopLevelCallableSymbols(packageFqName, name)
|
||||
for (symbol in symbols) {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class A(i: Int)
|
||||
|
||||
typealias AA = A
|
||||
|
||||
class B<T>(t: T)
|
||||
|
||||
typealias BB<U> = B<U>
|
||||
|
||||
fun main() {
|
||||
val x = AA(1)
|
||||
val y = BB<String>("bb")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
FILE: typeAliasConstructor.kt
|
||||
public final class A : R|kotlin/Any| {
|
||||
public constructor(i: R|kotlin/Int|): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final typealias AA = R|A|
|
||||
public final class B<T> : R|kotlin/Any| {
|
||||
public constructor<T>(t: R|T|): R|B<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final typealias BB<U> = R|B<U>|
|
||||
public final fun main(): R|kotlin/Unit| {
|
||||
lval x: R|A| = R|/A.A|(Int(1))
|
||||
lval y: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/B.B]> = <Inapplicable(INAPPLICABLE): [/B.B]>#<R|kotlin/String|>(String(bb))
|
||||
}
|
||||
+5
@@ -262,6 +262,11 @@ public class FirResolveTestCaseGenerated extends AbstractFirResolveTestCase {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/this.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasConstructor.kt")
|
||||
public void testTypeAliasConstructor() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/typeAliasConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/expresssions/vararg.kt");
|
||||
|
||||
Reference in New Issue
Block a user