Skip to content

Commit 59b8242

Browse files
refactoring
1 parent 609a123 commit 59b8242

7 files changed

Lines changed: 15327 additions & 12 deletions

File tree

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ artifacts/
77
out/
88
project.c2l.*
99
project.func.*
10-
project.functions.*
1110
ollama_benchmark_results.csv
1211
*_benchmark_results.csv
1312
.idea

code2logic/cli.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,11 @@ def _maybe_print_pretty_help() -> bool:
651651
action='store_true',
652652
help='Write all output to stdout instead of files (including schema and function-logic). Useful for piping.'
653653
)
654+
parser.add_argument(
655+
'--no-repeat-name',
656+
action='store_true',
657+
help='Reduce repeated directory prefixes in TOON outputs by using ./file for consecutive entries in the same folder (applies to function-logic TOON and TOON module lists).'
658+
)
654659
parser.add_argument(
655660
'--no-install',
656661
action='store_true',
@@ -961,7 +966,11 @@ def _maybe_print_pretty_help() -> bool:
961966
'standard': 'standard',
962967
'full': 'full',
963968
}
964-
output = generator.generate(project, detail=detail_map.get(args.detail, 'standard'))
969+
output = generator.generate(
970+
project,
971+
detail=detail_map.get(args.detail, 'standard'),
972+
no_repeat_name=args.no_repeat_name,
973+
)
965974

966975
# Generate schema if requested
967976
if args.with_schema:
@@ -1012,7 +1021,7 @@ def _maybe_print_pretty_help() -> bool:
10121021
elif lower.endswith(('.yaml', '.yml')):
10131022
logic_out = logic_gen.generate_yaml(project, detail=args.detail)
10141023
elif lower.endswith('.toon'):
1015-
logic_out = logic_gen.generate_toon(project, detail=args.detail)
1024+
logic_out = logic_gen.generate_toon(project, detail=args.detail, no_repeat_name=args.no_repeat_name)
10161025
else:
10171026
logic_out = logic_gen.generate(project, detail=args.detail)
10181027

code2logic/function_logic.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def generate_yaml(self, project: ProjectInfo, detail: str = 'full') -> str:
5959
return self.generate(project, detail)
6060
return yaml.dump(data, default_flow_style=False, allow_unicode=True, sort_keys=False, width=120)
6161

62-
def generate_toon(self, project: ProjectInfo, detail: str = 'full') -> str:
62+
def generate_toon(self, project: ProjectInfo, detail: str = 'full', no_repeat_name: bool = False) -> str:
6363
if detail == 'detailed':
6464
detail = 'full'
6565
toon = TOONGenerator()
@@ -73,19 +73,31 @@ def generate_toon(self, project: ProjectInfo, detail: str = 'full') -> str:
7373

7474
modules = list(project.modules or [])
7575
lines.append(f"modules[{len(modules)}]{{path{dm}lang{dm}items}}:")
76+
prev_dir: str | None = None
7677
for m in modules:
7778
items = self._module_items(m)
78-
lines.append(f" {toon._quote(m.path)}{delim}{m.language}{delim}{len(items)}")
79+
if no_repeat_name:
80+
compressed_path, prev_dir = toon._compress_module_path(m.path, prev_dir)
81+
path_out = compressed_path
82+
else:
83+
path_out = m.path
84+
lines.append(f" {toon._quote(path_out)}{delim}{toon._short_lang(m.language)}{delim}{len(items)}")
7985

8086
lines.append("")
8187
lines.append("function_details:")
8288

89+
prev_dir = None
8390
for m in modules:
8491
items = self._module_items(m)
8592
if not items:
8693
continue
8794

88-
lines.append(f" {toon._quote(m.path)}:")
95+
if no_repeat_name:
96+
compressed_path, prev_dir = toon._compress_module_path(m.path, prev_dir)
97+
details_key = compressed_path
98+
else:
99+
details_key = m.path
100+
lines.append(f" {toon._quote(details_key)}:")
89101

90102
header = f"name{dm}kind{dm}sig{dm}loc{dm}async{dm}lines{dm}cc"
91103
if detail in ('standard', 'full'):

code2logic/toon_format.py

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,37 @@ class TOONGenerator:
3333
SPECIAL_CHARS = re.compile(r'[:\"\\\[\]\{\}\n\t\r,]')
3434
LOOKS_LIKE_LITERAL = re.compile(r'^(true|false|null|-?\d+\.?\d*([eE][+-]?\d+)?|-)$')
3535

