001 /*
002 * Copyright 2010-2014 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.resolve.lazy.descriptors;
018
019 import com.google.common.base.Predicate;
020 import com.google.common.collect.Collections2;
021 import com.google.common.collect.Lists;
022 import com.intellij.psi.PsiElement;
023 import kotlin.Function0;
024 import kotlin.Function1;
025 import kotlin.KotlinPackage;
026 import kotlin.Unit;
027 import org.jetbrains.annotations.Mutable;
028 import org.jetbrains.annotations.NotNull;
029 import org.jetbrains.annotations.Nullable;
030 import org.jetbrains.annotations.ReadOnly;
031 import org.jetbrains.jet.lang.descriptors.*;
032 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
033 import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorBase;
034 import org.jetbrains.jet.lang.psi.*;
035 import org.jetbrains.jet.lang.resolve.BindingContext;
036 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
037 import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
038 import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil;
039 import org.jetbrains.jet.lang.resolve.lazy.LazyEntity;
040 import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
041 import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider;
042 import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
043 import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
044 import org.jetbrains.jet.lang.resolve.lazy.data.SyntheticClassObjectInfo;
045 import org.jetbrains.jet.lang.resolve.lazy.declarations.ClassMemberDeclarationProvider;
046 import org.jetbrains.jet.lang.resolve.name.Name;
047 import org.jetbrains.jet.lang.resolve.scopes.*;
048 import org.jetbrains.jet.lang.types.AbstractClassTypeConstructor;
049 import org.jetbrains.jet.lang.types.JetType;
050 import org.jetbrains.jet.lang.types.TypeConstructor;
051 import org.jetbrains.jet.lang.types.TypeUtils;
052 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
053 import org.jetbrains.jet.storage.MemoizedFunctionToNotNull;
054 import org.jetbrains.jet.storage.NotNullLazyValue;
055 import org.jetbrains.jet.storage.NullableLazyValue;
056 import org.jetbrains.jet.storage.StorageManager;
057
058 import java.util.*;
059
060 import static org.jetbrains.jet.lang.diagnostics.Errors.CLASS_OBJECT_NOT_ALLOWED;
061 import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isSyntheticClassObject;
062 import static org.jetbrains.jet.lang.resolve.ModifiersChecker.*;
063 import static org.jetbrains.jet.lang.resolve.name.SpecialNames.getClassObjectName;
064 import static org.jetbrains.jet.lang.resolve.source.SourcePackage.toSourceElement;
065
066 public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes, LazyEntity {
067 private static final Predicate<JetType> VALID_SUPERTYPE = new Predicate<JetType>() {
068 @Override
069 public boolean apply(JetType type) {
070 assert !type.isError() : "Error types must be filtered out in DescriptorResolver";
071 return TypeUtils.getClassDescriptor(type) != null;
072 }
073 };
074 private final ResolveSession resolveSession;
075
076 private final JetClassLikeInfo originalClassInfo;
077 private final ClassMemberDeclarationProvider declarationProvider;
078
079 private final LazyClassTypeConstructor typeConstructor;
080 private final Modality modality;
081 private final Visibility visibility;
082 private final ClassKind kind;
083 private final boolean isInner;
084
085 private final Annotations annotations;
086 private final NullableLazyValue<LazyClassDescriptor> classObjectDescriptor;
087 private final MemoizedFunctionToNotNull<JetClassObject, ClassDescriptor> extraClassObjectDescriptors;
088
089 private final LazyClassMemberScope unsubstitutedMemberScope;
090 private final JetScope staticScope = new StaticScopeForKotlinClass(this);
091
092 private final NotNullLazyValue<JetScope> scopeForClassHeaderResolution;
093 private final NotNullLazyValue<JetScope> scopeForMemberDeclarationResolution;
094 private final NotNullLazyValue<JetScope> scopeForPropertyInitializerResolution;
095
096 private final NullableLazyValue<Void> forceResolveAllContents;
097
098 public LazyClassDescriptor(
099 @NotNull final ResolveSession resolveSession,
100 @NotNull DeclarationDescriptor containingDeclaration,
101 @NotNull Name name,
102 @NotNull JetClassLikeInfo classLikeInfo
103 ) {
104 super(resolveSession.getStorageManager(), containingDeclaration, name,
105 toSourceElement(classLikeInfo.getCorrespondingClassOrObject())
106 );
107 this.resolveSession = resolveSession;
108
109 if (classLikeInfo.getCorrespondingClassOrObject() != null) {
110 this.resolveSession.getTrace().record(BindingContext.CLASS, classLikeInfo.getCorrespondingClassOrObject(), this);
111 }
112 this.resolveSession.getTrace().record(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, DescriptorUtils.getFqName(this), this);
113
114 this.originalClassInfo = classLikeInfo;
115 this.declarationProvider = resolveSession.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfo);
116
117 this.unsubstitutedMemberScope = createMemberScope(resolveSession, this.declarationProvider);
118
119 this.typeConstructor = new LazyClassTypeConstructor();
120
121 this.kind = classLikeInfo.getClassKind();
122
123 JetModifierList modifierList = classLikeInfo.getModifierList();
124 if (kind.isSingleton()) {
125 this.modality = Modality.FINAL;
126 }
127 else {
128 Modality defaultModality = kind == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
129 this.modality = resolveModalityFromModifiers(modifierList, defaultModality);
130 }
131 this.visibility = isSyntheticClassObject(this)
132 ? DescriptorUtils.getSyntheticClassObjectVisibility()
133 : resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this));
134 this.isInner = isInnerClass(modifierList);
135
136 StorageManager storageManager = resolveSession.getStorageManager();
137
138
139 if (modifierList != null) {
140 this.annotations = new LazyAnnotations(
141 new LazyAnnotationsContext(
142 resolveSession.getAnnotationResolver(),
143 resolveSession.getStorageManager(),
144 resolveSession.getTrace()
145 ) {
146 @NotNull
147 @Override
148 public JetScope getScope() {
149 JetClassLikeInfo ownerInfo = declarationProvider.getOwnerInfo();
150 return resolveSession.getScopeProvider().getResolutionScopeForDeclaration(ownerInfo.getScopeAnchor());
151 }
152 },
153 modifierList.getAnnotationEntries()
154 );
155
156 }
157 else {
158 this.annotations = Annotations.EMPTY;
159 }
160
161 this.classObjectDescriptor = storageManager.createNullableLazyValue(new Function0<LazyClassDescriptor>() {
162 @Override
163 public LazyClassDescriptor invoke() {
164 return computeClassObjectDescriptor(declarationProvider.getOwnerInfo().getClassObject());
165 }
166 });
167 this.extraClassObjectDescriptors = storageManager.createMemoizedFunction(new Function1<JetClassObject, ClassDescriptor>() {
168 @Override
169 public ClassDescriptor invoke(JetClassObject classObject) {
170 return computeClassObjectDescriptor(classObject);
171 }
172 });
173 this.scopeForClassHeaderResolution = storageManager.createLazyValue(new Function0<JetScope>() {
174 @Override
175 public JetScope invoke() {
176 return computeScopeForClassHeaderResolution();
177 }
178 });
179 this.scopeForMemberDeclarationResolution = storageManager.createLazyValue(new Function0<JetScope>() {
180 @Override
181 public JetScope invoke() {
182 return computeScopeForMemberDeclarationResolution();
183 }
184 });
185 this.scopeForPropertyInitializerResolution = storageManager.createLazyValue(new Function0<JetScope>() {
186 @Override
187 public JetScope invoke() {
188 return computeScopeForPropertyInitializerResolution();
189 }
190 });
191 this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue(new Function0<Void>() {
192 @Override
193 public Void invoke() {
194 doForceResolveAllContents();
195 return null;
196 }
197 }, null);
198 }
199
200 // NOTE: Called from constructor!
201 @NotNull
202 protected LazyClassMemberScope createMemberScope(
203 @NotNull ResolveSession resolveSession,
204 @NotNull ClassMemberDeclarationProvider declarationProvider
205 ) {
206 return new LazyClassMemberScope(resolveSession, declarationProvider, this, resolveSession.getTrace());
207 }
208
209 @NotNull
210 @Override
211 public JetScope getScopeForMemberLookup() {
212 return unsubstitutedMemberScope;
213 }
214
215 @Override
216 @NotNull
217 public JetScope getScopeForClassHeaderResolution() {
218 return scopeForClassHeaderResolution.invoke();
219 }
220
221 @NotNull
222 private JetScope computeScopeForClassHeaderResolution() {
223 WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Scope with type parameters for " + getName());
224 for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
225 scope.addClassifierDescriptor(typeParameterDescriptor);
226 }
227 scope.changeLockLevel(WritableScope.LockLevel.READING);
228
229 PsiElement scopeAnchor = declarationProvider.getOwnerInfo().getScopeAnchor();
230
231 return new ChainedScope(this, "ScopeForClassHeaderResolution: " + getName(),
232 scope,
233 getScopeProvider().getResolutionScopeForDeclaration(scopeAnchor));
234 }
235
236 @Override
237 @NotNull
238 public JetScope getScopeForMemberDeclarationResolution() {
239 return scopeForMemberDeclarationResolution.invoke();
240 }
241
242 @NotNull
243 private JetScope computeScopeForMemberDeclarationResolution() {
244 WritableScopeImpl thisScope = new WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Scope with 'this' for " + getName());
245 thisScope.addLabeledDeclaration(this);
246 thisScope.setImplicitReceiver(this.getThisAsReceiverParameter());
247 thisScope.changeLockLevel(WritableScope.LockLevel.READING);
248
249 ClassDescriptor classObject = getClassObjectDescriptor();
250 JetScope classObjectAdapterScope = (classObject != null) ? new ClassObjectMixinScope(classObject) : JetScope.EMPTY;
251
252 return new ChainedScope(
253 this,
254 "ScopeForMemberDeclarationResolution: " + getName(),
255 thisScope,
256 getScopeForMemberLookup(),
257 getScopeForClassHeaderResolution(),
258 classObjectAdapterScope,
259 getStaticScope()
260 );
261 }
262
263 @Override
264 @NotNull
265 public JetScope getScopeForInitializerResolution() {
266 return scopeForPropertyInitializerResolution.invoke();
267 }
268
269 @NotNull
270 @Override
271 public Collection<CallableMemberDescriptor> getDeclaredCallableMembers() {
272 //noinspection unchecked
273 return (Collection) KotlinPackage.filter(
274 unsubstitutedMemberScope.getAllDescriptors(),
275 new Function1<DeclarationDescriptor, Boolean>() {
276 @Override
277 public Boolean invoke(DeclarationDescriptor descriptor) {
278 return descriptor instanceof CallableMemberDescriptor
279 && ((CallableMemberDescriptor) descriptor).getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
280 }
281 }
282 );
283 }
284
285 @NotNull
286 private JetScope computeScopeForPropertyInitializerResolution() {
287 ConstructorDescriptor primaryConstructor = getUnsubstitutedPrimaryConstructor();
288 if (primaryConstructor == null) return getScopeForMemberDeclarationResolution();
289
290 WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, primaryConstructor, RedeclarationHandler.DO_NOTHING, "Scope with constructor parameters in " + getName());
291 for (int i = 0; i < originalClassInfo.getPrimaryConstructorParameters().size(); i++) {
292 JetParameter jetParameter = originalClassInfo.getPrimaryConstructorParameters().get(i);
293 if (!jetParameter.hasValOrVarNode()) {
294 scope.addVariableDescriptor(primaryConstructor.getValueParameters().get(i));
295 }
296 }
297 scope.changeLockLevel(WritableScope.LockLevel.READING);
298
299 return new ChainedScope(
300 primaryConstructor,
301 "ScopeForPropertyInitializerResolution: " + getName(),
302 scope, getScopeForMemberDeclarationResolution());
303 }
304
305 @NotNull
306 @Override
307 public JetScope getStaticScope() {
308 return staticScope;
309 }
310
311 @NotNull
312 @Override
313 public Collection<ConstructorDescriptor> getConstructors() {
314 return unsubstitutedMemberScope.getConstructors();
315 }
316
317 @Override
318 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
319 return unsubstitutedMemberScope.getPrimaryConstructor();
320 }
321
322 @NotNull
323 @Override
324 public TypeConstructor getTypeConstructor() {
325 return typeConstructor;
326 }
327
328 @Override
329 public LazyClassDescriptor getClassObjectDescriptor() {
330 return classObjectDescriptor.invoke();
331 }
332
333 @NotNull
334 @ReadOnly
335 public List<ClassDescriptor> getDescriptorsForExtraClassObjects() {
336 return KotlinPackage.map(
337 KotlinPackage.filter(
338 declarationProvider.getOwnerInfo().getClassObjects(),
339 new Function1<JetClassObject, Boolean>() {
340 @Override
341 public Boolean invoke(JetClassObject classObject) {
342 return classObject != declarationProvider.getOwnerInfo().getClassObject();
343 }
344 }
345 ),
346 new Function1<JetClassObject, ClassDescriptor>() {
347 @Override
348 public ClassDescriptor invoke(JetClassObject classObject) {
349 return extraClassObjectDescriptors.invoke(classObject);
350 }
351 }
352 );
353 }
354
355 @Nullable
356 private LazyClassDescriptor computeClassObjectDescriptor(@Nullable JetClassObject classObject) {
357 JetClassLikeInfo classObjectInfo = getClassObjectInfo(classObject);
358 if (classObjectInfo != null) {
359 return new LazyClassDescriptor(resolveSession, this, getClassObjectName(getName()), classObjectInfo);
360 }
361 return null;
362 }
363
364 @Nullable
365 private JetClassLikeInfo getClassObjectInfo(@Nullable JetClassObject classObject) {
366 if (classObject != null) {
367 if (getKind().isSingleton() || isInner()) {
368 resolveSession.getTrace().report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
369 }
370
371 return JetClassInfoUtil.createClassLikeInfo(classObject.getObjectDeclaration());
372 }
373 else if (getKind() == ClassKind.OBJECT || getKind() == ClassKind.ENUM_ENTRY) {
374 return new SyntheticClassObjectInfo(originalClassInfo, this);
375 }
376
377 return null;
378 }
379
380 @NotNull
381 @Override
382 public ClassKind getKind() {
383 return kind;
384 }
385
386 @NotNull
387 @Override
388 public Modality getModality() {
389 return modality;
390 }
391
392 @NotNull
393 @Override
394 public Visibility getVisibility() {
395 return visibility;
396 }
397
398 @Override
399 public boolean isInner() {
400 return isInner;
401 }
402
403 @NotNull
404 @Override
405 public Annotations getAnnotations() {
406 return annotations;
407 }
408
409 @Override
410 public String toString() {
411 // not using descriptor render to preserve laziness
412 return "lazy class " + getName().toString();
413 }
414
415 @Override
416 public void forceResolveAllContents() {
417 forceResolveAllContents.invoke();
418 }
419
420 private void doForceResolveAllContents() {
421 resolveMemberHeaders();
422 ClassDescriptor classObjectDescriptor = getClassObjectDescriptor();
423 if (classObjectDescriptor != null) {
424 ForceResolveUtil.forceResolveAllContents(classObjectDescriptor);
425 }
426
427 ForceResolveUtil.forceResolveAllContents(getConstructors());
428 ForceResolveUtil.forceResolveAllContents(getDescriptorsForExtraClassObjects());
429 ForceResolveUtil.forceResolveAllContents(getScopeForMemberLookup());
430 ForceResolveUtil.forceResolveAllContents(getTypeConstructor());
431 }
432
433 // Note: headers of member classes' members are not resolved
434 public void resolveMemberHeaders() {
435 ForceResolveUtil.forceResolveAllContents(getAnnotations());
436
437 getClassObjectDescriptor();
438
439 getDescriptorsForExtraClassObjects();
440
441 getClassObjectType();
442 getConstructors();
443 getContainingDeclaration();
444 getThisAsReceiverParameter();
445 getKind();
446 getModality();
447 getName();
448 getOriginal();
449 getScopeForClassHeaderResolution();
450 getScopeForMemberDeclarationResolution();
451 getScopeForMemberLookup().getAllDescriptors();
452 getScopeForInitializerResolution();
453 getUnsubstitutedInnerClassesScope();
454 getTypeConstructor().getSupertypes();
455 for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
456 typeParameterDescriptor.getUpperBounds();
457 typeParameterDescriptor.getLowerBounds();
458 }
459 getUnsubstitutedPrimaryConstructor();
460 getVisibility();
461 }
462
463 private static class Supertypes {
464 @Mutable
465 public final Collection<JetType> trueSupertypes;
466 @Mutable
467 public final Collection<JetType> cyclicSupertypes;
468
469 private Supertypes(@Mutable @NotNull Collection<JetType> trueSupertypes) {
470 this(trueSupertypes, new ArrayList<JetType>(0));
471 }
472
473 private Supertypes(@Mutable @NotNull Collection<JetType> trueSupertypes, @Mutable @NotNull Collection<JetType> cyclicSupertypes) {
474 this.trueSupertypes = trueSupertypes;
475 this.cyclicSupertypes = cyclicSupertypes;
476 }
477
478 @NotNull
479 public Collection<JetType> getAllSupertypes() {
480 return KotlinPackage.plus(trueSupertypes, cyclicSupertypes);
481 }
482 }
483
484 private class LazyClassTypeConstructor extends AbstractClassTypeConstructor implements LazyEntity {
485 private final NotNullLazyValue<Supertypes> supertypes = resolveSession.getStorageManager().createLazyValueWithPostCompute(
486 new Function0<Supertypes>() {
487 @Override
488 public Supertypes invoke() {
489 if (KotlinBuiltIns.getInstance().isSpecialClassWithNoSupertypes(LazyClassDescriptor.this)) {
490 return new Supertypes(Collections.<JetType>emptyList());
491 }
492
493 JetClassLikeInfo info = declarationProvider.getOwnerInfo();
494 if (info instanceof SyntheticClassObjectInfo) {
495 LazyClassDescriptor descriptor = ((SyntheticClassObjectInfo) info).getClassDescriptor();
496 if (descriptor.getKind().isSingleton()) {
497 return new Supertypes(Collections.singleton(descriptor.getDefaultType()));
498 }
499 }
500
501 JetClassOrObject classOrObject = info.getCorrespondingClassOrObject();
502 if (classOrObject == null) {
503 return new Supertypes(Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
504 }
505
506 List<JetType> allSupertypes = resolveSession.getDescriptorResolver()
507 .resolveSupertypes(getScopeForClassHeaderResolution(), LazyClassDescriptor.this, classOrObject,
508 resolveSession.getTrace());
509
510 return new Supertypes(Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE)));
511 }
512 },
513 new Function1<Boolean, Supertypes>() {
514 @Override
515 public Supertypes invoke(Boolean firstTime) {
516 return new Supertypes(Collections.<JetType>emptyList());
517 }
518 },
519 new Function1<Supertypes, Unit>() {
520 @Override
521 public Unit invoke(@NotNull Supertypes supertypes) {
522 findAndDisconnectLoopsInTypeHierarchy(supertypes);
523 return Unit.INSTANCE$;
524 }
525 }
526 );
527
528 private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters = resolveSession.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
529 @Override
530 public List<TypeParameterDescriptor> invoke() {
531 JetClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
532 List<JetTypeParameter> typeParameters = classInfo.getTypeParameters();
533
534 List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
535 for (int i = 0; i < typeParameters.size(); i++) {
536 parameters.add(new LazyTypeParameterDescriptor(resolveSession, LazyClassDescriptor.this, typeParameters.get(i), i));
537 }
538
539 return parameters;
540 }
541 });
542
543 private final NullableLazyValue<Void> forceResolveAllContents =
544 resolveSession.getStorageManager().createRecursionTolerantNullableLazyValue(new Function0<Void>() {
545 @Override
546 public Void invoke() {
547 doForceResolveAllContents();
548 return null;
549 }
550 }, null);
551
552 @NotNull
553 @Override
554 public List<TypeParameterDescriptor> getParameters() {
555 return parameters.invoke();
556 }
557
558 @NotNull
559 @Override
560 public Collection<JetType> getSupertypes() {
561 return supertypes.invoke().trueSupertypes;
562 }
563
564 private void findAndDisconnectLoopsInTypeHierarchy(Supertypes supertypes) {
565 for (Iterator<JetType> iterator = supertypes.trueSupertypes.iterator(); iterator.hasNext(); ) {
566 JetType supertype = iterator.next();
567 if (isReachable(supertype.getConstructor(), this, new HashSet<TypeConstructor>())) {
568 iterator.remove();
569 supertypes.cyclicSupertypes.add(supertype);
570
571 ClassifierDescriptor supertypeDescriptor = supertype.getConstructor().getDeclarationDescriptor();
572 if (supertypeDescriptor instanceof ClassDescriptor) {
573 ClassDescriptor superclass = (ClassDescriptor) supertypeDescriptor;
574 TypeHierarchyResolver.reportCyclicInheritanceHierarchyError(resolveSession.getTrace(), LazyClassDescriptor.this,
575 superclass);
576 }
577 }
578 }
579 }
580
581 private boolean isReachable(TypeConstructor from, TypeConstructor to, Set<TypeConstructor> visited) {
582 if (!visited.add(from)) return false;
583 for (JetType supertype : getNeighbors(from)) {
584 TypeConstructor supertypeConstructor = supertype.getConstructor();
585 if (supertypeConstructor == to) {
586 return true;
587 }
588 if (isReachable(supertypeConstructor, to, visited)) {
589 return true;
590 }
591 }
592 return false;
593 }
594
595 private Collection<JetType> getNeighbors(TypeConstructor from) {
596 // Supertypes + type for container
597 Collection<JetType> neighbours = new ArrayList<JetType>(
598 from instanceof LazyClassTypeConstructor
599 ? ((LazyClassTypeConstructor) from).supertypes.invoke().getAllSupertypes()
600 : from.getSupertypes()
601 );
602
603 ClassifierDescriptor fromDescriptor = from.getDeclarationDescriptor();
604 if (fromDescriptor != null) {
605 DeclarationDescriptor container = fromDescriptor.getContainingDeclaration();
606 if (container instanceof ClassDescriptor) {
607 neighbours.add(((ClassDescriptor) container).getDefaultType());
608 }
609 }
610 return neighbours;
611 }
612
613 @Override
614 public boolean isFinal() {
615 return !getModality().isOverridable();
616 }
617
618 @Override
619 public boolean isDenotable() {
620 return true;
621 }
622
623 @Override
624 public ClassifierDescriptor getDeclarationDescriptor() {
625 return LazyClassDescriptor.this;
626 }
627
628 @NotNull
629 @Override
630 public Annotations getAnnotations() {
631 return Annotations.EMPTY; // TODO
632 }
633
634 @Override
635 public String toString() {
636 return LazyClassDescriptor.this.getName().toString();
637 }
638
639 @Override
640 public void forceResolveAllContents() {
641 forceResolveAllContents.invoke();
642 }
643
644 private void doForceResolveAllContents() {
645 ForceResolveUtil.forceResolveAllContents(getAnnotations());
646 ForceResolveUtil.forceResolveAllContents(getSupertypes());
647 ForceResolveUtil.forceResolveAllContents(getParameters());
648 }
649 }
650
651 @NotNull
652 private ScopeProvider getScopeProvider() {
653 return resolveSession.getScopeProvider();
654 }
655 }