|
@@ -636,19 +636,6 @@ static int _get_method_location(const StringName &p_class, const StringName &p_m
|
|
return depth | ScriptLanguage::LOCATION_PARENT_MASK;
|
|
return depth | ScriptLanguage::LOCATION_PARENT_MASK;
|
|
}
|
|
}
|
|
|
|
|
|
-static int _get_method_location(Ref<Script> p_script, const StringName &p_method) {
|
|
|
|
- int depth = 0;
|
|
|
|
- Ref<Script> scr = p_script;
|
|
|
|
- while (scr.is_valid()) {
|
|
|
|
- if (scr->get_member_line(p_method) != -1) {
|
|
|
|
- return depth | ScriptLanguage::LOCATION_PARENT_MASK;
|
|
|
|
- }
|
|
|
|
- depth++;
|
|
|
|
- scr = scr->get_base_script();
|
|
|
|
- }
|
|
|
|
- return depth + _get_method_location(p_script->get_instance_base_type(), p_method);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static int _get_enum_constant_location(const StringName &p_class, const StringName &p_enum_constant) {
|
|
static int _get_enum_constant_location(const StringName &p_class, const StringName &p_enum_constant) {
|
|
if (!ClassDB::get_integer_constant_enum(p_class, p_enum_constant)) {
|
|
if (!ClassDB::get_integer_constant_enum(p_class, p_enum_constant)) {
|
|
return ScriptLanguage::LOCATION_OTHER;
|
|
return ScriptLanguage::LOCATION_OTHER;
|
|
@@ -1020,9 +1007,9 @@ static void _find_identifiers_in_suite(const GDScriptParser::SuiteNode *p_suite,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base, bool p_only_functions, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, int p_recursion_depth);
|
|
|
|
|
|
+static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base, bool p_only_functions, bool p_types_only, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, int p_recursion_depth);
|
|
|
|
|
|
-static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class, bool p_only_functions, bool p_static, bool p_parent_only, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, int p_recursion_depth) {
|
|
|
|
|
|
+static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class, bool p_only_functions, bool p_types_only, bool p_static, bool p_parent_only, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, int p_recursion_depth) {
|
|
ERR_FAIL_COND(p_recursion_depth > COMPLETION_RECURSION_LIMIT);
|
|
ERR_FAIL_COND(p_recursion_depth > COMPLETION_RECURSION_LIMIT);
|
|
|
|
|
|
if (!p_parent_only) {
|
|
if (!p_parent_only) {
|
|
@@ -1036,13 +1023,13 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
|
|
ScriptLanguage::CodeCompletionOption option;
|
|
ScriptLanguage::CodeCompletionOption option;
|
|
switch (member.type) {
|
|
switch (member.type) {
|
|
case GDScriptParser::ClassNode::Member::VARIABLE:
|
|
case GDScriptParser::ClassNode::Member::VARIABLE:
|
|
- if (p_only_functions || outer || (p_static && !member.variable->is_static)) {
|
|
|
|
|
|
+ if (p_types_only || p_only_functions || outer || (p_static && !member.variable->is_static)) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
option = ScriptLanguage::CodeCompletionOption(member.variable->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, location);
|
|
option = ScriptLanguage::CodeCompletionOption(member.variable->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, location);
|
|
break;
|
|
break;
|
|
case GDScriptParser::ClassNode::Member::CONSTANT:
|
|
case GDScriptParser::ClassNode::Member::CONSTANT:
|
|
- if (p_only_functions) {
|
|
|
|
|
|
+ if (p_types_only || p_only_functions) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
if (r_result.has(member.constant->identifier->name)) {
|
|
if (r_result.has(member.constant->identifier->name)) {
|
|
@@ -1060,7 +1047,7 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
|
|
option = ScriptLanguage::CodeCompletionOption(member.m_class->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_CLASS, location);
|
|
option = ScriptLanguage::CodeCompletionOption(member.m_class->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_CLASS, location);
|
|
break;
|
|
break;
|
|
case GDScriptParser::ClassNode::Member::ENUM_VALUE:
|
|
case GDScriptParser::ClassNode::Member::ENUM_VALUE:
|
|
- if (p_only_functions) {
|
|
|
|
|
|
+ if (p_types_only || p_only_functions) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
option = ScriptLanguage::CodeCompletionOption(member.enum_value.identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, location);
|
|
option = ScriptLanguage::CodeCompletionOption(member.enum_value.identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, location);
|
|
@@ -1072,7 +1059,7 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
|
|
option = ScriptLanguage::CodeCompletionOption(member.m_enum->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_ENUM, location);
|
|
option = ScriptLanguage::CodeCompletionOption(member.m_enum->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_ENUM, location);
|
|
break;
|
|
break;
|
|
case GDScriptParser::ClassNode::Member::FUNCTION:
|
|
case GDScriptParser::ClassNode::Member::FUNCTION:
|
|
- if (outer || (p_static && !member.function->is_static) || member.function->identifier->name.operator String().begins_with("@")) {
|
|
|
|
|
|
+ if (p_types_only || outer || (p_static && !member.function->is_static) || member.function->identifier->name.operator String().begins_with("@")) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
option = ScriptLanguage::CodeCompletionOption(member.function->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION, location);
|
|
option = ScriptLanguage::CodeCompletionOption(member.function->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION, location);
|
|
@@ -1083,7 +1070,7 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case GDScriptParser::ClassNode::Member::SIGNAL:
|
|
case GDScriptParser::ClassNode::Member::SIGNAL:
|
|
- if (p_only_functions || outer || p_static) {
|
|
|
|
|
|
+ if (p_types_only || p_only_functions || outer || p_static) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
option = ScriptLanguage::CodeCompletionOption(member.signal->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_SIGNAL, location);
|
|
option = ScriptLanguage::CodeCompletionOption(member.signal->identifier->name, ScriptLanguage::CODE_COMPLETION_KIND_SIGNAL, location);
|
|
@@ -1095,6 +1082,10 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
|
|
}
|
|
}
|
|
r_result.insert(option.display, option);
|
|
r_result.insert(option.display, option);
|
|
}
|
|
}
|
|
|
|
+ if (p_types_only) {
|
|
|
|
+ break; // Otherwise, it will fill the results with types from the outer class (which is undesired for that case).
|
|
|
|
+ }
|
|
|
|
+
|
|
outer = true;
|
|
outer = true;
|
|
clss = clss->outer;
|
|
clss = clss->outer;
|
|
classes_processed++;
|
|
classes_processed++;
|
|
@@ -1106,15 +1097,15 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
|
|
base_type.type = p_class->base_type;
|
|
base_type.type = p_class->base_type;
|
|
base_type.type.is_meta_type = p_static;
|
|
base_type.type.is_meta_type = p_static;
|
|
|
|
|
|
- _find_identifiers_in_base(base_type, p_only_functions, r_result, p_recursion_depth + 1);
|
|
|
|
|
|
+ _find_identifiers_in_base(base_type, p_only_functions, p_types_only, r_result, p_recursion_depth + 1);
|
|
}
|
|
}
|
|
|
|
|
|
-static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base, bool p_only_functions, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, int p_recursion_depth) {
|
|
|
|
|
|
+static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base, bool p_only_functions, bool p_types_only, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, int p_recursion_depth) {
|
|
ERR_FAIL_COND(p_recursion_depth > COMPLETION_RECURSION_LIMIT);
|
|
ERR_FAIL_COND(p_recursion_depth > COMPLETION_RECURSION_LIMIT);
|
|
|
|
|
|
GDScriptParser::DataType base_type = p_base.type;
|
|
GDScriptParser::DataType base_type = p_base.type;
|
|
|
|
|
|
- if (base_type.is_meta_type && base_type.kind != GDScriptParser::DataType::BUILTIN && base_type.kind != GDScriptParser::DataType::ENUM) {
|
|
|
|
|
|
+ if (!p_types_only && base_type.is_meta_type && base_type.kind != GDScriptParser::DataType::BUILTIN && base_type.kind != GDScriptParser::DataType::ENUM) {
|
|
ScriptLanguage::CodeCompletionOption option("new", ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION, ScriptLanguage::LOCATION_LOCAL);
|
|
ScriptLanguage::CodeCompletionOption option("new", ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION, ScriptLanguage::LOCATION_LOCAL);
|
|
option.insert_text += "(";
|
|
option.insert_text += "(";
|
|
r_result.insert(option.display, option);
|
|
r_result.insert(option.display, option);
|
|
@@ -1123,14 +1114,16 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
|
|
while (!base_type.has_no_type()) {
|
|
while (!base_type.has_no_type()) {
|
|
switch (base_type.kind) {
|
|
switch (base_type.kind) {
|
|
case GDScriptParser::DataType::CLASS: {
|
|
case GDScriptParser::DataType::CLASS: {
|
|
- _find_identifiers_in_class(base_type.class_type, p_only_functions, base_type.is_meta_type, false, r_result, p_recursion_depth);
|
|
|
|
|
|
+ _find_identifiers_in_class(base_type.class_type, p_only_functions, p_types_only, base_type.is_meta_type, false, r_result, p_recursion_depth);
|
|
// This already finds all parent identifiers, so we are done.
|
|
// This already finds all parent identifiers, so we are done.
|
|
base_type = GDScriptParser::DataType();
|
|
base_type = GDScriptParser::DataType();
|
|
} break;
|
|
} break;
|
|
case GDScriptParser::DataType::SCRIPT: {
|
|
case GDScriptParser::DataType::SCRIPT: {
|
|
Ref<Script> scr = base_type.script_type;
|
|
Ref<Script> scr = base_type.script_type;
|
|
if (scr.is_valid()) {
|
|
if (scr.is_valid()) {
|
|
- if (!p_only_functions) {
|
|
|
|
|
|
+ if (p_types_only) {
|
|
|
|
+ // TODO: Need to implement Script::get_script_enum_list and retrieve the enum list from a script.
|
|
|
|
+ } else if (!p_only_functions) {
|
|
if (!base_type.is_meta_type) {
|
|
if (!base_type.is_meta_type) {
|
|
List<PropertyInfo> members;
|
|
List<PropertyInfo> members;
|
|
scr->get_script_property_list(&members);
|
|
scr->get_script_property_list(&members);
|
|
@@ -1163,20 +1156,22 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- List<MethodInfo> methods;
|
|
|
|
- scr->get_script_method_list(&methods);
|
|
|
|
- for (const MethodInfo &E : methods) {
|
|
|
|
- if (E.name.begins_with("@")) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- int location = p_recursion_depth + _get_method_location(scr, E.name);
|
|
|
|
- ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION, location);
|
|
|
|
- if (E.arguments.size()) {
|
|
|
|
- option.insert_text += "(";
|
|
|
|
- } else {
|
|
|
|
- option.insert_text += "()";
|
|
|
|
|
|
+ if (!p_types_only) {
|
|
|
|
+ List<MethodInfo> methods;
|
|
|
|
+ scr->get_script_method_list(&methods);
|
|
|
|
+ for (const MethodInfo &E : methods) {
|
|
|
|
+ if (E.name.begins_with("@")) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ int location = p_recursion_depth + _get_method_location(scr->get_class_name(), E.name);
|
|
|
|
+ ScriptLanguage::CodeCompletionOption option(E.name, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION, location);
|
|
|
|
+ if (E.arguments.size()) {
|
|
|
|
+ option.insert_text += "(";
|
|
|
|
+ } else {
|
|
|
|
+ option.insert_text += "()";
|
|
|
|
+ }
|
|
|
|
+ r_result.insert(option.display, option);
|
|
}
|
|
}
|
|
- r_result.insert(option.display, option);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
Ref<Script> base_script = scr->get_base_script();
|
|
Ref<Script> base_script = scr->get_base_script();
|
|
@@ -1197,6 +1192,16 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (p_types_only) {
|
|
|
|
+ List<StringName> enums;
|
|
|
|
+ ClassDB::get_enum_list(type, &enums);
|
|
|
|
+ for (const StringName &E : enums) {
|
|
|
|
+ ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_ENUM);
|
|
|
|
+ r_result.insert(option.display, option);
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!p_only_functions) {
|
|
if (!p_only_functions) {
|
|
List<String> constants;
|
|
List<String> constants;
|
|
ClassDB::get_integer_constant_list(type, &constants);
|
|
ClassDB::get_integer_constant_list(type, &constants);
|
|
@@ -1255,6 +1260,10 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
|
|
} break;
|
|
} break;
|
|
case GDScriptParser::DataType::ENUM:
|
|
case GDScriptParser::DataType::ENUM:
|
|
case GDScriptParser::DataType::BUILTIN: {
|
|
case GDScriptParser::DataType::BUILTIN: {
|
|
|
|
+ if (p_types_only) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
Callable::CallError err;
|
|
Callable::CallError err;
|
|
Variant tmp;
|
|
Variant tmp;
|
|
Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err);
|
|
Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err);
|
|
@@ -1322,7 +1331,7 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context
|
|
}
|
|
}
|
|
|
|
|
|
if (p_context.current_class) {
|
|
if (p_context.current_class) {
|
|
- _find_identifiers_in_class(p_context.current_class, p_only_functions, (!p_context.current_function || p_context.current_function->is_static), false, r_result, p_recursion_depth);
|
|
|
|
|
|
+ _find_identifiers_in_class(p_context.current_class, p_only_functions, false, (!p_context.current_function || p_context.current_function->is_static), false, r_result, p_recursion_depth);
|
|
}
|
|
}
|
|
|
|
|
|
List<StringName> functions;
|
|
List<StringName> functions;
|
|
@@ -3157,7 +3166,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- _find_identifiers_in_base(base, is_function, options, 0);
|
|
|
|
|
|
+ _find_identifiers_in_base(base, is_function, false, options, 0);
|
|
}
|
|
}
|
|
} break;
|
|
} break;
|
|
case GDScriptParser::COMPLETION_SUBSCRIPT: {
|
|
case GDScriptParser::COMPLETION_SUBSCRIPT: {
|
|
@@ -3167,7 +3176,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- _find_identifiers_in_base(base, false, options, 0);
|
|
|
|
|
|
+ _find_identifiers_in_base(base, false, false, options, 0);
|
|
} break;
|
|
} break;
|
|
case GDScriptParser::COMPLETION_TYPE_ATTRIBUTE: {
|
|
case GDScriptParser::COMPLETION_TYPE_ATTRIBUTE: {
|
|
if (!completion_context.current_class) {
|
|
if (!completion_context.current_class) {
|
|
@@ -3175,25 +3184,41 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
|
}
|
|
}
|
|
const GDScriptParser::TypeNode *type = static_cast<const GDScriptParser::TypeNode *>(completion_context.node);
|
|
const GDScriptParser::TypeNode *type = static_cast<const GDScriptParser::TypeNode *>(completion_context.node);
|
|
bool found = true;
|
|
bool found = true;
|
|
|
|
+
|
|
GDScriptCompletionIdentifier base;
|
|
GDScriptCompletionIdentifier base;
|
|
base.type.kind = GDScriptParser::DataType::CLASS;
|
|
base.type.kind = GDScriptParser::DataType::CLASS;
|
|
base.type.type_source = GDScriptParser::DataType::INFERRED;
|
|
base.type.type_source = GDScriptParser::DataType::INFERRED;
|
|
base.type.is_constant = true;
|
|
base.type.is_constant = true;
|
|
- base.type.class_type = completion_context.current_class;
|
|
|
|
- base.value = completion_context.base;
|
|
|
|
|
|
|
|
- for (int i = 0; i < completion_context.current_argument; i++) {
|
|
|
|
- GDScriptCompletionIdentifier ci;
|
|
|
|
- if (!_guess_identifier_type_from_base(completion_context, base, type->type_chain[i]->name, ci)) {
|
|
|
|
- found = false;
|
|
|
|
- break;
|
|
|
|
|
|
+ if (completion_context.current_argument == 1) {
|
|
|
|
+ StringName type_name = type->type_chain[0]->name;
|
|
|
|
+
|
|
|
|
+ if (ClassDB::class_exists(type_name)) {
|
|
|
|
+ base.type.kind = GDScriptParser::DataType::NATIVE;
|
|
|
|
+ base.type.native_type = type_name;
|
|
|
|
+ } else if (ScriptServer::is_global_class(type_name)) {
|
|
|
|
+ base.type.kind = GDScriptParser::DataType::SCRIPT;
|
|
|
|
+ String scr_path = ScriptServer::get_global_class_path(type_name);
|
|
|
|
+ base.type.script_type = ResourceLoader::load(scr_path);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (base.type.kind == GDScriptParser::DataType::CLASS) {
|
|
|
|
+ base.type.class_type = completion_context.current_class;
|
|
|
|
+ base.value = completion_context.base;
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < completion_context.current_argument; i++) {
|
|
|
|
+ GDScriptCompletionIdentifier ci;
|
|
|
|
+ if (!_guess_identifier_type_from_base(completion_context, base, type->type_chain[i]->name, ci)) {
|
|
|
|
+ found = false;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ base = ci;
|
|
}
|
|
}
|
|
- base = ci;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- // TODO: Improve this to only list types.
|
|
|
|
if (found) {
|
|
if (found) {
|
|
- _find_identifiers_in_base(base, false, options, 0);
|
|
|
|
|
|
+ _find_identifiers_in_base(base, false, true, options, 0);
|
|
}
|
|
}
|
|
r_forced = true;
|
|
r_forced = true;
|
|
} break;
|
|
} break;
|
|
@@ -3328,7 +3353,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
|
|
if (!completion_context.current_class) {
|
|
if (!completion_context.current_class) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- _find_identifiers_in_class(completion_context.current_class, true, false, true, options, 0);
|
|
|
|
|
|
+ _find_identifiers_in_class(completion_context.current_class, true, false, false, true, options, 0);
|
|
} break;
|
|
} break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3633,14 +3658,50 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
|
|
analyzer.analyze();
|
|
analyzer.analyze();
|
|
|
|
|
|
if (context.current_class && context.current_class->extends.size() > 0) {
|
|
if (context.current_class && context.current_class->extends.size() > 0) {
|
|
|
|
+ StringName class_name = context.current_class->extends[0]->name;
|
|
|
|
+
|
|
bool success = false;
|
|
bool success = false;
|
|
- ClassDB::get_integer_constant(context.current_class->extends[0]->name, p_symbol, &success);
|
|
|
|
|
|
+ ClassDB::get_integer_constant(class_name, p_symbol, &success);
|
|
if (success) {
|
|
if (success) {
|
|
r_result.type = ScriptLanguage::LOOKUP_RESULT_CLASS_CONSTANT;
|
|
r_result.type = ScriptLanguage::LOOKUP_RESULT_CLASS_CONSTANT;
|
|
- r_result.class_name = context.current_class->extends[0]->name;
|
|
|
|
|
|
+ r_result.class_name = class_name;
|
|
r_result.class_member = p_symbol;
|
|
r_result.class_member = p_symbol;
|
|
return OK;
|
|
return OK;
|
|
}
|
|
}
|
|
|
|
+ do {
|
|
|
|
+ List<StringName> enums;
|
|
|
|
+ ClassDB::get_enum_list(class_name, &enums, true);
|
|
|
|
+ for (const StringName &enum_name : enums) {
|
|
|
|
+ if (enum_name == p_symbol) {
|
|
|
|
+ r_result.type = ScriptLanguage::LOOKUP_RESULT_CLASS_ENUM;
|
|
|
|
+ r_result.class_name = class_name;
|
|
|
|
+ r_result.class_member = p_symbol;
|
|
|
|
+ return OK;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ class_name = ClassDB::get_parent_class_nocheck(class_name);
|
|
|
|
+ } while (class_name != StringName());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const GDScriptParser::TypeNode *type_node = dynamic_cast<const GDScriptParser::TypeNode *>(context.node);
|
|
|
|
+ if (type_node != nullptr && !type_node->type_chain.is_empty()) {
|
|
|
|
+ StringName class_name = type_node->type_chain[0]->name;
|
|
|
|
+ if (ScriptServer::is_global_class(class_name)) {
|
|
|
|
+ class_name = ScriptServer::get_global_class_native_base(class_name);
|
|
|
|
+ }
|
|
|
|
+ do {
|
|
|
|
+ List<StringName> enums;
|
|
|
|
+ ClassDB::get_enum_list(class_name, &enums, true);
|
|
|
|
+ for (const StringName &enum_name : enums) {
|
|
|
|
+ if (enum_name == p_symbol) {
|
|
|
|
+ r_result.type = ScriptLanguage::LOOKUP_RESULT_CLASS_ENUM;
|
|
|
|
+ r_result.class_name = class_name;
|
|
|
|
+ r_result.class_member = p_symbol;
|
|
|
|
+ return OK;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ class_name = ClassDB::get_parent_class_nocheck(class_name);
|
|
|
|
+ } while (class_name != StringName());
|
|
}
|
|
}
|
|
|
|
|
|
bool is_function = false;
|
|
bool is_function = false;
|