@@ -13,7 +13,9 @@ use crate::ast::{
1313 Expr , ExprKind , LitKind , MetaItem , MetaItemInner , MetaItemKind , MetaItemLit , NormalAttr , Path ,
1414 PathSegment , Safety ,
1515} ;
16- use crate :: token:: { self , CommentKind , Delimiter , InvisibleOrigin , MetaVarKind , Token } ;
16+ use crate :: token:: {
17+ self , CommentKind , Delimiter , DocFragmentKind , InvisibleOrigin , MetaVarKind , Token ,
18+ } ;
1719use crate :: tokenstream:: {
1820 DelimSpan , LazyAttrTokenStream , Spacing , TokenStream , TokenStreamIter , TokenTree ,
1921} ;
@@ -179,15 +181,21 @@ impl AttributeExt for Attribute {
179181 }
180182
181183 /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
182- /// * `///doc` returns `Some(("doc", CommentKind::Line))`.
183- /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`.
184- /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line ))`.
184+ /// * `///doc` returns `Some(("doc", DocFragmentKind::Sugared( CommentKind::Line) ))`.
185+ /// * `/** doc */` returns `Some(("doc", DocFragmentKind::Sugared( CommentKind::Block) ))`.
186+ /// * `#[doc = "doc"]` returns `Some(("doc", DocFragmentKind::Raw ))`.
185187 /// * `#[doc(...)]` returns `None`.
186- fn doc_str_and_comment_kind ( & self ) -> Option < ( Symbol , CommentKind ) > {
188+ fn doc_str_and_fragment_kind ( & self ) -> Option < ( Symbol , DocFragmentKind ) > {
187189 match & self . kind {
188- AttrKind :: DocComment ( kind, data) => Some ( ( * data, * kind) ) ,
190+ AttrKind :: DocComment ( kind, data) => Some ( ( * data, DocFragmentKind :: Sugared ( * kind) ) ) ,
189191 AttrKind :: Normal ( normal) if normal. item . path == sym:: doc => {
190- normal. item . value_str ( ) . map ( |s| ( s, CommentKind :: Line ) )
192+ if let Some ( value) = normal. item . value_str ( )
193+ && let Some ( value_span) = normal. item . value_span ( )
194+ {
195+ Some ( ( value, DocFragmentKind :: Raw ( value_span) ) )
196+ } else {
197+ None
198+ }
191199 }
192200 _ => None ,
193201 }
@@ -220,6 +228,24 @@ impl AttributeExt for Attribute {
220228 fn is_automatically_derived_attr ( & self ) -> bool {
221229 self . has_name ( sym:: automatically_derived)
222230 }
231+
232+ fn is_doc_hidden ( & self ) -> bool {
233+ self . has_name ( sym:: doc)
234+ && self . meta_item_list ( ) . is_some_and ( |l| list_contains_name ( & l, sym:: hidden) )
235+ }
236+
237+ fn is_doc_keyword_or_attribute ( & self ) -> bool {
238+ if self . has_name ( sym:: doc)
239+ && let Some ( items) = self . meta_item_list ( )
240+ {
241+ for item in items {
242+ if item. has_name ( sym:: keyword) || item. has_name ( sym:: attribute) {
243+ return true ;
244+ }
245+ }
246+ }
247+ false
248+ }
223249}
224250
225251impl Attribute {
@@ -300,6 +326,25 @@ impl AttrItem {
300326 }
301327 }
302328
329+ /// Returns the span in:
330+ ///
331+ /// ```text
332+ /// #[attribute = "value"]
333+ /// ^^^^^^^
334+ /// ```
335+ ///
336+ /// It returns `None` in any other cases like:
337+ ///
338+ /// ```text
339+ /// #[attr("value")]
340+ /// ```
341+ fn value_span ( & self ) -> Option < Span > {
342+ match & self . args {
343+ AttrArgs :: Eq { expr, .. } => Some ( expr. span ) ,
344+ AttrArgs :: Delimited ( _) | AttrArgs :: Empty => None ,
345+ }
346+ }
347+
303348 pub fn meta ( & self , span : Span ) -> Option < MetaItem > {
304349 Some ( MetaItem {
305350 unsafety : Safety :: Default ,
@@ -820,7 +865,7 @@ pub trait AttributeExt: Debug {
820865 /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`.
821866 /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`.
822867 /// * `#[doc(...)]` returns `None`.
823- fn doc_str_and_comment_kind ( & self ) -> Option < ( Symbol , CommentKind ) > ;
868+ fn doc_str_and_fragment_kind ( & self ) -> Option < ( Symbol , DocFragmentKind ) > ;
824869
825870 /// Returns outer or inner if this is a doc attribute or a sugared doc
826871 /// comment, otherwise None.
@@ -830,6 +875,12 @@ pub trait AttributeExt: Debug {
830875 /// commented module (for inner doc) vs within its parent module (for outer
831876 /// doc).
832877 fn doc_resolution_scope ( & self ) -> Option < AttrStyle > ;
878+
879+ /// Returns `true` if this attribute contains `doc(hidden)`.
880+ fn is_doc_hidden ( & self ) -> bool ;
881+
882+ /// Returns `true` is this attribute contains `doc(keyword)` or `doc(attribute)`.
883+ fn is_doc_keyword_or_attribute ( & self ) -> bool ;
833884}
834885
835886// FIXME(fn_delegation): use function delegation instead of manually forwarding
@@ -902,7 +953,7 @@ impl Attribute {
902953 AttributeExt :: is_proc_macro_attr ( self )
903954 }
904955
905- pub fn doc_str_and_comment_kind ( & self ) -> Option < ( Symbol , CommentKind ) > {
906- AttributeExt :: doc_str_and_comment_kind ( self )
956+ pub fn doc_str_and_fragment_kind ( & self ) -> Option < ( Symbol , DocFragmentKind ) > {
957+ AttributeExt :: doc_str_and_fragment_kind ( self )
907958 }
908959}
0 commit comments