Scony / godot-gdscript-toolkit

Independent set of GDScript tools - parser, linter, formatter, and more
MIT License
994 stars 69 forks source link

gdformat DedentError when using multiple lambdas #339

Open PastMoments opened 18 hours ago

PastMoments commented 18 hours ago

I'm using 4.3.3 off of master, since I saw #191 and thought it would help, but master still has this issue.

func _ready():
    var string_array: Array[String]
    var result := string_array.map(func(a): return a).filter(
        func(has_underscore):
            return (has_underscore.begins_with("a") or has_underscore.begins_with("b"))
    )

This gives the following error. I'm not 100% sure the conditions to cause this

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Scripts\gdformat.exe\__main__.py", line 7, in <module>
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\formatter\__main__.py", line 92, in main
    _check_files_formatting(
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\formatter\__main__.py", line 175, in _check_files_formatting
    success, actually_formatted, formatted_code = _format_code(
                                                  ^^^^^^^^^^^^^
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\formatter\__main__.py", line 289, in _format_code
    check_formatting_safety(
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\formatter\__init__.py", line 35, in check_formatting_safety
    formatted_code_parse_tree = parser.parse(formatted_code, gather_metadata=True)
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\parser\parser.py", line 54, in parse
    self._parser_with_metadata.parse(adjusted_code)
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\lark\lark.py", line 658, in parse
    return self.parser.parse(text, start=start, on_error=on_error)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\lark\parser_frontends.py", line 104, in parse
    return self.parser.parse(stream, chosen_start, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\lark\parsers\lalr_parser.py", line 42, in parse
    return self.parser.parse(lexer, start)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\lark\parsers\lalr_parser.py", line 88, in parse
    return self.parse_from_state(parser_state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\lark\parsers\lalr_parser.py", line 100, in parse_from_state
    for token in state.lexer.lex(state):
                 ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\parser\gdscript_indenter.py", line 60, in _process
    yield from self.handle_NL(token)
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\parser\gdscript_indenter.py", line 28, in handle_NL
    yield from self._handle_lambdas_on_newline_token_in_parens(
  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\parser\gdscript_indenter.py", line 105, in _handle_lambdas_on_newline_token_in_parens
    raise DedentError(
lark.indenter.DedentError: Unexpected dedent to column 8. Expected dedent to 4
jamie-pate commented 2 hours ago

A workaround for this issue is to properly format nested lambda functions before hand, allowing the parser to continue.

It would be nice if _format_code() had an exception case for Exception so it could print out the file that was being scanned (and raise it again)

  File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python312\Lib\site-packages\gdtoolkit\formatter\__main__.py", line 175, in _check_files_formatting
    success, actually_formatted, formatted_code = _format_code(
                                                  ^^^^^^^^^^^^^
Scony commented 3 minutes ago

Thanks for reporting! Looks like you've discovered another flavor of https://github.com/Scony/godot-gdscript-toolkit/issues/326 This is clearly a bug.