1
0
Fork 0

Add columns to Language Server

This commit is contained in:
voylin 2025-12-19 15:20:18 +09:00
parent 5ad8b27d8d
commit ea1cb8fe67
10 changed files with 68 additions and 50 deletions

View File

@ -222,7 +222,8 @@ public:
/* EDITOR FUNCTIONS */
struct Warning {
int start_line = -1, end_line = -1;
int start_line = 0;
int end_line = 0;
int code;
String string_code;
String message;

View File

@ -820,10 +820,10 @@ Error GDScript::reload(bool p_keep_state) {
}
if (err) {
if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message);
GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), parser.get_errors().front()->get().start_line, "Parser Error: " + parser.get_errors().front()->get().message);
}
// TODO: Show all error messages.
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), parser.get_errors().front()->get().start_line, ("Parse Error: " + parser.get_errors().front()->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
reloading = false;
return ERR_PARSE_ERROR;
}
@ -833,12 +833,12 @@ Error GDScript::reload(bool p_keep_state) {
if (err) {
if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message);
GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), parser.get_errors().front()->get().start_line, "Parser Error: " + parser.get_errors().front()->get().message);
}
const List<GDScriptParser::ParserError>::Element *e = parser.get_errors().front();
while (e != nullptr) {
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().line, ("Parse Error: " + e->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
_err_print_error("GDScript::reload", path.is_empty() ? "built-in" : (const char *)path.utf8().get_data(), e->get().start_line, ("Parse Error: " + e->get().message).utf8().get_data(), false, ERR_HANDLER_SCRIPT);
e = e->next();
}
reloading = false;

View File

@ -169,8 +169,8 @@ bool GDScriptLanguage::validate(const String &p_script, const String &p_path, Li
for (const GDScriptParser::ParserError &pe : parser.get_errors()) {
ScriptLanguage::ScriptError e;
e.path = p_path;
e.line = pe.line;
e.column = pe.column;
e.line = pe.start_line;
e.column = pe.start_column;
e.message = pe.message;
r_errors->push_back(e);
}
@ -180,8 +180,8 @@ bool GDScriptLanguage::validate(const String &p_script, const String &p_path, Li
for (const GDScriptParser::ParserError &pe : depended_parser->get_errors()) {
ScriptLanguage::ScriptError e;
e.path = E.key;
e.line = pe.line;
e.column = pe.column;
e.line = pe.start_line;
e.column = pe.start_column;
e.message = pe.message;
r_errors->push_back(e);
}

View File

@ -235,12 +235,22 @@ void GDScriptParser::push_error(const String &p_message, const Node *p_origin) {
// TODO: Improve error reporting by pointing at source code.
// TODO: Errors might point at more than one place at once (e.g. show previous declaration).
panic_mode = true;
// TODO: Improve positional information.
ParserError err;
err.message = p_message;
if (p_origin == nullptr) {
errors.push_back({ p_message, previous.start_line, previous.start_column });
err.start_line = previous.start_line;
err.start_column = previous.start_column;
err.end_line = previous.end_line;
err.end_column = previous.end_column;
} else {
errors.push_back({ p_message, p_origin->start_line, p_origin->start_column });
err.start_line = p_origin->start_line;
err.start_column = p_origin->start_column;
err.end_line = p_origin->end_line;
err.end_column = p_origin->end_column;
}
errors.push_back(err);
}
#ifdef DEBUG_ENABLED
@ -279,7 +289,9 @@ void GDScriptParser::apply_pending_warnings() {
warning.code = pw.code;
warning.symbols = pw.symbols;
warning.start_line = pw.source->start_line;
warning.start_column = pw.source->start_column;
warning.end_line = pw.source->end_line;
warning.end_column = pw.source->end_column;
if (pw.treated_as_error) {
push_error(warning.get_message() + String(" (Warning treated as error.)"), pw.source);

View File

@ -269,7 +269,10 @@ public:
// };
// Type type = NO_ERROR;
String message;
int line = 0, column = 0;
int start_line = 0;
int start_column = 0;
int end_line = 0;
int end_column = 0;
};
#ifdef TOOLS_ENABLED
@ -337,8 +340,10 @@ public:
};
Type type = NONE;
int start_line = 0, end_line = 0;
int start_column = 0, end_column = 0;
int start_line = 0;
int start_column = 0;
int end_line = 0;
int end_column = 0;
Node *next = nullptr;
List<AnnotationNode *> annotations;
@ -1108,8 +1113,10 @@ public:
StringName name;
FunctionNode *source_function = nullptr;
int start_line = 0, end_line = 0;
int start_column = 0, end_column = 0;
int start_line = 0;
int start_column = 0;
int end_line = 0;
int end_column = 0;
DataType get_datatype() const;
String get_name() const;

View File

@ -165,7 +165,10 @@ public:
Type type = EMPTY;
Variant literal;
int start_line = 0, end_line = 0, start_column = 0, end_column = 0;
int start_line = 0;
int start_column = 0;
int end_line = 0;
int end_column = 0;
CursorPlace cursor_place = CURSOR_NONE;
String source;
@ -224,13 +227,16 @@ class GDScriptTokenizerText : public GDScriptTokenizer {
String source;
const char32_t *_source = nullptr;
const char32_t *_current = nullptr;
int line = -1, column = -1;
int cursor_line = -1, cursor_column = -1;
int line = 0;
int column = 0;
int cursor_line = -1;
int cursor_column = -1;
int tab_size = 4;
// Keep track of multichar tokens.
const char32_t *_start = nullptr;
int start_line = 0, start_column = 0;
int start_line = 0;
int start_column = 0;
// Info cache.
bool line_continuation = false; // Whether this line is a continuation of the previous, like when using '\'.

View File

@ -158,7 +158,10 @@ public:
static_assert(std_size(default_warning_levels) == WARNING_MAX, "Amount of default levels does not match the amount of warnings.");
Code code = WARNING_MAX;
int start_line = -1, end_line = -1;
int start_line = 0;
int start_column = 0;
int end_line = 0;
int end_column = 0;
Vector<String> symbols;
String get_name() const;

View File

@ -135,18 +135,12 @@ void ExtendGDScriptParser::update_diagnostics() {
diagnostic.severity = LSP::DiagnosticSeverity::Error;
diagnostic.message = error.message;
diagnostic.source = "gdscript";
diagnostic.code = -1;
LSP::Range range;
LSP::Position pos;
const PackedStringArray line_array = get_lines();
int line = CLAMP(LINE_NUMBER_TO_INDEX(error.line), 0, line_array.size() - 1);
const String &line_text = line_array[line];
pos.line = line;
pos.character = line_text.length() - line_text.strip_edges(true, false).length();
range.start = pos;
range.end = range.start;
range.end.character = line_text.strip_edges(false).length();
diagnostic.range = range;
GodotRange godot_range(
GodotPosition(error.start_line, error.start_column),
GodotPosition(error.end_line, error.end_column));
diagnostic.range = godot_range.to_lsp(get_lines());
diagnostics.push_back(diagnostic);
}
@ -156,17 +150,12 @@ void ExtendGDScriptParser::update_diagnostics() {
diagnostic.severity = LSP::DiagnosticSeverity::Warning;
diagnostic.message = "(" + warning.get_name() + "): " + warning.get_message();
diagnostic.source = "gdscript";
diagnostic.code = warning.code;
LSP::Range range;
LSP::Position pos;
int line = LINE_NUMBER_TO_INDEX(warning.start_line);
const String &line_text = get_lines()[line];
pos.line = line;
pos.character = line_text.length() - line_text.strip_edges(true, false).length();
range.start = pos;
range.end = pos;
range.end.character = line_text.strip_edges(false).length();
diagnostic.range = range;
GodotRange godot_range(
GodotPosition(warning.start_line, warning.start_column),
GodotPosition(warning.end_line, warning.end_column));
diagnostic.range = godot_range.to_lsp(get_lines());
diagnostics.push_back(diagnostic);
}
}

View File

@ -575,7 +575,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
StringBuilder error_string;
for (const GDScriptParser::ParserError &error : parser.get_errors()) {
error_string.append(vformat(">> ERROR at line %d: %s\n", error.line, error.message));
error_string.append(vformat(">> ERROR at line %d: %s\n", error.start_line, error.message));
}
result.output += error_string.as_string();
if (!p_is_generating) {

View File

@ -175,7 +175,7 @@ static void test_parser(const String &p_code, const String &p_script_path, const
if (err != OK) {
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
print_line(vformat("%02d:%02d: %s", error.start_line, error.start_column, error.message));
}
}
@ -185,7 +185,7 @@ static void test_parser(const String &p_code, const String &p_script_path, const
if (err != OK) {
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
print_line(vformat("%02d:%02d: %s", error.start_line, error.start_column, error.message));
}
}
@ -261,7 +261,7 @@ static void test_compiler(const String &p_code, const String &p_script_path, con
print_line("Error in parser:");
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
print_line(vformat("%02d:%02d: %s", error.start_line, error.start_column, error.message));
}
return;
}
@ -273,7 +273,7 @@ static void test_compiler(const String &p_code, const String &p_script_path, con
print_line("Error in analyzer:");
const List<GDScriptParser::ParserError> &errors = parser.get_errors();
for (const GDScriptParser::ParserError &error : errors) {
print_line(vformat("%02d:%02d: %s", error.line, error.column, error.message));
print_line(vformat("%02d:%02d: %s", error.start_line, error.start_column, error.message));
}
return;
}