@@ -23,7 +23,10 @@ use solar_parse::{
23
23
Parser ,
24
24
} ;
25
25
use solar_sema:: { hir:: Arena , ParsingContext } ;
26
- use std:: path:: { Path , PathBuf } ;
26
+ use std:: {
27
+ collections:: HashSet ,
28
+ path:: { Path , PathBuf } ,
29
+ } ;
27
30
28
31
mod data;
29
32
mod deps;
@@ -60,62 +63,66 @@ impl Preprocessor<SolcCompiler> for TestOptimizerPreprocessor {
60
63
_solc : & SolcCompiler ,
61
64
mut input : SolcVersionedInput ,
62
65
paths : & ProjectPathsConfig < SolcLanguage > ,
63
- ) -> Result < SolcVersionedInput > {
66
+ ) -> Result < ( SolcVersionedInput , Option < HashSet < PathBuf > > ) > {
64
67
let sources = & mut input. input . sources ;
65
68
// Skip if we are not preprocessing any tests or scripts. Avoids unnecessary AST parsing.
66
69
if sources. iter ( ) . all ( |( path, _) | !is_test_or_script ( path, paths) ) {
67
70
trace ! ( "no tests or sources to preprocess" ) ;
68
- return Ok ( input) ;
71
+ return Ok ( ( input, None ) ) ;
69
72
}
70
73
71
74
let sess = Session :: builder ( ) . with_buffer_emitter ( Default :: default ( ) ) . build ( ) ;
72
- let _ = sess. enter_parallel ( || -> solar_parse:: interface:: Result < ( ) > {
73
- let hir_arena = Arena :: new ( ) ;
74
- let mut parsing_context = ParsingContext :: new ( & sess) ;
75
- // Set remappings into HIR parsing context.
76
- for remapping in & paths. remappings {
77
- parsing_context
78
- . file_resolver
79
- . add_import_map ( PathBuf :: from ( & remapping. name ) , PathBuf :: from ( & remapping. path ) ) ;
80
- }
81
- // Load and parse test and script contracts only (dependencies are automatically
82
- // resolved).
83
- let preprocessed_paths = sources
84
- . into_iter ( )
85
- . filter ( |( path, source) | {
86
- is_test_or_script ( path, paths) && !source. content . is_empty ( )
87
- } )
88
- . map ( |( path, _) | path. clone ( ) )
89
- . collect_vec ( ) ;
90
- parsing_context. load_files ( & preprocessed_paths) ?;
75
+ let mocks = sess
76
+ . enter_parallel ( || -> solar_parse:: interface:: Result < Option < HashSet < PathBuf > > > {
77
+ let hir_arena = Arena :: new ( ) ;
78
+ let mut parsing_context = ParsingContext :: new ( & sess) ;
79
+ // Set remappings into HIR parsing context.
80
+ for remapping in & paths. remappings {
81
+ parsing_context. file_resolver . add_import_map (
82
+ PathBuf :: from ( & remapping. name ) ,
83
+ PathBuf :: from ( & remapping. path ) ,
84
+ ) ;
85
+ }
86
+ // Load and parse test and script contracts only (dependencies are automatically
87
+ // resolved).
88
+ let preprocessed_paths = sources
89
+ . into_iter ( )
90
+ . filter ( |( path, source) | {
91
+ is_test_or_script ( path, paths) && !source. content . is_empty ( )
92
+ } )
93
+ . map ( |( path, _) | path. clone ( ) )
94
+ . collect_vec ( ) ;
95
+ parsing_context. load_files ( & preprocessed_paths) ?;
91
96
92
- let hir = & parsing_context. parse_and_lower_to_hir ( & hir_arena) ?;
93
- // Collect tests and scripts dependencies.
94
- let deps = PreprocessorDependencies :: new (
95
- & sess,
96
- hir,
97
- & preprocessed_paths,
98
- & paths. paths_relative ( ) . sources ,
99
- ) ;
100
- // Collect data of source contracts referenced in tests and scripts.
101
- let data = collect_preprocessor_data ( & sess, hir, & deps. referenced_contracts ) ;
97
+ let hir = & parsing_context. parse_and_lower_to_hir ( & hir_arena) ?;
98
+ // Collect tests and scripts dependencies and identify mock contracts.
99
+ let deps = PreprocessorDependencies :: new (
100
+ & sess,
101
+ hir,
102
+ & preprocessed_paths,
103
+ & paths. paths_relative ( ) . sources ,
104
+ & paths. root ,
105
+ ) ;
106
+ // Collect data of source contracts referenced in tests and scripts.
107
+ let data = collect_preprocessor_data ( & sess, hir, & deps. referenced_contracts ) ;
102
108
103
- // Extend existing sources with preprocessor deploy helper sources.
104
- sources. extend ( create_deploy_helpers ( & data) ) ;
109
+ // Extend existing sources with preprocessor deploy helper sources.
110
+ sources. extend ( create_deploy_helpers ( & data) ) ;
105
111
106
- // Generate and apply preprocessor source updates.
107
- apply_updates ( sources, remove_bytecode_dependencies ( hir, & deps, & data) ) ;
112
+ // Generate and apply preprocessor source updates.
113
+ apply_updates ( sources, remove_bytecode_dependencies ( hir, & deps, & data) ) ;
108
114
109
- Ok ( ( ) )
110
- } ) ;
115
+ Ok ( Some ( deps. mocks ) )
116
+ } )
117
+ . unwrap_or_default ( ) ;
111
118
112
119
// Return if any diagnostics emitted during content parsing.
113
120
if let Err ( err) = sess. emitted_errors ( ) . unwrap ( ) {
114
121
trace ! ( "failed preprocessing {err}" ) ;
115
122
return Err ( SolcError :: Message ( err. to_string ( ) ) ) ;
116
123
}
117
124
118
- Ok ( input)
125
+ Ok ( ( input, mocks ) )
119
126
}
120
127
}
121
128
@@ -125,18 +132,18 @@ impl Preprocessor<MultiCompiler> for TestOptimizerPreprocessor {
125
132
compiler : & MultiCompiler ,
126
133
input : <MultiCompiler as Compiler >:: Input ,
127
134
paths : & ProjectPathsConfig < MultiCompilerLanguage > ,
128
- ) -> Result < <MultiCompiler as Compiler >:: Input > {
135
+ ) -> Result < ( <MultiCompiler as Compiler >:: Input , Option < HashSet < PathBuf > > ) > {
129
136
match input {
130
137
MultiCompilerInput :: Solc ( input) => {
131
138
if let Some ( solc) = & compiler. solc {
132
139
let paths = paths. clone ( ) . with_language :: < SolcLanguage > ( ) ;
133
- let input = self . preprocess ( solc, input, & paths) ?;
134
- Ok ( MultiCompilerInput :: Solc ( input) )
140
+ let ( input, mocks ) = self . preprocess ( solc, input, & paths) ?;
141
+ Ok ( ( MultiCompilerInput :: Solc ( input) , mocks ) )
135
142
} else {
136
- Ok ( MultiCompilerInput :: Solc ( input) )
143
+ Ok ( ( MultiCompilerInput :: Solc ( input) , None ) )
137
144
}
138
145
}
139
- MultiCompilerInput :: Vyper ( input) => Ok ( MultiCompilerInput :: Vyper ( input) ) ,
146
+ MultiCompilerInput :: Vyper ( input) => Ok ( ( MultiCompilerInput :: Vyper ( input) , None ) ) ,
140
147
}
141
148
}
142
149
}
0 commit comments