diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2026-02-10 22:16:15 +0000 |
|---|---|---|
| committer | gingerBill <gingerBill@users.noreply.github.com> | 2026-02-10 22:16:15 +0000 |
| commit | ae91b9b3693f1ee5b39f14e38a67af5f502bc829 (patch) | |
| tree | 8a232d4e225039054c0799d3517739afac6b71ee /src/main.cpp | |
| parent | 3eaa11044c7d3141693bf74071fba98f0dffb23b (diff) | |
Add `-show-import-graph`
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp index 0b642e9a8..009281d4e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -302,6 +302,7 @@ enum BuildFlagKind { BuildFlag_ShowUnused, BuildFlag_ShowUnusedWithLocation, BuildFlag_ShowMoreTimings, + BuildFlag_ShowImportGraph, BuildFlag_ExportTimings, BuildFlag_ExportTimingsFile, BuildFlag_ExportDependencies, @@ -530,6 +531,7 @@ gb_internal bool parse_build_flags(Array<String> args) { add_flag(&build_flags, BuildFlag_OptimizationMode, str_lit("o"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_ShowImportGraph, str_lit("show-import-graph"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ExportTimings, str_lit("export-timings"), BuildFlagParam_String, Command__does_check); add_flag(&build_flags, BuildFlag_ExportTimingsFile, str_lit("export-timings-file"), BuildFlagParam_String, Command__does_check); add_flag(&build_flags, BuildFlag_ExportDependencies, str_lit("export-dependencies"), BuildFlagParam_String, Command__does_build); @@ -870,6 +872,10 @@ gb_internal bool parse_build_flags(Array<String> args) { build_context.show_timings = true; build_context.show_more_timings = true; break; + case BuildFlag_ShowImportGraph: + GB_ASSERT(value.kind == ExactValue_Invalid); + build_context.show_import_graph = true; + break; case BuildFlag_ExportTimings: { GB_ASSERT(value.kind == ExactValue_String); /* @@ -2071,6 +2077,73 @@ gb_internal void show_defineables(Checker *c) { } } +gb_internal void show_import_graph(Checker *c) { + Parser *p = c->parser; + + gb_printf("\nDOT Import graph:\n\n"); + gb_printf("digraph odin_import_graph {\n\tnode [shape=box];\n"); + + int cluster_counter = 0; + for (LibraryCollections coll : library_collections) { + gb_printf("\tsubgraph cluster_%i {\n", cluster_counter); + gb_printf("\t\tlabel = \"%.*s\";\n", LIT(coll.name)); + gb_printf("\t\tnode [style=filled, fillcolor=white];\n"); + if (coll.name =="core") { + gb_printf("\t\tbgcolor = lightsalmon;\n"); + } else if (coll.name =="vendor") { + gb_printf("\t\tbgcolor = lightblue;\n"); + } else if (coll.name =="base") { + gb_printf("\t\tbgcolor = lightcoral;\n"); + gb_printf("\t\tintrinsics;\n"); + gb_printf("\t\tbuiltin;\n"); + } + for (AstPackage *pkg : p->packages) { + if (string_starts_with(pkg->fullpath, coll.path)) { + gb_printf("\t\t\"%.*s\";\n", LIT(pkg->fullpath)); + } + } + gb_printf("\t}\n"); + cluster_counter += 1; + } + + for (AstPackage *pkg : p->packages) { + for (int i = 0; i < pkg->files.count; i++) { + AstFile *file = pkg->files[i]; + for(Ast *imp : file->imports) { + GB_ASSERT(imp->kind == Ast_ImportDecl); + + bool exists = false; + for (int j = i + 1; j < pkg->files.count; j++) { + AstFile *other_file = pkg->files[j]; + for(Ast *other_imp : other_file->imports) { + GB_ASSERT(other_imp->kind == Ast_ImportDecl); + if (0 == string_compare(imp->ImportDecl.fullpath, other_imp->ImportDecl.fullpath)) { + exists = true; + break; + } + } + if (exists) { + break; + } + } + + if (exists) { + continue; + } + + String path = imp->ImportDecl.fullpath; + if (imp->ImportDecl.package != nullptr) { + path = imp->ImportDecl.package->fullpath; + } + + gb_printf("\t\"%.*s\" -> \"%.*s\";\n", LIT(pkg->fullpath), LIT(path)); + } + } + } + + gb_printf("}\n\n"); +} + gb_internal void show_timings(Checker *c, Timings *t) { Parser *p = c->parser; isize lines = p->total_line_count; @@ -2928,6 +3001,10 @@ gb_internal int print_show_help(String const arg0, String command, String option print_usage_line(2, "Prints the whole command and arguments for calls to external tools like linker and assembler."); } + if (print_flag("-show-import-graph")) { + print_usage_line(2, "Shows dot graph text format of the import graph of a project."); + } + if (print_flag("-show-timings")) { print_usage_line(2, "Shows basic overview of the timings of different stages within the compiler in milliseconds."); } @@ -3976,6 +4053,9 @@ int main(int arg_count, char const **arg_ptr) { if (build_context.show_timings) { show_timings(checker, &global_timings); } + if (build_context.show_import_graph) { + show_import_graph(checker); + } return 0; } @@ -3987,6 +4067,9 @@ int main(int arg_count, char const **arg_ptr) { if (build_context.show_timings) { show_timings(checker, &global_timings); } + if (build_context.show_import_graph) { + show_import_graph(checker); + } if (global_error_collector.count != 0) { return 1; @@ -4020,6 +4103,9 @@ int main(int arg_count, char const **arg_ptr) { if (build_context.show_timings) { show_timings(checker, &global_timings); } + if (build_context.show_import_graph) { + show_import_graph(checker); + } if (build_context.export_dependencies_format != DependenciesExportUnspecified) { export_dependencies(checker); @@ -4051,6 +4137,9 @@ int main(int arg_count, char const **arg_ptr) { if (build_context.show_timings) { show_timings(checker, &global_timings); } + if (build_context.show_import_graph) { + show_import_graph(checker); + } if (build_context.export_dependencies_format != DependenciesExportUnspecified) { export_dependencies(checker); @@ -4096,6 +4185,9 @@ end_of_code_gen:; if (build_context.show_timings) { show_timings(checker, &global_timings); } + if (build_context.show_import_graph) { + show_import_graph(checker); + } if (run_output) { String exe_name = path_to_string(heap_allocator(), build_context.build_paths[BuildPath_Output]); |