Skip to content

Commit

Permalink
LSP: Fix spec violations that break the VSCode outline
Browse files Browse the repository at this point in the history
  • Loading branch information
HolonProduction committed Nov 15, 2024
1 parent 98ddec4 commit b7bebf5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
11 changes: 10 additions & 1 deletion modules/gdscript/language_server/gdscript_extend_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ lsp::Position GodotPosition::to_lsp(const Vector<String> &p_lines) const {
return res;
}
res.line = line - 1;

// Special case: `column = 0` -> Starts at beginning of line.
if (column <= 0) {
return res;
}

// Note: character outside of `pos_line.length()-1` is valid.
res.character = column - 1;

Expand Down Expand Up @@ -238,9 +244,12 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
r_symbol.kind = lsp::SymbolKind::Class;
r_symbol.deprecated = false;
r_symbol.range = range_of_node(p_class);
r_symbol.range.start.line = MAX(r_symbol.range.start.line, 0);
if (p_class->identifier) {
r_symbol.selectionRange = range_of_node(p_class->identifier);
} else {
// No meaningful `selectionRange`, but we must ensure that it is inside of `range`.
r_symbol.selectionRange.start = r_symbol.range.start;
r_symbol.selectionRange.end = r_symbol.range.start;
}
r_symbol.detail = "class " + r_symbol.name;
{
Expand Down
31 changes: 31 additions & 0 deletions modules/gdscript/tests/test_lsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,18 @@ func f():
gd.to_lsp(lines);
}

SUBCASE("special case: zero column for root class") {
GodotPosition gd(1, 0);
lsp::Position expected = lsp_pos(0, 0);
lsp::Position actual = gd.to_lsp(lines);
CHECK_EQ(actual, expected);
}
SUBCASE("special case: zero line and column for root class") {
GodotPosition gd(0, 0);
lsp::Position expected = lsp_pos(0, 0);
lsp::Position actual = gd.to_lsp(lines);
CHECK_EQ(actual, expected);
}
SUBCASE("special case: negative line for root class") {
GodotPosition gd(-1, 0);
lsp::Position expected = lsp_pos(0, 0);
Expand Down Expand Up @@ -468,6 +480,25 @@ func f():
test_resolve_symbols(uri, all_test_data, all_test_data);
}

memdelete(proto);
finish_language();
}
TEST_CASE("[workspace][document_symbol]") {
GDScriptLanguageProtocol *proto = initialize(root);
REQUIRE(proto);

SUBCASE("selectionRange of root class must be inside range") {
String path = "res://lsp/first_line_comment.gd";
assert_no_errors_in(path);
GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_local_script(path);
ExtendGDScriptParser *parser = GDScriptLanguageProtocol::get_singleton()->get_workspace()->parse_results[path];
REQUIRE(parser);
lsp::DocumentSymbol cls = parser->get_symbols();

REQUIRE(((cls.range.start.line == cls.selectionRange.start.line && cls.range.start.character <= cls.selectionRange.start.character) || (cls.range.start.line < cls.selectionRange.start.line)));
REQUIRE(((cls.range.end.line == cls.selectionRange.end.line && cls.range.end.character >= cls.selectionRange.end.character) || (cls.range.end.line > cls.selectionRange.end.line)));
}

memdelete(proto);
finish_language();
}
Expand Down

0 comments on commit b7bebf5

Please sign in to comment.