Skip to content

GUT broken in Godot 4.7 #816

@bitwes

Description

@bitwes

Versions

(list all versions where you have replicated the bug)

  • Godot: 4.7
  • GUT: 9.6
  • OS: Mac, but probably all

Doubling abstract classes issue

Abstract methods do not include a return type in the metadata, only implemented abstract methods have a return type.

Given

@abstract
class AbstractClass:
	@abstract
	func abstract_method() -> Variant

The metadata is

{
  "args": [],
  "default_args": [],
  "flags": 129,
  "id": 0,
  "name": "abstract_method",
  "return": {
    "class_name": "",
    "hint": 0,
    "hint_string": "",
    "name": "",
    "type": 0,
    "usage": 6
  }
}

But if you implement it

class ExtendsAbstract:
	extends AbstractClass

	func abstract_method() -> int:
		return 10

The metadata is

{
  "args": [],
  "default_args": [],
  "flags": 1,
  "id": 0,
  "name": "abstract_method",
  "return": {
    "class_name": "",
    "hint": 0,
    "hint_string": "",
    "name": "",
    "type": 2,
    "usage": 0
  }
}

Solution

Maybe a stub for return type. Otherwise you have to create a local class that implements the abastract method and use that for doubling.

Doubling and Void Return Type Issue

Given

class Example:
	func explicit_void() -> void:
		pass

	func inferred_void():
		pass

There is no way to tell the difference between the return types of explicit_void and inferred_void from the metadata. Both look like they have a void return type. Since there is no way to know, you cannot stub inferred_void to return a value.

The real issue is that you cannot have a return clause in explicit_void, but since I can't tell the difference, I cannot include a return clause in inferred_void, even though it is valid GDScript.

--- explicit_void() ---
{
  "args": [],
  "default_args": [],
  "flags": 1,
  "id": 0,
  "name": "explicit_void",
  "return": {
    "class_name": "",
    "hint": 0,
    "hint_string": "",
    "name": "",
    "type": 0,
    "usage": 6
  }
}

--- inferred_void() ---
{
  "args": [],
  "default_args": [],
  "flags": 1,
  "id": 0,
  "name": "inferred_void",
  "return": {
    "class_name": "",
    "hint": 0,
    "hint_string": "",
    "name": "",
    "type": 0,
    "usage": 6
  }
}

Solution

Maybe a stub for return type. The user can also just add a return to the method and that will change the metadata.

# This now becomes an inferred Variant return type
func inferred_void():
	return

This is probably the right answer, but GUT can't give specific messages to tell the user what should be done.

Doubles and return type enforcement issue

Godot has become more strict with function return types. In previous versions you could return null in overriden methods. This is no longer possible. The following worked in 4.6, but results in a parser error in 4.7.

class Example:
	func int_return() -> int:
		return 10

class ExtendsExample:
	extends Example

	func int_return():
		return null

Solution

I think this will require default return values for all return types. I'm not sure if they need to be changeable by the user. Should int be 0? Probably, but maybe it should be max or min int value. Should Vector2 be (0, 0)? Maybe. If you need a specific value, you should stub instead, which is what you'd have to do if it returned null. It's just that before, you would get an error about null, and now you'll get a valid value which could be misleading.

Godot Issue Ref

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions