186 lines
7.2 KiB
Python
186 lines
7.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Convert C# 7/8 features in ONIAgentBridge.cs to C# 6 compatible code.
|
|
|
|
DEPRECATED: The mod source (ONIAgentBridge.cs) has been rewritten to use if-else chains.
|
|
This script is kept for historical reference only and should not be run on the current source.
|
|
"""
|
|
|
|
import re
|
|
|
|
with open('mod/ONIAgentBridge.cs', 'r') as f:
|
|
content = f.read()
|
|
|
|
# 1. Convert tuple switch at ProcessRequest to if-else chain
|
|
# Find the switch and replace it
|
|
old_switch_start = """ switch (path, method)
|
|
{"""
|
|
|
|
# Read the entire switch block and reconstruct
|
|
lines = content.split('\n')
|
|
new_lines = []
|
|
i = 0
|
|
while i < len(lines):
|
|
line = lines[i]
|
|
|
|
# Find the C# 7 tuple switch
|
|
if 'switch (path, method)' in line and '{' in lines[i+1]:
|
|
new_lines.append(' // --- C# 6 compatible dispatch ---')
|
|
new_lines.append(' bool _handled = false;')
|
|
i += 2 # skip "switch (path, method)" and "{"
|
|
|
|
while i < len(lines):
|
|
stripped = lines[i].strip()
|
|
|
|
# Check for case pattern: case ("...", "..."):
|
|
m = re.match(r'case \("([^"]+)", "([^"]+)"\):', stripped)
|
|
if m:
|
|
endpoint = m.group(1)
|
|
method = m.group(2)
|
|
indent = lines[i][:len(lines[i]) - len(lines[i].lstrip())]
|
|
new_lines.append(f'{indent}else if (path == "{endpoint}" && method == "{method}")')
|
|
new_lines.append(f'{indent}{{')
|
|
new_lines.append(f'{indent} _handled = true;')
|
|
i += 1
|
|
# Copy lines until "break;"
|
|
while i < len(lines) and lines[i].strip() != 'break;':
|
|
new_lines.append(lines[i])
|
|
i += 1
|
|
new_lines.append(f'{indent}}}')
|
|
i += 1 # skip "break;"
|
|
continue
|
|
|
|
# Check for default case
|
|
if stripped == 'default:':
|
|
i += 1
|
|
# Skip the opening brace
|
|
if lines[i].strip() == '{':
|
|
i += 1
|
|
new_lines.append(' if (!_handled)')
|
|
new_lines.append(' {')
|
|
while i < len(lines):
|
|
if lines[i].strip() == '}' and not _is_end_of_method(lines, i):
|
|
# This could be the switch closing brace
|
|
# Check if next line is the method closing
|
|
break
|
|
new_lines.append(lines[i])
|
|
i += 1
|
|
new_lines.append(' }')
|
|
# Skip the closing brace of the switch
|
|
if lines[i].strip() == '}':
|
|
i += 1
|
|
continue
|
|
|
|
# Check for closing brace of switch
|
|
if stripped == '}':
|
|
i += 1
|
|
break
|
|
|
|
# Any other content inside switch (shouldn't happen)
|
|
new_lines.append(lines[i])
|
|
i += 1
|
|
continue
|
|
|
|
new_lines.append(line)
|
|
i += 1
|
|
|
|
content = '\n'.join(new_lines)
|
|
|
|
def _is_end_of_method(lines, idx):
|
|
"""Check if this } ends a method (next non-blank is a method or class member)."""
|
|
for j in range(idx+1, min(idx+10, len(lines))):
|
|
s = lines[j].strip()
|
|
if s == '' or s.startswith('//') or s.startswith('/*'):
|
|
continue
|
|
if s.startswith('private ') or s.startswith('public ') or s.startswith('internal ') or s.startswith('static ') or s.startswith('}'):
|
|
return True
|
|
return False
|
|
return False
|
|
|
|
# 2. Fix switch expressions (C# 8): `wireType switch { ... }` -> if-else
|
|
# Pattern: string buildingId = wireType switch { "heavy" => "HeaviWatWire", ... }
|
|
def fix_switch_expr(match):
|
|
full = match.group(0)
|
|
var_name = match.group(1)
|
|
# Parse the switch arms
|
|
# Extract the expression after "= "
|
|
body = match.group(2)
|
|
return full # placeholder, we'll handle below
|
|
|
|
# Fix: string buildingId = wireType switch { "heavy" => "HeaviWatWire", _ => "Wire" };
|
|
# Convert to: string buildingId; if (wireType == "heavy") buildingId = "HeaviWatWire"; else ...
|
|
for pattern in [
|
|
(r'wireType switch\s*\{([^}]+)\}', 'wireType'),
|
|
(r'error switch\s*\{([^}]+)\}', 'error'),
|
|
(r'i switch\s*\{([^}]+)\}', 'i'),
|
|
]:
|
|
pat, varname = pattern
|
|
matches = list(re.finditer(pat, content))
|
|
for m in reversed(matches):
|
|
body = m.group(1)
|
|
arms = re.findall(r'"([^"]*)"\s*=>\s*"([^"]*)"', body)
|
|
default = re.findall(r'_\s*=>\s*(null|"[^"]*")', body)
|
|
|
|
if varname == 'i':
|
|
# label assignment
|
|
replacements = []
|
|
for key, val in arms:
|
|
replacements.append(f' if ({varname} == {key}) label = "{val}";')
|
|
if default:
|
|
replacements.append(f' else label = {default[0]};')
|
|
new_code = '\n'.join(replacements)
|
|
else:
|
|
# Find the variable being assigned
|
|
start = m.start()
|
|
# Look backwards to find the variable name
|
|
line_start = content.rfind('\n', 0, start) + 1
|
|
line_before = content[line_start:start]
|
|
var_match = re.match(r'\s*(?:\w+\s+)?(\w+)\s*=\s*$', line_before)
|
|
|
|
indent = ' ' * 16
|
|
if varname == 'wireType':
|
|
# Multiple instances in wire building, find each by context
|
|
context_before = content[max(0,start-200):start]
|
|
if 'bridgeId' in context_before:
|
|
varname_full = 'bridgeId'
|
|
else:
|
|
varname_full = 'buildingId'
|
|
else:
|
|
varname_full = varname
|
|
|
|
lines_code = [f' string {varname_full};']
|
|
first = True
|
|
for key, val in arms:
|
|
prefix = 'if' if first else 'else if'
|
|
lines_code.append(f' {prefix} ({varname} == "{key}") {varname_full} = "{val}";')
|
|
first = False
|
|
if default:
|
|
dval = default[0]
|
|
lines_code.append(f' else {varname_full} = {dval};')
|
|
|
|
new_code = '\n'.join(lines_code)
|
|
|
|
# Replace the assignment line + switch expression
|
|
# Find the full assignment
|
|
assign_start = content.rfind('\n', 0, start)
|
|
assign_end = m.end()
|
|
while assign_end < len(content) and content[assign_end] != '\n':
|
|
assign_end += 1
|
|
old = content[assign_start:assign_end]
|
|
content = content[:assign_start] + '\n' + new_code + content[assign_end:]
|
|
|
|
# Write result
|
|
with open('mod/ONIAgentBridge.cs', 'w') as f:
|
|
f.write(content)
|
|
|
|
print('Done. Checking for remaining C# 7+ features...')
|
|
|
|
# Verify
|
|
remaining = re.findall(r'\bswitch\b', content)
|
|
print(f'Remaining "switch" keywords: {len(remaining)}')
|
|
# Count them
|
|
for i, line in enumerate(content.split('\n')):
|
|
if 'switch' in line and not line.strip().startswith('//') and 'ProcessRequest' not in line:
|
|
sline = line.strip()
|
|
if 'if (' not in line and 'dictionary' not in line.lower() and 'dispatch' not in line:
|
|
print(f' Line ~{i}: {sline[:80]}')
|