From 2c5b23cf001eaea4603c8e5c8067a1d8c51e4151 Mon Sep 17 00:00:00 2001 From: Richard Plevin Date: Tue, 15 Oct 2019 14:49:41 -0700 Subject: [PATCH 1/2] - Generalized connected_params and unconnected_params to work on all composites (not just ModelDefs) - Removed function import_params! - Added function propagate_params! - Added call to propagate_params! to code emitted by @defcomposite, now exporting only unconnected params. - Deprecated old function name() in favor of nameof(). --- src/core/build.jl | 3 +- src/core/connections.jl | 167 +++++++++++++++++++++++---------------- src/core/defcomposite.jl | 13 +-- src/core/defs.jl | 71 +++++------------ 4 files changed, 123 insertions(+), 131 deletions(-) diff --git a/src/core/build.jl b/src/core/build.jl index 92f4cb011..5960ec6fa 100644 --- a/src/core/build.jl +++ b/src/core/build.jl @@ -232,7 +232,6 @@ end function build(m::Model) # fix paths and propagate imports fix_comp_paths!(m.md) - import_params!(m.md) # Reference a copy in the ModelInstance to avoid changes underfoot md = deepcopy(m.md) @@ -267,4 +266,4 @@ end function build(mm::MarginalModel) build(mm.base) build(mm.marginal) -end \ No newline at end of file +end diff --git a/src/core/connections.jl b/src/core/connections.jl index f7ba08fa1..399076003 100644 --- a/src/core/connections.jl +++ b/src/core/connections.jl @@ -50,7 +50,7 @@ end # Default string, string unit check function verify_units(unit1::AbstractString, unit2::AbstractString) = (unit1 == unit2) -function _check_labels(obj::AbstractCompositeComponentDef, +function _check_labels(obj::AbstractCompositeComponentDef, comp_def::ComponentDef, param_name::Symbol, ext_param::ArrayModelParameter) param_def = parameter(comp_def, param_name) @@ -77,9 +77,9 @@ function _check_labels(obj::AbstractCompositeComponentDef, # index_values = indexvalues(obj) for (i, dim) in enumerate(comp_dims) - if isa(dim, Symbol) + if isa(dim, Symbol) param_length = size(ext_param.values)[i] - if dim == :time + if dim == :time t = dimension(obj, :time) first = find_first_period(comp_def) last = find_last_period(comp_def) @@ -99,7 +99,7 @@ end check_labels::Bool=true) Connect a parameter `param_name` in the component `comp_name` of composite `obj` to -the external parameter `ext_param_name`. +the external parameter `ext_param_name`. """ function connect_param!(obj::AbstractCompositeComponentDef, comp_name::Symbol, param_name::Symbol, ext_param_name::Symbol; check_labels::Bool=true) @@ -120,23 +120,23 @@ function connect_param!(obj::AbstractCompositeComponentDef, comp_name::Symbol, p end """ - connect_param!(obj::AbstractCompositeComponentDef, - dst_comp_path::ComponentPath, dst_par_name::Symbol, + connect_param!(obj::AbstractCompositeComponentDef, + dst_comp_path::ComponentPath, dst_par_name::Symbol, src_comp_path::ComponentPath, src_var_name::Symbol, - backup::Union{Nothing, Array}=nothing; + backup::Union{Nothing, Array}=nothing; ignoreunits::Bool=false, offset::Int=0) Bind the parameter `dst_par_name` of one component `dst_comp_path` of composite `obj` to a -variable `src_var_name` in another component `src_comp_path` of the same model using +variable `src_var_name` in another component `src_comp_path` of the same model using `backup` to provide default values and the `ignoreunits` flag to indicate the need to -check match units between the two. The `offset` argument indicates the offset between -the destination and the source ie. the value would be `1` if the destination component +check match units between the two. The `offset` argument indicates the offset between +the destination and the source ie. the value would be `1` if the destination component parameter should only be calculated for the second timestep and beyond. """ -function connect_param!(obj::AbstractCompositeComponentDef, - dst_comp_path::ComponentPath, dst_par_name::Symbol, +function connect_param!(obj::AbstractCompositeComponentDef, + dst_comp_path::ComponentPath, dst_par_name::Symbol, src_comp_path::ComponentPath, src_var_name::Symbol, - backup::Union{Nothing, Array}=nothing; + backup::Union{Nothing, Array}=nothing; ignoreunits::Bool=false, offset::Int=0) # remove any existing connections for this dst parameter @@ -167,55 +167,55 @@ function connect_param!(obj::AbstractCompositeComponentDef, dst_dims = dim_names(dst_param) backup = convert(Array{Union{Missing, number_type(obj)}}, backup) # converts number type and, if it's a NamedArray, it's converted to Array - first = first_period(obj, dst_comp_def) + first = first_period(obj, dst_comp_def) T = eltype(backup) - + dim_count = length(dst_dims) if dim_count == 0 values = backup else ti = get_time_index_position(dst_param) - + if isuniform(obj) # use the first from the comp_def not the ModelDef stepsize = step_size(obj) - last = last_period(obj, dst_comp_def) + last = last_period(obj, dst_comp_def) values = TimestepArray{FixedTimestep{first, stepsize, last}, T, dim_count, ti}(backup) else times = time_labels(obj) - # use the first from the comp_def - first_index = findfirst(isequal(first), times) + # use the first from the comp_def + first_index = findfirst(isequal(first), times) values = TimestepArray{VariableTimestep{(times[first_index:end]...,)}, T, dim_count, ti}(backup) end - + end set_external_array_param!(obj, dst_par_name, values, dst_dims) backup_param_name = dst_par_name - else + else # If backup not provided, make sure the source component covers the span of the destination component src_first, src_last = first_and_last(src_comp_def) dst_first, dst_last = first_and_last(dst_comp_def) - if (dst_first !== nothing && src_first !== nothing && dst_first < src_first) || + if (dst_first !== nothing && src_first !== nothing && dst_first < src_first) || (dst_last !== nothing && src_last !== nothing && dst_last > src_last) src_first = printable(src_first) src_last = printable(src_last) dst_first = printable(dst_first) dst_last = printable(dst_last) - error("""Cannot connect parameter: $src_comp_path runs only from $src_first to $src_last, + error("""Cannot connect parameter: $src_comp_path runs only from $src_first to $src_last, whereas $dst_comp_path runs from $dst_first to $dst_last. Backup data must be provided for missing years. -Try calling: +Try calling: `connect_param!(m, comp_name, par_name, comp_name, var_name, backup_data)`""") - end + end - backup_param_name = nothing + backup_param_name = nothing end # Check the units, if provided - if ! ignoreunits && ! verify_units(variable_unit(src_comp_def, src_var_name), + if ! ignoreunits && ! verify_units(variable_unit(src_comp_def, src_var_name), parameter_unit(dst_comp_def, dst_par_name)) error("Units of $src_comp_path:$src_var_name do not match $dst_comp_path:$dst_par_name.") end @@ -226,30 +226,30 @@ Try calling: return nothing end -function connect_param!(obj::AbstractCompositeComponentDef, - dst_comp_name::Symbol, dst_par_name::Symbol, +function connect_param!(obj::AbstractCompositeComponentDef, + dst_comp_name::Symbol, dst_par_name::Symbol, src_comp_name::Symbol, src_var_name::Symbol, backup::Union{Nothing, Array}=nothing; ignoreunits::Bool=false, offset::Int=0) - connect_param!(obj, ComponentPath(obj, dst_comp_name), dst_par_name, + connect_param!(obj, ComponentPath(obj, dst_comp_name), dst_par_name, ComponentPath(obj, src_comp_name), src_var_name, backup; ignoreunits=ignoreunits, offset=offset) end """ - connect_param!(obj::AbstractCompositeComponentDef, - dst::Pair{Symbol, Symbol}, src::Pair{Symbol, Symbol}, - backup::Union{Nothing, Array}=nothing; + connect_param!(obj::AbstractCompositeComponentDef, + dst::Pair{Symbol, Symbol}, src::Pair{Symbol, Symbol}, + backup::Union{Nothing, Array}=nothing; ignoreunits::Bool=false, offset::Int=0) Bind the parameter `dst[2]` of one component `dst[1]` of composite `obj` to a variable `src[2]` in another component `src[1]` of the same composite using `backup` to provide default values and the `ignoreunits` flag to indicate the need to check match units between the two. The `offset` argument indicates the offset -between the destination and the source ie. the value would be `1` if the destination +between the destination and the source ie. the value would be `1` if the destination component parameter should only be calculated for the second timestep and beyond. """ -function connect_param!(obj::AbstractCompositeComponentDef, - dst::Pair{Symbol, Symbol}, src::Pair{Symbol, Symbol}, +function connect_param!(obj::AbstractCompositeComponentDef, + dst::Pair{Symbol, Symbol}, src::Pair{Symbol, Symbol}, backup::Union{Nothing, Array}=nothing; ignoreunits::Bool=false, offset::Int=0) connect_param!(obj, dst[1], dst[2], src[1], src[2], backup; ignoreunits=ignoreunits, offset=offset) end @@ -262,7 +262,7 @@ Split a string of the form "/path/to/component:datum_name" into the component pa """ function split_datum_path(obj::AbstractCompositeComponentDef, s::AbstractString) elts = split(s, ":") - length(elts) != 2 && error("Can't split datum path '$s' into ComponentPath and datum name") + length(elts) != 2 && error("Can't split datum path '$s' into ComponentPath and datum name") return (ComponentPath(obj, elts[1]), Symbol(elts[2])) end @@ -277,7 +277,7 @@ function connect_param!(obj::AbstractCompositeComponentDef, dst::AbstractString, src_path, src_name = split_datum_path(obj, src) connect_param!(obj, dst_path, dst_name, src_path, src_name, - backup; ignoreunits=ignoreunits, offset=offset) + backup; ignoreunits=ignoreunits, offset=offset) end @@ -297,14 +297,14 @@ function _collect_connected_params(obj::AbstractCompositeComponentDef, connected end """ - connected_params(md::ModelDef) + connected_params(obj::AbstractCompositeComponentDef) Recursively search the component tree to find connected parameters in leaf components. Return a vector of tuples of the form `(path::ComponentPath, param_name::Symbol)`. """ -function connected_params(md::ModelDef) +function connected_params(obj::AbstractCompositeComponentDef) connected = ParamVector() - _collect_connected_params(md, connected) + _collect_connected_params(obj, connected) return connected end @@ -326,16 +326,16 @@ function _collect_unconnected_params(obj::AbstractCompositeComponentDef, connect end """ - unconnected_params(md::ModelDef) + unconnected_params(obj::AbstractCompositeComponentDef) Return a list of tuples (comp_path, param_name) of parameters -that have not been connected to a value anywhere in `md`. +that have not been connected to a value anywhere within `obj`. """ -function unconnected_params(md::ModelDef) +function unconnected_params(obj::AbstractCompositeComponentDef) unconnected = ParamVector() - connected = connected_params(md) + connected = connected_params(obj) - _collect_unconnected_params(md, connected, unconnected) + _collect_unconnected_params(obj, connected, unconnected) return unconnected end @@ -409,19 +409,19 @@ function set_external_param!(obj::AbstractCompositeComponentDef, name::Symbol, v dirty!(obj) end -function set_external_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::Number; +function set_external_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::Number; param_dims::Union{Nothing,Array{Symbol}} = nothing) set_external_scalar_param!(obj, name, value) end -function set_external_param!(obj::AbstractCompositeComponentDef, name::Symbol, - value::Union{AbstractArray, AbstractRange, Tuple}; +function set_external_param!(obj::AbstractCompositeComponentDef, name::Symbol, + value::Union{AbstractArray, AbstractRange, Tuple}; param_dims::Union{Nothing,Array{Symbol}} = nothing) ti = get_time_index_position(param_dims) if ti != nothing value = convert(Array{number_type(obj)}, value) num_dims = length(param_dims) - values = get_timestep_array(obj, eltype(value), num_dims, ti, value) + values = get_timestep_array(obj, eltype(value), num_dims, ti, value) else values = value end @@ -430,38 +430,38 @@ function set_external_param!(obj::AbstractCompositeComponentDef, name::Symbol, end """ - set_external_array_param!(obj::AbstractCompositeComponentDef, + set_external_array_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::TimestepVector, dims) Add a one dimensional time-indexed array parameter indicated by `name` and `value` to the composite `obj`. In this case `dims` must be `[:time]`. """ -function set_external_array_param!(obj::AbstractCompositeComponentDef, +function set_external_array_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::TimestepVector, dims) param = ArrayModelParameter(value, [:time]) # must be :time set_external_param!(obj, name, param) end """ - set_external_array_param!(obj::AbstractCompositeComponentDef, + set_external_array_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::TimestepMatrix, dims) Add a multi-dimensional time-indexed array parameter `name` with value `value` to the composite `obj`. In this case `dims` must be `[:time]`. """ -function set_external_array_param!(obj::AbstractCompositeComponentDef, +function set_external_array_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::TimestepArray, dims) param = ArrayModelParameter(value, dims === nothing ? Vector{Symbol}() : dims) set_external_param!(obj, name, param) end """ - set_external_array_param!(obj::AbstractCompositeComponentDef, + set_external_array_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::AbstractArray, dims) Add an array type parameter `name` with value `value` and `dims` dimensions to the composite `obj`. """ -function set_external_array_param!(obj::AbstractCompositeComponentDef, +function set_external_array_param!(obj::AbstractCompositeComponentDef, name::Symbol, value::AbstractArray, dims) numtype = Union{Missing, number_type(obj)} @@ -486,16 +486,16 @@ end """ update_param!(obj::AbstractCompositeComponentDef, name::Symbol, value; update_timesteps = false) -Update the `value` of an external model parameter in composite `obj`, referenced -by `name`. Optional boolean argument `update_timesteps` with default value -`false` indicates whether to update the time keys associated with the parameter +Update the `value` of an external model parameter in composite `obj`, referenced +by `name`. Optional boolean argument `update_timesteps` with default value +`false` indicates whether to update the time keys associated with the parameter values to match the model's time index. """ function update_param!(obj::AbstractCompositeComponentDef, name::Symbol, value; update_timesteps = false) _update_param!(obj::AbstractCompositeComponentDef, name, value, update_timesteps; raise_error = true) end -function _update_param!(obj::AbstractCompositeComponentDef, +function _update_param!(obj::AbstractCompositeComponentDef, name::Symbol, value, update_timesteps; raise_error = true) param = external_param(obj, name, missing_ok=true) if param === nothing @@ -529,12 +529,12 @@ end function _update_array_param!(obj::AbstractCompositeComponentDef, name, value, update_timesteps, raise_error) # Get original parameter param = external_param(obj, name) - + # Check type of provided parameter if !(typeof(value) <: AbstractArray) error("Cannot update array parameter $name with a value of type $(typeof(value)).") - elseif !(eltype(value) <: eltype(param.values)) + elseif !(eltype(value) <: eltype(param.values)) try value = convert(Array{eltype(param.values)}, value) catch e @@ -545,7 +545,7 @@ function _update_array_param!(obj::AbstractCompositeComponentDef, name, value, u # Check size of provided parameter if update_timesteps && param.values isa TimestepArray expected_size = ([length(dim_keys(obj, d)) for d in dim_names(param)]...,) - else + else expected_size = size(param.values) end if size(value) != expected_size @@ -553,7 +553,7 @@ function _update_array_param!(obj::AbstractCompositeComponentDef, name, value, u end if update_timesteps - if param.values isa TimestepArray + if param.values isa TimestepArray T = eltype(value) N = length(size(value)) ti = get_time_index_position(param) @@ -577,13 +577,13 @@ function _update_array_param!(obj::AbstractCompositeComponentDef, name, value, u end """ - update_params!(obj::AbstractCompositeComponentDef, parameters::Dict{T, Any}; + update_params!(obj::AbstractCompositeComponentDef, parameters::Dict{T, Any}; update_timesteps = false) where T For each (k, v) in the provided `parameters` dictionary, `update_param!` -is called to update the external parameter by name k to value v, with optional +is called to update the external parameter by name k to value v, with optional Boolean argument update_timesteps. Each key k must be a symbol or convert to a -symbol matching the name of an external parameter that already exists in the +symbol matching the name of an external parameter that already exists in the component definition. """ function update_params!(obj::AbstractCompositeComponentDef, parameters::Dict; update_timesteps = false) @@ -623,15 +623,15 @@ function add_connector_comps!(obj::AbstractCompositeComponentDef) # Add the connector component before the user-defined component that required it conn_comp = add_comp!(obj, conn_comp_def, conn_comp_name, before=comp_name) conn_path = conn_comp.comp_path - + # add a connection between src_component and the ConnectorComp add_internal_param_conn!(obj, InternalParameterConnection(conn.src_comp_path, conn.src_var_name, conn_path, :input1, conn.ignoreunits)) # add a connection between ConnectorComp and dst_component - add_internal_param_conn!(obj, InternalParameterConnection(conn_path, :output, - conn.dst_comp_path, conn.dst_par_name, + add_internal_param_conn!(obj, InternalParameterConnection(conn_path, :output, + conn.dst_comp_path, conn.dst_par_name, conn.ignoreunits)) # add a connection between ConnectorComp and the external backup data @@ -648,3 +648,30 @@ function add_connector_comps!(obj::AbstractCompositeComponentDef) return nothing end + +""" +propagate_params!( + obj::AbstractCompositeComponentDef; + names::Union{Nothing,Vector{Symbol}}=nothing) + +Exports all unconnected parameters below the given composite `obj` by adding references +to these parameters in `obj`. If `names` is not `nothing`, only the given names are +exported into `obj`. + +This is called automatically by `build!()`, but it can be +useful for developers of composites as well. + +TBD: should we just call this at the end of code emitted by @defcomposite? +""" +function propagate_params!( + obj::AbstractCompositeComponentDef; + names::Union{Nothing,Vector{Symbol}}=nothing) + + # returns a Vector{ParamPath}, which are Tuple{ComponentPath, Symbol} + for (path, name) in unconnected_params(obj) + comp = compdef(obj, path) + if names === nothing || name in names + obj[name] = datum_reference(comp, name) + end + end +end diff --git a/src/core/defcomposite.jl b/src/core/defcomposite.jl index 5b05a7dbb..a5fb68e27 100644 --- a/src/core/defcomposite.jl +++ b/src/core/defcomposite.jl @@ -121,7 +121,7 @@ macro defcomposite(cc_name, ex) comps = SubComponent[] imports = [] conns = [] - + calling_module = __module__ # @info "defcomposite calling module: $calling_module" @@ -154,7 +154,7 @@ macro defcomposite(cc_name, ex) # @info "import as $left = $var_par" # note that `comp_Symbol.name_Symbol` failed; bug in MacroTools? - elseif @capture(left, comp_.name_) # simple connection case + elseif @capture(left, comp_.name_) # simple connection case dst = parse_dotted_symbols(left) dst === nothing && error("Expected dot-delimited sequence of symbols, got $left") @@ -179,7 +179,7 @@ macro defcomposite(cc_name, ex) result = :( let conns = $conns, imports = $imports, - + cc_id = Mimi.ComponentId($calling_module, $(QuoteNode(cc_name))) global $cc_name = Mimi.CompositeComponentDef(cc_id, $(QuoteNode(cc_name)), $comps, $__module__) @@ -188,7 +188,7 @@ macro defcomposite(cc_name, ex) function _store_in_ns(refs, local_name) isempty(refs) && return - + if length(refs) == 1 $cc_name[local_name] = refs[1] else @@ -218,13 +218,14 @@ macro defcomposite(cc_name, ex) _store_in_ns(par_refs, local_name) end - # Mimi.import_params!($cc_name) - for ((dst_path, dst_name), (src_path, src_name)) in conns # @info "connect_param!($(nameof($cc_name)), $dst_path, :$dst_name, $src_path, :$src_name)" Mimi.connect_param!($cc_name, dst_path, dst_name, src_path, src_name) end + # propagates unconnected parameters + Mimi.propagate_params!($cc_name) + $cc_name end ) diff --git a/src/core/defs.jl b/src/core/defs.jl index d90319d67..2e0f22489 100644 --- a/src/core/defs.jl +++ b/src/core/defs.jl @@ -112,7 +112,7 @@ Example: `filter(istype(AbstractComponentDef), obj.namespace)` """ istype(T::DataType) = (pair -> pair.second isa T) -# Namespace filter functions return dicts of values for the given type. +# Namespace filter functions return dicts of values for the given type. # N.B. only composites hold comps in the namespace. components(obj::AbstractCompositeComponentDef) = filter(istype(AbstractComponentDef), obj.namespace) @@ -153,7 +153,7 @@ function _ns_get(obj::AbstractComponentDef, name::Symbol, T::DataType) return item end -function _save_to_namespace(comp::AbstractComponentDef, key::Symbol, value::NamespaceElement) +function _save_to_namespace(comp::AbstractComponentDef, key::Symbol, value::NamespaceElement) # Allow replacement of existing values for a key only with items of the same type. if haskey(comp, key) elt_type = typeof(comp[key]) @@ -169,7 +169,7 @@ end Create a reference to the given datum, which must already exist. """ -function datum_reference(comp::ComponentDef, datum_name::Symbol) +function datum_reference(comp::ComponentDef, datum_name::Symbol) obj = _ns_get(comp, datum_name, AbstractDatumDef) path = @or(obj.comp_path, ComponentPath(comp.name)) ref_type = obj isa ParameterDef ? ParameterDefReference : VariableDefReference @@ -262,7 +262,7 @@ function _check_run_period(obj::AbstractComponentDef, new_first, new_last) if new_first !== nothing && old_first !== nothing && new_first < old_first error("Attempted to set first period of $(obj.comp_id) to an earlier period ($new_first) than component indicates ($old_first)") end - + if new_last !== nothing && old_last !== nothing && new_last > old_last error("Attempted to set last period of $(obj.comp_id) to a later period ($new_last) than component indicates ($old_last)") end @@ -279,7 +279,7 @@ end _set_run_period!(obj::AbstractComponentDef, first, last) Allows user to change the bounds on a AbstractComponentDef's time dimension. -An error is raised if the new time bounds are outside those of any +An error is raised if the new time bounds are outside those of any subcomponent, recursively. """ function _set_run_period!(obj::AbstractComponentDef, first, last) @@ -364,10 +364,10 @@ function parameter_dimensions(obj::AbstractComponentDef, comp_name::Symbol, para end """ - set_param!(obj::AbstractCompositeComponentDef, comp_path::ComponentPath, + set_param!(obj::AbstractCompositeComponentDef, comp_path::ComponentPath, value_dict::Dict{Symbol, Any}, param_names) -Call `set_param!()` for each name in `param_names`, retrieving the corresponding value from +Call `set_param!()` for each name in `param_names`, retrieving the corresponding value from `value_dict[param_name]`. """ function set_param!(obj::AbstractCompositeComponentDef, comp_name::Symbol, value_dict::Dict{Symbol, Any}, param_names) @@ -377,13 +377,13 @@ function set_param!(obj::AbstractCompositeComponentDef, comp_name::Symbol, value end """ - set_param!(obj::AbstractCompositeComponentDef, comp_path::ComponentPath, param_name::Symbol, + set_param!(obj::AbstractCompositeComponentDef, comp_path::ComponentPath, param_name::Symbol, value_dict::Dict{Symbol, Any}, dims=nothing) -Call `set_param!()` with `param_name` and a value dict in which `value_dict[param_name]` references +Call `set_param!()` with `param_name` and a value dict in which `value_dict[param_name]` references the value of parameter `param_name`. """ -function set_param!(obj::AbstractCompositeComponentDef, comp_name::Symbol, value_dict::Dict{Symbol, Any}, +function set_param!(obj::AbstractCompositeComponentDef, comp_name::Symbol, value_dict::Dict{Symbol, Any}, param_name::Symbol, dims=nothing) value = value_dict[param_name] set_param!(obj, comp_name, param_name, value, dims) @@ -479,7 +479,7 @@ function set_param!(obj::AbstractCompositeComponentDef, comp_name::Symbol, param if ti != nothing # there is a time dimension T = eltype(value) - if num_dims == 0 + if num_dims == 0 values = value else # Use the first from the comp_def if it has it, else use the tree root (usu. a ModelDef) @@ -611,7 +611,7 @@ function _set_comps!(obj::AbstractCompositeComponentDef, comps::OrderedDict{Symb for (key, value) in comps obj[key] = value end - + dirty!(obj) end @@ -709,7 +709,7 @@ Propagate a time dimension down through the comp def tree. """ function propagate_time!(obj::AbstractComponentDef, t::Dimension) set_dimension!(obj, :time, t) - + obj.first = firstindex(t) obj.last = lastindex(t) @@ -718,47 +718,12 @@ function propagate_time!(obj::AbstractComponentDef, t::Dimension) end end -""" - import_params!(comp::AbstractComponentDef) - -Recursively (depth-first) import parameters from leaf comps to composites, and from -sub-composites to their parents. N.B. this is done in _build() after calling -fix_comp_paths!(). -""" -function import_params!(comp::AbstractComponentDef) - # nothing to do if there are no sub-components - length(comp) == 0 && return - - sub_comps = values(components(comp)) - - for sub_comp in sub_comps - import_params!(sub_comp) - end - - # grab any items imported in @defcomposite; create a reverse-lookup map - d = Dict() - for (local_name, ref) in param_dict(comp) - d[(ref.comp_path, ref.name)] = local_name - end - - # import any unreferenced (and usually renamed locally) parameters - for sub_comp in sub_comps - # N.B. param_dict() returns dict of either params (for leafs) or param refs (from composite) - for (local_name, param) in param_dict(sub_comp) - ref = (param isa AbstractDatumReference ? param : datum_reference(sub_comp, nameof(param))) - if ! haskey(d, (ref.comp_path, ref.name)) - comp[local_name] = ref # add the reference to the local namespace - end - end - end -end - """ add_comp!(obj::AbstractCompositeComponentDef, comp_def::AbstractComponentDef, comp_name::Symbol=comp_def.comp_id.comp_name; rename=nothing, first=nothing, last=nothing, before=nothing, after=nothing) -Add the component `comp_def` to the composite component indicated by `obj`. The component is +Add the component `comp_def` to the composite component indicated by `obj`. The component is added at the end of the list unless one of the keywords `before` or `after` is specified. Note that a copy of `comp_id` is made in the composite and assigned the give name. The optional argument `rename` can be a list of pairs indicating `original_name => imported_name`. @@ -833,9 +798,9 @@ end add_comp!(obj::CompositeComponentDef, comp_id::ComponentId; comp_name::Symbol=comp_id.comp_name, first=nothing, last=nothing, before=nothing, after=nothing, rename=nothing) -Add the component indicated by `comp_id` to the composite component indicated by `obj`. The -component is added at the end of the list unless one of the keywords `before` or `after` is -specified. Note that a copy of `comp_id` is made in the composite and assigned the give name. +Add the component indicated by `comp_id` to the composite component indicated by `obj`. The +component is added at the end of the list unless one of the keywords `before` or `after` is +specified. Note that a copy of `comp_id` is made in the composite and assigned the give name. The optional argument `rename` can be a list of pairs indicating `original_name => imported_name`. Note: `first` and `last` keywords are currently disabled. @@ -954,5 +919,5 @@ function replace_comp!(obj::AbstractCompositeComponentDef, comp_id::ComponentId, end # Re-add - return add_comp!(obj, comp_id, comp_name; before=before, after=after) # first=first, last=last, + return add_comp!(obj, comp_id, comp_name; before=before, after=after) # first=first, last=last, end From 1a1a07b588fed0a83d67ca07b7f53638f123db1d Mon Sep 17 00:00:00 2001 From: Richard Plevin Date: Tue, 15 Oct 2019 14:50:10 -0700 Subject: [PATCH 2/2] One more file for last commit... --- src/core/types/defs.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/types/defs.jl b/src/core/types/defs.jl index 9d2029396..f546dd6e8 100644 --- a/src/core/types/defs.jl +++ b/src/core/types/defs.jl @@ -15,8 +15,8 @@ Return the name of `def`. `NamedDef`s include `DatumDef`, `ComponentDef`, """ Base.nameof(obj::AbstractNamedObj) = obj.name -# TBD: old definition; should deprecate this... -name(obj::AbstractNamedObj) = obj.name +# Deprecate old definition in favor of standard name +@deprecate name(obj::AbstractNamedObj) nameof(obj) # Similar structure is used for variables and parameters (parameters merely adds `default`) @class mutable DatumDef <: NamedObj begin @@ -47,7 +47,7 @@ end # That type is defined later, so we declare Any here. Parent is `nothing` for # detached (i.e., "template") components and is set when added to a composite. parent::Any - + function ComponentDef(self::ComponentDef, comp_id::Nothing) error("Leaf ComponentDef objects must have a valid ComponentId name (not nothing)") @@ -162,7 +162,7 @@ global const NamespaceElement = Union{LeafNamespaceElement, CompositeNa end # Used by @defcomposite -function CompositeComponentDef(comp_id::ComponentId, alias::Symbol, subcomps::Vector{SubComponent}, +function CompositeComponentDef(comp_id::ComponentId, alias::Symbol, subcomps::Vector{SubComponent}, calling_module::Module) # @info "CompositeComponentDef($comp_id, $alias, $subcomps)" composite = CompositeComponentDef(comp_id)