Basics of the entire code index in place for jump to definition

master
Allen Webster 2019-12-13 16:20:59 -08:00
parent 6993c3c0d5
commit c9a01fbe0e
7 changed files with 130 additions and 88 deletions

View File

@ -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 | * - <end-of-file>] <end-of-file>
file: [preprocessor | scope | parens | function | type | * - <end-of-file>] <end-of-file>
preprocessor: <preprocessor> [scope | parens | stmnt]{pp-body}
scope: <scope-open> [preprocessor | scope | parens | * - <scope-close>] <scope-close>
paren: <paren-open> [preprocessor | scope | parens | * - <paren-close>] <paren-close>
@ -266,6 +266,7 @@ struct: "struct" <identifier> $(";" | "{")
union: "union" <identifier> $(";" | "{")
enum: "enum" <identifier> $(";" | "{")
typedef: "typedef" [* - (<identifier> (";" | "("))] <identifier> $(";" | "(")
function: <identifier> >"("
#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);

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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;