Provide LookupLocation when resolve calls

This commit is contained in:
Zalim Bashorov
2015-08-18 20:40:43 +03:00
parent 45e6747061
commit cca57af401
4 changed files with 65 additions and 60 deletions
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.tasks.collectors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorUtils.isStaticNestedClass
@@ -35,13 +35,13 @@ import org.jetbrains.kotlin.utils.singletonOrEmptyList
public interface CallableDescriptorCollector<D : CallableDescriptor> {
public fun getNonExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<D>
public fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<D>
public fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<D>
public fun getMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<D>
public fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<D>
public fun getStaticMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<D>
public fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, bindingTrace: BindingTrace): Collection<D>
public fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, location: LookupLocation, bindingTrace: BindingTrace): Collection<D>
}
private fun <D : CallableDescriptor> CallableDescriptorCollector<D>.withDefaultFilter() = filtered { !LibrarySourceHacks.shouldSkip(it) }
@@ -73,14 +73,14 @@ public fun <D : CallableDescriptor> CallableDescriptorCollectors<D>.filtered(fil
private object FunctionCollector : CallableDescriptorCollector<FunctionDescriptor> {
override fun getNonExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
return scope.getFunctions(name).filter { it.extensionReceiverParameter == null } + getConstructors(scope, name)
override fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
return scope.getFunctions(name, location).filter { it.extensionReceiverParameter == null } + getConstructors(scope, name, location)
}
override fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
override fun getMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
val receiverScope = receiver.memberScope
val members = receiverScope.getFunctions(name)
val constructors = getConstructors(receiverScope, name, { !isStaticNestedClass(it) })
val members = receiverScope.getFunctions(name, location)
val constructors = getConstructors(receiverScope, name, location, { !isStaticNestedClass(it) })
if (name == OperatorConventions.INVOKE && KotlinBuiltIns.isExtensionFunctionType(receiver)) {
// If we're looking for members of an extension function type, we ignore the non-extension "invoke"s
@@ -95,14 +95,14 @@ private object FunctionCollector : CallableDescriptorCollector<FunctionDescripto
return members + constructors
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
return getConstructors(receiver.memberScope, name, { isStaticNestedClass(it) })
override fun getStaticMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
return getConstructors(receiver.memberScope, name, location, { isStaticNestedClass(it) })
}
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
val functions = scope.getFunctions(name)
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, location: LookupLocation, bindingTrace: BindingTrace): Collection<FunctionDescriptor> {
val functions = scope.getFunctions(name, location)
val (extensions, nonExtensions) = functions.partition { it.extensionReceiverParameter != null }
val syntheticExtensions = scope.getSyntheticExtensionFunctions(receiverTypes, name, NoLookupLocation.UNSORTED)
val syntheticExtensions = scope.getSyntheticExtensionFunctions(receiverTypes, name, location)
if (name == OperatorConventions.INVOKE) {
// Create synthesized "invoke" extensions for each non-extension "invoke" found in the scope
@@ -113,9 +113,11 @@ private object FunctionCollector : CallableDescriptorCollector<FunctionDescripto
}
private fun getConstructors(
scope: JetScope, name: Name, filterClassPredicate: (ClassDescriptor) -> Boolean = { true }
scope: JetScope, name: Name,
location: LookupLocation,
filterClassPredicate: (ClassDescriptor) -> Boolean = { true }
): Collection<FunctionDescriptor> {
val classifier = scope.getClassifier(name)
val classifier = scope.getClassifier(name, location)
if (classifier !is ClassDescriptor || ErrorUtils.isError(classifier) || !filterClassPredicate(classifier)
// Constructors of singletons shouldn't be callable from the code
|| classifier.kind.isSingleton) {
@@ -129,39 +131,39 @@ private object FunctionCollector : CallableDescriptorCollector<FunctionDescripto
private object VariableCollector : CallableDescriptorCollector<VariableDescriptor> {
private fun getFakeDescriptorForObject(scope: JetScope, name: Name): VariableDescriptor? {
val classifier = scope.getClassifier(name)
private fun getFakeDescriptorForObject(scope: JetScope, name: Name, location: LookupLocation): VariableDescriptor? {
val classifier = scope.getClassifier(name, location)
if (classifier !is ClassDescriptor || !classifier.hasClassObjectType) return null
return FakeCallableDescriptorForObject(classifier)
}
override fun getNonExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
override fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
val localVariable = scope.getLocalVariable(name)
if (localVariable != null) {
return setOf(localVariable)
}
val properties = scope.getProperties(name).filter { it.extensionReceiverParameter == null }
val fakeDescriptor = getFakeDescriptorForObject(scope, name)
val properties = scope.getProperties(name, location).filter { it.extensionReceiverParameter == null }
val fakeDescriptor = getFakeDescriptorForObject(scope, name, location)
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
}
override fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
override fun getMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
val memberScope = receiver.memberScope
val properties = memberScope.getProperties(name)
val fakeDescriptor = getFakeDescriptorForObject(memberScope, name)
val properties = memberScope.getProperties(name, location)
val fakeDescriptor = getFakeDescriptorForObject(memberScope, name, location)
return if (fakeDescriptor != null) properties + fakeDescriptor else properties
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
override fun getStaticMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return listOf()
}
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
// property may have an extension function type, we check the applicability later to avoid an early computing of deferred types
return scope.getLocalVariable(name).singletonOrEmptyList() +
scope.getProperties(name) +
scope.getSyntheticExtensionProperties(receiverTypes, name, NoLookupLocation.UNSORTED)
scope.getProperties(name, location) +
scope.getSyntheticExtensionProperties(receiverTypes, name, location)
}
override fun toString() = "VARIABLES"
@@ -171,20 +173,20 @@ private object PropertyCollector : CallableDescriptorCollector<VariableDescripto
private fun filterProperties(variableDescriptors: Collection<VariableDescriptor>) =
variableDescriptors.filter { it is PropertyDescriptor }
override fun getNonExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getNonExtensionsByName(scope, name, bindingTrace))
override fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getNonExtensionsByName(scope, name, location, bindingTrace))
}
override fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getMembersByName(receiver, name, bindingTrace))
override fun getMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getMembersByName(receiver, name, location, bindingTrace))
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getStaticMembersByName(receiver, name, bindingTrace))
override fun getStaticMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getStaticMembersByName(receiver, name, location, bindingTrace))
}
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getExtensionsByName(scope, name, receiverTypes, bindingTrace))
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, location: LookupLocation, bindingTrace: BindingTrace): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getExtensionsByName(scope, name, receiverTypes, location, bindingTrace))
}
override fun toString() = "PROPERTIES"
@@ -193,20 +195,20 @@ private object PropertyCollector : CallableDescriptorCollector<VariableDescripto
private fun <D : CallableDescriptor> CallableDescriptorCollector<D>.filtered(filter: (D) -> Boolean): CallableDescriptorCollector<D> {
val delegate = this
return object : CallableDescriptorCollector<D> {
override fun getNonExtensionsByName(scope: JetScope, name: Name, bindingTrace: BindingTrace): Collection<D> {
return delegate.getNonExtensionsByName(scope, name, bindingTrace).filter(filter)
override fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<D> {
return delegate.getNonExtensionsByName(scope, name, location, bindingTrace).filter(filter)
}
override fun getMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<D> {
return delegate.getMembersByName(receiver, name, bindingTrace).filter(filter)
override fun getMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<D> {
return delegate.getMembersByName(receiver, name, location, bindingTrace).filter(filter)
}
override fun getStaticMembersByName(receiver: JetType, name: Name, bindingTrace: BindingTrace): Collection<D> {
return delegate.getStaticMembersByName(receiver, name, bindingTrace).filter(filter)
override fun getStaticMembersByName(receiver: JetType, name: Name, location: LookupLocation, bindingTrace: BindingTrace): Collection<D> {
return delegate.getStaticMembersByName(receiver, name, location, bindingTrace).filter(filter)
}
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, bindingTrace: BindingTrace): Collection<D> {
return delegate.getExtensionsByName(scope, name, receiverTypes, bindingTrace).filter(filter)
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, location: LookupLocation, bindingTrace: BindingTrace): Collection<D> {
return delegate.getExtensionsByName(scope, name, receiverTypes, location, bindingTrace).filter(filter)
}
override fun toString(): String {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.tasks
import com.google.common.collect.Lists
import com.google.common.collect.Sets
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.Call
@@ -178,7 +179,7 @@ public class TaskPrioritizer(
convertWithImpliedThis(
c.scope,
explicitReceiver.value,
callableDescriptorCollector.getExtensionsByName(c.scope, c.name, explicitReceiver.types, c.context.trace),
callableDescriptorCollector.getExtensionsByName(c.scope, c.name, explicitReceiver.types, createLookupLocation(c), c.context.trace),
createKind(EXTENSION_RECEIVER, isExplicit),
c.context.call
)
@@ -197,10 +198,10 @@ public class TaskPrioritizer(
val members = Lists.newArrayList<ResolutionCandidate<D>>()
for (type in explicitReceiver.types) {
val membersForThisVariant = if (staticMembers) {
callableDescriptorCollector.getStaticMembersByName(type, c.name, c.context.trace)
callableDescriptorCollector.getStaticMembersByName(type, c.name, createLookupLocation(c), c.context.trace)
}
else {
callableDescriptorCollector.getMembersByName(type, c.name, c.context.trace)
callableDescriptorCollector.getMembersByName(type, c.name, createLookupLocation(c), c.context.trace)
}
convertWithReceivers(
membersForThisVariant,
@@ -229,7 +230,7 @@ public class TaskPrioritizer(
val dynamicScope = DynamicCallableDescriptors.createDynamicDescriptorScope(c.context.call, c.scope.getContainingDeclaration())
val dynamicDescriptors = c.callableDescriptorCollectors.flatMap {
it.getNonExtensionsByName(dynamicScope, c.name, c.context.trace)
it.getNonExtensionsByName(dynamicScope, c.name, createLookupLocation(c), c.context.trace)
}
convertWithReceivers(dynamicDescriptors, explicitReceiver.value, NO_RECEIVER, createKind(DISPATCH_RECEIVER, isExplicit), c.context.call)
@@ -250,7 +251,7 @@ public class TaskPrioritizer(
) {
c.result.addCandidates {
val memberExtensions =
callableDescriptorCollector.getExtensionsByName(dispatchReceiver.type.memberScope, c.name, receiverParameter.types, c.context.trace)
callableDescriptorCollector.getExtensionsByName(dispatchReceiver.type.memberScope, c.name, receiverParameter.types, createLookupLocation(c), c.context.trace)
convertWithReceivers(memberExtensions, dispatchReceiver, receiverParameter.value, receiverKind, c.context.call)
}
}
@@ -265,7 +266,7 @@ public class TaskPrioritizer(
val members = convertWithImpliedThisAndNoReceiver(
c.scope,
callableDescriptorCollector.getNonExtensionsByName(c.scope, c.name, c.context.trace),
callableDescriptorCollector.getNonExtensionsByName(c.scope, c.name, createLookupLocation(c), c.context.trace),
c.context.call
)
@@ -298,6 +299,8 @@ public class TaskPrioritizer(
}
}
private fun createLookupLocation(c: TaskPrioritizerContext<*, *>) = KotlinLookupLocation(c.context.call.callElement)
private fun <D : CallableDescriptor, F : D> addCandidatesForInvoke(explicitReceiver: ReceiverWithTypes, c: TaskPrioritizerContext<D, F>) {
val implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope)
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.tasks
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -29,7 +30,6 @@ import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCol
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.JetScopeImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
import org.jetbrains.kotlin.types.DynamicType
import org.jetbrains.kotlin.types.JetType
@@ -224,8 +224,8 @@ public fun DeclarationDescriptor.isDynamic(): Boolean {
}
class CollectorForDynamicReceivers<D: CallableDescriptor>(val delegate: CallableDescriptorCollector<D>) : CallableDescriptorCollector<D> by delegate {
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, bindingTrace: BindingTrace): Collection<D> {
return delegate.getExtensionsByName(scope, name, receiverTypes, bindingTrace).filter {
override fun getExtensionsByName(scope: JetScope, name: Name, receiverTypes: Collection<JetType>, location: LookupLocation, bindingTrace: BindingTrace): Collection<D> {
return delegate.getExtensionsByName(scope, name, receiverTypes, location, bindingTrace).filter {
it.getExtensionReceiverParameter()?.getType()?.isDynamic() ?: false
}
}
@@ -3,15 +3,15 @@ package foo
import bar.*
import baz./*p:baz*/C
/*p:foo*/val a = /**p:foo p:bar*/A()
/*p:foo*/var b: /*p:foo p:bar*/baz./*p:baz*/B = /**p:foo p:bar*/baz./**p:baz*/B()
/*p:foo*/val a = /*p:foo p:bar*/A()
/*p:foo*/var b: /*p:foo p:bar*/baz./*p:baz*/B = /*p:foo p:bar*/baz./*p:baz*/B()
/*p:foo*/fun function(p: /*p:foo p:bar*/B): /*p:foo p:bar*/B {
/**p:foo*/a
return /**p:foo p:bar*/B()
/*p:foo p:bar*/a
return /*p:foo p:bar*/B()
}
/*p:foo*/fun /*p:foo*/MyClass.extFunc(p: /**p:foo p:bar*//*p:foo*/Array</*p:foo p:bar*/B>, e: /*p:foo*/MyEnum, c: /**???*/C): /*p:foo*/MyInterface {
/**p:foo*/b
return /**p:foo*/MyClass()
/*p:foo p:bar c:foo.MyClass*/b
return /*p:foo p:bar c:foo.MyClass*/MyClass()
}