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.descriptors.impl;
018    
019    import com.google.common.collect.Lists;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.jet.lang.descriptors.*;
023    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
024    import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
025    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl;
026    import org.jetbrains.jet.lang.resolve.name.Name;
027    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
028    import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
029    import org.jetbrains.jet.lang.types.JetType;
030    import org.jetbrains.jet.lang.types.TypeConstructor;
031    import org.jetbrains.jet.lang.types.TypeConstructorImpl;
032    import org.jetbrains.jet.lang.types.TypeUtils;
033    import org.jetbrains.jet.renderer.DescriptorRenderer;
034    import org.jetbrains.jet.storage.LockBasedStorageManager;
035    
036    import java.util.ArrayList;
037    import java.util.Collection;
038    import java.util.List;
039    
040    public abstract class MutableClassDescriptorLite extends ClassDescriptorBase {
041    
042        private Annotations annotations;
043    
044        private List<TypeParameterDescriptor> typeParameters;
045        private Collection<JetType> supertypes = Lists.newArrayList();
046    
047        private TypeConstructor typeConstructor;
048    
049        private Modality modality;
050        private Visibility visibility;
051    
052        private final boolean isInner;
053    
054        private MutableClassDescriptorLite classObjectDescriptor;
055        private final ClassKind kind;
056    
057        private JetScope scopeForMemberLookup;
058    
059        private ReceiverParameterDescriptor implicitReceiver;
060    
061        public MutableClassDescriptorLite(@NotNull DeclarationDescriptor containingDeclaration,
062                                          @NotNull Name name,
063                                          @NotNull ClassKind kind,
064                                          boolean isInner
065        ) {
066            super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, name);
067            this.kind = kind;
068            this.isInner = isInner;
069        }
070    
071        @NotNull
072        @Override
073        public TypeConstructor getTypeConstructor() {
074            return typeConstructor;
075        }
076    
077        public void setScopeForMemberLookup(@NotNull JetScope scopeForMemberLookup) {
078            this.scopeForMemberLookup = scopeForMemberLookup;
079        }
080    
081        public void createTypeConstructor() {
082            assert typeConstructor == null : typeConstructor;
083            this.typeConstructor = new TypeConstructorImpl(
084                    this,
085                    Annotations.EMPTY, // TODO : pass annotations from the class?
086                    !getModality().isOverridable(),
087                    getName().asString(),
088                    typeParameters,
089                    supertypes);
090        }
091    
092        private WritableScope getScopeForMemberLookupAsWritableScope() {
093            // hack
094            return (WritableScope) scopeForMemberLookup;
095        }
096    
097        @Override
098        @NotNull
099        public JetScope getScopeForMemberLookup() {
100            return scopeForMemberLookup;
101        }
102    
103        @NotNull
104        @Override
105        public ClassKind getKind() {
106            return kind;
107        }
108    
109        public void setModality(Modality modality) {
110            this.modality = modality;
111        }
112    
113        public void setVisibility(Visibility visibility) {
114            this.visibility = visibility;
115        }
116    
117        @Override
118        @NotNull
119        public Modality getModality() {
120            return modality;
121        }
122    
123        @NotNull
124        @Override
125        public Visibility getVisibility() {
126            return visibility;
127        }
128    
129        @Override
130        public boolean isInner() {
131            return isInner;
132        }
133    
134        public Collection<JetType> getSupertypes() {
135            return supertypes;
136        }
137    
138        public void setSupertypes(@NotNull Collection<JetType> supertypes) {
139            this.supertypes = supertypes;
140        }
141    
142    
143        @Override
144        @Nullable
145        public MutableClassDescriptorLite getClassObjectDescriptor() {
146            return classObjectDescriptor;
147        }
148    
149        public void addSupertype(@NotNull JetType supertype) {
150            assert !supertype.isError() : "Error types must be filtered out in DescriptorResolver";
151            if (TypeUtils.getClassDescriptor(supertype) != null) {
152                // See the Errors.SUPERTYPE_NOT_A_CLASS_OR_TRAIT
153                supertypes.add(supertype);
154            }
155        }
156    
157        public void setTypeParameterDescriptors(List<TypeParameterDescriptor> typeParameters) {
158            if (this.typeParameters != null) {
159                throw new IllegalStateException("Type parameters are already set for " + getName());
160            }
161            this.typeParameters = new ArrayList<TypeParameterDescriptor>();
162            for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
163                this.typeParameters.add(typeParameterDescriptor);
164            }
165        }
166    
167        public void lockScopes() {
168            getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING);
169            if (classObjectDescriptor != null) {
170                classObjectDescriptor.lockScopes();
171            }
172        }
173    
174        @Override
175        public String toString() {
176            try {
177                return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]";
178            } catch (Throwable e) {
179                return super.toString();
180            }
181        }
182    
183        @NotNull
184        @Override
185        public Annotations getAnnotations() {
186            if (annotations == null) {
187                annotations = new AnnotationsImpl(new ArrayList<AnnotationDescriptor>(0));
188            }
189            return annotations;
190        }
191    
192        public void setAnnotations(Annotations annotations) {
193            this.annotations = annotations;
194        }
195    
196        public void addAnnotations(@NotNull Iterable<AnnotationDescriptor> annotationDescriptors) {
197    
198            AnnotationsImpl annotationsImpl = (AnnotationsImpl) getAnnotations();
199            for (AnnotationDescriptor annotationDescriptor : annotationDescriptors) {
200                annotationsImpl.getAnnotationDescriptors().add(annotationDescriptor);
201            }
202        }
203    
204        private PackageLikeBuilder builder = null;
205    
206        @NotNull
207        public PackageLikeBuilder getBuilder() {
208            if (builder == null) {
209                builder = new PackageLikeBuilder() {
210                    @NotNull
211                    @Override
212                    public DeclarationDescriptor getOwnerForChildren() {
213                        return MutableClassDescriptorLite.this;
214                    }
215    
216                    @Override
217                    public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
218                        getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor);
219                    }
220    
221                    @Override
222                    public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
223                        getScopeForMemberLookupAsWritableScope().addFunctionDescriptor(functionDescriptor);
224                    }
225    
226                    @Override
227                    public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
228                        getScopeForMemberLookupAsWritableScope().addPropertyDescriptor(propertyDescriptor);
229                    }
230    
231                    @Override
232                    public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
233                        if (getKind() == ClassKind.CLASS_OBJECT || isInner()) {
234                            return ClassObjectStatus.NOT_ALLOWED;
235                        }
236    
237                        if (MutableClassDescriptorLite.this.classObjectDescriptor != null) {
238                            return ClassObjectStatus.DUPLICATE;
239                        }
240    
241                        assert classObjectDescriptor.getKind() == ClassKind.CLASS_OBJECT;
242                        MutableClassDescriptorLite.this.classObjectDescriptor = classObjectDescriptor;
243    
244                        return ClassObjectStatus.OK;
245                    }
246                };
247            }
248    
249            return builder;
250        }
251    }