@@ -862,7 +862,8 @@ static void _get_directory_contents(EditorFileSystemDirectory *p_dir, HashMap<St
862862 }
863863}
864864
865- static void _find_annotation_arguments (const GDScriptParser::AnnotationNode *p_annotation, int p_argument, const String p_quote_style, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) {
865+ static void _find_annotation_arguments (const GDScriptParser::AnnotationNode *p_annotation, int p_argument, const String p_quote_style, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, String &r_arghint) {
866+ r_arghint = _make_arguments_hint (p_annotation->info ->info , p_argument, true );
866867 if (p_annotation->name == SNAME (" @export_range" )) {
867868 if (p_argument == 3 || p_argument == 4 || p_argument == 5 ) {
868869 // Slider hint.
@@ -2127,7 +2128,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
21272128 // Look in blocks first.
21282129 int last_assign_line = -1 ;
21292130 const GDScriptParser::ExpressionNode *last_assigned_expression = nullptr ;
2130- GDScriptParser::DataType id_type;
2131+ GDScriptCompletionIdentifier id_type;
21312132 GDScriptParser::SuiteNode *suite = p_context.current_suite ;
21322133 bool is_function_parameter = false ;
21332134
@@ -2149,7 +2150,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
21492150 if (can_be_local && suite && suite->has_local (p_identifier->name )) {
21502151 const GDScriptParser::SuiteNode::Local &local = suite->get_local (p_identifier->name );
21512152
2152- id_type = local.get_datatype ();
2153+ id_type. type = local.get_datatype ();
21532154
21542155 // Check initializer as the first assignment.
21552156 switch (local.type ) {
@@ -2187,7 +2188,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
21872188 base.type .is_meta_type = p_context.current_function && p_context.current_function ->is_static ;
21882189
21892190 if (_guess_identifier_type_from_base (p_context, base, p_identifier->name , base_identifier)) {
2190- id_type = base_identifier. type ;
2191+ id_type = base_identifier;
21912192 }
21922193 }
21932194 }
@@ -2227,7 +2228,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
22272228 c.current_line = type_test->operand ->start_line ;
22282229 c.current_suite = suite;
22292230 if (type_test->test_datatype .is_hard_type ()) {
2230- id_type = type_test->test_datatype ;
2231+ id_type. type = type_test->test_datatype ;
22312232 if (last_assign_line < c.current_line ) {
22322233 // Override last assignment.
22332234 last_assign_line = c.current_line ;
@@ -2245,10 +2246,10 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
22452246 c.current_line = last_assign_line;
22462247 GDScriptCompletionIdentifier assigned_type;
22472248 if (_guess_expression_type (c, last_assigned_expression, assigned_type)) {
2248- if (id_type.is_set () && assigned_type.type .is_set () && !GDScriptAnalyzer::check_type_compatibility (id_type, assigned_type.type )) {
2249+ if (id_type.type . is_set () && assigned_type.type .is_set () && !GDScriptAnalyzer::check_type_compatibility (id_type. type , assigned_type.type )) {
22492250 // The assigned type is incompatible. The annotated type takes priority.
2251+ r_type = id_type;
22502252 r_type.assigned_expression = last_assigned_expression;
2251- r_type.type = id_type;
22522253 } else {
22532254 r_type = assigned_type;
22542255 }
@@ -2266,8 +2267,8 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
22662267 GDScriptParser::FunctionNode *parent_function = base_type.class_type ->get_member (p_context.current_function ->identifier ->name ).function ;
22672268 if (parent_function->parameters_indices .has (p_identifier->name )) {
22682269 const GDScriptParser::ParameterNode *parameter = parent_function->parameters [parent_function->parameters_indices [p_identifier->name ]];
2269- if ((!id_type.is_set () || id_type.is_variant ()) && parameter->get_datatype ().is_hard_type ()) {
2270- id_type = parameter->get_datatype ();
2270+ if ((!id_type.type . is_set () || id_type. type .is_variant ()) && parameter->get_datatype ().is_hard_type ()) {
2271+ id_type. type = parameter->get_datatype ();
22712272 }
22722273 if (parameter->initializer ) {
22732274 GDScriptParser::CompletionContext c = p_context;
@@ -2283,7 +2284,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
22832284 base_type = base_type.class_type ->base_type ;
22842285 break ;
22852286 case GDScriptParser::DataType::NATIVE: {
2286- if (id_type.is_set () && !id_type.is_variant ()) {
2287+ if (id_type.type . is_set () && !id_type. type .is_variant ()) {
22872288 base_type = GDScriptParser::DataType ();
22882289 break ;
22892290 }
@@ -2304,8 +2305,8 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
23042305 }
23052306 }
23062307
2307- if (id_type.is_set () && !id_type.is_variant ()) {
2308- r_type. type = id_type;
2308+ if (id_type.type . is_set () && !id_type. type .is_variant ()) {
2309+ r_type = id_type;
23092310 return true ;
23102311 }
23112312
@@ -3197,7 +3198,7 @@ ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_pa
31973198 break ;
31983199 }
31993200 const GDScriptParser::AnnotationNode *annotation = static_cast <const GDScriptParser::AnnotationNode *>(completion_context.node );
3200- _find_annotation_arguments (annotation, completion_context.current_argument , quote_style, options);
3201+ _find_annotation_arguments (annotation, completion_context.current_argument , quote_style, options, r_call_hint );
32013202 r_forced = true ;
32023203 } break ;
32033204 case GDScriptParser::COMPLETION_BUILT_IN_TYPE_CONSTANT_OR_STATIC_METHOD: {
@@ -3321,11 +3322,36 @@ ::Error GDScriptLanguage::complete_code(const String &p_code, const String &p_pa
33213322 case GDScriptParser::COMPLETION_SUBSCRIPT: {
33223323 const GDScriptParser::SubscriptNode *subscript = static_cast <const GDScriptParser::SubscriptNode *>(completion_context.node );
33233324 GDScriptCompletionIdentifier base;
3324- if (!_guess_expression_type (completion_context, subscript->base , base)) {
3325- break ;
3326- }
3325+ const bool res = _guess_expression_type (completion_context, subscript->base , base);
3326+
3327+ // If the type is not known, we assume it is BUILTIN, since indices on arrays is the most common use case.
3328+ if (!subscript->is_attribute && (!res || base.type .kind == GDScriptParser::DataType::BUILTIN || base.type .is_variant ())) {
3329+ if (base.value .get_type () == Variant::DICTIONARY) {
3330+ List<PropertyInfo> members;
3331+ base.value .get_property_list (&members);
33273332
3328- _find_identifiers_in_base (base, false , false , options, 0 );
3333+ for (const PropertyInfo &E : members) {
3334+ ScriptLanguage::CodeCompletionOption option (E.name .quote (quote_style), ScriptLanguage::CODE_COMPLETION_KIND_MEMBER, ScriptLanguage::LOCATION_LOCAL);
3335+ options.insert (option.display , option);
3336+ }
3337+ }
3338+ if (!subscript->index || subscript->index ->type != GDScriptParser::Node::LITERAL) {
3339+ _find_identifiers (completion_context, false , options, 0 );
3340+ }
3341+ } else if (res) {
3342+ if (!subscript->is_attribute ) {
3343+ // Quote the options if they are not accessed as attribute.
3344+
3345+ HashMap<String, ScriptLanguage::CodeCompletionOption> opt;
3346+ _find_identifiers_in_base (base, false , false , opt, 0 );
3347+ for (const KeyValue<String, CodeCompletionOption> &E : opt) {
3348+ ScriptLanguage::CodeCompletionOption option (E.value .insert_text .quote (quote_style), E.value .kind , E.value .location );
3349+ options.insert (option.display , option);
3350+ }
3351+ } else {
3352+ _find_identifiers_in_base (base, false , false , options, 0 );
3353+ }
3354+ }
33293355 } break ;
33303356 case GDScriptParser::COMPLETION_TYPE_ATTRIBUTE: {
33313357 if (!completion_context.current_class ) {
0 commit comments