001    /*
002     * Copyright 2010-2016 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.kotlin.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 com.intellij.psi.PsiNameIdentifierOwner;
024    import kotlin.collections.CollectionsKt;
025    import kotlin.jvm.functions.Function0;
026    import kotlin.jvm.functions.Function1;
027    import org.jetbrains.annotations.NotNull;
028    import org.jetbrains.annotations.Nullable;
029    import org.jetbrains.annotations.ReadOnly;
030    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
031    import org.jetbrains.kotlin.descriptors.*;
032    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
033    import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
034    import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
035    import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
036    import org.jetbrains.kotlin.lexer.KtTokens;
037    import org.jetbrains.kotlin.name.Name;
038    import org.jetbrains.kotlin.psi.*;
039    import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
040    import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
041    import org.jetbrains.kotlin.resolve.*;
042    import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
043    import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
044    import org.jetbrains.kotlin.resolve.lazy.LazyClassContext;
045    import org.jetbrains.kotlin.resolve.lazy.LazyEntity;
046    import org.jetbrains.kotlin.resolve.lazy.data.KtClassInfoUtil;
047    import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo;
048    import org.jetbrains.kotlin.resolve.lazy.data.KtClassOrObjectInfo;
049    import org.jetbrains.kotlin.resolve.lazy.data.KtObjectInfo;
050    import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider;
051    import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
052    import org.jetbrains.kotlin.resolve.scopes.MemberScope;
053    import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum;
054    import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
055    import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
056    import org.jetbrains.kotlin.storage.NotNullLazyValue;
057    import org.jetbrains.kotlin.storage.NullableLazyValue;
058    import org.jetbrains.kotlin.storage.StorageManager;
059    import org.jetbrains.kotlin.types.AbstractClassTypeConstructor;
060    import org.jetbrains.kotlin.types.KotlinType;
061    import org.jetbrains.kotlin.types.TypeConstructor;
062    import org.jetbrains.kotlin.types.TypeUtils;
063    
064    import java.util.ArrayList;
065    import java.util.Collection;
066    import java.util.Collections;
067    import java.util.List;
068    
069    import static kotlin.collections.CollectionsKt.firstOrNull;
070    import static org.jetbrains.kotlin.descriptors.Visibilities.PUBLIC;
071    import static org.jetbrains.kotlin.diagnostics.Errors.CYCLIC_INHERITANCE_HIERARCHY;
072    import static org.jetbrains.kotlin.diagnostics.Errors.TYPE_PARAMETERS_IN_ENUM;
073    import static org.jetbrains.kotlin.resolve.BindingContext.TYPE;
074    import static org.jetbrains.kotlin.resolve.ModifiersChecker.*;
075    
076    public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDescriptorWithResolutionScopes, LazyEntity {
077        private static final Predicate<KotlinType> VALID_SUPERTYPE = new Predicate<KotlinType>() {
078            @Override
079            public boolean apply(KotlinType type) {
080                assert !type.isError() : "Error types must be filtered out in DescriptorResolver";
081                return TypeUtils.getClassDescriptor(type) != null;
082            }
083        };
084        private final LazyClassContext c;
085    
086        @Nullable // can be null in KtScript
087        private final KtClassOrObject classOrObject;
088    
089        private final ClassMemberDeclarationProvider declarationProvider;
090    
091        private final LazyClassTypeConstructor typeConstructor;
092        private final NotNullLazyValue<Modality> modality;
093        private final Visibility visibility;
094        private final ClassKind kind;
095        private final boolean isInner;
096        private final boolean isData;
097        private final boolean isHeader;
098        private final boolean isImpl;
099    
100        private final Annotations annotations;
101        private final Annotations danglingAnnotations;
102        private final NullableLazyValue<ClassDescriptorWithResolutionScopes> companionObjectDescriptor;
103        private final MemoizedFunctionToNotNull<KtObjectDeclaration, ClassDescriptor> extraCompanionObjectDescriptors;
104    
105        private final LazyClassMemberScope unsubstitutedMemberScope;
106        private final MemberScope staticScope;
107    
108        private final NullableLazyValue<Void> forceResolveAllContents;
109        private final boolean isCompanionObject;
110    
111        private final ClassResolutionScopesSupport resolutionScopesSupport;
112        private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters;
113    
114        private final NotNullLazyValue<LexicalScope> scopeForInitializerResolution;
115    
116        private final NotNullLazyValue<Collection<ClassDescriptor>> sealedSubclasses;
117    
118        public LazyClassDescriptor(
119                @NotNull final LazyClassContext c,
120                @NotNull DeclarationDescriptor containingDeclaration,
121                @NotNull Name name,
122                @NotNull final KtClassLikeInfo classLikeInfo,
123                boolean isExternal
124        ) {
125            super(c.getStorageManager(), containingDeclaration, name,
126                  KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject()),
127                  isExternal
128            );
129            this.c = c;
130    
131            classOrObject = classLikeInfo.getCorrespondingClassOrObject();
132            if (classOrObject != null) {
133                this.c.getTrace().record(BindingContext.CLASS, classOrObject, this);
134            }
135            this.c.getTrace().record(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, DescriptorUtils.getFqName(this), this);
136    
137            this.declarationProvider = c.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfo);
138    
139            StorageManager storageManager = c.getStorageManager();
140    
141            this.unsubstitutedMemberScope = createMemberScope(c, this.declarationProvider);
142            this.kind = classLikeInfo.getClassKind();
143            this.staticScope = kind == ClassKind.ENUM_CLASS ? new StaticScopeForKotlinEnum(storageManager, this) : MemberScope.Empty.INSTANCE;
144    
145            this.typeConstructor = new LazyClassTypeConstructor();
146    
147            this.isCompanionObject = classLikeInfo instanceof KtObjectInfo && ((KtObjectInfo) classLikeInfo).isCompanionObject();
148    
149            final KtModifierList modifierList = classLikeInfo.getModifierList();
150            if (kind.isSingleton()) {
151                this.modality = storageManager.createLazyValue(new Function0<Modality>() {
152                    @Override
153                    public Modality invoke() {
154                        return Modality.FINAL;
155                    }
156                });
157            }
158            else {
159                final Modality defaultModality = kind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL;
160                this.modality = storageManager.createLazyValue(new Function0<Modality>() {
161                    @Override
162                    public Modality invoke() {
163                        return resolveModalityFromModifiers(classOrObject, defaultModality,
164                                                            c.getTrace().getBindingContext(),
165                                                            null,
166                                                            /* allowSealed = */ true);
167                    }
168                });
169            }
170    
171            boolean isLocal = classOrObject != null && KtPsiUtil.isLocal(classOrObject);
172            Visibility defaultVisibility;
173            if (kind == ClassKind.ENUM_ENTRY || (kind == ClassKind.OBJECT && isCompanionObject)) {
174                defaultVisibility = Visibilities.PUBLIC;
175            }
176            else {
177                defaultVisibility = Visibilities.DEFAULT_VISIBILITY;
178            }
179            this.visibility = isLocal ? Visibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, defaultVisibility);
180    
181            this.isInner = isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(this);
182            this.isData = modifierList != null && modifierList.hasModifier(KtTokens.DATA_KEYWORD);
183            this.isHeader = modifierList != null && modifierList.hasModifier(KtTokens.HEADER_KEYWORD);
184            this.isImpl = modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD);
185    
186            // Annotation entries are taken from both own annotations (if any) and object literal annotations (if any)
187            List<KtAnnotationEntry> annotationEntries = new ArrayList<KtAnnotationEntry>();
188            if (classOrObject != null && classOrObject.getParent() instanceof KtObjectLiteralExpression) {
189                // TODO: it would be better to have separate ObjectLiteralDescriptor without so much magic
190                annotationEntries.addAll(KtPsiUtilKt.getAnnotationEntries((KtObjectLiteralExpression) classOrObject.getParent()));
191            }
192            if (modifierList != null) {
193                annotationEntries.addAll(modifierList.getAnnotationEntries());
194            }
195            if (!annotationEntries.isEmpty()) {
196                this.annotations = new LazyAnnotations(
197                        new LazyAnnotationsContext(
198                                c.getAnnotationResolver(),
199                                storageManager,
200                                c.getTrace()
201                        ) {
202                            @NotNull
203                            @Override
204                            public LexicalScope getScope() {
205                                return getOuterScope();
206                            }
207                        },
208                        annotationEntries
209                );
210            }
211            else {
212                this.annotations = Annotations.Companion.getEMPTY();
213            }
214    
215            List<KtAnnotationEntry> jetDanglingAnnotations = classLikeInfo.getDanglingAnnotations();
216            if (jetDanglingAnnotations.isEmpty()) {
217                this.danglingAnnotations = Annotations.Companion.getEMPTY();
218            }
219            else {
220                this.danglingAnnotations = new LazyAnnotations(
221                        new LazyAnnotationsContext(
222                                c.getAnnotationResolver(),
223                                storageManager,
224                                c.getTrace()
225                        ) {
226                            @NotNull
227                            @Override
228                            public LexicalScope getScope() {
229                                return getScopeForMemberDeclarationResolution();
230                            }
231                        },
232                        jetDanglingAnnotations
233                );
234            }
235    
236            this.companionObjectDescriptor = storageManager.createNullableLazyValue(new Function0<ClassDescriptorWithResolutionScopes>() {
237                @Override
238                public ClassDescriptorWithResolutionScopes invoke() {
239                    return computeCompanionObjectDescriptor(getCompanionObjectIfAllowed());
240                }
241            });
242            this.extraCompanionObjectDescriptors = storageManager.createMemoizedFunction(new Function1<KtObjectDeclaration, ClassDescriptor>() {
243                @Override
244                public ClassDescriptor invoke(KtObjectDeclaration companionObject) {
245                    return computeCompanionObjectDescriptor(companionObject);
246                }
247            });
248            this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue(new Function0<Void>() {
249                @Override
250                public Void invoke() {
251                    doForceResolveAllContents();
252                    return null;
253                }
254            }, null);
255    
256            this.resolutionScopesSupport = new ClassResolutionScopesSupport(this, storageManager, new Function0<LexicalScope>() {
257                @Override
258                public LexicalScope invoke() {
259                    return getOuterScope();
260                }
261            });
262    
263            this.parameters = c.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
264                @Override
265                public List<TypeParameterDescriptor> invoke() {
266                    KtClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
267                    KtTypeParameterList typeParameterList = classInfo.getTypeParameterList();
268                    if (typeParameterList == null) return Collections.emptyList();
269    
270                    if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
271                        c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
272                    }
273    
274                    List<KtTypeParameter> typeParameters = typeParameterList.getParameters();
275                    if (typeParameters.isEmpty()) return Collections.emptyList();
276    
277                    List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size());
278    
279                    for (int i = 0; i < typeParameters.size(); i++) {
280                        parameters.add(new LazyTypeParameterDescriptor(c, LazyClassDescriptor.this, typeParameters.get(i), i));
281                    }
282    
283                    return parameters;
284                }
285            });
286    
287            this.scopeForInitializerResolution = storageManager.createLazyValue(new Function0<LexicalScope>() {
288                @Override
289                public LexicalScope invoke() {
290                    return ClassResolutionScopesSupportKt.scopeForInitializerResolution(LazyClassDescriptor.this,
291                                                                                        createInitializerScopeParent(),
292                                                                                        classLikeInfo.getPrimaryConstructorParameters());
293                }
294            });
295    
296            this.sealedSubclasses = storageManager.createLazyValue(new Function0<Collection<ClassDescriptor>>() {
297                @Override
298                public Collection<ClassDescriptor> invoke() {
299                    // TODO: only consider classes from the same file, not the whole package fragment
300                    return DescriptorUtilsKt.computeSealedSubclasses(LazyClassDescriptor.this);
301                }
302            });
303        }
304    
305        @NotNull
306        private DeclarationDescriptor createInitializerScopeParent() {
307            ConstructorDescriptor primaryConstructor = getUnsubstitutedPrimaryConstructor();
308            if (primaryConstructor != null) return primaryConstructor;
309    
310            return new FunctionDescriptorImpl(
311                    LazyClassDescriptor.this, null, Annotations.Companion.getEMPTY(), Name.special("<init-blocks>"),
312                    CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE
313            ) {
314                {
315                    initialize(null, null, Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
316                               null, Modality.FINAL, Visibilities.PRIVATE);
317                }
318    
319                @NotNull
320                @Override
321                protected FunctionDescriptorImpl createSubstitutedCopy(
322                        @NotNull DeclarationDescriptor newOwner,
323                        @Nullable FunctionDescriptor original,
324                        @NotNull Kind kind,
325                        @Nullable Name newName,
326                        @NotNull Annotations annotations,
327                        @NotNull SourceElement source
328                ) {
329                    throw new UnsupportedOperationException();
330                }
331            };
332        }
333    
334        // NOTE: Called from constructor!
335        @NotNull
336        protected LazyClassMemberScope createMemberScope(
337                @NotNull LazyClassContext c,
338                @NotNull ClassMemberDeclarationProvider declarationProvider
339        ) {
340            return new LazyClassMemberScope(c, declarationProvider, this, c.getTrace());
341        }
342    
343        @NotNull
344        @Override
345        public MemberScope getUnsubstitutedMemberScope() {
346            return unsubstitutedMemberScope;
347        }
348    
349        @NotNull
350        protected LexicalScope getOuterScope() {
351            return c.getDeclarationScopeProvider().getResolutionScopeForDeclaration(declarationProvider.getOwnerInfo().getScopeAnchor());
352        }
353    
354        @Override
355        @NotNull
356        public LexicalScope getScopeForClassHeaderResolution() {
357            return resolutionScopesSupport.getScopeForClassHeaderResolution().invoke();
358        }
359    
360        @Override
361        @NotNull
362        public LexicalScope getScopeForConstructorHeaderResolution() {
363            return resolutionScopesSupport.getScopeForConstructorHeaderResolution().invoke();
364        }
365    
366        @Override
367        @NotNull
368        public LexicalScope getScopeForCompanionObjectHeaderResolution() {
369            return resolutionScopesSupport.getScopeForCompanionObjectHeaderResolution().invoke();
370        }
371    
372        @Override
373        @NotNull
374        public LexicalScope getScopeForMemberDeclarationResolution() {
375            return resolutionScopesSupport.getScopeForMemberDeclarationResolution().invoke();
376        }
377    
378        @Override
379        @NotNull
380        public LexicalScope getScopeForStaticMemberDeclarationResolution() {
381            return resolutionScopesSupport.getScopeForStaticMemberDeclarationResolution().invoke();
382        }
383    
384        @Override
385        @NotNull
386        public LexicalScope getScopeForInitializerResolution() {
387            return scopeForInitializerResolution.invoke();
388        }
389    
390        @NotNull
391        @Override
392        public Collection<CallableMemberDescriptor> getDeclaredCallableMembers() {
393            //noinspection unchecked
394            return (Collection) CollectionsKt.filter(
395                    DescriptorUtils.getAllDescriptors(unsubstitutedMemberScope),
396                    new Function1<DeclarationDescriptor, Boolean>() {
397                        @Override
398                        public Boolean invoke(DeclarationDescriptor descriptor) {
399                            return descriptor instanceof CallableMemberDescriptor
400                                   && ((CallableMemberDescriptor) descriptor).getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
401                        }
402                    }
403            );
404        }
405    
406        @NotNull
407        @Override
408        public MemberScope getStaticScope() {
409            return staticScope;
410        }
411    
412        @NotNull
413        @Override
414        public Collection<ClassConstructorDescriptor> getConstructors() {
415            return unsubstitutedMemberScope.getConstructors();
416        }
417    
418        @Override
419        public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
420            return unsubstitutedMemberScope.getPrimaryConstructor();
421        }
422    
423        @NotNull
424        @Override
425        public TypeConstructor getTypeConstructor() {
426            return typeConstructor;
427        }
428    
429        @Override
430        public ClassDescriptorWithResolutionScopes getCompanionObjectDescriptor() {
431            return companionObjectDescriptor.invoke();
432        }
433    
434        @NotNull
435        @ReadOnly
436        public List<ClassDescriptor> getDescriptorsForExtraCompanionObjects() {
437            final KtObjectDeclaration allowedCompanionObject = getCompanionObjectIfAllowed();
438    
439            return CollectionsKt.map(
440                    CollectionsKt.filter(
441                            declarationProvider.getOwnerInfo().getCompanionObjects(),
442                            new Function1<KtObjectDeclaration, Boolean>() {
443                                @Override
444                                public Boolean invoke(KtObjectDeclaration companionObject) {
445                                    return companionObject != allowedCompanionObject;
446                                }
447                            }
448                    ),
449                    new Function1<KtObjectDeclaration, ClassDescriptor>() {
450                        @Override
451                        public ClassDescriptor invoke(KtObjectDeclaration companionObject) {
452                            return extraCompanionObjectDescriptors.invoke(companionObject);
453                        }
454                    }
455            );
456        }
457    
458        @Nullable
459        private ClassDescriptorWithResolutionScopes computeCompanionObjectDescriptor(@Nullable KtObjectDeclaration companionObject) {
460            if (companionObject == null)
461                return createSyntheticCompanionObjectDescriptor();
462            KtClassLikeInfo companionObjectInfo = getCompanionObjectInfo(companionObject);
463            if (!(companionObjectInfo instanceof KtClassOrObjectInfo)) {
464                return null;
465            }
466            Name name = ((KtClassOrObjectInfo) companionObjectInfo).getName();
467            assert name != null;
468            getUnsubstitutedMemberScope().getContributedClassifier(name, NoLookupLocation.WHEN_GET_COMPANION_OBJECT);
469            ClassDescriptor companionObjectDescriptor = c.getTrace().get(BindingContext.CLASS, companionObject);
470            if (companionObjectDescriptor instanceof ClassDescriptorWithResolutionScopes) {
471                assert DescriptorUtils.isCompanionObject(companionObjectDescriptor) : "Not a companion object: " + companionObjectDescriptor;
472                return (ClassDescriptorWithResolutionScopes)companionObjectDescriptor;
473            }
474            else {
475                return null;
476            }
477        }
478    
479        private ClassDescriptorWithResolutionScopes createSyntheticCompanionObjectDescriptor() {
480            Name syntheticCompanionName = c.getSyntheticResolveExtension().getSyntheticCompanionObjectNameIfNeeded(this);
481            if (syntheticCompanionName == null)
482                return null;
483            return new SyntheticClassOrObjectDescriptor(c,
484                    /* parentClassOrObject= */ classOrObject,
485                    this, syntheticCompanionName, getSource(),
486                    /* outerScope= */ getOuterScope(),
487                    Modality.FINAL, PUBLIC, ClassKind.OBJECT, true);
488        }
489    
490        @Nullable
491        private static KtClassLikeInfo getCompanionObjectInfo(@Nullable KtObjectDeclaration companionObject) {
492            if (companionObject != null) {
493                return KtClassInfoUtil.createClassLikeInfo(companionObject);
494            }
495    
496            return null;
497        }
498    
499        @Nullable
500        private KtObjectDeclaration getCompanionObjectIfAllowed() {
501            KtObjectDeclaration companionObject = firstOrNull(declarationProvider.getOwnerInfo().getCompanionObjects());
502            return (companionObject != null && isCompanionObjectAllowed()) ? companionObject : null;
503        }
504    
505        private boolean isCompanionObjectAllowed() {
506            return !(getKind().isSingleton() || isInner() || DescriptorUtils.isLocal(this));
507        }
508    
509        @NotNull
510        @Override
511        public ClassKind getKind() {
512            return kind;
513        }
514    
515        @NotNull
516        @Override
517        public Modality getModality() {
518            return modality.invoke();
519        }
520    
521        @NotNull
522        @Override
523        public Visibility getVisibility() {
524            return visibility;
525        }
526    
527        @Override
528        public boolean isInner() {
529            return isInner;
530        }
531    
532        @Override
533        public boolean isData() {
534            return isData;
535        }
536    
537        @Override
538        public boolean isCompanionObject() {
539            return isCompanionObject;
540        }
541    
542        @Override
543        public boolean isHeader() {
544            return isHeader;
545        }
546    
547        @Override
548        public boolean isImpl() {
549            return isImpl;
550        }
551    
552        @NotNull
553        @Override
554        public Annotations getAnnotations() {
555            return annotations;
556        }
557    
558        @NotNull
559        public Annotations getDanglingAnnotations() {
560            return danglingAnnotations;
561        }
562    
563        @NotNull
564        @Override
565        public Collection<ClassDescriptor> getSealedSubclasses() {
566            return sealedSubclasses.invoke();
567        }
568    
569        @Override
570        public String toString() {
571            // not using descriptor render to preserve laziness
572            return "lazy class " + getName().toString();
573        }
574    
575        @Override
576        public void forceResolveAllContents() {
577            forceResolveAllContents.invoke();
578        }
579    
580        private void doForceResolveAllContents() {
581            resolveMemberHeaders();
582            ClassDescriptor companionObjectDescriptor = getCompanionObjectDescriptor();
583            if (companionObjectDescriptor != null) {
584                ForceResolveUtil.forceResolveAllContents(companionObjectDescriptor);
585            }
586    
587            ForceResolveUtil.forceResolveAllContents(getConstructors());
588            ForceResolveUtil.forceResolveAllContents(getDescriptorsForExtraCompanionObjects());
589            ForceResolveUtil.forceResolveAllContents(getUnsubstitutedMemberScope());
590            ForceResolveUtil.forceResolveAllContents(getTypeConstructor());
591        }
592    
593        // Note: headers of member classes' members are not resolved
594        public void resolveMemberHeaders() {
595            ForceResolveUtil.forceResolveAllContents(getAnnotations());
596            ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations());
597    
598            getCompanionObjectDescriptor();
599    
600            getDescriptorsForExtraCompanionObjects();
601    
602            getConstructors();
603            getContainingDeclaration();
604            getThisAsReceiverParameter();
605            getKind();
606            getModality();
607            getName();
608            getOriginal();
609            getScopeForClassHeaderResolution();
610            getScopeForMemberDeclarationResolution();
611            DescriptorUtils.getAllDescriptors(getUnsubstitutedMemberScope());
612            getScopeForInitializerResolution();
613            getUnsubstitutedInnerClassesScope();
614            getTypeConstructor().getSupertypes();
615            for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
616                typeParameterDescriptor.getUpperBounds();
617            }
618            getUnsubstitutedPrimaryConstructor();
619            getVisibility();
620        }
621    
622        @NotNull
623        @Override
624        public List<TypeParameterDescriptor> getDeclaredTypeParameters() {
625            return parameters.invoke();
626        }
627    
628        private class LazyClassTypeConstructor extends AbstractClassTypeConstructor {
629            private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters = c.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
630                @Override
631                public List<TypeParameterDescriptor> invoke() {
632                    return TypeParameterUtilsKt.computeConstructorTypeParameters(LazyClassDescriptor.this);
633                }
634            });
635    
636            public LazyClassTypeConstructor() {
637                super(LazyClassDescriptor.this.c.getStorageManager());
638            }
639    
640            @NotNull
641            @Override
642            protected Collection<KotlinType> computeSupertypes() {
643                return LazyClassDescriptor.this.computeSupertypes();
644            }
645    
646            @Override
647            protected void reportSupertypeLoopError(@NotNull KotlinType type) {
648                ClassifierDescriptor supertypeDescriptor = type.getConstructor().getDeclarationDescriptor();
649                if (supertypeDescriptor instanceof ClassDescriptor) {
650                    ClassDescriptor superclass = (ClassDescriptor) supertypeDescriptor;
651                    reportCyclicInheritanceHierarchyError(c.getTrace(), LazyClassDescriptor.this, superclass);
652                }
653            }
654    
655            private void reportCyclicInheritanceHierarchyError(
656                    @NotNull BindingTrace trace,
657                    @NotNull ClassDescriptor classDescriptor,
658                    @NotNull ClassDescriptor superclass
659            ) {
660                PsiElement psiElement = DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);
661    
662                PsiElement elementToMark = null;
663                if (psiElement instanceof KtClassOrObject) {
664                    KtClassOrObject classOrObject = (KtClassOrObject) psiElement;
665                    for (KtSuperTypeListEntry delegationSpecifier : classOrObject.getSuperTypeListEntries()) {
666                        KtTypeReference typeReference = delegationSpecifier.getTypeReference();
667                        if (typeReference == null) continue;
668                        KotlinType supertype = trace.get(TYPE, typeReference);
669                        if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
670                            elementToMark = typeReference;
671                        }
672                    }
673                }
674                if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
675                    PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
676                    PsiElement nameIdentifier = namedElement.getNameIdentifier();
677                    if (nameIdentifier != null) {
678                        elementToMark = nameIdentifier;
679                    }
680                }
681                if (elementToMark != null) {
682                    trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
683                }
684            }
685    
686            @NotNull
687            @Override
688            protected SupertypeLoopChecker getSupertypeLoopChecker() {
689                return c.getSupertypeLoopChecker();
690            }
691    
692            @NotNull
693            @Override
694            public List<TypeParameterDescriptor> getParameters() {
695                return parameters.invoke();
696            }
697    
698            @Override
699            public boolean isFinal() {
700                return getModality() == Modality.FINAL;
701            }
702    
703            @Override
704            public boolean isDenotable() {
705                return true;
706            }
707    
708            @Override
709            @NotNull
710            public ClassifierDescriptor getDeclarationDescriptor() {
711                return LazyClassDescriptor.this;
712            }
713    
714            @Override
715            public String toString() {
716                return LazyClassDescriptor.this.getName().toString();
717            }
718        }
719    
720        @NotNull
721        protected Collection<KotlinType> computeSupertypes() {
722            if (KotlinBuiltIns.isSpecialClassWithNoSupertypes(this)) {
723                return Collections.emptyList();
724            }
725    
726            KtClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
727            if (classOrObject == null) {
728                return Collections.<KotlinType>singleton(c.getModuleDescriptor().getBuiltIns().getAnyType());
729            }
730    
731            List<KotlinType> allSupertypes =
732                    c.getDescriptorResolver()
733                            .resolveSupertypes(getScopeForClassHeaderResolution(), this, classOrObject,
734                                               c.getTrace());
735    
736            return Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE));
737        }
738    }