bool NFieldType::is_assignable_from()

in src/Trinity.TSL/Trinity.TSL.Parser/SyntaxNode.cpp [326:394]


bool NFieldType::is_assignable_from(NFieldType* that)
{
    if (!NFieldType_Compare(this, that))
        return true;

    if (!this->is_nullable() && that->is_nullable())
        return false;

    if (this->is_nullable() && !that->is_nullable())
    {
        // mark this temporarily as non-optional
        this->field->unset_optional();

        bool non_optional_this_assignable_from_that = this->is_assignable_from(that);

        // mark this back as optional
        this->field->set_optional();

        return non_optional_this_assignable_from_that;
    }

    /* For arrays with same rank & same element type, we say they are compatible. */
    if (this->is_array_same_rank_same_element_type(that))
        return true;

    if (this->is_list() && that->is_list())
        return (0 == NFieldType_Compare(this->listElementType, that->listElementType));

    if (this->is_enum() && that->is_enum())
        return this->referencedNEnum == that->referencedNEnum;

    if (this->is_struct() && that->is_struct())
        return this->referencedNStruct == that->referencedNStruct;

    if (!(this->is_atom() && that->is_atom()))
        return false;

    /* Here we have this->is_atom() and that->is_atom */

    if (this->is_string() && that->is_string())
        return true;

    if (this->is_integral() && that->is_integral())
    {
        return
            (this->type_size() > that->type_size() && (this->is_signed() || !that->is_signed()))
            ||
            (this->type_size() == that->type_size()
             &&
             this->is_signed() == that->is_signed());
    }

    if (this->is_bool() && that->is_bool())
        return true;

    if (this->is_floating_point() && that->is_integral())
        return true;

    if (this->is_floating_point() && that->is_floating_point())
    {
        if (this->is_decimal() /* && !that->is_decimal() */)
            return false;

        return this->type_size() > that->type_size();
    }

    /* anything else, we say this is not assignable from that. */
    return false;
}