diff options
Diffstat (limited to 'modules/gdscript/editor/gdscript_highlighter.cpp')
-rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.cpp | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 439555bacb..f83b784f85 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -53,7 +53,6 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l bool in_keyword = false; bool in_word = false; bool in_number = false; - bool in_raw_string = false; bool in_node_path = false; bool in_node_ref = false; bool in_annotation = false; @@ -65,8 +64,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l bool in_function_name = false; // Any call. bool in_function_declaration = false; // Only declaration. - bool in_var_const_declaration = false; bool in_signal_declaration = false; + bool is_after_func_signal_declaration = false; + bool in_var_const_declaration = false; + bool is_after_var_const_declaration = false; bool expect_type = false; int in_declaration_params = 0; // The number of opened `(` after func/signal name. @@ -125,6 +126,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l if (from != line_length) { // Check if we are in entering a region. if (in_region == -1) { + const bool r_prefix = from > 0 && str[from - 1] == 'r'; for (int c = 0; c < color_regions.size(); c++) { // Check there is enough room. int chars_left = line_length - from; @@ -134,6 +136,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l continue; } + if (color_regions[c].is_string && color_regions[c].r_prefix != r_prefix) { + continue; + } + // Search the line. bool match = true; const char32_t *start_key = color_regions[c].start_key.get_data(); @@ -152,7 +158,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l // Check if it's the whole line. if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) { // Don't skip comments, for highlighting markers. - if (color_regions[in_region].type == ColorRegion::TYPE_COMMENT) { + if (color_regions[in_region].is_comment) { break; } if (from + end_key_length > line_length) { @@ -174,7 +180,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } // Don't skip comments, for highlighting markers. - if (j == line_length && color_regions[in_region].type != ColorRegion::TYPE_COMMENT) { + if (j == line_length && !color_regions[in_region].is_comment) { continue; } } @@ -196,7 +202,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l highlighter_info["color"] = region_color; color_map[j] = highlighter_info; - if (color_regions[in_region].type == ColorRegion::TYPE_COMMENT) { + if (color_regions[in_region].is_comment) { int marker_start_pos = from; int marker_len = 0; while (from <= line_length) { @@ -240,7 +246,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } if (str[from] == '\\') { - if (!in_raw_string) { + if (!color_regions[in_region].r_prefix) { Dictionary escape_char_highlighter_info; escape_char_highlighter_info["color"] = symbol_color; color_map[from] = escape_char_highlighter_info; @@ -248,7 +254,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l from++; - if (!in_raw_string) { + if (!color_regions[in_region].r_prefix) { int esc_len = 0; if (str[from] == 'u') { esc_len = 4; @@ -410,6 +416,8 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l col = class_names[word]; } else if (reserved_keywords.has(word)) { col = reserved_keywords[word]; + // Don't highlight `list` as a type in `for elem: Type in list`. + expect_type = false; } else if (member_keywords.has(word)) { col = member_keywords[word]; } @@ -480,6 +488,13 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } if (is_a_symbol) { + if (in_function_declaration || in_signal_declaration) { + is_after_func_signal_declaration = true; + } + if (in_var_const_declaration) { + is_after_var_const_declaration = true; + } + if (in_declaration_params > 0) { switch (str[j]) { case '(': @@ -495,7 +510,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_declaration_param_dicts -= 1; break; } - } else if ((in_function_declaration || in_signal_declaration || prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) && str[j] == '(') { + } else if ((is_after_func_signal_declaration || prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) && str[j] == '(') { in_declaration_params = 1; in_declaration_param_dicts = 0; } @@ -526,28 +541,25 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l expect_type = true; in_type_params = 0; } - if ((in_var_const_declaration || (in_declaration_params == 1 && in_declaration_param_dicts == 0)) && str[j] == ':') { + if ((is_after_var_const_declaration || (in_declaration_params == 1 && in_declaration_param_dicts == 0)) && str[j] == ':') { expect_type = true; in_type_params = 0; } } + in_function_name = false; + in_function_declaration = false; + in_signal_declaration = false; + in_var_const_declaration = false; + in_lambda = false; + in_member_variable = false; + if (!is_whitespace(str[j])) { - in_function_declaration = false; - in_var_const_declaration = false; - in_signal_declaration = false; - in_function_name = false; - in_lambda = false; - in_member_variable = false; + is_after_func_signal_declaration = false; + is_after_var_const_declaration = false; } } - if (!in_raw_string && in_region == -1 && str[j] == 'r' && j < line_length - 1 && (str[j + 1] == '"' || str[j + 1] == '\'')) { - in_raw_string = true; - } else if (in_raw_string && in_region == -1) { - in_raw_string = false; - } - // Keep symbol color for binary '&&'. In the case of '&&&' use StringName color for the last ampersand. if (!in_string_name && in_region == -1 && str[j] == '&' && !is_binary_op) { if (j >= 2 && str[j - 1] == '&' && str[j - 2] != '&' && prev_is_binary_op) { @@ -579,7 +591,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_annotation = false; } - if (in_raw_string) { + const bool in_raw_string_prefix = in_region == -1 && str[j] == 'r' && j + 1 < line_length && (str[j + 1] == '"' || str[j + 1] == '\''); + + if (in_raw_string_prefix) { color = string_color; } else if (in_node_ref) { next_type = NODE_REF; @@ -781,6 +795,10 @@ void GDScriptSyntaxHighlighter::_update_cache() { add_color_region(ColorRegion::TYPE_STRING, "'", "'", string_color); add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "\"\"\"", "\"\"\"", string_color); add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "'''", "'''", string_color); + add_color_region(ColorRegion::TYPE_STRING, "\"", "\"", string_color, false, true); + add_color_region(ColorRegion::TYPE_STRING, "'", "'", string_color, false, true); + add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "\"\"\"", "\"\"\"", string_color, false, true); + add_color_region(ColorRegion::TYPE_MULTILINE_STRING, "'''", "'''", string_color, false, true); const Ref<Script> scr = _get_edited_resource(); if (scr.is_valid()) { @@ -913,7 +931,7 @@ void GDScriptSyntaxHighlighter::_update_cache() { } } -void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only) { +void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const String &p_start_key, const String &p_end_key, const Color &p_color, bool p_line_only, bool p_r_prefix) { ERR_FAIL_COND_MSG(p_start_key.is_empty(), "Color region start key cannot be empty."); ERR_FAIL_COND_MSG(!is_symbol(p_start_key[0]), "Color region start key must start with a symbol."); @@ -922,9 +940,9 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const } int at = 0; - for (int i = 0; i < color_regions.size(); i++) { - ERR_FAIL_COND_MSG(color_regions[i].start_key == p_start_key, "Color region with start key '" + p_start_key + "' already exists."); - if (p_start_key.length() < color_regions[i].start_key.length()) { + for (const ColorRegion ®ion : color_regions) { + ERR_FAIL_COND_MSG(region.start_key == p_start_key && region.r_prefix == p_r_prefix, "Color region with start key '" + p_start_key + "' already exists."); + if (p_start_key.length() < region.start_key.length()) { at++; } else { break; @@ -937,6 +955,9 @@ void GDScriptSyntaxHighlighter::add_color_region(ColorRegion::Type p_type, const color_region.start_key = p_start_key; color_region.end_key = p_end_key; color_region.line_only = p_line_only; + color_region.r_prefix = p_r_prefix; + color_region.is_string = p_type == ColorRegion::TYPE_STRING || p_type == ColorRegion::TYPE_MULTILINE_STRING; + color_region.is_comment = p_type == ColorRegion::TYPE_COMMENT || p_type == ColorRegion::TYPE_CODE_REGION; color_regions.insert(at, color_region); clear_highlighting_cache(); } |