neo_solidity/cli/cli_parts/cli_run/
output.rs

1fn emit_contract_warnings(
2    artifacts: &[CompilationArtifacts],
3    json_warnings: bool,
4    json_errors: bool,
5    suppress_prefixes: &[String],
6    promote_prefixes: &[String],
7) {
8    for artifact in artifacts {
9        for warning in &artifact.warnings {
10            let code = warning.code.as_deref().unwrap_or_else(|| {
11                // Fallback: infer a code from the message text
12                standard_json::infer_validation_code(&warning.message, warning.severity)
13            });
14
15            // --Wno-<prefix>: suppress warnings whose code starts with prefix
16            if suppress_prefixes.iter().any(|p| code.starts_with(p.as_str())) {
17                continue;
18            }
19
20            // --Werror=<prefix>: promote matching warnings to errors
21            if promote_prefixes.iter().any(|p| code.starts_with(p.as_str())) {
22                emit_error(&warning.message, code, json_errors);
23                continue;
24            }
25
26            emit_warning_with_suggestion(
27                &warning.message,
28                Some(&artifact.metadata.name),
29                json_warnings,
30                Some(code),
31                warning.suggestion.as_deref(),
32            );
33        }
34    }
35}
36
37struct OutputConfig<'a> {
38    format: &'a str,
39    output_prefix: &'a str,
40    input_file: &'a str,
41    nef_source_override: Option<&'a str>,
42    deployer: Option<[u8; 20]>,
43    json_errors: bool,
44    json_warnings: bool,
45}
46
47fn write_contract_outputs(
48    artifacts: &[CompilationArtifacts],
49    config: &OutputConfig<'_>,
50) {
51    for (index, artifact) in artifacts.iter().enumerate() {
52        let prefix = contract_output_prefix(
53            config.output_prefix,
54            &artifact.metadata.name,
55            index,
56            artifacts.len(),
57        );
58
59        match config.format {
60            "nef" => {
61                let nef_path = if prefix.ends_with(".nef") {
62                    prefix.clone()
63                } else {
64                    format!("{prefix}.nef")
65                };
66                let checksum = match write_nef_file(
67                    &nef_path,
68                    &artifact.bytecode,
69                    &artifact.tokens,
70                    config.nef_source_override.unwrap_or(config.input_file),
71                    config.json_warnings,
72                ) {
73                    Ok(checksum) => checksum,
74                    Err(err) => {
75                        emit_error(&err, "OUTPUT_WRITE_ERROR", config.json_errors);
76                        std::process::exit(1);
77                    }
78                };
79                println!(
80                    "✅ [{}] NEF file generated: {nef_path}",
81                    artifact.metadata.name
82                );
83                if let Some(sender) = config.deployer {
84                    let predicted = neo_solidity::neo::compute_contract_hash(
85                        sender,
86                        checksum,
87                        artifact.metadata.name.as_str(),
88                    );
89                    println!(
90                        "   • Predicted contract hash (sender {}, checksum 0x{checksum:08x}): {}",
91                        neo_solidity::neo::format_uint160_hex_be(&sender),
92                        neo_solidity::neo::format_uint160_hex_be(&predicted)
93                    );
94                }
95            }
96            "manifest" => {
97                let manifest_path = if prefix.ends_with(".manifest.json") {
98                    prefix.clone()
99                } else {
100                    format!("{prefix}.manifest.json")
101                };
102                if let Err(err) = write_manifest_file(&manifest_path, &artifact.manifest) {
103                    emit_error(&err, "OUTPUT_WRITE_ERROR", config.json_errors);
104                    std::process::exit(1);
105                }
106                println!(
107                    "✅ [{}] Manifest file generated: {manifest_path}",
108                    artifact.metadata.name
109                );
110            }
111            "complete" => {
112                let nef_path = format!("{prefix}.nef");
113                let manifest_path = format!("{prefix}.manifest.json");
114                let checksum = match write_nef_file(
115                    &nef_path,
116                    &artifact.bytecode,
117                    &artifact.tokens,
118                    config.nef_source_override.unwrap_or(config.input_file),
119                    config.json_warnings,
120                ) {
121                    Ok(checksum) => checksum,
122                    Err(err) => {
123                        emit_error(&err, "OUTPUT_WRITE_ERROR", config.json_errors);
124                        std::process::exit(1);
125                    }
126                };
127                if let Err(err) = write_manifest_file(&manifest_path, &artifact.manifest) {
128                    emit_error(&err, "OUTPUT_WRITE_ERROR", config.json_errors);
129                    std::process::exit(1);
130                }
131                println!(
132                    "✅ [{}] Contract files generated:\n   📄 {nef_path}\n   📄 {manifest_path}",
133                    artifact.metadata.name
134                );
135                if let Some(sender) = config.deployer {
136                    let predicted = neo_solidity::neo::compute_contract_hash(
137                        sender,
138                        checksum,
139                        artifact.metadata.name.as_str(),
140                    );
141                    println!(
142                        "   • Predicted contract hash (sender {}, checksum 0x{checksum:08x}): {}",
143                        neo_solidity::neo::format_uint160_hex_be(&sender),
144                        neo_solidity::neo::format_uint160_hex_be(&predicted)
145                    );
146                }
147            }
148            "json" => {
149                let json_path = if prefix.ends_with(".json") {
150                    prefix.clone()
151                } else {
152                    format!("{prefix}.json")
153                };
154                if let Err(err) = write_json_file(
155                    &json_path,
156                    &artifact.bytecode,
157                    &artifact.tokens,
158                    &artifact.manifest,
159                    &artifact.metadata,
160                    config.nef_source_override.unwrap_or(config.input_file),
161                    config.json_warnings,
162                ) {
163                    emit_error(&err, "OUTPUT_WRITE_ERROR", config.json_errors);
164                    std::process::exit(1);
165                }
166                println!(
167                    "✅ [{}] JSON file generated: {json_path}",
168                    artifact.metadata.name
169                );
170            }
171            "assembly" => {
172                let asm_path = if prefix.ends_with(".asm") {
173                    prefix.clone()
174                } else {
175                    format!("{prefix}.asm")
176                };
177                if let Err(err) = write_assembly_file(&asm_path, &artifact.bytecode) {
178                    emit_error(&err, "OUTPUT_WRITE_ERROR", config.json_errors);
179                    std::process::exit(1);
180                }
181                println!(
182                    "✅ [{}] Assembly file generated: {asm_path}",
183                    artifact.metadata.name
184                );
185            }
186            other => {
187                println!("Unsupported format: {other}");
188            }
189        }
190    }
191}