36+
LANGUAGE_ABBREVIATIONS = {
37+
'python': 'py',
38+
'javascript': 'js',
39+
'typescript': 'ts',
40+
'tsx': 'tsx',
41+
'jsx': 'jsx',
42+
'java': 'java',
43+
'kotlin': 'kt',
44+
'go': 'go',
45+
'rust': 'rs',
46+
'c': 'c',
47+
'cpp': 'cpp',
48+
'c++': 'cpp',
49+
'csharp': 'cs',
50+
'c#': 'cs',
51+
'php': 'php',
52+
'ruby': 'rb',
53+
'swift': 'swift',
54+
'scala': 'scala',
55+
'bash': 'sh',
56+
'shell': 'sh',
57+
'sql': 'sql',
58+
'yaml': 'yaml',
59+
'json': 'json',
60+
'toml': 'toml',
61+
'markdown': 'md',
62+
'html': 'html',
63+
'css': 'css',
64+
'dockerfile': 'docker',
65+
}
66+
3667
def __init__(self, delimiter: str = ',', use_tabs: bool = False):
3768
"""
3869
Initialize TOON generator.
@@ -46,7 +77,27 @@ def __init__(self, delimiter: str = ',', use_tabs: bool = False):
4677
# parsers/LLMs can read them. Use comma-separated headers regardless of row delimiter.
4778
self.delim_marker = ','
4879

49-
def generate(self, project: ProjectInfo, detail: str = 'standard') -> str:
80+
def _short_lang(self, lang: str) -> str:
81+
lang_norm = (lang or '').strip().lower()
82+
return self.LANGUAGE_ABBREVIATIONS.get(lang_norm, lang)
83+
84+
def _compress_module_path(self, path: str, prev_dir: str | None) -> tuple[str, str]:
85+
"""Compress repeated directory prefixes for module summary tables.
86+
87+
If consecutive modules are in the same directory, emit './<basename>' instead
88+
of repeating '<dir>/<basename>'. The first entry for a directory stays as the
89+
full path.
90+
"""
91+
p = (path or '')
92+
if '/' not in p:
93+
return p, ''
94+
95+
cur_dir, base = p.rsplit('/', 1)
96+
if prev_dir is not None and cur_dir == prev_dir:
97+
return f"./{base}", cur_dir
98+
return p, cur_dir
99+
100+
def generate(self, project: ProjectInfo, detail: str = 'standard', no_repeat_name: bool = False) -> str:
50101
"""
51102
Generate TOON format from ProjectInfo.
52103
@@ -71,26 +122,33 @@ def generate(self, project: ProjectInfo, detail: str = 'standard') -> str:
71122

72123
# Languages as primitive array
73124
if project.languages:
74-
lang_items = [f"{k}:{v}" for k, v in project.languages.items()]
125+
lang_items = [f"{self._short_lang(k)}:{v}" for k, v in project.languages.items()]
75126
lines.append(f" languages[{len(lang_items)}]: {self.delimiter.join(lang_items)}")
76127

77128
# Modules - tabular format for efficiency
78129
if project.modules:
79130
lines.append("")
80-
lines.extend(self._generate_modules(project.modules, detail))
131+
lines.extend(self._generate_modules(project.modules, detail, no_repeat_name=no_repeat_name))
81132

82133
return '\n'.join(lines)
83134

84-
def _generate_modules(self, modules: List[ModuleInfo], detail: str) -> List[str]:
135+
def _generate_modules(self, modules: List[ModuleInfo], detail: str, no_repeat_name: bool = False) -> List[str]:
85136
"""Generate modules section."""
86137
lines = []
87138

88139
# Module summary as tabular array
89140
lines.append(f"modules[{len(modules)}]{{path{self.delim_marker}lang{self.delim_marker}lines{self.delim_marker}kb}}:")
141+
prev_dir: str | None = None
90142
for m in modules:
91-
path = self._quote(m.path)
143+
if no_repeat_name:
144+
path_out, prev_dir = self._compress_module_path(m.path, prev_dir)
145+
else:
146+
path_out = m.path
147+
path = self._quote(path_out)
92148
kb = round((getattr(m, 'file_bytes', 0) or 0) / 1024, 1)
93-
lines.append(f" {path}{self.delimiter}{m.language}{self.delimiter}{m.lines_code}{self.delimiter}{kb}")
149+
lines.append(
150+
f" {path}{self.delimiter}{self._short_lang(m.language)}{self.delimiter}{m.lines_code}{self.delimiter}{kb}"
151+
)
94152

95153
# Detailed module info
96154
if detail in ('standard', 'full'):

0 commit comments

Comments
 (0)