@@ -5,7 +5,7 @@ pub mod builtin;
55#[ cfg( test) ]
66mod tests;
77
8- use std:: { hash:: Hash , ops} ;
8+ use std:: { hash:: Hash , ops, slice :: Iter as SliceIter } ;
99
1010use base_db:: CrateId ;
1111use cfg:: { CfgExpr , CfgOptions } ;
@@ -14,12 +14,11 @@ use hir_expand::{
1414 attrs:: { collect_attrs, Attr , AttrId , RawAttrs } ,
1515 HirFileId , InFile ,
1616} ;
17- use itertools:: Itertools ;
1817use la_arena:: { ArenaMap , Idx , RawIdx } ;
1918use mbe:: DelimiterKind ;
2019use syntax:: {
21- ast:: { self , HasAttrs , IsString } ,
22- AstPtr , AstToken , SmolStr , TextRange , TextSize ,
20+ ast:: { self , HasAttrs } ,
21+ AstPtr , SmolStr ,
2322} ;
2423use triomphe:: Arc ;
2524
@@ -33,26 +32,6 @@ use crate::{
3332 LocalFieldId , Lookup , MacroId , VariantId ,
3433} ;
3534
36- /// Holds documentation
37- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
38- pub struct Documentation ( String ) ;
39-
40- impl Documentation {
41- pub fn new ( s : String ) -> Self {
42- Documentation ( s)
43- }
44-
45- pub fn as_str ( & self ) -> & str {
46- & self . 0
47- }
48- }
49-
50- impl From < Documentation > for String {
51- fn from ( Documentation ( string) : Documentation ) -> Self {
52- string
53- }
54- }
55-
5635#[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
5736pub struct Attrs ( RawAttrs ) ;
5837
@@ -221,33 +200,6 @@ impl Attrs {
221200 self . by_key ( "lang" ) . string_value ( ) . and_then ( |it| LangItem :: from_str ( it) )
222201 }
223202
224- pub fn docs ( & self ) -> Option < Documentation > {
225- let docs = self . by_key ( "doc" ) . attrs ( ) . filter_map ( |attr| attr. string_value ( ) ) ;
226- let indent = doc_indent ( self ) ;
227- let mut buf = String :: new ( ) ;
228- for doc in docs {
229- // str::lines doesn't yield anything for the empty string
230- if !doc. is_empty ( ) {
231- buf. extend ( Itertools :: intersperse (
232- doc. lines ( ) . map ( |line| {
233- line. char_indices ( )
234- . nth ( indent)
235- . map_or ( line, |( offset, _) | & line[ offset..] )
236- . trim_end ( )
237- } ) ,
238- "\n " ,
239- ) ) ;
240- }
241- buf. push ( '\n' ) ;
242- }
243- buf. pop ( ) ;
244- if buf. is_empty ( ) {
245- None
246- } else {
247- Some ( Documentation ( buf) )
248- }
249- }
250-
251203 pub fn has_doc_hidden ( & self ) -> bool {
252204 self . by_key ( "doc" ) . tt_values ( ) . any ( |tt| {
253205 tt. delimiter . kind == DelimiterKind :: Parenthesis &&
@@ -299,7 +251,6 @@ impl Attrs {
299251 }
300252}
301253
302- use std:: slice:: Iter as SliceIter ;
303254#[ derive( Debug , Clone , PartialEq , Eq , Hash , Ord , PartialOrd ) ]
304255pub enum DocAtom {
305256 /// eg. `#[doc(hidden)]`
@@ -313,7 +264,6 @@ pub enum DocAtom {
313264
314265// Adapted from `CfgExpr` parsing code
315266#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
316- // #[cfg_attr(test, derive(derive_arbitrary::Arbitrary))]
317267pub enum DocExpr {
318268 Invalid ,
319269 /// eg. `#[doc(hidden)]`, `#[doc(alias = "x")]`
@@ -574,62 +524,6 @@ impl AttrsWithOwner {
574524
575525 AttrSourceMap :: new ( owner. as_ref ( ) . map ( |node| node as & dyn HasAttrs ) )
576526 }
577-
578- pub fn docs_with_rangemap (
579- & self ,
580- db : & dyn DefDatabase ,
581- ) -> Option < ( Documentation , DocsRangeMap ) > {
582- let docs =
583- self . by_key ( "doc" ) . attrs ( ) . filter_map ( |attr| attr. string_value ( ) . map ( |s| ( s, attr. id ) ) ) ;
584- let indent = doc_indent ( self ) ;
585- let mut buf = String :: new ( ) ;
586- let mut mapping = Vec :: new ( ) ;
587- for ( doc, idx) in docs {
588- if !doc. is_empty ( ) {
589- let mut base_offset = 0 ;
590- for raw_line in doc. split ( '\n' ) {
591- let line = raw_line. trim_end ( ) ;
592- let line_len = line. len ( ) ;
593- let ( offset, line) = match line. char_indices ( ) . nth ( indent) {
594- Some ( ( offset, _) ) => ( offset, & line[ offset..] ) ,
595- None => ( 0 , line) ,
596- } ;
597- let buf_offset = buf. len ( ) ;
598- buf. push_str ( line) ;
599- mapping. push ( (
600- TextRange :: new ( buf_offset. try_into ( ) . ok ( ) ?, buf. len ( ) . try_into ( ) . ok ( ) ?) ,
601- idx,
602- TextRange :: at (
603- ( base_offset + offset) . try_into ( ) . ok ( ) ?,
604- line_len. try_into ( ) . ok ( ) ?,
605- ) ,
606- ) ) ;
607- buf. push ( '\n' ) ;
608- base_offset += raw_line. len ( ) + 1 ;
609- }
610- } else {
611- buf. push ( '\n' ) ;
612- }
613- }
614- buf. pop ( ) ;
615- if buf. is_empty ( ) {
616- None
617- } else {
618- Some ( ( Documentation ( buf) , DocsRangeMap { mapping, source_map : self . source_map ( db) } ) )
619- }
620- }
621- }
622-
623- fn doc_indent ( attrs : & Attrs ) -> usize {
624- attrs
625- . by_key ( "doc" )
626- . attrs ( )
627- . filter_map ( |attr| attr. string_value ( ) )
628- . flat_map ( |s| s. lines ( ) )
629- . filter ( |line| !line. chars ( ) . all ( |c| c. is_whitespace ( ) ) )
630- . map ( |line| line. chars ( ) . take_while ( |c| c. is_whitespace ( ) ) . count ( ) )
631- . min ( )
632- . unwrap_or ( 0 )
633527}
634528
635529#[ derive( Debug ) ]
@@ -673,7 +567,7 @@ impl AttrSourceMap {
673567 self . source_of_id ( attr. id )
674568 }
675569
676- fn source_of_id ( & self , id : AttrId ) -> InFile < & Either < ast:: Attr , ast:: Comment > > {
570+ pub fn source_of_id ( & self , id : AttrId ) -> InFile < & Either < ast:: Attr , ast:: Comment > > {
677571 let ast_idx = id. ast_index ( ) ;
678572 let file_id = match self . mod_def_site_file_id {
679573 Some ( ( file_id, def_site_cut) ) if def_site_cut <= ast_idx => file_id,
@@ -687,69 +581,6 @@ impl AttrSourceMap {
687581 }
688582}
689583
690- /// A struct to map text ranges from [`Documentation`] back to TextRanges in the syntax tree.
691- #[ derive( Debug ) ]
692- pub struct DocsRangeMap {
693- source_map : AttrSourceMap ,
694- // (docstring-line-range, attr_index, attr-string-range)
695- // a mapping from the text range of a line of the [`Documentation`] to the attribute index and
696- // the original (untrimmed) syntax doc line
697- mapping : Vec < ( TextRange , AttrId , TextRange ) > ,
698- }
699-
700- impl DocsRangeMap {
701- /// Maps a [`TextRange`] relative to the documentation string back to its AST range
702- pub fn map ( & self , range : TextRange ) -> Option < InFile < TextRange > > {
703- let found = self . mapping . binary_search_by ( |( probe, ..) | probe. ordering ( range) ) . ok ( ) ?;
704- let ( line_docs_range, idx, original_line_src_range) = self . mapping [ found] ;
705- if !line_docs_range. contains_range ( range) {
706- return None ;
707- }
708-
709- let relative_range = range - line_docs_range. start ( ) ;
710-
711- let InFile { file_id, value : source } = self . source_map . source_of_id ( idx) ;
712- match source {
713- Either :: Left ( attr) => {
714- let string = get_doc_string_in_attr ( attr) ?;
715- let text_range = string. open_quote_text_range ( ) ?;
716- let range = TextRange :: at (
717- text_range. end ( ) + original_line_src_range. start ( ) + relative_range. start ( ) ,
718- string. syntax ( ) . text_range ( ) . len ( ) . min ( range. len ( ) ) ,
719- ) ;
720- Some ( InFile { file_id, value : range } )
721- }
722- Either :: Right ( comment) => {
723- let text_range = comment. syntax ( ) . text_range ( ) ;
724- let range = TextRange :: at (
725- text_range. start ( )
726- + TextSize :: try_from ( comment. prefix ( ) . len ( ) ) . ok ( ) ?
727- + original_line_src_range. start ( )
728- + relative_range. start ( ) ,
729- text_range. len ( ) . min ( range. len ( ) ) ,
730- ) ;
731- Some ( InFile { file_id, value : range } )
732- }
733- }
734- }
735- }
736-
737- fn get_doc_string_in_attr ( it : & ast:: Attr ) -> Option < ast:: String > {
738- match it. expr ( ) {
739- // #[doc = lit]
740- Some ( ast:: Expr :: Literal ( lit) ) => match lit. kind ( ) {
741- ast:: LiteralKind :: String ( it) => Some ( it) ,
742- _ => None ,
743- } ,
744- // #[cfg_attr(..., doc = "", ...)]
745- None => {
746- // FIXME: See highlight injection for what to do here
747- None
748- }
749- _ => None ,
750- }
751- }
752-
753584#[ derive( Debug , Clone , Copy ) ]
754585pub struct AttrQuery < ' attr > {
755586 attrs : & ' attr Attrs ,
0 commit comments