diff options
Diffstat (limited to 'modules/gdscript/editor/gdscript_highlighter.cpp')
-rw-r--r-- | modules/gdscript/editor/gdscript_highlighter.cpp | 119 |
1 files changed, 90 insertions, 29 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index e488d6e266..8dbd262b22 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -52,6 +52,7 @@ 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; @@ -62,11 +63,13 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l bool in_lambda = false; bool in_function_name = false; - bool in_function_args = false; bool in_variable_declaration = false; bool in_signal_declaration = false; bool expect_type = false; + int in_function_args = 0; + int in_function_arg_dicts = 0; + Color keyword_color; Color color; @@ -146,7 +149,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].start_key == "#") { + if (color_regions[in_region].start_key.begins_with("#")) { break; } if (from + end_key_length > line_length) { @@ -168,7 +171,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].start_key != "#") { + if (j == line_length && !color_regions[in_region].start_key.begins_with("#")) { continue; } } @@ -190,7 +193,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].start_key == "#") { + if (color_regions[in_region].start_key.begins_with("#")) { int marker_start_pos = from; int marker_len = 0; while (from <= line_length) { @@ -234,15 +237,33 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } if (str[from] == '\\') { - Dictionary escape_char_highlighter_info; - escape_char_highlighter_info["color"] = symbol_color; - color_map[from] = escape_char_highlighter_info; + if (!in_raw_string) { + Dictionary escape_char_highlighter_info; + escape_char_highlighter_info["color"] = symbol_color; + color_map[from] = escape_char_highlighter_info; + } from++; - Dictionary region_continue_highlighter_info; - region_continue_highlighter_info["color"] = region_color; - color_map[from + 1] = region_continue_highlighter_info; + if (!in_raw_string) { + int esc_len = 0; + if (str[from] == 'u') { + esc_len = 4; + } else if (str[from] == 'U') { + esc_len = 6; + } + for (int k = 0; k < esc_len && from < line_length - 1; k++) { + if (!is_hex_digit(str[from + 1])) { + break; + } + from++; + } + + Dictionary region_continue_highlighter_info; + region_continue_highlighter_info["color"] = region_color; + color_map[from + 1] = region_continue_highlighter_info; + } + continue; } @@ -423,7 +444,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l if (str[k] == '(') { in_function_name = true; - } else if (prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) { + } else if (prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR) || prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FOR)) { in_variable_declaration = true; } @@ -453,15 +474,27 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } if (is_a_symbol) { - if (in_function_name) { - in_function_args = true; - } - - if (in_function_args && str[j] == ')') { - in_function_args = false; + if (in_function_args > 0) { + switch (str[j]) { + case '(': + in_function_args += 1; + break; + case ')': + in_function_args -= 1; + break; + case '{': + in_function_arg_dicts += 1; + break; + case '}': + in_function_arg_dicts -= 1; + break; + } + } else if (in_function_name && str[j] == '(') { + in_function_args = 1; + in_function_arg_dicts = 0; } - if (expect_type && (prev_is_char || str[j] == '=') && str[j] != '[') { + if (expect_type && (prev_is_char || str[j] == '=') && str[j] != '[' && str[j] != '.') { expect_type = false; } @@ -469,15 +502,15 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l expect_type = true; } - if (in_variable_declaration || in_function_args) { + if (in_variable_declaration || in_function_args > 0) { int k = j; - // Skip space + // Skip space. while (k < line_length && is_whitespace(str[k])) { k++; } - if (str[k] == ':') { - // has type hint + if (str[k] == ':' && in_function_arg_dicts == 0) { + // Has type hint. expect_type = true; } } @@ -489,6 +522,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_member_variable = 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) { @@ -520,7 +559,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l in_annotation = false; } - if (in_node_ref) { + if (in_raw_string) { + color = string_color; + } else if (in_node_ref) { next_type = NODE_REF; color = node_ref_color; } else if (in_annotation) { @@ -535,16 +576,11 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } else if (in_keyword) { next_type = KEYWORD; color = keyword_color; - } else if (in_member_variable) { - next_type = MEMBER; - color = member_color; } else if (in_signal_declaration) { next_type = SIGNAL; - color = member_color; } else if (in_function_name) { next_type = FUNCTION; - if (!in_lambda && prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) { color = function_definition_color; } else { @@ -559,6 +595,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l } else if (expect_type) { next_type = TYPE; color = type_color; + } else if (in_member_variable) { + next_type = MEMBER; + color = member_color; } else { next_type = IDENTIFIER; } @@ -656,6 +695,12 @@ void GDScriptSyntaxHighlighter::_update_cache() { for (const String &E : core_types) { class_names[StringName(E)] = basetype_color; } + class_names[SNAME("Variant")] = basetype_color; + class_names[SNAME("void")] = basetype_color; + // `get_core_type_words()` doesn't return primitive types. + class_names[SNAME("bool")] = basetype_color; + class_names[SNAME("int")] = basetype_color; + class_names[SNAME("float")] = basetype_color; /* Reserved words. */ const Color keyword_color = EDITOR_GET("text_editor/theme/highlighting/keyword_color"); @@ -670,6 +715,10 @@ void GDScriptSyntaxHighlighter::_update_cache() { } } + // Highlight `set` and `get` as "keywords" with the function color to avoid conflicts with method calls. + reserved_keywords[SNAME("set")] = function_color; + reserved_keywords[SNAME("get")] = function_color; + /* Global functions. */ List<StringName> global_function_list; GDScriptUtilityFunctions::get_function_list(&global_function_list); @@ -691,8 +740,18 @@ void GDScriptSyntaxHighlighter::_update_cache() { add_color_region(beg, end, comment_color, end.is_empty()); } + /* Doc comments */ + const Color doc_comment_color = EDITOR_GET("text_editor/theme/highlighting/doc_comment_color"); + List<String> doc_comments; + gdscript->get_doc_comment_delimiters(&doc_comments); + for (const String &doc_comment : doc_comments) { + String beg = doc_comment.get_slice(" ", 0); + String end = doc_comment.get_slice_count(" ") > 1 ? doc_comment.get_slice(" ", 1) : String(); + add_color_region(beg, end, doc_comment_color, end.is_empty()); + } + /* Strings */ - const Color string_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); + string_color = EDITOR_GET("text_editor/theme/highlighting/string_color"); List<String> strings; gdscript->get_string_delimiters(&strings); for (const String &string : strings) { @@ -848,6 +907,8 @@ void GDScriptSyntaxHighlighter::add_color_region(const String &p_start_key, cons 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()) { at++; + } else { + break; } } |