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: Out of order member resolution #69471

Merged
merged 1 commit into from Dec 15, 2022

Conversation

rune-scape
Copy link
Contributor

@rune-scape rune-scape commented Dec 2, 2022

Implements out of order member resolution
-- this was allowed in some specific places, but this PR pulls it out into its own function to make the behavior consistent
-- and allow more complex ordering

class members are now resolved just before they are needed
-- This means class members will always have resolved types before used, else an error is pushed
same goes for members of external classes
-- This fixes alot of dependency errors.

also fixes a few minor bugs:
-- singleton datatypes now get properly resolved in extends
-- Object and Variant no longer allow array syntax (Variant[int] doesn't parse)
-- pushes an error if a native enum doesn't exist when resolving a type
those were all just missing a line or 2

fixes #68069
fixes #69479
fixes #67085
fixes #69763
fixes #68017
may fix #44375 (didn't read the all the comments, but it addresses the problem in the most recent ones)

@rune-scape rune-scape requested a review from a team as a code owner December 2, 2022 05:25
@Chaosus Chaosus added this to the 4.0 milestone Dec 2, 2022
@MewPurPur
Copy link
Contributor

Does this address #61159?

@rune-scape
Copy link
Contributor Author

rune-scape commented Dec 2, 2022

@MewPurPur i can check in a bit, but my instinct is no

@adamscott
Copy link
Member

adamscott commented Dec 2, 2022

As is, this PR fixes #69479. I just tested it.
@rune-scape Can you add it in the description?

}
return result;
Copy link
Contributor Author

@rune-scape rune-scape Dec 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was annoyed that Variant and Object were the only ones to return a good result early
removing this actually fixes an annoying bug that allows the type Variant[int] but chops off the [int] part in the analyzer. same with Object

Copy link
Contributor

@anvilfolk anvilfolk Dec 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, deleted my comment after realizing that you can probably still fill out some stuff later, so you can do all these checks and assign partial information to result :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

found = true;
break;
case GDScriptParser::ClassNode::Member::ENUM:
result = member.m_enum->get_datatype();
result = member.get_datatype();
found = true;
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can now let CLASS fallthrough to ENUM since the code is the same! Wonder if there's any other places where this could be done :)

@rune-scape
Copy link
Contributor Author

@anvilfolk and @adamscott thank you for reviewing!

@rune-scape
Copy link
Contributor Author

Technically this could be expanded to allow the analyzer to resolve individual members of other scripts, allowing member dependencies both ways between script interfaces, but i'm not sure anyone has a use for that 🙂

@anvilfolk
Copy link
Contributor

Technically this could be expanded to allow the analyzer to resolve individual members of other scripts, allowing member dependencies both ways between script interfaces, but i'm not sure anyone has a use for that 🙂

Wouldn't this actually be really neat now that cyclic dependencies are possible? Could probably come up with a small interesting case like:

# A.gd

var a := B.b_func()

static func a_func() -> int:
  return 42


# B.gd

static func b_func() -> int:
  return A.a_func()

Something like that?

@rune-scape
Copy link
Contributor Author

@anvilfolk exactly! i do kinda wanna see how difficult it is, so i'll put it on my todo list 😄
who knows, maybe its dead simple

@rune-scape
Copy link
Contributor Author

i added braces inside resolve_class_member() to make the diff much more readable

@rune-scape
Copy link
Contributor Author

@MewPurPur no, this doesn't fix #61159, but i found the bug.
#69518 fixes that

@adamscott
Copy link
Member

I cannot NOT underline the great teamwork between you both, @rune-scape and @anvilfolk. <3

@anvilfolk
Copy link
Contributor

Looks like the PR you mentioned is in! :) I take it merging should wait until the bugs are ironed out?

@rune-scape
Copy link
Contributor Author

that was fast!, yes, i want to make some more complex tests now before this gets merged

@rune-scape rune-scape force-pushed the rune-out-of-order branch 2 times, most recently from 30600f0 to 2144162 Compare December 15, 2022 00:48
@rune-scape
Copy link
Contributor Author

rune-scape commented Dec 15, 2022

ok, it took a while to figure out, but tests are added and they helped me find a few bugs! they're finally done

@anvilfolk
Copy link
Contributor

Nice! Look forward to seeing this merged so I can fix conflicts with the enum PR! :)

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@akien-mga akien-mga merged commit 6debf86 into godotengine:master Dec 15, 2022
@akien-mga
Copy link
Member

Thanks!

@lufog
Copy link
Contributor

lufog commented Dec 15, 2022

I think this PR broke something in Autoloads.

on ec4de82:
MRP works

on 6debf86:
I get Parser Error: Cannot find member "audio_player" in base "".

MRP: var_from_autoload_test.zip

@adamscott
Copy link
Member

@lufog Can you create an issue?

@lufog
Copy link
Contributor

lufog commented Dec 15, 2022

@adamscott, to be honest, I don't even know how to properly formulate it. But I'll try.

@rune-scape
Copy link
Contributor Author

@lufog thank you for the project! i think i found the mistake

@adamscott
Copy link
Member

adamscott commented Dec 15, 2022

I don't even know how to properly formulate it.

@lufog You can formulate it like "Autoloads broken: cannot find members" and copy/paste what you wrote here in the issue.

It will be easier for @rune-scape to create a PR that links to your issue.

@lufog
Copy link
Contributor

lufog commented Dec 15, 2022

Done #70127

@dmaz
Copy link
Contributor

dmaz commented Dec 16, 2022

since this pr I'm also having some errors some of which was just lazy code on my part. My biggest issue that I'm having trouble isolating is from an autoload that loads a bunch of resources that create instances from a named base class. I get this
Parser Error: Could not resolve class ItemBase
I'm working on getting an example to actually give the same error

one of the other issues that was easily fixed was a reference from an autoload to another autoload
play3D(null, Game.player.global_position, key, 1.0, parms)
clearly this is lazy but it worked and being a "simple" scripting language I would figure we still want the compiler to be able be ok with stuff like this

@adamscott
Copy link
Member

@dmaz Please create issues and link them to this PR. Commenting here doesn't really help fixing your issues.

@dmaz
Copy link
Contributor

dmaz commented Dec 16, 2022

yeah for sure... just haven't been able to isolate class one into an example yet

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