""" This script generates docs/plugin-meta.lua. It accepts no arguments It assumes comments look like: /** * Thing * * @lua@param thing boolean * @lua@returns boolean * @exposed name */ - Do not have any useful info on '/**' and '*/' lines. - Class members are not allowed to have non-@command lines and commands different from @lua@field Valid commands are: 1. @exposeenum [dotted.name.in_lua.last_part] Define a table with keys of the enum. Values behind those keys aren't written on purpose. This generates three lines: - An type alias of [last_part] to integer, - A type description that describes available values of the enum, - A global table definition for the num 2. @lua[@command] Writes [@command] to the file as a comment, usually this is @class, @param, @return, ... @lua@class and @lua@field have special treatment when it comes to generation of spacing new lines 3. @exposed [c2.name] Generates a function definition line from the last `@lua@param`s. Non-command lines of comments are written with a space after '---' """ from pathlib import Path BOILERPLATE = """ ---@meta Chatterino2 -- This file is automatically generated from src/controllers/plugins/LuaAPI.hpp by the scripts/make_luals_meta.py script -- This file is intended to be used with LuaLS (https://luals.github.io/). -- Add the folder this file is in to "Lua.workspace.library". c2 = {} """ repo_root = Path(__file__).parent.parent lua_api_file = repo_root / "src" / "controllers" / "plugins" / "LuaAPI.hpp" lua_meta = repo_root / "docs" / "plugin-meta.lua" print("Reading from", lua_api_file.relative_to(repo_root)) print("Writing to", lua_meta.relative_to(repo_root)) with lua_api_file.open("r") as f: lines = f.read().splitlines() # Are we in a doc comment? comment: bool = False # Last `@lua@param`s seen - for @exposed generation last_params_names: list[str] = [] # Are we in a `@lua@class` definition? - makes newlines around @lua@class and @lua@field prettier is_class = False # The name of the next enum in lua world expose_next_enum_as: str | None = None # Name of the current enum in c++ world, used to generate internal typenames for current_enum_name: str | None = None with lua_meta.open("w") as out: out.write(BOILERPLATE[1:]) # skip the newline after triple quote for line in lines: line = line.strip() if line.startswith("enum class "): line = line.removeprefix("enum class ") temp = line.split(" ", 2) current_enum_name = temp[0] if not expose_next_enum_as: print( f"Skipping enum {current_enum_name}, there wasn't a @exposeenum command" ) current_enum_name = None continue current_enum_name = expose_next_enum_as.split(".", 1)[-1] out.write("---@alias " + current_enum_name + " integer\n") out.write("---@type { ") # temp[1] is '{' if len(temp) == 2: # no values on this line continue line = temp[2] if current_enum_name is not None: for i, tok in enumerate(line.split(" ")): if tok == "};": break entry = tok.removesuffix(",") if i != 0: out.write(", ") out.write(entry + ": " + current_enum_name) out.write(" }\n" f"{expose_next_enum_as} = {{}}\n") print(f"Wrote enum {expose_next_enum_as} => {current_enum_name}") current_enum_name = None expose_next_enum_as = None continue if line.startswith("/**"): comment = True continue elif "*/" in line: comment = False if not is_class: out.write("\n") continue if not comment: continue line = line.replace("*", "", 1).lstrip() if line == "": out.write("---\n") elif line.startswith("@exposeenum "): expose_next_enum_as = line.split(" ", 1)[1] elif line.startswith("@exposed "): exp = line.replace("@exposed ", "", 1) params = ", ".join(last_params_names) out.write(f"function {exp}({params}) end\n") print(f"Wrote function {exp}(...)") last_params_names = [] elif line.startswith("@lua"): command = line.replace("@lua", "", 1) if command.startswith("@param"): last_params_names.append(command.split(" ", 2)[1]) elif command.startswith("@class"): print(f"Writing {command}") if is_class: out.write("\n") is_class = True elif not command.startswith("@field"): is_class = False out.write("---" + command + "\n") else: if is_class: is_class = False out.write("\n") # note the space difference from the branch above out.write("--- " + line + "\n")