function bos/meta/class/isa-for-into() {
bos-namespaces/store-array-for-into "$1" isa "$2"
}
function bos/meta/class/set-superclasses-for() {
local isa_name; $self isa-for-into isa_name "$1"
local -n isa="$isa_name"
shift
isa=( "$@" )
return 0
}
function bos/meta/class/get-superclasses-for-into() {
local -n dest="$1"
local isa_name; $self isa-for-into isa_name "$2"
local -n isa="$isa_name"
dest=( "${isa[@]}" )
return 0
}
function bos/meta/class/mro-for-into() {
bos-namespaces/store-array-for-into "$1" mro "$2"
}
function bos/meta/class/make-mro-for() {
local class="$1"
local mro_name; $self mro-for-into mro_name "$class"
local -n mro="$mro_name"
mro=( "$class" )
local -a nextclasses
$self get-superclasses-for-into nextclasses "$class"
while [[ "${#nextclasses}" -gt 0 ]]; do
mro+=( "${nextclasses[0]}" )
class="${nextclasses[0]}"
$self get-superclasses-for-into nextclasses "$class"
done
mro+=( "bos/base" )
return 0
}
function bos/meta/class/find-method-into() {
local -n bos_meta_class_find_method_result="$1"
local class="$2"
local start_from_class="$3"
local method="$4"
local mro_store; $self mro-for-into mro_store "$class"
local -n mro="$mro_store"
if [[ "${#mro[@]}" -eq 0 ]]; then
mro=( "$class" )
fi
local idx=0
if [[ -n "$start_from_class" ]]; then
for (( ; idx < "${#mro[@]}" ; ++idx )); do
if [[ "${mro[$idx]}" == "$start_from_class" ]]; then
(( ++idx ))
break
fi
done
fi
for (( ; idx < "${#mro[@]}" ; ++idx )); do
local full_name="${mro[$idx]}/${method}"
if declare -F "$full_name" >/dev/null; then
bos_meta_class_find_method_result="${full_name}"
return 0
fi
done
>&2 echo "method $method not found via class $class"
return 1
}
function bos/meta/class/get-attribute-by-name-into() {
>&2 echo "get-attribute-by-name-into($*)"
local -n bos_meta_class_get_attribute_result="$1"; shift
local bos_meta_class_get_attribute_name="$1"
local bos_meta_class_attrs_name
local attribute_type='assoc'
local attribute_name='class_attributes'
local associated_class='bos/meta/class'
bos/meta/attribute/store-for-into bos_meta_class_attrs_name "$self"
local -n bos_meta_class_attrs="$bos_meta_class_attrs_name"
bos_meta_class_get_attribute_result="${bos_meta_class_attrs[$bos_meta_class_get_attribute_name]}"
return 0
}
function bos/meta/class/set-attribute-by-name() {
local bos_meta_class_attrs_name
local attribute_type='assoc'
local attribute_name='class_attributes'
local associated_class='bos/meta/class'
bos/meta/attribute/store-for-into bos_meta_class_attrs_name "$self"
local -n bos_meta_class_attrs="$bos_meta_class_attrs_name"
bos_meta_class_attrs["$1"]="$2"
return 0
}
function bos/meta/class/invoke() {
local bos_invoke_class="$1";shift
local bos_invoke_object_id="$1";shift
local bos_invoke_method="$1";shift
local bos_invoke_start_from_class=''
if [[ "$bos_invoke_method" == 'next/method' ]]; then
local bos_invoke_caller; bos-dispatch/caller-into bos_invoke_caller
bos_invoke_method="${bos_invoke_caller##*/}"
bos_invoke_start_from_class="${bos_invoke_caller%/*}"
fi
local ffsname="to_invoke_${#FUNCNAME[*]}"
$self find-method-into "$ffsname" "$bos_invoke_class" "$bos_invoke_start_from_class" "$bos_invoke_method"
local bos_invoke_target_obj
bos-object-id/pack-self-into bos_invoke_target_obj "$bos_invoke_class" "$bos_invoke_object_id"
local bos_invoke_target_class="${!ffsname%/*}"
local bos_invoke_target_metaclass_instance
bos-meta/metaclass-instance-for-class-into bos_invoke_target_metaclass_instance "$bos_invoke_target_class"
local bos_invoke_attrs_attr
$bos_invoke_target_metaclass_instance get-attribute-by-name-into bos_invoke_attrs_attr 'class_attributes'
>&2 echo "for (${bos_invoke_class}->${bos_invoke_target_class}) class_attributes = $bos_invoke_attrs_attr"
if [[ -n "$bos_invoke_attrs_attr" ]]; then
local -A bos_invoke_attrs
$bos_invoke_attrs_attr get-value-into bos_invoke_attrs "$bos_invoke_target_metaclass_instance"
local bos_invoke_attr_name bos_invoke_attr_store
for bos_invoke_attr_name in "${!bos_invoke_attrs[@]}"; do
bos_invoke_attr_obj="${bos_invoke_attrs[$bos_invoke_attr_name]}"
$bos_invoke_attr_obj store-for-into bos_invoke_attr_store "$bos_invoke_target_obj"
local -n "$bos_invoke_attr_name"="$bos_invoke_attr_store"
done
fi
local self="$bos_invoke_target_obj"
eval "\"\$$ffsname\" \"\$@\""
return $?
}
function bos/meta/class/create-object-into() {
local -n bos_meta_class_create_object_result="$1";shift
local class="$1";shift
local object_id_store; bos-namespaces/store-scalar-for-into object_id_store object_id "$class"
local -n object_id="$object_id_store"
(( ++object_id ))
bos-object-id/pack-self-into bos_meta_class_create_object_result "$class" "$object_id"
return 0
}
function bos/meta/class() {
bos-dispatch/invoke bos/meta/class 0 "$@"
}