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 11, 2023
1 parent ce7eed0 commit 3f64317
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
18 changes: 6 additions & 12 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)
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)
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)
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 @@ -632,9 +627,8 @@ function parse_icon!(icon, dict, body::String)
error("\n$body is not a valid icon")
end
end

function parse_icon!(icon, dict, body::Expr)
parse_icon!(icon, dict, eval(body))
function parse_icon!(body::Union{Expr, Symbol}, dict, icon, mod)
parse_icon!(Core.eval(mod, body), dict, icon, mod)

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

View check run for this annotation

Codecov / codecov/patch

src/systems/model_parsing.jl#L630-L631

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

### Parsing Components:
Expand Down
21 changes: 19 additions & 2 deletions test/model_parsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ using Distributions
using Unitful

ENV["MTK_ICONS_DIR"] = "$(@__DIR__)/icons"
ground_logo = read(abspath(ENV["MTK_ICONS_DIR"], "ground.svg"), String)

# Mock module used to test if the `@mtkmodel` macro works with fully-qualified names as well.
module MyMockModule
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 == ground_logo
@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,23 @@ 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, ModelWithExprIcon

@named model_with_component_array = ModelWithComponentArray()

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

@test ModelWithExprIcon.structure[:icon] == ground_logo

pop!(LOAD_PATH)
end

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

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

using ModelingToolkit
using Unitful

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

@mtkmodel ModelWithExprIcon begin
@icon read(abspath(@__DIR__, "..", "icons", "ground.svg"), String)
end

end

0 comments on commit 3f64317

Please sign in to comment.