In order to test the functions of this package some R scripts are downloaded from GitHub and provided locally:
# Define URLs to some example scripts
urls <- kwb.utils::resolve(list(
kwb = "https://raw.githubusercontent.com/KWB-R",
utils = "<kwb>/kwb.utils/master/R",
log = "<utils>/log.R",
main = "<utils>/main.R",
fakin = "<kwb>/kwb.fakin/master/R/plot_file_distribution.R"
))
# Create a temporary folder
root <- kwb.utils::createDirectory(
kwb.utils::tempSubdirectory("test"),
dbg = FALSE
)
# Helper function to download a text file to the temporary folder
download_script <- function(url) {
download.file(
url,
destfile = file.path(root, basename(url)),
mode = "wt"
)
}
# Download three scripts to the temporary folder
download_script(urls$fakin)
download_script(urls$log)
download_script(urls$main)
The parse tree is analysed. Each node of the tree is given the following attributes:
The idea probably was to use these information to extract objects of special interest from the parse tree (see below: get_elements_by_type())
x <- parse(urls$log)
result <- kwb.code::analyse(x)
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXct.default(x) :
#> do not know how to convert 'x' to class "POSIXct"
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.finite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.infinite.POSIXlt(x) returned an error. Returning FALSE.
#> Error in as.POSIXlt.character(x, tz, ...) :
#> character string is not in a standard unambiguous format
#> is.nan.POSIXlt(x) returned an error. Returning FALSE.
This function returns the names of the arguments of a function:
This function requires a directory of R scripts. All scripts are parsed. String constants that are used in the script are returned.
string_constants <- kwb.code::find_string_constants(root)
#> Splitting paths ... ok. (0.00 secs)
#> Removing the first 3 path segments ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/log.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/main.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/plot_file_distribution.R ... ok. (0.00 secs)
knitr::kable(string_constants)
file_id | folder_path | file_name | string | count |
---|---|---|---|---|
file_01 | test | log.R | 1 | |
file_01 | test | log.R | *** | 3 |
file_01 | test | log.R | *** ok. | 1 |
file_01 | test | log.R | … | 1 |
file_02 | test | main.R | 2 | |
file_02 | test | main.R | *** The object is empty! | 1 |
file_02 | test | main.R | as requested but | 1 |
file_02 | test | main.R | ! | 1 |
file_02 | test | main.R | $ | 1 |
file_02 | test | main.R | %s_%d | 1 |
file_02 | test | main.R | %s_1 | 1 |
file_02 | test | main.R | ‘assign(x, value, envir = .GlobalEnv)’ | 1 |
file_02 | test | main.R | (returned in attribute ‘invalid’) | 1 |
file_02 | test | main.R | . | 1 |
file_02 | test | main.R | Bug in randomValuesWithSum(): The sum of generated values is not | 1 |
file_02 | test | main.R | Division by zero. Using substitute value of | 1 |
file_02 | test | main.R | The first element must not be NA | 1 |
file_02 | test | main.R | There are differences in parallel non-NA values | 1 |
file_02 | test | main.R | There are duplicate values: | 1 |
file_02 | test | main.R | _()$ | 1 |
file_02 | test | main.R | assignGlobally() | 1 |
file_02 | test | main.R | invalid | 1 |
file_02 | test | main.R | parName | 1 |
file_02 | test | main.R | parVal | 1 |
file_02 | test | main.R | stringsAsFactors | 1 |
file_02 | test | main.R | stringsAsFactors must be TRUE or FALSE | 1 |
file_03 | test | plot_file_distribution.R | lr | 1 |
file_03 | test | plot_file_distribution.R | v | 1 |
Check for expressions in scripts that can be improved.
x <- parse(text = c(
"texts <- c(",
" paste('this is a very long', 'text'),",
" paste('this is a very long', 'string')",
")",
"",
"indices <- 1:length(texts)"
))
weaknesses <- kwb.code::find_weaknesses_in_scripts(
x = list(test = x),
min_duplicate_frequency = 2L
)
knitr::kable(weaknesses)
file | expression | frequency | recommendation | |
---|---|---|---|---|
1 | test | 1:length(texts) | 1 | use seq_along() |
3 | test | “this is a very long” | 2 | check for duplicated strings |
This function groups similar elements that are found in a parse tree.
# Parse an R script file (here, a file from kwb.utils)
x <- parse(urls$log)
# For each "type" of code segment, extract all occurrences
elements <- kwb.code::get_elements_by_type(x, result = result)
# Show all code blocks in curly braces
elements[["language|call|{|2|"]]
#> [[1]]
#> {
#> cat("***", ...)
#> }
#>
#> [[2]]
#> {
#> cat("***", ..., "\n")
#> }
#>
#> [[3]]
#> {
#> catIf(dbg, "*** ok.\n")
#> }
#>
#> [[4]]
#> {
#> catIf(dbg, "***", ..., "... ")
#> }
This function analyses a list of parse trees each of which has been read from an R script.
It provides information on the functions that are defined in the scripts:
trees <- kwb.code::parse_scripts(root, dbg = FALSE)
function_info <- kwb.code::get_full_function_info(trees)
knitr::kable(function_info)
script | functionName | n.def | bodyClass | n.args | n.defaults | n.expr |
---|---|---|---|---|---|---|
log.R | .log | 1 | { | 1 | 0 | 1 |
log.R | .logline | 1 | { | 1 | 0 | 1 |
log.R | .logok | 1 | { | 1 | 1 | 1 |
log.R | .logstart | 1 | { | 2 | 1 | 1 |
plot_file_distribution.R | arrange_file_in_depth_plots | 1 | { | 3 | 0 | 5 |
main.R | assignAll | 1 | { | 3 | 1 | 2 |
main.R | assignGlobally | 1 | { | 2 | 0 | 2 |
main.R | assignPackageObjects | 1 | { | 1 | 0 | 1 |
main.R | breakInSequence | 1 | { | 2 | 1 | 2 |
main.R | callWithStringsAsFactors | 1 | { | 3 | 0 | 6 |
main.R | extendLimits | 1 | { | 4 | 2 | 3 |
main.R | getEvenNumbers | 1 | { | 1 | 0 | 1 |
main.R | getGlobally | 1 | { | 3 | 2 | 2 |
main.R | getOddNumbers | 1 | { | 1 | 0 | 1 |
main.R | hsMatrixToListForm | 1 | { | 6 | 4 | 4 |
main.R | hsSafeName | 1 | { | 2 | 0 | 3 |
main.R | makeUnique | 1 | { | 4 | 3 | 3 |
main.R | naToLastNonNa | 1 | { | 2 | 1 | 6 |
main.R | parallelNonNA | 1 | { | 2 | 0 | 12 |
plot_file_distribution.R | plot_file_distribution | 1 | { | 5 | 1 | 11 |
main.R | quotient | 1 | { | 4 | 2 | 6 |
main.R | randomValuesWithSum | 1 | { | 3 | 1 | 5 |
main.R | recursiveNames | 1 | { | 2 | 1 | 4 |
main.R | warnIfEmpty | 1 | { | 1 | 0 | 2 |
What packages are used in the scripts?
kwb.code::get_names_of_used_packages(root)
#> Analysing /tmp/RtmprISxBN/test/log.R ... ok. (0.00 secs)
#> Analysing /tmp/RtmprISxBN/test/main.R ... ok. (0.00 secs)
#> Analysing /tmp/RtmprISxBN/test/plot_file_distribution.R ... ok. (0.00 secs)
#> character(0)
This function simply looks for calls to library()
. It
does not take into account functions that are called with
::
as the following simple grep()
reveals:
pattern <- "[^A-Za-z_.]([A-Za-z_.]+::[A-Za-z_.]+)[^A-Za-z_.]"
text <- grep(pattern, readLines(urls$fakin), value = TRUE)
unique(kwb.utils::extractSubstring(pattern, text, index = 1))
#> [1] "kwb.pathdict::random_paths" "kwb.utils::noFactorDataFrame"
#> [3] "kwb.fakin::plot_file_distribution" "kwb.utils::assignPackageObjects"
#> [5] "kwb.utils::preparePdfIf" "kwb.utils::finishAndShowPdfIf"
#> [7] "cowplot::plot_grid"
TODO: Use another function instead…
tree <- kwb.code::parse_scripts(root, dbg = FALSE)
function_usage <- kwb.code::get_package_function_usage(
tree,
package = "kwb.utils"
)
knitr::kable(function_usage)
package | name | count | explicit | implicit |
---|---|---|---|---|
kwb.utils | catIf | 2 | 0 | 2 |
kwb.utils | finishAndShowPdfIf | 1 | 1 | 0 |
kwb.utils | hsRestoreAttributes | 1 | 0 | 1 |
kwb.utils | isEvenNumber | 1 | 0 | 1 |
kwb.utils | isNullOrEmpty | 1 | 0 | 1 |
kwb.utils | isOddNumber | 1 | 0 | 1 |
kwb.utils | lastElement | 1 | 0 | 1 |
kwb.utils | preparePdfIf | 1 | 1 | 0 |
kwb.utils | rbindAll | 1 | 0 | 1 |
kwb.utils | recursiveNames | 1 | 0 | 1 |
kwb.utils | stringList | 1 | 0 | 1 |
kwb.utils | warningDeprecated | 1 | 0 | 1 |
package_usage <- kwb.code::get_package_usage_per_script(
root,
packages = "kwb.utils"
)
#> Reading /tmp/RtmprISxBN/test/log.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/main.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/plot_file_distribution.R ... ok. (0.00 secs)
#> 3 scripts have been parsed.
#> Checking usage of kwb.utils ...
#> ok. (0.02 secs)
package | script | name | count | explicit | implicit |
---|---|---|---|---|---|
kwb.utils | log.R | catIf | 2 | 0 | 2 |
kwb.utils | main.R | hsRestoreAttributes | 1 | 0 | 1 |
kwb.utils | main.R | isEvenNumber | 1 | 0 | 1 |
kwb.utils | main.R | isNullOrEmpty | 1 | 0 | 1 |
kwb.utils | main.R | isOddNumber | 1 | 0 | 1 |
kwb.utils | main.R | lastElement | 1 | 0 | 1 |
kwb.utils | main.R | rbindAll | 1 | 0 | 1 |
kwb.utils | main.R | recursiveNames | 1 | 0 | 1 |
kwb.utils | main.R | stringList | 1 | 0 | 1 |
kwb.utils | main.R | warningDeprecated | 1 | 0 | 1 |
kwb.utils | plot_file_distribution.R | finishAndShowPdfIf | 1 | 1 | 0 |
kwb.utils | plot_file_distribution.R | preparePdfIf | 1 | 1 | 0 |
string_constants <- kwb.code::get_string_constants_in_scripts(root)
#> Splitting paths ... ok. (0.00 secs)
#> Removing the first 3 path segments ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/log.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/main.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/plot_file_distribution.R ... ok. (0.00 secs)
file_id | string | count |
---|---|---|
file_01 | 1 | |
file_01 | *** | 3 |
file_01 | *** ok. | 1 |
file_01 | … | 1 |
file_02 | 2 | |
file_02 | *** The object is empty! | 1 |
file_02 | as requested but | 1 |
file_02 | ! | 1 |
file_02 | $ | 1 |
file_02 | %s_%d | 1 |
file_02 | %s_1 | 1 |
file_02 | ‘assign(x, value, envir = .GlobalEnv)’ | 1 |
file_02 | (returned in attribute ‘invalid’) | 1 |
file_02 | . | 1 |
file_02 | Bug in randomValuesWithSum(): The sum of generated values is not | 1 |
file_02 | Division by zero. Using substitute value of | 1 |
file_02 | The first element must not be NA | 1 |
file_02 | There are differences in parallel non-NA values | 1 |
file_02 | There are duplicate values: | 1 |
file_02 | _()$ | 1 |
file_02 | assignGlobally() | 1 |
file_02 | invalid | 1 |
file_02 | parName | 1 |
file_02 | parVal | 1 |
file_02 | stringsAsFactors | 1 |
file_02 | stringsAsFactors must be TRUE or FALSE | 1 |
file_03 | lr | 1 |
file_03 | v | 1 |
x <- kwb.code::parse_scripts(root)
#> Reading /tmp/RtmprISxBN/test/log.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/main.R ... ok. (0.00 secs)
#> Reading /tmp/RtmprISxBN/test/plot_file_distribution.R ... ok. (0.00 secs)
str(x, 2)
#> List of 3
#> $ log.R :length 4 expression(.log <- function(...) { cat("***", ...) }, .logline <- function(...) { cat("***", ..., "\n") }, .log| __truncated__ ...
#> ..- attr(*, "n.lines")= int 50
#> $ main.R :length 18 expression(randomValuesWithSum <- function(n, sumOfValues, names = seq_len(n)) { breaks <- sort(sample(sumOfValu| __truncated__ ...
#> ..- attr(*, "n.lines")= int 575
#> $ plot_file_distribution.R:length 2 expression(plot_file_distribution <- function(file_data, start_path, n_root_parts, ..., to_pdf = TRUE) { data_s| __truncated__
#> ..- attr(*, "n.lines")= int 93
This function creates statistics about R scripts.
script | errors | rows | expr | rpe | <- | fun |
---|---|---|---|---|---|---|
log.R | 50 | 4 | 12.5 | 4 | 4 | |
main.R | 575 | 18 | 31.9 | 18 | 18 | |
plot_file_distribution.R | 93 | 2 | 46.5 | 2 | 2 |