@@ -76,7 +76,7 @@ async fn ns_populate_srcref_without_vdoc_insertion(
7676
7777 for b in ns. iter ( ) . filter_map ( Result :: ok) {
7878 span. in_scope ( || {
79- match generate_source ( & b, vdoc. len ( ) , & uri) {
79+ match generate_source ( & b, ns . inner . sexp , vdoc. len ( ) , & uri) {
8080 Ok ( Some ( mut lines) ) => {
8181 n_ok = n_ok + 1 ;
8282
@@ -122,6 +122,7 @@ fn ark_ns_uri(ns_name: &str) -> String {
122122#[ tracing:: instrument( level = "trace" , skip_all, fields( name = %binding. name) ) ]
123123fn generate_source (
124124 binding : & Binding ,
125+ ns_env : SEXP ,
125126 line : usize ,
126127 uri : & String ,
127128) -> anyhow:: Result < Option < Vec < String > > > {
@@ -160,10 +161,8 @@ fn generate_source(
160161 // Inject source references in functions. This is slightly unsafe but we
161162 // couldn't think of a dire failure mode.
162163 unsafe {
163- // First replace the body which contains expressions tagged with srcrefs
164- // such as calls to `{`. Compiled functions are a little more tricky.
164+ let body = harp:: fn_body ( old. sexp ) ;
165165
166- let body = BODY ( old. sexp ) ;
167166 if r_typeof ( body) == BCODESXP {
168167 // This is a compiled function. We could recompile the fresh
169168 // function we just created but the compiler is very slow. Instead,
@@ -179,16 +178,35 @@ fn generate_source(
179178 // Inject new body instrumented with source references
180179 SET_VECTOR_ELT ( consts, 0 , R_ClosureExpr ( new) ) ;
181180 }
181+
182+ Rf_setAttrib (
183+ old. sexp ,
184+ r_symbol ! ( "srcref" ) ,
185+ Rf_getAttrib ( new, r_symbol ! ( "srcref" ) ) ,
186+ ) ;
182187 } else {
183- SET_BODY ( old. sexp , BODY ( new) ) ;
184- }
188+ let new_body = harp:: fn_body ( new) ;
189+ let out = RObject :: new ( harp:: new_function (
190+ harp:: fn_formals ( old. sexp ) ,
191+ new_body,
192+ harp:: fn_env ( old. sexp ) ,
193+ ) ) ;
194+
195+ // TODO: Avoid `ATTRIB()`
196+ let attrib = ATTRIB ( old. sexp ) ;
197+ if attrib != R_NilValue {
198+ let attrib = RObject :: new ( Rf_shallow_duplicate ( attrib) ) ;
199+ SET_ATTRIB ( out. sexp , attrib. sexp ) ;
200+ }
185201
186- // Finally push the srcref attribute for the whole function
187- Rf_setAttrib (
188- old. sexp ,
189- r_symbol ! ( "srcref" ) ,
190- Rf_getAttrib ( new, r_symbol ! ( "srcref" ) ) ,
191- ) ;
202+ Rf_setAttrib (
203+ out. sexp ,
204+ r_symbol ! ( "srcref" ) ,
205+ Rf_getAttrib ( new, r_symbol ! ( "srcref" ) ) ,
206+ ) ;
207+
208+ harp:: env_bind_force ( ns_env, binding. name . sexp , out. sexp ) ;
209+ }
192210 }
193211
194212 let text: Vec < String > = RObject :: view ( text) . try_into ( ) ?;
0 commit comments