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