Optimize TowerResolver.run implementation
- run `processor` at each level instead of list construction - make it as lazy as possible Speed up analysis time nearly for 2-5%
This commit is contained in:
+2
-2
@@ -116,12 +116,12 @@ class NewResolveOldInference(
|
|||||||
Candidate(ResolutionCandidateStatus(diagnostics), resolvedCall)
|
Candidate(ResolutionCandidateStatus(diagnostics), resolvedCall)
|
||||||
}
|
}
|
||||||
if (basicCallContext.collectAllCandidates) {
|
if (basicCallContext.collectAllCandidates) {
|
||||||
val allCandidates = towerResolver.run(listOf(TowerData.Empty), KnownResultProcessor(resolvedCandidates),
|
val allCandidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolvedCandidates),
|
||||||
TowerResolver.AllCandidatesCollector { it.candidateStatus }, useOrder = false)
|
TowerResolver.AllCandidatesCollector { it.candidateStatus }, useOrder = false)
|
||||||
return allCandidatesResult(allCandidates) as OverloadResolutionResultsImpl<D>
|
return allCandidatesResult(allCandidates) as OverloadResolutionResultsImpl<D>
|
||||||
}
|
}
|
||||||
|
|
||||||
val processedCandidates = towerResolver.run(listOf(TowerData.Empty), KnownResultProcessor(resolvedCandidates),
|
val processedCandidates = towerResolver.runWithEmptyTowerData(KnownResultProcessor(resolvedCandidates),
|
||||||
TowerResolver.SuccessfulResultCollector { it.candidateStatus }, useOrder = true)
|
TowerResolver.SuccessfulResultCollector { it.candidateStatus }, useOrder = true)
|
||||||
|
|
||||||
return convertToOverloadResults(processedCandidates, tracing, basicCallContext) as OverloadResolutionResultsImpl<D>
|
return convertToOverloadResults(processedCandidates, tracing, basicCallContext) as OverloadResolutionResultsImpl<D>
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ class TowerResolver {
|
|||||||
context: TowerContext<C>,
|
context: TowerContext<C>,
|
||||||
processor: ScopeTowerProcessor<C>,
|
processor: ScopeTowerProcessor<C>,
|
||||||
useOrder: Boolean
|
useOrder: Boolean
|
||||||
): Collection<C> = run(context.scopeTower.createTowerDataList(), processor, SuccessfulResultCollector { context.getStatus(it) }, useOrder)
|
): Collection<C> = context.scopeTower.run(processor, SuccessfulResultCollector { context.getStatus(it) }, useOrder)
|
||||||
|
|
||||||
fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C>
|
fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C>
|
||||||
= run(context.scopeTower.createTowerDataList(), processor, AllCandidatesCollector { context.getStatus(it) }, false)
|
= context.scopeTower.run(processor, AllCandidatesCollector { context.getStatus(it) }, false)
|
||||||
|
|
||||||
private fun ScopeTower.createNonLocalLevels(): List<ScopeTowerLevel> {
|
private fun ScopeTower.createNonLocalLevels(): List<ScopeTowerLevel> {
|
||||||
val result = ArrayList<ScopeTowerLevel>()
|
val result = ArrayList<ScopeTowerLevel>()
|
||||||
@@ -87,98 +87,108 @@ class TowerResolver {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ScopeTower.createTowerDataList(): List<TowerData> {
|
private fun <C> ScopeTower.run(
|
||||||
val result = ArrayList<TowerData>()
|
processor: ScopeTowerProcessor<C>,
|
||||||
|
resultCollector: ResultCollector<C>,
|
||||||
operator fun TowerData.unaryPlus() = result.add(this)
|
useOrder: Boolean
|
||||||
|
): Collection<C> {
|
||||||
|
fun TowerData.process() = processTowerData(processor, resultCollector, useOrder, this)
|
||||||
|
|
||||||
val localLevels = lexicalScope.parentsWithSelf.
|
val localLevels = lexicalScope.parentsWithSelf.
|
||||||
filterIsInstance<LexicalScope>().filter { it.kind.withLocalDescriptors }.
|
filterIsInstance<LexicalScope>().filter { it.kind.withLocalDescriptors }.
|
||||||
map { ScopeBasedTowerLevel(this@createTowerDataList, it) }
|
map { ScopeBasedTowerLevel(this@run, it) }
|
||||||
|
|
||||||
val nonLocalLevels = createNonLocalLevels()
|
// Lazy calculation
|
||||||
|
var nonLocalLevels: Collection<ScopeTowerLevel>? = null
|
||||||
val hidesMembersLevel = HidesMembersTowerLevel(this)
|
val hidesMembersLevel = HidesMembersTowerLevel(this)
|
||||||
val syntheticLevel = SyntheticScopeBasedTowerLevel(this, syntheticScopes)
|
val syntheticLevel = SyntheticScopeBasedTowerLevel(this, syntheticScopes)
|
||||||
|
|
||||||
// hides members extensions for explicit receiver
|
// hides members extensions for explicit receiver
|
||||||
+ TowerData.TowerLevel(hidesMembersLevel)
|
TowerData.TowerLevel(hidesMembersLevel).process()?.let { return it }
|
||||||
// possibly there is explicit member
|
// possibly there is explicit member
|
||||||
+ TowerData.Empty
|
TowerData.Empty.process()?.let { return it }
|
||||||
// synthetic member for explicit receiver
|
// synthetic member for explicit receiver
|
||||||
+ TowerData.TowerLevel(syntheticLevel)
|
TowerData.TowerLevel(syntheticLevel).process()?.let { return it }
|
||||||
|
|
||||||
// local non-extensions or extension for explicit receiver
|
// local non-extensions or extension for explicit receiver
|
||||||
for (localLevel in localLevels) {
|
for (localLevel in localLevels) {
|
||||||
+ TowerData.TowerLevel(localLevel)
|
TowerData.TowerLevel(localLevel).process()?.let { return it }
|
||||||
}
|
}
|
||||||
|
|
||||||
for (scope in this.lexicalScope.parentsWithSelf) {
|
for (scope in lexicalScope.parentsWithSelf) {
|
||||||
if (scope is LexicalScope) {
|
if (scope is LexicalScope) {
|
||||||
// statics
|
// statics
|
||||||
if (!scope.kind.withLocalDescriptors) {
|
if (!scope.kind.withLocalDescriptors) {
|
||||||
+ TowerData.TowerLevel(ScopeBasedTowerLevel(this, scope))
|
TowerData.TowerLevel(ScopeBasedTowerLevel(this, scope)).process()?.let { return it }
|
||||||
}
|
}
|
||||||
|
|
||||||
val implicitReceiver = scope.implicitReceiver?.value
|
val implicitReceiver = scope.implicitReceiver?.value
|
||||||
if (implicitReceiver != null) {
|
if (implicitReceiver != null) {
|
||||||
// hides members extensions
|
// hides members extensions
|
||||||
+ TowerData.BothTowerLevelAndImplicitReceiver(hidesMembersLevel, implicitReceiver)
|
TowerData.BothTowerLevelAndImplicitReceiver(hidesMembersLevel, implicitReceiver).process()?.let { return it }
|
||||||
|
|
||||||
// members of implicit receiver or member extension for explicit receiver
|
// members of implicit receiver or member extension for explicit receiver
|
||||||
+ TowerData.TowerLevel(ReceiverScopeTowerLevel(this, implicitReceiver))
|
TowerData.TowerLevel(ReceiverScopeTowerLevel(this, implicitReceiver)).process()?.let { return it }
|
||||||
|
|
||||||
// synthetic members
|
// synthetic members
|
||||||
+ TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver)
|
TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver).process()?.let { return it }
|
||||||
|
|
||||||
// invokeExtension on local variable
|
// invokeExtension on local variable
|
||||||
+ TowerData.OnlyImplicitReceiver(implicitReceiver)
|
TowerData.OnlyImplicitReceiver(implicitReceiver).process()?.let { return it }
|
||||||
|
|
||||||
// local extensions for implicit receiver
|
// local extensions for implicit receiver
|
||||||
for (localLevel in localLevels) {
|
for (localLevel in localLevels) {
|
||||||
+ TowerData.BothTowerLevelAndImplicitReceiver(localLevel, implicitReceiver)
|
TowerData.BothTowerLevelAndImplicitReceiver(localLevel, implicitReceiver).process()?.let { return it }
|
||||||
}
|
}
|
||||||
|
|
||||||
// extension for implicit receiver
|
// extension for implicit receiver
|
||||||
|
if (nonLocalLevels == null) {
|
||||||
|
nonLocalLevels = createNonLocalLevels()
|
||||||
|
}
|
||||||
|
|
||||||
for (nonLocalLevel in nonLocalLevels) {
|
for (nonLocalLevel in nonLocalLevels) {
|
||||||
+ TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver)
|
TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver).process()?.let { return it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// functions with no receiver or extension for explicit receiver
|
// functions with no receiver or extension for explicit receiver
|
||||||
+ TowerData.TowerLevel(ImportingScopeBasedTowerLevel(this, scope as ImportingScope))
|
TowerData.TowerLevel(ImportingScopeBasedTowerLevel(this, scope as ImportingScope)).process()?.let { return it }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <C> run(
|
|
||||||
towerDataList: List<TowerData>,
|
|
||||||
processor: ScopeTowerProcessor<C>,
|
|
||||||
resultCollector: ResultCollector<C>,
|
|
||||||
useOrder: Boolean
|
|
||||||
): Collection<C> {
|
|
||||||
|
|
||||||
for (towerData in towerDataList) {
|
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
|
||||||
|
|
||||||
val candidatesGroups = if (useOrder) {
|
|
||||||
processor.process(towerData)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
listOf(processor.process(towerData).flatMap { it })
|
|
||||||
}
|
|
||||||
|
|
||||||
for (candidatesGroup in candidatesGroups) {
|
|
||||||
resultCollector.pushCandidates(candidatesGroup)
|
|
||||||
resultCollector.getSuccessfulCandidates()?.let { return it }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultCollector.getFinalCandidates()
|
return resultCollector.getFinalCandidates()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <C> runWithEmptyTowerData(
|
||||||
|
processor: ScopeTowerProcessor<C>,
|
||||||
|
resultCollector: ResultCollector<C>,
|
||||||
|
useOrder: Boolean
|
||||||
|
): Collection<C> = processTowerData(processor, resultCollector, useOrder, TowerData.Empty) ?: resultCollector.getFinalCandidates()
|
||||||
|
|
||||||
|
private fun <C> processTowerData(
|
||||||
|
processor: ScopeTowerProcessor<C>,
|
||||||
|
resultCollector: ResultCollector<C>,
|
||||||
|
useOrder: Boolean,
|
||||||
|
towerData: TowerData
|
||||||
|
): Collection<C>? {
|
||||||
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
|
val candidatesGroups = if (useOrder) {
|
||||||
|
processor.process(towerData)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
listOf(processor.process(towerData).flatMap { it })
|
||||||
|
}
|
||||||
|
|
||||||
|
for (candidatesGroup in candidatesGroups) {
|
||||||
|
resultCollector.pushCandidates(candidatesGroup)
|
||||||
|
resultCollector.getSuccessfulCandidates()?.let { return it }
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
abstract class ResultCollector<C>(protected val getStatus: (C) -> ResolutionCandidateStatus) {
|
abstract class ResultCollector<C>(protected val getStatus: (C) -> ResolutionCandidateStatus) {
|
||||||
abstract fun getSuccessfulCandidates(): Collection<C>?
|
abstract fun getSuccessfulCandidates(): Collection<C>?
|
||||||
|
|||||||
Reference in New Issue
Block a user