Skip to content

Commit f79289f

Browse files
committed
Add function overload support for Register events
1 parent 931bdda commit f79289f

File tree

4 files changed

+106
-12
lines changed

4 files changed

+106
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Download the latest generated definitions from the build workflow action, altern
2222
## Installation
2323
1. **Install LuaLS**: Follow the [LuaLS installation instructions](https://luals.github.io/#vscode-install).
2424
2. **Configure Your Workspace**: Point your workspace/LSP configuration to the location of the generated definitions.
25+
3. **Enable parameter inference**: In the LuaLS configuration, enable Lua.type.inferParamType, this is required for callback parameters to function properly.
2526

2627
## Usage
2728
1. Install Python 3, Pip, and dependencies:

parser.py

Lines changed: 98 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import os
22
import sys
3+
import re
34
from bs4 import BeautifulSoup
45

6+
debug = False
7+
58
def extract_method_info(soup):
69
method_section = soup.find('h1')
710
class_name_tag = method_section.find_next()
@@ -105,6 +108,62 @@ def extract_argument_name_opt(argument_name):
105108
argument_optional_value = optional_part
106109
return argument_name, argument_optional, argument_optional_value
107110

111+
def extract_table(soup):
112+
# Extract the header row
113+
header = soup.find('thead')
114+
if header is None:
115+
return []
116+
117+
header_row = header.find_all('th')
118+
if not header_row:
119+
return []
120+
121+
# Extract the column names (keys) from the header
122+
headers = [header.get_text(strip=True) for header in header_row]
123+
124+
# Find all the table rows, skipping the header
125+
rows = soup.find_all('tr')[1:]
126+
if not rows:
127+
return []
128+
129+
row_list = []
130+
131+
for row in rows:
132+
cells = row.find_all('td')
133+
if not cells:
134+
return []
135+
136+
# Ensure the row has the same number of columns as the header
137+
if len(cells) != len(headers):
138+
continue # Skip rows that don't match the header
139+
140+
cell_data = {}
141+
for idx, cell in enumerate(cells):
142+
# Check if the cell contains any <span> elements
143+
if cell.find_all('span'):
144+
cell_data[headers[idx]] = extract_parameters(cell)
145+
else:
146+
cell_data[headers[idx]] = cell.get_text(strip=True)
147+
148+
row_list.append(cell_data)
149+
150+
return row_list
151+
152+
def extract_parameters(cell):
153+
parameters = {}
154+
155+
# Find all <span> tags in the 'cell'
156+
spans = cell.find_all('span')
157+
158+
# Extract the 'title' as the key and text as the value
159+
for span in spans:
160+
title = span.get('title')
161+
text = span.get_text(strip=True)
162+
if title:
163+
parameters[text] = title
164+
165+
return parameters
166+
108167
def extract_return_values(soup):
109168
returns_section = soup.find('h2', id='returns')
110169
if returns_section is None:
@@ -143,9 +202,9 @@ def extract_return_values(soup):
143202
return_values_list.append({'type': return_type, 'name': return_name, 'description': return_description})
144203
return return_values_list
145204

146-
def write_lua_stub(class_name, method_string, arguments_list, return_values_list, output_directory):
205+
def write_lua_stub(class_name, method_string, arguments_list, table_list, return_values_list, output_directory):
147206
with open(os.path.join(output_directory, class_name + ".lua"), "a") as lua_file:
148-
# Write the parameter and return values
207+
# Write the parameter definitions
149208
for argument in arguments_list:
150209
lua_file.write("---@param " + argument['name'])
151210
if argument['optional']:
@@ -157,6 +216,27 @@ def write_lua_stub(class_name, method_string, arguments_list, return_values_list
157216
lua_file.write(" Default value: (" + argument['optional_val'] + ")")
158217

159218
lua_file.write(" " + argument['description'] + "\n")
219+
220+
# Hard code table parsing for register events for now (function overload definitions)
221+
if(class_name == "Global") and re.match(r"^Register\w+Event$", method_string):
222+
for row in table_list:
223+
# Only create function overloads for properly formatted parameter data
224+
if 'Parameters' in row and isinstance(row['Parameters'], dict):
225+
lua_file.write("---@overload fun(event: " + row['ID'] + ", func: fun(")
226+
227+
# Loop through parameters and check for 'event', we want to define this as the event ID and not a type
228+
params = []
229+
for key, value in row['Parameters'].items():
230+
if key == 'event':
231+
params.append(f'{key}: {row["ID"]}')
232+
else:
233+
params.append(f'{key}: {value}')
234+
235+
# Join the parameters and write to the file
236+
lua_file.write(', '.join(params))
237+
lua_file.write("), shots?: number): function\n")
238+
239+
# Write the return value definitions
160240
for return_value in return_values_list:
161241
lua_file.write("---@return " + return_value['type'] + " " + return_value['name'] + " " + return_value['description'] + "\n")
162242

@@ -173,7 +253,9 @@ def write_lua_stub(class_name, method_string, arguments_list, return_values_list
173253

174254
lua_file.write(") end\n\n")
175255

176-
print(f"'{method_string}' stubs appended to '{class_name}.lua'")
256+
global debug
257+
if debug:
258+
print(f"'{method_string}' stubs appended to '{class_name}.lua'")
177259

178260
def write_lua_class(class_name, inherited_objects, output_directory):
179261
with open(os.path.join(output_directory, class_name + ".lua"), "w") as lua_file:
@@ -184,8 +266,10 @@ def write_lua_class(class_name, inherited_objects, output_directory):
184266
lua_file.write(f": {', '.join(inherited_objects)}")
185267

186268
lua_file.write(f"\n{class_name} = {{}}\n\n")
187-
188-
print(f"'{class_name}' class information appended to '{class_name}.lua'")
269+
270+
global debug
271+
if debug:
272+
print(f"'{class_name}' class information appended to '{class_name}.lua'")
189273

190274
def process_html_file(html_file, filename, output_directory):
191275
with open(html_file, "r") as f:
@@ -202,19 +286,25 @@ def process_html_file(html_file, filename, output_directory):
202286
# Otherwise process like normal
203287
class_name, method_string = extract_method_info(soup)
204288
arguments_list = extract_arguments(soup)
289+
table_list = extract_table(soup)
205290
return_values_list = extract_return_values(soup)
206291

207-
write_lua_stub(class_name, method_string, arguments_list, return_values_list, output_directory)
292+
write_lua_stub(class_name, method_string, arguments_list, table_list, return_values_list, output_directory)
208293

209294
def main():
210295
# Check if command-line arguments are provided
211-
if len(sys.argv) != 3:
212-
print("Usage: python parser.py <html_input_directory> <output_directory>")
296+
if len(sys.argv) < 3:
297+
print("Usage: python parser.py <html_input_directory> <output_directory> <debug=false>")
213298
sys.exit(1)
214299

215300
directory = sys.argv[1]
216301
output_directory = sys.argv[2]
217302

303+
# Debug (Optional) - Default to false if not provided
304+
if(sys.argv[3]):
305+
global debug
306+
debug = True if sys.argv[3].lower() == 'true' else False
307+
218308
# Special case to process our class definitions
219309
html_file = os.path.join(directory, "index.html")
220310
process_html_file(html_file, "index.html", output_directory)

runParser.ps1

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
# Define the paths to the parser script and the parent directory containing Eluna API HTML files
2-
$parserScriptPath = "C:\Path\To\parser.py"
3-
$htmlParentDirectory = "C:\Path\To\ElunaLuaEngine.github.io-master"
2+
$parserScriptPath = "C:\Users\foereaper\Desktop\luaLS\LuaLS-Eluna-Parser\parser.py"
3+
$htmlParentDirectory = "C:\Users\foereaper\Desktop\tc\elunatrinitywotlk\src\server\game\LuaEngine\docs\build"
44

55
# Define the output directory for the LuaLS workspace
6-
$outputDirectory = "C:\Path\To\LuaLS\Workspace"
6+
$outputDirectory = "C:\Users\foereaper\Desktop\luaLS\LuaLS-Eluna-Parser\build"
7+
8+
$debug = $false
79

810
# Define the list of subdirectories to process
911
$subdirectories = @("Aura", "BattleGround", "Corpse", "Creature", "ElunaQuery", "GameObject", "Group", "Guild", "Global", "Item", "Map", "Object", "Player", "Quest", "Spell", "Unit", "Vehicle", "WorldObject", "WorldPacket")
1012

1113
# Iterate over each subdirectory
1214
foreach ($subdir in $subdirectories) {
1315
$htmlDirectory = Join-Path -Path $htmlParentDirectory -ChildPath $subdir
14-
python $parserScriptPath $htmlDirectory $outputDirectory
16+
python $parserScriptPath $htmlDirectory $outputDirectory $debug
1517
}

0 commit comments

Comments
 (0)