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