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 kotlin.DeprecationLevel;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.kotlin.descriptors.*;
023    import org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt;
024    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
025    import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl;
026    import org.jetbrains.kotlin.descriptors.impl.*;
027    import org.jetbrains.kotlin.name.Name;
028    import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
029    import org.jetbrains.kotlin.types.KotlinType;
030    import org.jetbrains.kotlin.types.Variance;
031    
032    import java.util.Collections;
033    
034    import static org.jetbrains.kotlin.resolve.DescriptorUtils.getDefaultConstructorVisibility;
035    import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getBuiltIns;
036    
037    public class DescriptorFactory {
038        private static class DefaultConstructorDescriptor extends ConstructorDescriptorImpl {
039            public DefaultConstructorDescriptor(@NotNull ClassDescriptor containingClass, @NotNull SourceElement source) {
040                super(containingClass, null, Annotations.Companion.getEMPTY(), true, Kind.DECLARATION, source);
041                initialize(Collections.<ValueParameterDescriptor>emptyList(),
042                           getDefaultConstructorVisibility(containingClass));
043            }
044        }
045    
046        private DescriptorFactory() {
047        }
048    
049        @NotNull
050        public static PropertySetterDescriptorImpl createDefaultSetter(
051                @NotNull PropertyDescriptor propertyDescriptor,
052                @NotNull Annotations annotations
053        ) {
054            return createSetter(propertyDescriptor, annotations, true, false, propertyDescriptor.getSource());
055        }
056    
057        @NotNull
058        public static PropertySetterDescriptorImpl createSetter(
059                @NotNull PropertyDescriptor propertyDescriptor,
060                @NotNull Annotations annotations,
061                boolean isDefault,
062                boolean isExternal,
063                @NotNull SourceElement sourceElement
064        ) {
065            return createSetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getVisibility(), sourceElement);
066        }
067    
068        @NotNull
069        public static PropertySetterDescriptorImpl createSetter(
070                @NotNull PropertyDescriptor propertyDescriptor,
071                @NotNull Annotations annotations,
072                boolean isDefault,
073                boolean isExternal,
074                @NotNull Visibility visibility,
075                @NotNull SourceElement sourceElement
076        ) {
077            PropertySetterDescriptorImpl setterDescriptor =
078                    new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
079                                                     visibility, !isDefault, isDefault, isExternal,
080                                                     CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement);
081            setterDescriptor.initializeDefault();
082            return setterDescriptor;
083        }
084    
085        @NotNull
086        public static PropertyGetterDescriptorImpl createDefaultGetter(
087                @NotNull PropertyDescriptor propertyDescriptor,
088                @NotNull Annotations annotations
089        ) {
090            return createGetter(propertyDescriptor, annotations, true, false);
091        }
092    
093        @NotNull
094        public static PropertyGetterDescriptorImpl createGetter(
095                @NotNull PropertyDescriptor propertyDescriptor,
096                @NotNull Annotations annotations,
097                boolean isDefault,
098                boolean isExternal
099        ) {
100            return createGetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getSource());
101        }
102    
103        @NotNull
104        public static PropertyGetterDescriptorImpl createGetter(
105                @NotNull PropertyDescriptor propertyDescriptor,
106                @NotNull Annotations annotations,
107                boolean isDefault,
108                boolean isExternal,
109                @NotNull SourceElement sourceElement) {
110            return new PropertyGetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
111                                                    propertyDescriptor.getVisibility(), !isDefault, isDefault, isExternal,
112                                                    CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement);
113        }
114    
115        @NotNull
116        public static ConstructorDescriptorImpl createPrimaryConstructorForObject(
117                @NotNull ClassDescriptor containingClass,
118                @NotNull SourceElement source
119        ) {
120            return new DefaultConstructorDescriptor(containingClass, source);
121        }
122    
123        @NotNull
124        public static SimpleFunctionDescriptor createEnumValuesMethod(@NotNull ClassDescriptor enumClass) {
125            SimpleFunctionDescriptorImpl values =
126                    SimpleFunctionDescriptorImpl.create(enumClass, Annotations.Companion.getEMPTY(), DescriptorUtils.ENUM_VALUES,
127                                                        CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource());
128            return values.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
129                                     Collections.<ValueParameterDescriptor>emptyList(),
130                                     getBuiltIns(enumClass).getArrayType(Variance.INVARIANT, enumClass.getDefaultType()),
131                                     Modality.FINAL, Visibilities.PUBLIC);
132        }
133    
134        @NotNull
135        public static PropertyDescriptor createEnumValuesProperty(@NotNull ClassDescriptor enumClass) {
136            AnnotationsImpl annotations = AnnotationsImpl.createWithNoTarget(
137                    AnnotationUtilKt.createDeprecatedAnnotation(getBuiltIns(enumClass),
138                                                                "Use 'values()' function instead", "this.values()",
139                                                                DeprecationLevel.ERROR)
140            );
141    
142            PropertyDescriptorImpl values =
143                    PropertyDescriptorImpl.create(
144                            enumClass, annotations, Modality.FINAL, Visibilities.PUBLIC, /* isVar */ false,
145                            DescriptorUtils.ENUM_VALUES, CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource(),
146                            /* lateInit = */ false, /* isConst = */ false
147                    );
148    
149            KotlinType type = getBuiltIns(enumClass).getArrayType(Variance.INVARIANT, enumClass.getDefaultType());
150    
151            PropertyGetterDescriptorImpl getter = createGetter(
152                    values, Annotations.Companion.getEMPTY(), /* isDefault = */ false, /* isExternal = */ false);
153    
154            values.initialize(getter, null);
155            getter.initialize(type);
156            values.setType(type, Collections.<TypeParameterDescriptor>emptyList(), null, (KotlinType) null);
157    
158            return values;
159        }
160    
161        @NotNull
162        public static SimpleFunctionDescriptor createEnumValueOfMethod(@NotNull ClassDescriptor enumClass) {
163            SimpleFunctionDescriptorImpl valueOf =
164                    SimpleFunctionDescriptorImpl.create(enumClass, Annotations.Companion.getEMPTY(), DescriptorUtils.ENUM_VALUE_OF,
165                                                        CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource());
166            ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
167                    valueOf, null, 0, Annotations.Companion.getEMPTY(), Name.identifier("value"), getBuiltIns(enumClass).getStringType(),
168                    /* declaresDefaultValue = */ false,
169                    /* isCrossinline = */ false,
170                    /* isNoinline = */ false,
171                    null,
172                    enumClass.getSource()
173            );
174            return valueOf.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
175                                      Collections.singletonList(parameterDescriptor), enumClass.getDefaultType(),
176                                      Modality.FINAL, Visibilities.PUBLIC);
177        }
178    
179        @Nullable
180        public static ReceiverParameterDescriptor createExtensionReceiverParameterForCallable(
181                @NotNull CallableDescriptor owner,
182                @Nullable KotlinType receiverParameterType
183        ) {
184            return receiverParameterType == null
185                   ? null
186                   : new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType));
187        }
188    }