Added static methods, nested classes and companion object from superclasses.

This commit is contained in:
Stanislav Erokhin
2015-10-01 21:00:44 +03:00
parent ace99f6c3f
commit d5dbc9638d
53 changed files with 2657 additions and 19 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.descriptorUtil.hasClassObjectType
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.LexicalChainedScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
import org.jetbrains.kotlin.resolve.scopes.utils.getLocalVariable
@@ -41,6 +42,9 @@ public interface CallableDescriptorCollector<D : CallableDescriptor> {
public fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation): Collection<D>
// todo this is hack for static members priority
public fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<D>
public fun getMembersByName(receiver: JetType, name: Name, location: LookupLocation): Collection<D>
public fun getStaticMembersByName(receiver: JetType, name: Name, location: LookupLocation): Collection<D>
@@ -76,6 +80,17 @@ public fun <D : CallableDescriptor> CallableDescriptorCollectors<D>.filtered(fil
CallableDescriptorCollectors(this.collectors.map { it.filtered(filter) })
private object FunctionCollector : CallableDescriptorCollector<FunctionDescriptor> {
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
return lexicalScope.collectAllFromMeAndParent {
if (it is LexicalChainedScope && it.isStaticScope) {
it.getDeclaredFunctions(name, location).filter { it.extensionReceiverParameter == null }
}
else {
emptyList()
}
}
}
override fun getLocalNonExtensionsByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
return lexicalScope.collectAllFromMeAndParent {
if (it.ownerDescriptor is FunctionDescriptor) {
@@ -156,6 +171,17 @@ private object VariableCollector : CallableDescriptorCollector<VariableDescripto
return listOfNotNull(lexicalScope.getLocalVariable(name))
}
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
return lexicalScope.collectAllFromMeAndParent {
if (it is LexicalChainedScope && it.isStaticScope) {
it.getDeclaredVariables(name, location)
}
else {
emptyList()
}
}
}
private fun getFakeDescriptorForObject(scope: JetScope, name: Name, location: LookupLocation): VariableDescriptor? {
val classifier = scope.getClassifier(name, location)
if (classifier !is ClassDescriptor || !classifier.hasClassObjectType) return null
@@ -202,6 +228,10 @@ private object PropertyCollector : CallableDescriptorCollector<VariableDescripto
return filterProperties(VARIABLES_COLLECTOR.getLocalNonExtensionsByName(lexicalScope, name, location))
}
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getStaticInheritanceByName(lexicalScope, name, location))
}
override fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation): Collection<VariableDescriptor> {
return filterProperties(VARIABLES_COLLECTOR.getNonExtensionsByName(scope, name, location))
}
@@ -228,6 +258,10 @@ private fun <D : CallableDescriptor> CallableDescriptorCollector<D>.filtered(fil
return delegate.getLocalNonExtensionsByName(lexicalScope, name, location).filter(filter)
}
override fun getStaticInheritanceByName(lexicalScope: LexicalScope, name: Name, location: LookupLocation): Collection<D> {
return delegate.getStaticInheritanceByName(lexicalScope, name, location)
}
override fun getNonExtensionsByName(scope: JetScope, name: Name, location: LookupLocation): Collection<D> {
return delegate.getNonExtensionsByName(scope, name, location).filter(filter)
}
@@ -314,6 +314,14 @@ public class TaskPrioritizer(
addCandidatesForExplicitReceiver(implicitReceiver, implicitReceivers, c, isExplicit = false)
}
// static members hack
c.callableDescriptorCollectors.forEach {
c.result.addCandidates {
val descriptors = it.getStaticInheritanceByName(c.scope, c.name, lookupLocation)
convertWithImpliedThisAndNoReceiver(c.scope, descriptors, c.context.call)
}
}
//nonlocals
c.callableDescriptorCollectors.forEach {
c.result.addCandidates {
@@ -16,12 +16,18 @@
package org.jetbrains.kotlin.resolve.lazy.descriptors
import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.JetParameter
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.LexicalChainedScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
class ClassResolutionScopesSupport(
private val classDescriptor: ClassDescriptor,
@@ -39,23 +45,22 @@ class ClassResolutionScopesSupport(
scopeWithGenerics(getOuterScope(), "Scope for class header resolution for ${classDescriptor.name}")
}
private val scopeWithStaticMembersAndCompanionObjectReceiver = storageManager.createLazyValue {
val staticScopes = classDescriptor.companionObjectDescriptor?.let {
arrayOf(classDescriptor.staticScope, it.unsubstitutedInnerClassesScope)
} ?: arrayOf(classDescriptor.staticScope)
private val inheritanceScope: () -> LexicalScope = storageManager.createLazyValueWithPostCompute(
{
classDescriptor.getAllSuperclassesAndMeWithoutAny().asReversed().fold(getOuterScope()) { scope, currentClass ->
createInheritanceScope(parent = scope, ownerDescriptor = classDescriptor, classDescriptor = currentClass)
}
},
{ createInheritanceScope(getOuterScope(), classDescriptor, classDescriptor) },
{}
)
LexicalChainedScope(getOuterScope(), classDescriptor, false,
classDescriptor.companionObjectDescriptor?.thisAsReceiverParameter,
"Scope with static members and companion object for ${classDescriptor.name}",
memberScopes = *staticScopes)
}
public val scopeForMemberDeclarationResolution: () -> LexicalScope = storageManager.createLazyValue {
val scopeWithGenerics = scopeWithGenerics(scopeWithStaticMembersAndCompanionObjectReceiver(),
val scopeWithGenerics = scopeWithGenerics(inheritanceScope(),
"Scope with generics for ${classDescriptor.name}")
LexicalChainedScope(scopeWithGenerics, classDescriptor, true, classDescriptor.thisAsReceiverParameter,
"Scope for member declaration resolution: ${classDescriptor.name}",
classDescriptor.unsubstitutedInnerClassesScope)
LexicalScopeImpl(scopeWithGenerics, classDescriptor, true, classDescriptor.thisAsReceiverParameter,
"Scope for member declaration resolution: ${classDescriptor.name}")
}
public val scopeForStaticMemberDeclarationResolution: () -> LexicalScope = storageManager.createLazyValue {
@@ -63,9 +68,8 @@ class ClassResolutionScopesSupport(
scopeForMemberDeclarationResolution()
}
else {
LexicalChainedScope(scopeWithStaticMembersAndCompanionObjectReceiver(), classDescriptor, false, null,
"Scope for static member declaration resolution: ${classDescriptor.name}",
classDescriptor.unsubstitutedInnerClassesScope)
LexicalScopeImpl(inheritanceScope(), classDescriptor, false, null,
"Scope for static member declaration resolution: ${classDescriptor.name}")
}
}
@@ -86,4 +90,36 @@ class ClassResolutionScopesSupport(
}
}
public fun ClassDescriptor.getAllSuperclassesAndMeWithoutAny(): List<ClassDescriptor> {
val superClassesAndMe = SmartList<ClassDescriptor>()
var parent: ClassDescriptor? = this
do {
superClassesAndMe.add(parent)
parent = parent!!.getSuperClassNotAny()
}
while(parent != null && parent != this) // possible recursion in inheritance
return superClassesAndMe
}
private fun createInheritanceScope(
parent: LexicalScope,
ownerDescriptor: DeclarationDescriptor,
classDescriptor: ClassDescriptor
): LexicalScope {
val staticScopes = ArrayList<JetScope>(3)
// todo filter fake overrides
staticScopes.add(classDescriptor.staticScope)
staticScopes.add(classDescriptor.unsubstitutedInnerClassesScope)
staticScopes.addIfNotNull(classDescriptor.companionObjectDescriptor?.unsubstitutedInnerClassesScope)
return LexicalChainedScope(parent, ownerDescriptor, false,
classDescriptor.companionObjectDescriptor?.thisAsReceiverParameter,
"Scope with static members, nested classes and companion object for ${classDescriptor.name}",
memberScopes = *staticScopes.toTypedArray(), isStaticScope = true)
}
}
@@ -31,7 +31,9 @@ public class LexicalChainedScope(
override val isOwnerDescriptorAccessibleByLabel: Boolean,
override val implicitReceiver: ReceiverParameterDescriptor?,
private val debugName: String,
vararg memberScopes: JetScope // todo JetScope -> MemberScope
vararg memberScopes: JetScope, // todo JetScope -> MemberScope
@Deprecated("This value is temporary hack for resolve -- don't use it!")
val isStaticScope: Boolean = false
): LexicalScope {
override val parent = parent.takeSnapshot()
private val scopeChain = memberScopes.clone()