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;
|
assert contextForMigration.name != null;
|
||||||
return (OverloadResolutionResultsImpl<F>)
|
return (OverloadResolutionResultsImpl<F>)
|
||||||
newCallResolver.runResolve(context, contextForMigration.name, contextForMigration.resolveKind, tracing);
|
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
|
@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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.model.VariableAsFunctionResolvedCallImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionResultsHandler
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors
|
import org.jetbrains.kotlin.resolve.calls.tasks.*
|
||||||
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.isHiddenInResolution
|
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
||||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||||
@@ -77,10 +74,7 @@ class NewResolveOldInference(
|
|||||||
var processor = createResolveProcessor(kind, explicitReceiver, context, baseContext)
|
var processor = createResolveProcessor(kind, explicitReceiver, context, baseContext)
|
||||||
|
|
||||||
if (context.collectAllCandidates) {
|
if (context.collectAllCandidates) {
|
||||||
val allCandidates = towerResolver.collectAllCandidates(baseContext, processor)
|
return allCandidatesResult(towerResolver.collectAllCandidates(baseContext, processor))
|
||||||
val result = OverloadResolutionResultsImpl.nameNotFound<CallableDescriptor>()
|
|
||||||
result.allCandidates = allCandidates.map { it.resolvedCall as MutableResolvedCall<CallableDescriptor> }
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
// Temporary fix for code migration (unaryPlus()/unaryMinus())
|
// Temporary fix for code migration (unaryPlus()/unaryMinus())
|
||||||
val unaryConventionName = getUnaryPlusOrMinusOperatorFunctionName(context.call)
|
val unaryConventionName = getUnaryPlusOrMinusOperatorFunctionName(context.call)
|
||||||
@@ -97,6 +91,46 @@ class NewResolveOldInference(
|
|||||||
return convertToOverloadResults(candidates, tracing, context)
|
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(
|
private fun createResolveProcessor(
|
||||||
kind: CallResolver.ResolveKind,
|
kind: CallResolver.ResolveKind,
|
||||||
explicitReceiver : Receiver?,
|
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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -64,18 +64,11 @@ class TowerResolver {
|
|||||||
internal fun <C> runResolve(
|
internal fun <C> runResolve(
|
||||||
context: TowerContext<C>,
|
context: TowerContext<C>,
|
||||||
processor: ScopeTowerProcessor<C>,
|
processor: ScopeTowerProcessor<C>,
|
||||||
useOrder: Boolean = true
|
useOrder: Boolean
|
||||||
): Collection<C> {
|
): Collection<C> = run(context.scopeTower.createTowerDataList(), processor, SuccessfulResultCollector { context.getStatus(it) }, useOrder)
|
||||||
return run(context, processor, useOrder, SuccessfulResultCollector(context))
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C> {
|
internal fun <C> collectAllCandidates(context: TowerContext<C>, processor: ScopeTowerProcessor<C>): Collection<C>
|
||||||
return run(context, processor, false, AllCandidatesCollector(context))
|
= run(context.scopeTower.createTowerDataList(), processor, AllCandidatesCollector { context.getStatus(it) }, false)
|
||||||
}
|
|
||||||
|
|
||||||
private fun ScopeTower.createLocalLevels() = lexicalScope.parentsWithSelf.
|
|
||||||
filterIsInstance<LexicalScope>().filter { it.kind.withLocalDescriptors }.
|
|
||||||
map { ScopeBasedTowerLevel(this, it) }
|
|
||||||
|
|
||||||
private fun ScopeTower.createNonLocalLevels(): List<ScopeTowerLevel> {
|
private fun ScopeTower.createNonLocalLevels(): List<ScopeTowerLevel> {
|
||||||
val result = ArrayList<ScopeTowerLevel>()
|
val result = ArrayList<ScopeTowerLevel>()
|
||||||
@@ -160,14 +153,14 @@ class TowerResolver {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <C> run(
|
internal fun <C> run(
|
||||||
context: TowerContext<C>,
|
towerDataList: List<TowerData>,
|
||||||
processor: ScopeTowerProcessor<C>,
|
processor: ScopeTowerProcessor<C>,
|
||||||
useOrder: Boolean,
|
resultCollector: ResultCollector<C>,
|
||||||
resultCollector: ResultCollector<C>
|
useOrder: Boolean
|
||||||
): Collection<C> {
|
): Collection<C> {
|
||||||
|
|
||||||
for (towerData in context.scopeTower.createTowerDataList()) {
|
for (towerData in towerDataList) {
|
||||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||||
|
|
||||||
val candidatesGroups = if (useOrder) {
|
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 getSuccessfulCandidates(): Collection<C>?
|
||||||
|
|
||||||
abstract fun getFinalCandidates(): Collection<C>
|
abstract fun getFinalCandidates(): Collection<C>
|
||||||
|
|
||||||
fun pushCandidates(candidates: Collection<C>) {
|
fun pushCandidates(candidates: Collection<C>) {
|
||||||
val filteredCandidates = candidates.filter {
|
val filteredCandidates = candidates.filter {
|
||||||
context.getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
getStatus(it).resultingApplicability != ResolutionCandidateApplicability.HIDDEN
|
||||||
}
|
}
|
||||||
if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates)
|
if (filteredCandidates.isNotEmpty()) addCandidates(filteredCandidates)
|
||||||
}
|
}
|
||||||
@@ -202,7 +195,7 @@ class TowerResolver {
|
|||||||
protected abstract fun addCandidates(candidates: Collection<C>)
|
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>()
|
private val allCandidates = ArrayList<C>()
|
||||||
|
|
||||||
override fun getSuccessfulCandidates(): Collection<C>? = null
|
override fun getSuccessfulCandidates(): Collection<C>? = null
|
||||||
@@ -212,10 +205,9 @@ class TowerResolver {
|
|||||||
override fun addCandidates(candidates: Collection<C>) {
|
override fun addCandidates(candidates: Collection<C>) {
|
||||||
allCandidates.addAll(candidates)
|
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 currentCandidates: Collection<C> = emptyList()
|
||||||
private var currentLevel: ResolutionCandidateApplicability? = null
|
private var currentLevel: ResolutionCandidateApplicability? = null
|
||||||
|
|
||||||
@@ -234,10 +226,10 @@ class TowerResolver {
|
|||||||
override fun getFinalCandidates() = getResolved() ?: getResolvedSynthetic() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList()
|
override fun getFinalCandidates() = getResolved() ?: getResolvedSynthetic() ?: getResolvedLowPriority() ?: getErrors() ?: emptyList()
|
||||||
|
|
||||||
override fun addCandidates(candidates: Collection<C>) {
|
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) {
|
if (currentLevel == null || currentLevel!! > minimalLevel) {
|
||||||
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.*
|
import j.*
|
||||||
|
|
||||||
class K : Observable<String>({})
|
class K : Observable<String>({})
|
||||||
|
|
||||||
|
class J : Observable<String>(null)
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
package
|
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 final class K : j.Observable<kotlin.String> {
|
||||||
public constructor K()
|
public constructor K()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
|||||||
Reference in New Issue
Block a user