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 kotlin.Function0;
020 import kotlin.Function1;
021 import kotlin.KotlinPackage;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.annotations.Nullable;
024 import org.jetbrains.jet.descriptors.serialization.*;
025 import org.jetbrains.jet.lang.descriptors.*;
026 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
027 import org.jetbrains.jet.lang.descriptors.impl.AbstractClassDescriptor;
028 import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
029 import org.jetbrains.jet.lang.descriptors.impl.EnumEntrySyntheticClassDescriptor;
030 import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
031 import org.jetbrains.jet.lang.resolve.DescriptorFactory;
032 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
033 import org.jetbrains.jet.lang.resolve.OverridingUtil;
034 import org.jetbrains.jet.lang.resolve.name.Name;
035 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
036 import org.jetbrains.jet.lang.types.ErrorUtils;
037 import org.jetbrains.jet.lang.types.JetType;
038 import org.jetbrains.jet.lang.types.TypeConstructor;
039 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
040 import org.jetbrains.jet.storage.MemoizedFunctionToNullable;
041 import org.jetbrains.jet.storage.NotNullLazyValue;
042 import org.jetbrains.jet.storage.NullableLazyValue;
043 import org.jetbrains.jet.storage.StorageManager;
044
045 import java.util.*;
046
047 import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
048 import static org.jetbrains.jet.lang.resolve.name.SpecialNames.getClassObjectName;
049
050 public class DeserializedClassDescriptor extends AbstractClassDescriptor implements ClassDescriptor {
051
052 private final ClassId classId;
053 private final ProtoBuf.Class classProto;
054 private final StorageManager storageManager;
055 private final TypeDeserializer typeDeserializer;
056 private final DescriptorDeserializer deserializer;
057 private final DeserializedMemberScope memberScope;
058
059 private final NullableLazyValue<ConstructorDescriptor> primaryConstructor;
060
061 private final AnnotationDeserializer annotationDeserializer;
062 private final NotNullLazyValue<Annotations> annotations;
063
064 private final NullableLazyValue<ClassDescriptor> classObjectDescriptor;
065
066 private final NestedClassDescriptors nestedClasses;
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 DescriptorFinder descriptorFinder;
075 private final PackageFragmentProvider packageFragmentProvider;
076
077 public DeserializedClassDescriptor(
078 @NotNull StorageManager storageManager,
079 @NotNull AnnotationDeserializer annotationResolver,
080 @NotNull DescriptorFinder descriptorFinder,
081 @NotNull PackageFragmentProvider packageFragmentProvider,
082 @NotNull NameResolver nameResolver,
083 @NotNull ProtoBuf.Class classProto
084 ) {
085 super(storageManager, nameResolver.getClassId(classProto.getFqName()).getRelativeClassName().shortName());
086 this.classProto = classProto;
087 this.classId = nameResolver.getClassId(classProto.getFqName());
088 this.storageManager = storageManager;
089 this.packageFragmentProvider = packageFragmentProvider;
090 this.descriptorFinder = descriptorFinder;
091
092 TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver,
093 descriptorFinder, "Deserializer for class " + getName(), NONE);
094 DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(storageManager, notNullTypeDeserializer,
095 this, nameResolver, annotationResolver);
096 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount());
097 this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParameterList(), typeParameters);
098 this.typeDeserializer = deserializer.getTypeDeserializer();
099
100 this.containingDeclaration = storageManager.createLazyValue(new Function0<DeclarationDescriptor>() {
101 @Override
102 public DeclarationDescriptor invoke() {
103 return computeContainingDeclaration();
104 }
105 });
106
107 this.typeConstructor = new DeserializedClassTypeConstructor(typeParameters);
108 this.memberScope = new DeserializedClassMemberScope(storageManager, this);
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<Annotations>() {
118 @Override
119 public Annotations 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
138 this.nestedClasses = new NestedClassDescriptors();
139 }
140
141 @NotNull
142 @Override
143 public DeclarationDescriptor getContainingDeclaration() {
144 return containingDeclaration.invoke();
145 }
146
147 @NotNull
148 private DeclarationDescriptor computeContainingDeclaration() {
149 if (classId.isTopLevelClass()) {
150 List<PackageFragmentDescriptor> fragments = packageFragmentProvider.getPackageFragments(classId.getPackageFqName());
151 assert fragments.size() == 1 : "there should be exactly one package: " + fragments;
152 return fragments.iterator().next();
153 }
154 else {
155 ClassOrPackageFragmentDescriptor result = descriptorFinder.findClass(classId.getOuterClassId());
156 return result != null ? result : ErrorUtils.getErrorModule();
157 }
158 }
159
160 @NotNull
161 @Override
162 public TypeConstructor getTypeConstructor() {
163 return typeConstructor;
164 }
165
166
167 @NotNull
168 @Override
169 public ClassKind getKind() {
170 return kind;
171 }
172
173 @NotNull
174 @Override
175 public Modality getModality() {
176 return modality;
177 }
178
179 @NotNull
180 @Override
181 public Visibility getVisibility() {
182 return visibility;
183 }
184
185 @Override
186 public boolean isInner() {
187 return isInner;
188 }
189
190 private Annotations computeAnnotations() {
191 if (!Flags.HAS_ANNOTATIONS.get(classProto.getFlags())) {
192 return Annotations.EMPTY;
193 }
194 return annotationDeserializer.loadClassAnnotations(this, classProto);
195 }
196
197 @NotNull
198 @Override
199 public Annotations getAnnotations() {
200 return annotations.invoke();
201 }
202
203 @NotNull
204 @Override
205 protected JetScope getScopeForMemberLookup() {
206 return memberScope;
207 }
208
209 @Nullable
210 private ConstructorDescriptor computePrimaryConstructor() {
211 if (!classProto.hasPrimaryConstructor()) return null;
212
213 ProtoBuf.Class.PrimaryConstructor constructorProto = classProto.getPrimaryConstructor();
214 if (!constructorProto.hasData()) {
215 ConstructorDescriptorImpl descriptor = DescriptorFactory.createPrimaryConstructorForObject(this);
216 descriptor.setReturnType(getDefaultType());
217 return descriptor;
218 }
219
220 return (ConstructorDescriptor) deserializer.loadCallable(constructorProto.getData());
221 }
222
223 @Nullable
224 @Override
225 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
226 return primaryConstructor.invoke();
227 }
228
229 @NotNull
230 @Override
231 public Collection<ConstructorDescriptor> getConstructors() {
232 ConstructorDescriptor constructor = getUnsubstitutedPrimaryConstructor();
233 if (constructor == null) {
234 return Collections.emptyList();
235 }
236 // TODO: other constructors
237 return Collections.singletonList(constructor);
238 }
239
240 @Nullable
241 private ClassDescriptor computeClassObjectDescriptor() {
242 if (!classProto.hasClassObject()) {
243 return null;
244 }
245
246 if (getKind() == ClassKind.ENUM_CLASS) {
247 return createEnumClassObject();
248 }
249
250 if (getKind() == ClassKind.OBJECT) {
251 ProtoBuf.Class.ClassObject classObjectProto = classProto.getClassObject();
252 if (!classObjectProto.hasData()) {
253 throw new IllegalStateException("Object should have a serialized class object: " + classId);
254 }
255
256 return new DeserializedClassDescriptor(storageManager, annotationDeserializer, descriptorFinder, packageFragmentProvider,
257 deserializer.getNameResolver(), classObjectProto.getData());
258 }
259
260 return descriptorFinder.findClass(classId.createNestedClassId(getClassObjectName(getName())));
261 }
262
263 @NotNull
264 private ClassDescriptorWithResolutionScopes createEnumClassObject() {
265 final MutableClassDescriptor classObject = new MutableClassDescriptor(this, getScopeForMemberLookup(), ClassKind.CLASS_OBJECT,
266 false, getClassObjectName(getName()));
267 JetType supertype = KotlinBuiltIns.getInstance().getAnyType();
268 classObject.setSupertypes(Collections.singleton(supertype));
269 classObject.setModality(Modality.FINAL);
270 classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility());
271 classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
272 classObject.setPrimaryConstructor(DescriptorFactory.createPrimaryConstructorForObject(classObject));
273 classObject.createTypeConstructor();
274
275 JetType enumType = getDefaultType();
276 JetType enumArrayType = KotlinBuiltIns.getInstance().getArrayType(enumType);
277 classObject.getBuilder().addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValuesMethod(classObject, enumArrayType));
278 classObject.getBuilder().addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValueOfMethod(classObject, enumType));
279
280 OverridingUtil.DescriptorSink sink = new OverridingUtil.DescriptorSink() {
281 @Override
282 public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
283 OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new OverridingUtil.NotInferredVisibilitySink() {
284 @Override
285 public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
286 throw new IllegalStateException("Cannot infer visibility for " + descriptor + " in " + classObject);
287 }
288 });
289 classObject.getBuilder().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
290 }
291
292 @Override
293 public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
294 throw new IllegalStateException("Conflict on enum class object override: " + fromSuper + " vs " + fromCurrent);
295 }
296 };
297
298 JetScope superScope = supertype.getMemberScope();
299
300 for (DeclarationDescriptor descriptor : superScope.getAllDescriptors()) {
301 if (descriptor instanceof FunctionDescriptor) {
302 Name name = descriptor.getName();
303 OverridingUtil.generateOverridesInFunctionGroup(name, superScope.getFunctions(name),
304 Collections.<FunctionDescriptor>emptySet(), classObject, sink);
305 }
306 }
307
308 return classObject;
309 }
310
311 @Nullable
312 @Override
313 public ClassDescriptor getClassObjectDescriptor() {
314 return classObjectDescriptor.invoke();
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 // not using descriptor render to preserve laziness
328 return "deserialized class " + getName().toString();
329 }
330
331 private class DeserializedClassTypeConstructor implements TypeConstructor {
332 private final Collection<JetType> supertypes = computeSuperTypes();
333 private final List<TypeParameterDescriptor> parameters;
334
335 public DeserializedClassTypeConstructor(@NotNull List<TypeParameterDescriptor> typeParameters) {
336 parameters = typeParameters;
337 }
338
339 @NotNull
340 @Override
341 public List<TypeParameterDescriptor> getParameters() {
342 return parameters;
343 }
344
345 @NotNull
346 @Override
347 public Collection<JetType> getSupertypes() {
348 // We cannot have error supertypes because subclasses inherit error functions from them
349 // Filtering right away means copying the list every time, so we check for the rare condition first, and only then filter
350 for (JetType supertype : supertypes) {
351 if (supertype.isError()) {
352 return KotlinPackage.filter(supertypes, new Function1<JetType, Boolean>() {
353 @Override
354 public Boolean invoke(JetType type) {
355 return !type.isError();
356 }
357 });
358 }
359 }
360 return supertypes;
361 }
362
363 @Override
364 public boolean isFinal() {
365 return !getModality().isOverridable();
366 }
367
368 @Override
369 public boolean isDenotable() {
370 return true;
371 }
372
373 @Nullable
374 @Override
375 public ClassifierDescriptor getDeclarationDescriptor() {
376 return DeserializedClassDescriptor.this;
377 }
378
379 @NotNull
380 @Override
381 public Annotations getAnnotations() {
382 return Annotations.EMPTY; // TODO
383 }
384
385 @Override
386 public String toString() {
387 return getName().toString();
388 }
389 }
390
391 private static class DeserializedClassMemberScope extends DeserializedMemberScope {
392 private final DeserializedClassDescriptor classDescriptor;
393
394 public DeserializedClassMemberScope(@NotNull StorageManager storageManager, @NotNull DeserializedClassDescriptor classDescriptor) {
395 super(storageManager, classDescriptor, classDescriptor.deserializer, classDescriptor.classProto.getMemberList());
396 this.classDescriptor = classDescriptor;
397 }
398
399 @Override
400 protected void computeNonDeclaredFunctions(
401 @NotNull Name name, @NotNull Collection<FunctionDescriptor> functions
402 ) {
403 Collection<FunctionDescriptor> fromSupertypes = new ArrayList<FunctionDescriptor>();
404 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
405 fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
406 }
407 generateFakeOverrides(name, fromSupertypes, functions);
408 }
409
410 @Override
411 protected void computeNonDeclaredProperties(
412 @NotNull Name name, @NotNull Collection<PropertyDescriptor> property
413 ) {
414 Collection<PropertyDescriptor> fromSupertypes = new ArrayList<PropertyDescriptor>();
415 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
416 //noinspection unchecked
417 fromSupertypes.addAll((Collection) supertype.getMemberScope().getProperties(name));
418 }
419 generateFakeOverrides(name, fromSupertypes, property);
420 }
421
422 private <D extends CallableMemberDescriptor> void generateFakeOverrides(
423 @NotNull Name name,
424 @NotNull Collection<D> fromSupertypes,
425 @NotNull final Collection<D> result
426 ) {
427 List<CallableMemberDescriptor> fromCurrent = new ArrayList<CallableMemberDescriptor>(result);
428 OverridingUtil.generateOverridesInFunctionGroup(
429 name,
430 fromSupertypes,
431 fromCurrent,
432 classDescriptor,
433 new OverridingUtil.DescriptorSink() {
434 @Override
435 public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
436 OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new OverridingUtil.NotInferredVisibilitySink() {
437 @Override
438 public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
439 // Do nothing
440 // TODO: do something
441 }
442 });
443 //noinspection unchecked
444 result.add((D) fakeOverride);
445 }
446
447 @Override
448 public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
449 // TODO report conflicts
450 }
451 }
452 );
453 }
454
455 @Override
456 protected void addNonDeclaredDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
457 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
458 for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
459 if (descriptor instanceof FunctionDescriptor) {
460 result.addAll(getFunctions(descriptor.getName()));
461 }
462 else if (descriptor instanceof PropertyDescriptor) {
463 result.addAll(getProperties(descriptor.getName()));
464 }
465 // Nothing else is inherited
466 }
467 }
468 }
469
470 @Nullable
471 @Override
472 protected ReceiverParameterDescriptor getImplicitReceiver() {
473 return classDescriptor.getThisAsReceiverParameter();
474 }
475
476 @Nullable
477 @Override
478 protected ClassifierDescriptor getClassDescriptor(@NotNull Name name) {
479 return classDescriptor.nestedClasses.findClass.invoke(name);
480 }
481
482 @Override
483 protected void addAllClassDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
484 result.addAll(classDescriptor.nestedClasses.getAllDescriptors());
485 }
486 }
487
488 private class NestedClassDescriptors {
489 private final Set<Name> nestedClassNames;
490 private final MemoizedFunctionToNullable<Name, ClassDescriptor> findClass;
491 private final Set<Name> enumEntryNames;
492
493 public NestedClassDescriptors() {
494 this.nestedClassNames = nestedClassNames();
495 this.enumEntryNames = enumEntryNames();
496
497 final NotNullLazyValue<Collection<Name>> enumMemberNames = storageManager.createLazyValue(new Function0<Collection<Name>>() {
498 @Override
499 public Collection<Name> invoke() {
500 return computeEnumMemberNames();
501 }
502 });
503
504 this.findClass = storageManager.createMemoizedFunctionWithNullableValues(new Function1<Name, ClassDescriptor>() {
505 @Override
506 public ClassDescriptor invoke(Name name) {
507 if (enumEntryNames.contains(name)) {
508 return EnumEntrySyntheticClassDescriptor
509 .create(storageManager, DeserializedClassDescriptor.this, name, enumMemberNames);
510 }
511 if (nestedClassNames.contains(name)) {
512 return descriptorFinder.findClass(classId.createNestedClassId(name));
513 }
514 return null;
515 }
516 });
517 }
518
519 @NotNull
520 private Set<Name> nestedClassNames() {
521 Set<Name> result = new HashSet<Name>();
522 NameResolver nameResolver = deserializer.getNameResolver();
523 for (Integer index : classProto.getNestedClassNameList()) {
524 result.add(nameResolver.getName(index));
525 }
526 return result;
527 }
528
529 @NotNull
530 private Set<Name> enumEntryNames() {
531 if (getKind() != ClassKind.ENUM_CLASS) {
532 return Collections.emptySet();
533 }
534
535 Set<Name> result = new HashSet<Name>();
536 NameResolver nameResolver = deserializer.getNameResolver();
537 for (Integer index : classProto.getEnumEntryList()) {
538 result.add(nameResolver.getName(index));
539 }
540 return result;
541 }
542
543 @NotNull
544 private Collection<Name> computeEnumMemberNames() {
545 Collection<Name> result = new HashSet<Name>();
546
547 for (JetType supertype : getTypeConstructor().getSupertypes()) {
548 for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
549 if (descriptor instanceof SimpleFunctionDescriptor || descriptor instanceof PropertyDescriptor) {
550 result.add(descriptor.getName());
551 }
552 }
553 }
554
555 final NameResolver nameResolver = deserializer.getNameResolver();
556 return KotlinPackage.mapTo(classProto.getMemberList(), result, new Function1<ProtoBuf.Callable, Name>() {
557 @Override
558 public Name invoke(@NotNull ProtoBuf.Callable callable) {
559 return nameResolver.getName(callable.getName());
560 }
561 });
562 }
563
564 @NotNull
565 public Collection<ClassDescriptor> getAllDescriptors() {
566 Collection<ClassDescriptor> result = new ArrayList<ClassDescriptor>(nestedClassNames.size() + enumEntryNames.size());
567 for (Name name : nestedClassNames) {
568 ClassDescriptor descriptor = findClass.invoke(name);
569 if (descriptor != null) {
570 result.add(descriptor);
571 }
572 }
573 for (Name name : enumEntryNames) {
574 ClassDescriptor descriptor = findClass.invoke(name);
575 if (descriptor != null) {
576 result.add(descriptor);
577 }
578 }
579 return result;
580 }
581 }
582 }