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.descriptors.impl;
018    
019    import com.google.common.collect.Sets;
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.Annotations;
024    import org.jetbrains.kotlin.name.Name;
025    import org.jetbrains.kotlin.resolve.scopes.*;
026    import org.jetbrains.kotlin.storage.LockBasedStorageManager;
027    import org.jetbrains.kotlin.types.*;
028    
029    import java.util.ArrayList;
030    import java.util.Collection;
031    import java.util.List;
032    import java.util.Set;
033    
034    public class MutableClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes {
035        private final ClassKind kind;
036        private final boolean isInner;
037    
038        private Modality modality;
039        private Visibility visibility;
040        private TypeConstructor typeConstructor;
041        private List<TypeParameterDescriptor> typeParameters;
042        private Collection<JetType> supertypes = new ArrayList<JetType>();
043    
044        private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
045        private ConstructorDescriptor primaryConstructor;
046    
047        private final Set<CallableMemberDescriptor> declaredCallableMembers = Sets.newLinkedHashSet();
048        private final Set<PropertyDescriptor> properties = Sets.newLinkedHashSet();
049        private final Set<SimpleFunctionDescriptor> functions = Sets.newLinkedHashSet();
050    
051        private final WritableScope scopeForMemberResolution;
052        // This scope contains type parameters but does not contain inner classes
053        private final WritableScope scopeForSupertypeResolution;
054        private WritableScope scopeForInitializers; //contains members + primary constructor value parameters + map for backing fields
055        private JetScope scopeForMemberLookup;
056        private final JetScope staticScope = new StaticScopeForKotlinClass(this);
057    
058        public MutableClassDescriptor(
059                @NotNull DeclarationDescriptor containingDeclaration,
060                @NotNull JetScope outerScope,
061                @NotNull ClassKind kind,
062                boolean isInner,
063                @NotNull Name name,
064                @NotNull SourceElement source
065        ) {
066            super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, name, source);
067            assert kind != ClassKind.OBJECT : "Fix isCompanionObject()";
068    
069            this.kind = kind;
070            this.isInner = isInner;
071    
072            RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING;
073    
074            setScopeForMemberLookup(new WritableScopeImpl(JetScope.Empty.INSTANCE$, this, redeclarationHandler, "MemberLookup")
075                                            .changeLockLevel(WritableScope.LockLevel.BOTH));
076            this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution")
077                    .changeLockLevel(WritableScope.LockLevel.BOTH);
078            this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution")
079                    .changeLockLevel(WritableScope.LockLevel.BOTH);
080    
081            if (kind == ClassKind.INTERFACE) {
082                setUpScopeForInitializers(this);
083            }
084    
085            scopeForMemberResolution.importScope(staticScope);
086            scopeForMemberResolution.addLabeledDeclaration(this);
087        }
088    
089        @Nullable
090        @Override
091        public MutableClassDescriptor getCompanionObjectDescriptor() {
092            return null;
093        }
094    
095        @NotNull
096        @Override
097        public Annotations getAnnotations() {
098            return Annotations.EMPTY;
099        }
100    
101        public void setModality(@NotNull Modality modality) {
102            this.modality = modality;
103        }
104    
105        @Override
106        @NotNull
107        public Modality getModality() {
108            return modality;
109        }
110    
111        @NotNull
112        @Override
113        public ClassKind getKind() {
114            return kind;
115        }
116    
117        public void setVisibility(@NotNull Visibility visibility) {
118            this.visibility = visibility;
119        }
120    
121        @NotNull
122        @Override
123        public Visibility getVisibility() {
124            return visibility;
125        }
126    
127        @Override
128        public boolean isInner() {
129            return isInner;
130        }
131    
132        @Override
133        public boolean isCompanionObject() {
134            return false;
135        }
136    
137        @NotNull
138        @Override
139        public TypeConstructor getTypeConstructor() {
140            return typeConstructor;
141        }
142    
143        @NotNull
144        public Collection<JetType> getSupertypes() {
145            return supertypes;
146        }
147    
148        public void setSupertypes(@NotNull Collection<JetType> supertypes) {
149            this.supertypes = supertypes;
150        }
151    
152        public void addSupertype(@NotNull JetType supertype) {
153            assert !supertype.isError() : "Error types must be filtered out in DescriptorResolver";
154            if (TypeUtils.getClassDescriptor(supertype) != null) {
155                // See the Errors.SUPERTYPE_NOT_A_CLASS_OR_TRAIT
156                supertypes.add(supertype);
157            }
158        }
159    
160        public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
161            assert primaryConstructor == null : "Primary constructor assigned twice " + this;
162            primaryConstructor = constructorDescriptor;
163    
164            constructors.add(constructorDescriptor);
165    
166            ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(new DelegatingType() {
167                @Override
168                protected JetType getDelegate() {
169                    return getDefaultType();
170                }
171            });
172    
173            if (constructorDescriptor.isPrimary()) {
174                setUpScopeForInitializers(constructorDescriptor);
175            }
176        }
177    
178        @NotNull
179        @Override
180        public Set<ConstructorDescriptor> getConstructors() {
181            return constructors;
182        }
183    
184        @Override
185        @Nullable
186        public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
187            return primaryConstructor;
188        }
189    
190        @NotNull
191        public Set<SimpleFunctionDescriptor> getFunctions() {
192            return functions;
193        }
194    
195        @NotNull
196        public Set<PropertyDescriptor> getProperties() {
197            return properties;
198        }
199    
200        @Override
201        @NotNull
202        public Set<CallableMemberDescriptor> getDeclaredCallableMembers() {
203            return declaredCallableMembers;
204        }
205    
206        public void setTypeParameterDescriptors(@NotNull List<TypeParameterDescriptor> typeParameters) {
207            if (this.typeParameters != null) {
208                throw new IllegalStateException("Type parameters are already set for " + getName());
209            }
210            this.typeParameters = new ArrayList<TypeParameterDescriptor>(typeParameters);
211            for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
212                scopeForSupertypeResolution.addClassifierDescriptor(typeParameterDescriptor);
213            }
214            scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
215        }
216    
217        public void createTypeConstructor() {
218            assert typeConstructor == null : typeConstructor;
219            this.typeConstructor = TypeConstructorImpl.createForClass(
220                    this,
221                    Annotations.EMPTY,
222                    !getModality().isOverridable(),
223                    getName().asString(),
224                    typeParameters,
225                    supertypes
226            );
227            for (FunctionDescriptor functionDescriptor : getConstructors()) {
228                ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
229            }
230            scopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter());
231        }
232    
233        @Override
234        @NotNull
235        public JetScope getScopeForClassHeaderResolution() {
236            return scopeForSupertypeResolution;
237        }
238    
239        @Override
240        @NotNull
241        public JetScope getScopeForMemberDeclarationResolution() {
242            return scopeForMemberResolution;
243        }
244    
245        private WritableScope getWritableScopeForInitializers() {
246            if (scopeForInitializers == null) {
247                throw new IllegalStateException("Scope for initializers queried before the primary constructor is set");
248            }
249            return scopeForInitializers;
250        }
251    
252        @Override
253        @NotNull
254        public JetScope getScopeForInitializerResolution() {
255            return getWritableScopeForInitializers();
256        }
257    
258        private void setUpScopeForInitializers(@NotNull DeclarationDescriptor containingDeclaration) {
259            this.scopeForInitializers = new WritableScopeImpl(
260                    scopeForMemberResolution, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Initializers")
261                        .changeLockLevel(WritableScope.LockLevel.BOTH);
262        }
263    
264        public void setScopeForMemberLookup(@NotNull JetScope scopeForMemberLookup) {
265            this.scopeForMemberLookup = scopeForMemberLookup;
266        }
267    
268        @Override
269        @NotNull
270        public JetScope getScopeForMemberLookup() {
271            return scopeForMemberLookup;
272        }
273    
274        @NotNull
275        @Override
276        public JetScope getStaticScope() {
277            return staticScope;
278        }
279    
280        @Override
281        public String toString() {
282            return DeclarationDescriptorImpl.toString(this);
283        }
284    }