godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.7k stars 20.12k forks source link

GDScript: empty class definition leads to error somewhere else #56703

Open just-like-that opened 2 years ago

just-like-that commented 2 years ago

Godot version

3.4.2

System information

Windows 10

Issue description

Implementing a script class including an inner class with "pass" as body in one line leads to error some place else.

I created the inner class with a given name as a temporary placeholder - prior to full implementation - to use it as an argument in other functions.

The error message itself is just misleading as it refers to a place in code which has nothing to do with the error itself. I know this is a minor thing. It cost me a bit to figure out what the real cause was.

Steps to reproduce

Inner class definition in single line including pass as body.

class Whatever: pass

# bug_class_one_liner.gd
extends Node2D

# line 07 leads to
# 'error(16,1): The method "to_local" isn't declared in the current class.'
# (line 08 to 09 works - same code including line-break.)
class WorxNot: pass
#class Worx:
#   pass

var var1

var var2

func icon_at(pos: Vector2):
    pos = to_local(pos)
    # other statements

leads to error at line "pos = to_local(pos)" in function icon_at().

Minimal reproduction project

bug_class_one_liner.zip

Calinou commented 2 years ago

I can't reproduce this on master b6b81e800, so this is fixed in the new GDScript implementation. I can reproduce this on 3.x cd47ff141 though.

image

arlez80 commented 2 years ago

I also found this bug at Godot 3.4.3 and 3.4.4. It will be define all functions/members under empty class.

one_line.gd

extends Node

class TestClass: pass

# These are define under TestClass
var a:int = 42
var b:int = 0

func test( ):
    print( "It's works" )
    return 1024

test.gd

extends Node

func _ready( ):
    var one_line = preload("one_line.gd")

    # These are error.
    # var one_line_inst = one_line.new( )
    # print( one_line_inst.a )
    # print( one_line_inst.b )
    # print( one_line_inst.test( ) )

    # These are ok.
    var test_class = one_line.TestClass.new( )
    print( test_class.a )
    print( test_class.b )
    print( test_class.test( ) )
kdiduk commented 2 years ago

If no one has started working on it yet, I can make a fix for this bug and submit a PR. Looks like the fix for this should be simple.

Calinou commented 2 years ago

If no one has started working on it yet, I can make a fix for this bug and submit a PR. Looks like the fix for this should be simple.

Feel free to open a pull request for this :slightly_smiling_face:

kdiduk commented 2 years ago

GDScript grammar specification says that after the colon in the inner class declaration there should be a newline:

innerClass = "class" IDENTIFIER [ inheritance ] ":" NEWLINE
    INDENT [ inheritance NEWLINE ] topLevelDecl { topLevelDecl } DEDENT ;

I can make a fix according to this spec.

On the other hand, I can make a fix so that it would allow a statement like pass on the same line after the colon, but then the documentation for GDScript grammar should be updated (for 4.0 as well :slightly_smiling_face:).

kdiduk commented 2 years ago

The fix for this issue is ready here #61993, waiting to be merged :slightly_smiling_face:

just-like-that commented 2 years ago

Thank you very much. Looking forward 😃

On Jun 28, 2022, 10:39, at 10:39, Kirill Diduk @.***> wrote:

The fix for this issue is ready here #61993, waiting to be merged :slightly_smiling_face:

-- Reply to this email directly or view it on GitHub: https://github.com/godotengine/godot/issues/56703#issuecomment-1168415583 You are receiving this because you authored the thread.

Message ID: @.***>

akien-mga commented 2 years ago

Fixed by #61993.

akien-mga commented 1 month ago

Reopening as #61993 was reverted due to regressions.