001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.resolve;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.descriptors.*;
022    import org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt;
023    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
024    import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
025    import org.jetbrains.kotlin.descriptors.impl.*;
026    import org.jetbrains.kotlin.name.Name;
027    import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
028    import org.jetbrains.kotlin.types.KotlinType;
029    import org.jetbrains.kotlin.types.Variance;
030    
031    import java.util.Collections;
032    
033    import static org.jetbrains.kotlin.resolve.DescriptorUtils.getDefaultConstructorVisibility;
034    import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getBuiltIns;
035    
036    public class DescriptorFactory {
037        private static class DefaultConstructorDescriptor extends ConstructorDescriptorImpl {
038            public DefaultConstructorDescriptor(@NotNull ClassDescriptor containingClass, @NotNull SourceElement source) {
039                super(containingClass, null, Annotations.Companion.getEMPTY(), true, Kind.DECLARATION, source);
040                initialize(Collections.<ValueParameterDescriptor>emptyList(),
041                           getDefaultConstructorVisibility(containingClass));
042            }
043        }
044    
045        private DescriptorFactory() {
046        }
047    
048        @NotNull
049        public static PropertySetterDescriptorImpl createDefaultSetter(
050                @NotNull PropertyDescriptor propertyDescriptor,
051                @NotNull Annotations annotations
052        ) {
053            return createSetter(propertyDescriptor, annotations, true, false, propertyDescriptor.getSource());
054        }
055    
056        @NotNull
057        public static PropertySetterDescriptorImpl createSetter(
058                @NotNull PropertyDescriptor propertyDescriptor,
059                @NotNull Annotations annotations,
060                boolean isDefault,
061                boolean isExternal,
062                @NotNull SourceElement sourceElement
063        ) {
064            return createSetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getVisibility(), sourceElement);
065        }
066    
067        @NotNull
068        public static PropertySetterDescriptorImpl createSetter(
069                @NotNull PropertyDescriptor propertyDescriptor,
070                @NotNull Annotations annotations,
071                boolean isDefault,
072                boolean isExternal,
073                @NotNull Visibility visibility,
074                @NotNull SourceElement sourceElement
075        ) {
076            PropertySetterDescriptorImpl setterDescriptor =
077                    new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
078                                                     visibility, !isDefault, isDefault, isExternal,
079                                                     CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement);
080            setterDescriptor.initializeDefault();
081            return setterDescriptor;
082        }
083    
084        @NotNull
085        public static PropertyGetterDescriptorImpl createDefaultGetter(
086                @NotNull PropertyDescriptor propertyDescriptor,
087                @NotNull Annotations annotations
088        ) {
089            return createGetter(propertyDescriptor, annotations, true, false);
090        }
091    
092        @NotNull
093        public static PropertyGetterDescriptorImpl createGetter(
094                @NotNull PropertyDescriptor propertyDescriptor,
095                @NotNull Annotations annotations,
096                boolean isDefault,
097                boolean isExternal
098        ) {
099            return createGetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getSource());
100        }
101    
102        @NotNull
103        public static PropertyGetterDescriptorImpl createGetter(
104                @NotNull PropertyDescriptor propertyDescriptor,
105                @NotNull Annotations annotations,
106                boolean isDefault,
107                boolean isExternal,
108                @NotNull SourceElement sourceElement) {
109            return new PropertyGetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
110                                                    propertyDescriptor.getVisibility(), !isDefault, isDefault, isExternal,
111                                                    CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement);
112        }
113    
114        @NotNull
115        public static ConstructorDescriptorImpl createPrimaryConstructorForObject(
116                @NotNull ClassDescriptor containingClass,
117                @NotNull SourceElement source
118        ) {
119            return new DefaultConstructorDescriptor(containingClass, source);
120        }
121    
122        @NotNull
123        public static SimpleFunctionDescriptor createEnumValuesMethod(@NotNull ClassDescriptor enumClass) {
124            SimpleFunctionDescriptorImpl values =
125                    SimpleFunctionDescriptorImpl.create(enumClass, Annotations.Companion.getEMPTY(), DescriptorUtils.ENUM_VALUES,
126                                                        CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource());
127            return values.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
128                                     Collections.<ValueParameterDescriptor>emptyList(),
129                                     getBuiltIns(enumClass).getArrayType(Variance.INVARIANT, enumClass.getDefaultType()),
130                                     Modality.FINAL, Visibilities.PUBLIC);
131        }
132    
133        @NotNull
134        public static PropertyDescriptor createEnumValuesProperty(@NotNull ClassDescriptor enumClass) {
135            AnnotationsImpl annotations = AnnotationsImpl.createWithNoTarget(AnnotationUtilKt.createDeprecatedAnnotation(
136                    getBuiltIns(enumClass), "Use 'values()' function instead", "this.values()", "ERROR"
137            ));
138    
139            PropertyDescriptorImpl values =
140                    PropertyDescriptorImpl.create(
141                            enumClass, annotations, Modality.FINAL, Visibilities.PUBLIC, /* isVar */ false,
142                            DescriptorUtils.ENUM_VALUES, CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource(),
143                            /* lateInit = */ false, /* isConst = */ false
144                    );
145    
146            KotlinType type = getBuiltIns(enumClass).getArrayType(Variance.INVARIANT, enumClass.getDefaultType());
147    
148            PropertyGetterDescriptorImpl getter = createGetter(
149                    values, Annotations.Companion.getEMPTY(), /* isDefault = */ false, /* isExternal = */ false);
150    
151            values.initialize(getter, null);
152            getter.initialize(type);
153            values.setType(type, Collections.<TypeParameterDescriptor>emptyList(), null, (KotlinType) null);
154    
155            return values;
156        }
157    
158        @NotNull
159        public static SimpleFunctionDescriptor createEnumValueOfMethod(@NotNull ClassDescriptor enumClass) {
160            SimpleFunctionDescriptorImpl valueOf =
161                    SimpleFunctionDescriptorImpl.create(enumClass, Annotations.Companion.getEMPTY(), DescriptorUtils.ENUM_VALUE_OF,
162                                                        CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource());
163            ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
164                    valueOf, null, 0, Annotations.Companion.getEMPTY(), Name.identifier("value"), getBuiltIns(enumClass).getStringType(),
165                    /* declaresDefaultValue = */ false,
166                    /* isCrossinline = */ false,
167                    /* isNoinline = */ false,
168                    null,
169                    enumClass.getSource()
170            );
171            return valueOf.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
172                                      Collections.singletonList(parameterDescriptor), enumClass.getDefaultType(),
173                                      Modality.FINAL, Visibilities.PUBLIC);
174        }
175    
176        @Nullable
177        public static ReceiverParameterDescriptor createExtensionReceiverParameterForCallable(
178                @NotNull CallableDescriptor owner,
179                @Nullable KotlinType receiverParameterType
180        ) {
181            return receiverParameterType == null
182                   ? null
183                   : new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType));
184        }
185    }