Search in sources :

Example 1 with AnnotationSplitter

use of org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter in project kotlin by JetBrains.

the class DescriptorResolver method resolvePropertyDescriptor.

@NotNull
public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull LexicalScope scopeForDeclarationResolution, @NotNull LexicalScope scopeForInitializerResolution, @NotNull KtProperty property, @NotNull final BindingTrace trace, @NotNull DataFlowInfo dataFlowInfo) {
    KtModifierList modifierList = property.getModifierList();
    boolean isVar = property.isVar();
    boolean hasBody = hasBody(property);
    Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
    Modality modality = containingDeclaration instanceof ClassDescriptor ? resolveMemberModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody), trace.getBindingContext(), containingDeclaration) : Modality.FINAL;
    final AnnotationSplitter.PropertyWrapper wrapper = new AnnotationSplitter.PropertyWrapper(property);
    Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scopeForDeclarationResolution, modifierList, trace);
    AnnotationSplitter annotationSplitter = new AnnotationSplitter(storageManager, allAnnotations, new Function0<Set<AnnotationUseSiteTarget>>() {

        @Override
        public Set<AnnotationUseSiteTarget> invoke() {
            return AnnotationSplitter.getTargetSet(false, trace.getBindingContext(), wrapper);
        }
    });
    Annotations propertyAnnotations = new CompositeAnnotations(CollectionsKt.listOf(annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD, PROPERTY_DELEGATE_FIELD), annotationSplitter.getOtherAnnotations()));
    PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(containingDeclaration, propertyAnnotations, modality, visibility, isVar, KtPsiUtil.safeName(property.getName()), CallableMemberDescriptor.Kind.DECLARATION, KotlinSourceElementKt.toSourceElement(property), modifierList != null && modifierList.hasModifier(KtTokens.LATEINIT_KEYWORD), modifierList != null && modifierList.hasModifier(KtTokens.CONST_KEYWORD), modifierList != null && modifierList.hasModifier(KtTokens.HEADER_KEYWORD) || containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).isHeader(), modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD), modifierList != null && modifierList.hasModifier(KtTokens.EXTERNAL_KEYWORD), property.hasDelegate());
    wrapper.setDescriptor(propertyDescriptor);
    List<TypeParameterDescriptorImpl> typeParameterDescriptors;
    LexicalScope scopeForDeclarationResolutionWithTypeParameters;
    LexicalScope scopeForInitializerResolutionWithTypeParameters;
    KotlinType receiverType = null;
    {
        List<KtTypeParameter> typeParameters = property.getTypeParameters();
        if (typeParameters.isEmpty()) {
            scopeForDeclarationResolutionWithTypeParameters = scopeForDeclarationResolution;
            scopeForInitializerResolutionWithTypeParameters = scopeForInitializerResolution;
            typeParameterDescriptors = Collections.emptyList();
        } else {
            LexicalWritableScope writableScopeForDeclarationResolution = new LexicalWritableScope(scopeForDeclarationResolution, containingDeclaration, false, new TraceBasedLocalRedeclarationChecker(trace, overloadChecker), LexicalScopeKind.PROPERTY_HEADER);
            LexicalWritableScope writableScopeForInitializerResolution = new LexicalWritableScope(scopeForInitializerResolution, containingDeclaration, 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(property, propertyDescriptor, writableScopeForDeclarationResolution, typeParameterDescriptors, trace);
            scopeForDeclarationResolutionWithTypeParameters = writableScopeForDeclarationResolution;
            scopeForInitializerResolutionWithTypeParameters = writableScopeForInitializerResolution;
        }
        KtTypeReference receiverTypeRef = property.getReceiverTypeReference();
        if (receiverTypeRef != null) {
            receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true);
        }
    }
    ReceiverParameterDescriptor receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(propertyDescriptor, receiverType);
    LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
    KotlinType typeIfKnown = variableTypeAndInitializerResolver.resolveTypeNullable(propertyDescriptor, scopeForInitializer, property, dataFlowInfo, /* local = */
    trace, false);
    PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(scopeForDeclarationResolutionWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace, typeIfKnown);
    KotlinType type = typeIfKnown != null ? typeIfKnown : getter.getReturnType();
    assert type != null : "At least getter type must be initialized via resolvePropertyGetterDescriptor";
    variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(propertyDescriptor, scopeForInitializer, property, dataFlowInfo, type, trace);
    propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(containingDeclaration), receiverDescriptor);
    PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeForDeclarationResolutionWithTypeParameters, property, propertyDescriptor, annotationSplitter, trace);
    propertyDescriptor.initialize(getter, setter);
    trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
    return propertyDescriptor;
}
Also used : CompositeAnnotations(org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations) CompositeAnnotations(org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations) Annotations(org.jetbrains.kotlin.descriptors.annotations.Annotations) AnnotationSplitter(org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with AnnotationSplitter

use of org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter in project kotlin by JetBrains.

the class DescriptorResolver method resolvePrimaryConstructorParameterToAProperty.

@NotNull
public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(@NotNull ClassDescriptor classDescriptor, @NotNull ValueParameterDescriptor valueParameter, @NotNull LexicalScope scope, @NotNull KtParameter parameter, final BindingTrace trace) {
    KotlinType type = resolveParameterType(scope, parameter, trace);
    Name name = parameter.getNameAsSafeName();
    boolean isMutable = parameter.isMutable();
    KtModifierList modifierList = parameter.getModifierList();
    if (modifierList != null) {
        if (modifierList.hasModifier(KtTokens.ABSTRACT_KEYWORD)) {
            trace.report(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.on(parameter));
        }
    }
    final AnnotationSplitter.PropertyWrapper propertyWrapper = new AnnotationSplitter.PropertyWrapper(parameter);
    Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, parameter.getModifierList(), trace);
    AnnotationSplitter annotationSplitter = new AnnotationSplitter(storageManager, allAnnotations, new Function0<Set<AnnotationUseSiteTarget>>() {

        @Override
        public Set<AnnotationUseSiteTarget> invoke() {
            return AnnotationSplitter.getTargetSet(true, trace.getBindingContext(), propertyWrapper);
        }
    });
    Annotations propertyAnnotations = new CompositeAnnotations(annotationSplitter.getAnnotationsForTargets(PROPERTY, FIELD), annotationSplitter.getOtherAnnotations());
    PropertyDescriptorImpl propertyDescriptor = PropertyDescriptorImpl.create(classDescriptor, propertyAnnotations, resolveMemberModalityFromModifiers(parameter, Modality.FINAL, trace.getBindingContext(), classDescriptor), resolveVisibilityFromModifiers(parameter, getDefaultVisibility(parameter, classDescriptor)), isMutable, name, CallableMemberDescriptor.Kind.DECLARATION, KotlinSourceElementKt.toSourceElement(parameter), false, false, classDescriptor.isHeader(), modifierList != null && modifierList.hasModifier(KtTokens.IMPL_KEYWORD), false, false);
    propertyWrapper.setDescriptor(propertyDescriptor);
    propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), getDispatchReceiverParameterIfNeeded(classDescriptor), (ReceiverParameterDescriptor) null);
    Annotations setterAnnotations = annotationSplitter.getAnnotationsForTarget(PROPERTY_SETTER);
    Annotations getterAnnotations = new CompositeAnnotations(CollectionsKt.listOf(annotationSplitter.getAnnotationsForTarget(PROPERTY_GETTER)));
    PropertyGetterDescriptorImpl getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, getterAnnotations);
    PropertySetterDescriptor setter = propertyDescriptor.isVar() ? DescriptorFactory.createDefaultSetter(propertyDescriptor, setterAnnotations) : null;
    propertyDescriptor.initialize(getter, setter);
    getter.initialize(propertyDescriptor.getType());
    trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor);
    trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter, propertyDescriptor);
    return propertyDescriptor;
}
Also used : CompositeAnnotations(org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations) FqName(org.jetbrains.kotlin.name.FqName) Name(org.jetbrains.kotlin.name.Name) CompositeAnnotations(org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations) Annotations(org.jetbrains.kotlin.descriptors.annotations.Annotations) AnnotationSplitter(org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with AnnotationSplitter

use of org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter in project kotlin by JetBrains.

the class DescriptorResolver method resolveValueParameterDescriptor.

@NotNull
public ValueParameterDescriptorImpl resolveValueParameterDescriptor(@NotNull final LexicalScope scope, @NotNull final FunctionDescriptor owner, @NotNull KtParameter valueParameter, int index, @NotNull final KotlinType type, @NotNull final BindingTrace trace) {
    KotlinType varargElementType = null;
    KotlinType variableType = type;
    if (valueParameter.hasModifier(VARARG_KEYWORD)) {
        varargElementType = type;
        variableType = getVarargParameterType(type);
    }
    KtModifierList modifierList = valueParameter.getModifierList();
    Annotations allAnnotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, valueParameter.getModifierList(), trace);
    Annotations valueParameterAnnotations = Annotations.Companion.getEMPTY();
    if (modifierList != null) {
        if (valueParameter.hasValOrVar()) {
            AnnotationSplitter annotationSplitter = AnnotationSplitter.create(storageManager, allAnnotations, SetsKt.setOf(CONSTRUCTOR_PARAMETER));
            valueParameterAnnotations = annotationSplitter.getAnnotationsForTarget(CONSTRUCTOR_PARAMETER);
        } else {
            valueParameterAnnotations = allAnnotations;
        }
    }
    final KtDestructuringDeclaration destructuringDeclaration = valueParameter.getDestructuringDeclaration();
    Function0<List<VariableDescriptor>> destructuringVariables;
    if (destructuringDeclaration != null) {
        if (!languageVersionSettings.supportsFeature(LanguageFeature.DestructuringLambdaParameters)) {
            trace.report(Errors.UNSUPPORTED_FEATURE.on(valueParameter, TuplesKt.to(LanguageFeature.DestructuringLambdaParameters, languageVersionSettings)));
        }
        destructuringVariables = new Function0<List<VariableDescriptor>>() {

            @Override
            public List<VariableDescriptor> invoke() {
                assert owner.getDispatchReceiverParameter() == null : "Destructuring declarations are only be parsed for lambdas, and they must not have a dispatch receiver";
                LexicalScope scopeForDestructuring = ScopeUtilsKt.createScopeForDestructuring(scope, owner.getExtensionReceiverParameter());
                List<VariableDescriptor> result = destructuringDeclarationResolver.resolveLocalVariablesFromDestructuringDeclaration(scope, destructuringDeclaration, new TransientReceiver(type), /* initializer = */
                null, ExpressionTypingContext.newContext(trace, scopeForDestructuring, DataFlowInfoFactory.EMPTY, TypeUtils.NO_EXPECTED_TYPE));
                modifiersChecker.withTrace(trace).checkModifiersForDestructuringDeclaration(destructuringDeclaration);
                return result;
            }
        };
    } else {
        destructuringVariables = null;
    }
    Name parameterName;
    if (destructuringDeclaration == null) {
        // NB: val/var for parameter is only allowed in primary constructors where single underscore names are still prohibited.
        // The problem with val/var is that when lazy resolve try to find their descriptor, it searches through the member scope
        // of containing class where, it can not find a descriptor with special name.
        // Thus, to preserve behavior, we don't use a special name for val/var.
        parameterName = !valueParameter.hasValOrVar() && UnderscoreUtilKt.isSingleUnderscore(valueParameter) ? Name.special("<anonymous parameter " + index + ">") : KtPsiUtil.safeName(valueParameter.getName());
    } else {
        parameterName = Name.special("<name for destructuring parameter " + index + ">");
    }
    ValueParameterDescriptorImpl valueParameterDescriptor = ValueParameterDescriptorImpl.createWithDestructuringDeclarations(owner, null, index, valueParameterAnnotations, parameterName, variableType, valueParameter.hasDefaultValue(), valueParameter.hasModifier(CROSSINLINE_KEYWORD), valueParameter.hasModifier(NOINLINE_KEYWORD), varargElementType, KotlinSourceElementKt.toSourceElement(valueParameter), destructuringVariables);
    trace.record(BindingContext.VALUE_PARAMETER, valueParameter, valueParameterDescriptor);
    return valueParameterDescriptor;
}
Also used : CompositeAnnotations(org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations) Annotations(org.jetbrains.kotlin.descriptors.annotations.Annotations) TransientReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver) AnnotationSplitter(org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter) FqName(org.jetbrains.kotlin.name.FqName) Name(org.jetbrains.kotlin.name.Name) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with AnnotationSplitter

