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.Sets;
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.*;
028 import org.jetbrains.jet.lang.types.*;
029 import org.jetbrains.jet.storage.LockBasedStorageManager;
030
031 import java.util.ArrayList;
032 import java.util.Collection;
033 import java.util.List;
034 import java.util.Set;
035
036 public class MutableClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes {
037 private final ClassKind kind;
038 private final boolean isInner;
039
040 private Annotations annotations;
041 private Modality modality;
042 private Visibility visibility;
043 private TypeConstructor typeConstructor;
044 private List<TypeParameterDescriptor> typeParameters;
045 private Collection<JetType> supertypes = new ArrayList<JetType>();
046
047 private MutableClassDescriptor classObjectDescriptor;
048
049 private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet();
050 private ConstructorDescriptor primaryConstructor;
051
052 private final Set<CallableMemberDescriptor> declaredCallableMembers = Sets.newLinkedHashSet();
053 private final Set<CallableMemberDescriptor> allCallableMembers = Sets.newLinkedHashSet(); // includes fake overrides
054 private final Set<PropertyDescriptor> properties = Sets.newLinkedHashSet();
055 private final Set<SimpleFunctionDescriptor> functions = Sets.newLinkedHashSet();
056
057 private final WritableScope scopeForMemberResolution;
058 // This scope contains type parameters but does not contain inner classes
059 private final WritableScope scopeForSupertypeResolution;
060 private WritableScope scopeForInitializers = null; //contains members + primary constructor value parameters + map for backing fields
061 private JetScope scopeForMemberLookup;
062
063 public MutableClassDescriptor(
064 @NotNull DeclarationDescriptor containingDeclaration,
065 @NotNull JetScope outerScope,
066 @NotNull ClassKind kind,
067 boolean isInner,
068 @NotNull Name name
069 ) {
070 super(LockBasedStorageManager.NO_LOCKS, containingDeclaration, name);
071 this.kind = kind;
072 this.isInner = isInner;
073
074 RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING;
075
076 setScopeForMemberLookup(new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler, "MemberLookup")
077 .changeLockLevel(WritableScope.LockLevel.BOTH));
078 this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution")
079 .changeLockLevel(WritableScope.LockLevel.BOTH);
080 this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution")
081 .changeLockLevel(WritableScope.LockLevel.BOTH);
082 if (getKind() == ClassKind.TRAIT) {
083 setUpScopeForInitializers(this);
084 }
085
086 scopeForMemberResolution.addLabeledDeclaration(this);
087 }
088
089 @Nullable
090 @Override
091 public MutableClassDescriptor getClassObjectDescriptor() {
092 return classObjectDescriptor;
093 }
094
095 @NotNull
096 @Override
097 public Annotations getAnnotations() {
098 if (annotations == null) {
099 annotations = new AnnotationsImpl(new ArrayList<AnnotationDescriptor>(0));
100 }
101 return annotations;
102 }
103
104 public void addAnnotations(@NotNull Iterable<AnnotationDescriptor> annotationsToAdd) {
105 List<AnnotationDescriptor> annotations = ((AnnotationsImpl) getAnnotations()).getAnnotationDescriptors();
106 for (AnnotationDescriptor annotationDescriptor : annotationsToAdd) {
107 annotations.add(annotationDescriptor);
108 }
109 }
110
111 public void setModality(@NotNull Modality modality) {
112 this.modality = modality;
113 }
114
115 @Override
116 @NotNull
117 public Modality getModality() {
118 return modality;
119 }
120
121 @NotNull
122 @Override
123 public ClassKind getKind() {
124 return kind;
125 }
126
127 public void setVisibility(@NotNull Visibility visibility) {
128 this.visibility = visibility;
129 }
130
131 @NotNull
132 @Override
133 public Visibility getVisibility() {
134 return visibility;
135 }
136
137 @Override
138 public boolean isInner() {
139 return isInner;
140 }
141
142 @NotNull
143 @Override
144 public TypeConstructor getTypeConstructor() {
145 return typeConstructor;
146 }
147
148 @NotNull
149 public Collection<JetType> getSupertypes() {
150 return supertypes;
151 }
152
153 public void setSupertypes(@NotNull Collection<JetType> supertypes) {
154 this.supertypes = supertypes;
155 }
156
157 public void addSupertype(@NotNull JetType supertype) {
158 assert !supertype.isError() : "Error types must be filtered out in DescriptorResolver";
159 if (TypeUtils.getClassDescriptor(supertype) != null) {
160 // See the Errors.SUPERTYPE_NOT_A_CLASS_OR_TRAIT
161 supertypes.add(supertype);
162 }
163 }
164
165 public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor) {
166 assert primaryConstructor == null : "Primary constructor assigned twice " + this;
167 primaryConstructor = constructorDescriptor;
168
169 constructors.add(constructorDescriptor);
170
171 ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(new DelegatingType() {
172 @Override
173 protected JetType getDelegate() {
174 return getDefaultType();
175 }
176 });
177
178 if (constructorDescriptor.isPrimary()) {
179 setUpScopeForInitializers(constructorDescriptor);
180 }
181 }
182
183 public void addConstructorParametersToInitializersScope(@NotNull Collection<? extends VariableDescriptor> variables) {
184 WritableScope scope = getWritableScopeForInitializers();
185 for (VariableDescriptor variable : variables) {
186 scope.addVariableDescriptor(variable);
187 }
188 }
189
190 @NotNull
191 @Override
192 public Set<ConstructorDescriptor> getConstructors() {
193 return constructors;
194 }
195
196 @Override
197 @Nullable
198 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
199 return primaryConstructor;
200 }
201
202 @NotNull
203 public Set<SimpleFunctionDescriptor> getFunctions() {
204 return functions;
205 }
206
207 @NotNull
208 public Set<PropertyDescriptor> getProperties() {
209 return properties;
210 }
211
212 @Override
213 @NotNull
214 public Set<CallableMemberDescriptor> getDeclaredCallableMembers() {
215 return declaredCallableMembers;
216 }
217
218 @NotNull
219 public Set<CallableMemberDescriptor> getAllCallableMembers() {
220 return allCallableMembers;
221 }
222
223 public void setTypeParameterDescriptors(@NotNull List<TypeParameterDescriptor> typeParameters) {
224 if (this.typeParameters != null) {
225 throw new IllegalStateException("Type parameters are already set for " + getName());
226 }
227 this.typeParameters = new ArrayList<TypeParameterDescriptor>(typeParameters);
228 for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
229 scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor);
230 }
231 scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
232 }
233
234 public void createTypeConstructor() {
235 assert typeConstructor == null : typeConstructor;
236 this.typeConstructor = new TypeConstructorImpl(
237 this,
238 Annotations.EMPTY, // TODO : pass annotations from the class?
239 !getModality().isOverridable(),
240 getName().asString(),
241 typeParameters,
242 supertypes
243 );
244 for (FunctionDescriptor functionDescriptor : getConstructors()) {
245 ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
246 }
247 scopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter());
248 }
249
250 @Override
251 @NotNull
252 public JetScope getScopeForClassHeaderResolution() {
253 return scopeForSupertypeResolution;
254 }
255
256 @Override
257 @NotNull
258 public JetScope getScopeForMemberDeclarationResolution() {
259 return scopeForMemberResolution;
260 }
261
262 private WritableScope getWritableScopeForInitializers() {
263 if (scopeForInitializers == null) {
264 throw new IllegalStateException("Scope for initializers queried before the primary constructor is set");
265 }
266 return scopeForInitializers;
267 }
268
269 @Override
270 @NotNull
271 public JetScope getScopeForInitializerResolution() {
272 return getWritableScopeForInitializers();
273 }
274
275 private void setUpScopeForInitializers(@NotNull DeclarationDescriptor containingDeclaration) {
276 this.scopeForInitializers = new WritableScopeImpl(
277 scopeForMemberResolution, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Initializers")
278 .changeLockLevel(WritableScope.LockLevel.BOTH);
279 }
280
281 public void setScopeForMemberLookup(@NotNull JetScope scopeForMemberLookup) {
282 this.scopeForMemberLookup = scopeForMemberLookup;
283 }
284
285 @Override
286 @NotNull
287 public JetScope getScopeForMemberLookup() {
288 return scopeForMemberLookup;
289 }
290
291 @NotNull
292 private WritableScope getScopeForMemberLookupAsWritableScope() {
293 // hack
294 return (WritableScope) scopeForMemberLookup;
295 }
296
297 public void lockScopes() {
298 getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING);
299 if (classObjectDescriptor != null) {
300 classObjectDescriptor.lockScopes();
301 }
302 scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
303 scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING);
304 getWritableScopeForInitializers().changeLockLevel(WritableScope.LockLevel.READING);
305 }
306
307 private PackageLikeBuilder builder = null;
308
309 @NotNull
310 public PackageLikeBuilder getBuilder() {
311 if (builder == null) {
312 builder = new PackageLikeBuilder() {
313 @NotNull
314 @Override
315 public DeclarationDescriptor getOwnerForChildren() {
316 return MutableClassDescriptor.this;
317 }
318
319 @Override
320 public void addClassifierDescriptor(@NotNull MutableClassDescriptor classDescriptor) {
321 getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor);
322 scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
323 }
324
325 @Override
326 public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
327 getScopeForMemberLookupAsWritableScope().addFunctionDescriptor(functionDescriptor);
328 functions.add(functionDescriptor);
329 if (functionDescriptor.getKind().isReal()) {
330 declaredCallableMembers.add(functionDescriptor);
331 }
332 allCallableMembers.add(functionDescriptor);
333 scopeForMemberResolution.addFunctionDescriptor(functionDescriptor);
334 }
335
336 @Override
337 public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
338 if (getKind() == ClassKind.CLASS_OBJECT || isInner()) {
339 return ClassObjectStatus.NOT_ALLOWED;
340 }
341
342 if (MutableClassDescriptor.this.classObjectDescriptor != null) {
343 return ClassObjectStatus.DUPLICATE;
344 }
345
346 assert classObjectDescriptor.getKind() == ClassKind.CLASS_OBJECT;
347 MutableClassDescriptor.this.classObjectDescriptor = classObjectDescriptor;
348
349 // Members of the class object are accessible from the class
350 // The scope must be lazy, because classObjectDescriptor may not by fully built yet
351 scopeForMemberResolution.importScope(new ClassObjectMixinScope(classObjectDescriptor));
352
353 return ClassObjectStatus.OK;
354 }
355
356 @Override
357 public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
358 getScopeForMemberLookupAsWritableScope().addPropertyDescriptor(propertyDescriptor);
359 properties.add(propertyDescriptor);
360 if (propertyDescriptor.getKind().isReal()) {
361 declaredCallableMembers.add(propertyDescriptor);
362 }
363 allCallableMembers.add(propertyDescriptor);
364 scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor);
365 }
366 };
367 }
368
369 return builder;
370 }
371
372 @Override
373 public String toString() {
374 return DeclarationDescriptorImpl.toString(this);
375 }
376 }