From c9a01fbe0e7de3910144c466e935feba6932bd64 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 13 Dec 2019 16:20:59 -0800 Subject: [PATCH] Basics of the entire code index in place for jump to definition --- custom/4coder_code_index.cpp | 164 +++++++++++++++------------ custom/4coder_code_index.h | 3 + custom/4coder_code_index_listers.cpp | 26 ++++- custom/4coder_default_hooks.cpp | 3 + custom/4coder_helper.cpp | 10 +- custom/4coder_types.h | 4 - custom/generated/command_metadata.h | 8 +- 7 files changed, 130 insertions(+), 88 deletions(-) diff --git a/custom/4coder_code_index.cpp b/custom/4coder_code_index.cpp index daa95538..6bd1f40a 100644 --- a/custom/4coder_code_index.cpp +++ b/custom/4coder_code_index.cpp @@ -255,7 +255,7 @@ X | Y = either X or Y X{Y} = X with flag Y // NOTE(allen): grammar of code index parse -file: [preprocessor | scope | parens | type | * - ] +file: [preprocessor | scope | parens | function | type | * - ] preprocessor: [scope | parens | stmnt]{pp-body} scope: [preprocessor | scope | parens | * - ] paren: [preprocessor | scope | parens | * - ] @@ -266,6 +266,7 @@ struct: "struct" $(";" | "{") union: "union" $(";" | "{") enum: "enum" $(";" | "{") typedef: "typedef" [* - ( (";" | "("))] $(";" | "(") +function: >"(" #endif @@ -284,6 +285,76 @@ index_new_note(Code_Index_File *index, Generic_Parse_State *state, Range_i64 ran return(result); } +function void +cpp_parse_type_structure(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + Token *token = token_it_read(&state->it); + if (token != 0 && token->kind == TokenBaseKind_Identifier){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + Token *peek = token_it_read(&state->it); + if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ScopeOpen){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); + } + } +} + +function void +cpp_parse_type_def(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + for (;;){ + b32 did_advance = false; + Token *token = token_it_read(&state->it); + if (token == 0){ + break; + } + if (token->kind == TokenBaseKind_Identifier){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + did_advance = true; + Token *peek = token_it_read(&state->it); + if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ParentheticalOpen){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); + break; + } + } + else if (token->kind == TokenBaseKind_StatementClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose){ + break; + } + else if (token->kind == TokenBaseKind_Keyword){ + String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); + if (string_match(lexeme, string_u8_litexpr("struct")) || + string_match(lexeme, string_u8_litexpr("union")) || + string_match(lexeme, string_u8_litexpr("enum"))){ + break; + } + } + if (!did_advance){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + } + } +} + +function void +cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ + Token *token = token_it_read(&state->it); + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + Token *peek = token_it_read(&state->it); + if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); + } +} + function Code_Index_Nest* generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state); @@ -364,6 +435,13 @@ generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state){ state->in_preprocessor = true; + b32 potential_macro = false; + if (state->do_cpp_parse){ + if (token->sub_kind == TokenCppKind_PPDefine){ + potential_macro = true; + } + } + generic_parse_inc(state); for (;;){ generic_parse_skip_soft_tokens(index, state); @@ -379,6 +457,13 @@ generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state){ break; } + if (state->do_cpp_parse && potential_macro){ + if (token->sub_kind == TokenCppKind_Identifier){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Macro, result); + } + potential_macro = false; + } + if (token->kind == TokenBaseKind_ScopeOpen){ Code_Index_Nest *nest = generic_parse_scope(index, state); nest->parent = result; @@ -558,72 +643,10 @@ generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state){ return(result); } -function void -cpp_parse_type_structure(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - Token *token = token_it_read(&state->it); - if (token != 0 && token->kind == TokenBaseKind_Identifier){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - Token *peek = token_it_read(&state->it); - if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ScopeOpen){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); - } - } -} - -function void -cpp_parse_type_def(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - for (;;){ - b32 did_advance = false; - Token *token = token_it_read(&state->it); - if (token == 0){ - break; - } - if (token->kind == TokenBaseKind_Identifier){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - did_advance = true; - Token *peek = token_it_read(&state->it); - if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ParentheticalOpen){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); - break; - } - } - else if (token->kind == TokenBaseKind_StatementClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose){ - break; - } - else if (token->kind == TokenBaseKind_Keyword){ - String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); - if (string_match(lexeme, string_u8_litexpr("struct")) || - string_match(lexeme, string_u8_litexpr("union")) || - string_match(lexeme, string_u8_litexpr("enum"))){ - break; - } - } - if (!did_advance){ - generic_parse_inc(state); - generic_parse_skip_soft_tokens(index, state); - } - } -} - function b32 generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *state, i32 limit){ b32 result = false; - // TODO(allen): abstract the C++ parse parts somehow? - b32 do_cpp_parse = true; - i64 first_index = token_it_index(&state->it); i64 one_past_last_index = first_index + limit; for (;;){ @@ -647,20 +670,21 @@ generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *sta Code_Index_Nest *nest = generic_parse_paren(index, state); code_index_push_nest(&index->nest_list, nest); } - else if (token->kind == TokenBaseKind_Keyword && do_cpp_parse){ - String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); - if (string_match(lexeme, string_u8_litexpr("struct")) || - string_match(lexeme, string_u8_litexpr("union")) || - string_match(lexeme, string_u8_litexpr("enum"))){ + else if (state->do_cpp_parse){ + if (token->sub_kind == TokenCppKind_Struct || + token->sub_kind == TokenCppKind_Union || + token->sub_kind == TokenCppKind_Enum){ cpp_parse_type_structure(index, state, 0); } - else if (string_match(lexeme, string_u8_litexpr("typedef"))){ + else if (token->sub_kind == TokenCppKind_Typedef){ cpp_parse_type_def(index, state, 0); } + else if (token->sub_kind == TokenCppKind_Identifier){ + cpp_parse_function(index, state, 0); + } else{ generic_parse_inc(state); } - } else{ generic_parse_inc(state); diff --git a/custom/4coder_code_index.h b/custom/4coder_code_index.h index 71962556..3e75c258 100644 --- a/custom/4coder_code_index.h +++ b/custom/4coder_code_index.h @@ -46,6 +46,7 @@ enum{ CodeIndexNote_Type, CodeIndexNote_Function, CodeIndexNote_Macro, + CodeIndexNote_4coderCommand, }; struct Code_Index_Note{ @@ -111,6 +112,8 @@ struct Generic_Parse_State{ i32 paren_counter; b32 in_preprocessor; b32 in_statement; + + b32 do_cpp_parse; }; #endif diff --git a/custom/4coder_code_index_listers.cpp b/custom/4coder_code_index_listers.cpp index 892de4e1..fdc24c24 100644 --- a/custom/4coder_code_index_listers.cpp +++ b/custom/4coder_code_index_listers.cpp @@ -9,12 +9,12 @@ struct Tiny_Jump{ i64 pos; }; -CUSTOM_UI_COMMAND_SIG(jump_to_type_definition) -CUSTOM_DOC("List all types in the code index and jump to one chosen by the user.") +CUSTOM_UI_COMMAND_SIG(jump_to_definition) +CUSTOM_DOC("List all definitions in the code index and jump to one chosen by the user.") { - char *query = "Type:"; + char *query = "Definition:"; - Scratch_Block scratch(app, Scratch_Share); + Scratch_Block scratch(app); Lister *lister = begin_lister(app, scratch); lister_set_query(lister, query); lister->handlers = lister_get_default_handlers(); @@ -30,7 +30,23 @@ CUSTOM_DOC("List all types in the code index and jump to one chosen by the user. Tiny_Jump *jump = push_array(scratch, Tiny_Jump, 1); jump->buffer = buffer; jump->pos = note->pos.first; - lister_add_item(lister, note->text, string_u8_litexpr("type"), jump, 0); + + String_Const_u8 sort = {}; + switch (note->note_kind){ + case CodeIndexNote_Type: + { + sort = string_u8_litexpr("type"); + }break; + case CodeIndexNote_Function: + { + sort = string_u8_litexpr("function"); + }break; + case CodeIndexNote_Macro: + { + sort = string_u8_litexpr("macro"); + }break; + } + lister_add_item(lister, note->text, sort, jump, 0); } } } diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index e9896dbb..1f696f93 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -182,6 +182,9 @@ default_tick(Application_Links *app, Frame_Info frame_info){ Generic_Parse_State state = {}; generic_parse_init(app, &arena, contents, &tokens, &state); + // TODO(allen): Actually determine this in a fair way. + // Maybe switch to an enum. + state.do_cpp_parse = true; generic_parse_full_input_breaks(index, &state, max_i32); code_index_lock(); diff --git a/custom/4coder_helper.cpp b/custom/4coder_helper.cpp index af8ad70f..831a8372 100644 --- a/custom/4coder_helper.cpp +++ b/custom/4coder_helper.cpp @@ -351,8 +351,8 @@ internal Range_Cursor get_line_range(Application_Links *app, Buffer_ID buffer, i64 line_number){ b32 success = false; Range_Cursor result = {}; - result.begin = get_line_start(app, buffer, line_number); - if (result.begin.line != 0){ + result.start = get_line_start(app, buffer, line_number); + if (result.start.line != 0){ result.end = get_line_end(app, buffer, line_number); if (result.end.line != 0){ success = true; @@ -369,15 +369,15 @@ internal Range_i64 get_line_pos_range(Application_Links *app, Buffer_ID buffer, i64 line_number){ Range_Cursor range = get_line_range(app, buffer, line_number); Range_i64 result = {}; - if (range.begin.line != 0 && range.end.line != 0){ - result = Ii64(range.begin.pos, range.end.pos); + if (range.start.line != 0 && range.end.line != 0){ + result = Ii64(range.start.pos, range.end.pos); } return(result); } internal Range_i64 make_range_from_cursors(Range_Cursor range){ - return(Ii64(range.begin.pos, range.end.pos)); + return(Ii64(range.start.pos, range.end.pos)); } internal i64 diff --git a/custom/4coder_types.h b/custom/4coder_types.h index 184fa6f5..8d2b179a 100644 --- a/custom/4coder_types.h +++ b/custom/4coder_types.h @@ -358,10 +358,6 @@ struct Range_Cursor{ Buffer_Cursor min; Buffer_Cursor max; }; - struct{ - Buffer_Cursor begin; - Buffer_Cursor end; - }; struct{ Buffer_Cursor start; Buffer_Cursor end; diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index ced8e98c..836c98df 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -75,7 +75,7 @@ CUSTOM_COMMAND_SIG(interactive_new); CUSTOM_COMMAND_SIG(interactive_open); CUSTOM_COMMAND_SIG(interactive_open_or_new); CUSTOM_COMMAND_SIG(interactive_switch_buffer); -CUSTOM_COMMAND_SIG(jump_to_type_definition); +CUSTOM_COMMAND_SIG(jump_to_definition); CUSTOM_COMMAND_SIG(keyboard_macro_finish_recording); CUSTOM_COMMAND_SIG(keyboard_macro_replay); CUSTOM_COMMAND_SIG(keyboard_macro_start_recording); @@ -316,7 +316,7 @@ static Command_Metadata fcoder_metacmd_table[228] = { { PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 634 }, { PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 563 }, { PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 505 }, -{ PROC_LINKS(jump_to_type_definition, 0), true, "jump_to_type_definition", 23, "List all types in the code index and jump to one chosen by the user.", 68, "w:\\4ed\\code\\custom\\4coder_code_index_listers.cpp", 48, 12 }, +{ PROC_LINKS(jump_to_definition, 0), true, "jump_to_definition", 18, "List all definitions in the code index and jump to one chosen by the user.", 74, "w:\\4ed\\code\\custom\\4coder_code_index_listers.cpp", 48, 12 }, { PROC_LINKS(keyboard_macro_finish_recording, 0), false, "keyboard_macro_finish_recording", 31, "Stop macro recording, do nothing if macro recording is not already started", 74, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 57 }, { PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 80 }, { PROC_LINKS(keyboard_macro_start_recording, 0), false, "keyboard_macro_start_recording", 30, "Start macro recording, do nothing if macro recording is already started", 71, "w:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 44 }, @@ -459,7 +459,7 @@ static Command_Metadata fcoder_metacmd_table[228] = { { PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 415 }, { PROC_LINKS(toggle_paren_matching_helper, 0), false, "toggle_paren_matching_helper", 28, "In code files matching parentheses pairs are colored with distinguishing colors.", 80, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 445 }, { PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 712 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1098 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "w:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1122 }, { PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 20 }, { PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "w:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 34 }, { PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "w:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 137 }, @@ -545,7 +545,7 @@ static i32 fcoder_metacmd_ID_interactive_new = 62; static i32 fcoder_metacmd_ID_interactive_open = 63; static i32 fcoder_metacmd_ID_interactive_open_or_new = 64; static i32 fcoder_metacmd_ID_interactive_switch_buffer = 65; -static i32 fcoder_metacmd_ID_jump_to_type_definition = 66; +static i32 fcoder_metacmd_ID_jump_to_definition = 66; static i32 fcoder_metacmd_ID_keyboard_macro_finish_recording = 67; static i32 fcoder_metacmd_ID_keyboard_macro_replay = 68; static i32 fcoder_metacmd_ID_keyboard_macro_start_recording = 69;