@@ -24,8 +24,6 @@ pub use resolver::Graph;
2424pub mod compilers;
2525pub use compilers:: * ;
2626
27- pub mod preprocessor;
28-
2927mod compile;
3028pub use compile:: {
3129 output:: { AggregatedCompilerOutput , ProjectCompileOutput } ,
@@ -41,8 +39,9 @@ pub use filter::{FileFilter, SparseOutputFilter, TestFileFilter};
4139pub mod report;
4240
4341/// Updates to be applied to the sources.
44- /// source_path -> (start, end, new_value)
45- pub ( crate ) type Updates = HashMap < PathBuf , BTreeSet < ( usize , usize , String ) > > ;
42+ ///
43+ /// `source_path -> (start, end, new_value)`
44+ pub type Updates = HashMap < PathBuf , BTreeSet < ( usize , usize , String ) > > ;
4645
4746/// Utilities for creating, mocking and testing of (temporary) projects
4847#[ cfg( feature = "project-util" ) ]
@@ -65,6 +64,8 @@ use foundry_compilers_core::error::{Result, SolcError, SolcIoError};
6564use output:: sources:: { VersionedSourceFile , VersionedSourceFiles } ;
6665use project:: ProjectCompiler ;
6766use semver:: Version ;
67+ use solar_parse:: Parser ;
68+ use solar_sema:: interface:: { diagnostics:: EmittedDiagnostics , source_map:: FileName , Session } ;
6869use solc:: SolcSettings ;
6970use std:: {
7071 collections:: { BTreeMap , BTreeSet , HashMap , HashSet } ,
@@ -891,7 +892,7 @@ fn rebase_path(base: &Path, path: &Path) -> PathBuf {
891892}
892893
893894/// Utility function to apply a set of updates to provided sources.
894- fn apply_updates ( sources : & mut Sources , updates : Updates ) {
895+ pub fn apply_updates ( sources : & mut Sources , updates : Updates ) {
895896 for ( path, source) in sources {
896897 if let Some ( updates) = updates. get ( path) {
897898 source. content = Arc :: new ( replace_source_content (
@@ -904,20 +905,42 @@ fn apply_updates(sources: &mut Sources, updates: Updates) {
904905
905906/// Utility function to change source content ranges with provided updates.
906907/// Assumes that the updates are sorted.
907- fn replace_source_content < ' a > (
908- source : & str ,
909- updates : impl IntoIterator < Item = ( Range < usize > , & ' a str ) > ,
908+ pub fn replace_source_content < ' a > (
909+ source : impl Into < String > ,
910+ updates : impl IntoIterator < Item = ( Range < usize > , impl AsRef < str > ) > ,
910911) -> String {
911912 let mut offset = 0 ;
912- let mut content = source. as_bytes ( ) . to_vec ( ) ;
913+ let mut content = source. into ( ) ;
913914 for ( range, new_value) in updates {
914915 let update_range = utils:: range_by_offset ( & range, offset) ;
915-
916- content. splice ( update_range. start ..update_range . end , new_value. bytes ( ) ) ;
916+ let new_value = new_value . as_ref ( ) ;
917+ content. replace_range ( update_range. clone ( ) , new_value) ;
917918 offset += new_value. len ( ) as isize - ( update_range. end - update_range. start ) as isize ;
918919 }
920+ content
921+ }
919922
920- String :: from_utf8 ( content) . unwrap ( )
923+ pub ( crate ) fn parse_one_source < R > (
924+ content : & str ,
925+ path : & Path ,
926+ f : impl FnOnce ( solar_sema:: ast:: SourceUnit < ' _ > ) -> R ,
927+ ) -> Result < R , EmittedDiagnostics > {
928+ let sess = Session :: builder ( ) . with_buffer_emitter ( Default :: default ( ) ) . build ( ) ;
929+ let res = sess. enter ( || -> solar_parse:: interface:: Result < _ > {
930+ let arena = solar_parse:: ast:: Arena :: new ( ) ;
931+ let filename = FileName :: Real ( path. to_path_buf ( ) ) ;
932+ let mut parser = Parser :: from_source_code ( & sess, & arena, filename, content. to_string ( ) ) ?;
933+ let ast = parser. parse_file ( ) . map_err ( |e| e. emit ( ) ) ?;
934+ Ok ( f ( ast) )
935+ } ) ;
936+
937+ // Return if any diagnostics emitted during content parsing.
938+ if let Err ( err) = sess. emitted_errors ( ) . unwrap ( ) {
939+ trace ! ( "failed parsing {path:?}:\n {err}" ) ;
940+ return Err ( err) ;
941+ }
942+
943+ Ok ( res. unwrap ( ) )
921944}
922945
923946#[ cfg( test) ]
0 commit comments