From eeebcf106479af8fcae0b28921e16170982b7ce1 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:48:17 +0530 Subject: [PATCH 1/2] fix: remove `eval`s from model parsing - Ensure that modules consisting MTKModels with component arrays and icons of `Expr` type and `unit` metadata can be precompiled. --- format/Project.toml | 2 ++ src/systems/model_parsing.jl | 17 ++++++--------- test/model_parsing.jl | 21 ++++++++++++++++--- .../precompile_test/ModelParsingPrecompile.jl | 12 +++++++++++ 4 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 format/Project.toml create mode 100644 test/precompile_test/ModelParsingPrecompile.jl diff --git a/format/Project.toml b/format/Project.toml new file mode 100644 index 0000000000..f3aab8b8bf --- /dev/null +++ b/format/Project.toml @@ -0,0 +1,2 @@ +[deps] +JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" diff --git a/src/systems/model_parsing.jl b/src/systems/model_parsing.jl index 52ef0560d7..4a8d73652c 100644 --- a/src/systems/model_parsing.jl +++ b/src/systems/model_parsing.jl @@ -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 @@ -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 @@ -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)) @@ -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) end ### Parsing Components: diff --git a/test/model_parsing.jl b/test/model_parsing.jl index b1d990d1cf..d08903dfe0 100644 --- a/test/model_parsing.jl +++ b/test/model_parsing.jl @@ -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 @@ -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] == @@ -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 diff --git a/test/precompile_test/ModelParsingPrecompile.jl b/test/precompile_test/ModelParsingPrecompile.jl new file mode 100644 index 0000000000..8430831b55 --- /dev/null +++ b/test/precompile_test/ModelParsingPrecompile.jl @@ -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 From e60c2146046af1f34c8a57dbdae6acde0477d454 Mon Sep 17 00:00:00 2001 From: Venkateshprasad <32921645+ven-k@users.noreply.github.com> Date: Fri, 15 Dec 2023 12:42:52 +0530 Subject: [PATCH 2/2] style: fix format --- test/model_parsing.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/model_parsing.jl b/test/model_parsing.jl index d08903dfe0..7b07425532 100644 --- a/test/model_parsing.jl +++ b/test/model_parsing.jl @@ -165,7 +165,8 @@ 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] ==