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