All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlinx.serialization.compiler.resolve.SerializableProperties.kt Maven / Gradle / Ivy

There is a newer version: 2.1.20-Beta1
Show newest version
/*
 * Copyright 2010-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jetbrains.kotlinx.serialization.compiler.resolve

import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter

class SerializableProperties(private val serializableClass: ClassDescriptor, val bindingContext: BindingContext) {
    private val primaryConstructorParameters: List =
        serializableClass.unsubstitutedPrimaryConstructor?.valueParameters ?: emptyList()

    private val primaryConstructorProperties: Map =
        primaryConstructorParameters.asSequence()
            .map { parameter -> bindingContext[BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter] to parameter.declaresDefaultValue() }
            .mapNotNull { (a, b) -> if (a == null) null else a to b }
            .toMap()

    val isExternallySerializable: Boolean =
        primaryConstructorParameters.size == primaryConstructorProperties.size

    val serializableProperties: List =
        serializableClass.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.VARIABLES)
            .asSequence()
            .filterIsInstance()
            .filter { it.kind == CallableMemberDescriptor.Kind.DECLARATION }
            .filter(this::isPropSerializable)
            .map { prop -> SerializableProperty(prop, primaryConstructorProperties[prop] ?: false) }
            .partition { primaryConstructorProperties.contains(it.descriptor) }
            .run {
                val supers = serializableClass.getSuperClassNotAny()
                if (supers == null || !supers.isInternalSerializable)
                    first + second
                else
                    SerializableProperties(supers, bindingContext).serializableProperties + first + second
            }


    private fun isPropSerializable(it: PropertyDescriptor) =
        if (serializableClass.isInternalSerializable) !it.annotations.serialTransient
        else !Visibilities.isPrivate(it.visibility) && ((it.isVar && !it.annotations.serialTransient) || primaryConstructorProperties.contains(
            it
        ))

    val serializableConstructorProperties: List =
        serializableProperties.asSequence()
            .filter { primaryConstructorProperties.contains(it.descriptor) }
            .toList()

    val serializableStandaloneProperties: List =
        serializableProperties.minus(serializableConstructorProperties)

    val size = serializableProperties.size
    val indices = serializableProperties.indices
    operator fun get(index: Int) = serializableProperties[index]
    operator fun iterator() = serializableProperties.iterator()

    val primaryConstructorWithDefaults = serializableClass.unsubstitutedPrimaryConstructor
        ?.original?.valueParameters?.any { it.declaresDefaultValue() } ?: false
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy