Extract superclass from FunctionClassScope and CloneableClassScope

This commit is contained in:
Alexander Udalov
2016-10-25 14:58:10 +03:00
parent 416569c2d2
commit 2b34d62848
3 changed files with 110 additions and 126 deletions
@@ -20,69 +20,23 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.resolve.scopes.GivenFunctionsMemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.utils.Printer
import java.util.*
class CloneableClassScope(storageManager: StorageManager, private val classDescriptor: ClassDescriptor) : MemberScopeImpl() {
private val allDescriptors by storageManager.createLazyValue {
val cloneFunction =
SimpleFunctionDescriptorImpl.create(classDescriptor, Annotations.EMPTY, CLONE_NAME, DECLARATION, SourceElement.NO_SOURCE)
cloneFunction.initialize(null, classDescriptor.thisAsReceiverParameter, emptyList(), emptyList(), classDescriptor.builtIns.anyType,
Modality.OPEN, Visibilities.PROTECTED)
listOf(cloneFunction) + createFakeOverrides()
}
private val functionNames = setOf(CLONE_NAME) + classDescriptor.builtIns.anyType.memberScope.getFunctionNames()
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> =
if (name in functionNames) allDescriptors.filter { it.name == name } else emptySet()
override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> = allDescriptors
override fun getFunctionNames(): Set<Name> = functionNames
private fun createFakeOverrides(): List<SimpleFunctionDescriptor> {
val result = ArrayList<SimpleFunctionDescriptor>(3)
val allSuperDescriptors = classDescriptor.typeConstructor.supertypes
.flatMap { it.memberScope.getContributedDescriptors() }
.filterIsInstance<SimpleFunctionDescriptor>()
for ((name, descriptors) in allSuperDescriptors.groupBy { it.name }) {
OverridingUtil.generateOverridesInFunctionGroup(
name,
/* membersFromSupertypes = */ descriptors,
/* membersFromCurrent = */ emptyList(),
classDescriptor,
object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)
result.add(fakeOverride as SimpleFunctionDescriptor)
}
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
error("Conflict in scope of $classDescriptor: $fromSuper vs $fromCurrent")
}
}
)
}
return result
}
override fun printScopeStructure(p: Printer) {
p.println("kotlin.Cloneable member scope")
}
class CloneableClassScope(
storageManager: StorageManager,
containingClass: ClassDescriptor
) : GivenFunctionsMemberScope(storageManager, containingClass) {
override fun computeDeclaredFunctions(): List<FunctionDescriptor> = listOf(
SimpleFunctionDescriptorImpl.create(containingClass, Annotations.EMPTY, CLONE_NAME, DECLARATION, SourceElement.NO_SOURCE).apply {
initialize(
null, containingClass.thisAsReceiverParameter, emptyList(), emptyList(), containingClass.builtIns.anyType,
Modality.OPEN, Visibilities.PROTECTED
)
}
)
companion object {
internal val CLONE_NAME = Name.identifier("clone")
@@ -16,76 +16,17 @@
package org.jetbrains.kotlin.builtins.functions
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverridingStrategy
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.scopes.GivenFunctionsMemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.toReadOnlyList
import java.util.ArrayList
class FunctionClassScope(
storageManager: StorageManager,
private val functionClass: FunctionClassDescriptor
) : MemberScopeImpl() {
private val allDescriptors = storageManager.createLazyValue {
if (functionClass.functionKind == FunctionClassDescriptor.Kind.Function) {
val invoke = FunctionInvokeDescriptor.create(functionClass)
(listOf(invoke) + createFakeOverrides(invoke)).toReadOnlyList()
}
else {
createFakeOverrides(null).toReadOnlyList()
}
}
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
if (!kindFilter.acceptsKinds(DescriptorKindFilter.CALLABLES.kindMask)) return listOf()
return allDescriptors()
}
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
return allDescriptors().filterIsInstance<SimpleFunctionDescriptor>().filter { it.name == name }
}
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
return allDescriptors().filterIsInstance<PropertyDescriptor>().filter { it.name == name }
}
private fun createFakeOverrides(invoke: FunctionDescriptor?): List<DeclarationDescriptor> {
val result = ArrayList<DeclarationDescriptor>(3)
val allSuperDescriptors = functionClass.typeConstructor.supertypes
.flatMap { it.memberScope.getContributedDescriptors() }
.filterIsInstance<CallableMemberDescriptor>()
for ((name, group) in allSuperDescriptors.groupBy { it.name }) {
for ((isFunction, descriptors) in group.groupBy { it is FunctionDescriptor }) {
OverridingUtil.generateOverridesInFunctionGroup(
name,
/* membersFromSupertypes = */ descriptors,
/* membersFromCurrent = */ if (isFunction && name == invoke?.name) listOf(invoke) else listOf(),
functionClass,
object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)
result.add(fakeOverride)
}
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
error("Conflict in scope of $functionClass: $fromSuper vs $fromCurrent")
}
}
)
containingClass: FunctionClassDescriptor
) : GivenFunctionsMemberScope(storageManager, containingClass) {
override fun computeDeclaredFunctions(): List<FunctionDescriptor> =
if ((containingClass as FunctionClassDescriptor).functionKind == FunctionClassDescriptor.Kind.Function) {
listOf(FunctionInvokeDescriptor.create(containingClass))
}
}
return result
}
override fun printScopeStructure(p: Printer) {
p.println("Scope of function class $functionClass")
}
else emptyList()
}
@@ -0,0 +1,89 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve.scopes
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.compactIfPossible
import java.util.*
/**
* A scope that may contain some declared functions + fake-overridden functions/properties from supertypes.
*/
abstract class GivenFunctionsMemberScope(
storageManager: StorageManager,
protected val containingClass: ClassDescriptor
) : MemberScopeImpl() {
private val allDescriptors by storageManager.createLazyValue {
val fromCurrent = computeDeclaredFunctions()
fromCurrent + createFakeOverrides(fromCurrent)
}
protected abstract fun computeDeclaredFunctions(): List<FunctionDescriptor>
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
if (!kindFilter.acceptsKinds(DescriptorKindFilter.CALLABLES.kindMask)) return listOf()
return allDescriptors
}
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
return allDescriptors.filterIsInstance<SimpleFunctionDescriptor>().filter { it.name == name }
}
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> {
return allDescriptors.filterIsInstance<PropertyDescriptor>().filter { it.name == name }
}
private fun createFakeOverrides(functionsFromCurrent: List<FunctionDescriptor>): List<DeclarationDescriptor> {
val result = ArrayList<DeclarationDescriptor>(3)
val allSuperDescriptors = containingClass.typeConstructor.supertypes
.flatMap { it.memberScope.getContributedDescriptors() }
.filterIsInstance<CallableMemberDescriptor>()
for ((name, group) in allSuperDescriptors.groupBy { it.name }) {
for ((isFunction, descriptors) in group.groupBy { it is FunctionDescriptor }) {
OverridingUtil.generateOverridesInFunctionGroup(
name,
/* membersFromSupertypes = */ descriptors,
/* membersFromCurrent = */ if (isFunction) functionsFromCurrent.filter { it.name == name } else listOf(),
containingClass,
object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)
result.add(fakeOverride)
}
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
error("Conflict in scope of $containingClass: $fromSuper vs $fromCurrent")
}
}
)
}
}
return result.compactIfPossible()
}
override fun printScopeStructure(p: Printer) {
p.println("Scope of class: $containingClass")
}
}