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