Skip to content

Conversation

Meorge
Copy link
Contributor

@Meorge Meorge commented Apr 3, 2025

Closes godotengine/godot-proposals#12105 .

This PR adds a new warning, DEPRECATED_IDENTIFIER, to GDScript. As the name suggests, it activates when a line contains an identifier that has been marked as deprecated in the documentation.

CleanShot 2025-04-02 at 21 55 01@2x

Tested cases

  • User-defined method call
  • User-defined method call in inner class
  • Native method call
  • Main class of file as type annotation
  • Main class of file for constructors, static methods, etc
  • Inner class as type annotation
  • Inner class for constructors, static methods, etc
  • Native class as type annotation
  • Native class for constructors, static methods, etc
  • Autoload with global name as type annotation
  • Autoload with global name for constructors, methods, etc
  • User-defined class constant
  • User-defined class constant in inner class
  • User-defined local constant
  • User-defined named enum
  • User-defined named enum in inner class
  • Individual value in user-defined anonymous enum
  • Individual value in user-defined anonymous enum in inner class
  • Individual value in user-defined named enum
  • Individual value in user-defined named enum in inner class
  • Individual value in native enum
  • Constant in global scope
  • Local variable
  • User-defined property
  • User-defined property in inner class
  • Native property
  • User-defined signal
  • User-defined signal in inner class
  • Native signal

To Do

  • Get all the cases working!
  • Make the message more professional
  • Add context to the message (for example, instead of "identifier" say "variable", "method", etc)
  • Clean up some code that goes against Godot's code style (I think I used an auto or two)
  • Re-run tests to generate new warning output
    • Add tests to detect use of deprecated identifiers?

@Mickeon
Copy link
Member

Mickeon commented Apr 3, 2025

I foresee that if this is implemented, users would rather the warning be a strikethrough on the deprecated subject (even if currently CodeEdit cannot support it)

@Meorge
Copy link
Contributor Author

Meorge commented Apr 3, 2025

Another PR of mine, #100019, adds a strikethrough to deprecated items in the code completion list, which is similar at least 🙂

@Meorge
Copy link
Contributor Author

Meorge commented Apr 6, 2025

There are still a few cases to figure out, and then the other tasks to complete as well, but I think this is close enough to complete now that it'd make sense to open it for review. I'm also keeping the commits separate for now (i.e., not squashing) since I'm trying to include one type of detection per commit so I can tell them apart easier. Once it's ready for merging, I'll squash and force push.

@Meorge Meorge marked this pull request as ready for review April 6, 2025 05:29
@Meorge Meorge requested a review from a team as a code owner April 6, 2025 05:29
StringName enum_type = type.enum_type; // Something like MyEnum.
GDScriptParser::ClassNode *class_type = type.class_type;
StringName class_name = class_type ? class_type->identifier->name : "@GlobalScope";
DocTools *dd = EditorHelp::get_doc_data();
Copy link
Member

Choose a reason for hiding this comment

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

There's a warning here but I bring it up to attention as well. You're calling get_doc_data here even though it's already done above at line 1991

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think I saw that in my terminal output, so thanks for catching that! I'll have to take a look at it again and confirm it's working properly.

@Meorge
Copy link
Contributor Author

Meorge commented Apr 7, 2025

All of my test cases appear to be working now!

I would really appreciate it if someone more familiar with the GDScript parser could take a look at gdscript_analyzer.cpp:4033. The current way I'm distinguishing native and user-defined enums feels a bit hacky, so if there's a better way to do it then I'd be all for it.

I've also noticed that as a little quirk of the identifier recognition, accessing a deprecated property from within its getter or setter causes those lines to trigger the warning.

CleanShot 2025-04-07 at 08 35 53@2x

Ultimately, it does make sense, I guess - you are using the deprecated identifier - but in this specific context, it's a bit funny for it to complain about.

@Meorge
Copy link
Contributor Author

Meorge commented Apr 8, 2025

Warnings now display information about what exactly is deprecated!

CleanShot 2025-04-07 at 21 30 58@2x

The only case that doesn't seem to work right is when an autoload's global variable name is used as a type specifier:

var my_autoload: SomeAutoload

I'm having trouble extracting the name SomeAutoload to display in the warning. But I'm not entirely sure if that should be allowed. In any case, for right now it just defaults to "The class is deprecated".

I tried regenerating the GDScript tests, but one of them is causing a hard crash. I'll have to look more at it over the next couple of days when I have time.

@Meorge Meorge force-pushed the feat/deprecated-warning branch from 37e9286 to bdd6cd1 Compare April 8, 2025 05:09
@ydeltastar
Copy link
Contributor

ydeltastar commented Apr 8, 2025

I'm getting a crash while typing an enum name.

extends Node2D

enum MyEnum {
	OPTION1,
	OPTION2
}

# Type MyEnum here to crash.
var my_enum:

I would really appreciate it if someone more familiar with the GDScript parser could take a look at gdscript_analyzer.cpp:4033. The current way I'm distinguishing native and user-defined enums feels a bit hacky, so if there's a better way to do it then I'd be all for it.

There is CoreConstants::is_global_enum(name).

I'm having trouble extracting the name SomeAutoload to display in the warning. But I'm not entirely sure if that should be allowed. In any case, for right now it just defaults to "The class is deprecated".

Autoloads are more a project setting than a class type but the parser shows the global name and path when there are errors. You can find the name like this p_assignable->datatype_specifier->type_chain[0]->name.

By the way, you can build with warnings=extra werror=yes strict_checks=yes to catch most of these CI issues locally.

@Meorge Meorge force-pushed the feat/deprecated-warning branch 2 times, most recently from 1fde830 to 314605d Compare April 17, 2025 20:42
@Meorge Meorge requested a review from a team as a code owner April 17, 2025 20:42
Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

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

Tested locally, it works as expected. Code looks good to me. Great work on the comprehensive integration tests 🙂

image

I've looked at the TODOs in code comments but can't think of a better way to implement these right now.

PS: I noticed --script --check-only does not print any warnings when the script contains warnings. We should look into implementing this in a separate PR to make it more viable for CI use, along with an additional --warnings-as-errors CLI argument (which would complement #99254 nicely).

@Meorge
Copy link
Contributor Author

Meorge commented Apr 18, 2025

Thank you very much! 😄 I had that script for testing on my side, and realized it would make for a nice comprehensive unit test file.

It seems I have run into a bit of a pickle with the tests, though. It looks like at least the RenderingServer may not be constructed when running tests - trying to instantiate AnimatedTexture or TileMap in a test file causes the test to fail with a SIGSEGV error. When I add the following to the beginning of AnimatedTexture's constructor, on the master branch:

ERR_FAIL_NULL_MSG(RS::get_singleton(), "RenderingServer is null, so AnimatedTexture can't set itself up");

It prints out in the test results.

I've changed it to use VisualShaderNodeComment for a native class and AStarGrid2D.new().size for a native property, which seem to partially work.
AnimatedTexture is deprecated, of course, so I don't know how much effort should be put into updating it to work with tests. But this also happens with Control.new(), so that should probably be looked into further.

But tests on some other platforms appear to still be failing 🙁

modules\gdscript\tests\gdscript_test_runner.cpp(217): ERROR: CHECK( result.passed ) is NOT correct!
  values: CHECK( false )
  logged: D:/a/godot/godot/modules/gdscript/tests/scripts/runtime/features/call_native_static_method_validated.gd
          GDTEST_OK
false
166362874999 - Stray Node:  (Type: AnimationPlayer)

@Meorge Meorge force-pushed the feat/deprecated-warning branch from 983b14e to 880dd04 Compare April 18, 2025 04:48
@Meorge Meorge requested a review from a team as a code owner April 18, 2025 04:48
@Meorge Meorge force-pushed the feat/deprecated-warning branch 2 times, most recently from c5d4dac to 9b9b711 Compare April 21, 2025 04:56
@Meorge Meorge force-pushed the feat/deprecated-warning branch 3 times, most recently from 35d9438 to 82c9b92 Compare April 26, 2025 04:16
@Repiteo Repiteo modified the milestones: 4.x, 4.5 Apr 26, 2025
@Meorge Meorge force-pushed the feat/deprecated-warning branch 2 times, most recently from 624bc89 to 10d8954 Compare May 16, 2025 17:56
@Meorge Meorge force-pushed the feat/deprecated-warning branch 5 times, most recently from 21c7498 to 593603e Compare May 28, 2025 17:59
@Meorge Meorge force-pushed the feat/deprecated-warning branch 3 times, most recently from 6709959 to b7f23be Compare June 3, 2025 03:19
@Meorge Meorge force-pushed the feat/deprecated-warning branch 5 times, most recently from d1af266 to da55f72 Compare June 14, 2025 20:48
@Meorge Meorge force-pushed the feat/deprecated-warning branch from da55f72 to dcecc7b Compare June 17, 2025 15:54
@Repiteo Repiteo modified the milestones: 4.5, 4.6 Jun 19, 2025
@Meorge Meorge force-pushed the feat/deprecated-warning branch 3 times, most recently from 56cc5c2 to b6d5083 Compare July 5, 2025 04:45
@Meorge Meorge force-pushed the feat/deprecated-warning branch 2 times, most recently from 9b88a0a to a429bdf Compare September 18, 2025 23:13
@Meorge Meorge force-pushed the feat/deprecated-warning branch 4 times, most recently from 6e03308 to d4a5b47 Compare September 25, 2025 15:42
Note to self about methods for other non-user classes

Display warning for deprecated methods on built-in classes (like AnimationPlayer)

Protect from doc data being null

Push warning for user-defined signal marked as `@deprecated`

Recognize user-defined constant marked as `@deprecated`

Recognize user-defined enums and values in anonymous enums marked as `@deprecated`

Recognize user-defined property marked as `@deprecated`

Recognize local variable marked as `@deprecated`

Recognize built-in class (such as for constructors or static methods) marked as deprecated

Recognize global autoload marked as `@deprecated`

Recognize constant in `@GlobalScope` marked as deprecated

Recognize global script class(?) marked as deprecated

Recognize types from type hints in assignment statements marked as deprecated

Recognize signal from native class marked as deprecated

Recognize property from native class marked as deprecated

Recognize constant from native class marked as deprecated

Recognize enum from native class marked as deprecated

Recognize individual value in enum marked as deprecated

Recognize local constant marked as deprecated

Recognize inner class in expression marked as deprecated

Recognize individual value in user-defined named enum in inner class marked as deprecated

Fix recognition of individual value from native enum with enum name marked as deprecated

Remove some duplicate code

Update modules/gdscript/gdscript_warning.cpp

Co-authored-by: Micky <[email protected]>

Provide context for warning, including type and name, when available

Get rid of `auto` usages

Fix some crashes when trying to access a null identifier

Add test for warning

Fix variable redeclaration

Update test to use classes that don't crash

Try removing AnimationPlayer case from unit test

Add description in documentation for DEPRECATED_IDENTIFIER

Replace DEBUG_ENABLED with TOOLS_ENABLED

Add explanation for test case being commented out

Update doc/classes/ProjectSettings.xml

Co-authored-by: Micky <[email protected]>

Update test

Apply suggestions from code review

Co-authored-by: A Thousand Ships <[email protected]>

# Conflicts:
#	modules/gdscript/gdscript_analyzer.cpp

Update modules/gdscript/gdscript_analyzer.cpp

Co-authored-by: A Thousand Ships <[email protected]>
@Meorge Meorge force-pushed the feat/deprecated-warning branch from d4a5b47 to 1c28228 Compare September 26, 2025 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add warning for use of deprecated identifier in GDScript
7 participants