Skip to content

Commit

Permalink
fix: remove evals from model parsing
Browse files Browse the repository at this point in the history
- Ensure that modules consisting MTKModels with component arrays and icons of
`Expr` type and `unit` metadata can be precompiled.
  • Loading branch information
ven-k committed Dec 14, 2023
1 parent ce7eed0 commit 409a05d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 14 deletions.
2 changes: 2 additions & 0 deletions format/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[deps]
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
17 changes: 6 additions & 11 deletions src/systems/model_parsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,10 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs;
(var, def)
end
Expr(:ref, a, b...) => begin
indices = map(i -> UnitRange(i.args[2], i.args[end]), b)

Check warning on line 181 in src/systems/model_parsing.jl

View check run for this annotation

Codecov / codecov/patch

src/systems/model_parsing.jl#L181

Added line #L181 was not covered by tests
parse_variable_def!(dict, mod, a, varclass, kwargs;
def, indices = [eval.(b)...])
def, indices)
end
#= Expr(:if, condition, a) => begin
var, def = [], []
for var_def in a.args
parse_variable_def!(dict, mod, var_def, varclass, kwargs)
end
end =#
_ => error("$arg cannot be parsed")
end
end
Expand Down Expand Up @@ -301,7 +296,7 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps,
parse_equations!(exprs, eqs, dict, body)
elseif mname == Symbol("@icon")
isassigned(icon) && error("This model has more than one icon.")
parse_icon!(icon, dict, body)
parse_icon!(body, dict, icon, mod)

Check warning on line 299 in src/systems/model_parsing.jl

View check run for this annotation

Codecov / codecov/patch

src/systems/model_parsing.jl#L299

Added line #L299 was not covered by tests
else
error("$mname is not handled.")
end
Expand Down Expand Up @@ -614,7 +609,7 @@ function parse_equations!(exprs, eqs, dict, body)
end
end

function parse_icon!(icon, dict, body::String)
function parse_icon!(body::String, dict, icon, mod)

Check warning on line 612 in src/systems/model_parsing.jl

View check run for this annotation

Codecov / codecov/patch

src/systems/model_parsing.jl#L612

Added line #L612 was not covered by tests
icon_dir = get(ENV, "MTK_ICONS_DIR", joinpath(DEPOT_PATH[1], "mtk_icons"))
dict[:icon] = icon[] = if isfile(body)
URI("file:///" * abspath(body))
Expand All @@ -633,8 +628,8 @@ function parse_icon!(icon, dict, body::String)
end
end

function parse_icon!(icon, dict, body::Expr)
parse_icon!(icon, dict, eval(body))
function parse_icon!(body::Symbol, dict, icon, mod)
parse_icon!(getfield(mod, body), dict, icon, mod)

Check warning on line 632 in src/systems/model_parsing.jl

View check run for this annotation

Codecov / codecov/patch

src/systems/model_parsing.jl#L631-L632

Added lines #L631 - L632 were not covered by tests
end

### Parsing Components:
Expand Down
21 changes: 18 additions & 3 deletions test/model_parsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ export Pin
@icon "pin.png"
end

ground_logo = read(abspath(ENV["MTK_ICONS_DIR"], "ground.svg"), String)
@mtkmodel Ground begin
@components begin
g = Pin()
end
@icon read(abspath(ENV["MTK_ICONS_DIR"], "ground.svg"), String)
@icon ground_logo
@equations begin
g.v ~ 0
end
Expand Down Expand Up @@ -164,8 +165,7 @@ resistor = getproperty(rc, :resistor; namespace = false)

@test get_gui_metadata(rc.resistor).layout == Resistor.structure[:icon] ==
read(joinpath(ENV["MTK_ICONS_DIR"], "resistor.svg"), String)
@test get_gui_metadata(rc.ground).layout ==
read(abspath(ENV["MTK_ICONS_DIR"], "ground.svg"), String)
@test get_gui_metadata(rc.ground).layout == read(abspath(ENV["MTK_ICONS_DIR"], "ground.svg"), String)
@test get_gui_metadata(rc.capacitor).layout ==
URI("https://upload.wikimedia.org/wikipedia/commons/7/78/Capacitor_symbol.svg")
@test OnePort.structure[:icon] ==
Expand Down Expand Up @@ -321,6 +321,21 @@ end
@test A.structure[:components] == [[:cc, :C]]
end

# Ensure that modules consisting MTKModels with component arrays and icons of
# `Expr` type and `unit` metadata can be precompiled.
@testset "Precompile packages with MTKModels" begin
push!(LOAD_PATH, joinpath(@__DIR__, "precompile_test"))

using ModelParsingPrecompile: ModelWithComponentArray

@named model_with_component_array = ModelWithComponentArray()

@test ModelWithComponentArray.structure[:parameters][:R][:unit] == u""
@test lastindex(parameters(model_with_component_array)) == 3

pop!(LOAD_PATH)
end

@testset "Conditional statements inside the blocks" begin
@mtkmodel C begin end

Expand Down
12 changes: 12 additions & 0 deletions test/precompile_test/ModelParsingPrecompile.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module ModelParsingPrecompile

using ModelingToolkit
using Unitful

@mtkmodel ModelWithComponentArray begin
@parameters begin
R(t)[1:3] = 1, [description = "Parameter array", unit = u""]
end
end

end

0 comments on commit 409a05d

Please sign in to comment.