summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/editor/gdscript_highlighter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/editor/gdscript_highlighter.cpp')
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp119
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;
}
}