9#include "absl/status/status.h"
10#include "absl/strings/str_cat.h"
12#if __has_include("z3dk_core/assembler.h")
13#include "z3dk_core/assembler.h"
14#include "z3dk_core/emit.h"
15#include "z3dk_core/lint.h"
59 std::vector<std::pair<std::string, std::string>>
defines;
106 const std::string& rom_path);
158 const std::string& annotations_json) {
159 std::vector<AssemblyDiagnostic> notes;
160 if (annotations_json.empty()) {
175 for (
const auto& item : root[
"annotations"]) {
178 const std::string type = item.value(
"type",
"annotation");
179 const std::string label = item.value(
"label",
"");
180 const std::string expr = item.value(
"expr",
"");
181 const std::string note = item.value(
"note",
"");
182 if (!label.empty()) {
183 diag.
message = absl::StrCat(
"@", type,
" ", label);
184 }
else if (!expr.empty()) {
185 diag.
message = absl::StrCat(
"@", type,
" ", expr);
186 }
else if (!note.empty()) {
187 diag.
message = absl::StrCat(
"@", type,
" ", note);
189 diag.
message = absl::StrCat(
"@", type);
192 const std::string source = item.value(
"source",
"");
193 if (!source.empty()) {
194 const size_t colon = source.find_last_of(
':');
195 if (colon != std::string::npos) {
196 diag.
file = source.substr(0, colon);
198 diag.
line = std::stoi(source.substr(colon + 1));
207 notes.push_back(std::move(diag));
223 {.start = range.start, .end = range.end, .reason = range.reason});
229 std::vector<std::string>* errors,
230 std::vector<std::string>* warnings) {
237 std::string flat = d.file.empty()
239 : absl::StrCat(d.file,
":", d.line,
": ", d.message);
241 warnings->push_back(std::move(flat));
243 errors->push_back(std::move(flat));
263 for (
const auto& label : src.
labels) {
265 sym.
name = label.name;
268 out.
symbols.push_back(std::move(sym));
281Z3dkWrapper& Z3dkWrapper::operator=(Z3dkWrapper&&) noexcept = default;
285 return absl::OkStatus();
290 return "z3dk-core (embedded Asar fork)";
294 const std::string& patch_path, std::vector<uint8_t>& rom_data,
295 const std::vector<std::string>& include_paths) {
298 return ApplyPatch(patch_path, rom_data, options);
302 const std::string& patch_path, std::vector<uint8_t>& rom_data,
304 return Assemble(patch_path, rom_data, options,
true);
308 const std::string& patch_path, std::vector<uint8_t>& rom_data,
321 if (!options.
mapper.empty()) {
322 const auto mapper_it = std::find_if(
324 [](
const auto& define) { return define.first ==
"z3dk_mapper"; });
325 if (mapper_it == opts.
defines.end()) {
337 if (opts.
rom_data.size() < kMinLoromScratchBytes) {
338 opts.
rom_data.resize(kMinLoromScratchBytes, 0);
342 auto z_result = assembler.
Assemble(opts);
343 auto result = ConvertResult(z_result);
345 if (z_result.success) {
349 AppendStructuredDiagnostic(ConvertDiagnostic(diag), &result);
359 const auto annotation_notes = BuildAnnotationNotes(result.annotations_json);
360 for (
const auto& diag : annotation_notes) {
361 result.structured_diagnostics.push_back(diag);
365 result.success =
false;
371 if (!update_apply_cache) {
375 if (result.success) {
379 last_result_ = std::make_unique<z3dk::AssembleResult>(std::move(z_result));
381 result.rom_size =
static_cast<uint32_t
>(rom_data.size());
384 for (
const auto& s : result.symbols) {
395 const std::string& asm_path,
396 const std::vector<std::string>& include_paths) {
404 if (!std::filesystem::exists(asm_path)) {
405 return absl::NotFoundError(
406 absl::StrCat(
"Assembly file not found: ", asm_path));
408 std::vector<uint8_t> scratch;
410 Assemble(asm_path, scratch, options,
false);
411 if (!result_or.ok()) {
412 return result_or.status();
414 if (!result_or->success) {
415 return absl::InternalError(
"Assembly validation failed");
417 return absl::OkStatus();
421 const std::string& name)
const {
428absl::StatusOr<std::vector<AssemblyDiagnostic>>
431 return absl::FailedPreconditionError(
432 "No assemble result cached; call ApplyPatch first.");
436 std::vector<AssemblyDiagnostic> out;
439 out.push_back(ConvertDiagnostic(d));
static Json parse(const std::string &)
bool contains(const std::string &) const
absl::StatusOr< AsarPatchResult > Assemble(const std::string &patch_path, std::vector< uint8_t > &rom_data, const Z3dkAssembleOptions &options, bool update_apply_cache)
std::vector< std::string > last_errors_
absl::StatusOr< std::vector< AssemblyDiagnostic > > RunLintOnLastResult(const Z3dkAssembleOptions &options) const
std::optional< AsarSymbol > FindSymbol(const std::string &name) const
absl::Status Initialize()
std::vector< std::string > last_warnings_
std::string GetVersion() const
absl::Status ValidateAssembly(const std::string &asm_path, const std::vector< std::string > &include_paths={})
absl::StatusOr< AsarPatchResult > ApplyPatch(const std::string &patch_path, std::vector< uint8_t > &rom_data, const std::vector< std::string > &include_paths={})
std::unique_ptr<::z3dk::AssembleResult > last_result_
std::map< std::string, AsarSymbol > symbol_table_
AssembleResult Assemble(const AssembleOptions &options) const
void RebuildLegacyDiagnosticCaches(const AsarPatchResult &result, std::vector< std::string > *errors, std::vector< std::string > *warnings)
std::vector< AssemblyDiagnostic > BuildAnnotationNotes(const std::string &annotations_json)
z3dk::LintOptions BuildLintOptions(const Z3dkAssembleOptions &options)
constexpr std::size_t kMinLoromScratchBytes
AssemblyDiagnosticSeverity ConvertSeverity(z3dk::DiagnosticSeverity s)
AssemblyDiagnostic ConvertDiagnostic(const z3dk::Diagnostic &d)
void AppendStructuredDiagnostic(const AssemblyDiagnostic &diag, AsarPatchResult *out)
AsarPatchResult ConvertResult(const z3dk::AssembleResult &src)
AssemblyDiagnosticSeverity
LintResult RunLint(const AssembleResult &result, const LintOptions &options)
std::string SourceMapToJson(const SourceMap &map)
std::string AnnotationsToJson(const AssembleResult &result)
std::string HooksToJson(const AssembleResult &result, const std::string &rom_path)
std::string SymbolsToMlb(const std::vector< Label > &labels)
std::string DiagnosticsListToJson(const std::vector< Diagnostic > &diagnostics, bool success)
Asar patch result information.
std::vector< AssemblyDiagnostic > structured_diagnostics
std::vector< std::string > errors
std::vector< AsarSymbol > symbols
std::vector< std::string > warnings
Symbol information extracted from Asar assembly.
AssemblyDiagnosticSeverity severity
bool warn_branch_outside_bank
std::vector< Z3dkMemoryRange > prohibited_memory_ranges
bool capture_nocash_symbols
std::vector< std::string > include_paths
std::vector< std::pair< std::string, std::string > > defines
std::string std_defines_path
bool warn_unauthorized_hook
std::string std_includes_path
std::string hooks_rom_path
std::vector< uint8_t > rom_data
bool capture_nocash_symbols
std::string std_includes_path
std::string std_defines_path
std::vector< std::pair< std::string, std::string > > defines
std::vector< std::string > include_paths
std::vector< Label > labels
std::vector< Diagnostic > diagnostics
std::vector< Define > defines
std::vector< WrittenBlock > written_blocks
std::vector< uint8_t > rom_data
DiagnosticSeverity severity
std::vector< MemoryRange > prohibited_memory_ranges
bool warn_branch_outside_bank
bool warn_unauthorized_hook
std::vector< Diagnostic > diagnostics
std::vector< SourceFile > files
std::vector< SourceMapEntry > entries