| 800 | } |
| 801 | |
| 802 | GDScriptParser::ClassNode *GDScriptParser::find_class(const String &p_qualified_name) const { |
| 803 | String first = p_qualified_name.get_slice("::", 0); |
| 804 | |
| 805 | Vector<String> class_names; |
| 806 | GDScriptParser::ClassNode *result = nullptr; |
| 807 | // Empty initial name means start at the head. |
| 808 | if (first.is_empty() || (head->identifier && first == head->identifier->name)) { |
| 809 | class_names = p_qualified_name.split("::"); |
| 810 | result = head; |
| 811 | } else if (p_qualified_name.begins_with(script_path)) { |
| 812 | // Script path could have a class path separator("::") in it. |
| 813 | class_names = p_qualified_name.trim_prefix(script_path).split("::"); |
| 814 | result = head; |
| 815 | } else if (head->has_member(first)) { |
| 816 | class_names = p_qualified_name.split("::"); |
| 817 | GDScriptParser::ClassNode::Member member = head->get_member(first); |
| 818 | if (member.type == GDScriptParser::ClassNode::Member::CLASS) { |
| 819 | result = member.m_class; |
| 820 | } |
| 821 | } |
| 822 | |
| 823 | // Starts at index 1 because index 0 was handled above. |
| 824 | for (int i = 1; result != nullptr && i < class_names.size(); i++) { |
| 825 | const String ¤t_name = class_names[i]; |
| 826 | GDScriptParser::ClassNode *next = nullptr; |
| 827 | if (result->has_member(current_name)) { |
| 828 | GDScriptParser::ClassNode::Member member = result->get_member(current_name); |
| 829 | if (member.type == GDScriptParser::ClassNode::Member::CLASS) { |
| 830 | next = member.m_class; |
| 831 | } |
| 832 | } |
| 833 | result = next; |
| 834 | } |
| 835 | |
| 836 | return result; |
| 837 | } |
| 838 | |
| 839 | bool GDScriptParser::has_class(const GDScriptParser::ClassNode *p_class) const { |
| 840 | if (head->fqcn.is_empty() && p_class->fqcn.get_slice("::", 0).is_empty()) { |
no test coverage detected