[FIR] Stop using .fir when checking conflicts
Use the symbols API in the declarations presenter and conflicts helpers.
This commit is contained in:
committed by
Space Team
parent
942bff8a03
commit
a1cb6258bc
+92
-94
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION
|
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl.Companion.DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.modifiersRepresentation
|
import org.jetbrains.kotlin.fir.declarations.impl.modifiersRepresentation
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
|
import org.jetbrains.kotlin.fir.declarations.utils.nameOrSpecialName
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
@@ -32,10 +31,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.TypeAliasConstructorsSubstitutingSco
|
|||||||
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.util.ListMultimap
|
import org.jetbrains.kotlin.fir.util.ListMultimap
|
||||||
@@ -47,8 +43,8 @@ import org.jetbrains.kotlin.utils.SmartSet
|
|||||||
|
|
||||||
val DEFAULT_STATUS_FOR_NORMAL_MAIN_FUNCTION = DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
val DEFAULT_STATUS_FOR_NORMAL_MAIN_FUNCTION = DEFAULT_STATUS_FOR_STATUSLESS_DECLARATIONS
|
||||||
|
|
||||||
private val FirSimpleFunction.hasMainFunctionStatus
|
private val FirNamedFunctionSymbol.hasMainFunctionStatus
|
||||||
get() = when (status.modifiersRepresentation) {
|
get() = when (resolvedStatus.modifiersRepresentation) {
|
||||||
DEFAULT_STATUS_FOR_NORMAL_MAIN_FUNCTION.modifiersRepresentation,
|
DEFAULT_STATUS_FOR_NORMAL_MAIN_FUNCTION.modifiersRepresentation,
|
||||||
DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION.modifiersRepresentation,
|
DEFAULT_STATUS_FOR_SUSPEND_MAIN_FUNCTION.modifiersRepresentation,
|
||||||
-> true
|
-> true
|
||||||
@@ -57,76 +53,81 @@ private val FirSimpleFunction.hasMainFunctionStatus
|
|||||||
|
|
||||||
private val CallableId.isTopLevel get() = className == null
|
private val CallableId.isTopLevel get() = className == null
|
||||||
|
|
||||||
private fun FirDeclaration.isCollectable(): Boolean {
|
private fun FirBasedSymbol<*>.isCollectable(): Boolean {
|
||||||
if (this is FirCallableDeclaration) {
|
if (this is FirCallableSymbol<*>) {
|
||||||
if (contextReceivers.any { it.typeRef.coneType.hasError() }) return false
|
if (resolvedContextReceivers.any { it.typeRef.coneType.hasError() }) return false
|
||||||
if (typeParameters.any { it.toConeType().hasError() }) return false
|
if (typeParameterSymbols.any { it.toConeType().hasError() }) return false
|
||||||
if (receiverParameter?.typeRef?.coneType?.hasError() == true) return false
|
if (receiverParameter?.typeRef?.coneType?.hasError() == true) return false
|
||||||
if (this is FirFunction && valueParameters.any { it.returnTypeRef.coneType.hasError() }) return false
|
if (this is FirFunctionSymbol<*> && valueParameterSymbols.any { it.resolvedReturnType.hasError() }) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (this) {
|
return when (this) {
|
||||||
// - see tests with `fun () {}`.
|
// - see tests with `fun () {}`.
|
||||||
// you can't redeclare something that has no name.
|
// you can't redeclare something that has no name.
|
||||||
is FirSimpleFunction -> source?.kind !is KtFakeSourceElementKind && name != SpecialNames.NO_NAME_PROVIDED
|
is FirNamedFunctionSymbol -> source?.kind !is KtFakeSourceElementKind && name != SpecialNames.NO_NAME_PROVIDED
|
||||||
is FirRegularClass -> name != SpecialNames.NO_NAME_PROVIDED
|
is FirRegularClassSymbol -> name != SpecialNames.NO_NAME_PROVIDED
|
||||||
// - see testEnumValuesValueOf.
|
// - see testEnumValuesValueOf.
|
||||||
// it generates a static function that has
|
// it generates a static function that has
|
||||||
// the same signature as the function defined
|
// the same signature as the function defined
|
||||||
// explicitly.
|
// explicitly.
|
||||||
is FirProperty -> source?.kind !is KtFakeSourceElementKind.EnumGeneratedDeclaration
|
is FirPropertySymbol -> source?.kind !is KtFakeSourceElementKind.EnumGeneratedDeclaration
|
||||||
// class delegation field will be renamed after by the IR backend in a case of a name clash
|
// class delegation field will be renamed after by the IR backend in a case of a name clash
|
||||||
is FirField -> source?.kind != KtFakeSourceElementKind.ClassDelegationField
|
is FirFieldSymbol -> source?.kind != KtFakeSourceElementKind.ClassDelegationField
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isExpectAndActual(declaration1: FirDeclaration, declaration2: FirDeclaration): Boolean {
|
private val FirBasedSymbol<*>.resolvedStatus
|
||||||
if (declaration1 !is FirMemberDeclaration) return false
|
get() = when (this) {
|
||||||
if (declaration2 !is FirMemberDeclaration) return false
|
is FirCallableSymbol<*> -> resolvedStatus
|
||||||
return (declaration1.status.isExpect && declaration2.status.isActual) ||
|
is FirClassLikeSymbol<*> -> resolvedStatus
|
||||||
(declaration1.status.isActual && declaration2.status.isExpect)
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isExpectAndActual(declaration1: FirBasedSymbol<*>, declaration2: FirBasedSymbol<*>): Boolean {
|
||||||
|
val status1 = declaration1.resolvedStatus ?: return false
|
||||||
|
val status2 = declaration2.resolvedStatus ?: return false
|
||||||
|
return (status1.isExpect && status2.isActual) || (status1.isActual && status2.isExpect)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DeclarationBuckets {
|
private class DeclarationBuckets {
|
||||||
val simpleFunctions = mutableListOf<Pair<FirSimpleFunction, String>>()
|
val simpleFunctions = mutableListOf<Pair<FirNamedFunctionSymbol, String>>()
|
||||||
val constructors = mutableListOf<Pair<FirConstructor, String>>()
|
val constructors = mutableListOf<Pair<FirConstructorSymbol, String>>()
|
||||||
val classLikes = mutableListOf<Pair<FirClassLikeDeclaration, String>>()
|
val classLikes = mutableListOf<Pair<FirClassLikeSymbol<*>, String>>()
|
||||||
val properties = mutableListOf<Pair<FirProperty, String>>()
|
val properties = mutableListOf<Pair<FirPropertySymbol, String>>()
|
||||||
val extensionProperties = mutableListOf<Pair<FirProperty, String>>()
|
val extensionProperties = mutableListOf<Pair<FirPropertySymbol, String>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun groupTopLevelByName(declarations: List<FirDeclaration>, context: CheckerContext): Map<Name, DeclarationBuckets> {
|
private fun groupTopLevelByName(declarations: List<FirDeclaration>, context: CheckerContext): Map<Name, DeclarationBuckets> {
|
||||||
val groups = mutableMapOf<Name, DeclarationBuckets>()
|
val groups = mutableMapOf<Name, DeclarationBuckets>()
|
||||||
for (declaration in declarations) {
|
for (declaration in declarations) {
|
||||||
if (!declaration.isCollectable()) continue
|
if (!declaration.symbol.isCollectable()) continue
|
||||||
|
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is FirSimpleFunction ->
|
is FirSimpleFunction ->
|
||||||
groups.getOrPut(declaration.name, ::DeclarationBuckets).simpleFunctions +=
|
groups.getOrPut(declaration.name, ::DeclarationBuckets).simpleFunctions +=
|
||||||
declaration to FirRedeclarationPresenter.represent(declaration)
|
declaration.symbol to FirRedeclarationPresenter.represent(declaration.symbol)
|
||||||
is FirProperty -> {
|
is FirProperty -> {
|
||||||
val group = groups.getOrPut(declaration.name, ::DeclarationBuckets)
|
val group = groups.getOrPut(declaration.name, ::DeclarationBuckets)
|
||||||
val representation = FirRedeclarationPresenter.represent(declaration)
|
val representation = FirRedeclarationPresenter.represent(declaration.symbol)
|
||||||
if (declaration.receiverParameter != null) {
|
if (declaration.receiverParameter != null) {
|
||||||
group.extensionProperties += declaration to representation
|
group.extensionProperties += declaration.symbol to representation
|
||||||
} else {
|
} else {
|
||||||
group.properties += declaration to representation
|
group.properties += declaration.symbol to representation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is FirClassLikeDeclaration -> {
|
is FirClassLikeDeclaration -> {
|
||||||
val representation = FirRedeclarationPresenter.represent(declaration) ?: continue
|
val representation = FirRedeclarationPresenter.represent(declaration.symbol) ?: continue
|
||||||
val group = groups.getOrPut(declaration.nameOrSpecialName, ::DeclarationBuckets)
|
val group = groups.getOrPut(declaration.nameOrSpecialName, ::DeclarationBuckets)
|
||||||
group.classLikes += declaration to representation
|
group.classLikes += declaration.symbol to representation
|
||||||
|
|
||||||
declaration.expandedClassWithConstructorsScope(context)?.let { (expandedClass, scopeWithConstructors) ->
|
declaration.symbol.expandedClassWithConstructorsScope(context)?.let { (expandedClass, scopeWithConstructors) ->
|
||||||
if (expandedClass.classKind == ClassKind.OBJECT) {
|
if (expandedClass.classKind == ClassKind.OBJECT) {
|
||||||
return@let
|
return@let
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(SymbolInternals::class)
|
|
||||||
scopeWithConstructors.processDeclaredConstructors {
|
scopeWithConstructors.processDeclaredConstructors {
|
||||||
group.constructors += it.fir to FirRedeclarationPresenter.represent(it.fir, declaration.symbol)
|
group.constructors += it to FirRedeclarationPresenter.represent(it, declaration.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,9 +138,9 @@ private fun groupTopLevelByName(declarations: List<FirDeclaration>, context: Che
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects FirDeclarations for further analysis.
|
* Collects symbols of FirDeclarations for further analysis.
|
||||||
*/
|
*/
|
||||||
class FirDeclarationCollector<D : FirDeclaration>(
|
class FirDeclarationCollector<D : FirBasedSymbol<*>>(
|
||||||
internal val context: CheckerContext,
|
internal val context: CheckerContext,
|
||||||
) {
|
) {
|
||||||
internal val session: FirSession get() = context.sessionHolder.session
|
internal val session: FirSession get() = context.sessionHolder.session
|
||||||
@@ -147,44 +148,44 @@ class FirDeclarationCollector<D : FirDeclaration>(
|
|||||||
val declarationConflictingSymbols: HashMap<D, SmartSet<FirBasedSymbol<*>>> = hashMapOf()
|
val declarationConflictingSymbols: HashMap<D, SmartSet<FirBasedSymbol<*>>> = hashMapOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirDeclarationCollector<FirDeclaration>.collectClassMembers(klass: FirRegularClass) {
|
fun FirDeclarationCollector<FirBasedSymbol<*>>.collectClassMembers(klass: FirRegularClassSymbol) {
|
||||||
val otherDeclarations = mutableMapOf<String, MutableList<FirDeclaration>>()
|
val otherDeclarations = mutableMapOf<String, MutableList<FirBasedSymbol<*>>>()
|
||||||
val functionDeclarations = mutableMapOf<String, MutableList<FirDeclaration>>()
|
val functionDeclarations = mutableMapOf<String, MutableList<FirBasedSymbol<*>>>()
|
||||||
|
|
||||||
// TODO, KT-61243: Use declaredMemberScope
|
// TODO, KT-61243: Use declaredMemberScope
|
||||||
for (it in klass.declarations) {
|
@OptIn(SymbolInternals::class)
|
||||||
if (!it.isCollectable()) continue
|
for (it in klass.fir.declarations) {
|
||||||
|
if (!it.symbol.isCollectable()) continue
|
||||||
|
|
||||||
when (it) {
|
when (it) {
|
||||||
is FirSimpleFunction -> collect(it, FirRedeclarationPresenter.represent(it), functionDeclarations)
|
is FirSimpleFunction -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), functionDeclarations)
|
||||||
is FirRegularClass -> collect(it, FirRedeclarationPresenter.represent(it), otherDeclarations)
|
is FirRegularClass -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), otherDeclarations)
|
||||||
is FirTypeAlias -> collect(it, FirRedeclarationPresenter.represent(it), otherDeclarations)
|
is FirTypeAlias -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), otherDeclarations)
|
||||||
is FirVariable -> collect(it, FirRedeclarationPresenter.represent(it), otherDeclarations)
|
is FirVariable -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), otherDeclarations)
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun collectConflictingLocalFunctionsFrom(block: FirBlock, context: CheckerContext): Map<FirFunction, Set<FirBasedSymbol<*>>> {
|
fun collectConflictingLocalFunctionsFrom(block: FirBlock, context: CheckerContext): Map<FirFunctionSymbol<*>, Set<FirBasedSymbol<*>>> {
|
||||||
val collectables =
|
val collectables =
|
||||||
block.statements.filter {
|
block.statements.filter {
|
||||||
(it is FirSimpleFunction || it is FirRegularClass) && (it as FirDeclaration).isCollectable()
|
(it is FirSimpleFunction || it is FirRegularClass) && (it as FirDeclaration).symbol.isCollectable()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collectables.isEmpty()) return emptyMap()
|
if (collectables.isEmpty()) return emptyMap()
|
||||||
|
|
||||||
val inspector = FirDeclarationCollector<FirFunction>(context)
|
val inspector = FirDeclarationCollector<FirFunctionSymbol<*>>(context)
|
||||||
val functionDeclarations = mutableMapOf<String, MutableList<FirFunction>>()
|
val functionDeclarations = mutableMapOf<String, MutableList<FirFunctionSymbol<*>>>()
|
||||||
|
|
||||||
for (collectable in collectables) {
|
for (collectable in collectables) {
|
||||||
when (collectable) {
|
when (collectable) {
|
||||||
is FirSimpleFunction ->
|
is FirSimpleFunction ->
|
||||||
inspector.collect(collectable, FirRedeclarationPresenter.represent(collectable), functionDeclarations)
|
inspector.collect(collectable.symbol, FirRedeclarationPresenter.represent(collectable.symbol), functionDeclarations)
|
||||||
is FirClassLikeDeclaration -> {
|
is FirClassLikeDeclaration -> {
|
||||||
collectable.expandedClassWithConstructorsScope(context)?.let { (_, scopeWithConstructors) ->
|
collectable.symbol.expandedClassWithConstructorsScope(context)?.let { (_, scopeWithConstructors) ->
|
||||||
scopeWithConstructors.processDeclaredConstructors {
|
scopeWithConstructors.processDeclaredConstructors {
|
||||||
@OptIn(SymbolInternals::class)
|
inspector.collect(it, FirRedeclarationPresenter.represent(it, collectable.symbol), functionDeclarations)
|
||||||
inspector.collect(it.fir, FirRedeclarationPresenter.represent(it.fir, collectable.symbol), functionDeclarations)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +196,7 @@ fun collectConflictingLocalFunctionsFrom(block: FirBlock, context: CheckerContex
|
|||||||
return inspector.declarationConflictingSymbols
|
return inspector.declarationConflictingSymbols
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <D : FirDeclaration> FirDeclarationCollector<D>.collect(
|
private fun <D : FirBasedSymbol<*>> FirDeclarationCollector<D>.collect(
|
||||||
declaration: D,
|
declaration: D,
|
||||||
representation: String,
|
representation: String,
|
||||||
map: MutableMap<String, MutableList<D>>,
|
map: MutableMap<String, MutableList<D>>,
|
||||||
@@ -206,8 +207,8 @@ private fun <D : FirDeclaration> FirDeclarationCollector<D>.collect(
|
|||||||
val conflicts = SmartSet.create<FirBasedSymbol<*>>()
|
val conflicts = SmartSet.create<FirBasedSymbol<*>>()
|
||||||
for (otherDeclaration in it) {
|
for (otherDeclaration in it) {
|
||||||
if (otherDeclaration != declaration && !isOverloadable(declaration, otherDeclaration, session)) {
|
if (otherDeclaration != declaration && !isOverloadable(declaration, otherDeclaration, session)) {
|
||||||
conflicts.add(otherDeclaration.symbol)
|
conflicts.add(otherDeclaration)
|
||||||
declarationConflictingSymbols.getOrPut(otherDeclaration) { SmartSet.create() }.add(declaration.symbol)
|
declarationConflictingSymbols.getOrPut(otherDeclaration) { SmartSet.create() }.add(declaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,16 +234,15 @@ private fun <D : FirDeclaration> FirDeclarationCollector<D>.collect(
|
|||||||
* | constructors of classes | X | | | | |
|
* | constructors of classes | X | | | | |
|
||||||
* | properties | | | X | X | X |
|
* | properties | | | X | X | X |
|
||||||
*/
|
*/
|
||||||
@OptIn(SymbolInternals::class)
|
|
||||||
@Suppress("GrazieInspection")
|
@Suppress("GrazieInspection")
|
||||||
fun FirDeclarationCollector<FirDeclaration>.collectTopLevel(file: FirFile, packageMemberScope: FirPackageMemberScope) {
|
fun FirDeclarationCollector<FirBasedSymbol<*>>.collectTopLevel(file: FirFile, packageMemberScope: FirPackageMemberScope) {
|
||||||
|
|
||||||
for ((declarationName, group) in groupTopLevelByName(file.declarations, context)) {
|
for ((declarationName, group) in groupTopLevelByName(file.declarations, context)) {
|
||||||
val groupHasClassLikesOrProperties = group.classLikes.isNotEmpty() || group.properties.isNotEmpty()
|
val groupHasClassLikesOrProperties = group.classLikes.isNotEmpty() || group.properties.isNotEmpty()
|
||||||
val groupHasSimpleFunctions = group.simpleFunctions.isNotEmpty()
|
val groupHasSimpleFunctions = group.simpleFunctions.isNotEmpty()
|
||||||
|
|
||||||
fun collect(
|
fun collect(
|
||||||
declarations: List<Pair<FirDeclaration, String>>,
|
declarations: List<Pair<FirBasedSymbol<*>, String>>,
|
||||||
conflictingSymbol: FirBasedSymbol<*>,
|
conflictingSymbol: FirBasedSymbol<*>,
|
||||||
conflictingPresentation: String? = null,
|
conflictingPresentation: String? = null,
|
||||||
conflictingFile: FirFile? = null,
|
conflictingFile: FirFile? = null,
|
||||||
@@ -270,19 +270,17 @@ fun FirDeclarationCollector<FirDeclaration>.collectTopLevel(file: FirFile, packa
|
|||||||
collect(group.properties, conflictingSymbol, conflictingPresentation, conflictingFile)
|
collect(group.properties, conflictingSymbol, conflictingPresentation, conflictingFile)
|
||||||
|
|
||||||
if (groupHasSimpleFunctions) {
|
if (groupHasSimpleFunctions) {
|
||||||
val declaration = conflictingSymbol.fir
|
if (conflictingSymbol !is FirClassLikeSymbol<*>) {
|
||||||
|
|
||||||
if (declaration !is FirClassLikeDeclaration) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
declaration.expandedClassWithConstructorsScope(context)?.let { (expandedClass, scopeWithConstructors) ->
|
conflictingSymbol.expandedClassWithConstructorsScope(context)?.let { (expandedClass, scopeWithConstructors) ->
|
||||||
if (expandedClass.classKind == ClassKind.OBJECT || expandedClass.classKind == ClassKind.ENUM_ENTRY) {
|
if (expandedClass.classKind == ClassKind.OBJECT || expandedClass.classKind == ClassKind.ENUM_ENTRY) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
scopeWithConstructors.processDeclaredConstructors { constructor ->
|
scopeWithConstructors.processDeclaredConstructors { constructor ->
|
||||||
val ctorRepresentation = FirRedeclarationPresenter.represent(constructor.fir, declaration.symbol)
|
val ctorRepresentation = FirRedeclarationPresenter.represent(constructor, conflictingSymbol)
|
||||||
collect(group.simpleFunctions, conflictingSymbol = constructor, conflictingPresentation = ctorRepresentation)
|
collect(group.simpleFunctions, conflictingSymbol = constructor, conflictingPresentation = ctorRepresentation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,7 +313,7 @@ fun FirDeclarationCollector<FirDeclaration>.collectTopLevel(file: FirFile, packa
|
|||||||
// session.nameConflictsTracker doesn't seem to work for LL API for redeclarations in the same file, for this reason
|
// session.nameConflictsTracker doesn't seem to work for LL API for redeclarations in the same file, for this reason
|
||||||
// we explicitly check classLikes in the same file, too.
|
// we explicitly check classLikes in the same file, too.
|
||||||
for ((classLike, representation) in group.classLikes) {
|
for ((classLike, representation) in group.classLikes) {
|
||||||
collectFromClassifierSource(classLike.symbol, conflictingPresentation = representation, conflictingFile = file)
|
collectFromClassifierSource(classLike, conflictingPresentation = representation, conflictingFile = file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,11 +328,11 @@ fun FirDeclarationCollector<FirDeclaration>.collectTopLevel(file: FirFile, packa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirClassLikeDeclaration.expandedClassWithConstructorsScope(context: CheckerContext): Pair<FirRegularClassSymbol, FirScope>? {
|
private fun FirClassLikeSymbol<*>.expandedClassWithConstructorsScope(context: CheckerContext): Pair<FirRegularClassSymbol, FirScope>? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is FirRegularClass -> symbol to unsubstitutedScope(context)
|
is FirRegularClassSymbol -> this to unsubstitutedScope(context)
|
||||||
is FirTypeAlias -> {
|
is FirTypeAliasSymbol -> {
|
||||||
val expandedType = expandedConeType
|
val expandedType = resolvedExpandedTypeRef.coneType as? ConeClassLikeType
|
||||||
val expandedClass = expandedType?.toRegularClassSymbol(context.session)
|
val expandedClass = expandedType?.toRegularClassSymbol(context.session)
|
||||||
val expandedTypeScope = expandedType?.scope(
|
val expandedTypeScope = expandedType?.scope(
|
||||||
context.session, context.scopeSession,
|
context.session, context.scopeSession,
|
||||||
@@ -344,7 +342,7 @@ private fun FirClassLikeDeclaration.expandedClassWithConstructorsScope(context:
|
|||||||
|
|
||||||
if (expandedType != null && expandedClass != null && expandedTypeScope != null) {
|
if (expandedType != null && expandedClass != null && expandedTypeScope != null) {
|
||||||
val outerType = outerType(expandedType, context.session) { it.outerClassSymbol(context) }
|
val outerType = outerType(expandedType, context.session) { it.outerClassSymbol(context) }
|
||||||
expandedClass to TypeAliasConstructorsSubstitutingScope(symbol, expandedTypeScope, outerType)
|
expandedClass to TypeAliasConstructorsSubstitutingScope(this, expandedTypeScope, outerType)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@@ -353,8 +351,8 @@ private fun FirClassLikeDeclaration.expandedClassWithConstructorsScope(context:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirDeclarationCollector<FirDeclaration>.collectTopLevelConflict(
|
private fun FirDeclarationCollector<FirBasedSymbol<*>>.collectTopLevelConflict(
|
||||||
declaration: FirDeclaration,
|
declaration: FirBasedSymbol<*>,
|
||||||
declarationPresentation: String,
|
declarationPresentation: String,
|
||||||
containingFile: FirFile,
|
containingFile: FirFile,
|
||||||
conflictingSymbol: FirBasedSymbol<*>,
|
conflictingSymbol: FirBasedSymbol<*>,
|
||||||
@@ -362,10 +360,8 @@ private fun FirDeclarationCollector<FirDeclaration>.collectTopLevelConflict(
|
|||||||
conflictingFile: FirFile? = null,
|
conflictingFile: FirFile? = null,
|
||||||
) {
|
) {
|
||||||
conflictingSymbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
conflictingSymbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||||
@OptIn(SymbolInternals::class)
|
if (conflictingSymbol == declaration || declaration.moduleData != conflictingSymbol.moduleData) return
|
||||||
val conflicting = conflictingSymbol.fir
|
val actualConflictingPresentation = conflictingPresentation ?: FirRedeclarationPresenter.represent(conflictingSymbol)
|
||||||
if (conflicting == declaration || declaration.moduleData != conflicting.moduleData) return
|
|
||||||
val actualConflictingPresentation = conflictingPresentation ?: FirRedeclarationPresenter.represent(conflicting)
|
|
||||||
if (actualConflictingPresentation != declarationPresentation) return
|
if (actualConflictingPresentation != declarationPresentation) return
|
||||||
val actualConflictingFile =
|
val actualConflictingFile =
|
||||||
conflictingFile ?: when (conflictingSymbol) {
|
conflictingFile ?: when (conflictingSymbol) {
|
||||||
@@ -373,22 +369,24 @@ private fun FirDeclarationCollector<FirDeclaration>.collectTopLevelConflict(
|
|||||||
is FirCallableSymbol<*> -> session.firProvider.getFirCallableContainerFile(conflictingSymbol)
|
is FirCallableSymbol<*> -> session.firProvider.getFirCallableContainerFile(conflictingSymbol)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
if (!conflicting.isCollectable()) return
|
if (!conflictingSymbol.isCollectable()) return
|
||||||
if (areCompatibleMainFunctions(declaration, containingFile, conflicting, actualConflictingFile, session)) return
|
if (areCompatibleMainFunctions(declaration, containingFile, conflictingSymbol, actualConflictingFile, session)) return
|
||||||
|
@OptIn(SymbolInternals::class)
|
||||||
|
val conflicting = conflictingSymbol.fir
|
||||||
if (
|
if (
|
||||||
conflicting is FirMemberDeclaration &&
|
conflicting is FirMemberDeclaration &&
|
||||||
!session.visibilityChecker.isVisible(conflicting, session, containingFile, emptyList(), dispatchReceiver = null)
|
!session.visibilityChecker.isVisible(conflicting, session, containingFile, emptyList(), dispatchReceiver = null)
|
||||||
) return
|
) return
|
||||||
if (isOverloadable(declaration, conflicting, session)) return
|
if (isOverloadable(declaration, conflictingSymbol, session)) return
|
||||||
|
|
||||||
declarationConflictingSymbols.getOrPut(declaration) { SmartSet.create() }.add(conflictingSymbol)
|
declarationConflictingSymbols.getOrPut(declaration) { SmartSet.create() }.add(conflictingSymbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirSimpleFunction.representsMainFunctionAllowingConflictingOverloads(session: FirSession): Boolean {
|
private fun FirNamedFunctionSymbol.representsMainFunctionAllowingConflictingOverloads(session: FirSession): Boolean {
|
||||||
if (name != StandardNames.MAIN || !symbol.callableId.isTopLevel || !hasMainFunctionStatus) return false
|
if (name != StandardNames.MAIN || !callableId.isTopLevel || !hasMainFunctionStatus) return false
|
||||||
if (receiverParameter != null || typeParameters.isNotEmpty()) return false
|
if (receiverParameter != null || typeParameterSymbols.isNotEmpty()) return false
|
||||||
if (valueParameters.isEmpty()) return true
|
if (valueParameterSymbols.isEmpty()) return true
|
||||||
val paramType = valueParameters.singleOrNull()?.returnTypeRef?.coneType?.fullyExpandedType(session) ?: return false
|
val paramType = valueParameterSymbols.singleOrNull()?.resolvedReturnTypeRef?.coneType?.fullyExpandedType(session) ?: return false
|
||||||
if (!paramType.isNonPrimitiveArray) return false
|
if (!paramType.isNonPrimitiveArray) return false
|
||||||
val typeArgument = paramType.typeArguments.singleOrNull() as? ConeKotlinTypeProjection ?: return false
|
val typeArgument = paramType.typeArguments.singleOrNull() as? ConeKotlinTypeProjection ?: return false
|
||||||
// only Array<String> and Array<out String> are accepted
|
// only Array<String> and Array<out String> are accepted
|
||||||
@@ -397,18 +395,18 @@ private fun FirSimpleFunction.representsMainFunctionAllowingConflictingOverloads
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun areCompatibleMainFunctions(
|
private fun areCompatibleMainFunctions(
|
||||||
declaration1: FirDeclaration, file1: FirFile,
|
declaration1: FirBasedSymbol<*>, file1: FirFile,
|
||||||
declaration2: FirDeclaration, file2: FirFile?,
|
declaration2: FirBasedSymbol<*>, file2: FirFile?,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
) = file1 != file2
|
) = file1 != file2
|
||||||
&& declaration1 is FirSimpleFunction
|
&& declaration1 is FirNamedFunctionSymbol
|
||||||
&& declaration2 is FirSimpleFunction
|
&& declaration2 is FirNamedFunctionSymbol
|
||||||
&& declaration1.representsMainFunctionAllowingConflictingOverloads(session)
|
&& declaration1.representsMainFunctionAllowingConflictingOverloads(session)
|
||||||
&& declaration2.representsMainFunctionAllowingConflictingOverloads(session)
|
&& declaration2.representsMainFunctionAllowingConflictingOverloads(session)
|
||||||
|
|
||||||
private fun isOverloadable(
|
private fun isOverloadable(
|
||||||
declaration: FirDeclaration,
|
declaration: FirBasedSymbol<*>,
|
||||||
conflicting: FirDeclaration,
|
conflicting: FirBasedSymbol<*>,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (isExpectAndActual(declaration, conflicting)) return true
|
if (isExpectAndActual(declaration, conflicting)) return true
|
||||||
@@ -417,8 +415,8 @@ private fun isOverloadable(
|
|||||||
val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
|
val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
|
||||||
if (declarationIsLowPriority != conflictingIsLowPriority) return true
|
if (declarationIsLowPriority != conflictingIsLowPriority) return true
|
||||||
|
|
||||||
return declaration is FirCallableDeclaration &&
|
return declaration is FirCallableSymbol<*> &&
|
||||||
conflicting is FirCallableDeclaration &&
|
conflicting is FirCallableSymbol<*> &&
|
||||||
session.declarationOverloadabilityHelper.isOverloadable(declaration, conflicting)
|
session.declarationOverloadabilityHelper.isOverloadable(declaration, conflicting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-25
@@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
@@ -34,18 +34,18 @@ internal object FirRedeclarationPresenter {
|
|||||||
append(it.callableName)
|
append(it.callableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendRepresentation(it: FirValueParameter) {
|
private fun StringBuilder.appendRepresentation(it: FirValueParameterSymbol) {
|
||||||
if (it.isVararg) {
|
if (it.isVararg) {
|
||||||
append("vararg ")
|
append("vararg ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendRepresentationBeforeCallableId(it: FirCallableDeclaration) {
|
private fun StringBuilder.appendRepresentationBeforeCallableId(it: FirCallableSymbol<*>) {
|
||||||
repeat(it.contextReceivers.size) {
|
repeat(it.resolvedContextReceivers.size) {
|
||||||
append(',')
|
append(',')
|
||||||
}
|
}
|
||||||
append('<')
|
append('<')
|
||||||
repeat(it.typeParameters.size) {
|
repeat(it.typeParameterSymbols.size) {
|
||||||
append(',')
|
append(',')
|
||||||
}
|
}
|
||||||
append('>')
|
append('>')
|
||||||
@@ -56,55 +56,55 @@ internal object FirRedeclarationPresenter {
|
|||||||
append(']')
|
append(']')
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun StringBuilder.appendValueParameters(it: FirSimpleFunction) {
|
private fun StringBuilder.appendValueParameters(it: FirNamedFunctionSymbol) {
|
||||||
append('(')
|
append('(')
|
||||||
it.valueParameters.forEach {
|
it.valueParameterSymbols.forEach {
|
||||||
appendRepresentation(it)
|
appendRepresentation(it)
|
||||||
append(',')
|
append(',')
|
||||||
}
|
}
|
||||||
append(')')
|
append(')')
|
||||||
}
|
}
|
||||||
|
|
||||||
fun represent(declaration: FirDeclaration): String? = when (declaration) {
|
fun represent(declaration: FirBasedSymbol<*>): String? = when (declaration) {
|
||||||
is FirSimpleFunction -> represent(declaration)
|
is FirNamedFunctionSymbol -> represent(declaration)
|
||||||
is FirRegularClass -> represent(declaration)
|
is FirRegularClassSymbol -> represent(declaration)
|
||||||
is FirTypeAlias -> represent(declaration)
|
is FirTypeAliasSymbol -> represent(declaration)
|
||||||
is FirProperty -> represent(declaration)
|
is FirPropertySymbol -> represent(declaration)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun represent(it: FirSimpleFunction) = buildString {
|
fun represent(it: FirNamedFunctionSymbol) = buildString {
|
||||||
appendRepresentationBeforeCallableId(it)
|
appendRepresentationBeforeCallableId(it)
|
||||||
if (it.isOperator) {
|
if (it.isOperator) {
|
||||||
append("operator ")
|
append("operator ")
|
||||||
}
|
}
|
||||||
appendRepresentation(it.symbol.callableId)
|
appendRepresentation(it.callableId)
|
||||||
appendValueParameters(it)
|
appendValueParameters(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun represent(it: FirVariable) = buildString {
|
fun represent(it: FirVariableSymbol<*>) = buildString {
|
||||||
appendRepresentationBeforeCallableId(it)
|
appendRepresentationBeforeCallableId(it)
|
||||||
appendRepresentation(it.symbol.callableId)
|
appendRepresentation(it.callableId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun represent(it: FirTypeAlias) = representClassLike(it)
|
fun represent(it: FirTypeAliasSymbol) = representClassLike(it)
|
||||||
fun represent(it: FirRegularClass) = representClassLike(it)
|
fun represent(it: FirRegularClassSymbol) = representClassLike(it)
|
||||||
|
|
||||||
private fun representClassLike(it: FirClassLikeDeclaration) = buildString {
|
private fun representClassLike(it: FirClassLikeSymbol<*>) = buildString {
|
||||||
append('<')
|
append('<')
|
||||||
append('>')
|
append('>')
|
||||||
append('[')
|
append('[')
|
||||||
append(']')
|
append(']')
|
||||||
appendRepresentation(it.symbol.classId)
|
appendRepresentation(it.classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun represent(it: FirConstructor, owner: FirClassLikeSymbol<*>) = buildString {
|
fun represent(it: FirConstructorSymbol, owner: FirClassLikeSymbol<*>) = buildString {
|
||||||
repeat(it.contextReceivers.size) {
|
repeat(it.resolvedContextReceivers.size) {
|
||||||
append(',')
|
append(',')
|
||||||
}
|
}
|
||||||
append('<')
|
append('<')
|
||||||
repeat(it.typeParameters.size) {
|
repeat(it.typeParameterSymbols.size) {
|
||||||
append(',')
|
append(',')
|
||||||
}
|
}
|
||||||
append('>')
|
append('>')
|
||||||
@@ -112,7 +112,7 @@ internal object FirRedeclarationPresenter {
|
|||||||
append(']')
|
append(']')
|
||||||
appendRepresentation(owner.classId)
|
appendRepresentation(owner.classId)
|
||||||
append('(')
|
append('(')
|
||||||
it.valueParameters.forEach {
|
it.valueParameterSymbols.forEach {
|
||||||
appendRepresentation(it)
|
appendRepresentation(it)
|
||||||
append(',')
|
append(',')
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-14
@@ -9,20 +9,18 @@ import org.jetbrains.kotlin.KtFakeSourceElementKind
|
|||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
import org.jetbrains.kotlin.fir.FirNameConflictsTrackerComponent
|
import org.jetbrains.kotlin.fir.FirNameConflictsTrackerComponent
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationCollector
|
import org.jetbrains.kotlin.fir.analysis.checkers.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.checkForLocalRedeclarations
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.collectClassMembers
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.collectTopLevel
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.packageFqName
|
import org.jetbrains.kotlin.fir.packageFqName
|
||||||
import org.jetbrains.kotlin.fir.resolve.getContainingDeclaration
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.PACKAGE_MEMBER
|
import org.jetbrains.kotlin.fir.scopes.impl.PACKAGE_MEMBER
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor
|
import org.jetbrains.kotlin.fir.scopes.impl.typeAliasForConstructor
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.utils.SmartSet
|
import org.jetbrains.kotlin.utils.SmartSet
|
||||||
|
|
||||||
@@ -30,7 +28,7 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is FirFile -> {
|
is FirFile -> {
|
||||||
val inspector = FirDeclarationCollector<FirDeclaration>(context)
|
val inspector = FirDeclarationCollector<FirBasedSymbol<*>>(context)
|
||||||
checkFile(declaration, inspector, context)
|
checkFile(declaration, inspector, context)
|
||||||
reportConflicts(reporter, context, inspector.declarationConflictingSymbols)
|
reportConflicts(reporter, context, inspector.declarationConflictingSymbols)
|
||||||
}
|
}
|
||||||
@@ -38,8 +36,8 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
if (declaration.source?.kind !is KtFakeSourceElementKind) {
|
if (declaration.source?.kind !is KtFakeSourceElementKind) {
|
||||||
checkForLocalRedeclarations(declaration.typeParameters, context, reporter)
|
checkForLocalRedeclarations(declaration.typeParameters, context, reporter)
|
||||||
}
|
}
|
||||||
val inspector = FirDeclarationCollector<FirDeclaration>(context)
|
val inspector = FirDeclarationCollector<FirBasedSymbol<*>>(context)
|
||||||
inspector.collectClassMembers(declaration)
|
inspector.collectClassMembers(declaration.symbol)
|
||||||
reportConflicts(reporter, context, inspector.declarationConflictingSymbols)
|
reportConflicts(reporter, context, inspector.declarationConflictingSymbols)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -56,18 +54,18 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
private fun reportConflicts(
|
private fun reportConflicts(
|
||||||
reporter: DiagnosticReporter,
|
reporter: DiagnosticReporter,
|
||||||
context: CheckerContext,
|
context: CheckerContext,
|
||||||
declarationConflictingSymbols: Map<FirDeclaration, SmartSet<FirBasedSymbol<*>>>,
|
declarationConflictingSymbols: Map<FirBasedSymbol<*>, SmartSet<FirBasedSymbol<*>>>,
|
||||||
) {
|
) {
|
||||||
declarationConflictingSymbols.forEach { (conflictingDeclaration, symbols) ->
|
declarationConflictingSymbols.forEach { (conflictingDeclaration, symbols) ->
|
||||||
val typeAliasForConstructorSource = (conflictingDeclaration as? FirConstructor)?.typeAliasForConstructor?.source
|
val typeAliasForConstructorSource = (conflictingDeclaration as? FirConstructorSymbol)?.typeAliasForConstructor?.source
|
||||||
val source = typeAliasForConstructorSource ?: conflictingDeclaration.source
|
val source = typeAliasForConstructorSource ?: conflictingDeclaration.source
|
||||||
if (symbols.isEmpty()) return@forEach
|
if (symbols.isEmpty()) return@forEach
|
||||||
|
|
||||||
val factory =
|
val factory =
|
||||||
if (conflictingDeclaration is FirSimpleFunction || conflictingDeclaration is FirConstructor) {
|
if (conflictingDeclaration is FirNamedFunctionSymbol || conflictingDeclaration is FirConstructorSymbol) {
|
||||||
FirErrors.CONFLICTING_OVERLOADS
|
FirErrors.CONFLICTING_OVERLOADS
|
||||||
} else if (conflictingDeclaration is FirClassLikeDeclaration &&
|
} else if (conflictingDeclaration is FirClassLikeSymbol<*> &&
|
||||||
conflictingDeclaration.getContainingDeclaration(context.session) == null &&
|
conflictingDeclaration.getContainingClassSymbol(context.session) == null &&
|
||||||
symbols.any { it is FirClassLikeSymbol<*> }
|
symbols.any { it is FirClassLikeSymbol<*> }
|
||||||
) {
|
) {
|
||||||
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
|
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
|
||||||
@@ -79,7 +77,7 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkFile(file: FirFile, inspector: FirDeclarationCollector<FirDeclaration>, context: CheckerContext) {
|
private fun checkFile(file: FirFile, inspector: FirDeclarationCollector<FirBasedSymbol<*>>, context: CheckerContext) {
|
||||||
val packageMemberScope: FirPackageMemberScope = context.sessionHolder.scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
|
val packageMemberScope: FirPackageMemberScope = context.sessionHolder.scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
|
||||||
FirPackageMemberScope(file.packageFqName, context.sessionHolder.session)
|
FirPackageMemberScope(file.packageFqName, context.sessionHolder.session)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -7,9 +7,10 @@ package org.jetbrains.kotlin.fir.declarations
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
|
||||||
interface FirDeclarationOverloadabilityHelper : FirSessionComponent {
|
interface FirDeclarationOverloadabilityHelper : FirSessionComponent {
|
||||||
fun isOverloadable(a: FirCallableDeclaration, b: FirCallableDeclaration): Boolean
|
fun isOverloadable(a: FirCallableSymbol<*>, b: FirCallableSymbol<*>): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.declarationOverloadabilityHelper: FirDeclarationOverloadabilityHelper by FirSession.sessionComponentAccessor()
|
val FirSession.declarationOverloadabilityHelper: FirDeclarationOverloadabilityHelper by FirSession.sessionComponentAccessor()
|
||||||
|
|||||||
+13
-15
@@ -6,19 +6,17 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOverloadabilityHelper
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.typeSpecificityComparatorProvider
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.*
|
import org.jetbrains.kotlin.resolve.calls.results.*
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
|
||||||
class FirDeclarationOverloadabilityHelperImpl(val session: FirSession) : FirDeclarationOverloadabilityHelper {
|
class FirDeclarationOverloadabilityHelperImpl(val session: FirSession) : FirDeclarationOverloadabilityHelper {
|
||||||
override fun isOverloadable(a: FirCallableDeclaration, b: FirCallableDeclaration): Boolean {
|
override fun isOverloadable(a: FirCallableSymbol<*>, b: FirCallableSymbol<*>): Boolean {
|
||||||
val sigA = createSignature(a)
|
val sigA = createSignature(a)
|
||||||
val sigB = createSignature(b)
|
val sigB = createSignature(b)
|
||||||
|
|
||||||
@@ -26,8 +24,8 @@ class FirDeclarationOverloadabilityHelperImpl(val session: FirSession) : FirDecl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isNotLessSpecific(
|
private fun isNotLessSpecific(
|
||||||
sigA: FlatSignature<FirCallableDeclaration>,
|
sigA: FlatSignature<FirCallableSymbol<*>>,
|
||||||
sigB: FlatSignature<FirCallableDeclaration>,
|
sigB: FlatSignature<FirCallableSymbol<*>>,
|
||||||
): Boolean = createEmptyConstraintSystem().isSignatureNotLessSpecific(
|
): Boolean = createEmptyConstraintSystem().isSignatureNotLessSpecific(
|
||||||
sigA,
|
sigA,
|
||||||
sigB,
|
sigB,
|
||||||
@@ -35,23 +33,23 @@ class FirDeclarationOverloadabilityHelperImpl(val session: FirSession) : FirDecl
|
|||||||
session.typeSpecificityComparatorProvider?.typeSpecificityComparator ?: TypeSpecificityComparator.NONE,
|
session.typeSpecificityComparatorProvider?.typeSpecificityComparator ?: TypeSpecificityComparator.NONE,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createSignature(declaration: FirCallableDeclaration): FlatSignature<FirCallableDeclaration> {
|
private fun createSignature(declaration: FirCallableSymbol<*>): FlatSignature<FirCallableSymbol<*>> {
|
||||||
val valueParameters = (declaration as? FirFunction)?.valueParameters.orEmpty()
|
val valueParameters = (declaration as? FirFunctionSymbol<*>)?.valueParameterSymbols.orEmpty()
|
||||||
|
|
||||||
return FlatSignature(
|
return FlatSignature(
|
||||||
origin = declaration,
|
origin = declaration,
|
||||||
typeParameters = declaration.typeParameters.map { it.symbol.toLookupTag() },
|
typeParameters = declaration.typeParameterSymbols.map { it.toLookupTag() },
|
||||||
valueParameterTypes = buildList<KotlinTypeMarker> {
|
valueParameterTypes = buildList<KotlinTypeMarker> {
|
||||||
declaration.contextReceivers.mapTo(this) { it.typeRef.coneType }
|
declaration.resolvedContextReceivers.mapTo(this) { it.typeRef.coneType }
|
||||||
declaration.receiverParameter?.let { add(it.typeRef.coneType) }
|
declaration.receiverParameter?.let { add(it.typeRef.coneType) }
|
||||||
valueParameters.mapTo(this) { it.returnTypeRef.coneType }
|
valueParameters.mapTo(this) { it.resolvedReturnType }
|
||||||
},
|
},
|
||||||
hasExtensionReceiver = declaration.receiverParameter != null,
|
hasExtensionReceiver = declaration.receiverParameter != null,
|
||||||
contextReceiverCount = declaration.contextReceivers.size,
|
contextReceiverCount = declaration.resolvedContextReceivers.size,
|
||||||
hasVarargs = valueParameters.any { it.isVararg },
|
hasVarargs = valueParameters.any { it.isVararg },
|
||||||
numDefaults = 0,
|
numDefaults = 0,
|
||||||
isExpect = declaration.isExpect,
|
isExpect = declaration.isExpect,
|
||||||
isSyntheticMember = declaration.isSynthetic
|
isSyntheticMember = declaration.origin is FirDeclarationOrigin.Synthetic
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user