Skip to content

Commit c2d6654

Browse files
author
Lavisha Gupta
committed
fix(compiler): prevent line wrapping in language-specific syntax constructs
- Add wrap_line/wrap_lines methods to BaseGenerator for smart line breaking - Override wrap_line in Go generator to preserve function signatures and struct tags - Override wrap_line in Python generator to preserve assignments and conditionals - Modify Java generator to use string concatenation for long error messages - Fix ruff formatting issues (multi-line if statements, trailing whitespace) This fixes syntax errors in generated IDL code across Java, Go, and Python.
1 parent 0a7f658 commit c2d6654

3 files changed

Lines changed: 48 additions & 21 deletions

File tree

compiler/fory_compiler/generators/base.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,12 @@ def wrap_line(
239239
return [line]
240240

241241
# Don't wrap comment lines (license headers, etc.)
242-
if stripped.startswith("//") or stripped.startswith("/*") or stripped.startswith("*") or stripped.startswith("#"):
242+
if (
243+
stripped.startswith("//")
244+
or stripped.startswith("/*")
245+
or stripped.startswith("*")
246+
or stripped.startswith("#")
247+
):
243248
return [line]
244249

245250
# Extract the leading indent
@@ -275,7 +280,18 @@ def wrap_line(
275280
search_text = current[:available]
276281

277282
# Try to break at common delimiters (working backwards)
278-
for delimiter in [", ", " && ", " || ", " + ", " - ", " * ", " / ", " = ", " ", ","]:
283+
for delimiter in [
284+
", ",
285+
" && ",
286+
" || ",
287+
" + ",
288+
" - ",
289+
" * ",
290+
" / ",
291+
" = ",
292+
" ",
293+
",",
294+
]:
279295
idx = search_text.rfind(delimiter)
280296
if idx > 0:
281297
break_point = idx + len(delimiter)

compiler/fory_compiler/generators/go.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,34 +207,38 @@ def wrap_line(
207207
continuation_indent: str = None,
208208
) -> List[str]:
209209
"""Override base wrap_line to handle Go-specific syntax.
210-
210+
211211
Go has specific constructs that should not be wrapped:
212212
1. Function signatures - must not split between params and return type
213213
2. Struct field tags - backtick strings must not be split
214214
3. Single-line function bodies - must not split "{ return ... }"
215215
"""
216216
if continuation_indent is None:
217217
continuation_indent = indent + " "
218-
218+
219219
# If line is already short enough, return as is
220220
if len(line) <= max_width:
221221
return [line]
222-
222+
223223
stripped = line.lstrip()
224-
224+
225225
# Don't wrap comments
226-
if stripped.startswith("//") or stripped.startswith("/*") or stripped.startswith("*"):
226+
if (
227+
stripped.startswith("//")
228+
or stripped.startswith("/*")
229+
or stripped.startswith("*")
230+
):
227231
return [line]
228-
232+
229233
# Don't wrap lines with backticks (struct tags)
230234
if "`" in line:
231235
return [line]
232-
236+
233237
# Don't wrap function definitions (including one-liners like "func Foo() Type { return ... }")
234238
# Detect by checking if line starts with "func " and contains "{"
235239
if stripped.startswith("func ") and "{" in line:
236240
return [line]
237-
241+
238242
# For all other cases, use base class wrapping
239243
return super().wrap_line(line, max_width, indent, continuation_indent)
240244

@@ -902,7 +906,7 @@ def generate_field(
902906
if tags:
903907
tag_str = ",".join(tags)
904908
# Concatenate parts to ensure single line in output
905-
lines.append(f"{field_name} {go_type} `fory:\"{tag_str}\"`")
909+
lines.append(f'{field_name} {go_type} `fory:"{tag_str}"`')
906910
else:
907911
lines.append(f"{field_name} {go_type}")
908912

compiler/fory_compiler/generators/python.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,46 +149,53 @@ def wrap_line(
149149
continuation_indent: str = None,
150150
) -> List[str]:
151151
"""Override base wrap_line to handle Python-specific syntax.
152-
152+
153153
Python has specific constructs that should not be wrapped:
154154
1. Assignment statements - must not split between variable and value
155155
2. Conditional statements with logical operators (and, or, not)
156156
3. Raise statements with string literals
157157
"""
158158
if continuation_indent is None:
159159
continuation_indent = indent + " "
160-
160+
161161
# If line is already short enough, return as is
162162
if len(line) <= max_width:
163163
return [line]
164-
164+
165165
stripped = line.lstrip()
166-
166+
167167
# Don't wrap comments
168168
if stripped.startswith("#"):
169169
return [line]
170-
170+
171171
# Don't wrap raise statements (they often have long string literals)
172172
if stripped.startswith("raise "):
173173
return [line]
174-
174+
175175
# Don't wrap assignment statements (lines containing " = " at the statement level)
176176
# This prevents splitting like: _threadsafe_fory = pyfory.ThreadSafeFory(...)
177177
# Only check for simple assignments (not comparisons or keyword args)
178-
if " = " in line and not line.strip().startswith("if ") and not line.strip().startswith("elif ") and not line.strip().startswith("while "):
178+
if (
179+
" = " in line
180+
and not line.strip().startswith("if ")
181+
and not line.strip().startswith("elif ")
182+
and not line.strip().startswith("while ")
183+
):
179184
# Check if this looks like a simple assignment (has = but not == or <= or >=)
180185
# and the = comes before any opening parentheses
181186
eq_pos = line.find(" = ")
182187
paren_pos = line.find("(")
183188
if eq_pos > 0 and (paren_pos < 0 or eq_pos < paren_pos):
184189
# This is likely an assignment statement, don't wrap it
185190
return [line]
186-
191+
187192
# Don't wrap conditional statements (if/elif/while) with logical operators
188193
# This prevents splitting like: if condition and not\n isinstance(...)
189-
if stripped.startswith(("if ", "elif ", "while ")) and (" and " in line or " or " in line):
194+
if stripped.startswith(("if ", "elif ", "while ")) and (
195+
" and " in line or " or " in line
196+
):
190197
return [line]
191-
198+
192199
# For all other cases, use base class wrapping
193200
return super().wrap_line(line, max_width, indent, continuation_indent)
194201

0 commit comments

Comments
 (0)