|
@@ -115,6 +115,36 @@ const lsp::DocumentSymbol *GDScriptWorkspace::get_script_symbol(const String &p_
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
+const lsp::DocumentSymbol *GDScriptWorkspace::get_parameter_symbol(const lsp::DocumentSymbol *p_parent, const String &symbol_identifier) {
|
|
|
+ for (int i = 0; i < p_parent->children.size(); ++i) {
|
|
|
+ const lsp::DocumentSymbol *parameter_symbol = &p_parent->children[i];
|
|
|
+ if (!parameter_symbol->detail.empty() && parameter_symbol->name == symbol_identifier) {
|
|
|
+ return parameter_symbol;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
+const lsp::DocumentSymbol *GDScriptWorkspace::get_local_symbol(const ExtendGDScriptParser *p_parser, const String &p_symbol_identifier) {
|
|
|
+ const lsp::DocumentSymbol *class_symbol = &p_parser->get_symbols();
|
|
|
+
|
|
|
+ for (int i = 0; i < class_symbol->children.size(); ++i) {
|
|
|
+ if (class_symbol->children[i].kind == lsp::SymbolKind::Function || class_symbol->children[i].kind == lsp::SymbolKind::Class) {
|
|
|
+ const lsp::DocumentSymbol *function_symbol = &class_symbol->children[i];
|
|
|
+
|
|
|
+ for (int l = 0; l < function_symbol->children.size(); ++l) {
|
|
|
+ const lsp::DocumentSymbol *local = &function_symbol->children[l];
|
|
|
+ if (!local->detail.empty() && local->name == p_symbol_identifier) {
|
|
|
+ return local;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
void GDScriptWorkspace::reload_all_workspace_scripts() {
|
|
|
List<String> paths;
|
|
|
list_script_files("res://", paths);
|
|
@@ -347,6 +377,50 @@ Error GDScriptWorkspace::parse_script(const String &p_path, const String &p_cont
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+Dictionary GDScriptWorkspace::rename(const lsp::TextDocumentPositionParams &p_doc_pos, const String &new_name) {
|
|
|
+ Error err;
|
|
|
+ String path = get_file_path(p_doc_pos.textDocument.uri);
|
|
|
+
|
|
|
+ lsp::WorkspaceEdit edit;
|
|
|
+
|
|
|
+ List<String> paths;
|
|
|
+ list_script_files("res://", paths);
|
|
|
+
|
|
|
+ const lsp::DocumentSymbol *reference_symbol = resolve_symbol(p_doc_pos);
|
|
|
+ if (reference_symbol) {
|
|
|
+ String identifier = reference_symbol->name;
|
|
|
+
|
|
|
+ for (List<String>::Element *PE = paths.front(); PE; PE = PE->next()) {
|
|
|
+ Vector<String> content = FileAccess::get_file_as_string(PE->get(), &err).split("\n");
|
|
|
+ for (int i = 0; i < content.size(); ++i) {
|
|
|
+ String line = content[i];
|
|
|
+
|
|
|
+ int character = line.find(identifier);
|
|
|
+ while (character > -1) {
|
|
|
+ lsp::TextDocumentPositionParams params;
|
|
|
+
|
|
|
+ lsp::TextDocumentIdentifier text_doc;
|
|
|
+ text_doc.uri = get_file_uri(PE->get());
|
|
|
+
|
|
|
+ params.textDocument = text_doc;
|
|
|
+ params.position.line = i;
|
|
|
+ params.position.character = character;
|
|
|
+
|
|
|
+ const lsp::DocumentSymbol *other_symbol = resolve_symbol(params);
|
|
|
+
|
|
|
+ if (other_symbol == reference_symbol) {
|
|
|
+ edit.add_change(text_doc.uri, i, character, character + identifier.length(), new_name);
|
|
|
+ }
|
|
|
+
|
|
|
+ character = line.find(identifier, character + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return edit.to_json();
|
|
|
+}
|
|
|
+
|
|
|
Error GDScriptWorkspace::parse_local_script(const String &p_path) {
|
|
|
Error err;
|
|
|
String content = FileAccess::get_file_as_string(p_path, &err);
|
|
@@ -477,6 +551,10 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
|
|
|
|
|
|
if (const ExtendGDScriptParser *target_parser = get_parse_result(target_script_path)) {
|
|
|
symbol = target_parser->get_symbol_defined_at_line(LINE_NUMBER_TO_INDEX(ret.location));
|
|
|
+
|
|
|
+ if (symbol && symbol->kind == lsp::SymbolKind::Function && symbol->name != symbol_identifier) {
|
|
|
+ symbol = get_parameter_symbol(symbol, symbol_identifier);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
} else {
|
|
@@ -488,6 +566,10 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
|
|
|
}
|
|
|
} else {
|
|
|
symbol = parser->get_member_symbol(symbol_identifier);
|
|
|
+
|
|
|
+ if (!symbol) {
|
|
|
+ symbol = get_local_symbol(parser, symbol_identifier);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|