Support "given candidates" mode in new resolution algorithm.
This commit is contained in:
@@ -648,13 +648,16 @@ public class CallResolver {
|
||||
}
|
||||
}
|
||||
|
||||
if (contextForMigration.resolveKind != ResolveKind.GIVEN_CANDIDATES && useNewResolve) {
|
||||
if (contextForMigration.resolveKind != ResolveKind.GIVEN_CANDIDATES) {
|
||||
assert contextForMigration.name != null;
|
||||
return (OverloadResolutionResultsImpl<F>)
|
||||
newCallResolver.runResolve(context, contextForMigration.name, contextForMigration.resolveKind, tracing);
|
||||
}
|
||||
else {
|
||||
return (OverloadResolutionResultsImpl<F>) newCallResolver.runResolveForGivenCandidates(context, tracing, contextForMigration.givenCandidates);
|
||||
}
|
||||
|
||||
return doResolveCall(context, contextForMigration.lazyTasks.invoke(), contextForMigration.callTransformer, tracing);
|
||||
//return doResolveCall(context, contextForMigration.lazyTasks.invoke(), contextForMigration.callTransformer, tracing);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+43
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,10 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.*
|
||||
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
@@ -77,10 +74,7 @@ class NewResolveOldInference(
|
||||
var processor = createResolveProcessor(kind, explicitReceiver, context, baseContext)
|
||||
|
||||
if (context.collectAllCandidates) {
|
||||
val allCandidates = towerResolver.collectAllCandidates(baseContext, processor)
|
||||
val result = OverloadResolutionResultsImpl.nameNotFound<CallableDescriptor>()
|
||||
result.allCandidates = allCandidates.map { it.resolvedCall as MutableResolvedCall<CallableDescriptor> }
|
||||
return result
|
||||
return allCandidatesResult(towerResolver.collectAllCandidates(baseContext, processor))
|
||||
}
|
||||
// Temporary fix for code migration (unaryPlus()/unaryMinus())
|
||||
val unaryConventionName = getUnaryPlusOrMinusOperatorFunctionName(context.call)
|
||||
@@ -97,6 +91,46 @@ class NewResolveOldInference(
|
||||
return convertToOverloadResults(candidates, tracing, context)
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor> runResolveForGivenCandidates(
|
||||
basicCallContext: BasicCallResolutionContext,
|
||||
tracing: TracingStrategy,
|
||||
candidates: Collection<ResolutionCandidate<D>>
|
||||
): OverloadResolutionResultsImpl<D> {
|
||||
val resolvedCandidates = candidates.mapNotNull { candidate ->
|
||||
val candidateTrace = TemporaryBindingTrace.create(basicCallContext.trace, "Context for resolve candidate")
|
||||
val resolvedCall = ResolvedCallImpl.create(candidate, candidateTrace, tracing, basicCallContext.dataFlowInfoForArguments)
|
||||
|
||||
if (candidate.descriptor.isHiddenInResolution()) {
|
||||
return@mapNotNull Candidate(ResolutionCandidateStatus(listOf(HiddenDescriptor)), resolvedCall)
|
||||
}
|
||||
|
||||
val callCandidateResolutionContext = CallCandidateResolutionContext.create(
|
||||
resolvedCall, basicCallContext, candidateTrace, tracing, basicCallContext.call,
|
||||
null, CandidateResolveMode.FULLY // todo
|
||||
)
|
||||
candidateResolver.performResolutionForCandidateCall(callCandidateResolutionContext, basicCallContext.checkArguments) // todo
|
||||
|
||||
val diagnostics = listOfNotNull(SynthesizedDescriptorDiagnostic.check { candidate.descriptor.isSynthesized },
|
||||
createPreviousResolveError(resolvedCall.status))
|
||||
Candidate(ResolutionCandidateStatus(diagnostics), resolvedCall)
|
||||
}
|
||||
if (basicCallContext.collectAllCandidates) {
|
||||
val allCandidates = towerResolver.run(listOf(TowerData.Empty), KnownResultProcessor(resolvedCandidates),
|
||||
TowerResolver.AllCandidatesCollector { it.candidateStatus }, useOrder = false)
|
||||
return allCandidatesResult(allCandidates) as OverloadResolutionResultsImpl<D>
|
||||
}
|
||||
|
||||
val processedCandidates = towerResolver.run(listOf(TowerData.Empty), KnownResultProcessor(resolvedCandidates),
|
||||
TowerResolver.SuccessfulResultCollector { it.candidateStatus }, useOrder = true)
|
||||
|
||||
return convertToOverloadResults(processedCandidates, tracing, basicCallContext) as OverloadResolutionResultsImpl<D>
|
||||
}
|
||||
|
||||
private fun allCandidatesResult(allCandidates: Collection<Candidate>)
|
||||
= OverloadResolutionResultsImpl.nameNotFound<CallableDescriptor>().apply {
|
||||
this.allCandidates = allCandidates.map { it.resolvedCall as MutableResolvedCall<CallableDescriptor> }
|
||||
}
|
||||
|
||||
private fun createResolveProcessor(
|
||||
kind: CallResolver.ResolveKind,
|
||||
explicitReceiver : Receiver?,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -64,18 +64,11 @@ class TowerResolver {
|
||||
internal fun <C> runResolve(
|
||||
context: TowerContext<C>,
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
useOrder: Boolean = true
|
||||
): Collection<C> {
|
||||
return run(context, processor, useOrder, SuccessfulResultCollector(context))
|
||||
}
|
||||
useOrder: Boolean
|
||||
): Collection<C> = run(context.scopeTower.createTowerDataList(), processor, SuccessfulResultCollector { context.getStatus(it) }, useOrder)
|
||||
|
||||
internal fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C> {
|
||||
return run(context, processor, false, AllCandidatesCollector(context))
|
||||
}
|
||||
|
||||
private fun ScopeTower.createLocalLevels() = lexicalScope.parentsWithSelf.
|
||||
filterIsInstance<LexicalScope>().filter { it.kind.withLocalDescriptors }.
|
||||
map { ScopeBasedTowerLevel(this, it) }
|
||||
internal fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C>
|
||||
= run(context.scopeTower.createTowerDataList(), processor, AllCandidatesCollector { context.getStatus(it) }, false)
|
||||
|
||||
private fun ScopeTower.createNonLocalLevels(): List<ScopeTowerLevel> {
|
||||
val result = ArrayList<ScopeTowerLevel>()
|
||||
@@ -160,14 +153,14 @@ class TowerResolver {
|
||||
return result
|
||||
}
|
||||
|
||||
private fun <C> run(
|
||||
context: TowerContext<C>,
|
||||
internal fun <C> run(
|
||||
towerDataList: List<TowerData>,
|
||||
processor: ScopeTowerProcessor<C>,
|
||||
useOrder: Boolean,
|
||||
resultCollector: ResultCollector<C>
|
||||
resultCollector: ResultCollector<C>,
|
||||
useOrder: Boolean
|
||||
): Collection<C> {
|
||||
|
||||
for (towerData in context.scopeTower.createTowerDataList()) {
|
||||
for (towerData in towerDataList) {
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
val candidatesGroups = if (useOrder) {
|
||||
@@ -187,14 +180,14 @@ class TowerResolver {
|
||||
}
|
||||
|
||||
|
||||
internal abstract class ResultCollector<C>(val context: TowerContext<C>) {
|
||||
internal abstract class ResultCollector<C>(protected val getStatus: (C) -> ResolutionCandidateStatus) {
|
||||
abstract fun getSuccessfulCandidates(): Collection<C>?
|
||||
|
||||
abstract fun getFinalCandidates(): Collection<C>
|
||||
|
||||
fun pushCandidates(candidates: Collection<C>) {
|
||||
val filteredCandidates = candidates.filter {
|
||||
context.getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
||||
getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
||||
}
|
||||
if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates)
|
||||
}
|
||||
@@ -202,7 +195,7 @@ class TowerResolver {
|
||||
protected abstract fun addCandidates(candidates: Collection<C>)
|
||||
}
|
||||
|
||||
internal class AllCandidatesCollector<C>(context: TowerContext<C>): ResultCollector<C>(context) {
|
||||
internal class AllCandidatesCollector<C>(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector<C>(getStatus) {
|
||||
private val allCandidates = ArrayList<C>()
|
||||
|
||||
override fun getSuccessfulCandidates(): Collection<C>? = null
|
||||
@@ -212,10 +205,9 @@ class TowerResolver {
|
||||
override fun addCandidates(candidates: Collection<C>) {
|
||||
allCandidates.addAll(candidates)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class SuccessfulResultCollector<C>(context: TowerContext<C>): ResultCollector<C>(context) {
|
||||
internal class SuccessfulResultCollector<C>(getStatus: (C) -> ResolutionCandidateStatus): ResultCollector<C>(getStatus) {
|
||||
private var currentCandidates: Collection<C> = emptyList()
|
||||
private var currentLevel: ResolutionCandidateApplicability? = null
|
||||
|
||||
@@ -234,10 +226,10 @@ class TowerResolver {
|
||||
override fun getFinalCandidates() = getResolved() ?: getResolvedSynthetic() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList()
|
||||
|
||||
override fun addCandidates(candidates: Collection<C>) {
|
||||
val minimalLevel = candidates.map { context.getStatus(it).resultingApplicability }.min()!!
|
||||
val minimalLevel = candidates.map { getStatus(it).resultingApplicability }.min()!!
|
||||
if (currentLevel == null || currentLevel!! > minimalLevel) {
|
||||
currentLevel = minimalLevel
|
||||
currentCandidates = candidates.filter { context.getStatus(it).resultingApplicability == minimalLevel }
|
||||
currentCandidates = candidates.filter { getStatus(it).resultingApplicability == minimalLevel }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,3 +19,5 @@ public class Observable<T> {
|
||||
import j.*
|
||||
|
||||
class K : Observable<String>({})
|
||||
|
||||
class J : Observable<String>(null)
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package
|
||||
|
||||
public final class J : j.Observable<kotlin.String> {
|
||||
public constructor J()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class K : j.Observable<kotlin.String> {
|
||||
public constructor K()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
|
||||
Reference in New Issue
Block a user