Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GDScript: Fix common mismatched external parser errors (second try) #94871

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 156 additions & 42 deletions modules/gdscript/gdscript_analyzer.cpp

Large diffs are not rendered by default.

19 changes: 18 additions & 1 deletion modules/gdscript/gdscript_analyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,22 @@
class GDScriptAnalyzer {
GDScriptParser *parser = nullptr;

template <typename Fn>
class Finally {
Fn fn;

public:
Finally(Fn p_fn) :
fn(p_fn) {}
~Finally() {
fn();
}
};

const GDScriptParser::EnumNode *current_enum = nullptr;
GDScriptParser::LambdaNode *current_lambda = nullptr;
List<GDScriptParser::LambdaNode *> pending_body_resolution_lambdas;
HashMap<const GDScriptParser::ClassNode *, Ref<GDScriptParserRef>> external_class_parser_cache;
bool static_context = false;

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

void get_class_node_current_scope_classes(GDScriptParser::ClassNode *p_node, List<GDScriptParser::ClassNode *> *p_list);
void get_class_node_current_scope_classes(GDScriptParser::ClassNode *p_node, List<GDScriptParser::ClassNode *> *p_list, GDScriptParser::Node *p_source);

Error resolve_class_inheritance(GDScriptParser::ClassNode *p_class, const GDScriptParser::Node *p_source = nullptr);
Error resolve_class_inheritance(GDScriptParser::ClassNode *p_class, bool p_recursive);
Expand Down Expand Up @@ -132,6 +145,10 @@ class GDScriptAnalyzer {
void resolve_pending_lambda_bodies();
bool class_exists(const StringName &p_class) const;
void reduce_identifier_from_base_set_class(GDScriptParser::IdentifierNode *p_identifier, GDScriptParser::DataType p_identifier_datatype);
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);
Ref<GDScriptParserRef> find_cached_parser_for_class(const GDScriptParser::ClassNode *p_class, const Ref<GDScriptParserRef> &p_dependant_parser);
Ref<GDScriptParserRef> find_cached_parser_for_class(const GDScriptParser::ClassNode *p_class, GDScriptParser *p_dependant_parser);
Ref<GDScript> get_depended_shallow_script(const String &p_path, Error &r_error);
#ifdef DEBUG_ENABLED
void is_shadowing(GDScriptParser::IdentifierNode *p_identifier, const String &p_context, const bool p_in_local_scope);
#endif
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
GDTEST_ANALYZER_ERROR
Could not resolve member "v".
Could not resolve external class member "v".
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
extends "external_parser_base1.notest.gd"

const External1 = preload("external_parser_script1.notest.gd")

func baz(e1: External1) -> void:
print(e1.e1c.bar)
print(e1.baz)

func test_external_base_parser_type_resolve(_v: TypeFromBase):
pass

func test():
var ext := External1.new()
print(ext.array[0].test2)
print(ext.get_external2().get_external3().test3)
# TODO: This actually produces a runtime error, but we're testing the analyzer here
#baz(ext)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GDTEST_OK
test2
test3
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extends "external_parser_base2.notest.gd"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class TypeFromBase:
pass
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extends "external_parser_script1_base.notest.gd"

const External2 = preload("external_parser_script2.notest.gd")
const External1c = preload("external_parser_script1c.notest.gd")

@export var e1c: External1c

var array: Array[External2] = [ External2.new() ]
var baz: int

func get_external2() -> External2:
return External2.new()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extends Resource
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extends "external_parser_script1d.notest.gd"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
extends "external_parser_script1f.notest.gd"

const External1e = preload("external_parser_script1e.notest.gd")

var bar: Array[External1e]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extends Resource
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const External3 = preload("external_parser_script3.notest.gd")

var test2 := "test2"

func get_external3() -> External3:
return External3.new()
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var test3 := "test3"
Loading