Validate odin code. This is primarily intended for use within other applications.
Arguments
- expr
Odin code as the path to a file (a string), a character vector of code, or as an expression (typically within braces
{}
).- input_type
An optional string describing the type of input for
expr
- must be one offile
,text
orexpression
. If given, this skips the type detection logic and odin will throw an error if the wrong type of input is given. Using this may be beneficial in programmatic environments.- compatibility
Compatibility mode to use. Valid options are "warning", which updates code that can be fixed, with warnings, and "error", which will error. The option "silent" will silently rewrite code, but this is not recommended for general use as eventually the compatibility mode will be removed (this option is primarily intended for comparing output of odin1 and odin2 models against old code).
Value
A list with elements:
success
: boolean,TRUE
if validation was successfulresult
: Metadata about the model; see Details above for the format.error
: EitherNULL
(ifsuccess
isTRUE
) or an error; see Details above for interpreting this value.compatibility
: Adata.frame
of compatibility issues. This is formatted similarly tosrc
withinerror
(see above), but also includestype
(a code for the compatibility issue),description
(a human-readable description of the issue),original
(the original expression) andvalue
(the final expression).
The intention is that we won't throw generally from this function.
Result
On successful validation, we return a list with metadata about the model. Currently this contains:
time
: The time mode of the model (a string of either "discrete" or "continuous")parameters
: Adata.frame
describing parameters. Currently the only column isname
.variables
: Adata.frame
describing the model variables. Currently the only column isname
.data
: Adata.frame
describing data used by the model (if it supports this). Currently the only column isname
.
Errors
Most errors will have class odin_parse_error
. These will print
context information if rethrown. They have fields:
message
: The headline error messagecode
: The odin error code, as listed invignette("errors")
, and used by odin_error_explainsrc
: Source information about the error. This is adata.frame
with columnsindex
(the expression number),expr
(a list column with the expression),start
(the starting line; possiblyNA
),end
(the finishing line; possiblyNA
),str
(the string containing the literal value of the expression; possiblyNA
) andmigrated
(a logical, indicating if the source has been automatically migrated from odin1 code). If any ofstart
,end
orstr
isNA
, all will be, for all rows.
You can get the full rendered message using conditionMessage()
on the error object.
Examples
# A successful validation:
odin_validate({
initial(x) <- 1
deriv(x) <- a
a <- parameter()
})
#> $success
#> [1] TRUE
#>
#> $error
#> NULL
#>
#> $result
#> $result$time
#> [1] "continuous"
#>
#> $result$variables
#> name
#> 1 x
#>
#> $result$parameters
#> name
#> 1 a
#>
#> $result$data
#> [1] name
#> <0 rows> (or 0-length row.names)
#>
#>
#> $compatibility
#> NULL
#>
# A failure:
odin_validate({
initial(x) <- 1
deriv(x) <- a
})
#> $success
#> [1] FALSE
#>
#> $error
#> <error/odin_parse_error>
#> Error in `odin_validate()`:
#> ! Unknown variable used in odin code: 'a'
#> → Context:
#> deriv(x) <- a
#> ℹ For more information, run `odin2::odin_error_explain("E2006")`
#> ---
#> Backtrace:
#> ▆
#> 1. └─pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
#> 2. └─pkgdown::build_site(...)
#> 3. └─pkgdown:::build_site_local(...)
#> 4. └─pkgdown::build_reference(...)
#> 5. ├─pkgdown:::unwrap_purrr_error(...)
#> 6. │ └─base::withCallingHandlers(...)
#> 7. └─purrr::map(...)
#> 8. └─purrr:::map_("list", .x, .f, ..., .progress = .progress)
#> 9. ├─purrr:::with_indexed_errors(...)
#> 10. │ └─base::withCallingHandlers(...)
#> 11. ├─purrr:::call_with_cleanup(...)
#> 12. └─pkgdown (local) .f(.x[[i]], ...)
#> 13. ├─base::withCallingHandlers(...)
#> 14. └─pkgdown:::data_reference_topic(...)
#> 15. └─pkgdown:::run_examples(...)
#> 16. └─pkgdown:::highlight_examples(code, topic, env = env)
#> 17. └─downlit::evaluate_and_highlight(...)
#> 18. └─evaluate::evaluate(code, child_env(env), new_device = TRUE, output_handler = output_handler)
#> 19. ├─base::withRestarts(...)
#> 20. │ └─base (local) withRestartList(expr, restarts)
#> 21. │ ├─base (local) withOneRestart(withRestartList(expr, restarts[-nr]), restarts[[nr]])
#> 22. │ │ └─base (local) doWithOneRestart(return(expr), restart)
#> 23. │ └─base (local) withRestartList(expr, restarts[-nr])
#> 24. │ ├─base (local) withOneRestart(withRestartList(expr, restarts[-nr]), restarts[[nr]])
#> 25. │ │ └─base (local) doWithOneRestart(return(expr), restart)
#> 26. │ └─base (local) withRestartList(expr, restarts[-nr])
#> 27. │ └─base (local) withOneRestart(expr, restarts[[1L]])
#> 28. │ └─base (local) doWithOneRestart(return(expr), restart)
#> 29. ├─evaluate:::with_handlers(...)
#> 30. │ ├─base::eval(call)
#> 31. │ │ └─base::eval(call)
#> 32. │ └─base::withCallingHandlers(...)
#> 33. ├─base::withVisible(eval(expr, envir))
#> 34. └─base::eval(expr, envir)
#> 35. └─base::eval(expr, envir)
#> 36. └─odin2::odin_validate(...)
#>
#> $result
#> NULL
#>
#> $compatibility
#> NULL
#>
# Migration warnings
odin_validate({
initial(x)
deriv(x) <- a
a <- user()
})
#> $success
#> [1] FALSE
#>
#> $error
#> <error/odin_parse_error>
#> Error in `odin_validate()`:
#> ! Unclassifiable expression
#> ℹ Expected an assignment (with '<-') or a relationship (with '~')
#> → Context:
#> initial(x)
#> ℹ For more information, run `odin2::odin_error_explain("E1001")`
#> ---
#> Backtrace:
#> ▆
#> 1. └─pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
#> 2. └─pkgdown::build_site(...)
#> 3. └─pkgdown:::build_site_local(...)
#> 4. └─pkgdown::build_reference(...)
#> 5. ├─pkgdown:::unwrap_purrr_error(...)
#> 6. │ └─base::withCallingHandlers(...)
#> 7. └─purrr::map(...)
#> 8. └─purrr:::map_("list", .x, .f, ..., .progress = .progress)
#> 9. ├─purrr:::with_indexed_errors(...)
#> 10. │ └─base::withCallingHandlers(...)
#> 11. ├─purrr:::call_with_cleanup(...)
#> 12. └─pkgdown (local) .f(.x[[i]], ...)
#> 13. ├─base::withCallingHandlers(...)
#> 14. └─pkgdown:::data_reference_topic(...)
#> 15. └─pkgdown:::run_examples(...)
#> 16. └─pkgdown:::highlight_examples(code, topic, env = env)
#> 17. └─downlit::evaluate_and_highlight(...)
#> 18. └─evaluate::evaluate(code, child_env(env), new_device = TRUE, output_handler = output_handler)
#> 19. ├─base::withRestarts(...)
#> 20. │ └─base (local) withRestartList(expr, restarts)
#> 21. │ ├─base (local) withOneRestart(withRestartList(expr, restarts[-nr]), restarts[[nr]])
#> 22. │ │ └─base (local) doWithOneRestart(return(expr), restart)
#> 23. │ └─base (local) withRestartList(expr, restarts[-nr])
#> 24. │ ├─base (local) withOneRestart(withRestartList(expr, restarts[-nr]), restarts[[nr]])
#> 25. │ │ └─base (local) doWithOneRestart(return(expr), restart)
#> 26. │ └─base (local) withRestartList(expr, restarts[-nr])
#> 27. │ └─base (local) withOneRestart(expr, restarts[[1L]])
#> 28. │ └─base (local) doWithOneRestart(return(expr), restart)
#> 29. ├─evaluate:::with_handlers(...)
#> 30. │ ├─base::eval(call)
#> 31. │ │ └─base::eval(call)
#> 32. │ └─base::withCallingHandlers(...)
#> 33. ├─base::withVisible(eval(expr, envir))
#> 34. └─base::eval(expr, envir)
#> 35. └─base::eval(expr, envir)
#> 36. └─odin2::odin_validate(...)
#>
#> $result
#> NULL
#>
#> $compatibility
#> index type description original
#> 1 3 user Replace calls to 'user()' with 'parameter()' <-, a, u....
#> value start end str
#> 1 <-, a, p.... NA NA <NA>
#>