@@ -30,16 +30,14 @@ use crate::vector::CharacterVector;
30
30
use crate :: vector:: Vector ;
31
31
32
32
pub struct RCall {
33
- package : String ,
34
- function : String ,
33
+ function : RObject ,
35
34
arguments : Vec < RArgument > ,
36
35
}
37
36
38
37
impl RCall {
39
- pub fn new ( package : & str , function : & str ) -> Self {
38
+ pub fn new ( function : impl Into < RObject > ) -> Self {
40
39
Self {
41
- package : package. to_string ( ) ,
42
- function : function. to_string ( ) ,
40
+ function : function. into ( ) ,
43
41
arguments : Vec :: new ( ) ,
44
42
}
45
43
}
@@ -60,22 +58,11 @@ impl RCall {
60
58
unsafe {
61
59
let mut protect = RProtect :: new ( ) ;
62
60
63
- let fun = if self . package . is_empty ( ) {
64
- r_symbol ! ( self . function)
65
- } else {
66
- Rf_lang3 (
67
- r_symbol ! ( "::" ) ,
68
- r_symbol ! ( self . package) ,
69
- r_symbol ! ( self . function) ,
70
- )
71
- } ;
72
- protect. add ( fun) ;
73
-
74
61
// Now, build the actual call to be evaluated
75
62
let size = ( 1 + self . arguments . len ( ) ) as R_xlen_t ;
76
63
let call = protect. add ( Rf_allocVector ( LANGSXP , size) ) ;
77
64
SET_TAG ( call, R_NilValue ) ;
78
- SETCAR ( call, fun ) ;
65
+ SETCAR ( call, self . function . sexp ) ;
79
66
80
67
// Append arguments to the call
81
68
let mut slot = CDR ( call) ;
@@ -103,23 +90,71 @@ impl RCall {
103
90
RObject :: new ( call)
104
91
}
105
92
}
93
+ }
94
+
95
+ pub struct RArgument {
96
+ pub name : String ,
97
+ pub value : RObject ,
98
+ }
99
+
100
+ impl RArgument {
101
+ pub fn new ( name : & str , value : RObject ) -> Self {
102
+ Self {
103
+ name : name. to_string ( ) ,
104
+ value,
105
+ }
106
+ }
107
+ }
108
+
109
+ pub struct RFunction {
110
+ pub call : RCall ,
111
+ is_namespaced : bool ,
112
+ }
113
+
114
+ impl RFunction {
115
+ pub fn new ( package : & str , function : & str ) -> Self {
116
+ Self :: new_ext ( package, function, false )
117
+ }
118
+
119
+ pub fn new_internal ( package : & str , function : & str ) -> Self {
120
+ Self :: new_ext ( package, function, true )
121
+ }
122
+
123
+ fn new_ext ( package : & str , function : & str , internal : bool ) -> Self {
124
+ unsafe {
125
+ let is_namespaced = !package. is_empty ( ) ;
126
+
127
+ let fun = if is_namespaced {
128
+ let op = if internal { ":::" } else { "::" } ;
129
+ Rf_lang3 ( r_symbol ! ( op) , r_symbol ! ( package) , r_symbol ! ( function) )
130
+ } else {
131
+ r_symbol ! ( function)
132
+ } ;
133
+ let fun = RObject :: new ( fun) ;
134
+
135
+ RFunction {
136
+ call : RCall :: new ( fun) ,
137
+ is_namespaced,
138
+ }
139
+ }
140
+ }
106
141
107
142
pub fn call ( & mut self ) -> Result < RObject > {
108
143
// FIXME: Once we have ArkFunction (see
109
144
// https://github.com/posit-dev/positron/issues/2324), we no longer need
110
145
// this logic to call in global. This probably shouldn't be the default?
111
- let env = if self . package . is_empty ( ) {
112
- R_ENVS . global
113
- } else {
146
+ let env = if self . is_namespaced {
114
147
R_ENVS . base
148
+ } else {
149
+ R_ENVS . global
115
150
} ;
116
151
117
152
self . call_in ( env)
118
153
}
119
154
120
155
pub fn call_in ( & mut self , env : SEXP ) -> Result < RObject > {
121
156
unsafe {
122
- let call = self . build ( ) ;
157
+ let call = self . call . build ( ) ;
123
158
124
159
let mut protect = RProtect :: new ( ) ;
125
160
@@ -152,43 +187,6 @@ impl RCall {
152
187
}
153
188
}
154
189
155
- pub struct RArgument {
156
- pub name : String ,
157
- pub value : RObject ,
158
- }
159
-
160
- impl RArgument {
161
- pub fn new ( name : & str , value : RObject ) -> Self {
162
- Self {
163
- name : name. to_string ( ) ,
164
- value,
165
- }
166
- }
167
- }
168
-
169
- pub struct RFunction {
170
- call : RCall ,
171
- }
172
-
173
- // TODO: Should be replaced by RCall. Then RFunction could become an enum
174
- // representation of LANGSXP's CAR (with symbolic and inline variants?),
175
- // consistently with RArgument being a representation of a LISTSXP's CAR/TAG.
176
- impl RFunction {
177
- pub fn new ( package : & str , function : & str ) -> Self {
178
- RFunction {
179
- call : RCall :: new ( package, function) ,
180
- }
181
- }
182
-
183
- pub fn call_in ( & mut self , env : SEXP ) -> Result < RObject > {
184
- self . call . call_in ( env)
185
- }
186
-
187
- pub fn call ( & mut self ) -> Result < RObject > {
188
- self . call . call ( )
189
- }
190
- }
191
-
192
190
impl From < & str > for RFunction {
193
191
fn from ( function : & str ) -> Self {
194
192
RFunction :: new ( "" , function)
0 commit comments