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.<TypeParameterDescriptor>emptyList(), 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);
054        }
055    
056        @NotNull
057        public static PropertySetterDescriptorImpl createSetter(
058                @NotNull PropertyDescriptor propertyDescriptor,
059                @NotNull Annotations annotations,
060                boolean isDefault,
061                boolean isExternal
062        ) {
063            return createSetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getVisibility());
064        }
065    
066        @NotNull
067        public static PropertySetterDescriptorImpl createSetter(
068                @NotNull PropertyDescriptor propertyDescriptor,
069                @NotNull Annotations annotations,
070                boolean isDefault,
071                boolean isExternal,
072                @NotNull Visibility visibility
073        ) {
074            PropertySetterDescriptorImpl setterDescriptor =
075                    new PropertySetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
076                                                     visibility, !isDefault, isDefault, isExternal,
077                                                     CallableMemberDescriptor.Kind.DECLARATION, null, propertyDescriptor.getSource());
078            setterDescriptor.initializeDefault();
079            return setterDescriptor;
080        }
081    
082        @NotNull
083        public static PropertyGetterDescriptorImpl createDefaultGetter(
084                @NotNull PropertyDescriptor propertyDescriptor,
085                @NotNull Annotations annotations
086        ) {
087            return createGetter(propertyDescriptor, annotations, true, false);
088        }
089    
090        @NotNull
091        public static PropertyGetterDescriptorImpl createGetter(
092                @NotNull PropertyDescriptor propertyDescriptor,
093                @NotNull Annotations annotations,
094                boolean isDefault,
095                boolean isExternal
096        ) {
097            return createGetter(propertyDescriptor, annotations, isDefault, isExternal, propertyDescriptor.getSource());
098        }
099    
100        @NotNull
101        public static PropertyGetterDescriptorImpl createGetter(
102                @NotNull PropertyDescriptor propertyDescriptor,
103                @NotNull Annotations annotations,
104                boolean isDefault,
105                boolean isExternal,
106                @NotNull SourceElement sourceElement) {
107            return new PropertyGetterDescriptorImpl(propertyDescriptor, annotations, propertyDescriptor.getModality(),
108                                                    propertyDescriptor.getVisibility(), !isDefault, isDefault, isExternal,
109                                                    CallableMemberDescriptor.Kind.DECLARATION, null, sourceElement);
110        }
111    
112        @NotNull
113        public static ConstructorDescriptorImpl createPrimaryConstructorForObject(
114                @NotNull ClassDescriptor containingClass,
115                @NotNull SourceElement source
116        ) {
117            return new DefaultConstructorDescriptor(containingClass, source);
118        }
119    
120        @NotNull
121        public static SimpleFunctionDescriptor createEnumValuesMethod(@NotNull ClassDescriptor enumClass) {
122            AnnotationsImpl annotations = AnnotationsImpl.createWithNoTarget(
123                    AnnotationUtilKt.createDeprecatedAnnotation(getBuiltIns(enumClass), "Use 'values' property instead", "this.values")
124            );
125    
126            SimpleFunctionDescriptorImpl values =
127                    SimpleFunctionDescriptorImpl.create(enumClass, annotations, DescriptorUtils.ENUM_VALUES,
128                                                        CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource());
129            return values.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
130                                     Collections.<ValueParameterDescriptor>emptyList(),
131                                     getBuiltIns(enumClass).getArrayType(Variance.INVARIANT, enumClass.getDefaultType()),
132                                     Modality.FINAL, Visibilities.PUBLIC);
133        }
134    
135        @NotNull
136        public static PropertyDescriptor createEnumValuesProperty(@NotNull ClassDescriptor enumClass) {
137            PropertyDescriptorImpl values =
138                    PropertyDescriptorImpl.create(
139                            enumClass, Annotations.Companion.getEMPTY(), Modality.FINAL, Visibilities.PUBLIC, /* isVar */ false,
140                            DescriptorUtils.ENUM_VALUES, CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource(),
141                            /* lateInit = */ false, /* isConst = */ false
142                    );
143    
144            KotlinType type = getBuiltIns(enumClass).getArrayType(Variance.INVARIANT, enumClass.getDefaultType());
145    
146            PropertyGetterDescriptorImpl getter = createDefaultGetter(values, Annotations.Companion.getEMPTY());
147    
148            values.initialize(getter, null);
149            getter.initialize(type);
150            values.setType(type, Collections.<TypeParameterDescriptor>emptyList(), null, (KotlinType) null);
151    
152            return values;
153        }
154    
155        @NotNull
156        public static SimpleFunctionDescriptor createEnumValueOfMethod(@NotNull ClassDescriptor enumClass) {
157            SimpleFunctionDescriptorImpl valueOf =
158                    SimpleFunctionDescriptorImpl.create(enumClass, Annotations.Companion.getEMPTY(), DescriptorUtils.ENUM_VALUE_OF,
159                                                        CallableMemberDescriptor.Kind.SYNTHESIZED, enumClass.getSource());
160            ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
161                    valueOf, null, 0, Annotations.Companion.getEMPTY(), Name.identifier("value"), getBuiltIns(enumClass).getStringType(),
162                    /* declaresDefaultValue = */ false,
163                    /* isCrossinline = */ false,
164                    /* isNoinline = */ false,
165                    null,
166                    enumClass.getSource()
167            );
168            return valueOf.initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(),
169                                      Collections.singletonList(parameterDescriptor), enumClass.getDefaultType(),
170                                      Modality.FINAL, Visibilities.PUBLIC);
171        }
172    
173        @Nullable
174        public static ReceiverParameterDescriptor createExtensionReceiverParameterForCallable(
175                @NotNull CallableDescriptor owner,
176                @Nullable KotlinType receiverParameterType
177        ) {
178            return receiverParameterType == null
179                   ? null
180                   : new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType));
181        }
182    }