public void resolveSuperTypeEntryList()

in compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java [277:436]


    public void resolveSuperTypeEntryList(
            @NotNull DataFlowInfo outerDataFlowInfo,
            @NotNull KtClassOrObject ktClass,
            @NotNull ClassDescriptor descriptor,
            @Nullable ConstructorDescriptor primaryConstructor,
            @NotNull LexicalScope scopeForConstructorResolution,
            @NotNull LexicalScope scopeForMemberResolution,
            @Nullable InferenceSession inferenceSession
    ) {
        ProgressManager.checkCanceled();

        LexicalScope scopeForConstructor =
                primaryConstructor == null
                ? null
                : FunctionDescriptorUtil.getFunctionInnerScope(scopeForConstructorResolution, primaryConstructor, trace, overloadChecker);
        if (primaryConstructor == null) {
            checkRedeclarationsInClassHeaderWithoutPrimaryConstructor(descriptor, scopeForConstructorResolution);
        }
        ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow

        Map<KtTypeReference, KotlinType> supertypes = Maps.newLinkedHashMap();
        ResolvedCall<?>[] primaryConstructorDelegationCall = new ResolvedCall[1];
        KtVisitorVoid visitor = new KtVisitorVoid() {
            private void recordSupertype(KtTypeReference typeReference, KotlinType supertype) {
                if (supertype == null) return;
                supertypes.put(typeReference, supertype);
            }

            @Override
            public void visitDelegatedSuperTypeEntry(@NotNull KtDelegatedSuperTypeEntry specifier) {
                if (descriptor.getKind() == ClassKind.INTERFACE) {
                    trace.report(DELEGATION_IN_INTERFACE.on(specifier));
                }
                KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
                recordSupertype(specifier.getTypeReference(), supertype);
                if (supertype != null) {
                    DeclarationDescriptor declarationDescriptor = supertype.getConstructor().getDeclarationDescriptor();
                    if (declarationDescriptor instanceof ClassDescriptor) {
                        ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
                        if (classDescriptor.getKind() != ClassKind.INTERFACE) {
                            trace.report(DELEGATION_NOT_TO_INTERFACE.on(specifier.getTypeReference()));
                        }
                    }
                }
                KtExpression delegateExpression = specifier.getDelegateExpression();
                if (delegateExpression != null) {
                    LexicalScope scope = scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor;
                    KotlinType expectedType = supertype != null ? supertype : NO_EXPECTED_TYPE;
                    typeInferrer.getType(
                            scope, delegateExpression, expectedType, outerDataFlowInfo,
                            inferenceSession != null ? inferenceSession : InferenceSession.Companion.getDefault(), trace
                    );
                }

                if (descriptor.isExpect()) {
                    trace.report(IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS.on(specifier));
                }
                else if (primaryConstructor == null) {
                    trace.report(UNSUPPORTED.on(specifier, "Delegation without primary constructor is not supported"));
                }
            }

            @Override
            public void visitSuperTypeCallEntry(@NotNull KtSuperTypeCallEntry call) {
                KtValueArgumentList valueArgumentList = call.getValueArgumentList();
                PsiElement elementToMark = valueArgumentList == null ? call : valueArgumentList;
                if (descriptor.getKind() == ClassKind.INTERFACE) {
                    trace.report(SUPERTYPE_INITIALIZED_IN_INTERFACE.on(elementToMark));
                }
                if (descriptor.isExpect()) {
                    trace.report(SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS.on(elementToMark));
                }
                KtTypeReference typeReference = call.getTypeReference();
                if (typeReference == null) return;
                if (primaryConstructor == null) {
                    if (descriptor.getKind() != ClassKind.INTERFACE) {
                        trace.report(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR.on(call));
                    }
                    recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
                    return;
                }
                OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
                        trace, scopeForConstructor, CallMaker.makeConstructorCallWithoutTypeArguments(call),
                        NO_EXPECTED_TYPE, outerDataFlowInfo, false, inferenceSession
                );
                if (results.isSingleResult()) {
                    KotlinType supertype = results.getResultingDescriptor().getReturnType();
                    recordSupertype(typeReference, supertype);
                    ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
                    if (classDescriptor != null) {
                        // allow only one delegating constructor
                        if (primaryConstructorDelegationCall[0] == null) {
                            primaryConstructorDelegationCall[0] = results.getResultingCall();
                        }
                        else {
                            primaryConstructorDelegationCall[0] = null;
                        }
                    }
                    // Recording type info for callee to use later in JetObjectLiteralExpression
                    trace.record(PROCESSED, call.getCalleeExpression(), true);
                    trace.record(EXPRESSION_TYPE_INFO, call.getCalleeExpression(),
                                 TypeInfoFactoryKt.noTypeInfo(results.getResultingCall().getDataFlowInfoForArguments().getResultInfo()));
                }
                else {
                    recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
                }
            }

            @Override
            public void visitSuperTypeEntry(@NotNull KtSuperTypeEntry specifier) {
                KtTypeReference typeReference = specifier.getTypeReference();
                KotlinType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
                recordSupertype(typeReference, supertype);
                if (supertype == null) return;
                ClassDescriptor superClass = TypeUtils.getClassDescriptor(supertype);
                if (superClass == null) return;
                if (superClass.getKind().isSingleton()) {
                    // A "singleton in supertype" diagnostic will be reported later
                    return;
                }
                if (descriptor.getKind() != ClassKind.INTERFACE &&
                    descriptor.getUnsubstitutedPrimaryConstructor() != null &&
                    superClass.getKind() != ClassKind.INTERFACE &&
                    !descriptor.isExpect() && !isEffectivelyExternal(descriptor) &&
                    !ErrorUtils.isError(superClass)
                ) {
                    trace.report(SUPERTYPE_NOT_INITIALIZED.on(specifier));
                }
            }

            @Override
            public void visitKtElement(@NotNull KtElement element) {
                throw new UnsupportedOperationException(element.getText() + " : " + element);
            }
        };

        if (ktClass instanceof KtEnumEntry && DescriptorUtils.isEnumEntry(descriptor) && ktClass.getSuperTypeListEntries().isEmpty()) {
            assert scopeForConstructor != null : "Scope for enum class constructor should be non-null: " + descriptor;
            resolveConstructorCallForEnumEntryWithoutInitializer(
                    (KtEnumEntry) ktClass, descriptor, scopeForConstructor,
                    outerDataFlowInfo, primaryConstructorDelegationCall, inferenceSession
            );
        }

        for (KtSuperTypeListEntry delegationSpecifier : ktClass.getSuperTypeListEntries()) {
            ProgressManager.checkCanceled();

            delegationSpecifier.accept(visitor);
        }

        if (DescriptorUtils.isAnnotationClass(descriptor) && ktClass.getSuperTypeList() != null) {
            trace.report(SUPERTYPES_FOR_ANNOTATION_CLASS.on(ktClass.getSuperTypeList()));
        }

        if (primaryConstructorDelegationCall[0] != null && primaryConstructor != null) {
            recordConstructorDelegationCall(trace, primaryConstructor, primaryConstructorDelegationCall[0]);
        }

        checkSupertypeList(descriptor, supertypes, ktClass);
    }