Skip to content

Commit 6e8fa6d

Browse files
committed
GDScript: Fix common mismatched external parser errors
1 parent 607b230 commit 6e8fa6d

15 files changed

+225
-44
lines changed

modules/gdscript/gdscript_analyzer.cpp

Lines changed: 156 additions & 42 deletions
Large diffs are not rendered by default.

modules/gdscript/gdscript_analyzer.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,22 @@
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+
4456
const GDScriptParser::EnumNode *current_enum = nullptr;
4557
GDScriptParser::LambdaNode *current_lambda = nullptr;
4658
List<GDScriptParser::LambdaNode *> pending_body_resolution_lambdas;
59+
HashMap<const GDScriptParser::ClassNode *, Ref<GDScriptParserRef>> external_class_parser_cache;
4760
bool static_context = false;
4861

4962
// Tests for detecting invalid overloading of script members
@@ -52,7 +65,7 @@ class GDScriptAnalyzer {
5265
Error check_native_member_name_conflict(const StringName &p_member_name, const GDScriptParser::Node *p_member_node, const StringName &p_native_type_string);
5366
Error check_class_member_name_conflict(const GDScriptParser::ClassNode *p_class_node, const StringName &p_member_name, const GDScriptParser::Node *p_member_node);
5467

55-
void get_class_node_current_scope_classes(GDScriptParser::ClassNode *p_node, List<GDScriptParser::ClassNode *> *p_list);
68+
void get_class_node_current_scope_classes(GDScriptParser::ClassNode *p_node, List<GDScriptParser::ClassNode *> *p_list, GDScriptParser::Node *p_source);
5669

5770
Error resolve_class_inheritance(GDScriptParser::ClassNode *p_class, const GDScriptParser::Node *p_source = nullptr);
5871
Error resolve_class_inheritance(GDScriptParser::ClassNode *p_class, bool p_recursive);
@@ -132,6 +145,10 @@ class GDScriptAnalyzer {
132145
void resolve_pending_lambda_bodies();
133146
bool class_exists(const StringName &p_class) const;
134147
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<GDScriptParserRef> find_cached_parser_for_class(const GDScriptParser::ClassNode *p_class, const Ref<GDScriptParserRef> &p_dependant_parser);
150+
Ref<GDScriptParserRef> find_cached_parser_for_class(const GDScriptParser::ClassNode *p_class, GDScriptParser *p_dependant_parser);
151+
Ref<GDScript> get_depended_shallow_script(const String &p_path, Error &r_error);
135152
#ifdef DEBUG_ENABLED
136153
void is_shadowing(GDScriptParser::IdentifierNode *p_identifier, const String &p_context, const bool p_in_local_scope);
137154
#endif
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
GDTEST_ANALYZER_ERROR
2-
Could not resolve member "v".
2+
Could not resolve external class member "v".
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
extends "external_parser_base1.notest.gd"
2+
3+
const External1 = preload("external_parser_script1.notest.gd")
4+
5+
func baz(e1: External1) -> void:
6+
print(e1.e1c.bar)
7+
print(e1.baz)
8+
9+
func test_external_base_parser_type_resolve(_v: TypeFromBase):
10+
pass
11+
12+
func test():
13+
var ext := External1.new()
14+
print(ext.array[0].test2)
15+
print(ext.get_external2().get_external3().test3)
16+
# TODO: This actually produces a runtime error, but we're testing the analyzer here
17+
#baz(ext)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
GDTEST_OK
2+
test2
3+
test3
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extends "external_parser_base2.notest.gd"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class TypeFromBase:
2+
pass
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
extends "external_parser_script1_base.notest.gd"
2+
3+
const External2 = preload("external_parser_script2.notest.gd")
4+
const External1c = preload("external_parser_script1c.notest.gd")
5+
6+
@export var e1c: External1c
7+
8+
var array: Array[External2] = [ External2.new() ]
9+
var baz: int
10+
11+
func get_external2() -> External2:
12+
return External2.new()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extends Resource
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extends "external_parser_script1d.notest.gd"

0 commit comments

Comments
 (0)