@@ -149,6 +149,8 @@ struct ItemMetadata {
149149 comment : Option < Comment > ,
150150 /// A feature requirement that must be enabled for the item
151151 feature : Option < Feature > ,
152+ /// A deprecation message for the item
153+ deprecation : Option < Deprecation > ,
152154}
153155
154156impl ItemMetadata {
@@ -162,35 +164,49 @@ impl ItemMetadata {
162164 /// * `prev` is not a comment, and not a feature requirement.
163165 /// * `prev` is a Comment, and has no feature requirement before it.
164166 /// * `prev` is a Comment, and has a feature requirement before it.
167+ /// * `prev` is a Deprecation, and has a comment and feature requirement before it.
168+ /// * `prev` is a Deprecation, and has a comment and no feature requirement before it.
165169 /// * `prev` is a bare feature requirement
166170 ///
167- /// cbindgen won't create a comment before a feature requirement so we don't have to
168- /// consider that case .
171+ /// cbindgen won't create other permutations (e.g. comment before a feature requirement, or
172+ /// a deprecation before a feature requirement) so we don't have to consider those cases .
169173 fn new ( prev : Node , src : & [ u8 ] ) -> Result < Self , Box < dyn Error > > {
170174 let prev_prev = prev. prev_named_sibling ( ) ;
171175 // In the simple case, `prev` is a comment and `prev_prev` may be a feature requirement.
176+ // Deprecations aren't in play in this case based on how cbindgen works.
172177 if let Ok ( comment) = Comment :: new ( prev, src) {
173178 return Ok ( Self {
174179 comment : Some ( comment) ,
175180 feature : prev_prev. and_then ( |prev_prev| Feature :: new ( prev_prev, src) . ok ( ) ) ,
181+ deprecation : None ,
176182 } ) ;
177183 }
178184
179- // If node wasn't a comment, see if it was an expression_statement
180- // that itself was preceded by a comment. This skips over
181- // expression-like preprocessor attributes on function decls.
182- if prev. kind ( ) == "expression_statement" {
183- return match prev_prev {
184- Some ( prev_prev) => Self :: new ( prev_prev, src) ,
185- None => Ok ( ItemMetadata :: default ( ) ) ,
185+ // `prev` is a deprecation, `prev_prev` may be a comment, and `prev_prev_prev`
186+ // may be a feature requirement.
187+ if let Ok ( deprecation) = Deprecation :: new ( prev, src) {
188+ let ( comment, feature) = match prev_prev {
189+ Some ( prev_prev) => (
190+ Comment :: new ( prev_prev, src) . ok ( ) ,
191+ prev_prev
192+ . prev_named_sibling ( )
193+ . and_then ( |prev_prev_prev| Feature :: new ( prev_prev_prev, src) . ok ( ) ) ,
194+ ) ,
195+ None => ( None , None ) ,
186196 } ;
197+ return Ok ( ItemMetadata {
198+ comment,
199+ feature,
200+ deprecation : Some ( deprecation) ,
201+ } ) ;
187202 }
188203
189- // If `prev` wasn't a comment, or an expression_statement preceded by a comment ,
204+ // If `prev` wasn't a comment, or a deprecation ,
190205 // then it's either a bare feature requirement or we have no metadata to return.
191206 Ok ( Self {
192207 comment : None ,
193208 feature : Feature :: new ( prev, src) . ok ( ) ,
209+ deprecation : None ,
194210 } )
195211 }
196212
@@ -320,6 +336,43 @@ impl Display for Comment {
320336 }
321337}
322338
339+ #[ derive( Debug , Default , Serialize ) ]
340+ struct Deprecation ( String ) ;
341+
342+ impl Deprecation {
343+ fn new ( node : Node , src : & [ u8 ] ) -> Result < Self , Box < dyn Error > > {
344+ require_kind ( "expression_statement" , node, src) ?;
345+
346+ let query_str = r#"
347+ (call_expression
348+ function: (identifier) @func (#eq? @func "DEPRECATED_FUNC")
349+ arguments: (argument_list
350+ (string_literal (string_content) @content)
351+ )
352+ )
353+ "# ;
354+
355+ let mut query_cursor = QueryCursor :: new ( ) ;
356+ let language = tree_sitter_c:: LANGUAGE ;
357+ let query = Query :: new ( & language. into ( ) , query_str) ?;
358+
359+ let mut captures = query_cursor. captures ( & query, node, src) ;
360+ loop {
361+ captures. advance ( ) ;
362+ let Some ( ( mat, _) ) = captures. get ( ) else {
363+ break ;
364+ } ;
365+ for capture in mat. captures {
366+ if query. capture_names ( ) [ capture. index as usize ] == "content" {
367+ return Ok ( Self ( node_text ( capture. node , src) ) ) ;
368+ }
369+ }
370+ }
371+
372+ Err ( node_error ( "DEPRECATED_FUNC call not found or malformed" , node, src) . into ( ) )
373+ }
374+ }
375+
323376fn process_typedef_item (
324377 mut metadata : ItemMetadata ,
325378 item : Node ,
0 commit comments