@@ -94,7 +94,7 @@ impl DocBuilder {
9494 }
9595
9696 /// Parse the sources and build the documentation.
97- pub fn build ( self ) -> eyre:: Result < ( ) > {
97+ pub fn build ( self , compiler : & mut solar :: sema :: Compiler ) -> eyre:: Result < ( ) > {
9898 fs:: create_dir_all ( self . root . join ( & self . config . out ) )
9999 . wrap_err ( "failed to create output directory" ) ?;
100100
@@ -124,135 +124,149 @@ impl DocBuilder {
124124 . collect :: < Vec < _ > > ( ) ;
125125
126126 let out_dir = self . out_dir ( ) ?;
127- let documents = combined_sources
128- . par_iter ( )
129- . enumerate ( )
130- . map ( |( i, ( path, from_library) ) | {
131- let path = * path;
132- let from_library = * from_library;
133-
134- // Read and parse source file
135- let source = fs:: read_to_string ( path) ?;
136- let source =
137- forge_fmt:: format ( & source, self . fmt . clone ( ) ) . into_result ( ) . unwrap_or ( source) ;
138-
139- let ( mut source_unit, comments) = match solang_parser:: parse ( & source, i) {
140- Ok ( res) => res,
141- Err ( err) => {
142- if from_library {
143- // Ignore failures for library files
144- return Ok ( Vec :: new ( ) ) ;
145- } else {
146- return Err ( eyre:: eyre!(
147- "Failed to parse Solidity code for {}\n Debug info: {:?}" ,
148- path. display( ) ,
149- err
150- ) ) ;
127+ let documents = compiler. enter_mut ( |compiler| -> eyre:: Result < Vec < Vec < Document > > > {
128+ let gcx = compiler. gcx ( ) ;
129+ let documents = combined_sources
130+ . par_iter ( )
131+ . enumerate ( )
132+ . map ( |( i, ( path, from_library) ) | {
133+ let path = * path;
134+ let from_library = * from_library;
135+ let mut files = vec ! [ ] ;
136+
137+ // Read and parse source file
138+ if let Some ( ( _, ast) ) = gcx. get_ast_source ( path)
139+ && let Some ( source) =
140+ forge_fmt:: format_ast ( gcx, ast, self . fmt . clone ( ) . into ( ) )
141+ {
142+ let ( mut source_unit, comments) = match solang_parser:: parse ( & source, i) {
143+ Ok ( res) => res,
144+ Err ( err) => {
145+ if from_library {
146+ // Ignore failures for library files
147+ return Ok ( files) ;
148+ } else {
149+ return Err ( eyre:: eyre!(
150+ "Failed to parse Solidity code for {}\n Debug info: {:?}" ,
151+ path. display( ) ,
152+ err
153+ ) ) ;
154+ }
155+ }
156+ } ;
157+
158+ // Visit the parse tree
159+ let mut doc = Parser :: new ( comments, source) ;
160+ source_unit
161+ . visit ( & mut doc)
162+ . map_err ( |err| eyre:: eyre!( "Failed to parse source: {err}" ) ) ?;
163+
164+ // Split the parsed items on top-level constants and rest.
165+ let ( items, consts) : ( Vec < ParseItem > , Vec < ParseItem > ) = doc
166+ . items ( )
167+ . into_iter ( )
168+ . partition ( |item| !matches ! ( item. source, ParseSource :: Variable ( _) ) ) ;
169+
170+ // Attempt to group overloaded top-level functions
171+ let mut remaining = Vec :: with_capacity ( items. len ( ) ) ;
172+ let mut funcs: HashMap < String , Vec < ParseItem > > = HashMap :: default ( ) ;
173+ for item in items {
174+ if matches ! ( item. source, ParseSource :: Function ( _) ) {
175+ funcs. entry ( item. source . ident ( ) ) . or_default ( ) . push ( item) ;
176+ } else {
177+ // Put the item back
178+ remaining. push ( item) ;
179+ }
151180 }
152- }
153- } ;
154-
155- // Visit the parse tree
156- let mut doc = Parser :: new ( comments, source) ;
157- source_unit
158- . visit ( & mut doc)
159- . map_err ( |err| eyre:: eyre!( "Failed to parse source: {err}" ) ) ?;
160-
161- // Split the parsed items on top-level constants and rest.
162- let ( items, consts) : ( Vec < ParseItem > , Vec < ParseItem > ) = doc
163- . items ( )
164- . into_iter ( )
165- . partition ( |item| !matches ! ( item. source, ParseSource :: Variable ( _) ) ) ;
166-
167- // Attempt to group overloaded top-level functions
168- let mut remaining = Vec :: with_capacity ( items. len ( ) ) ;
169- let mut funcs: HashMap < String , Vec < ParseItem > > = HashMap :: default ( ) ;
170- for item in items {
171- if matches ! ( item. source, ParseSource :: Function ( _) ) {
172- funcs. entry ( item. source . ident ( ) ) . or_default ( ) . push ( item) ;
173- } else {
174- // Put the item back
175- remaining. push ( item) ;
176- }
177- }
178- let ( items, overloaded) : (
179- HashMap < String , Vec < ParseItem > > ,
180- HashMap < String , Vec < ParseItem > > ,
181- ) = funcs. into_iter ( ) . partition ( |( _, v) | v. len ( ) == 1 ) ;
182- remaining. extend ( items. into_iter ( ) . flat_map ( |( _, v) | v) ) ;
183-
184- // Each regular item will be written into its own file.
185- let mut files = remaining
186- . into_iter ( )
187- . map ( |item| {
188- let relative_path = path. strip_prefix ( & self . root ) ?. join ( item. filename ( ) ) ;
189-
190- let target_path = out_dir. join ( Self :: SRC ) . join ( relative_path) ;
191- let ident = item. source . ident ( ) ;
192- Ok ( Document :: new (
193- path. clone ( ) ,
194- target_path,
195- from_library,
196- self . config . out . clone ( ) ,
197- )
198- . with_content ( DocumentContent :: Single ( item) , ident) )
199- } )
200- . collect :: < eyre:: Result < Vec < _ > > > ( ) ?;
201-
202- // If top-level constants exist, they will be written to the same file.
203- if !consts. is_empty ( ) {
204- let filestem = path. file_stem ( ) . and_then ( |stem| stem. to_str ( ) ) ;
205-
206- let filename = {
207- let mut name = "constants" . to_owned ( ) ;
208- if let Some ( stem) = filestem {
209- name. push_str ( & format ! ( ".{stem}" ) ) ;
181+ let ( items, overloaded) : (
182+ HashMap < String , Vec < ParseItem > > ,
183+ HashMap < String , Vec < ParseItem > > ,
184+ ) = funcs. into_iter ( ) . partition ( |( _, v) | v. len ( ) == 1 ) ;
185+ remaining. extend ( items. into_iter ( ) . flat_map ( |( _, v) | v) ) ;
186+
187+ // Each regular item will be written into its own file.
188+ files = remaining
189+ . into_iter ( )
190+ . map ( |item| {
191+ let relative_path =
192+ path. strip_prefix ( & self . root ) ?. join ( item. filename ( ) ) ;
193+
194+ let target_path = out_dir. join ( Self :: SRC ) . join ( relative_path) ;
195+ let ident = item. source . ident ( ) ;
196+ Ok ( Document :: new (
197+ path. clone ( ) ,
198+ target_path,
199+ from_library,
200+ self . config . out . clone ( ) ,
201+ )
202+ . with_content ( DocumentContent :: Single ( item) , ident) )
203+ } )
204+ . collect :: < eyre:: Result < Vec < _ > > > ( ) ?;
205+
206+ // If top-level constants exist, they will be written to the same file.
207+ if !consts. is_empty ( ) {
208+ let filestem = path. file_stem ( ) . and_then ( |stem| stem. to_str ( ) ) ;
209+
210+ let filename = {
211+ let mut name = "constants" . to_owned ( ) ;
212+ if let Some ( stem) = filestem {
213+ name. push_str ( & format ! ( ".{stem}" ) ) ;
214+ }
215+ name. push_str ( ".md" ) ;
216+ name
217+ } ;
218+ let relative_path = path. strip_prefix ( & self . root ) ?. join ( filename) ;
219+ let target_path = out_dir. join ( Self :: SRC ) . join ( relative_path) ;
220+
221+ let identity = match filestem {
222+ Some ( stem) if stem. to_lowercase ( ) . contains ( "constants" ) => {
223+ stem. to_owned ( )
224+ }
225+ Some ( stem) => format ! ( "{stem} constants" ) ,
226+ None => "constants" . to_owned ( ) ,
227+ } ;
228+
229+ files. push (
230+ Document :: new (
231+ path. clone ( ) ,
232+ target_path,
233+ from_library,
234+ self . config . out . clone ( ) ,
235+ )
236+ . with_content ( DocumentContent :: Constants ( consts) , identity) ,
237+ )
210238 }
211- name. push_str ( ".md" ) ;
212- name
213- } ;
214- let relative_path = path. strip_prefix ( & self . root ) ?. join ( filename) ;
215- let target_path = out_dir. join ( Self :: SRC ) . join ( relative_path) ;
216239
217- let identity = match filestem {
218- Some ( stem) if stem. to_lowercase ( ) . contains ( "constants" ) => stem. to_owned ( ) ,
219- Some ( stem) => format ! ( "{stem} constants" ) ,
220- None => "constants" . to_owned ( ) ,
240+ // If overloaded functions exist, they will be written to the same file
241+ if !overloaded. is_empty ( ) {
242+ for ( ident, funcs) in overloaded {
243+ let filename =
244+ funcs. first ( ) . expect ( "no overloaded functions" ) . filename ( ) ;
245+ let relative_path = path. strip_prefix ( & self . root ) ?. join ( filename) ;
246+
247+ let target_path = out_dir. join ( Self :: SRC ) . join ( relative_path) ;
248+ files. push (
249+ Document :: new (
250+ path. clone ( ) ,
251+ target_path,
252+ from_library,
253+ self . config . out . clone ( ) ,
254+ )
255+ . with_content (
256+ DocumentContent :: OverloadedFunctions ( funcs) ,
257+ ident,
258+ ) ,
259+ ) ;
260+ }
261+ }
221262 } ;
222263
223- files. push (
224- Document :: new (
225- path. clone ( ) ,
226- target_path,
227- from_library,
228- self . config . out . clone ( ) ,
229- )
230- . with_content ( DocumentContent :: Constants ( consts) , identity) ,
231- )
232- }
264+ Ok ( files)
265+ } )
266+ . collect :: < eyre:: Result < Vec < _ > > > ( ) ?;
233267
234- // If overloaded functions exist, they will be written to the same file
235- if !overloaded. is_empty ( ) {
236- for ( ident, funcs) in overloaded {
237- let filename = funcs. first ( ) . expect ( "no overloaded functions" ) . filename ( ) ;
238- let relative_path = path. strip_prefix ( & self . root ) ?. join ( filename) ;
239-
240- let target_path = out_dir. join ( Self :: SRC ) . join ( relative_path) ;
241- files. push (
242- Document :: new (
243- path. clone ( ) ,
244- target_path,
245- from_library,
246- self . config . out . clone ( ) ,
247- )
248- . with_content ( DocumentContent :: OverloadedFunctions ( funcs) , ident) ,
249- ) ;
250- }
251- }
252-
253- Ok ( files)
254- } )
255- . collect :: < eyre:: Result < Vec < _ > > > ( ) ?;
268+ Ok ( documents)
269+ } ) ?;
256270
257271 // Flatten results and apply preprocessors to files
258272 let documents = self
@@ -262,15 +276,17 @@ impl DocBuilder {
262276 p. preprocess ( docs)
263277 } ) ?;
264278
265- // Sort the results
266- let documents = documents. into_iter ( ) . sorted_by ( |doc1, doc2| {
267- doc1. item_path . display ( ) . to_string ( ) . cmp ( & doc2. item_path . display ( ) . to_string ( ) )
268- } ) ;
279+ // Sort the results and filter libraries.
280+ let documents = documents
281+ . into_iter ( )
282+ . sorted_by ( |doc1, doc2| {
283+ doc1. item_path . display ( ) . to_string ( ) . cmp ( & doc2. item_path . display ( ) . to_string ( ) )
284+ } )
285+ . filter ( |d| !d. from_library || self . include_libraries )
286+ . collect_vec ( ) ;
269287
270288 // Write mdbook related files
271- self . write_mdbook (
272- documents. filter ( |d| !d. from_library || self . include_libraries ) . collect_vec ( ) ,
273- ) ?;
289+ self . write_mdbook ( documents) ?;
274290
275291 // Build the book if requested
276292 if self . should_build {
0 commit comments