Skip to content

Commit e343dbb

Browse files
committed
Merge pull request godotengine#94723 from akien-mga/revert-94617
Revert "GDScript: Fix common mismatched external parser errors"
2 parents 0b26cc1 + f2918c7 commit e343dbb

File tree

2 files changed

+35
-124
lines changed

2 files changed

+35
-124
lines changed

modules/gdscript/gdscript_analyzer.cpp

+35-109
Original file line numberDiff line numberDiff line change
@@ -312,15 +312,6 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c
312312
p_source = p_class;
313313
}
314314

315-
Ref<GDScriptParserRef> parser_ref = ensure_cached_parser_for_class(p_class, nullptr, vformat(R"(Trying to resolve class inheritance of "%s" from "%s")", p_class->fqcn, parser->script_path), p_source);
316-
Finally finally([&]() {
317-
GDScriptParser::ClassNode *look_class = p_class;
318-
do {
319-
ensure_cached_parser_for_class(look_class->base_type.class_type, look_class, vformat(R"(Trying to resolve class inheritance of "%s" from "%s")", p_class->fqcn, parser->script_path), p_source);
320-
look_class = look_class->base_type.class_type;
321-
} while (look_class != nullptr);
322-
});
323-
324315
if (p_class->base_type.is_resolving()) {
325316
push_error(vformat(R"(Could not resolve class "%s": Cyclic reference.)", type_from_metatype(p_class->get_datatype()).to_string()), p_source);
326317
return ERR_PARSE_ERROR;
@@ -332,17 +323,21 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c
332323
}
333324

