foundry_cli/opts/build/
utils.rs
1use crate::{opts::BuildOpts, utils::LoadConfig};
2
3use eyre::Result;
4use foundry_compilers::{
5 CompilerInput, Graph, Project,
6 artifacts::{Source, Sources},
7 multi::{MultiCompilerLanguage, MultiCompilerParsedSource},
8 solc::{SolcLanguage, SolcVersionedInput},
9};
10use solar_sema::{ParsingContext, interface::Session};
11use std::path::PathBuf;
12
13pub fn solar_pcx_from_build_opts<'sess>(
21 sess: &'sess Session,
22 build: &BuildOpts,
23 project: Option<&Project>,
24 target_paths: Option<&[PathBuf]>,
25) -> Result<ParsingContext<'sess>> {
26 let config = build.load_config()?;
28 let project = match project {
29 Some(project) => project,
30 None => &config.ephemeral_project()?,
31 };
32
33 let sources = match target_paths {
34 Some(targets) => {
36 let mut sources = Sources::new();
37 for t in targets {
38 let path = dunce::canonicalize(t)?;
39 let source = Source::read(&path)?;
40 sources.insert(path, source);
41 }
42 sources
43 }
44 None => project.paths.read_input_files()?,
46 };
47
48 let graph = Graph::<MultiCompilerParsedSource>::resolve_sources(&project.paths, sources)?;
50 let (version, sources, _) = graph
51 .into_sources_by_version(project)?
53 .sources
54 .into_iter()
55 .find(|(lang, _)| *lang == MultiCompilerLanguage::Solc(SolcLanguage::Solidity))
57 .ok_or_else(|| eyre::eyre!("no Solidity sources"))?
58 .1
59 .into_iter()
60 .max_by(|(v1, _, _), (v2, _, _)| v1.cmp(v2))
62 .unwrap();
63
64 let solc = SolcVersionedInput::build(
65 sources,
66 config.solc_settings()?,
67 SolcLanguage::Solidity,
68 version,
69 );
70
71 Ok(solar_pcx_from_solc_project(sess, project, &solc, true))
72}
73
74pub fn solar_pcx_from_solc_project<'sess>(
80 sess: &'sess Session,
81 project: &Project,
82 solc: &SolcVersionedInput,
83 add_source_files: bool,
84) -> ParsingContext<'sess> {
85 let mut pcx = ParsingContext::new(sess);
87
88 pcx.file_resolver
89 .set_current_dir(solc.cli_settings.base_path.as_ref().unwrap_or(&project.paths.root));
90 for remapping in &project.paths.remappings {
91 pcx.file_resolver.add_import_remapping(solar_sema::interface::config::ImportRemapping {
92 context: remapping.context.clone().unwrap_or_default(),
93 prefix: remapping.name.clone(),
94 path: remapping.path.clone(),
95 });
96 }
97 pcx.file_resolver.add_include_paths(solc.cli_settings.include_paths.iter().cloned());
98
99 if add_source_files {
100 for (path, source) in &solc.input.sources {
101 if let Ok(src_file) =
102 sess.source_map().new_source_file(path.clone(), source.content.as_str())
103 {
104 pcx.add_file(src_file);
105 }
106 }
107 }
108
109 pcx
110}