summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/language_server/gdscript_extend_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/language_server/gdscript_extend_parser.cpp')
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp108
1 files changed, 89 insertions, 19 deletions
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index a6fbfd3779..16f4324da8 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -91,6 +91,16 @@ void ExtendGDScriptParser::update_symbols() {
for (int i = 0; i < class_symbol.children.size(); i++) {
const lsp::DocumentSymbol &symbol = class_symbol.children[i];
members.set(symbol.name, &symbol);
+
+ // cache level one inner classes
+ if (symbol.kind == lsp::SymbolKind::Class) {
+ ClassMembers inner_class;
+ for (int j = 0; j < symbol.children.size(); j++) {
+ const lsp::DocumentSymbol &s = symbol.children[j];
+ inner_class.set(s.name, &s);
+ }
+ inner_classes.set(symbol.name, inner_class);
+ }
}
}
}
@@ -112,7 +122,8 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
r_symbol.range.end.line = LINE_NUMBER_TO_INDEX(p_class->end_line);
r_symbol.selectionRange.start.line = r_symbol.range.start.line;
r_symbol.detail = "class " + r_symbol.name;
- r_symbol.documentation = parse_documentation(LINE_NUMBER_TO_INDEX(p_class->line));
+ bool is_root_class = &r_symbol == &class_symbol;
+ r_symbol.documentation = parse_documentation(is_root_class ? 0 : LINE_NUMBER_TO_INDEX(p_class->line), is_root_class);
for (int i = 0; i < p_class->variables.size(); ++i) {
@@ -192,7 +203,26 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
if (c.type.kind != GDScriptParser::DataType::UNRESOLVED) {
symbol.detail += ": " + c.type.to_string();
}
- symbol.detail += " = " + String(node->value);
+
+ String value_text;
+ if (node->value.get_type() == Variant::OBJECT) {
+ RES res = node->value;
+ if (res.is_valid() && !res->get_path().empty()) {
+ value_text = "preload(\"" + res->get_path() + "\")";
+ if (symbol.documentation.empty()) {
+ if (Map<String, ExtendGDScriptParser *>::Element *S = GDScriptLanguageProtocol::get_singleton()->get_workspace().scripts.find(res->get_path())) {
+ symbol.documentation = S->get()->class_symbol.documentation;
+ }
+ }
+ } else {
+ value_text = JSON::print(node->value);
+ }
+ } else {
+ value_text = JSON::print(node->value);
+ }
+ if (!value_text.empty()) {
+ symbol.detail += " = " + value_text;
+ }
r_symbol.children.push_back(symbol);
}
@@ -296,29 +326,43 @@ void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionN
}
}
-String ExtendGDScriptParser::parse_documentation(int p_line) {
+String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
ERR_FAIL_INDEX_V(p_line, lines.size(), String());
List<String> doc_lines;
- // inline comment
- String inline_comment = lines[p_line];
- int comment_start = inline_comment.find("#");
- if (comment_start != -1) {
- inline_comment = inline_comment.substr(comment_start, inline_comment.length());
- if (inline_comment.length() > 1) {
- doc_lines.push_back(inline_comment.substr(1, inline_comment.length()));
+ if (!p_docs_down) { // inline comment
+ String inline_comment = lines[p_line];
+ int comment_start = inline_comment.find("#");
+ if (comment_start != -1) {
+ inline_comment = inline_comment.substr(comment_start, inline_comment.length());
+ if (inline_comment.length() > 1) {
+ doc_lines.push_back(inline_comment.substr(1, inline_comment.length()));
+ }
}
}
- // upper line comments
- for (int i = p_line - 1; i >= 0; --i) {
+ int step = p_docs_down ? 1 : -1;
+ int start_line = p_docs_down ? p_line : p_line - 1;
+ for (int i = start_line; true; i += step) {
+
+ if (i < 0 || i >= lines.size()) break;
+
String line_comment = lines[i].strip_edges(true, false);
if (line_comment.begins_with("#")) {
if (line_comment.length() > 1) {
- doc_lines.push_front(line_comment.substr(1, line_comment.length()));
+ line_comment = line_comment.substr(1, line_comment.length());
+ if (p_docs_down) {
+ doc_lines.push_back(line_comment);
+ } else {
+ doc_lines.push_front(line_comment);
+ }
} else {
- doc_lines.push_front("");
+ if (p_docs_down) {
+ doc_lines.push_back("");
+ } else {
+ doc_lines.push_front("");
+ }
}
} else {
break;
@@ -456,11 +500,20 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int
return search_symbol_defined_at_line(p_line, class_symbol);
}
-const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String &p_name) const {
+const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String &p_name, const String &p_subclass) const {
- const lsp::DocumentSymbol *const *ptr = members.getptr(p_name);
- if (ptr) {
- return *ptr;
+ if (p_subclass.empty()) {
+ const lsp::DocumentSymbol *const *ptr = members.getptr(p_name);
+ if (ptr) {
+ return *ptr;
+ }
+ } else {
+ if (const ClassMembers *_class = inner_classes.getptr(p_subclass)) {
+ const lsp::DocumentSymbol *const *ptr = _class->getptr(p_name);
+ if (ptr) {
+ return *ptr;
+ }
+ }
}
return NULL;
@@ -474,12 +527,29 @@ const Array &ExtendGDScriptParser::get_member_completions() {
while (name) {
const lsp::DocumentSymbol *symbol = members.get(*name);
- lsp::CompletionItem item = symbol->make_completion_item(false);
+ lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(path, *name);
member_completions.push_back(item.to_json());
name = members.next(name);
}
+
+ const String *_class = inner_classes.next(NULL);
+ while (_class) {
+
+ const ClassMembers *inner_class = inner_classes.getptr(*_class);
+ const String *member_name = inner_class->next(NULL);
+ while (member_name) {
+ const lsp::DocumentSymbol *symbol = inner_class->get(*member_name);
+ lsp::CompletionItem item = symbol->make_completion_item();
+ item.data = JOIN_SYMBOLS(path, JOIN_SYMBOLS(*_class, *member_name));
+ member_completions.push_back(item.to_json());
+
+ member_name = inner_class->next(member_name);
+ }
+
+ _class = inner_classes.next(_class);
+ }
}
return member_completions;