334325
if (!parser->has_class(p_class)) {
326+
String script_path = p_class->get_datatype().script_path;
327+
Ref<GDScriptParserRef> parser_ref = parser->get_depended_parser_for(script_path);
335328
if (parser_ref.is_null()) {
336-
// Error already pushed.
329+
push_error(vformat(R"(Could not find script "%s".)", script_path), p_source);
337330
return ERR_PARSE_ERROR;
338331
}
339332

340333
Error err = parser_ref->raise_status(GDScriptParserRef::PARSED);
341334
if (err) {
342-
push_error(vformat(R"(Could not parse script "%s": %s.)", p_class->get_datatype().script_path, error_names[err]), p_source);
335+
push_error(vformat(R"(Could not parse script "%s": %s.)", script_path, error_names[err]), p_source);
343336
return ERR_PARSE_ERROR;
344337
}
345338

339+
ERR_FAIL_COND_V_MSG(!parser_ref->get_parser()->has_class(p_class), ERR_PARSE_ERROR, R"(Parser bug: Mismatched external parser.)");
340+
346341
GDScriptAnalyzer *other_analyzer = parser_ref->get_analyzer();
347342
GDScriptParser *other_parser = parser_ref->get_parser();
348343

@@ -888,11 +883,6 @@ void GDScriptAnalyzer::resolve_class_member(GDScriptParser::ClassNode *p_class,
888883
p_source = member.get_source_node();
889884
}
890885

891-
Ref<GDScriptParserRef> parser_ref = ensure_cached_parser_for_class(p_class, nullptr, vformat(R"(Trying to resolve class member "%s" of "%s" from "%s")", member.get_name(), p_class->fqcn, parser->script_path), p_source);
892-
Finally finally([&]() {
893-
ensure_cached_parser_for_class(member.get_datatype().class_type, p_class, vformat(R"(Trying to resolve class member "%s" of "%s" from "%s")", member.get_name(), p_class->fqcn, parser->script_path), p_source);
894-
});
895-
896886
if (member.get_datatype().is_resolving()) {
897887
push_error(vformat(R"(Could not resolve member "%s": Cyclic reference.)", member.get_name()), p_source);
898888
return;
@@ -902,39 +892,42 @@ void GDScriptAnalyzer::resolve_class_member(GDScriptParser::ClassNode *p_class,
902892
return;
903893
}
904894

905-
// If it's already resolving, that's ok.
906-
if (!p_class->base_type.is_resolving()) {
907-
Error err = resolve_class_inheritance(p_class);
908-
if (err) {
909-
return;
910-
}
911-
}
912-
913895
if (!parser->has_class(p_class)) {
896+
String script_path = p_class->get_datatype().script_path;
897+
Ref<GDScriptParserRef> parser_ref = parser->get_depended_parser_for(script_path);
914898
if (parser_ref.is_null()) {
915-
// Error already pushed.
899+
push_error(vformat(R"(Could not find script "%s" (While resolving "%s").)", script_path, member.get_name()), p_source);
916900
return;
917901
}
918902

919903
Error err = parser_ref->raise_status(GDScriptParserRef::PARSED);
920904
if (err) {
921-
push_error(vformat(R"(Could not parse script "%s": %s (While resolving member "%s").)", p_class->get_datatype().script_path, error_names[err], member.get_name()), p_source);
905+
push_error(vformat(R"(Could not resolve script "%s": %s (While resolving "%s").)", script_path, error_names[err], member.get_name()), p_source);
922906
return;
923907
}
924908

909+
ERR_FAIL_COND_MSG(!parser_ref->get_parser()->has_class(p_class), R"(Parser bug: Mismatched external parser.)");
910+
925911
GDScriptAnalyzer *other_analyzer = parser_ref->get_analyzer();
926912
GDScriptParser *other_parser = parser_ref->get_parser();
927913

928914
int error_count = other_parser->errors.size();
929915
other_analyzer->resolve_class_member(p_class, p_index);
930916
if (other_parser->errors.size() > error_count) {
931917
push_error(vformat(R"(Could not resolve member "%s".)", member.get_name()), p_source);
932-
return;
933918
}
934919

935920
return;
936921
}
937922

923+
// If it's already resolving, that's ok.
924+
if (!p_class->base_type.is_resolving()) {
925+
Error err = resolve_class_inheritance(p_class);
926+
if (err) {
927+
return;
928+
}
929+
}
930+
938931
GDScriptParser::ClassNode *previous_class = parser->current_class;
939932
parser->current_class = p_class;
940933

@@ -1177,33 +1170,34 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
11771170
p_source = p_class;
11781171
}
11791172

1180-
Ref<GDScriptParserRef> parser_ref = ensure_cached_parser_for_class(p_class, nullptr, vformat(R"(Trying to resolve class interface of "%s" from "%s")", p_class->fqcn, parser->script_path), p_source);
1181-
11821173
if (!p_class->resolved_interface) {
11831174
#ifdef DEBUG_ENABLED
11841175
bool has_static_data = p_class->has_static_data;
11851176
#endif
11861177

11871178
if (!parser->has_class(p_class)) {
1179+
String script_path = p_class->get_datatype().script_path;
1180+
Ref<GDScriptParserRef> parser_ref = parser->get_depended_parser_for(script_path);
11881181
if (parser_ref.is_null()) {
1189-
// Error already pushed.
1182+
push_error(vformat(R"(Could not find script "%s".)", script_path), p_source);
11901183
return;
11911184
}
11921185

11931186
Error err = parser_ref->raise_status(GDScriptParserRef::PARSED);
11941187
if (err) {
1195-
push_error(vformat(R"(Could not parse script "%s": %s.)", p_class->get_datatype().script_path, error_names[err]), p_source);
1188+
push_error(vformat(R"(Could not resolve script "%s": %s.)", script_path, error_names[err]), p_source);
11961189
return;
11971190
}
11981191

1192+
ERR_FAIL_COND_MSG(!parser_ref->get_parser()->has_class(p_class), R"(Parser bug: Mismatched external parser.)");
1193+
11991194
GDScriptAnalyzer *other_analyzer = parser_ref->get_analyzer();
12001195
GDScriptParser *other_parser = parser_ref->get_parser();
12011196

12021197
int error_count = other_parser->errors.size();
12031198
other_analyzer->resolve_class_interface(p_class);
12041199
if (other_parser->errors.size() > error_count) {
12051200
push_error(vformat(R"(Could not resolve class "%s".)", p_class->fqcn), p_source);
1206-
return;
12071201
}
12081202

12091203
return;
@@ -1267,32 +1261,33 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class, co
12671261
p_source = p_class;
12681262
}
12691263

1270-
Ref<GDScriptParserRef> parser_ref = ensure_cached_parser_for_class(p_class, nullptr, vformat(R"(Trying to resolve class body of "%s" from "%s")", p_class->fqcn, parser->script_path), p_source);
1271-
12721264
if (p_class->resolved_body) {
12731265
return;
12741266
}
12751267

12761268
if (!parser->has_class(p_class)) {
1269+
String script_path = p_class->get_datatype().script_path;
1270+
Ref<GDScriptParserRef> parser_ref = parser->get_depended_parser_for(script_path);
12771271
if (parser_ref.is_null()) {
1278-
// Error already pushed.
1272+
push_error(vformat(R"(Could not find script "%s".)", script_path), p_source);
12791273
return;
12801274
}
12811275

12821276
Error err = parser_ref->raise_status(GDScriptParserRef::PARSED);
12831277
if (err) {
1284-
push_error(vformat(R"(Could not parse script "%s": %s.)", p_class->get_datatype().script_path, error_names[err]), p_source);
1278+
push_error(vformat(R"(Could not resolve script "%s": %s.)", script_path, error_names[err]), p_source);
12851279
return;
12861280
}
12871281

1282+
ERR_FAIL_COND_MSG(!parser_ref->get_parser()->has_class(p_class), R"(Parser bug: Mismatched external parser.)");
1283+
12881284
GDScriptAnalyzer *other_analyzer = parser_ref->get_analyzer();
12891285
GDScriptParser *other_parser = parser_ref->get_parser();
12901286

12911287
int error_count = other_parser->errors.size();
12921288
other_analyzer->resolve_class_body(p_class);
12931289
if (other_parser->errors.size() > error_count) {
12941290
push_error(vformat(R"(Could not resolve class "%s".)", p_class->fqcn), p_source);
1295-
return;
12961291
}
12971292

12981293
return;
@@ -3650,81 +3645,12 @@ GDScriptParser::DataType GDScriptAnalyzer::make_global_class_meta_type(const Str
36503645
}
36513646
}
36523647

3653-
Ref<GDScriptParserRef> GDScriptAnalyzer::ensure_cached_parser_for_class(const GDScriptParser::ClassNode *p_class, const GDScriptParser::ClassNode *p_from_class, const String &p_context, const GDScriptParser::Node *p_source) {
3654-
if (p_class == nullptr) {
3655-
return nullptr;
3656-
}
3657-
3658-
if (parser->has_class(p_class)) {
3659-
return nullptr;
3660-
}
3661-
3662-
{
3663-
HashMap<const GDScriptParser::ClassNode *, Ref<GDScriptParserRef>>::Iterator E = external_class_parser_cache.find(p_class);
3664-
if (E) {
3665-
return E->value;
3666-
}
3667-
}
3668-
3669-
Ref<GDScriptParserRef> parser_ref;
3670-
Ref<GDScriptParserRef> dependant_parser_ref;
3671-
GDScriptParser *dependant_parser = parser;
3672-
do {
3673-
if (HashMap<const GDScriptParser::ClassNode *, Ref<GDScriptParserRef>>::Iterator E = external_class_parser_cache.find(p_from_class)) {
3674-
dependant_parser_ref = E->value;
3675-
dependant_parser = E->value->get_parser();
3676-
3677-
// Silently ensure it's parsed.
3678-
dependant_parser_ref->raise_status(GDScriptParserRef::PARSED);
3679-
}
3680-
3681-
if (dependant_parser == nullptr) {
3682-
continue;
3683-
}
3684-
3685-
if (dependant_parser_ref.is_valid() && dependant_parser->has_class(p_class)) {
3686-
external_class_parser_cache.insert(p_class, dependant_parser_ref);
3687-
parser_ref = dependant_parser_ref;
3688-
break;
3689-
}
3690-
3691-
String script_path = p_class->get_datatype().script_path;
3692-
HashMap<String, Ref<GDScriptParserRef>>::Iterator E = dependant_parser->depended_parsers.find(script_path);
3693-
if (E) {
3694-
// Silently ensure it's parsed.
3695-
E->value->raise_status(GDScriptParserRef::PARSED);
3696-
if (E->value->get_parser()->has_class(p_class)) {
3697-
external_class_parser_cache.insert(p_class, E->value);
3698-
parser_ref = E->value;
3699-
break;
3700-
}
3701-
}
3702-
3703-
dependant_parser_ref = Ref<GDScriptParserRef>();
3704-
dependant_parser = nullptr;
3705-
p_from_class = p_from_class->base_type.class_type;
3706-
} while (p_from_class != nullptr);
3707-
3708-
if (parser_ref.is_null()) {
3709-
push_error(vformat(R"(Parser bug: Could not find external parser. (%s))", p_context), p_source);
3710-
}
3711-
3712-
return parser_ref;
3713-
}
3714-
3715-
Ref<GDScript> GDScriptAnalyzer::get_depended_shallow_script(const String &p_path, Error &r_error) {
3716-
// To keep a local cache of the parser for resolving external nodes later.
3717-
parser->get_depended_parser_for(p_path);
3718-
Ref<GDScript> scr = GDScriptCache::get_shallow_script(p_path, r_error, parser->script_path);
3719-
return scr;
3720-
}
3721-
37223648
void GDScriptAnalyzer::reduce_identifier_from_base_set_class(GDScriptParser::IdentifierNode *p_identifier, GDScriptParser::DataType p_identifier_datatype) {
37233649
ERR_FAIL_NULL(p_identifier);
37243650

37253651
p_identifier->set_datatype(p_identifier_datatype);
37263652
Error err = OK;
3727-
Ref<GDScript> scr = get_depended_shallow_script(p_identifier_datatype.script_path, err);
3653+
Ref<GDScript> scr = GDScriptCache::get_shallow_script(p_identifier_datatype.script_path, err, parser->script_path);
37283654
if (err) {
37293655
push_error(vformat(R"(Error while getting cache for script "%s".)", p_identifier_datatype.script_path), p_identifier);
37303656
return;
@@ -4414,7 +4340,7 @@ void GDScriptAnalyzer::reduce_preload(GDScriptParser::PreloadNode *p_preload) {
44144340
const String &res_type = ResourceLoader::get_resource_type(p_preload->resolved_path);
44154341
if (res_type == "GDScript") {
44164342
Error err = OK;
4417-
Ref<GDScript> res = get_depended_shallow_script(p_preload->resolved_path, err);
4343+
Ref<GDScript> res = GDScriptCache::get_shallow_script(p_preload->resolved_path, err, parser->script_path);
44184344
p_preload->resource = res;
44194345
if (err != OK) {
44204346
push_error(vformat(R"(Could not preload resource script "%s".)", p_preload->resolved_path), p_preload->path);
@@ -4990,7 +4916,7 @@ Array GDScriptAnalyzer::make_array_from_element_datatype(const GDScriptParser::D
49904916
Ref<Script> script_type = p_element_datatype.script_type;
49914917
if (p_element_datatype.kind == GDScriptParser::DataType::CLASS && script_type.is_null()) {
49924918
Error err = OK;
4993-
Ref<GDScript> scr = get_depended_shallow_script(p_element_datatype.script_path, err);
4919+
Ref<GDScript> scr = GDScriptCache::get_shallow_script(p_element_datatype.script_path, err, parser->script_path);
49944920
if (err) {
49954921
push_error(vformat(R"(Error while getting cache for script "%s".)", p_element_datatype.script_path), p_source_node);
49964922
return array;

modules/gdscript/gdscript_analyzer.h

-15
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,9 @@
4141
class GDScriptAnalyzer {
4242
GDScriptParser *parser = nullptr;
4343

44-
template <typename Fn>
45-
class Finally {
46-
Fn fn;
47-
48-
public:
49-
Finally(Fn p_fn) :
50-
fn(p_fn) {}
51-
~Finally() {
52-
fn();
53-
}
54-
};
55-
5644
const GDScriptParser::EnumNode *current_enum = nullptr;
5745
GDScriptParser::LambdaNode *current_lambda = nullptr;
5846
List<GDScriptParser::LambdaNode *> pending_body_resolution_lambdas;
59-
HashMap<const GDScriptParser::ClassNode *, Ref<GDScriptParserRef>> external_class_parser_cache;
6047
bool static_context = false;
6148

6249
// Tests for detecting invalid overloading of script members
@@ -145,8 +132,6 @@ class GDScriptAnalyzer {
145132
void resolve_pending_lambda_bodies();
146133
bool class_exists(const StringName &p_class) const;
147134
void reduce_identifier_from_base_set_class(GDScriptParser::IdentifierNode *p_identifier, GDScriptParser::DataType p_identifier_datatype);
148-
Ref<GDScriptParserRef> ensure_cached_parser_for_class(const GDScriptParser::ClassNode *p_class, const GDScriptParser::ClassNode *p_from_class, const String &p_context, const GDScriptParser::Node *p_source);
149-
Ref<GDScript> get_depended_shallow_script(const String &p_path, Error &r_error);
150135
#ifdef DEBUG_ENABLED
151136
void is_shadowing(GDScriptParser::IdentifierNode *p_identifier, const String &p_context, const bool p_in_local_scope);
152137
#endif

0 commit comments

Comments
 (0)