Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modules support #11

Merged
merged 59 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
e85c5dd
working pkg[att], working pkg[alist = att]
radbasa Aug 6, 2024
f49eabb
helper utils in both needed?
radbasa Aug 6, 2024
95449b5
delint
radbasa Aug 6, 2024
cd3a5b5
update helper utils
radbasa Aug 8, 2024
3ed8e93
move Rprofile lines to inst
radbasa Aug 8, 2024
1f4f5e3
move box_use_parser code to project file
radbasa Aug 8, 2024
2f3f5d5
new use_box_lsp function
radbasa Aug 8, 2024
a387514
some documentation
radbasa Aug 8, 2024
cef1497
repo metadata
radbasa Aug 8, 2024
3f7a585
news update
radbasa Aug 8, 2024
fcefd6f
a test environment set up that seems to work
radbasa Aug 9, 2024
e7d069d
maybe this?
radbasa Aug 9, 2024
b370dc2
another test
radbasa Aug 9, 2024
2eead97
maybe this one?
radbasa Aug 9, 2024
ab8df2b
change root file?
radbasa Aug 9, 2024
89c9cb3
will this work now?
radbasa Aug 9, 2024
08a8a2e
turn on r cmd check in ci
radbasa Aug 9, 2024
d679eb6
fix roxygen notes
radbasa Aug 9, 2024
5aafee9
use different methods for check and test to get source code
radbasa Aug 9, 2024
9e715cf
force r cmd check to pass
radbasa Aug 9, 2024
cdcaa90
need to quote and quote?
radbasa Aug 9, 2024
70d32e3
complete r cmd check args
radbasa Aug 9, 2024
6ce6fdf
github expects one line for args?
radbasa Aug 9, 2024
f7fc2f9
maybe it should be in this form
radbasa Aug 9, 2024
ee91171
a collection instead?
radbasa Aug 9, 2024
8db4763
a commma separated string?
radbasa Aug 9, 2024
b23e9b3
one single string?
radbasa Aug 9, 2024
6ee562f
I finally referred to r-lib/actions/ documentation
radbasa Aug 9, 2024
e68f0c5
fix some typos. replaced the error-on
radbasa Aug 9, 2024
cf15651
cleanup test helper-utils
radbasa Aug 9, 2024
b76999a
ci needs explicit source of function file
radbasa Aug 9, 2024
9c2b93c
keep sourcing of box_use_parser in the box.lsp environment
radbasa Aug 9, 2024
3000e3e
tests skipped for various reasons
radbasa Aug 13, 2024
d28e338
add function signatures to box-attached functions
radbasa Aug 13, 2024
da82f19
initial steps
radbasa Aug 13, 2024
8105ae7
refactor for code reuse
radbasa Aug 13, 2024
d304e75
cleanup
radbasa Aug 13, 2024
35532f7
add module support. add aliases support
radbasa Aug 13, 2024
8f8c98c
update NEWS
radbasa Aug 13, 2024
d248b70
Merge branch 'add-function-signatures' into modules-support
radbasa Aug 13, 2024
7ec5b28
delint
radbasa Aug 13, 2024
cda04bd
Merge branch 'add-function-signatures' into modules-support
radbasa Aug 13, 2024
89f00ba
delint
radbasa Aug 13, 2024
add30f7
Merge branch 'add-function-signatures' into modules-support
radbasa Aug 13, 2024
18c6f4d
fix DESCRIPTION title
radbasa Aug 13, 2024
47c2c26
update feature table
radbasa Aug 13, 2024
a5d0b27
Merge branch 'add-function-signatures' into modules-support
radbasa Aug 13, 2024
043410a
update feature table
radbasa Aug 13, 2024
76f7474
missed one cell
radbasa Aug 13, 2024
64aff24
spelling fix
radbasa Aug 13, 2024
1a2388c
clean up of orphaned imports
radbasa Aug 14, 2024
5f98c4a
Merge branch 'convert-to-package' into add-function-signatures
radbasa Aug 14, 2024
38e9e61
Merge branch 'add-function-signatures' into modules-support
radbasa Aug 14, 2024
302abd7
need to cast to character
radbasa Aug 14, 2024
0803d3e
Merge branch 'main' into convert-to-package
radbasa Aug 15, 2024
789ecf3
remove helper-utils orphaned from merge
radbasa Aug 15, 2024
9aa3c64
Merge branch 'convert-to-package' into add-function-signatures
radbasa Aug 15, 2024
0277511
Merge branch 'add-function-signatures' into modules-support
radbasa Aug 15, 2024
21e1bd5
Merge branch 'main' into modules-support
radbasa Aug 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/test-and-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ jobs:
extra-packages: any::rcmdcheck
needs: check

