Use a specialized scope in EnumClassObjectDescriptor

Instead of WritableScopeImpl
This commit is contained in:
Alexander Udalov
2014-07-06 16:29:05 +04:00
parent 6e5339ad3c
commit bf45a3590b
@@ -22,18 +22,19 @@ import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.SYNTHESI
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.resolve.name.SpecialNames
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler
import org.jetbrains.jet.lang.resolve.DescriptorUtils
import org.jetbrains.jet.lang.resolve.DescriptorFactory
import org.jetbrains.jet.lang.types.TypeConstructor
import org.jetbrains.jet.lang.types.TypeConstructorImpl
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
import org.jetbrains.jet.lang.resolve.OverridingUtil
import org.jetbrains.jet.lang.resolve.scopes.WritableScope.LockLevel
import org.jetbrains.jet.lang.types.DelegatingType
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl
import org.jetbrains.jet.utils.Printer
import java.util.ArrayList
import kotlin.properties.Delegates
public class EnumClassObjectDescriptor(
storageManager: StorageManager,
@@ -50,51 +51,7 @@ public class EnumClassObjectDescriptor(
private val _typeConstructor = TypeConstructorImpl.createForClass(this, getAnnotations(), true, getName().asString(),
listOf(), listOf(KotlinBuiltIns.getInstance().getAnyType()))
private val scope = WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "MemberLookup")
;{
val enumType = object : DelegatingType() {
override fun getDelegate() = (getContainingDeclaration() as ClassDescriptor).getDefaultType()
}
scope.addFunctionDescriptor(createEnumClassObjectValuesMethod(enumType))
scope.addFunctionDescriptor(createEnumClassObjectValueOfMethod(enumType))
val sink = object : OverridingUtil.DescriptorSink {
override fun addToScope(fakeOverride: CallableMemberDescriptor) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)
scope.addFunctionDescriptor(fakeOverride as SimpleFunctionDescriptor)
}
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
throw IllegalStateException("Conflict on enum class object override: $fromSuper vs $fromCurrent")
}
}
val superScope = KotlinBuiltIns.getInstance().getAnyType().getMemberScope()
for (descriptor in superScope.getAllDescriptors()) {
if (descriptor is FunctionDescriptor) {
val name = descriptor.getName()
OverridingUtil.generateOverridesInFunctionGroup(name, superScope.getFunctions(name), setOf(), this, sink)
}
}
scope.changeLockLevel(LockLevel.READING)
}
private fun createEnumClassObjectValuesMethod(enumType: JetType): SimpleFunctionDescriptor {
val enumArrayType = KotlinBuiltIns.getInstance().getArrayType(enumType)
val values = SimpleFunctionDescriptorImpl.create(this, Annotations.EMPTY, Name.identifier("values"), SYNTHESIZED)
return values.initialize(null, getThisAsReceiverParameter(), listOf(), listOf(), enumArrayType, Modality.FINAL, Visibilities.PUBLIC)
}
private fun createEnumClassObjectValueOfMethod(enumType: JetType): SimpleFunctionDescriptor {
val values = SimpleFunctionDescriptorImpl.create(this, Annotations.EMPTY, Name.identifier("valueOf"), SYNTHESIZED)
val parameter = ValueParameterDescriptorImpl(values, null, 0, Annotations.EMPTY, Name.identifier("value"),
KotlinBuiltIns.getInstance().getStringType(), false, null)
return values.initialize(null, getThisAsReceiverParameter(), listOf(), listOf(parameter), enumType, Modality.FINAL, Visibilities.PUBLIC)
}
private val scope = EnumClassObjectScope()
override fun getScopeForMemberLookup(): JetScope = scope
@@ -115,4 +72,65 @@ public class EnumClassObjectDescriptor(
override fun isInner(): Boolean = false
override fun getAnnotations(): Annotations = Annotations.EMPTY
private inner class EnumClassObjectScope : JetScopeImpl() {
private val enumClassObject: EnumClassObjectDescriptor
get() = this@EnumClassObjectDescriptor
private val functions: List<FunctionDescriptor> by Delegates.lazy {
val result = ArrayList<FunctionDescriptor>(5)
val enumType = object : DelegatingType() {
override fun getDelegate() = (enumClassObject.getContainingDeclaration() as ClassDescriptor).getDefaultType()
}
result.add(createEnumClassObjectValuesMethod(enumType))
result.add(createEnumClassObjectValueOfMethod(enumType))
val sink = object : OverridingUtil.DescriptorSink {
override fun addToScope(fakeOverride: CallableMemberDescriptor) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)
result.add(fakeOverride as FunctionDescriptor)
}
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
throw IllegalStateException("Conflict on enum class object override: $fromSuper vs $fromCurrent")
}
}
val superScope = KotlinBuiltIns.getInstance().getAnyType().getMemberScope()
for (descriptor in superScope.getAllDescriptors()) {
if (descriptor is FunctionDescriptor) {
val name = descriptor.getName()
OverridingUtil.generateOverridesInFunctionGroup(name, superScope.getFunctions(name), setOf(), enumClassObject, sink)
}
}
result
}
private fun createEnumClassObjectValuesMethod(enumType: JetType): SimpleFunctionDescriptor {
val enumArrayType = KotlinBuiltIns.getInstance().getArrayType(enumType)
val values = SimpleFunctionDescriptorImpl.create(enumClassObject, Annotations.EMPTY, Name.identifier("values"), SYNTHESIZED)
return values.initialize(null, getThisAsReceiverParameter(), listOf(), listOf(), enumArrayType, Modality.FINAL, Visibilities.PUBLIC)
}
private fun createEnumClassObjectValueOfMethod(enumType: JetType): SimpleFunctionDescriptor {
val values = SimpleFunctionDescriptorImpl.create(enumClassObject, Annotations.EMPTY, Name.identifier("valueOf"), SYNTHESIZED)
val parameter = ValueParameterDescriptorImpl(values, null, 0, Annotations.EMPTY, Name.identifier("value"),
KotlinBuiltIns.getInstance().getStringType(), false, null)
return values.initialize(null, getThisAsReceiverParameter(), listOf(), listOf(parameter), enumType, Modality.FINAL, Visibilities.PUBLIC)
}
override fun getFunctions(name: Name) = functions.filter { it.getName() == name }
override fun getAllDescriptors() = functions
override fun printScopeStructure(p: Printer) {
p.println("enum class object scope for $enumClassObject")
}
override fun getContainingDeclaration(): ClassDescriptor = enumClassObject
}
}