@NotNull private MutableClassDescriptor createSyntheticClassObject( @NotNull ClassDescriptor classDescriptor) { MutableClassDescriptor classObject = new MutableClassDescriptor( classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false, getClassObjectName(classDescriptor.getName())); classObject.setModality(Modality.FINAL); classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility()); classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList()); createPrimaryConstructorForObject(null, classObject); return classObject; }
private void createTypeConstructors(@NotNull TopDownAnalysisContext c) { for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getClasses().entrySet()) { JetClassOrObject classOrObject = entry.getKey(); MutableClassDescriptor descriptor = (MutableClassDescriptor) entry.getValue(); if (classOrObject instanceof JetClass) { descriptorResolver.resolveMutableClassDescriptor( (JetClass) classOrObject, descriptor, trace); } else if (classOrObject instanceof JetObjectDeclaration) { descriptor.setModality(Modality.FINAL); descriptor.setVisibility( resolveVisibilityFromModifiers(classOrObject, getDefaultClassVisibility(descriptor))); descriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList()); } descriptor.createTypeConstructor(); ClassKind kind = descriptor.getKind(); if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT || kind == ClassKind.ENUM_CLASS) { MutableClassDescriptorLite classObject = descriptor.getClassObjectDescriptor(); assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText(); JetType supertype; if (kind == ClassKind.ENUM_CLASS) { supertype = KotlinBuiltIns.getInstance().getAnyType(); } else { // This is a clever hack: each enum entry and object declaration (i.e. singleton) has a // synthetic class object. // We make this class object inherit from the singleton here, thus allowing to use the // singleton's class object where // the instance of the singleton is applicable. Effectively all members of the singleton // would be present in its class // object as fake overrides, so you can access them via standard class object notation: // ObjectName.memberName() supertype = descriptor.getDefaultType(); } classObject.setSupertypes(Collections.singleton(supertype)); classObject.createTypeConstructor(); } } }
@NotNull private static ClassDescriptor createClass( @NotNull PackageFragmentDescriptor packageFragment, @NotNull String name, @NotNull String... typeParameters) { MutableClassDescriptor descriptor = new MutableClassDescriptor( packageFragment, packageFragment.getMemberScope(), ClassKind.CLASS, false, Name.identifier(name)); List<TypeParameterDescriptor> typeParameterDescriptors = new ArrayList<TypeParameterDescriptor>(typeParameters.length); for (int i = 0; i < typeParameters.length; i++) { String[] s = typeParameters[i].split(" "); Variance variance = Variance.valueOf(s[0].toUpperCase() + "_VARIANCE"); String typeParameterName = s[1]; TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification( descriptor, Annotations.EMPTY, false, variance, Name.identifier(typeParameterName), i); typeParameter.setInitialized(); typeParameterDescriptors.add(typeParameter); } descriptor.setModality(Modality.FINAL); descriptor.setVisibility(Visibilities.PUBLIC); descriptor.setTypeParameterDescriptors(typeParameterDescriptors); descriptor.createTypeConstructor(); return descriptor; }