Fix completion popup for the variables created with `get_node` call
This commit is contained in:
parent
315c64282b
commit
65d14679e7
|
@ -2511,6 +2511,57 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, const GDScriptParser::SubscriptNode *p_subscript, GDScriptParser::DataType &r_base_type, Variant *r_base = nullptr) {
|
||||||
|
if (p_subscript->base->type == GDScriptParser::Node::IDENTIFIER) {
|
||||||
|
const GDScriptParser::GetNodeNode *get_node = nullptr;
|
||||||
|
const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(p_subscript->base);
|
||||||
|
|
||||||
|
switch (identifier_node->source) {
|
||||||
|
case GDScriptParser::IdentifierNode::Source::MEMBER_VARIABLE: {
|
||||||
|
if (p_context.current_class != nullptr) {
|
||||||
|
const StringName &member_name = identifier_node->name;
|
||||||
|
const GDScriptParser::ClassNode *current_class = p_context.current_class;
|
||||||
|
|
||||||
|
if (current_class->has_member(member_name)) {
|
||||||
|
const GDScriptParser::ClassNode::Member &member = current_class->get_member(member_name);
|
||||||
|
|
||||||
|
if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) {
|
||||||
|
const GDScriptParser::VariableNode *variable = static_cast<GDScriptParser::VariableNode *>(member.variable);
|
||||||
|
|
||||||
|
if (variable->initializer && variable->initializer->type == GDScriptParser::Node::GET_NODE) {
|
||||||
|
get_node = static_cast<GDScriptParser::GetNodeNode *>(variable->initializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case GDScriptParser::IdentifierNode::Source::LOCAL_VARIABLE: {
|
||||||
|
if (identifier_node->next != nullptr && identifier_node->next->type == GDScriptParser::ClassNode::Node::GET_NODE) {
|
||||||
|
get_node = static_cast<GDScriptParser::GetNodeNode *>(identifier_node->next);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_node != nullptr) {
|
||||||
|
const Object *node = p_context.base->call("get_node_or_null", NodePath(get_node->full_path));
|
||||||
|
if (node != nullptr) {
|
||||||
|
if (r_base != nullptr) {
|
||||||
|
*r_base = node;
|
||||||
|
}
|
||||||
|
r_base_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
||||||
|
r_base_type.kind = GDScriptParser::DataType::NATIVE;
|
||||||
|
r_base_type.native_type = node->get_class_name();
|
||||||
|
r_base_type.builtin_type = Variant::OBJECT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, const GDScriptParser::Node *p_call, int p_argidx, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) {
|
static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, const GDScriptParser::Node *p_call, int p_argidx, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) {
|
||||||
if (p_call->type == GDScriptParser::Node::PRELOAD) {
|
if (p_call->type == GDScriptParser::Node::PRELOAD) {
|
||||||
if (p_argidx == 0 && bool(EDITOR_GET("text_editor/completion/complete_file_paths"))) {
|
if (p_argidx == 0 && bool(EDITOR_GET("text_editor/completion/complete_file_paths"))) {
|
||||||
|
@ -2561,13 +2612,17 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subscript->is_attribute) {
|
if (p_context.base != nullptr && subscript->is_attribute) {
|
||||||
GDScriptCompletionIdentifier ci;
|
bool found_type = _get_subscript_type(p_context, subscript, base_type, &base);
|
||||||
if (_guess_expression_type(p_context, subscript->base, ci)) {
|
|
||||||
base_type = ci.type;
|
if (!found_type) {
|
||||||
base = ci.value;
|
GDScriptCompletionIdentifier ci;
|
||||||
} else {
|
if (_guess_expression_type(p_context, subscript->base, ci)) {
|
||||||
return;
|
base_type = ci.type;
|
||||||
|
base = ci.value;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_static = base_type.is_meta_type;
|
_static = base_type.is_meta_type;
|
||||||
|
@ -2765,60 +2820,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
||||||
const GDScriptParser::SubscriptNode *attr = static_cast<const GDScriptParser::SubscriptNode *>(completion_context.node);
|
const GDScriptParser::SubscriptNode *attr = static_cast<const GDScriptParser::SubscriptNode *>(completion_context.node);
|
||||||
if (attr->base) {
|
if (attr->base) {
|
||||||
GDScriptCompletionIdentifier base;
|
GDScriptCompletionIdentifier base;
|
||||||
bool found_type = false;
|
bool found_type = _get_subscript_type(completion_context, attr, base.type);
|
||||||
|
|
||||||
if (p_owner != nullptr && attr->base->type == GDScriptParser::Node::IDENTIFIER) {
|
|
||||||
const GDScriptParser::GetNodeNode *get_node = nullptr;
|
|
||||||
const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(attr->base);
|
|
||||||
|
|
||||||
switch (identifier_node->source) {
|
|
||||||
case GDScriptParser::IdentifierNode::Source::MEMBER_VARIABLE: {
|
|
||||||
if (completion_context.current_class != nullptr) {
|
|
||||||
const StringName &member_name = identifier_node->name;
|
|
||||||
const GDScriptParser::ClassNode *current_class = completion_context.current_class;
|
|
||||||
|
|
||||||
if (current_class->has_member(member_name)) {
|
|
||||||
const GDScriptParser::ClassNode::Member &member = current_class->get_member(member_name);
|
|
||||||
|
|
||||||
if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) {
|
|
||||||
const GDScriptParser::VariableNode *variable = static_cast<GDScriptParser::VariableNode *>(member.variable);
|
|
||||||
|
|
||||||
if (variable->initializer && variable->initializer->type == GDScriptParser::Node::GET_NODE) {
|
|
||||||
get_node = static_cast<GDScriptParser::GetNodeNode *>(variable->initializer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case GDScriptParser::IdentifierNode::Source::LOCAL_VARIABLE: {
|
|
||||||
if (identifier_node->next != nullptr && identifier_node->next->type == GDScriptParser::ClassNode::Node::GET_NODE) {
|
|
||||||
get_node = static_cast<GDScriptParser::GetNodeNode *>(identifier_node->next);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_node != nullptr) {
|
|
||||||
const Object *node = p_owner->call("get_node_or_null", NodePath(get_node->full_path));
|
|
||||||
if (node != nullptr) {
|
|
||||||
found_type = true;
|
|
||||||
|
|
||||||
GDScriptParser::DataType type;
|
|
||||||
type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
|
|
||||||
type.kind = GDScriptParser::DataType::NATIVE;
|
|
||||||
type.native_type = node->get_class_name();
|
|
||||||
type.builtin_type = Variant::OBJECT;
|
|
||||||
|
|
||||||
base.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_type) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_type && !_guess_expression_type(completion_context, attr->base, base)) {
|
if (!found_type && !_guess_expression_type(completion_context, attr->base, base)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue