private void reportCyclicInheritanceHierarchyError( @NotNull BindingTrace trace, @NotNull ClassDescriptor classDescriptor, @NotNull ClassDescriptor superclass) { PsiElement psiElement = DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor); PsiElement elementToMark = null; if (psiElement instanceof KtClassOrObject) { KtClassOrObject classOrObject = (KtClassOrObject) psiElement; for (KtSuperTypeListEntry delegationSpecifier : classOrObject.getSuperTypeListEntries()) { KtTypeReference typeReference = delegationSpecifier.getTypeReference(); if (typeReference == null) continue; KotlinType supertype = trace.get(TYPE, typeReference); if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) { elementToMark = typeReference; } } } if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) { PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement; PsiElement nameIdentifier = namedElement.getNameIdentifier(); if (nameIdentifier != null) { elementToMark = nameIdentifier; } } if (elementToMark != null) { trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark)); } }
public LazyClassDescriptor( @NotNull final LazyClassContext c, @NotNull DeclarationDescriptor containingDeclaration, @NotNull Name name, @NotNull final KtClassLikeInfo classLikeInfo) { super( c.getStorageManager(), containingDeclaration, name, KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject())); this.c = c; KtClassOrObject classOrObject = classLikeInfo.getCorrespondingClassOrObject(); if (classOrObject != null) { this.c.getTrace().record(BindingContext.CLASS, classOrObject, this); } this.c .getTrace() .record(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, DescriptorUtils.getFqName(this), this); this.declarationProvider = c.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfo); StorageManager storageManager = c.getStorageManager(); this.unsubstitutedMemberScope = createMemberScope(c, this.declarationProvider); this.kind = classLikeInfo.getClassKind(); this.staticScope = kind == ClassKind.ENUM_CLASS ? new StaticScopeForKotlinEnum(storageManager, this) : MemberScope.Empty.INSTANCE; this.typeConstructor = new LazyClassTypeConstructor(); this.isCompanionObject = classLikeInfo instanceof KtObjectInfo && ((KtObjectInfo) classLikeInfo).isCompanionObject(); KtModifierList modifierList = classLikeInfo.getModifierList(); if (kind.isSingleton()) { this.modality = Modality.FINAL; } else { Modality defaultModality = kind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL; this.modality = resolveModalityFromModifiers(modifierList, defaultModality, /* allowSealed = */ true); } boolean isLocal = classOrObject != null && KtPsiUtil.isLocal(classOrObject); Visibility defaultVisibility; if (kind == ClassKind.ENUM_ENTRY || (kind == ClassKind.OBJECT && isCompanionObject)) { defaultVisibility = Visibilities.PUBLIC; } else { defaultVisibility = Visibilities.DEFAULT_VISIBILITY; } this.visibility = isLocal ? Visibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, defaultVisibility); this.isInner = isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(this); this.isData = modifierList != null && modifierList.hasModifier(KtTokens.DATA_KEYWORD); // Annotation entries are taken from both own annotations (if any) and object literal // annotations (if any) List<KtAnnotationEntry> annotationEntries = new ArrayList<KtAnnotationEntry>(); if (classOrObject != null && classOrObject.getParent() instanceof KtObjectLiteralExpression) { // TODO: it would be better to have separate ObjectLiteralDescriptor without so much magic annotationEntries.addAll( KtPsiUtilKt.getAnnotationEntries((KtObjectLiteralExpression) classOrObject.getParent())); } if (modifierList != null) { annotationEntries.addAll(modifierList.getAnnotationEntries()); } if (!annotationEntries.isEmpty()) { this.annotations = new LazyAnnotations( new LazyAnnotationsContext(c.getAnnotationResolver(), storageManager, c.getTrace()) { @NotNull @Override public LexicalScope getScope() { return getOuterScope(); } }, annotationEntries); } else { this.annotations = Annotations.Companion.getEMPTY(); } List<KtAnnotationEntry> jetDanglingAnnotations = classLikeInfo.getDanglingAnnotations(); if (jetDanglingAnnotations.isEmpty()) { this.danglingAnnotations = Annotations.Companion.getEMPTY(); } else { this.danglingAnnotations = new LazyAnnotations( new LazyAnnotationsContext(c.getAnnotationResolver(), storageManager, c.getTrace()) { @NotNull @Override public LexicalScope getScope() { return getScopeForMemberDeclarationResolution(); } }, jetDanglingAnnotations); } this.companionObjectDescriptor = storageManager.createNullableLazyValue( new Function0<LazyClassDescriptor>() { @Override public LazyClassDescriptor invoke() { return computeCompanionObjectDescriptor(getCompanionObjectIfAllowed()); } }); this.extraCompanionObjectDescriptors = storageManager.createMemoizedFunction( new Function1<KtObjectDeclaration, ClassDescriptor>() { @Override public ClassDescriptor invoke(KtObjectDeclaration companionObject) { return computeCompanionObjectDescriptor(companionObject); } }); this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue( new Function0<Void>() { @Override public Void invoke() { doForceResolveAllContents(); return null; } }, null); this.resolutionScopesSupport = new ClassResolutionScopesSupport( this, storageManager, new Function0<LexicalScope>() { @Override public LexicalScope invoke() { return getOuterScope(); } }); this.parameters = c.getStorageManager() .createLazyValue( new Function0<List<TypeParameterDescriptor>>() { @Override public List<TypeParameterDescriptor> invoke() { KtClassLikeInfo classInfo = declarationProvider.getOwnerInfo(); KtTypeParameterList typeParameterList = classInfo.getTypeParameterList(); if (typeParameterList == null) return Collections.emptyList(); if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) { c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList)); } List<KtTypeParameter> typeParameters = typeParameterList.getParameters(); if (typeParameters.isEmpty()) return Collections.emptyList(); List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>(typeParameters.size()); for (int i = 0; i < typeParameters.size(); i++) { parameters.add( new LazyTypeParameterDescriptor( c, LazyClassDescriptor.this, typeParameters.get(i), i)); } return parameters; } }); this.scopeForInitializerResolution = storageManager.createLazyValue( new Function0<LexicalScope>() { @Override public LexicalScope invoke() { return ClassResolutionScopesSupportKt.scopeForInitializerResolution( LazyClassDescriptor.this, createInitializerScopeParent(), classLikeInfo.getPrimaryConstructorParameters()); } }); }