@@ -145,6 +145,8 @@ struct ItemMetadata {
145
145
comment : Option < Comment > ,
146
146
/// A feature requirement that must be enabled for the item
147
147
feature : Option < Feature > ,
148
+ /// A deprecation message for the item
149
+ deprecation : Option < Deprecation > ,
148
150
}
149
151
150
152
impl ItemMetadata {
@@ -158,15 +160,17 @@ impl ItemMetadata {
158
160
/// * `prev` is not a comment, and not a feature requirement.
159
161
/// * `prev` is a Comment, and has no feature requirement before it.
160
162
/// * `prev` is a Comment, and has a feature requirement before it.
163
+ /// * `prev` is a Deprecation, and has a comment and feature requirement before it.
164
+ /// * `prev` is a Deprecation, and has a comment and no feature requirement before it.
161
165
/// * `prev` is a bare feature requirement
162
166
///
163
- /// cbindgen won't create a comment before a feature requirement so we don't have to
164
- /// consider that case .
167
+ /// cbindgen won't create other permutations (e.g. comment before a feature requirement, or
168
+ /// a deprecation before a feature requirement) so we don't have to consider those cases .
165
169
fn new ( prev : Node , src : & [ u8 ] ) -> Result < Self , Box < dyn Error > > {
166
170
let prev_prev = prev. prev_named_sibling ( ) ;
167
171
168
172
// In the simple case, `prev` is a comment and `prev_prev` may
169
- // be a feature requirement.
173
+ // be a feature requirement. Deprecations aren't in play.
170
174
if let Ok ( comment) = Comment :: new ( prev, src) {
171
175
let feature = match prev_prev {
172
176
Some ( prev_prev) => Feature :: new ( prev_prev, src) . ok ( ) ,
@@ -175,24 +179,36 @@ impl ItemMetadata {
175
179
return Ok ( ItemMetadata {
176
180
comment : Some ( comment) ,
177
181
feature,
182
+ deprecation : None ,
178
183
} ) ;
179
184
}
180
185
181
- // If `prev` wasn't a comment, see if it was an expression_statement
182
- // that itself was preceded by a comment. This skips over
183
- // expression-like preprocessor attributes on function decls.
184
- if prev. kind ( ) == "expression_statement" {
185
- return match prev_prev {
186
- Some ( prev_prev) => Self :: new ( prev_prev, src) ,
187
- None => Ok ( ItemMetadata :: default ( ) ) ,
186
+ // `prev` is a deprecation, `prev_prev` may be a comment, and `prev_prev_prev`
187
+ // may be a feature requirement.
188
+ if let Ok ( deprecation) = Deprecation :: new ( prev, src) {
189
+ let comment = match prev_prev {
190
+ Some ( prev_prev) => Comment :: new ( prev_prev, src) . ok ( ) ,
191
+ None => None ,
192
+ } ;
193
+ let prev_prev_prev = prev_prev. and_then ( |prev_prev| prev_prev. prev_named_sibling ( ) ) ;
194
+ let feature = match prev_prev_prev {
195
+ Some ( prev_prev_prev) => Feature :: new ( prev_prev_prev, src) . ok ( ) ,
196
+ None => None ,
188
197
} ;
198
+ return Ok ( ItemMetadata {
199
+ comment,
200
+ feature,
201
+ deprecation : Some ( deprecation) ,
202
+ } ) ;
189
203
}
190
204
191
205
// If `prev` wasn't a comment, or an expression_statement preceded by a comment,
192
- // then it's either a bare feature requirement or we have no metadata to return.
206
+ // then it's either a bare feature requirement without a deprecation or we have no
207
+ // metadata to return.
193
208
Ok ( ItemMetadata {
194
209
comment : None ,
195
210
feature : Feature :: new ( prev, src) . ok ( ) ,
211
+ deprecation : None ,
196
212
} )
197
213
}
198
214
@@ -322,6 +338,39 @@ impl Display for Comment {
322
338
}
323
339
}
324
340
341
+ #[ derive( Debug , Default , Serialize ) ]
342
+ struct Deprecation ( String ) ;
343
+
344
+ impl Deprecation {
345
+ fn new ( node : Node , src : & [ u8 ] ) -> Result < Self , Box < dyn Error > > {
346
+ require_kind ( "expression_statement" , node, src) ?;
347
+
348
+ let query_str = r#"
349
+ (call_expression
350
+ function: (identifier) @func (#eq? @func "DEPRECATED_FUNC")
351
+ arguments: (argument_list
352
+ (string_literal (string_content) @content)
353
+ )
354
+ )
355
+ "# ;
356
+
357
+ let mut query_cursor = QueryCursor :: new ( ) ;
358
+ let language = tree_sitter_c:: LANGUAGE ;
359
+ let query = Query :: new ( & language. into ( ) , query_str) ?;
360
+
361
+ let captures = query_cursor. captures ( & query, node, src) ;
362
+ for ( mat, _) in captures {
363
+ for capture in mat. captures {
364
+ if query. capture_names ( ) [ capture. index as usize ] == "content" {
365
+ return Ok ( Self ( node_text ( capture. node , src) ) ) ;
366
+ }
367
+ }
368
+ }
369
+
370
+ Err ( node_error ( "DEPRECATED_FUNC call not found or malformed" , node, src) . into ( ) )
371
+ }
372
+ }
373
+
325
374
fn process_typedef_item (
326
375
mut metadata : ItemMetadata ,
327
376
item : Node ,
0 commit comments