in compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java [112:350]
public LazyClassDescriptor(
@NotNull LazyClassContext c,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull KtClassLikeInfo classLikeInfo,
boolean isExternal
) {
super(c.getStorageManager(), containingDeclaration, name,
KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject()),
isExternal
);
this.c = c;
classOrObject = classLikeInfo.getCorrespondingClassOrObject();
this.declarationProvider = c.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfo);
StorageManager storageManager = c.getStorageManager();
this.scopesHolderForClass = createScopesHolderForClass(c, this.declarationProvider);
this.kind = classLikeInfo.getClassKind();
this.staticScope = kind == ClassKind.ENUM_CLASS ?
new StaticScopeForKotlinEnum(
storageManager, this, /* enumEntriesCanBeUsed = */ true
) : MemberScope.Empty.INSTANCE;
this.typeConstructor = new LazyClassTypeConstructor();
this.isCompanionObject = classLikeInfo instanceof KtObjectInfo && ((KtObjectInfo) classLikeInfo).isCompanionObject();
KtModifierList modifierList = classLikeInfo.getModifierList();
if (kind.isSingleton()) {
this.modality = storageManager.createLazyValue(() -> Modality.FINAL);
}
else {
Modality defaultModality = kind == ClassKind.INTERFACE ? Modality.ABSTRACT : Modality.FINAL;
this.modality = storageManager.createLazyValue(
() -> resolveModalityFromModifiers(classOrObject, defaultModality, c.getTrace().getBindingContext(),
null, /* allowSealed = */ true));
}
boolean isLocal = classOrObject != null && KtPsiUtil.isLocal(classOrObject);
this.visibility = isLocal ? DescriptorVisibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, DescriptorVisibilities.DEFAULT_VISIBILITY);
this.isInner = modifierList != null && modifierList.hasModifier(INNER_KEYWORD) && !isIllegalInner(this);
this.isData = modifierList != null && modifierList.hasModifier(KtTokens.DATA_KEYWORD);
this.isInline = modifierList != null && modifierList.hasModifier(KtTokens.INLINE_KEYWORD);
this.isActual = modifierList != null && PsiUtilsKt.hasActualModifier(modifierList);
this.isExpect = modifierList != null && PsiUtilsKt.hasExpectModifier(modifierList) ||
containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).isExpect();
this.isFun = modifierList != null && PsiUtilsKt.hasFunModifier(modifierList);
this.isValue = modifierList != null && PsiUtilsKt.hasValueModifier(modifierList);
// Annotation entries are taken from both own annotations (if any) and object literal annotations (if any)
List<KtAnnotationEntry> annotationEntries = new ArrayList<>();
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> ktDanglingAnnotations = classLikeInfo.getDanglingAnnotations();
if (ktDanglingAnnotations.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();
}
},
ktDanglingAnnotations
);
}
this.companionObjectDescriptor = storageManager.createNullableLazyValue(
() -> computeCompanionObjectDescriptor(getCompanionObjectIfAllowed())
);
this.extraCompanionObjectDescriptors = storageManager.createMemoizedFunction(this::computeCompanionObjectDescriptor);
this.forceResolveAllContents = storageManager.createRecursionTolerantNullableLazyValue(() -> {
doForceResolveAllContents();
return null;
}, null);
this.resolutionScopesSupport = new ClassResolutionScopesSupport(
this,
storageManager,
c.getLanguageVersionSettings(),
this::getOuterScope
);
this.parameters = c.getStorageManager().createLazyValue(() -> {
KtClassLikeInfo classInfo = declarationProvider.getOwnerInfo();
KtTypeParameterList typeParameterList = classInfo.getTypeParameterList();
if (typeParameterList == null) return Collections.emptyList();
boolean isAnonymousObject = (classInfo.getClassKind() == ClassKind.CLASS) && (classInfo.getCorrespondingClassOrObject() instanceof KtObjectDeclaration);
if (classInfo.getClassKind() == ClassKind.ENUM_CLASS) {
c.getTrace().report(TYPE_PARAMETERS_IN_ENUM.on(typeParameterList));
}
if (classInfo.getClassKind() == ClassKind.OBJECT) {
c.getTrace().report(TYPE_PARAMETERS_IN_OBJECT.on(typeParameterList));
}
if (isAnonymousObject) {
DiagnosticFactory0<KtTypeParameterList> diagnosticFactory;
if (c.getLanguageVersionSettings().supportsFeature(LanguageFeature.ProhibitTypeParametersInAnonymousObjects)) {
diagnosticFactory = TYPE_PARAMETERS_IN_OBJECT;
} else {
diagnosticFactory = TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT;
}
c.getTrace().report(diagnosticFactory.on(typeParameterList));
}
List<KtTypeParameter> typeParameters = typeParameterList.getParameters();
if (typeParameters.isEmpty()) return Collections.emptyList();
boolean supportClassTypeParameterAnnotations = c.getLanguageVersionSettings().supportsFeature(LanguageFeature.ClassTypeParameterAnnotations);
List<TypeParameterDescriptor> parameters = new ArrayList<>(typeParameters.size());
for (int i = 0; i < typeParameters.size(); i++) {
KtTypeParameter parameter = typeParameters.get(i);
Annotations lazyAnnotations;
if (supportClassTypeParameterAnnotations) {
lazyAnnotations = new LazyAnnotations(
new LazyAnnotationsContext(
c.getAnnotationResolver(),
storageManager,
c.getTrace()
) {
@NotNull
@Override
public LexicalScope getScope() {
return getOuterScope();
}
},
parameter.getAnnotationEntries()
);
} else {
lazyAnnotations = Annotations.Companion.getEMPTY();
}
parameters.add(new LazyTypeParameterDescriptor(c, this, parameter, lazyAnnotations, i));
}
return parameters;
});
this.scopeForInitializerResolution = storageManager.createLazyValue(
() -> ClassResolutionScopesSupportKt.scopeForInitializerResolution(
this, createInitializerScopeParent(), classLikeInfo.getPrimaryConstructorParameters()
)
);
boolean freedomForSealedInterfacesSupported = c.getLanguageVersionSettings().supportsFeature(LanguageFeature.AllowSealedInheritorsInDifferentFilesOfSamePackage);
this.sealedSubclasses =
storageManager.createLazyValue(() -> {
if (getModality() == Modality.SEALED) {
return c.getSealedClassInheritorsProvider().computeSealedSubclasses(this, freedomForSealedInterfacesSupported);
}
else {
return Collections.emptyList();
}
});
this.contextReceivers = storageManager.createLazyValue(() -> {
if (classOrObject == null) {
return CollectionsKt.emptyList();
}
List<KtContextReceiver> contextReceivers = classOrObject.getContextReceivers();
List<ReceiverParameterDescriptor> contextReceiverDescriptors =
IntStream.range(0, contextReceivers.size())
.mapToObj(index -> {
KtContextReceiver contextReceiver = contextReceivers.get(index);
KtTypeReference typeReference = contextReceiver.typeReference();
if (typeReference == null) return null;
KotlinType kotlinType =
c.getTypeResolver().resolveType(getScopeForClassHeaderResolution(), typeReference, c.getTrace(), true);
Name label = contextReceiver.labelNameAsName() != null
? contextReceiver.labelNameAsName()
: contextReceiverName(index);
return DescriptorFactory.createContextReceiverParameterForClass(
this,
kotlinType,
contextReceiver.labelNameAsName(),
Annotations.Companion.getEMPTY(),
index
);
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (c.getLanguageVersionSettings().supportsFeature(LanguageFeature.ContextReceivers)) {
HashMultimap<String, ReceiverParameterDescriptor> labelNameToReceiverMap = HashMultimap.create();
for (int i = 0; i < contextReceivers.size(); i++) {
labelNameToReceiverMap.put(contextReceivers.get(i).name(), contextReceiverDescriptors.get(i));
}
c.getTrace().record(BindingContext.DESCRIPTOR_TO_CONTEXT_RECEIVER_MAP, this, labelNameToReceiverMap);
}
return contextReceiverDescriptors;
});
if (classOrObject != null) {
this.c.getTrace().record(BindingContext.CLASS, classOrObject, this);
}
this.c.getTrace().record(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, DescriptorUtils.getFqName(this), this);
}