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.descriptors.serialization.descriptors;
018
019 import jet.Function0;
020 import jet.Function1;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.jet.descriptors.serialization.*;
024 import org.jetbrains.jet.lang.descriptors.*;
025 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
026 import org.jetbrains.jet.lang.descriptors.impl.*;
027 import org.jetbrains.jet.lang.resolve.DescriptorFactory;
028 import org.jetbrains.jet.lang.resolve.OverridingUtil;
029 import org.jetbrains.jet.lang.resolve.name.Name;
030 import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
031 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
032 import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
033 import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
034 import org.jetbrains.jet.lang.types.ErrorUtils;
035 import org.jetbrains.jet.lang.types.JetType;
036 import org.jetbrains.jet.lang.types.TypeConstructor;
037 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
038 import org.jetbrains.jet.storage.MemoizedFunctionToNullable;
039 import org.jetbrains.jet.storage.NotNullLazyValue;
040 import org.jetbrains.jet.storage.NullableLazyValue;
041 import org.jetbrains.jet.storage.StorageManager;
042
043 import java.util.*;
044
045 import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
046 import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
047 import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName;
048
049 public class DeserializedClassDescriptor extends AbstractClassDescriptor implements ClassDescriptor {
050
051 private final ClassId classId;
052 private final ProtoBuf.Class classProto;
053 private final TypeDeserializer typeDeserializer;
054 private final DescriptorDeserializer deserializer;
055 private final DeserializedMemberScope memberScope;
056 private final ReceiverParameterDescriptor thisAsReceiverParameter;
057
058 private final NullableLazyValue<ConstructorDescriptor> primaryConstructor;
059
060 private final AnnotationDeserializer annotationDeserializer;
061 private final NotNullLazyValue<List<AnnotationDescriptor>> annotations;
062
063 private final NullableLazyValue<ClassDescriptor> classObjectDescriptor;
064
065 private final NestedClassDescriptors nestedClasses;
066 private final NestedClassDescriptors nestedObjects;
067
068 private final NotNullLazyValue<DeclarationDescriptor> containingDeclaration;
069 private final DeserializedClassTypeConstructor typeConstructor;
070 private final Modality modality;
071 private final Visibility visibility;
072 private final ClassKind kind;
073 private final boolean isInner;
074 private final InnerClassesScopeWrapper innerClassesScope;
075 private final DescriptorFinder descriptorFinder;
076
077 public DeserializedClassDescriptor(
078 @NotNull StorageManager storageManager,
079 @NotNull AnnotationDeserializer annotationResolver,
080 @NotNull DescriptorFinder descriptorFinder,
081 @NotNull ClassData classData
082 ) {
083 super(classData.getNameResolver().getClassId(classData.getClassProto().getFqName()).getRelativeClassName().shortName());
084 NameResolver nameResolver = classData.getNameResolver();
085 this.classProto = classData.getClassProto();
086
087 this.classId = nameResolver.getClassId(classProto.getFqName());
088 this.descriptorFinder = descriptorFinder;
089
090 TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver,
091 descriptorFinder, "Deserializer for class " + name, NONE);
092 DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(storageManager, notNullTypeDeserializer,
093 this, nameResolver, annotationResolver);
094 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount());
095 this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParameterList(), typeParameters);
096 this.typeDeserializer = deserializer.getTypeDeserializer();
097
098 this.containingDeclaration = storageManager.createLazyValue(new Function0<DeclarationDescriptor>() {
099 @Override
100 public DeclarationDescriptor invoke() {
101 return computeContainingDeclaration();
102 }
103 });
104
105 this.typeConstructor = new DeserializedClassTypeConstructor(typeParameters);
106 this.memberScope = new DeserializedClassMemberScope(storageManager, this);
107 this.innerClassesScope = new InnerClassesScopeWrapper(memberScope);
108 this.thisAsReceiverParameter = new LazyClassReceiverParameterDescriptor();
109
110 int flags = classProto.getFlags();
111 this.modality = DescriptorDeserializer.modality(Flags.MODALITY.get(flags));
112 this.visibility = DescriptorDeserializer.visibility(Flags.VISIBILITY.get(flags));
113 this.kind = DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(flags));
114 this.isInner = Flags.INNER.get(flags);
115
116 this.annotationDeserializer = annotationResolver;
117 this.annotations = storageManager.createLazyValue(new Function0<List<AnnotationDescriptor>>() {
118 @Override
119 public List<AnnotationDescriptor> invoke() {
120 return computeAnnotations();
121 }
122 });
123
124 this.primaryConstructor = storageManager.createNullableLazyValue(new Function0<ConstructorDescriptor>() {
125 @Override
126 public ConstructorDescriptor invoke() {
127 return computePrimaryConstructor();
128 }
129 });
130
131 this.classObjectDescriptor = storageManager.createNullableLazyValue(new Function0<ClassDescriptor>() {
132 @Override
133 public ClassDescriptor invoke() {
134 return computeClassObjectDescriptor();
135 }
136 });
137 this.nestedClasses = new NestedClassDescriptors(storageManager, names(classProto.getNestedClassNameList(), nameResolver));
138 this.nestedObjects = new NestedClassDescriptors(storageManager, names(classProto.getNestedObjectNameList(), nameResolver));
139 }
140
141 @NotNull
142 private static Set<Name> names(@NotNull List<Integer> nameIndices, @NotNull NameResolver nameResolver) {
143 Set<Name> result = new HashSet<Name>(nameIndices.size());
144 for (Integer index : nameIndices) {
145 result.add(nameResolver.getName(index));
146 }
147 return result;
148 }
149
150 @NotNull
151 @Override
152 public DeclarationDescriptor getContainingDeclaration() {
153 return containingDeclaration.invoke();
154 }
155
156 @NotNull
157 private DeclarationDescriptor computeContainingDeclaration() {
158 ClassOrNamespaceDescriptor result = classId.isTopLevelClass() ?
159 descriptorFinder.findPackage(classId.getPackageFqName()) :
160 descriptorFinder.findClass(classId.getOuterClassId());
161 return result != null ? result : ErrorUtils.getErrorModule();
162 }
163
164 @NotNull
165 @Override
166 public TypeConstructor getTypeConstructor() {
167 return typeConstructor;
168 }
169
170
171 @NotNull
172 @Override
173 public ClassKind getKind() {
174 return kind;
175 }
176
177 @NotNull
178 @Override
179 public Modality getModality() {
180 return modality;
181 }
182
183 @NotNull
184 @Override
185 public Visibility getVisibility() {
186 return visibility;
187 }
188
189 @Override
190 public boolean isInner() {
191 return isInner;
192 }
193
194 private List<AnnotationDescriptor> computeAnnotations() {
195 if (!Flags.HAS_ANNOTATIONS.get(classProto.getFlags())) {
196 return Collections.emptyList();
197 }
198 return annotationDeserializer.loadClassAnnotations(this, classProto);
199 }
200
201 @Override
202 public List<AnnotationDescriptor> getAnnotations() {
203 return annotations.invoke();
204 }
205
206 @Override
207 protected JetScope getScopeForMemberLookup() {
208 return memberScope;
209 }
210
211 @NotNull
212 @Override
213 public JetScope getUnsubstitutedInnerClassesScope() {
214 return innerClassesScope;
215 }
216
217 @Nullable
218 private ConstructorDescriptor computePrimaryConstructor() {
219 if (!classProto.hasPrimaryConstructor()) return null;
220
221 ProtoBuf.Callable constructorProto = classProto.getPrimaryConstructor();
222 return (ConstructorDescriptor) deserializer.loadCallable(constructorProto);
223 }
224
225 @Nullable
226 @Override
227 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
228 return primaryConstructor.invoke();
229 }
230
231 @NotNull
232 @Override
233 public Collection<ConstructorDescriptor> getConstructors() {
234 ConstructorDescriptor constructor = getUnsubstitutedPrimaryConstructor();
235 if (constructor == null) {
236 return Collections.emptyList();
237 }
238 // TODO: other constructors
239 return Collections.singletonList(constructor);
240 }
241
242 @Nullable
243 @Override
244 public JetType getClassObjectType() {
245 ClassDescriptor classObjectDescriptor = getClassObjectDescriptor();
246 return classObjectDescriptor == null ? null : classObjectDescriptor.getDefaultType();
247 }
248
249 @Nullable
250 private ClassDescriptor computeClassObjectDescriptor() {
251 if (!classProto.getClassObjectPresent()) {
252 return null;
253 }
254
255 if (getKind() == ClassKind.ENUM_CLASS) {
256 MutableClassDescriptor classObject = createEnumClassObject();
257
258 for (int enumEntry : classProto.getEnumEntryList()) {
259 createEnumEntry(classObject, deserializer.getNameResolver().getName(enumEntry));
260 }
261
262 return classObject;
263 }
264
265 return descriptorFinder.findClass(classId.createNestedClassId(getClassObjectName(getName())));
266 }
267
268 @NotNull
269 private MutableClassDescriptor createEnumClassObject() {
270 MutableClassDescriptor classObject = new MutableClassDescriptor(this, getScopeForMemberLookup(), ClassKind.CLASS_OBJECT,
271 false, getClassObjectName(getName()));
272 classObject.setModality(Modality.FINAL);
273 classObject.setVisibility(getVisibility());
274 classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
275 classObject.createTypeConstructor();
276
277 ConstructorDescriptorImpl primaryConstructor = DescriptorFactory.createPrimaryConstructorForObject(classObject);
278 primaryConstructor.setReturnType(classObject.getDefaultType());
279 classObject.setPrimaryConstructor(primaryConstructor);
280
281 JetType defaultType = getDefaultType();
282 JetType defaultTypeArray = KotlinBuiltIns.getInstance().getArrayType(defaultType);
283 classObject.getBuilder().addFunctionDescriptor(
284 DescriptorFactory.createEnumClassObjectValuesMethod(classObject, defaultTypeArray));
285 classObject.getBuilder().addFunctionDescriptor(
286 DescriptorFactory.createEnumClassObjectValueOfMethod(classObject, defaultType));
287
288 return classObject;
289 }
290
291 private void createEnumEntry(@NotNull MutableClassDescriptor enumClassObject, @NotNull Name name) {
292 PropertyDescriptorImpl property = new PropertyDescriptorForObjectImpl(enumClassObject,
293 Collections.<AnnotationDescriptor>emptyList(),
294 Visibilities.PUBLIC, name, this);
295 property.setType(getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(),
296 enumClassObject.getThisAsReceiverParameter(), NO_RECEIVER_PARAMETER);
297
298 PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(property);
299 getter.initialize(property.getReturnType());
300 property.initialize(getter, null);
301
302 enumClassObject.getBuilder().addPropertyDescriptor(property);
303 }
304
305 @Nullable
306 @Override
307 public ClassDescriptor getClassObjectDescriptor() {
308 return classObjectDescriptor.invoke();
309 }
310
311 @NotNull
312 @Override
313 public ReceiverParameterDescriptor getThisAsReceiverParameter() {
314 return thisAsReceiverParameter;
315 }
316
317 private Collection<JetType> computeSuperTypes() {
318 List<JetType> supertypes = new ArrayList<JetType>(classProto.getSupertypeCount());
319 for (ProtoBuf.Type supertype : classProto.getSupertypeList()) {
320 supertypes.add(typeDeserializer.type(supertype));
321 }
322 return supertypes;
323 }
324
325 @Override
326 public String toString() {
327 return "deserialized class " + getName().toString();
328 }
329
330 private class DeserializedClassTypeConstructor implements TypeConstructor {
331 private final Collection<JetType> supertypes = computeSuperTypes();
332 private final List<TypeParameterDescriptor> parameters;
333
334 public DeserializedClassTypeConstructor(@NotNull List<TypeParameterDescriptor> typeParameters) {
335 parameters = typeParameters;
336 }
337
338 @NotNull
339 @Override
340 public List<TypeParameterDescriptor> getParameters() {
341 return parameters;
342 }
343
344 @NotNull
345 @Override
346 public Collection<JetType> getSupertypes() {
347 return supertypes;
348 }
349
350 @Override
351 public boolean isFinal() {
352 return !getModality().isOverridable();
353 }
354
355 @Override
356 public boolean isDenotable() {
357 return true;
358 }
359
360 @Nullable
361 @Override
362 public ClassifierDescriptor getDeclarationDescriptor() {
363 return DeserializedClassDescriptor.this;
364 }
365
366 @Override
367 public List<AnnotationDescriptor> getAnnotations() {
368 return Collections.emptyList(); // TODO
369 }
370
371 @Override
372 public String toString() {
373 return getName().toString();
374 }
375 }
376
377 private static class DeserializedClassMemberScope extends DeserializedMemberScope {
378 private final DeserializedClassDescriptor classDescriptor;
379
380 public DeserializedClassMemberScope(@NotNull StorageManager storageManager, @NotNull DeserializedClassDescriptor classDescriptor) {
381 super(storageManager, classDescriptor, classDescriptor.deserializer, classDescriptor.classProto.getMemberList());
382 this.classDescriptor = classDescriptor;
383 }
384
385 @Override
386 protected void computeNonDeclaredFunctions(
387 @NotNull Name name, @NotNull Collection<FunctionDescriptor> functions
388 ) {
389 Collection<FunctionDescriptor> fromSupertypes = new ArrayList<FunctionDescriptor>();
390 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
391 fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
392 }
393 generateFakeOverrides(name, fromSupertypes, functions);
394 }
395
396 @Override
397 protected void computeNonDeclaredProperties(
398 @NotNull Name name, @NotNull Collection<PropertyDescriptor> property
399 ) {
400 Collection<PropertyDescriptor> fromSupertypes = new ArrayList<PropertyDescriptor>();
401 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
402 //noinspection unchecked
403 fromSupertypes.addAll((Collection) supertype.getMemberScope().getProperties(name));
404 }
405 generateFakeOverrides(name, fromSupertypes, property);
406 }
407
408 private <D extends CallableMemberDescriptor> void generateFakeOverrides(
409 @NotNull Name name,
410 @NotNull Collection<D> fromSupertypes,
411 @NotNull final Collection<D> result
412 ) {
413 List<CallableMemberDescriptor> fromCurrent = new ArrayList<CallableMemberDescriptor>(result);
414 OverridingUtil.generateOverridesInFunctionGroup(
415 name,
416 fromSupertypes,
417 fromCurrent,
418 classDescriptor,
419 new OverridingUtil.DescriptorSink() {
420 @Override
421 public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
422 OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new OverridingUtil.NotInferredVisibilitySink() {
423 @Override
424 public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
425 // Do nothing
426 // TODO: do something
427 }
428 });
429 //noinspection unchecked
430 result.add((D) fakeOverride);
431 }
432
433 @Override
434 public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
435 // TODO report conflicts
436 }
437 }
438 );
439 }
440
441 @Override
442 protected void addNonDeclaredDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
443 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
444 for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
445 if (descriptor instanceof FunctionDescriptor) {
446 result.addAll(getFunctions(descriptor.getName()));
447 }
448 else if (descriptor instanceof PropertyDescriptor) {
449 result.addAll(getProperties(descriptor.getName()));
450 }
451 // Nothing else is inherited
452 }
453 }
454 }
455
456 @Nullable
457 @Override
458 protected ReceiverParameterDescriptor getImplicitReceiver() {
459 return classDescriptor.getThisAsReceiverParameter();
460 }
461
462 @Nullable
463 @Override
464 protected ClassifierDescriptor getClassDescriptor(@NotNull Name name) {
465 return classDescriptor.nestedClasses.findClass.invoke(name);
466 }
467
468 @Override
469 protected void addAllClassDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
470 result.addAll(classDescriptor.nestedClasses.getAllDescriptors());
471 }
472
473 @Nullable
474 @Override
475 public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
476 return classDescriptor.nestedObjects.findClass.invoke(name);
477 }
478
479 @NotNull
480 @Override
481 protected Collection<ClassDescriptor> computeAllObjectDescriptors() {
482 return classDescriptor.nestedObjects.getAllDescriptors();
483 }
484 }
485
486 private class NestedClassDescriptors {
487 private final Set<Name> declaredNames;
488 private final MemoizedFunctionToNullable<Name, ClassDescriptor> findClass;
489
490 public NestedClassDescriptors(@NotNull StorageManager storageManager, @NotNull Set<Name> declaredNames) {
491 this.declaredNames = declaredNames;
492 this.findClass = storageManager.createMemoizedFunctionWithNullableValues(new Function1<Name, ClassDescriptor>() {
493 @Override
494 public ClassDescriptor invoke(Name name) {
495 return NestedClassDescriptors.this.declaredNames.contains(name) ?
496 descriptorFinder.findClass(classId.createNestedClassId(name)) :
497 null;
498 }
499 });
500 }
501
502 @NotNull
503 public Collection<ClassDescriptor> getAllDescriptors() {
504 Collection<ClassDescriptor> result = new ArrayList<ClassDescriptor>(declaredNames.size());
505 for (Name name : declaredNames) {
506 ClassDescriptor descriptor = findClass.invoke(name);
507 if (descriptor != null) {
508 result.add(descriptor);
509 }
510 }
511 return result;
512 }
513 }
514
515 private class LazyClassReceiverParameterDescriptor extends AbstractReceiverParameterDescriptor {
516 private final ClassReceiver classReceiver = new ClassReceiver(DeserializedClassDescriptor.this);
517
518 @NotNull
519 @Override
520 public JetType getType() {
521 return getDefaultType();
522 }
523
524 @NotNull
525 @Override
526 public ReceiverValue getValue() {
527 return classReceiver;
528 }
529
530 @NotNull
531 @Override
532 public DeclarationDescriptor getContainingDeclaration() {
533 return DeserializedClassDescriptor.this;
534 }
535 }
536 }
537