- name: R CMD CHECK
if: always()
uses: r-lib/actions/check-r-package@v2
with:
error-on: '"note"'
args: 'c("--no-tests", "--no-manual", "--as-cran")'

- name: Lint
if: always()
shell: Rscript {0}
Expand Down
17 changes: 11 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
Package: box.lsp
Title: What the Package Does (One Line, Title Case)
Version: 0.0.0.9002
Title: Provides box-compatibility for languageserver
Version: 0.0.0.9005
Authors@R:
c(
person("Ricardo Rodrigo", "Basa", role = c("aut", "cre"), email = "[email protected]"),
person("Pavel", "Demin", role = "aut", email = "[email protected]"),
person("Jakub", "Nowicki", role = "aut", email = "[email protected]"),
person("Appsilon Sp. z o.o.", role = "cph", email = "[email protected]")
)
Description: What the package does (one paragraph).
Description: A box-compatible custom language parser for the languageserver package to provide
completion and signature hints. Box is a package for modularized code. Languageserver is an
editor client helper for editor features such as auto completion.
License: LGPL (>= 3)
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
Imports:
box,
purrr
Suggests:
cli,
fs,
rlang
Suggests:
languageserver,
lintr,
magrittr,
mockery,
purrr,
rprojroot,
stringi,
stringr,
testthat (>= 3.0.0),
Expand Down
3 changes: 2 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Generated by roxygen2: do not edit by hand

export(box_use_parser)
export(use_box_lsp)
import(box)
import(purrr)
15 changes: 14 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
* box.lsp 0.0.0.9002
# box.lsp 0.0.0.9005

* adds support for modules
* add aliases for both packages and modules

# box.lsp 0.0.0.9004

* add function signatures

# box.lsp 0.0.0.9003

* steps towards package

# box.lsp 0.0.0.9002

* support for pkg[attach_list]
* support for pkg[alias = attached_function]
Expand Down
70 changes: 0 additions & 70 deletions R/Rprofile.R

This file was deleted.

161 changes: 127 additions & 34 deletions R/box_lsp.R
Original file line number Diff line number Diff line change
@@ -1,38 +1,131 @@
#' @import box
NULL

#' @import purrr
NULL
get_box_module_exports <- function(declaration, alias = "", caller = globalenv()) {
if (is.call(declaration)) {
declaration
} else if (is.character(declaration)) {
declaration <- rlang::parse_expr(declaration)
}
parse_spec <- get0("parse_spec", envir = base::loadNamespace("box"))
find_mod <- get0("find_mod.box$mod_spec", envir = base::loadNamespace("box"))
load_mod <- get0("load_mod.box$mod_info", envir = base::loadNamespace("box"))
namespace_info <- get0("namespace_info", envir = base::loadNamespace("box"))

if (any(sapply(list(parse_spec, find_mod, load_mod, namespace_info), is.null))) {
stop("box.linters couldn't load box functions")
}

spec <- parse_spec(declaration, alias)
info <- find_mod(spec, caller)
mod_ns <- load_mod(info)
func_names <- namespace_info(mod_ns, "exports")

lapply(func_names, function(func_name) {
signature <- deparse(mod_ns[[func_name]])[[1]]
names(signature) <- func_name
signature
})
}

