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