private PropertyDescriptor resolveAsPropertyDescriptor()

in compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java [870:1048]


    private PropertyDescriptor resolveAsPropertyDescriptor(
            @NotNull DeclarationDescriptor container,
            @NotNull LexicalScope scopeForDeclarationResolution,
            @NotNull LexicalScope scopeForInitializerResolution,
            @NotNull KtVariableDeclaration variableDeclaration,
            @NotNull BindingTrace trace,
            @NotNull DataFlowInfo dataFlowInfo,
            @Nullable InferenceSession inferenceSession,
            @NotNull VariableAsPropertyInfo propertyInfo
    ) {
        KtModifierList modifierList = variableDeclaration.getModifierList();
        boolean isVar = variableDeclaration.isVar();

        DescriptorVisibility visibility = resolveVisibilityFromModifiers(variableDeclaration, getDefaultVisibility(variableDeclaration, container));
        Modality modality = container instanceof ClassDescriptor
                            ? resolveMemberModalityFromModifiers(variableDeclaration,
                                                                 getDefaultModality(container, visibility, propertyInfo.getHasBody()),
                                                                 trace.getBindingContext(), container)
                            : Modality.FINAL;

        Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scopeForDeclarationResolution, modifierList, trace);
        Set<AnnotationUseSiteTarget> targetSet = EnumSet.of(PROPERTY, PROPERTY_GETTER, FIELD);
        if (isVar) {
            targetSet.add(PROPERTY_SETTER);
            targetSet.add(SETTER_PARAMETER);
        }
        if (variableDeclaration instanceof KtProperty && ((KtProperty) variableDeclaration).hasDelegate()) {
            targetSet.add(PROPERTY_DELEGATE_FIELD);
        }
        AnnotationSplitter annotationSplitter = new AnnotationSplitter(storageManager, allAnnotations, targetSet);

        Annotations propertyAnnotations = new CompositeAnnotations(CollectionsKt.listOf(
                annotationSplitter.getAnnotationsForTarget(PROPERTY),
                annotationSplitter.getOtherAnnotations())
        );

        PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(
                container,
                propertyAnnotations,
                modality,
                visibility,
                isVar,
                KtPsiUtil.safeName(variableDeclaration.getName()),
                CallableMemberDescriptor.Kind.DECLARATION,
                KotlinSourceElementKt.toSourceElement(variableDeclaration),
                modifierList != null && modifierList.hasModifier(KtTokens.LATEINIT_KEYWORD),
                modifierList != null && modifierList.hasModifier(KtTokens.CONST_KEYWORD),
                modifierList != null && PsiUtilsKt.hasExpectModifier(modifierList) && container instanceof PackageFragmentDescriptor ||
                container instanceof ClassDescriptor && ((ClassDescriptor) container).isExpect(),
                modifierList != null && PsiUtilsKt.hasActualModifier(modifierList),
                modifierList != null && modifierList.hasModifier(KtTokens.EXTERNAL_KEYWORD),
                propertyInfo.getHasDelegate()
        );

        List<TypeParameterDescriptorImpl> typeParameterDescriptors;
        LexicalScope scopeForDeclarationResolutionWithTypeParameters;
        LexicalScope scopeForInitializerResolutionWithTypeParameters;
        KotlinType receiverType = null;

        {
            List<KtTypeParameter> typeParameters = variableDeclaration.getTypeParameters();
            if (typeParameters.isEmpty()) {
                scopeForDeclarationResolutionWithTypeParameters = scopeForDeclarationResolution;
                scopeForInitializerResolutionWithTypeParameters = scopeForInitializerResolution;
                typeParameterDescriptors = Collections.emptyList();
            }
            else {
                LexicalWritableScope writableScopeForDeclarationResolution = new LexicalWritableScope(
                        scopeForDeclarationResolution, container, false, new TraceBasedLocalRedeclarationChecker(trace, overloadChecker),
                        LexicalScopeKind.PROPERTY_HEADER);
                LexicalWritableScope writableScopeForInitializerResolution = new LexicalWritableScope(
                        scopeForInitializerResolution, container, false, LocalRedeclarationChecker.DO_NOTHING.INSTANCE,
                        LexicalScopeKind.PROPERTY_HEADER);
                typeParameterDescriptors = resolveTypeParametersForDescriptor(
                        propertyDescriptor,
                        scopeForDeclarationResolution, typeParameters, trace);
                for (TypeParameterDescriptor descriptor : typeParameterDescriptors) {
                    writableScopeForDeclarationResolution.addClassifierDescriptor(descriptor);
                    writableScopeForInitializerResolution.addClassifierDescriptor(descriptor);
                }
                writableScopeForDeclarationResolution.freeze();
                writableScopeForInitializerResolution.freeze();
                resolveGenericBounds(variableDeclaration, propertyDescriptor, writableScopeForDeclarationResolution, typeParameterDescriptors, trace);
                scopeForDeclarationResolutionWithTypeParameters = writableScopeForDeclarationResolution;
                scopeForInitializerResolutionWithTypeParameters = writableScopeForInitializerResolution;
            }
        }

        KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference();
        ReceiverParameterDescriptor receiverDescriptor = null;
        if (receiverTypeRef != null) {
            receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true);
            AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
            receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
                    propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
            );
        }

        List<KtContextReceiver> contextReceivers = variableDeclaration.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 type = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, typeReference, trace, true);
            AnnotationSplitter splitter = new AnnotationSplitter(storageManager, type.getAnnotations(), EnumSet.of(RECEIVER));
            return DescriptorFactory.createContextReceiverParameterForCallable(
                    propertyDescriptor, type, contextReceiver.labelNameAsName(), splitter.getAnnotationsForTarget(RECEIVER), index
            );
        }).collect(Collectors.toList());

        if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
            Multimap<String, ReceiverParameterDescriptor> nameToReceiverMap = HashMultimap.create();
            if (receiverTypeRef != null) {
                String receiverName = receiverTypeRef.nameForReceiverLabel();
                if (receiverName != null) {
                    nameToReceiverMap.put(receiverName, receiverDescriptor);
                }
            }
            for (int i = 0; i < contextReceivers.size(); i++) {
                String contextReceiverName = contextReceivers.get(i).name();
                if (contextReceiverName != null) {
                    nameToReceiverMap.put(contextReceiverName, contextReceiverDescriptors.get(i));
                }
            }
            trace.record(DESCRIPTOR_TO_CONTEXT_RECEIVER_MAP, propertyDescriptor, nameToReceiverMap);
        }

        LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
        KotlinType propertyType = propertyInfo.getVariableType();
        KotlinType typeIfKnown = propertyType != null ? propertyType : variableTypeAndInitializerResolver.resolveTypeNullable(
                propertyDescriptor, scopeForInitializer,
                variableDeclaration, dataFlowInfo, inferenceSession,
                trace, /* local = */ false
        );

        PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(
                scopeForDeclarationResolutionWithTypeParameters,
                variableDeclaration,
                propertyDescriptor,
                annotationSplitter,
                trace,
                typeIfKnown,
                propertyInfo.getPropertyGetter(),
                propertyInfo.getHasDelegate(),
                inferenceSession
        );

        KotlinType type = typeIfKnown != null ? typeIfKnown : getter.getReturnType();

        assert type != null : "At least getter type must be initialized via resolvePropertyGetterDescriptor";

        variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(
                propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, inferenceSession, trace
        );

        propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(container), receiverDescriptor,
                                   contextReceiverDescriptors);

        PropertySetterDescriptor setter = resolvePropertySetterDescriptor(
                scopeForDeclarationResolutionWithTypeParameters,
                variableDeclaration,
                propertyDescriptor,
                annotationSplitter,
                trace,
                propertyInfo.getPropertySetter(),
                propertyInfo.getHasDelegate(),
                inferenceSession
        );

        propertyDescriptor.initialize(
                getter, setter,
                new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(FIELD), propertyDescriptor),
                new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(PROPERTY_DELEGATE_FIELD), propertyDescriptor)
        );
        trace.record(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor);
        return propertyDescriptor;
    }