Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
4 changes: 2 additions & 2 deletions crates/ark/src/lsp/completions/completion_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use std::fs::DirEntry;

use harp::environment::r_env_parent;
use harp::r_symbol;
use harp::syntax::is_valid_symbol;
use harp::syntax::sym_quote;
Expand All @@ -19,7 +20,6 @@ use harp::utils::r_typeof;
use libr::R_UnboundValue;
use libr::Rf_findVarInFrame;
use libr::Rf_isFunction;
use libr::ENCLOS;
use libr::PROMSXP;
use libr::PRVALUE;
use libr::SEXP;
Expand Down Expand Up @@ -480,7 +480,7 @@ pub(super) unsafe fn completion_item_from_namespace(
};

// Otherwise, try the imports environment.
let imports = ENCLOS(namespace);
let imports = r_env_parent(namespace);
let error_imports = match completion_item_from_symbol(
name,
imports,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//
//

use harp::environment::r_env_parent;
use harp::exec::RFunction;
use harp::exec::RFunctionExt;
use harp::utils::r_env_is_pkg_env;
Expand All @@ -14,7 +15,6 @@ use harp::vector::Vector;
use harp::RObject;
use libr::R_EmptyEnv;
use libr::R_lsInternal;
use libr::ENCLOS;
use tower_lsp::lsp_types::CompletionItem;

use crate::console;
Expand Down Expand Up @@ -113,7 +113,7 @@ fn completions_from_search_path(
}

// Get the next environment.
env = ENCLOS(env);
env = r_env_parent(env);
}

// Include installed packages as well.
Expand Down
30 changes: 20 additions & 10 deletions crates/harp/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,14 @@ impl Environment {
}

pub fn parent(&self) -> Option<Environment> {
unsafe {
let parent = ENCLOS(self.inner.sexp);
if parent == R_ENVS.empty {
None
} else {
Some(Self::new_filtered(
RObject::new(parent),
self.filter.clone(),
))
}
let parent = r_env_parent(self.inner.sexp);
if parent == R_ENVS.empty {
None
} else {
Some(Self::new_filtered(
RObject::new(parent),
self.filter.clone(),
))
}
}

Expand Down Expand Up @@ -253,6 +251,18 @@ impl Environment {
}
}

/// Returns the parent (enclosing) environment. Uses `R_ParentEnv` on
/// R >= 4.5 where `ENCLOS` is hidden, with fallback to `ENCLOS` for older R.
pub fn r_env_parent(env: SEXP) -> SEXP {
unsafe {
if libr::has::R_ParentEnv() {
libr::R_ParentEnv(env)
} else {
libr::ENCLOS(env)
}
}
}

impl From<Environment> for SEXP {
fn from(object: Environment) -> Self {
object.inner.sexp
Expand Down
7 changes: 4 additions & 3 deletions crates/harp/src/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::u32;
use libc::c_double;
use libr::*;

use crate::environment::r_env_parent;
use crate::environment::BindingValue;
use crate::environment::Environment;
use crate::environment::R_ENVS;
Expand Down Expand Up @@ -294,7 +295,7 @@ fn obj_size_tree(
}

size += obj_size_tree(
unsafe { libr::ENCLOS(x) },
r_env_parent(x),
base_env,
sizeof_node,
sizeof_vector,
Expand Down Expand Up @@ -359,15 +360,15 @@ fn obj_size_tree(
EXTPTRSXP => {
size += size_of::<*mut c_void>(); // the actual pointer
size += obj_size_tree(
unsafe { libr::EXTPTR_PROT(x) },
unsafe { libr::R_ExternalPtrProtected(x) },
base_env,
sizeof_node,
sizeof_vector,
seen,
depth + 1,
);
size += obj_size_tree(
unsafe { libr::EXTPTR_TAG(x) },
unsafe { libr::R_ExternalPtrTag(x) },
base_env,
sizeof_node,
sizeof_vector,
Expand Down
4 changes: 2 additions & 2 deletions crates/harp/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ pub fn r_is_altrep(object: SEXP) -> bool {
}

pub fn r_is_object(object: SEXP) -> bool {
unsafe { libr::OBJECT(object) != 0 }
unsafe { libr::Rf_isObject(object) != 0 }
}

pub fn r_is_s4(object: SEXP) -> bool {
unsafe { libr::IS_S4_OBJECT(object) != 0 }
unsafe { libr::Rf_isS4(object) != 0 }
Comment on lines -129 to +133
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please go through r.rs and remove anything we no longer need? Like I see OBJECT and IS_S4_OBJECT are still in there, and it would be nice to remove them so we don't accidentally use them again.

}

pub fn r_is_unbound(object: SEXP) -> bool {
Expand Down
10 changes: 10 additions & 0 deletions crates/libr/src/r.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use crate::types::*;
functions::generate! {
pub fn R_NewEnv(enclos: SEXP, hash: std::ffi::c_int, size: std::ffi::c_int) -> SEXP;

pub fn R_ParentEnv(x: SEXP) -> SEXP;

pub fn Rf_initialize_R(ac: std::ffi::c_int, av: *mut *mut std::ffi::c_char) -> std::ffi::c_int;

pub fn run_Rmainloop();
Expand Down Expand Up @@ -60,6 +62,10 @@ functions::generate! {

pub fn R_ExternalPtrAddr(s: SEXP) -> *mut std::ffi::c_void;

pub fn R_ExternalPtrProtected(s: SEXP) -> SEXP;

pub fn R_ExternalPtrTag(s: SEXP) -> SEXP;

pub fn R_MakeExternalPtr(p: *mut std::ffi::c_void, tag: SEXP, prot: SEXP) -> SEXP;

pub fn R_MakeWeakRefC(key: SEXP, val: SEXP, fin: R_CFinalizer_t, onexit: Rboolean) -> SEXP;
Expand Down Expand Up @@ -166,6 +172,10 @@ functions::generate! {

pub fn Rf_isInteger(arg1: SEXP) -> Rboolean;

pub fn Rf_isObject(arg1: SEXP) -> Rboolean;

pub fn Rf_isS4(arg1: SEXP) -> Rboolean;

pub fn Rf_isMatrix(arg1: SEXP) -> Rboolean;

pub fn Rf_isNumeric(arg1: SEXP) -> Rboolean;
Expand Down