@@ -144,6 +144,8 @@ struct ItemMetadata {
144144 comment : Option < Comment > ,
145145 /// A feature requirement that must be enabled for the item
146146 feature : Option < Feature > ,
147+ /// A deprecation message for the item
148+ deprecation : Option < Deprecation > ,
147149}
148150
149151impl ItemMetadata {
@@ -157,35 +159,50 @@ impl ItemMetadata {
157159 /// * `prev` is not a comment, and not a feature requirement.
158160 /// * `prev` is a Comment, and has no feature requirement before it.
159161 /// * `prev` is a Comment, and has a feature requirement before it.
162+ /// * `prev` is a Deprecation, and has a comment and feature requirement before it.
163+ /// * `prev` is a Deprecation, and has a comment and no feature requirement before it.
160164 /// * `prev` is a bare feature requirement
161165 ///
162- /// cbindgen won't create a comment before a feature requirement so we don't have to
163- /// consider that case .
166+ /// cbindgen won't create other permutations (e.g. comment before a feature requirement, or
167+ /// a deprecation before a feature requirement) so we don't have to consider those cases .
164168 fn new ( prev : Node , src : & [ u8 ] ) -> Result < Self , Box < dyn Error > > {
165169 let prev_prev = prev. prev_named_sibling ( ) ;
166170 // In the simple case, `prev` is a comment and `prev_prev` may be a feature requirement.
171+ // Deprecations aren't in play in this case based on how cbindgen works.
167172 if let Ok ( comment) = Comment :: new ( prev, src) {
168173 return Ok ( Self {
169174 comment : Some ( comment) ,
170175 feature : prev_prev. and_then ( |prev_prev| Feature :: new ( prev_prev, src) . ok ( ) ) ,
176+ deprecation : None ,
171177 } ) ;
172178 }
173179
174- // If node wasn't a comment, see if it was an expression_statement
175- // that itself was preceded by a comment. This skips over
176- // expression-like preprocessor attributes on function decls.
177- if prev. kind ( ) == "expression_statement" {
178- return match prev_prev {
179- Some ( prev_prev) => Self :: new ( prev_prev, src) ,
180- None => Ok ( ItemMetadata :: default ( ) ) ,
180+ // `prev` is a deprecation, `prev_prev` may be a comment, and `prev_prev_prev`
181+ // may be a feature requirement.
182+ if let Ok ( deprecation) = Deprecation :: new ( prev, src) {
183+ let ( comment, feature) = match prev_prev {
184+ Some ( prev_prev) => (
185+ Comment :: new ( prev_prev, src) . ok ( ) ,
186+ prev_prev
187+ . prev_named_sibling ( )
188+ . and_then ( |prev_prev_prev| Feature :: new ( prev_prev_prev, src) . ok ( ) ) ,
189+ ) ,
190+ None => ( None , None ) ,
181191 } ;
182- } ;
192+ return Ok ( ItemMetadata {
193+ comment,
194+ feature,
195+ deprecation : Some ( deprecation) ,
196+ } ) ;
197+ }
183198
184199 // If `prev` wasn't a comment, or an expression_statement preceded by a comment,
185- // then it's either a bare feature requirement or we have no metadata to return.
200+ // then it's either a bare feature requirement without a deprecation or we have no
201+ // metadata to return.
186202 Ok ( Self {
187203 comment : None ,
188204 feature : Feature :: new ( prev, src) . ok ( ) ,
205+ deprecation : None ,
189206 } )
190207 }
191208
@@ -315,6 +332,39 @@ impl Display for Comment {
315332 }
316333}
317334
335+ #[ derive( Debug , Default , Serialize ) ]
336+ struct Deprecation ( String ) ;
337+
338+ impl Deprecation {
339+ fn new ( node : Node , src : & [ u8 ] ) -> Result < Self , Box < dyn Error > > {
340+ require_kind ( "expression_statement" , node, src) ?;
341+
342+ let query_str = r#"
343+ (call_expression
344+ function: (identifier) @func (#eq? @func "DEPRECATED_FUNC")
345+ arguments: (argument_list
346+ (string_literal (string_content) @content)
347+ )
348+ )
349+ "# ;
350+
351+ let mut query_cursor = QueryCursor :: new ( ) ;
352+ let language = tree_sitter_c:: LANGUAGE ;
353+ let query = Query :: new ( & language. into ( ) , query_str) ?;
354+
355+ let captures = query_cursor. captures ( & query, node, src) ;
356+ for ( mat, _) in captures {
357+ for capture in mat. captures {
358+ if query. capture_names ( ) [ capture. index as usize ] == "content" {
359+ return Ok ( Self ( node_text ( capture. node , src) ) ) ;
360+ }
361+ }
362+ }
363+
364+ Err ( node_error ( "DEPRECATED_FUNC call not found or malformed" , node, src) . into ( ) )
365+ }
366+ }
367+
318368fn process_typedef_item (
319369 mut metadata : ItemMetadata ,
320370 item : Node ,
0 commit comments