Skip to content

Fix for lua 5.5 and read-only for variables#811

Open
LecrisUT wants to merge 1 commit intoTACC:mainfrom
LecrisUT:fix/lua5.5
Open

Fix for lua 5.5 and read-only for variables#811
LecrisUT wants to merge 1 commit intoTACC:mainfrom
LecrisUT:fix/lua5.5

Conversation

@LecrisUT
Copy link
Contributor

Used a script to go through all lua files and try to patch the cases where this needs a patch

If anyone needs the script

Details
#!/usr/bin/python3
# /// script
# dependencies = [
#   "luaparser",
# ]
# ///

import argparse
import re
from pathlib import Path
import logging

from luaparser import ast, astnodes


logging.basicConfig(level="INFO")
logger = logging.getLogger(Path(__file__).name)

ASSIGN_PATTERN = re.compile(r"(\w+)(\s+)=(\s+)")
REPLACE_PATTERN = r"local \1\2=\3"


def patch_lua_file(file: Path) -> None:
    content = file.read_text()
    tree = ast.parse(content)
    lines_to_patch = []
    for node in ast.walk(tree):
        if isinstance(node, astnodes.Forin):
            for_targets = node.targets
            for content_node in ast.walk(node):
                if isinstance(content_node, astnodes.LocalAssign):
                    # If we already patched it, do not check it again
                    if matched_target := next(
                        (
                            assign_target
                            for assign_target in content_node.targets
                            if assign_target in for_targets
                        ),
                        None,
                    ):
                        for_targets.remove(matched_target)
                elif isinstance(content_node, astnodes.Assign):
                    # Otherwise get the line so that we patch it and ignore it afterwards
                    if matched_target := next(
                        (
                            assign_target
                            for assign_target in content_node.targets
                            if assign_target in for_targets
                        ),
                        None,
                    ):
                        lines_to_patch.append(content_node.first_token.line)
                        for_targets.remove(matched_target)
    if not lines_to_patch:
        return
    logger.info("File %s needs patching for lines %s", file, lines_to_patch)
    fixed_content = ""
    for indx, line in enumerate(content.splitlines(keepends=True), start=1):
        if indx in lines_to_patch:
            line = ASSIGN_PATTERN.sub(REPLACE_PATTERN, line)
        fixed_content += line
    file.write_text(fixed_content)


def main(args: argparse.Namespace) -> None:
    args.workdir: Path
    args.files: str
    for file in args.workdir.glob(args.files):
        if str(file) in args.skip:
            logger.info("Skipping file: %s", file)
        logger.debug("Trying to patch: %s", file)
        try:
            patch_lua_file(file)
        except Exception:
            logger.error("Failed to parse: %s", file)


parser = argparse.ArgumentParser(
    description="Fix lua files after 5.5 chang making for loop variables."
)
parser.add_argument(
    "files",
    help="Files to patch. Can be a glob pattern.",
)
parser.add_argument(
    "--workdir",
    type=Path,
    default=Path("."),
    metavar="PATH",
    help="Base directory where the files are calculated from. Defaults to CWD.",
)
parser.add_argument(
    "--skip",
    action="append",
    metavar="PATH",
    help="Files to skip. Can be provided multiple times.",
    default=[],
)
args = parser.parse_args()
main(args)

Kudos to luaparser which enabled this programatic handling

@LecrisUT LecrisUT mentioned this pull request Mar 25, 2026
@LecrisUT
Copy link
Contributor Author

Note, it is possible some files were missed because either they did not have .lua suffix or it did not manage to read the lua file. Let me know which files might have been missed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant