@@ -1048,7 +1048,7 @@ static void _find_global_enums(HashMap<String, ScriptLanguage::CodeCompletionOpt
10481048 }
10491049}
10501050
1051- static void _list_available_types (bool p_inherit_only, GDScriptParser::CompletionContext &p_context, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) {
1051+ static void _list_available_types (bool p_inherit_only, bool p_include_trait, GDScriptParser::CompletionContext &p_context, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) {
10521052 // Built-in Variant Types
10531053 _find_built_in_variants (r_result, true );
10541054
@@ -1084,6 +1084,12 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio
10841084 ScriptLanguage::CodeCompletionOption option (member.m_class ->identifier ->name , ScriptLanguage::CODE_COMPLETION_KIND_CLASS, ScriptLanguage::LOCATION_LOCAL + location_offset);
10851085 r_result.insert (option.display , option);
10861086 } break ;
1087+ case GDScriptParser::ClassNode::Member::TRAIT: {
1088+ if (p_include_trait) {
1089+ ScriptLanguage::CodeCompletionOption option (member.m_class ->identifier ->name , ScriptLanguage::CODE_COMPLETION_KIND_CLASS, ScriptLanguage::LOCATION_LOCAL + location_offset);
1090+ r_result.insert (option.display , option);
1091+ }
1092+ } break ;
10871093 case GDScriptParser::ClassNode::Member::ENUM: {
10881094 if (!p_inherit_only) {
10891095 ScriptLanguage::CodeCompletionOption option (member.m_enum ->identifier ->name , ScriptLanguage::CODE_COMPLETION_KIND_ENUM, ScriptLanguage::LOCATION_LOCAL + location_offset);
@@ -1181,6 +1187,7 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class,
11811187 option.default_value = member.constant ->initializer ->reduced_value ;
11821188 }
11831189 break ;
1190+ case GDScriptParser::ClassNode::Member::TRAIT:
11841191 case GDScriptParser::ClassNode::Member::CLASS:
11851192 if (p_only_functions) {
11861193 continue ;
@@ -1261,6 +1268,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
12611268
12621269 while (!base_type.has_no_type ()) {
12631270 switch (base_type.kind ) {
1271+ case GDScriptParser::DataType::TRAIT:
12641272 case GDScriptParser::DataType::CLASS: {
12651273 _find_identifiers_in_class (base_type.class_type , p_only_functions, p_types_only, base_type.is_meta_type , false , p_add_braces, r_result, p_recursion_depth);
12661274 // This already finds all parent identifiers, so we are done.
@@ -1565,7 +1573,7 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context
15651573 }
15661574
15671575 static const char *_keywords_with_space[] = {
1568- " and" , " not" , " or" , " in" , " as" , " class" , " class_name" , " extends" , " is" , " func" , " signal" , " await" ,
1576+ " and" , " not" , " or" , " in" , " as" , " class" , " class_name" , " trait " , " extends" , " uses " , " is" , " func" , " signal" , " await" ,
15691577 " const" , " enum" , " static" , " var" , " if" , " elif" , " else" , " for" , " match" , " when" , " while" ,
15701578 nullptr
15711579 };
@@ -1892,6 +1900,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
18921900 r_type = _type_from_variant (p_expression->reduced_value , p_context);
18931901 switch (p_expression->get_datatype ().kind ) {
18941902 case GDScriptParser::DataType::ENUM:
1903+ case GDScriptParser::DataType::TRAIT:
18951904 case GDScriptParser::DataType::CLASS:
18961905 r_type.type = p_expression->get_datatype ();
18971906 break ;
@@ -2256,7 +2265,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
22562265 }
22572266
22582267 // If the found type was not fully analyzed we analyze it now.
2259- if (found && r_type.type .kind == GDScriptParser::DataType::CLASS && !r_type.type .class_type ->resolved_body ) {
2268+ if (found && ( r_type.type .kind == GDScriptParser::DataType::CLASS || r_type. type . kind == GDScriptParser::DataType::TRAIT) && !r_type.type .class_type ->resolved_body ) {
22602269 Error err;
22612270 Ref<GDScriptParserRef> r = GDScriptCache::get_parser (r_type.type .script_path , GDScriptParserRef::FULLY_SOLVED, err);
22622271 }
@@ -2294,6 +2303,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
22942303 case GDScriptParser::IdentifierNode::MEMBER_CONSTANT:
22952304 case GDScriptParser::IdentifierNode::MEMBER_FUNCTION:
22962305 case GDScriptParser::IdentifierNode::MEMBER_SIGNAL:
2306+ case GDScriptParser::IdentifierNode::MEMBER_TRAIT:
22972307 case GDScriptParser::IdentifierNode::MEMBER_CLASS:
22982308 case GDScriptParser::IdentifierNode::INHERITED_VARIABLE:
22992309 case GDScriptParser::IdentifierNode::STATIC_VARIABLE:
@@ -2419,6 +2429,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
24192429 GDScriptParser::DataType base_type = p_context.current_class ->base_type ;
24202430 while (base_type.is_set ()) {
24212431 switch (base_type.kind ) {
2432+ case GDScriptParser::DataType::TRAIT:
24222433 case GDScriptParser::DataType::CLASS:
24232434 if (base_type.class_type ->has_function (p_context.current_function ->identifier ->name )) {
24242435 GDScriptParser::FunctionNode *parent_function = base_type.class_type ->get_member (p_context.current_function ->identifier ->name ).function ;
@@ -2530,6 +2541,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
25302541 bool is_static = base_type.is_meta_type ;
25312542 while (base_type.is_set ()) {
25322543 switch (base_type.kind ) {
2544+ case GDScriptParser::DataType::TRAIT:
25332545 case GDScriptParser::DataType::CLASS:
25342546 if (base_type.class_type ->has_member (p_identifier)) {
25352547 const GDScriptParser::ClassNode::Member &member = base_type.class_type ->get_member (p_identifier);
@@ -2590,6 +2602,12 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
25902602 }
25912603 r_type = _callable_type_from_method_info (member.function ->info );
25922604 return true ;
2605+ case GDScriptParser::ClassNode::Member::TRAIT:
2606+ r_type.type .type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
2607+ r_type.type .kind = GDScriptParser::DataType::TRAIT;
2608+ r_type.type .class_type = member.m_class ;
2609+ r_type.type .is_meta_type = true ;
2610+ return true ;
25932611 case GDScriptParser::ClassNode::Member::CLASS:
25942612 r_type.type .type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
25952613 r_type.type .kind = GDScriptParser::DataType::CLASS;
@@ -2788,6 +2806,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex
27882806
27892807 while (base_type.is_set () && !base_type.is_variant ()) {
27902808 switch (base_type.kind ) {
2809+ case GDScriptParser::DataType::TRAIT:
27912810 case GDScriptParser::DataType::CLASS:
27922811 if (base_type.class_type ->has_function (p_method)) {
27932812 GDScriptParser::FunctionNode *method = base_type.class_type ->get_member (p_method).function ;
@@ -2941,6 +2960,7 @@ static void _list_call_arguments(GDScriptParser::CompletionContext &p_context, c
29412960
29422961 while (base_type.is_set () && !base_type.is_variant ()) {
29432962 switch (base_type.kind ) {
2963+ case GDScriptParser::DataType::TRAIT:
29442964 case GDScriptParser::DataType::CLASS: {
29452965 if (base_type.is_meta_type && method == SNAME (" new" )) {
29462966 const GDScriptParser::ClassNode *current = base_type.class_type ;
@@ -3085,6 +3105,7 @@ static void _list_call_arguments(GDScriptParser::CompletionContext &p_context, c
30853105 n++;
30863106 }
30873107 } break ;
3108+ case GDScriptParser::DataType::TRAIT:
30883109 case GDScriptParser::DataType::CLASS: {
30893110 GDScriptParser::ClassNode *clss = tweened_object->datatype .class_type ;
30903111 native_type = clss->base_type .native_type ;
@@ -3510,7 +3531,30 @@ ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_pa
35103531 }
35113532 } break ;
35123533 case GDScriptParser::COMPLETION_INHERIT_TYPE: {
3513- _list_available_types (true , completion_context, options);
3534+ _list_available_types (true , false , completion_context, options);
3535+ r_forced = true ;
3536+ } break ;
3537+ case GDScriptParser::COMPLETION_USES_TYPE: {
3538+ const GDScriptParser::ClassNode *current = completion_context.current_class ;
3539+ for (const GDScriptParser::ClassNode::Member &member : current->members ) {
3540+ switch (member.type ) {
3541+ case GDScriptParser::ClassNode::Member::TRAIT:
3542+ case GDScriptParser::ClassNode::Member::CLASS:
3543+ if (member.m_class && member.m_class ->identifier ) {
3544+ ScriptLanguage::CodeCompletionOption option (member.m_class ->identifier ->name , ScriptLanguage::CODE_COMPLETION_KIND_CLASS, ScriptLanguage::LOCATION_LOCAL);
3545+ options.insert (option.display , option);
3546+ }
3547+ break ;
3548+ default :
3549+ break ;
3550+ }
3551+ }
3552+ LocalVector<StringName> global_classes;
3553+ ScriptServer::get_global_class_list (global_classes);
3554+ for (const StringName &E : global_classes) {
3555+ ScriptLanguage::CodeCompletionOption option (E, ScriptLanguage::CODE_COMPLETION_KIND_CLASS, ScriptLanguage::LOCATION_OTHER_USER_CODE);
3556+ options.insert (option.display , option);
3557+ }
35143558 r_forced = true ;
35153559 } break ;
35163560 case GDScriptParser::COMPLETION_TYPE_NAME_OR_VOID: {
@@ -3519,11 +3563,11 @@ ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_pa
35193563 }
35203564 [[fallthrough]];
35213565 case GDScriptParser::COMPLETION_TYPE_NAME: {
3522- _list_available_types (false , completion_context, options);
3566+ _list_available_types (false , true , completion_context, options);
35233567 r_forced = true ;
35243568 } break ;
35253569 case GDScriptParser::COMPLETION_PROPERTY_DECLARATION_OR_TYPE: {
3526- _list_available_types (false , completion_context, options);
3570+ _list_available_types (false , false , completion_context, options);
35273571 ScriptLanguage::CodeCompletionOption get (" get" , ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
35283572 options.insert (get.display , get);
35293573 ScriptLanguage::CodeCompletionOption set (" set" , ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
@@ -3933,6 +3977,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
39333977
39343978 while (true ) {
39353979 switch (base_type.kind ) {
3980+ case GDScriptParser::DataType::TRAIT:
39363981 case GDScriptParser::DataType::CLASS: {
39373982 ERR_FAIL_NULL_V (base_type.class_type , ERR_BUG);
39383983
@@ -3952,6 +3997,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
39523997 case GDScriptParser::ClassNode::Member::UNDEFINED:
39533998 case GDScriptParser::ClassNode::Member::GROUP:
39543999 return ERR_BUG;
4000+ case GDScriptParser::ClassNode::Member::TRAIT:
39554001 case GDScriptParser::ClassNode::Member::CLASS: {
39564002 String doc_type_name;
39574003 String doc_enum_name;
@@ -4580,7 +4626,7 @@ ::Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symb
45804626 }
45814627 prev = E;
45824628 }
4583- if (base_type.kind != GDScriptParser::DataType::CLASS) {
4629+ if (base_type.kind != GDScriptParser::DataType::CLASS && base_type. kind != GDScriptParser::DataType::TRAIT ) {
45844630 GDScriptCompletionIdentifier base;
45854631 if (!_guess_expression_type (context, prev, base)) {
45864632 break ;
0 commit comments