001    /*
002     * Copyright 2010-2013 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.jet.lang.resolve;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.jet.lang.descriptors.*;
022    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
023    import org.jetbrains.jet.lang.descriptors.impl.*;
024    import org.jetbrains.jet.lang.resolve.name.Name;
025    import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
026    import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
027    import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
028    import org.jetbrains.jet.lang.types.JetType;
029    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
030    
031    import java.util.Collections;
032    
033    import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
034    import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getDefaultConstructorVisibility;
035    
036    public class DescriptorFactory {
037        public static final Name VALUE_OF_METHOD_NAME = Name.identifier("valueOf");
038        public static final Name VALUES_METHOD_NAME = Name.identifier("values");
039    
040        private DescriptorFactory() {
041        }
042    
043        @NotNull
044        public static PropertySetterDescriptorImpl createDefaultSetter(@NotNull PropertyDescriptor propertyDescriptor) {
045            return createSetter(propertyDescriptor, true);
046        }
047    
048        @NotNull
049        public static PropertySetterDescriptorImpl createSetter(@NotNull PropertyDescriptor propertyDescriptor, boolean isDefault) {
050            PropertySetterDescriptorImpl setterDescriptor = new PropertySetterDescriptorImpl(
051                    propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
052                    propertyDescriptor.getVisibility(),
053                    !isDefault, isDefault, CallableMemberDescriptor.Kind.DECLARATION);
054            setterDescriptor.initializeDefault();
055            return setterDescriptor;
056        }
057    
058        @NotNull
059        public static PropertyGetterDescriptorImpl createDefaultGetter(@NotNull PropertyDescriptor propertyDescriptor) {
060            return createGetter(propertyDescriptor, true);
061        }
062    
063        @NotNull
064        public static PropertyGetterDescriptorImpl createGetter(@NotNull PropertyDescriptor propertyDescriptor, boolean isDefault) {
065            return new PropertyGetterDescriptorImpl(
066                    propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
067                    propertyDescriptor.getVisibility(),
068                    !isDefault, isDefault, CallableMemberDescriptor.Kind.DECLARATION);
069        }
070    
071        @NotNull
072        public static ConstructorDescriptorImpl createPrimaryConstructorForObject(@NotNull ClassDescriptor containingClass) {
073            ConstructorDescriptorImpl constructorDescriptor =
074                    new ConstructorDescriptorImpl(containingClass, Collections.<AnnotationDescriptor>emptyList(), true);
075            constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
076                                             Collections.<ValueParameterDescriptor>emptyList(),
077                                             getDefaultConstructorVisibility(containingClass));
078            return constructorDescriptor;
079        }
080    
081        @NotNull
082        public static SimpleFunctionDescriptor createEnumClassObjectValuesMethod(
083                @NotNull ClassDescriptor classObject,
084                @NotNull JetType returnType
085        ) {
086            SimpleFunctionDescriptorImpl values =
087                    new SimpleFunctionDescriptorImpl(classObject, Collections.<AnnotationDescriptor>emptyList(), VALUES_METHOD_NAME,
088                                                     CallableMemberDescriptor.Kind.DECLARATION);
089            return values.initialize(null, classObject.getThisAsReceiverParameter(), Collections.<TypeParameterDescriptor>emptyList(),
090                                     Collections.<ValueParameterDescriptor>emptyList(),
091                                     returnType, Modality.FINAL,
092                                     Visibilities.PUBLIC, false);
093        }
094    
095        @NotNull
096        public static SimpleFunctionDescriptor createEnumClassObjectValueOfMethod(
097                @NotNull ClassDescriptor classObject,
098                @NotNull JetType returnType
099        ) {
100            SimpleFunctionDescriptorImpl values =
101                    new SimpleFunctionDescriptorImpl(classObject, Collections.<AnnotationDescriptor>emptyList(), VALUE_OF_METHOD_NAME,
102                                                     CallableMemberDescriptor.Kind.DECLARATION);
103            ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
104                    values,
105                    0,
106                    Collections.<AnnotationDescriptor>emptyList(),
107                    Name.identifier("value"),
108                    KotlinBuiltIns.getInstance().getStringType(),
109                    false,
110                    null);
111            return values.initialize(null, classObject.getThisAsReceiverParameter(),
112                                     Collections.<TypeParameterDescriptor>emptyList(),
113                                     Collections.singletonList(parameterDescriptor),
114                                     returnType, Modality.FINAL,
115                                     Visibilities.PUBLIC, false);
116        }
117    
118        @Nullable
119        public static ReceiverParameterDescriptor createReceiverParameterForCallable(
120                @NotNull CallableDescriptor owner,
121                @Nullable JetType receiverParameterType
122        ) {
123            return receiverParameterType == null
124                   ? NO_RECEIVER_PARAMETER
125                   : new ReceiverParameterDescriptorImpl(owner, receiverParameterType, new ExtensionReceiver(owner, receiverParameterType));
126        }
127    
128        @NotNull
129        public static ReceiverParameterDescriptor createLazyReceiverParameterDescriptor(@NotNull final ClassDescriptor classDescriptor) {
130            return new AbstractReceiverParameterDescriptor() {
131                private ClassReceiver value;
132    
133                @NotNull
134                @Override
135                public JetType getType() {
136                    // This must be lazy, thus the inner class
137                    return classDescriptor.getDefaultType();
138                }
139    
140                @NotNull
141                @Override
142                public ReceiverValue getValue() {
143                    if (value == null) {
144                        value = new ClassReceiver(classDescriptor);
145                    }
146                    return value;
147                }
148    
149                @NotNull
150                @Override
151                public DeclarationDescriptor getContainingDeclaration() {
152                    return classDescriptor;
153                }
154    
155                @Override
156                public String toString() {
157                    return "class " + classDescriptor.getName() + "::this";
158                }
159            };
160        }
161    }