[FIR] Merge DeclarationInspector into FirDeclarationInspector
There is no need of two separated classes
This commit is contained in:
committed by
Space Team
parent
07fd778319
commit
b490130e8e
+220
-14
@@ -6,20 +6,30 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirNameConflictsTracker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.util.ListMultimap
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
|
||||
/**
|
||||
* Provides representations for FirElement's.
|
||||
@@ -248,11 +258,11 @@ private fun FirDeclaration.isCollectable() = when (this) {
|
||||
/**
|
||||
* Collects FirDeclarations for further analysis.
|
||||
*/
|
||||
open class FirDeclarationInspector(
|
||||
protected val presenter: FirDeclarationPresenter = FirDefaultDeclarationPresenter()
|
||||
) {
|
||||
val otherDeclarations = mutableMapOf<String, MutableList<FirDeclaration>>()
|
||||
val functionDeclarations = mutableMapOf<String, MutableList<FirSimpleFunction>>()
|
||||
class FirDeclarationInspector {
|
||||
val declarationConflictingSymbols: HashMap<FirDeclaration, SmartSet<FirBasedSymbol<*>>> = hashMapOf()
|
||||
private val presenter: FirDeclarationPresenter = FirDefaultDeclarationPresenter()
|
||||
private val otherDeclarations = mutableMapOf<String, MutableList<FirDeclaration>>()
|
||||
private val functionDeclarations = mutableMapOf<String, MutableList<FirSimpleFunction>>()
|
||||
|
||||
fun collect(declaration: FirDeclaration) {
|
||||
when {
|
||||
@@ -264,26 +274,222 @@ open class FirDeclarationInspector(
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun collectNonFunctionDeclaration(key: String, declaration: FirDeclaration): MutableList<FirDeclaration> =
|
||||
fun collectWithExternalConflicts(
|
||||
declaration: FirDeclaration,
|
||||
containingFile: FirFile,
|
||||
session: FirSession,
|
||||
packageMemberScope: FirPackageMemberScope
|
||||
) {
|
||||
collect(declaration)
|
||||
var declarationName: Name? = null
|
||||
val declarationPresentation = presenter.represent(declaration) ?: return
|
||||
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> {
|
||||
declarationName = declaration.name
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processFunctionsByName(declarationName) {
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, it, null, null, session
|
||||
)
|
||||
}
|
||||
packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ ->
|
||||
symbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
@OptIn(SymbolInternals::class)
|
||||
val classWithSameName = symbol.fir as? FirRegularClass
|
||||
classWithSameName?.onConstructors { constructor ->
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile,
|
||||
constructor.symbol, presenter.represent(constructor, classWithSameName), null,
|
||||
session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirVariable -> {
|
||||
declarationName = declaration.name
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processPropertiesByName(declarationName) {
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, it, null, null, session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirRegularClass -> {
|
||||
declarationName = declaration.name
|
||||
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ ->
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, symbol, null, null, session
|
||||
)
|
||||
}
|
||||
declaration.onConstructors { constructor ->
|
||||
packageMemberScope.processFunctionsByName(declarationName!!) {
|
||||
collectExternalConflict(
|
||||
constructor, presenter.represent(constructor, declaration), containingFile,
|
||||
it, null, null, session
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
session.nameConflictsTracker?.let { it as? FirNameConflictsTracker }
|
||||
?.redeclaredClassifiers?.get(declaration.symbol.classId)?.forEach {
|
||||
collectExternalConflict(
|
||||
declaration,
|
||||
declarationPresentation,
|
||||
containingFile,
|
||||
it.classifier,
|
||||
null,
|
||||
it.file,
|
||||
session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirTypeAlias -> {
|
||||
declarationName = declaration.name
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ ->
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, symbol, null, null, session
|
||||
)
|
||||
}
|
||||
session.nameConflictsTracker?.let { it as? FirNameConflictsTracker }
|
||||
?.redeclaredClassifiers?.get(declaration.symbol.classId)?.forEach {
|
||||
collectExternalConflict(
|
||||
declaration,
|
||||
declarationPresentation,
|
||||
containingFile,
|
||||
it.classifier,
|
||||
null,
|
||||
it.file,
|
||||
session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
if (declarationName != null) {
|
||||
session.lookupTracker?.recordLookup(
|
||||
declarationName, containingFile.packageFqName.asString(), declaration.source, containingFile.source
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectNonFunctionDeclaration(key: String, declaration: FirDeclaration): MutableList<FirDeclaration> =
|
||||
otherDeclarations.getOrPut(key) {
|
||||
mutableListOf()
|
||||
}.also {
|
||||
it.add(declaration)
|
||||
collectLocalConflicts(declaration, it)
|
||||
}
|
||||
|
||||
protected open fun collectFunction(key: String, declaration: FirSimpleFunction): MutableList<FirSimpleFunction> =
|
||||
private fun collectFunction(key: String, declaration: FirSimpleFunction): MutableList<FirSimpleFunction> =
|
||||
functionDeclarations.getOrPut(key) {
|
||||
mutableListOf()
|
||||
}.also {
|
||||
it.add(declaration)
|
||||
collectLocalConflicts(declaration, it)
|
||||
}
|
||||
|
||||
fun contains(declaration: FirDeclaration) = when (declaration) {
|
||||
is FirSimpleFunction -> presenter.represent(declaration) in functionDeclarations
|
||||
is FirRegularClass -> presenter.represent(declaration) in otherDeclarations
|
||||
is FirTypeAlias -> presenter.represent(declaration) in otherDeclarations
|
||||
is FirProperty -> presenter.represent(declaration) in otherDeclarations
|
||||
else -> false
|
||||
private fun collectLocalConflicts(declaration: FirDeclaration, conflicting: List<FirDeclaration>) {
|
||||
val localConflicts = SmartSet.create<FirBasedSymbol<*>>()
|
||||
for (otherDeclaration in conflicting) {
|
||||
if (otherDeclaration is FirField && otherDeclaration.source?.kind == KtFakeSourceElementKind.ClassDelegationField) {
|
||||
// class delegation field will be renamed after by the IR backend in a case of a name clash
|
||||
continue
|
||||
}
|
||||
if (otherDeclaration != declaration && !isExpectAndActual(declaration, otherDeclaration)) {
|
||||
localConflicts.add(otherDeclaration.symbol)
|
||||
declarationConflictingSymbols.getOrPut(otherDeclaration) { SmartSet.create() }.add(declaration.symbol)
|
||||
}
|
||||
}
|
||||
declarationConflictingSymbols[declaration] = localConflicts
|
||||
}
|
||||
|
||||
private fun isExpectAndActual(declaration1: FirDeclaration, declaration2: FirDeclaration): Boolean {
|
||||
if (declaration1 !is FirMemberDeclaration) return false
|
||||
if (declaration2 !is FirMemberDeclaration) return false
|
||||
return (declaration1.status.isExpect && declaration2.status.isActual) ||
|
||||
(declaration1.status.isActual && declaration2.status.isExpect)
|
||||
}
|
||||
|
||||
private fun areCompatibleMainFunctions(
|
||||
declaration1: FirDeclaration, file1: FirFile, declaration2: FirDeclaration, file2: FirFile?
|
||||
): Boolean {
|
||||
// TODO: proper main function detector
|
||||
if (declaration1 !is FirSimpleFunction || declaration2 !is FirSimpleFunction) return false
|
||||
if (declaration1.name.asString() != "main" || declaration2.name.asString() != "main") return false
|
||||
return file1 != file2
|
||||
}
|
||||
|
||||
private fun collectExternalConflict(
|
||||
declaration: FirDeclaration,
|
||||
declarationPresentation: String,
|
||||
containingFile: FirFile,
|
||||
conflictingSymbol: FirBasedSymbol<*>,
|
||||
conflictingPresentation: String?,
|
||||
conflictingFile: FirFile?,
|
||||
session: FirSession
|
||||
) {
|
||||
conflictingSymbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
@OptIn(SymbolInternals::class)
|
||||
val conflicting = conflictingSymbol.fir
|
||||
if (conflicting == declaration || declaration.moduleData != conflicting.moduleData) return
|
||||
val actualConflictingPresentation = conflictingPresentation ?: presenter.represent(conflicting)
|
||||
if (actualConflictingPresentation != declarationPresentation) return
|
||||
val actualConflictingFile =
|
||||
conflictingFile ?: when (conflictingSymbol) {
|
||||
is FirClassLikeSymbol<*> -> session.firProvider.getFirClassifierContainerFileIfAny(conflictingSymbol)
|
||||
is FirCallableSymbol<*> -> session.firProvider.getFirCallableContainerFile(conflictingSymbol)
|
||||
else -> null
|
||||
}
|
||||
if (containingFile == actualConflictingFile && conflicting.origin == FirDeclarationOrigin.Precompiled) {
|
||||
return // TODO: rewrite local decls checker to the same logic and then remove the check
|
||||
}
|
||||
if (areCompatibleMainFunctions(declaration, containingFile, conflicting, actualConflictingFile)) return
|
||||
if (isExpectAndActual(declaration, conflicting)) return
|
||||
if (
|
||||
conflicting is FirMemberDeclaration &&
|
||||
!session.visibilityChecker.isVisible(conflicting, session, containingFile, emptyList(), dispatchReceiver = null)
|
||||
) return
|
||||
val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations)
|
||||
val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
|
||||
if (declarationIsLowPriority != conflictingIsLowPriority) return
|
||||
declarationConflictingSymbols.getOrPut(declaration) { SmartSet.create() }.add(conflictingSymbol)
|
||||
}
|
||||
|
||||
private fun FirDeclarationPresenter.represent(declaration: FirDeclaration): String? =
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> represent(declaration)
|
||||
is FirRegularClass -> represent(declaration)
|
||||
is FirTypeAlias -> represent(declaration)
|
||||
is FirProperty -> represent(declaration)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun FirRegularClass.onConstructors(action: (ctor: FirConstructor) -> Unit) {
|
||||
class ClassConstructorVisitor : FirVisitorVoid() {
|
||||
override fun visitElement(element: FirElement) {}
|
||||
|
||||
override fun visitConstructor(constructor: FirConstructor) {
|
||||
action(constructor)
|
||||
}
|
||||
|
||||
override fun visitDeclarationStatus(declarationStatus: FirDeclarationStatus) {}
|
||||
override fun visitRegularClass(regularClass: FirRegularClass) {}
|
||||
override fun visitProperty(property: FirProperty) {}
|
||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {}
|
||||
}
|
||||
|
||||
if (classKind != ClassKind.OBJECT && classKind != ClassKind.ENUM_ENTRY) {
|
||||
acceptChildren(ClassConstructorVisitor())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-233
@@ -6,234 +6,35 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.FirNameConflictsTrackerComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.checkConflictingElements
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.packageFqName
|
||||
import org.jetbrains.kotlin.fir.resolve.getContainingDeclaration
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.PACKAGE_MEMBER
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
|
||||
object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
|
||||
private class DeclarationInspector : FirDeclarationInspector() {
|
||||
|
||||
val declarationConflictingSymbols: HashMap<FirDeclaration, SmartSet<FirBasedSymbol<*>>> = hashMapOf()
|
||||
|
||||
override fun collectNonFunctionDeclaration(key: String, declaration: FirDeclaration): MutableList<FirDeclaration> =
|
||||
super.collectNonFunctionDeclaration(key, declaration).also {
|
||||
collectLocalConflicts(declaration, it)
|
||||
}
|
||||
|
||||
override fun collectFunction(key: String, declaration: FirSimpleFunction): MutableList<FirSimpleFunction> =
|
||||
super.collectFunction(key, declaration).also {
|
||||
collectLocalConflicts(declaration, it)
|
||||
}
|
||||
|
||||
private fun collectLocalConflicts(declaration: FirDeclaration, conflicting: List<FirDeclaration>) {
|
||||
val localConflicts = SmartSet.create<FirBasedSymbol<*>>()
|
||||
for (otherDeclaration in conflicting) {
|
||||
if (otherDeclaration is FirField && otherDeclaration.source?.kind == KtFakeSourceElementKind.ClassDelegationField) {
|
||||
// class delegation field will be renamed after by the IR backend in a case of a name clash
|
||||
continue
|
||||
}
|
||||
if (otherDeclaration != declaration && !isExpectAndActual(declaration, otherDeclaration)) {
|
||||
localConflicts.add(otherDeclaration.symbol)
|
||||
declarationConflictingSymbols.getOrPut(otherDeclaration) { SmartSet.create() }.add(declaration.symbol)
|
||||
}
|
||||
}
|
||||
declarationConflictingSymbols[declaration] = localConflicts
|
||||
}
|
||||
|
||||
private fun isExpectAndActual(declaration1: FirDeclaration, declaration2: FirDeclaration): Boolean {
|
||||
if (declaration1 !is FirMemberDeclaration) return false
|
||||
if (declaration2 !is FirMemberDeclaration) return false
|
||||
return (declaration1.status.isExpect && declaration2.status.isActual) ||
|
||||
(declaration1.status.isActual && declaration2.status.isExpect)
|
||||
}
|
||||
|
||||
private fun areCompatibleMainFunctions(
|
||||
declaration1: FirDeclaration, file1: FirFile, declaration2: FirDeclaration, file2: FirFile?
|
||||
): Boolean {
|
||||
// TODO: proper main function detector
|
||||
if (declaration1 !is FirSimpleFunction || declaration2 !is FirSimpleFunction) return false
|
||||
if (declaration1.name.asString() != "main" || declaration2.name.asString() != "main") return false
|
||||
return file1 != file2
|
||||
}
|
||||
|
||||
private fun collectExternalConflict(
|
||||
declaration: FirDeclaration,
|
||||
declarationPresentation: String,
|
||||
containingFile: FirFile,
|
||||
conflictingSymbol: FirBasedSymbol<*>,
|
||||
conflictingPresentation: String?,
|
||||
conflictingFile: FirFile?,
|
||||
session: FirSession
|
||||
) {
|
||||
conflictingSymbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
@OptIn(SymbolInternals::class)
|
||||
val conflicting = conflictingSymbol.fir
|
||||
if (conflicting == declaration || declaration.moduleData != conflicting.moduleData) return
|
||||
val actualConflictingPresentation = conflictingPresentation ?: presenter.represent(conflicting)
|
||||
if (actualConflictingPresentation != declarationPresentation) return
|
||||
val actualConflictingFile =
|
||||
conflictingFile ?: when (conflictingSymbol) {
|
||||
is FirClassLikeSymbol<*> -> session.firProvider.getFirClassifierContainerFileIfAny(conflictingSymbol)
|
||||
is FirCallableSymbol<*> -> session.firProvider.getFirCallableContainerFile(conflictingSymbol)
|
||||
else -> null
|
||||
}
|
||||
if (containingFile == actualConflictingFile && conflicting.origin == FirDeclarationOrigin.Precompiled) {
|
||||
return // TODO: rewrite local decls checker to the same logic and then remove the check
|
||||
}
|
||||
if (areCompatibleMainFunctions(declaration, containingFile, conflicting, actualConflictingFile)) return
|
||||
if (isExpectAndActual(declaration, conflicting)) return
|
||||
if (
|
||||
conflicting is FirMemberDeclaration &&
|
||||
!session.visibilityChecker.isVisible(conflicting, session, containingFile, emptyList(), dispatchReceiver = null)
|
||||
) return
|
||||
val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations)
|
||||
val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations)
|
||||
if (declarationIsLowPriority != conflictingIsLowPriority) return
|
||||
declarationConflictingSymbols.getOrPut(declaration) { SmartSet.create() }.add(conflictingSymbol)
|
||||
}
|
||||
|
||||
fun collectWithExternalConflicts(
|
||||
declaration: FirDeclaration,
|
||||
containingFile: FirFile,
|
||||
session: FirSession,
|
||||
packageMemberScope: FirPackageMemberScope
|
||||
) {
|
||||
collect(declaration)
|
||||
var declarationName: Name? = null
|
||||
val declarationPresentation = presenter.represent(declaration) ?: return
|
||||
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> {
|
||||
declarationName = declaration.name
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processFunctionsByName(declarationName) {
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, it, null, null, session
|
||||
)
|
||||
}
|
||||
packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ ->
|
||||
symbol.lazyResolveToPhase(FirResolvePhase.STATUS)
|
||||
@OptIn(SymbolInternals::class)
|
||||
val classWithSameName = symbol.fir as? FirRegularClass
|
||||
classWithSameName?.onConstructors { constructor ->
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile,
|
||||
constructor.symbol, presenter.represent(constructor, classWithSameName), null,
|
||||
session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirVariable -> {
|
||||
declarationName = declaration.name
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processPropertiesByName(declarationName) {
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, it, null, null, session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirRegularClass -> {
|
||||
declarationName = declaration.name
|
||||
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ ->
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, symbol, null, null, session
|
||||
)
|
||||
}
|
||||
declaration.onConstructors { constructor ->
|
||||
packageMemberScope.processFunctionsByName(declarationName!!) {
|
||||
collectExternalConflict(
|
||||
constructor, presenter.represent(constructor, declaration), containingFile,
|
||||
it, null, null, session
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
session.nameConflictsTracker?.let { it as? FirNameConflictsTracker }
|
||||
?.redeclaredClassifiers?.get(declaration.symbol.classId)?.forEach {
|
||||
collectExternalConflict(
|
||||
declaration,
|
||||
declarationPresentation,
|
||||
containingFile,
|
||||
it.classifier,
|
||||
null,
|
||||
it.file,
|
||||
session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is FirTypeAlias -> {
|
||||
declarationName = declaration.name
|
||||
if (!declarationName.isSpecial) {
|
||||
packageMemberScope.processClassifiersByNameWithSubstitution(declarationName) { symbol, _ ->
|
||||
collectExternalConflict(
|
||||
declaration, declarationPresentation, containingFile, symbol, null, null, session
|
||||
)
|
||||
}
|
||||
session.nameConflictsTracker?.let { it as? FirNameConflictsTracker }
|
||||
?.redeclaredClassifiers?.get(declaration.symbol.classId)?.forEach {
|
||||
collectExternalConflict(
|
||||
declaration,
|
||||
declarationPresentation,
|
||||
containingFile,
|
||||
it.classifier,
|
||||
null,
|
||||
it.file,
|
||||
session
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
if (declarationName != null) {
|
||||
session.lookupTracker?.recordLookup(
|
||||
declarationName, containingFile.packageFqName.asString(), declaration.source, containingFile.source
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val inspector: DeclarationInspector?
|
||||
val inspector: FirDeclarationInspector?
|
||||
|
||||
when (declaration) {
|
||||
is FirFile -> {
|
||||
inspector = DeclarationInspector()
|
||||
inspector = FirDeclarationInspector()
|
||||
checkFile(declaration, inspector, context)
|
||||
}
|
||||
is FirRegularClass -> {
|
||||
if (declaration.source?.kind !is KtFakeSourceElementKind) {
|
||||
checkConflictingElements(declaration.typeParameters, context, reporter)
|
||||
}
|
||||
inspector = DeclarationInspector()
|
||||
inspector = FirDeclarationInspector()
|
||||
checkRegularClass(declaration, inspector)
|
||||
}
|
||||
else -> {
|
||||
@@ -271,7 +72,7 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkFile(file: FirFile, inspector: DeclarationInspector, context: CheckerContext) {
|
||||
private fun checkFile(file: FirFile, inspector: FirDeclarationInspector, context: CheckerContext) {
|
||||
val packageMemberScope: FirPackageMemberScope = context.sessionHolder.scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
|
||||
FirPackageMemberScope(file.packageFqName, context.sessionHolder.session)
|
||||
}
|
||||
@@ -280,22 +81,13 @@ object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkRegularClass(declaration: FirRegularClass, inspector: DeclarationInspector) {
|
||||
private fun checkRegularClass(declaration: FirRegularClass, inspector: FirDeclarationInspector) {
|
||||
for (it in declaration.declarations) {
|
||||
inspector.collect(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclarationPresenter.represent(declaration: FirDeclaration): String? =
|
||||
when (declaration) {
|
||||
is FirSimpleFunction -> represent(declaration)
|
||||
is FirRegularClass -> represent(declaration)
|
||||
is FirTypeAlias -> represent(declaration)
|
||||
is FirProperty -> represent(declaration)
|
||||
else -> null
|
||||
}
|
||||
|
||||
class FirNameConflictsTracker : FirNameConflictsTrackerComponent() {
|
||||
|
||||
data class ClassifierWithFile(
|
||||
@@ -316,22 +108,4 @@ class FirNameConflictsTracker : FirNameConflictsTrackerComponent() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirRegularClass.onConstructors(action: (ctor: FirConstructor) -> Unit) {
|
||||
|
||||
class ClassConstructorVisitor : FirVisitorVoid() {
|
||||
override fun visitElement(element: FirElement) {}
|
||||
|
||||
override fun visitConstructor(constructor: FirConstructor) {
|
||||
action(constructor)
|
||||
}
|
||||
|
||||
override fun visitDeclarationStatus(declarationStatus: FirDeclarationStatus) {}
|
||||
override fun visitRegularClass(regularClass: FirRegularClass) {}
|
||||
override fun visitProperty(property: FirProperty) {}
|
||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {}
|
||||
}
|
||||
|
||||
if (classKind != ClassKind.OBJECT && classKind != ClassKind.ENUM_ENTRY) {
|
||||
acceptChildren(ClassConstructorVisitor())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user