process_module <- function(sym_name, signature, action) {
tmp_name <- "temp_func"
empty <- "{ }"
tmp_sig <- paste(tmp_name, "<-", signature, empty)
func_sig <- parse(text = tmp_sig, keep.source = TRUE)[[1]]

action$assign(symbol = as.character(sym_name), value = func_sig[[3L]])
action$parse(func_sig[[3L]])
}

#' Box::use Document Parser
#'
#' Custom \{languageserver\} parser hook for \{box\} modules.
#'
#' @param expr An R expression to evaluate
#' @param action A list of action functions from `languageserver:::parse_expr()`.
#' @returns Used for side-effects provided by the `action` list of functions.
#'
#' @export
box_use_parser <- function(expr, action) {
call <- match.call(box::use, expr)
packages <- unlist(lapply(call[-1], function(x) {
# this is for the last blank in box::use(something, )
if (x == "") {
return()
}

# this is for a whole package attached box::use(dplyr)
if (typeof(x) == "symbol") {
# attempts to get package$func to work
# nolint start
# action$assign(symbol = paste0(as.character(x), "$", getNamespaceExports(as.character(x))), value = NULL)
# action$assign(symbol = getNamespaceExports(as.character(x)), value = NULL)
# return()
# nolint end
return(as.character(x))
}

# this is for a whole module attached box::use(app/logic/utils)
if (as.character(x[[1]]) == "/") {
y <- x[[length(x)]]

# this case is for app/logic/module_one
if (length(y) == 1) {
action$assign(symbol = as.character(y), value = NULL)
}

# this case is for app/logic/module_two[...]
if (length(y) == 3 && y[[3]] == "...") {
# import box module, iterate over its namespace and assign
box_exports <- get_box_module_exports(x)
lapply(box_exports, function(box_export) {
sym_name <- names(box_export)
signature <- box_export

process_module(sym_name, signature, action)
})
}

attached_functions <- as.list(y[-c(1, 2)])
# this case is for app/logic/module_three[a, b, c]
lapply(seq_along(attached_functions), function(z) {
box_exports <- get_box_module_exports(x)
box_exports <- unlist(box_exports)

this_function <- attached_functions[[z]]
this_alias <- rlang::names2(attached_functions)[[z]]

signature <- box_exports[[this_function]]
sym_name <- ifelse(this_alias == "", this_function, this_alias)

process_module(sym_name, signature, action)
})

return()
}

# for box::use(dplyr[<assign list>])
if (x[[1]] == "[") {
attached_functions <- as.list(x[-c(1, 2)])
lapply(seq_along(attached_functions), function(y) {
this_function <- attached_functions[[y]]
this_alias <- rlang::names2(attached_functions)[[y]]

if (this_function != "...") {
namespaced_function <- paste0(as.character(x[[2]]), "::", this_function)
signature <- deparse(eval(parse(text = namespaced_function, keep.source = TRUE)))[[1]]
sym_name <- ifelse(this_alias == "", this_function, this_alias)

process_module(sym_name, signature, action)
}
})

# stash
# nolint start
# box_use_parser <- function(expr, action) {
# fun <- if (requireNamespace("box", quietly = TRUE)) box::use else
# function(...) NULL
# call <- match.call(fun, expr, expand.dots = FALSE)
#
# if(!isTRUE(call$character.only)) {
# packages <- vapply(
# call[["..."]],
# function(item) {
# item <- as.character(item)
# if (item[1] == "[" && grepl("\\.\\.\\.", item[3])) {
# return(item[2])
# } else {
# return("")
# }
# },
# character(1L)
# )
# packages <- purrr::keep(packages, ~. != "")
# action$update(packages = packages)
#
# test_value <- "function(x, y) { \"A \" }"
# action$assign(symbol = "module$fun", value = "function(x, y) { \"A \" }")
# action$parse(test_value)
# }
# }
# nolint end

options(languageserver.trace = TRUE)
options(languageserver.debug = TRUE)
# for box::use(dplyr[a, b, ...])
if (x[[length(x)]] == "...") {
as.character(x[[2]])
}
}
}))
action$update(packages = packages)
}
Loading