mirror of
https://github.com/godotengine/godot.git
synced 2025-10-22 09:23:40 +00:00
Improve symbol resolve for inner classes
Only level one inner classes would be resolved currently but it sould cover most real world use case Improve documation parseing for const values Improve documation format for native symbols
This commit is contained in:
parent
76c9e4ceb7
commit
b2f02317fa
5 changed files with 156 additions and 47 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue