@@ -22,18 +22,50 @@ pub struct Package {
22
22
pub description : Description ,
23
23
pub namespace : Namespace ,
24
24
pub documentation : Documentation ,
25
+
26
+ // List of symbols exported via NAMESPACE `export()` directives and via
27
+ // `DocType{data}`. Note the latter should only apply to packages with
28
+ // `LazyData: true` but currently applies to all packages, as a stopgap
29
+ // to prevent spurious diagnostics (we accept false negatives to avoid
30
+ // annoying false positives).
31
+ pub exported_symbols : Vec < String > ,
25
32
}
26
33
27
34
impl Package {
28
- pub fn new ( path : PathBuf , description : Description , namespace : Namespace ) -> Self {
35
+ pub fn new (
36
+ path : PathBuf ,
37
+ description : Description ,
38
+ namespace : Namespace ,
39
+ documentation : Documentation ,
40
+ ) -> Self {
41
+ // Compute exported symbols. Start from explicit NAMESPACE exports.
42
+ let mut exported_symbols = namespace. exports . clone ( ) ;
43
+
44
+ // Add exported datasets. Ideally we'd only do that for packages
45
+ // specifying `LazyData: true`.
46
+ let exported_datasets = documentation. rd_files . iter ( ) . filter_map ( |rd| {
47
+ if rd. doc_type == Some ( crate :: lsp:: inputs:: documentation_rd_file:: RdDocType :: Data ) {
48
+ rd. name . clone ( )
49
+ } else {
50
+ None
51
+ }
52
+ } ) ;
53
+ exported_symbols. extend ( exported_datasets) ;
54
+
29
55
Self {
30
56
path,
31
57
description,
32
58
namespace,
33
- documentation : Default :: default ( ) ,
59
+ documentation,
60
+ exported_symbols,
34
61
}
35
62
}
36
63
64
+ #[ cfg( test) ]
65
+ pub fn from_parts ( path : PathBuf , description : Description , namespace : Namespace ) -> Self {
66
+ Self :: new ( path, description, namespace, Default :: default ( ) )
67
+ }
68
+
37
69
/// Load a package from a given path.
38
70
pub fn load_from_folder ( package_path : & std:: path:: Path ) -> anyhow:: Result < Option < Self > > {
39
71
let description_path = package_path. join ( "DESCRIPTION" ) ;
@@ -69,12 +101,12 @@ impl Package {
69
101
} ,
70
102
} ;
71
103
72
- Ok ( Some ( Package {
73
- path : package_path. to_path_buf ( ) ,
104
+ Ok ( Some ( Self :: new (
105
+ package_path. to_path_buf ( ) ,
74
106
description,
75
107
namespace,
76
108
documentation,
77
- } ) )
109
+ ) ) )
78
110
}
79
111
80
112
/// Load a package from the given library path and name.
@@ -98,3 +130,57 @@ impl Package {
98
130
}
99
131
}
100
132
}
133
+
134
+ #[ cfg( test) ]
135
+ mod tests {
136
+ use super :: * ;
137
+ use crate :: lsp:: inputs:: documentation_rd_file:: RdDocType ;
138
+ use crate :: lsp:: inputs:: documentation_rd_file:: RdFile ;
139
+ use crate :: lsp:: inputs:: package_description:: Description ;
140
+ use crate :: lsp:: inputs:: package_namespace:: Namespace ;
141
+
142
+ #[ test]
143
+ fn test_exported_symbols_combining_namespace_and_rd_files ( ) {
144
+ let namespace = Namespace {
145
+ exports : vec ! [ "foo" . to_string( ) , "bar" . to_string( ) ] ,
146
+ ..Default :: default ( )
147
+ } ;
148
+
149
+ let rd_files = vec ! [
150
+ RdFile {
151
+ name: Some ( "data1" . to_string( ) ) ,
152
+ doc_type: Some ( RdDocType :: Data ) ,
153
+ } ,
154
+ RdFile {
155
+ name: Some ( "pkgdoc" . to_string( ) ) ,
156
+ doc_type: Some ( RdDocType :: Package ) ,
157
+ } ,
158
+ RdFile {
159
+ name: Some ( "other" . to_string( ) ) ,
160
+ doc_type: None ,
161
+ } ,
162
+ ] ;
163
+ let documentation = Documentation { rd_files } ;
164
+
165
+ let description = Description {
166
+ name : "mypkg" . to_string ( ) ,
167
+ version : "1.0.0" . to_string ( ) ,
168
+ depends : vec ! [ ] ,
169
+ fields : Default :: default ( ) ,
170
+ } ;
171
+
172
+ let package = Package :: new (
173
+ PathBuf :: from ( "/mock/path" ) ,
174
+ description,
175
+ namespace,
176
+ documentation,
177
+ ) ;
178
+
179
+ assert ! ( package. exported_symbols. contains( & "foo" . to_string( ) ) ) ;
180
+ assert ! ( package. exported_symbols. contains( & "bar" . to_string( ) ) ) ;
181
+ assert ! ( package. exported_symbols. contains( & "data1" . to_string( ) ) ) ;
182
+
183
+ assert ! ( !package. exported_symbols. contains( & "pkgdoc" . to_string( ) ) ) ;
184
+ assert ! ( !package. exported_symbols. contains( & "other" . to_string( ) ) ) ;
185
+ }
186
+ }
0 commit comments