diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt index 17a46fb271b..64848a166d9 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/impl/EnumClassObjectDescriptor.kt @@ -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 by Delegates.lazy { + val result = ArrayList(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 + } }