diff --git a/core/object/script_language.h b/core/object/script_language.h index 4e519f405e3..10b07c9c3da 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -214,7 +214,6 @@ public: /* EDITOR FUNCTIONS */ struct Warning { int start_line = -1, end_line = -1; - int leftmost_column = -1, rightmost_column = -1; int code; String string_code; String message; diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index e605cccc7ca..f9167fc3072 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -347,8 +347,6 @@ public: Dictionary warn = warning; ERR_CONTINUE(!warn.has("start_line")); ERR_CONTINUE(!warn.has("end_line")); - ERR_CONTINUE(!warn.has("leftmost_column")); - ERR_CONTINUE(!warn.has("rightmost_column")); ERR_CONTINUE(!warn.has("code")); ERR_CONTINUE(!warn.has("string_code")); ERR_CONTINUE(!warn.has("message")); @@ -356,8 +354,6 @@ public: Warning swarn; swarn.start_line = warn["start_line"]; swarn.end_line = warn["end_line"]; - swarn.leftmost_column = warn["leftmost_column"]; - swarn.rightmost_column = warn["rightmost_column"]; swarn.code = warn["code"]; swarn.string_code = warn["string_code"]; swarn.message = warn["message"]; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 2e6fe46f8ee..327adc382aa 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -79,7 +79,7 @@ void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::N error = p_error; if (p_node) { err_line = p_node->start_line; - err_column = p_node->leftmost_column; + err_column = p_node->start_column; } else { err_line = 0; err_column = 0; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 29885526afd..c5c09c61ae4 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -144,8 +144,6 @@ bool GDScriptLanguage::validate(const String &p_script, const String &p_path, Li ScriptLanguage::Warning w; w.start_line = warn.start_line; w.end_line = warn.end_line; - w.leftmost_column = warn.leftmost_column; - w.rightmost_column = warn.rightmost_column; w.code = (int)warn.code; w.string_code = GDScriptWarning::get_name_from_code(warn.code); w.message = warn.get_message(); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index a225d2fa6f3..adddc29a5e5 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -184,7 +184,7 @@ void GDScriptParser::push_error(const String &p_message, const Node *p_origin) { if (p_origin == nullptr) { errors.push_back({ p_message, previous.start_line, previous.start_column }); } else { - errors.push_back({ p_message, p_origin->start_line, p_origin->leftmost_column }); + errors.push_back({ p_message, p_origin->start_line, p_origin->start_column }); } } @@ -227,8 +227,6 @@ void GDScriptParser::apply_pending_warnings() { warning.symbols = pw.symbols; warning.start_line = pw.source->start_line; warning.end_line = pw.source->end_line; - warning.leftmost_column = pw.source->leftmost_column; - warning.rightmost_column = pw.source->rightmost_column; if (pw.treated_as_error) { push_error(warning.get_message() + String(" (Warning treated as error.)"), pw.source); @@ -412,8 +410,6 @@ Error GDScriptParser::parse(const String &p_source_code, const String &p_script_ nd->start_line = 1; nd->start_column = 0; nd->end_line = 1; - nd->leftmost_column = 0; - nd->rightmost_column = 0; push_warning(nd, GDScriptWarning::EMPTY_FILE); } #endif @@ -761,8 +757,6 @@ void GDScriptParser::parse_program() { head->end_line = current.end_line; head->end_column = current.end_column; - head->leftmost_column = MIN(head->leftmost_column, current.leftmost_column); - head->rightmost_column = MAX(head->rightmost_column, current.rightmost_column); complete_extents(head); @@ -1550,8 +1544,8 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum(bool p_is_abstract, bool p_ item.identifier = identifier; item.parent_enum = enum_node; item.line = previous.start_line; - item.leftmost_column = previous.leftmost_column; - item.rightmost_column = previous.rightmost_column; + item.start_column = previous.start_column; + item.end_column = previous.end_column; if (elements.has(item.identifier->name)) { push_error(vformat(R"(Name "%s" was already in this enum (at line %d).)", item.identifier->name, elements[item.identifier->name]), item.identifier); @@ -5463,8 +5457,6 @@ void GDScriptParser::complete_extents(Node *p_node) { void GDScriptParser::update_extents(Node *p_node) { p_node->end_line = previous.end_line; p_node->end_column = previous.end_column; - p_node->leftmost_column = MIN(p_node->leftmost_column, previous.leftmost_column); - p_node->rightmost_column = MAX(p_node->rightmost_column, previous.rightmost_column); } void GDScriptParser::reset_extents(Node *p_node, GDScriptTokenizer::Token p_token) { @@ -5472,8 +5464,6 @@ void GDScriptParser::reset_extents(Node *p_node, GDScriptTokenizer::Token p_toke p_node->end_line = p_token.end_line; p_node->start_column = p_token.start_column; p_node->end_column = p_token.end_column; - p_node->leftmost_column = p_token.leftmost_column; - p_node->rightmost_column = p_token.rightmost_column; } void GDScriptParser::reset_extents(Node *p_node, Node *p_from) { @@ -5484,8 +5474,6 @@ void GDScriptParser::reset_extents(Node *p_node, Node *p_from) { p_node->end_line = p_from->end_line; p_node->start_column = p_from->start_column; p_node->end_column = p_from->end_column; - p_node->leftmost_column = p_from->leftmost_column; - p_node->rightmost_column = p_from->rightmost_column; } /*---------- PRETTY PRINT FOR DEBUG ----------*/ diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index ee246c762ad..d3ffa7d27ac 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -339,7 +339,6 @@ public: Type type = NONE; int start_line = 0, end_line = 0; int start_column = 0, end_column = 0; - int leftmost_column = 0, rightmost_column = 0; Node *next = nullptr; List annotations; @@ -536,8 +535,8 @@ public: bool resolved = false; int64_t value = 0; int line = 0; - int leftmost_column = 0; - int rightmost_column = 0; + int start_column = 0; + int end_column = 0; #ifdef TOOLS_ENABLED MemberDocData doc_data; #endif // TOOLS_ENABLED @@ -1105,7 +1104,6 @@ public: int start_line = 0, end_line = 0; int start_column = 0, end_column = 0; - int leftmost_column = 0, rightmost_column = 0; DataType get_datatype() const; String get_name() const; @@ -1121,8 +1119,6 @@ public: end_line = p_constant->end_line; start_column = p_constant->start_column; end_column = p_constant->end_column; - leftmost_column = p_constant->leftmost_column; - rightmost_column = p_constant->rightmost_column; } Local(VariableNode *p_variable, FunctionNode *p_source_function) { type = VARIABLE; @@ -1134,8 +1130,6 @@ public: end_line = p_variable->end_line; start_column = p_variable->start_column; end_column = p_variable->end_column; - leftmost_column = p_variable->leftmost_column; - rightmost_column = p_variable->rightmost_column; } Local(ParameterNode *p_parameter, FunctionNode *p_source_function) { type = PARAMETER; @@ -1147,8 +1141,6 @@ public: end_line = p_parameter->end_line; start_column = p_parameter->start_column; end_column = p_parameter->end_column; - leftmost_column = p_parameter->leftmost_column; - rightmost_column = p_parameter->rightmost_column; } Local(IdentifierNode *p_identifier, FunctionNode *p_source_function) { type = FOR_VARIABLE; @@ -1160,8 +1152,6 @@ public: end_line = p_identifier->end_line; start_column = p_identifier->start_column; end_column = p_identifier->end_column; - leftmost_column = p_identifier->leftmost_column; - rightmost_column = p_identifier->rightmost_column; } }; Local empty; diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 93a06b2b76d..71c6133bdcd 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -329,9 +329,6 @@ char32_t GDScriptTokenizerText::_advance() { _current++; column++; position++; - if (column > rightmost_column) { - rightmost_column = column; - } if (unlikely(_is_at_end())) { // Add extra newline even if it's not there, to satisfy the parser. newline(true); @@ -367,8 +364,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::make_token(Token::Type p_type) { token.end_line = line; token.start_column = start_column; token.end_column = column; - token.leftmost_column = leftmost_column; - token.rightmost_column = rightmost_column; token.source = String::utf32(Span(_start, _current - _start)); if (p_type != Token::ERROR && cursor_line > -1) { @@ -671,8 +666,6 @@ void GDScriptTokenizerText::newline(bool p_make_token) { newline.end_line = line; newline.start_column = column - 1; newline.end_column = column; - newline.leftmost_column = newline.start_column; - newline.rightmost_column = newline.end_column; pending_newline = true; last_token = newline; last_newline = newline; @@ -681,7 +674,6 @@ void GDScriptTokenizerText::newline(bool p_make_token) { // Increment line/column counters. line++; column = 1; - leftmost_column = 1; } GDScriptTokenizer::Token GDScriptTokenizerText::number() { @@ -718,9 +710,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (base != 10 && is_underscore(_peek())) { // Disallow `0x_` and `0b_`. Token error = make_error(vformat(R"(Unexpected underscore after "0%c".)", _peek(-1))); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); has_error = true; } @@ -730,9 +720,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (previous_was_underscore) { Token error = make_error(R"(Multiple underscores cannot be adjacent in a numeric literal.)"); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); } previous_was_underscore = true; @@ -750,25 +738,19 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { } else if (base == 10) { Token error = make_error("Cannot use a decimal point twice in a number."); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); has_error = true; } else if (base == 16) { Token error = make_error("Cannot use a decimal point in a hexadecimal number."); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); has_error = true; } else { Token error = make_error("Cannot use a decimal point in a binary number."); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); has_error = true; } @@ -779,9 +761,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (is_underscore(_peek())) { // Disallow `10._`, but allow `10.`. Token error = make_error(R"(Unexpected underscore after decimal point.)"); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); has_error = true; } @@ -791,9 +771,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (previous_was_underscore) { Token error = make_error(R"(Multiple underscores cannot be adjacent in a numeric literal.)"); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); } previous_was_underscore = true; @@ -816,9 +794,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (!is_digit(_peek())) { Token error = make_error(R"(Expected exponent value after "e".)"); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); } previous_was_underscore = false; @@ -827,9 +803,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (previous_was_underscore) { Token error = make_error(R"(Multiple underscores cannot be adjacent in a numeric literal.)"); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); } previous_was_underscore = true; @@ -845,9 +819,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { // No digits in hex or bin literal. Token error = make_error(vformat(R"(Expected %s digit after "0%c".)", (base == 16 ? "hexadecimal" : "binary"), (base == 16 ? 'x' : 'b'))); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; return error; } @@ -855,9 +827,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::number() { if (!has_error && has_decimal && _peek() == '.' && _peek(1) != '.') { Token error = make_error("Cannot use a decimal point twice in a number."); error.start_column = column; - error.leftmost_column = column; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); has_error = true; } else if (is_unicode_identifier_start(_peek()) || is_unicode_identifier_continue(_peek())) { @@ -936,9 +906,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { error = make_error("Invisible text direction control character present in the string, escape it (\"\\u" + String::num_int64(ch, 16) + "\") to avoid confusion."); } error.start_column = column; - error.leftmost_column = error.start_column; error.end_column = column + 1; - error.rightmost_column = error.end_column; push_error(error); } @@ -1032,9 +1000,7 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { // Make error, but keep parsing the string. Token error = make_error("Invalid hexadecimal digit in unicode escape sequence."); error.start_column = column; - error.leftmost_column = error.start_column; error.end_column = column + 1; - error.rightmost_column = error.end_column; push_error(error); valid_escape = false; break; @@ -1063,7 +1029,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { default: Token error = make_error("Invalid escape in string."); error.start_column = column - 2; - error.leftmost_column = error.start_column; push_error(error); valid_escape = false; break; @@ -1078,7 +1043,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { } else { Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate."); error.start_column = column - 2; - error.leftmost_column = error.start_column; push_error(error); valid_escape = false; prev = 0; @@ -1087,7 +1051,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { if (prev == 0) { Token error = make_error("Invalid UTF-16 sequence in string, unpaired trail surrogate."); error.start_column = column - 2; - error.leftmost_column = error.start_column; push_error(error); valid_escape = false; } else { @@ -1098,7 +1061,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { if (prev != 0) { Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate."); error.start_column = prev_pos; - error.leftmost_column = error.start_column; push_error(error); prev = 0; } @@ -1112,7 +1074,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { if (prev != 0) { Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); error.start_column = prev_pos; - error.leftmost_column = error.start_column; push_error(error); prev = 0; } @@ -1135,7 +1096,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { if (prev != 0) { Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); error.start_column = prev_pos; - error.leftmost_column = error.start_column; push_error(error); prev = 0; } @@ -1149,7 +1109,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::string() { if (prev != 0) { Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate"); error.start_column = prev_pos; - error.leftmost_column = error.start_column; push_error(error); prev = 0; } @@ -1273,8 +1232,6 @@ void GDScriptTokenizerText::check_indent() { Token error = make_error("Mixed use of tabs and spaces for indentation."); error.start_line = line; error.start_column = 1; - error.leftmost_column = 1; - error.rightmost_column = column; push_error(error); } @@ -1293,8 +1250,6 @@ void GDScriptTokenizerText::check_indent() { _get_indent_char_name(current_indent_char), _get_indent_char_name(indent_char))); error.start_line = line; error.start_column = 1; - error.leftmost_column = 1; - error.rightmost_column = column; push_error(error); } @@ -1328,9 +1283,7 @@ void GDScriptTokenizerText::check_indent() { Token error = make_error("Unindent doesn't match the previous indentation level."); error.start_line = line; error.start_column = 1; - error.leftmost_column = 1; error.end_column = column + 1; - error.rightmost_column = column + 1; push_error(error); // Still, we'll be lenient and keep going, so keep this level in the stack. indent_stack.push_back(indent_count); @@ -1431,14 +1384,11 @@ GDScriptTokenizer::Token GDScriptTokenizerText::scan() { _start = _current; start_line = line; start_column = column; - leftmost_column = column; - rightmost_column = column; if (pending_indents != 0) { // Adjust position for indent. _start -= start_column - 1; start_column = 1; - leftmost_column = 1; if (pending_indents > 0) { // Indents. pending_indents--; @@ -1448,7 +1398,6 @@ GDScriptTokenizer::Token GDScriptTokenizerText::scan() { pending_indents++; Token dedent = make_token(Token::DEDENT); dedent.end_column += 1; - dedent.rightmost_column += 1; return dedent; } } diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index cfaa2aae053..94313edcdf5 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -165,7 +165,6 @@ public: Type type = EMPTY; Variant literal; int start_line = 0, end_line = 0, start_column = 0, end_column = 0; - int leftmost_column = 0, rightmost_column = 0; // Column span for multiline tokens. int cursor_position = -1; CursorPlace cursor_place = CURSOR_NONE; String source; @@ -226,7 +225,6 @@ class GDScriptTokenizerText : public GDScriptTokenizer { // Keep track of multichar tokens. const char32_t *_start = nullptr; int start_line = 0, start_column = 0; - int leftmost_column = 0, rightmost_column = 0; // Info cache. bool line_continuation = false; // Whether this line is a continuation of the previous, like when using '\'. diff --git a/modules/gdscript/gdscript_warning.h b/modules/gdscript/gdscript_warning.h index e86cd3b5965..5f47e120fa8 100644 --- a/modules/gdscript/gdscript_warning.h +++ b/modules/gdscript/gdscript_warning.h @@ -157,7 +157,6 @@ public: Code code = WARNING_MAX; int start_line = -1, end_line = -1; - int leftmost_column = -1, rightmost_column = -1; Vector symbols; String get_name() const; diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp index f8df46b256f..ed095a946b9 100644 --- a/modules/gdscript/language_server/gdscript_extend_parser.cpp +++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp @@ -403,8 +403,8 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p symbol.name = m.enum_value.identifier->name; symbol.kind = LSP::SymbolKind::EnumMember; symbol.deprecated = false; - symbol.range.start = GodotPosition(m.enum_value.line, m.enum_value.leftmost_column).to_lsp(lines); - symbol.range.end = GodotPosition(m.enum_value.line, m.enum_value.rightmost_column).to_lsp(lines); + symbol.range.start = GodotPosition(m.enum_value.line, m.enum_value.start_column).to_lsp(lines); + symbol.range.end = GodotPosition(m.enum_value.line, m.enum_value.end_column).to_lsp(lines); symbol.selectionRange = range_of_node(m.enum_value.identifier); symbol.documentation = m.enum_value.doc_data.description; symbol.uri = uri; @@ -439,8 +439,8 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p child.name = value.identifier->name; child.kind = LSP::SymbolKind::EnumMember; child.deprecated = false; - child.range.start = GodotPosition(value.line, value.leftmost_column).to_lsp(lines); - child.range.end = GodotPosition(value.line, value.rightmost_column).to_lsp(lines); + child.range.start = GodotPosition(value.line, value.start_column).to_lsp(lines); + child.range.end = GodotPosition(value.line, value.end_column).to_lsp(lines); child.selectionRange = range_of_node(value.identifier); child.documentation = value.doc_data.description; child.uri = uri; diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index aca1ed5a5f3..fe838919e07 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -64,25 +64,41 @@ static void test_tokenizer(const String &p_code, const Vector &p_lines) StringBuilder token; token += " --> "; // Padding for line number. + if (current.start_line != current.end_line) { + // Print "vvvvvv" to point at the token. + StringBuilder pointer; + pointer += " "; // Padding for line number. + + int line_width = 0; + if (current.start_line - 1 >= 0 && current.start_line - 1 < p_lines.size()) { + line_width = p_lines[current.start_line - 1].replace("\t", tab).length(); + } + + const int offset = MAX(0, current.start_column - 1); + const int width = MAX(0, line_width - current.start_column + 1); + pointer += String::chr(' ').repeat(offset) + String::chr('v').repeat(width); + + print_line(pointer.as_string()); + } + for (int l = current.start_line; l <= current.end_line && l <= p_lines.size(); l++) { print_line(vformat("%04d %s", l, p_lines[l - 1]).replace("\t", tab)); } { - // Print carets to point at the token. + // Print "^^^^^^" to point at the token. StringBuilder pointer; pointer += " "; // Padding for line number. - int rightmost_column = current.rightmost_column; - if (current.end_line > current.start_line) { - rightmost_column--; // Don't point to the newline as a column. - } - for (int col = 1; col < rightmost_column; col++) { - if (col < current.leftmost_column) { - pointer += " "; - } else { - pointer += "^"; - } + + if (current.start_line == current.end_line) { + const int offset = MAX(0, current.start_column - 1); + const int width = MAX(0, current.end_column - current.start_column); + pointer += String::chr(' ').repeat(offset) + String::chr('^').repeat(width); + } else { + const int width = MAX(0, current.end_column - 1); + pointer += String::chr('^').repeat(width); } + print_line(pointer.as_string()); }