@@ -145,6 +145,8 @@ struct ItemMetadata {
145145 comment : Option < Comment > ,
146146 /// A feature requirement that must be enabled for the item
147147 feature : Option < Feature > ,
148+ /// A deprecation message for the item
149+ deprecation : Option < Deprecation > ,
148150}
149151
150152impl ItemMetadata {
@@ -158,15 +160,17 @@ impl ItemMetadata {
158160 /// * `prev` is not a comment, and not a feature requirement.
159161 /// * `prev` is a Comment, and has no feature requirement before it.
160162 /// * `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.
161165 /// * `prev` is a bare feature requirement
162166 ///
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 .
165169 fn new ( prev : Node , src : & [ u8 ] ) -> Result < Self , Box < dyn Error > > {
166170 let prev_prev = prev. prev_named_sibling ( ) ;
167171
168172 // 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.
170174 if let Ok ( comment) = Comment :: new ( prev, src) {
171175 let feature = match prev_prev {
172176 Some ( prev_prev) => Feature :: new ( prev_prev, src) . ok ( ) ,
@@ -175,24 +179,36 @@ impl ItemMetadata {
175179 return Ok ( ItemMetadata {
176180 comment : Some ( comment) ,
177181 feature,
182+ deprecation : None ,
178183 } ) ;
179184 }
180185
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 ,
188197 } ;
198+ return Ok ( ItemMetadata {
199+ comment,
200+ feature,
201+ deprecation : Some ( deprecation) ,
202+ } ) ;
189203 }
190204
191205 // 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.
193208 Ok ( ItemMetadata {
194209 comment : None ,
195210 feature : Feature :: new ( prev, src) . ok ( ) ,
211+ deprecation : None ,
196212 } )
197213 }
198214
@@ -322,6 +338,39 @@ impl Display for Comment {
322338 }
323339}
324340
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+
325374fn process_typedef_item (
326375 mut metadata : ItemMetadata ,
327376 item : Node ,
0 commit comments