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.cpp73
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 &region : 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();
}