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