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.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.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 KtClassLikeInfo 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 KtObjectInfo && ((KtObjectInfo) 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 KtClassLikeInfo 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 getScopeForConstructorHeaderResolution() {
298 return resolutionScopesSupport.getScopeForConstructorHeaderResolution().invoke();
299 }
300
301 @Override
302 @NotNull
303 public LexicalScope getScopeForCompanionObjectHeaderResolution() {
304 return resolutionScopesSupport.getScopeForCompanionObjectHeaderResolution().invoke();
305 }
306
307 @Override
308 @NotNull
309 public LexicalScope getScopeForMemberDeclarationResolution() {
310 return resolutionScopesSupport.getScopeForMemberDeclarationResolution().invoke();
311 }
312
313 @Override
314 @NotNull
315 public LexicalScope getScopeForStaticMemberDeclarationResolution() {
316 return resolutionScopesSupport.getScopeForStaticMemberDeclarationResolution().invoke();
317 }
318
319 @Override
320 @NotNull
321 public LexicalScope getScopeForInitializerResolution() {
322 return resolutionScopesSupport.getScopeForInitializerResolution().invoke();
323 }
324
325 @NotNull
326 @Override
327 public Collection<CallableMemberDescriptor> getDeclaredCallableMembers() {
328 //noinspection unchecked
329 return (Collection) CollectionsKt.filter(
330 DescriptorUtils.getAllDescriptors(unsubstitutedMemberScope),
331 new Function1<DeclarationDescriptor, Boolean>() {
332 @Override
333 public Boolean invoke(DeclarationDescriptor descriptor) {
334 return descriptor instanceof CallableMemberDescriptor
335 && ((CallableMemberDescriptor) descriptor).getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
336 }
337 }
338 );
339 }
340
341 @NotNull
342 @Override
343 public MemberScope getStaticScope() {
344 return staticScope;
345 }
346
347 @NotNull
348 @Override
349 public Collection<ConstructorDescriptor> getConstructors() {
350 return unsubstitutedMemberScope.getConstructors();
351 }
352
353 @Override
354 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
355 return unsubstitutedMemberScope.getPrimaryConstructor();
356 }
357
358 @NotNull
359 @Override
360 public TypeConstructor getTypeConstructor() {
361 return typeConstructor;
362 }
363
364 @Override
365 public LazyClassDescriptor getCompanionObjectDescriptor() {
366 return companionObjectDescriptor.invoke();
367 }
368
369 @NotNull
370 @ReadOnly
371 public List<ClassDescriptor> getDescriptorsForExtraCompanionObjects() {
372 final KtObjectDeclaration allowedCompanionObject = getCompanionObjectIfAllowed();
373
374 return CollectionsKt.map(
375 CollectionsKt.filter(
376 declarationProvider.getOwnerInfo().getCompanionObjects(),
377 new Function1<KtObjectDeclaration, Boolean>() {
378 @Override
379 public Boolean invoke(KtObjectDeclaration companionObject) {
380 return companionObject != allowedCompanionObject;
381 }
382 }
383 ),
384 new Function1<KtObjectDeclaration, ClassDescriptor>() {
385 @Override
386 public ClassDescriptor invoke(KtObjectDeclaration companionObject) {
387 return extraCompanionObjectDescriptors.invoke(companionObject);
388 }
389 }
390 );
391 }
392
393 @Nullable
394 private LazyClassDescriptor computeCompanionObjectDescriptor(@Nullable KtObjectDeclaration companionObject) {
395 KtClassLikeInfo companionObjectInfo = getCompanionObjectInfo(companionObject);
396 if (!(companionObjectInfo instanceof KtClassOrObjectInfo)) {
397 return null;
398 }
399 Name name = ((KtClassOrObjectInfo) companionObjectInfo).getName();
400 assert name != null;
401 getUnsubstitutedMemberScope().getContributedClassifier(name, NoLookupLocation.WHEN_GET_COMPANION_OBJECT);
402 ClassDescriptor companionObjectDescriptor = c.getTrace().get(BindingContext.CLASS, companionObject);
403 if (companionObjectDescriptor instanceof LazyClassDescriptor) {
404 assert DescriptorUtils.isCompanionObject(companionObjectDescriptor) : "Not a companion object: " + companionObjectDescriptor;
405 return (LazyClassDescriptor) companionObjectDescriptor;
406 }
407 else {
408 return null;
409 }
410 }
411
412 @Nullable
413 private static KtClassLikeInfo getCompanionObjectInfo(@Nullable KtObjectDeclaration companionObject) {
414 if (companionObject != null) {
415 return KtClassInfoUtil.createClassLikeInfo(companionObject);
416 }
417
418 return null;
419 }
420
421 @Nullable
422 private KtObjectDeclaration getCompanionObjectIfAllowed() {
423 KtObjectDeclaration companionObject = firstOrNull(declarationProvider.getOwnerInfo().getCompanionObjects());
424 return (companionObject != null && isCompanionObjectAllowed()) ? companionObject : null;
425 }
426
427 private boolean isCompanionObjectAllowed() {
428 return !(getKind().isSingleton() || isInner() || DescriptorUtils.isLocal(this));
429 }
430
431 @NotNull
432 @Override
433 public ClassKind getKind() {
434 return kind.invoke();
435 }
436
437 @NotNull
438 @Override
439 public Modality getModality() {
440 return modality;
441 }
442
443 @NotNull
444 @Override
445 public Visibility getVisibility() {
446 return visibility;
447 }
448
449 @Override
450 public boolean isInner() {
451 return isInner.invoke();
452 }
453
454 @Override
455 public boolean isData() {
456 return isData.invoke();
457 }
458
459 @Override
460 public boolean isCompanionObject() {
461 return isCompanionObject;
462 }
463
464 @NotNull
465 @Override
466 public Annotations getAnnotations() {
467 return annotations;
468 }
469
470 @NotNull
471 public Annotations getDanglingAnnotations() {
472 return danglingAnnotations;
473 }
474
475 @Override
476 public String toString() {
477 // not using descriptor render to preserve laziness
478 return "lazy class " + getName().toString();
479 }
480
481 @Override
482 public void forceResolveAllContents() {
483 forceResolveAllContents.invoke();
484 }
485
486 private void doForceResolveAllContents() {
487 resolveMemberHeaders();
488 ClassDescriptor companionObjectDescriptor = getCompanionObjectDescriptor();
489 if (companionObjectDescriptor != null) {
490 ForceResolveUtil.forceResolveAllContents(companionObjectDescriptor);
491 }
492
493 ForceResolveUtil.forceResolveAllContents(getConstructors());
494 ForceResolveUtil.forceResolveAllContents(getDescriptorsForExtraCompanionObjects());
495 ForceResolveUtil.forceResolveAllContents(getUnsubstitutedMemberScope());
496 ForceResolveUtil.forceResolveAllContents(getTypeConstructor());
497 }
498
499 // Note: headers of member classes' members are not resolved
500 public void resolveMemberHeaders() {
501 ForceResolveUtil.forceResolveAllContents(getAnnotations());
502 ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations());
503
504 getCompanionObjectDescriptor();
505
506 getDescriptorsForExtraCompanionObjects();
507
508 getConstructors();
509 getContainingDeclaration();
510 getThisAsReceiverParameter();
511 getKind();
512 getModality();
513 getName();
514 getOriginal();
515 getScopeForClassHeaderResolution();
516 getScopeForMemberDeclarationResolution();
517 DescriptorUtils.getAllDescriptors(getUnsubstitutedMemberScope());
518 getScopeForInitializerResolution();
519 getUnsubstitutedInnerClassesScope();
520 getTypeConstructor().getSupertypes();
521 for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) {
522 typeParameterDescriptor.getUpperBounds();
523 typeParameterDescriptor.getLowerBounds();
524 }
525 getUnsubstitutedPrimaryConstructor();
526 getVisibility();
527 }
528
529 @NotNull
530 @Override
531 public List<TypeParameterDescriptor> getDeclaredTypeParameters() {
532 return parameters.invoke();
533 }
534
535 private static class Supertypes {
536 @Mutable
537 public final Collection<KotlinType> trueSupertypes;
538 @Mutable
539 public final Collection<KotlinType> allSuperTypes;
540
541 private Supertypes(@Mutable @NotNull Collection<KotlinType> allSuperTypes) {
542 this.trueSupertypes = allSuperTypes;
543 this.allSuperTypes = new ArrayList<KotlinType>(allSuperTypes);
544 }
545
546 @NotNull
547 public Collection<KotlinType> getAllSupertypes() {
548 return allSuperTypes;
549 }
550 }
551
552 private class LazyClassTypeConstructor extends AbstractClassTypeConstructor implements LazyEntity {
553 private final NotNullLazyValue<Supertypes> supertypes = c.getStorageManager().createLazyValueWithPostCompute(
554 new Function0<Supertypes>() {
555 @Override
556 public Supertypes invoke() {
557 if (KotlinBuiltIns.isSpecialClassWithNoSupertypes(LazyClassDescriptor.this)) {
558 return new Supertypes(Collections.<KotlinType>emptyList());
559 }
560
561 KtClassOrObject classOrObject = declarationProvider.getOwnerInfo().getCorrespondingClassOrObject();
562 if (classOrObject == null) {
563 return new Supertypes(Collections.singleton(c.getModuleDescriptor().getBuiltIns().getAnyType()));
564 }
565
566 List<KotlinType> allSupertypes = c.getDescriptorResolver()
567 .resolveSupertypes(getScopeForClassHeaderResolution(), LazyClassDescriptor.this, classOrObject,
568 c.getTrace());
569
570 return new Supertypes(Lists.newArrayList(Collections2.filter(allSupertypes, VALID_SUPERTYPE)));
571 }
572 },
573 new Function1<Boolean, Supertypes>() {
574 @Override
575 public Supertypes invoke(Boolean firstTime) {
576 return new Supertypes(Collections.<KotlinType>emptyList());
577 }
578 },
579 new Function1<Supertypes, Unit>() {
580 @Override
581 public Unit invoke(@NotNull Supertypes supertypes) {
582 findAndDisconnectLoopsInTypeHierarchy(supertypes.trueSupertypes);
583 return Unit.INSTANCE$;
584 }
585 }
586 );
587
588 private final NotNullLazyValue<List<TypeParameterDescriptor>> parameters = c.getStorageManager().createLazyValue(new Function0<List<TypeParameterDescriptor>>() {
589 @Override
590 public List<TypeParameterDescriptor> invoke() {
591 return TypeParameterUtilsKt.computeConstructorTypeParameters(LazyClassDescriptor.this);
592 }
593 });
594
595 private final NullableLazyValue<Void> forceResolveAllContents =
596 c.getStorageManager().createRecursionTolerantNullableLazyValue(new Function0<Void>() {
597 @Override
598 public Void invoke() {
599 doForceResolveAllContents();
600 return null;
601 }
602 }, null);
603
604 @NotNull
605 @Override
606 public List<TypeParameterDescriptor> getParameters() {
607 return parameters.invoke();
608 }
609
610 @NotNull
611 @Override
612 public Collection<KotlinType> getSupertypes() {
613 return supertypes.invoke().trueSupertypes;
614 }
615
616 private void findAndDisconnectLoopsInTypeHierarchy(@Mutable Collection<KotlinType> supertypes) {
617 c.getSupertypeLoopChecker().findLoopsInSupertypesAndDisconnect(
618 typeConstructor, supertypes,
619 new Function1<TypeConstructor, Iterable<? extends KotlinType>>() {
620 @Override
621 public Iterable<? extends KotlinType> invoke(TypeConstructor typeConstructor) {
622 return getNeighbors(typeConstructor);
623 }
624 },
625 new Function1<KotlinType, Unit>() {
626 @Override
627 public Unit invoke(KotlinType type) {
628 ClassifierDescriptor supertypeDescriptor = type.getConstructor().getDeclarationDescriptor();
629 if (supertypeDescriptor instanceof ClassDescriptor) {
630 ClassDescriptor superclass = (ClassDescriptor) supertypeDescriptor;
631 reportCyclicInheritanceHierarchyError(c.getTrace(), LazyClassDescriptor.this, superclass);
632 }
633
634 return Unit.INSTANCE;
635 }
636 }
637 );
638 }
639
640 private void reportCyclicInheritanceHierarchyError(
641 @NotNull BindingTrace trace,
642 @NotNull ClassDescriptor classDescriptor,
643 @NotNull ClassDescriptor superclass
644 ) {
645 PsiElement psiElement = DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);
646
647 PsiElement elementToMark = null;
648 if (psiElement instanceof KtClassOrObject) {
649 KtClassOrObject classOrObject = (KtClassOrObject) psiElement;
650 for (KtSuperTypeListEntry delegationSpecifier : classOrObject.getSuperTypeListEntries()) {
651 KtTypeReference typeReference = delegationSpecifier.getTypeReference();
652 if (typeReference == null) continue;
653 KotlinType supertype = trace.get(TYPE, typeReference);
654 if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
655 elementToMark = typeReference;
656 }
657 }
658 }
659 if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
660 PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
661 PsiElement nameIdentifier = namedElement.getNameIdentifier();
662 if (nameIdentifier != null) {
663 elementToMark = nameIdentifier;
664 }
665 }
666 if (elementToMark != null) {
667 trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
668 }
669 }
670
671 private Collection<KotlinType> getNeighbors(TypeConstructor from) {
672 // Supertypes + type for container
673 Collection<KotlinType> neighbours = new ArrayList<KotlinType>(
674 from instanceof LazyClassTypeConstructor
675 ? ((LazyClassTypeConstructor) from).supertypes.invoke().getAllSupertypes()
676 : from.getSupertypes()
677 );
678
679 ClassifierDescriptor fromDescriptor = from.getDeclarationDescriptor();
680 if (fromDescriptor != null) {
681 DeclarationDescriptor container = fromDescriptor.getContainingDeclaration();
682 if (container instanceof ClassDescriptor) {
683 neighbours.add(((ClassDescriptor) container).getDefaultType());
684 }
685 }
686 return neighbours;
687 }
688
689 @Override
690 public boolean isFinal() {
691 return getModality() == Modality.FINAL;
692 }
693
694 @Override
695 public boolean isDenotable() {
696 return true;
697 }
698
699 @Override
700 @NotNull
701 public ClassifierDescriptor getDeclarationDescriptor() {
702 return LazyClassDescriptor.this;
703 }
704
705 @NotNull
706 @Override
707 public Annotations getAnnotations() {
708 return Annotations.Companion.getEMPTY(); // TODO
709 }
710
711 @Override
712 public String toString() {
713 return LazyClassDescriptor.this.getName().toString();
714 }
715
716 @Override
717 public void forceResolveAllContents() {
718 forceResolveAllContents.invoke();
719 }
720
721 private void doForceResolveAllContents() {
722 ForceResolveUtil.forceResolveAllContents(getAnnotations());
723 ForceResolveUtil.forceResolveAllContents(getSupertypes());
724 ForceResolveUtil.forceResolveAllContents(getParameters());
725 }
726 }
727 }