From edd9d5e50b8c976c32f7227e0dfef8ddb9443c40 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 17 Nov 2020 13:02:10 +0000 Subject: [PATCH] Add `-show-unused-with-location` --- src/build_settings.cpp | 1 + src/docs.cpp | 127 ++++++++++++++++++----------------------- src/main.cpp | 98 +++++++++++-------------------- 3 files changed, 90 insertions(+), 136 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 5c1babe0c..3210c914c 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -144,6 +144,7 @@ struct BuildContext { i32 optimization_level; bool show_timings; bool show_unused; + bool show_unused_with_location; bool show_more_timings; bool show_system_calls; bool keep_temp_files; diff --git a/src/docs.cpp b/src/docs.cpp index 3bc0da649..a4a980e68 100644 --- a/src/docs.cpp +++ b/src/docs.cpp @@ -1,6 +1,58 @@ // Generates Documentation + +gb_global int print_entity_kind_ordering[Entity_Count] = { + /*Invalid*/ -1, + /*Constant*/ 0, + /*Variable*/ 1, + /*TypeName*/ 4, + /*Procedure*/ 2, + /*ProcGroup*/ 3, + /*Builtin*/ -1, + /*ImportName*/ -1, + /*LibraryName*/ -1, + /*Nil*/ -1, + /*Label*/ -1, +}; +gb_global char const *print_entity_names[Entity_Count] = { + /*Invalid*/ "", + /*Constant*/ "constants", + /*Variable*/ "variables", + /*TypeName*/ "types", + /*Procedure*/ "procedures", + /*ProcGroup*/ "proc_group", + /*Builtin*/ "", + /*ImportName*/ "import names", + /*LibraryName*/ "library names", + /*Nil*/ "", + /*Label*/ "", +}; + + +GB_COMPARE_PROC(cmp_entities_for_printing) { + GB_ASSERT(a != nullptr); + GB_ASSERT(b != nullptr); + Entity *x = *cast(Entity **)a; + Entity *y = *cast(Entity **)b; + int res = 0; + res = string_compare(x->pkg->name, y->pkg->name); + if (res != 0) { + return res; + } + int ox = print_entity_kind_ordering[x->kind]; + int oy = print_entity_kind_ordering[y->kind]; + if (ox < oy) { + return -1; + } else if (ox > oy) { + return +1; + } + res = string_compare(x->token.string, y->token.string); + return res; +} + + gbString expr_to_string(Ast *expression); +gbString type_to_string(Type *type); String alloc_comment_group_string(gbAllocator a, CommentGroup g) { isize len = 0; @@ -32,76 +84,7 @@ String alloc_comment_group_string(gbAllocator a, CommentGroup g) { return make_string(text, len); } -#if 0 -void print_type_spec(Ast *spec) { - ast_node(ts, TypeSpec, spec); - GB_ASSERT(ts->name->kind == Ast_Ident); - String name = ts->name->Ident.string; - if (name.len == 0) { - return; - } - if (name[0] == '_') { - return; - } - gb_printf("type %.*s\n", LIT(name)); -} - -void print_proc_decl(AstProcDecl *pd) { - GB_ASSERT(pd->name->kind == Ast_Ident); - String name = pd->name->Ident.string; - if (name.len == 0) { - return; - } - if (name[0] == '_') { - return; - } - - String docs = alloc_comment_group_string(heap_allocator(), pd->docs); - defer (gb_free(heap_allocator(), docs.text)); - - if (docs.len > 0) { - gb_file_write(&gb__std_files[gbFileStandard_Output], docs.text, docs.len); - } else { - return; - } - - ast_node(proc_type, ProcType, pd->type); - - gbString params = expr_to_string(proc_type->params); - defer (gb_string_free(params)); - gb_printf("proc %.*s(%s)", LIT(name), params); - if (proc_type->results != nullptr) { - ast_node(fl, FieldList, proc_type->results); - isize count = fl->list.count; - if (count > 0) { - gbString results = expr_to_string(proc_type->results); - defer (gb_string_free(results)); - gb_printf(" -> "); - if (count != 1) { - gb_printf("("); - } - gb_printf("%s", results); - if (count != 1) { - gb_printf(")"); - } - } - } - gb_printf("\n\n"); -} -#endif -void print_declaration(Ast *decl) { -} - -void generate_documentation(Parser *parser) { - // for_array(file_index, parser->files) { - // AstFile *file = parser->files[file_index]; - // Tokenizer *tokenizer = &file->tokenizer; - // String fullpath = tokenizer->fullpath; - // gb_printf("%.*s\n", LIT(fullpath)); - - // for_array(decl_index, file->decls) { - // Ast *decl = file->decls[decl_index]; - // print_declaration(decl); - // } - // } +void generate_documentation(Checker *c) { + CheckerInfo *info = &c->info; + } diff --git a/src/main.cpp b/src/main.cpp index 17477384e..0f27d5079 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,8 +18,8 @@ gb_global Timings global_timings = {0}; #include "checker.hpp" #include "parser.cpp" -#include "docs.cpp" #include "checker.cpp" +#include "docs.cpp" #if defined(LLVM_BACKEND_SUPPORT) @@ -522,7 +522,7 @@ void usage(String argv0) { print_usage_line(1, "run same as 'build', but also then runs the newly compiled executable."); print_usage_line(1, "check parse and type check .odin file"); print_usage_line(1, "query parse, type check, and output a .json file containing information about the program"); - print_usage_line(1, "docs generate documentation for a .odin file"); + print_usage_line(1, "doc generate documentation .odin file, or directory of .odin files"); print_usage_line(1, "version print version"); print_usage_line(0, ""); print_usage_line(0, "For more information of flags, apply the flag to see what is possible"); @@ -569,6 +569,7 @@ enum BuildFlagKind { BuildFlag_OptimizationLevel, BuildFlag_ShowTimings, BuildFlag_ShowUnused, + BuildFlag_ShowUnusedWithLocation, BuildFlag_ShowMoreTimings, BuildFlag_ShowSystemCalls, BuildFlag_ThreadCount, @@ -671,6 +672,7 @@ bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_OptimizationLevel, str_lit("opt"), BuildFlagParam_Integer); add_flag(&build_flags, BuildFlag_ShowTimings, str_lit("show-timings"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowUnused, str_lit("show-unused"), BuildFlagParam_None); + add_flag(&build_flags, BuildFlag_ShowUnusedWithLocation, str_lit("show-unused-with-location"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowMoreTimings, str_lit("show-more-timings"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ShowSystemCalls, str_lit("show-system-calls"), BuildFlagParam_None); add_flag(&build_flags, BuildFlag_ThreadCount, str_lit("thread-count"), BuildFlagParam_Integer); @@ -870,6 +872,15 @@ bool parse_build_flags(Array args) { bad_flags = true; } break; + case BuildFlag_ShowUnusedWithLocation: + GB_ASSERT(value.kind == ExactValue_Invalid); + build_context.show_unused = true; + build_context.show_unused_with_location = true; + if (build_context.command != "check") { + gb_printf_err("%.*s is only allowed with 'odin check'\n", LIT(name)); + bad_flags = true; + } + break; case BuildFlag_ShowMoreTimings: GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_timings = true; @@ -1489,12 +1500,13 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "check parse and type check .odin file"); } else if (command == "query") { print_usage_line(1, "query [experimental] parse, type check, and output a .json file containing information about the program"); - } else if (command == "docs") { - print_usage_line(1, "docs generate documentation for a .odin file"); + } else if (command == "doc") { + print_usage_line(1, "doc generate documentation from a .odin file, or directory of .odin files"); } else if (command == "version") { print_usage_line(1, "version print version"); } + bool doc = command == "doc"; bool build = command == "build"; bool run_or_build = command == "run" || command == "build"; bool check_only = command == "check"; @@ -1536,6 +1548,9 @@ void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-show-unused"); print_usage_line(2, "Shows unused package declarations within the current project"); print_usage_line(0, ""); + print_usage_line(1, "-show-unused-with-location"); + print_usage_line(2, "Shows unused package declarations within the current project with the declarations source location"); + print_usage_line(0, ""); } if (run_or_build) { @@ -1666,56 +1681,6 @@ void print_show_help(String const arg0, String const &command) { } } -int unused_entity_kind_ordering[Entity_Count] = { - /*Invalid*/ -1, - /*Constant*/ 0, - /*Variable*/ 1, - /*TypeName*/ 4, - /*Procedure*/ 2, - /*ProcGroup*/ 3, - /*Builtin*/ -1, - /*ImportName*/ -1, - /*LibraryName*/ -1, - /*Nil*/ -1, - /*Label*/ -1, -}; -char const *unused_entity_names[Entity_Count] = { - /*Invalid*/ "", - /*Constant*/ "constants", - /*Variable*/ "variables", - /*TypeName*/ "types", - /*Procedure*/ "procedures", - /*ProcGroup*/ "proc_group", - /*Builtin*/ "", - /*ImportName*/ "import names", - /*LibraryName*/ "library names", - /*Nil*/ "", - /*Label*/ "", -}; - - -GB_COMPARE_PROC(cmp_entities_for_unused) { - GB_ASSERT(a != nullptr); - GB_ASSERT(b != nullptr); - Entity *x = *cast(Entity **)a; - Entity *y = *cast(Entity **)b; - int res = 0; - res = string_compare(x->pkg->name, y->pkg->name); - if (res != 0) { - return res; - } - int ox = unused_entity_kind_ordering[x->kind]; - int oy = unused_entity_kind_ordering[y->kind]; - if (ox < oy) { - return -1; - } else if (ox > oy) { - return +1; - } - res = string_compare(x->token.string, y->token.string); - return res; -} - - void print_show_unused(Checker *c) { CheckerInfo *info = &c->info; @@ -1762,7 +1727,7 @@ void print_show_unused(Checker *c) { array_add(&unused, e); } - gb_sort_array(unused.data, unused.count, cmp_entities_for_unused); + gb_sort_array(unused.data, unused.count, cmp_entities_for_printing); print_usage_line(0, "Unused Package Declarations"); @@ -1778,11 +1743,14 @@ void print_show_unused(Checker *c) { } if (curr_entity_kind != e->kind) { curr_entity_kind = e->kind; - print_usage_line(1, "%s", unused_entity_names[e->kind]); + print_usage_line(1, "%s", print_entity_names[e->kind]); + } + if (build_context.show_unused_with_location) { + TokenPos pos = e->token.pos; + print_usage_line(2, "%.*s(%td:%td) %.*s", LIT(pos.file), pos.line, pos.column, LIT(e->token.string)); + } else { + print_usage_line(2, "%.*s", LIT(e->token.string)); } - // TokenPos pos = e->token.pos; - // print_usage_line(2, "%.*s(%td:%td) %.*s", LIT(pos.file), pos.line, pos.column, LIT(e->token.string)); - print_usage_line(2, "%.*s", LIT(e->token.string)); } print_usage_line(0, ""); } @@ -1867,7 +1835,7 @@ int main(int arg_count, char const **arg_ptr) { build_context.no_output_files = true; build_context.query_data_set_settings.ok = true; init_filename = args[2]; - } else if (command == "docs") { + } else if (command == "doc") { if (args.count < 3) { usage(args[0]); return 1; @@ -1875,6 +1843,7 @@ int main(int arg_count, char const **arg_ptr) { init_filename = args[2]; build_context.generate_docs = true; + build_context.no_entry_point = true; // ignore entry point #if 1 print_usage_line(0, "Documentation generation is not yet supported"); return 1; @@ -1956,10 +1925,6 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); - if (build_context.generate_docs) { - // generate_documentation(&parser); - return 0; - } timings_start_section(timings, str_lit("type check")); Checker checker = {0}; @@ -1975,6 +1940,11 @@ int main(int arg_count, char const **arg_ptr) { temp_allocator_free_all(&temporary_allocator_data); + if (build_context.generate_docs) { + generate_documentation(&checker); + return global_error_collector.count ? 1 : 0; + } + if (build_context.no_output_files) { if (build_context.show_unused) { print_show_unused(&checker);