[FIR] Merge DeclarationInspector into FirDeclarationInspector

There is no need of two separated classes
This commit is contained in:
Ivan Kochurkin
2023-01-24 22:40:42 +01:00
committed by Space Team
parent 07fd778319
commit b490130e8e
2 changed files with 227 additions and 247 deletions
@@ -6,20 +6,30 @@
package org.jetbrains.kotlin.fir.analysis.checkers package org.jetbrains.kotlin.fir.analysis.checkers
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.descriptors.ClassKind
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.FirElement import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext 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.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.declarations.utils.isOperator 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.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.types.*
import org.jetbrains.kotlin.fir.util.ListMultimap 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.CallableId
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.SmartSet
/** /**
* Provides representations for FirElement's. * Provides representations for FirElement's.
@@ -248,11 +258,11 @@ private fun FirDeclaration.isCollectable() = when (this) {
/** /**
* Collects FirDeclarations for further analysis. * Collects FirDeclarations for further analysis.
*/ */
open class FirDeclarationInspector( class FirDeclarationInspector {
protected val presenter: FirDeclarationPresenter = FirDefaultDeclarationPresenter() val declarationConflictingSymbols: HashMap<FirDeclaration, SmartSet<FirBasedSymbol<*>>> = hashMapOf()
) { private val presenter: FirDeclarationPresenter = FirDefaultDeclarationPresenter()
val otherDeclarations = mutableMapOf<String, MutableList<FirDeclaration>>() private val otherDeclarations = mutableMapOf<String, MutableList<FirDeclaration>>()
val functionDeclarations = mutableMapOf<String, MutableList<FirSimpleFunction>>() private val functionDeclarations = mutableMapOf<String, MutableList<FirSimpleFunction>>()
fun collect(declaration: FirDeclaration) { fun collect(declaration: FirDeclaration) {
when { 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) { otherDeclarations.getOrPut(key) {
mutableListOf() mutableListOf()
}.also { }.also {
it.add(declaration) 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) { functionDeclarations.getOrPut(key) {
mutableListOf() mutableListOf()
}.also { }.also {
it.add(declaration) it.add(declaration)
collectLocalConflicts(declaration, it)
} }
fun contains(declaration: FirDeclaration) = when (declaration) { private fun collectLocalConflicts(declaration: FirDeclaration, conflicting: List<FirDeclaration>) {
is FirSimpleFunction -> presenter.represent(declaration) in functionDeclarations val localConflicts = SmartSet.create<FirBasedSymbol<*>>()
is FirRegularClass -> presenter.represent(declaration) in otherDeclarations for (otherDeclaration in conflicting) {
is FirTypeAlias -> presenter.represent(declaration) in otherDeclarations if (otherDeclaration is FirField && otherDeclaration.source?.kind == KtFakeSourceElementKind.ClassDelegationField) {
is FirProperty -> presenter.represent(declaration) in otherDeclarations // class delegation field will be renamed after by the IR backend in a case of a name clash
else -> false 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())
}
} }
} }
@@ -6,234 +6,35 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.descriptors.ClassKind
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.* import org.jetbrains.kotlin.fir.FirNameConflictsTrackerComponent
import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector 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.checkConflictingElements
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.resolve.getContainingDeclaration 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.FirPackageMemberScope
import org.jetbrains.kotlin.fir.scopes.impl.PACKAGE_MEMBER 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.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.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.SmartSet
object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() { 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) { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
val inspector: DeclarationInspector? val inspector: FirDeclarationInspector?
when (declaration) { when (declaration) {
is FirFile -> { is FirFile -> {
inspector = DeclarationInspector() inspector = FirDeclarationInspector()
checkFile(declaration, inspector, context) checkFile(declaration, inspector, context)
} }
is FirRegularClass -> { is FirRegularClass -> {
if (declaration.source?.kind !is KtFakeSourceElementKind) { if (declaration.source?.kind !is KtFakeSourceElementKind) {
checkConflictingElements(declaration.typeParameters, context, reporter) checkConflictingElements(declaration.typeParameters, context, reporter)
} }
inspector = DeclarationInspector() inspector = FirDeclarationInspector()
checkRegularClass(declaration, inspector) checkRegularClass(declaration, inspector)
} }
else -> { 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) { val packageMemberScope: FirPackageMemberScope = context.sessionHolder.scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
FirPackageMemberScope(file.packageFqName, context.sessionHolder.session) 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) { for (it in declaration.declarations) {
inspector.collect(it) 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() { class FirNameConflictsTracker : FirNameConflictsTrackerComponent() {
data class ClassifierWithFile( 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())
}
}