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

Unexpected "Parser Error : Identifier not found" when using parent class member #78146

Closed
3lis4 opened this issue Jun 12, 2023 · 2 comments · Fixed by #79205
Closed

Unexpected "Parser Error : Identifier not found" when using parent class member #78146

3lis4 opened this issue Jun 12, 2023 · 2 comments · Fixed by #79205

Comments

@3lis4
Copy link

3lis4 commented Jun 12, 2023

Godot version

4.0.2

System information

Linux Mint 21

Issue description

On the minimal reproduction project, with a 3 level hierarchy and 2 autoloads, when running the game we get a parse error in daughter.gd where we use a parent member.

Additional remarks :

  • We have a circular dependency involving one of the autoloads : Autoload2 references Daughter which references Mother which references GrandMother which references Autoload2
  • Autoload1 references Mother which references GrandMother which references Autoload2
  • We don't have any error if we switch the 2 autoloads order in Project Settings
  • We get the same error if _member is put in GrandMother class instead of Mother class
  • We still get the issue if we disable Autoload1 in Project Settings

A quick look in Godot source code :

  • GDScriptCache::full_gdscript_cache contains invalid scripts (ie script->is_valid() is false)
  • I think the engine tries to compile GrandMother, then Daughter (but it fails), then Mother

(This issue might be related to #75388.)

Steps to reproduce

To get the parse error :

  • Open the minimal reproduction project
  • Run the game
    You'll get Parser Error: Identifier not found: _member.

Minimal reproduction project

ParseError_Project.zip

@anvilfolk
Copy link
Contributor

anvilfolk commented Jul 7, 2023

Doing some digging to help out with this one. It appears that GDScriptCache::get_full_script() is ignoring errors from GDScript::reload(), which is what actually does static analysis. If the order of loading changes when running the scene vs when running the editor, which is plausible, that could explain the strange identifier error without any other issues.

Here is what I am getting running the scene directly after adding error messages and printing information about what functions are getting called. get_shallow_script and get_full_script are only getting printed if they have not been found in the cache.

modules\gdscript\gdscript.cpp:2701 - ResourceFormatLoaderGDScript::load(res://stuff/autoload_1.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/autoload_1.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/autoload_1.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/mother.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/mother.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/grand_mother.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/grand_mother.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/autoload_2.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/autoload_2.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/daughter.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/daughter.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/mother.gd)
res://stuff/daughter.gd:4 - Compile Error: Identifier not found: _member
res://stuff/autoload_2.gd:4 - Compile Error: Can't load global class Daughter
res://stuff/grand_mother.gd:-1 - Compile Error: 
res://stuff/mother.gd:0 - Compile Error: Could not compile base class "GrandMother" from "res://stuff/grand_mother.gd": Compilation failed
res://stuff/autoload_1.gd:4 - Compile Error: Can't load global class Mother

And here is what happens when opening the editor:

modules\gdscript\gdscript.cpp:2701 - ResourceFormatLoaderGDScript::load(res://stuff/autoload_1.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/autoload_1.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/autoload_1.gd)
res://stuff/autoload_1.gd:4 - Parse Error: Identifier "Mother" not declared in the current scope.
Script does not inherit from Node: res://stuff/autoload_1.gd.
modules\gdscript\gdscript.cpp:2701 - ResourceFormatLoaderGDScript::load(res://stuff/autoload_2.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/autoload_2.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/autoload_2.gd)
res://stuff/autoload_2.gd:4 - Parse Error: Identifier "Daughter" not declared in the current scope.
Script does not inherit from Node: res://stuff/autoload_2.gd.

Followed some time later by:

modules\gdscript\gdscript.cpp:2701 - ResourceFormatLoaderGDScript::load(res://stuff/daughter.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/daughter.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/daughter.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/mother.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/mother.gd)
modules\gdscript\gdscript_cache.cpp:254 - GDScriptCache::get_shallow_script(res://stuff/grand_mother.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/grand_mother.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/autoload_2.gd)
modules\gdscript\gdscript_cache.cpp:290 - GDScriptCache::get_full_script(res://stuff/daughter.gd)

I suspect the reloading of daughter.gd (no idea why that gets called) is what finally fixes the issues in the editor, because the problem was there originally, since it loads in a sensible way: daughter->mother->grand_mother->autoload_2->daughter, which at that time seems to possibly have already been compiled and might be in the cache?

@anvilfolk
Copy link
Contributor

anvilfolk commented Jul 8, 2023

I managed to create an MRP that does not include autoloads, just for the record! Just open the project and run the scene. The dependency is as follows: Daughter extends Mother extends Grandmother, with Grandmother referring to (but not extending Daughter), and Mother being the first file loaded.

MRP.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants