Skip to content

Commit d9b0575

Browse files
author
Lavisha Gupta
committed
[Compiler] format generated code by header and line break #3233
1 parent 130066d commit d9b0575

6 files changed

Lines changed: 149 additions & 9 deletions

File tree

compiler/fory_compiler/generators/base.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,121 @@ def get_license_header(self, comment_prefix: str = "//") -> str:
206206
return "\n".join(
207207
f"{comment_prefix} {line}" if line else comment_prefix for line in lines
208208
)
209+
210+
def wrap_line(
211+
self,
212+
line: str,
213+
max_width: int = 80,
214+
indent: str = "",
215+
continuation_indent: str = None,
216+
) -> List[str]:
217+
"""Wrap a long line into multiple lines with max_width characters.
218+
219+
Args:
220+
line: The line to wrap
221+
max_width: Maximum width per line (default 80)
222+
indent: The indentation to preserve for the first line
223+
continuation_indent: Extra indentation for continuation lines.
224+
If None, uses indent + 4 spaces.
225+
226+
Returns:
227+
List of wrapped lines
228+
"""
229+
if continuation_indent is None:
230+
continuation_indent = indent + " "
231+
232+
# If line is already short enough, return as is
233+
if len(line) <= max_width:
234+
return [line]
235+
236+
# Don't wrap C++ preprocessor directives (macros)
237+
stripped = line.lstrip()
238+
if stripped.startswith("#"):
239+
return [line]
240+
241+
# Don't wrap comment lines (license headers, etc.)
242+
if stripped.startswith("//") or stripped.startswith("/*") or stripped.startswith("*") or stripped.startswith("#"):
243+
return [line]
244+
245+
# Extract the leading indent
246+
leading_spaces = line[: len(line) - len(line.lstrip())]
247+
248+
# Get the content without indent
249+
content = line[len(leading_spaces) :]
250+
251+
# If it's still too short after considering indent, don't wrap
252+
if len(leading_spaces) + len(content) <= max_width:
253+
return [line]
254+
255+
# Find good break points (prefer breaking at spaces, commas, operators)
256+
result = []
257+
current = content
258+
first_line = True
259+
260+
while len(leading_spaces) + len(current) > max_width:
261+
# Calculate available width
262+
if first_line:
263+
available = max_width - len(leading_spaces)
264+
else:
265+
available = max_width - len(continuation_indent)
266+
267+
if available <= 0:
268+
# Can't wrap reasonably, return original
269+
return [line]
270+
271+
# Find the best break point
272+
break_point = -1
273+
274+
# Look for break points in order of preference
275+
search_text = current[:available]
276+
277+
# Try to break at common delimiters (working backwards)
278+
for delimiter in [", ", " && ", " || ", " + ", " - ", " * ", " / ", " = ", " ", ","]:
279+
idx = search_text.rfind(delimiter)
280+
if idx > 0:
281+
break_point = idx + len(delimiter)
282+
break
283+
284+
# If no good break point found, just break at max width
285+
if break_point <= 0:
286+
break_point = available
287+
288+
# Add the line segment
289+
if first_line:
290+
result.append(leading_spaces + current[:break_point].rstrip())
291+
first_line = False
292+
else:
293+
result.append(continuation_indent + current[:break_point].rstrip())
294+
295+
# Continue with the rest
296+
current = current[break_point:].lstrip()
297+
298+
# Add the remaining content
299+
if current:
300+
if first_line:
301+
result.append(leading_spaces + current)
302+
else:
303+
result.append(continuation_indent + current)
304+
305+
return result if result else [line]
306+
307+
def wrap_lines(
308+
self, lines: List[str], max_width: int = 80, preserve_blank: bool = True
309+
) -> List[str]:
310+
"""Wrap multiple lines, handling each line's indentation.
311+
312+
Args:
313+
lines: List of lines to wrap
314+
max_width: Maximum width per line
315+
preserve_blank: If True, preserve blank lines as-is
316+
317+
Returns:
318+
List of wrapped lines
319+
"""
320+
result = []
321+
for line in lines:
322+
if preserve_blank and not line.strip():
323+
result.append(line)
324+
else:
325+
result.extend(self.wrap_line(line, max_width))
326+
return result

compiler/fory_compiler/generators/cpp.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,12 @@ def generate_header(self) -> GeneratedFile:
370370
lines.append(f"#endif // {guard_name}")
371371
lines.append("")
372372

373+
# Wrap long lines at 80 characters (careful with C++ macros)
374+
wrapped_lines = self.wrap_lines(lines, max_width=80)
375+
373376
return GeneratedFile(
374377
path=f"{self.get_header_name()}.h",
375-
content="\n".join(lines),
378+
content="\n".join(wrapped_lines),
376379
)
377380

378381
def collect_message_includes(self, message: Message, includes: Set[str]):

compiler/fory_compiler/generators/go.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,12 @@ def generate_file(self) -> GeneratedFile:
449449
lines.extend(self.generate_fory_helpers())
450450
lines.append("")
451451

452+
# Wrap long lines at 80 characters
453+
wrapped_lines = self.wrap_lines(lines, max_width=80)
454+
452455
return GeneratedFile(
453456
path=f"{self.get_file_name()}.go",
454-
content="\n".join(lines),
457+
content="\n".join(wrapped_lines),
455458
)
456459

457460
def collect_message_imports(self, message: Message, imports: Set[str]):

compiler/fory_compiler/generators/java.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,9 @@ def generate_enum_file(self, enum: Enum) -> GeneratedFile:
366366
else:
367367
path = f"{enum.name}.java"
368368

369-
return GeneratedFile(path=path, content="\n".join(lines))
369+
# Wrap long lines at 80 characters
370+
wrapped_lines = self.wrap_lines(lines, max_width=80)
371+
return GeneratedFile(path=path, content="\n".join(wrapped_lines))
370372

371373
def generate_union_file(self, union: Union) -> GeneratedFile:
372374
"""Generate a Java union class file."""
@@ -397,7 +399,9 @@ def generate_union_file(self, union: Union) -> GeneratedFile:
397399
else:
398400
path = f"{union.name}.java"
399401

400-
return GeneratedFile(path=path, content="\n".join(lines))
402+
# Wrap long lines at 80 characters
403+
wrapped_lines = self.wrap_lines(lines, max_width=80)
404+
return GeneratedFile(path=path, content="\n".join(wrapped_lines))
401405

402406
def generate_message_file(self, message: Message) -> GeneratedFile:
403407
"""Generate a Java class file for a message."""
@@ -486,7 +490,9 @@ def generate_message_file(self, message: Message) -> GeneratedFile:
486490
else:
487491
path = f"{message.name}.java"
488492

489-
return GeneratedFile(path=path, content="\n".join(lines))
493+
# Wrap long lines at 80 characters
494+
wrapped_lines = self.wrap_lines(lines, max_width=80)
495+
return GeneratedFile(path=path, content="\n".join(wrapped_lines))
490496

491497
def generate_outer_class_file(self, outer_classname: str) -> GeneratedFile:
492498
"""Generate a single Java file with all types as inner classes of an outer class.
@@ -559,7 +565,9 @@ def generate_outer_class_file(self, outer_classname: str) -> GeneratedFile:
559565
else:
560566
path = f"{outer_classname}.java"
561567

562-
return GeneratedFile(path=path, content="\n".join(lines))
568+
# Wrap long lines at 80 characters
569+
wrapped_lines = self.wrap_lines(lines, max_width=80)
570+
return GeneratedFile(path=path, content="\n".join(wrapped_lines))
563571

564572
def collect_message_imports(self, message: Message, imports: Set[str]):
565573
"""Collect imports for a message and all its nested types recursively."""
@@ -1447,7 +1455,9 @@ def generate_registration_file(
14471455
else:
14481456
path = f"{class_name}.java"
14491457

1450-
return GeneratedFile(path=path, content="\n".join(lines))
1458+
# Wrap long lines at 80 characters
1459+
wrapped_lines = self.wrap_lines(lines, max_width=80)
1460+
return GeneratedFile(path=path, content="\n".join(wrapped_lines))
14511461

14521462
def generate_enum_registration(
14531463
self, lines: List[str], enum: Enum, parent_path: str

compiler/fory_compiler/generators/python.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,12 @@ def generate_module(self) -> GeneratedFile:
323323
lines.extend(self.generate_fory_helpers())
324324
lines.append("")
325325

326+
# Wrap long lines at 80 characters
327+
wrapped_lines = self.wrap_lines(lines, max_width=80)
328+
326329
return GeneratedFile(
327330
path=f"{self.get_module_name()}.py",
328-
content="\n".join(lines),
331+
content="\n".join(wrapped_lines),
329332
)
330333

331334
def collect_message_imports(self, message: Message, imports: Set[str]):

compiler/fory_compiler/generators/rust.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,12 @@ def generate_module(self) -> GeneratedFile:
252252
lines.extend(self.generate_fory_helpers())
253253
lines.append("")
254254

255+
# Wrap long lines at 80 characters
256+
wrapped_lines = self.wrap_lines(lines, max_width=80)
257+
255258
return GeneratedFile(
256259
path=f"{self.get_module_name()}.rs",
257-
content="\n".join(lines),
260+
content="\n".join(wrapped_lines),
258261
)
259262

260263
def collect_message_uses(self, message: Message, uses: Set[str]):

0 commit comments

Comments
 (0)