use of org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter in project kotlin by JetBrains.

the class PropertyCodegen method genBackingFieldAndAnnotations.

private void genBackingFieldAndAnnotations(@Nullable KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
    boolean hasBackingField = hasBackingField(descriptor);
    boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();
    AnnotationSplitter annotationSplitter = AnnotationSplitter.create(LockBasedStorageManager.NO_LOCKS, descriptor.getAnnotations(), AnnotationSplitter.getTargetSet(isParameter, descriptor.isVar(), hasBackingField, hasDelegate));
    Annotations propertyAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY);
    // Fields and '$annotations' methods for non-private const properties are generated in the multi-file facade
    boolean isBackingFieldOwner = descriptor.isConst() && !Visibilities.isPrivate(descriptor.getVisibility()) ? !(context instanceof MultifileClassPartContext) : CodegenContextUtil.isImplClassOwner(context);
    if (isBackingFieldOwner) {
        Annotations fieldAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.FIELD);
        Annotations delegateAnnotations = annotationSplitter.getAnnotationsForTarget(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD);
        assert declaration != null : "Declaration is null: " + descriptor + " (context=" + context + ")";
        generateBackingField(declaration, descriptor, fieldAnnotations, delegateAnnotations);
        generateSyntheticMethodIfNeeded(descriptor, propertyAnnotations);
    }
    if (!propertyAnnotations.getAllAnnotations().isEmpty() && kind != OwnerKind.DEFAULT_IMPLS && CodegenContextUtil.isImplClassOwner(context)) {
        v.getSerializationBindings().put(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor, getSyntheticMethodSignature(descriptor));
    }
}
Also used : AnnotatedWithFakeAnnotations(org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations) Annotations(org.jetbrains.kotlin.descriptors.annotations.Annotations) AnnotationSplitter(org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter)

Aggregations

AnnotationSplitter (org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter)4 Annotations (org.jetbrains.kotlin.descriptors.annotations.Annotations)4 NotNull (org.jetbrains.annotations.NotNull)3 CompositeAnnotations (org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations)3 FqName (org.jetbrains.kotlin.name.FqName)2 Name (org.jetbrains.kotlin.name.Name)2 AnnotatedWithFakeAnnotations (org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations)1 TransientReceiver (org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver)1