code2logic 1.0.28__tar.gz → 1.0.30__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {code2logic-1.0.28 → code2logic-1.0.30}/PKG-INFO +1 -1
  2. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/__init__.py +1 -1
  3. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/analyzer.py +25 -4
  4. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/function_logic.py +18 -9
  5. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/toon_format.py +7 -3
  6. {code2logic-1.0.28 → code2logic-1.0.30}/pyproject.toml +2 -2
  7. {code2logic-1.0.28 → code2logic-1.0.30}/LICENSE +0 -0
  8. {code2logic-1.0.28 → code2logic-1.0.30}/README.md +0 -0
  9. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/__main__.py +0 -0
  10. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/adaptive.py +0 -0
  11. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/base.py +0 -0
  12. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/benchmark.py +0 -0
  13. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/benchmarks/__init__.py +0 -0
  14. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/benchmarks/common.py +0 -0
  15. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/benchmarks/results.py +0 -0
  16. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/benchmarks/runner.py +0 -0
  17. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/chunked_reproduction.py +0 -0
  18. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/cli.py +0 -0
  19. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/code_review.py +0 -0
  20. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/config.py +0 -0
  21. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/core/__init__.py +0 -0
  22. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/dependency.py +0 -0
  23. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/errors.py +0 -0
  24. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/file_formats.py +0 -0
  25. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/formats/__init__.py +0 -0
  26. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/generators.py +0 -0
  27. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/gherkin.py +0 -0
  28. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/integrations/__init__.py +0 -0
  29. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/intent.py +0 -0
  30. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/llm/__init__.py +0 -0
  31. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/llm.py +0 -0
  32. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/llm_clients.py +0 -0
  33. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/llm_clients_new.py +0 -0
  34. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/llm_profiler.py +0 -0
  35. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/logicml.py +0 -0
  36. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/markdown_format.py +0 -0
  37. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/mcp_server.py +0 -0
  38. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/metrics.py +0 -0
  39. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/models.py +0 -0
  40. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/parsers.py +0 -0
  41. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/project_reproducer.py +0 -0
  42. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/prompts.py +0 -0
  43. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/py.typed +0 -0
  44. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/quality.py +0 -0
  45. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/refactor.py +0 -0
  46. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/reproducer.py +0 -0
  47. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/reproduction.py +0 -0
  48. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/schemas/__init__.py +0 -0
  49. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/schemas/json_schema.py +0 -0
  50. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/schemas/logicml_schema.py +0 -0
  51. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/schemas/markdown_schema.py +0 -0
  52. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/schemas/yaml_schema.py +0 -0
  53. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/shared_utils.py +0 -0
  54. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/similarity.py +0 -0
  55. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/terminal.py +0 -0
  56. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/tools/__init__.py +0 -0
  57. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/universal.py +0 -0
  58. {code2logic-1.0.28 → code2logic-1.0.30}/code2logic/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: code2logic
3
- Version: 1.0.28
3
+ Version: 1.0.30
4
4
  Summary: Convert source code to logical representation for LLM analysis
5
5
  License: Apache-2.0
6
6
  Keywords: code-analysis,llm,ast,static-analysis,tree-sitter,code-understanding,documentation,dependency-graph,nlp
@@ -18,7 +18,7 @@ Example:
18
18
  >>> print(output)
19
19
  """
20
20
 
21
- __version__ = "1.0.28"
21
+ __version__ = "1.0.30"
22
22
  __author__ = "Softreck"
23
23
  __email__ = "info@softreck.dev"
24
24
  __license__ = "MIT"
@@ -8,7 +8,7 @@ import sys
8
8
  from collections import defaultdict
9
9
  from datetime import datetime
10
10
  from pathlib import Path
11
- from typing import Dict, List
11
+ from typing import Dict, List, Optional
12
12
 
13
13
  from .dependency import NETWORKX_AVAILABLE, DependencyAnalyzer
14
14
  from .intent import NLTK_AVAILABLE, SPACY_AVAILABLE
@@ -45,9 +45,13 @@ class ProjectAnalyzer:
45
45
  LANGUAGE_EXTENSIONS: Dict[str, str] = {
46
46
  '.py': 'python',
47
47
  '.js': 'javascript',
48
+ '.mjs': 'javascript',
49
+ '.cjs': 'javascript',
48
50
  '.jsx': 'javascript',
49
51
  '.ts': 'typescript',
50
52
  '.tsx': 'typescript',
53
+ '.mts': 'typescript',
54
+ '.cts': 'typescript',
51
55
  '.sql': 'sql',
52
56
  '.java': 'java',
53
57
  '.go': 'go',
@@ -82,6 +86,17 @@ class ProjectAnalyzer:
82
86
  'Cargo.lock', 'pnpm-lock.yaml',
83
87
  }
84
88
 
89
+ @staticmethod
90
+ def _language_from_shebang(first_line: str) -> Optional[str]:
91
+ s = (first_line or '').strip().lower()
92
+ if not s.startswith('#!'):
93
+ return None
94
+ if 'python' in s:
95
+ return 'python'
96
+ if 'node' in s:
97
+ return 'javascript'
98
+ return None
99
+
85
100
  def __init__(
86
101
  self,
87
102
  root_path: str,
@@ -177,12 +192,18 @@ class ProjectAnalyzer:
177
192
  if fp.name in self.IGNORE_FILES:
178
193
  continue
179
194
 
180
- # Check extension
181
195
  ext = fp.suffix.lower()
182
- if ext not in self.LANGUAGE_EXTENSIONS:
196
+ language = self.LANGUAGE_EXTENSIONS.get(ext)
197
+ if language is None and ext == '':
198
+ try:
199
+ with fp.open('r', encoding='utf-8', errors='ignore') as f:
200
+ language = self._language_from_shebang(f.readline())
201
+ except Exception:
202
+ language = None
203
+
204
+ if language is None:
183
205
  continue
184
206
 
185
- language = self.LANGUAGE_EXTENSIONS[ext]
186
207
  self.languages[language] += 1
187
208
 
188
209
  # Read file
@@ -35,7 +35,7 @@ class FunctionLogicGenerator:
35
35
  lines.append("functions:")
36
36
 
37
37
  for kind, qname, func in items:
38
- lines.extend(self._format_function(kind, qname, func, detail, indent=2))
38
+ lines.extend(self._format_function(kind, qname, func, detail, indent=2, module_language=module.language))
39
39
 
40
40
  lines.append("")
41
41
 
@@ -96,7 +96,7 @@ class FunctionLogicGenerator:
96
96
  lines.append(f" functions[{len(items)}]{{{header}}}:")
97
97
 
98
98
  for kind, qname, func in items:
99
- sig = self._build_sig(func, include_async_prefix=False)
99
+ sig = self._build_sig(func, include_async_prefix=False, language=m.language)
100
100
  loc = self._build_loc(func)
101
101
  is_async = 'true' if getattr(func, 'is_async', False) else 'false'
102
102
  row = [
@@ -134,7 +134,7 @@ class FunctionLogicGenerator:
134
134
  modules_data.append({
135
135
  'path': m.path,
136
136
  'language': m.language,
137
- 'functions': [self._item_to_dict(kind, qname, func, detail) for kind, qname, func in items]
137
+ 'functions': [self._item_to_dict(kind, qname, func, detail, module_language=m.language) for kind, qname, func in items]
138
138
  })
139
139
 
140
140
  data = {
@@ -156,11 +156,19 @@ class FunctionLogicGenerator:
156
156
 
157
157
  return items
158
158
 
159
- def _build_sig(self, func: FunctionInfo, include_async_prefix: bool = True) -> str:
159
+ def _build_sig(self, func: FunctionInfo, include_async_prefix: bool = True, language: str = '') -> str:
160
160
  clean_params = remove_self_from_params((func.params or [])[:10])
161
161
  params_str = ', '.join(clean_params)
162
- ret = func.return_type or 'None'
163
- sig = f"({params_str}) -> {ret}" if params_str else f"() -> {ret}"
162
+ ret = getattr(func, 'return_type', None)
163
+ if isinstance(ret, str):
164
+ ret = ret.strip()
165
+
166
+ if language in ('javascript', 'typescript') and ret == 'None':
167
+ ret = None
168
+
169
+ sig = f"({params_str})" if params_str else "()"
170
+ if ret:
171
+ sig = f"{sig} -> {ret}"
164
172
  if include_async_prefix and getattr(func, 'is_async', False):
165
173
  sig = f"async {sig}"
166
174
  return sig
@@ -178,11 +186,11 @@ class FunctionLogicGenerator:
178
186
  does = does.replace('\n', ' ').replace('"', "'").strip()
179
187
  return does or '-'
180
188
 
181
- def _item_to_dict(self, kind: str, qualified_name: str, func: FunctionInfo, detail: str) -> dict:
189
+ def _item_to_dict(self, kind: str, qualified_name: str, func: FunctionInfo, detail: str, module_language: str = '') -> dict:
182
190
  data = {
183
191
  'name': qualified_name,
184
192
  'kind': kind,
185
- 'sig': self._build_sig(func, include_async_prefix=True),
193
+ 'sig': self._build_sig(func, include_async_prefix=True, language=module_language),
186
194
  }
187
195
 
188
196
  start_line = getattr(func, 'start_line', 0) or 0
@@ -224,6 +232,7 @@ class FunctionLogicGenerator:
224
232
  func: FunctionInfo,
225
233
  detail: str,
226
234
  indent: int,
235
+ module_language: str = '',
227
236
  ) -> List[str]:
228
237
  prefix = ' ' * indent
229
238
  sub = ' ' * (indent + 2)
@@ -232,7 +241,7 @@ class FunctionLogicGenerator:
232
241
 
233
242
  lines.append(f"{sub}kind: {kind}")
234
243
 
235
- sig = self._build_sig(func, include_async_prefix=True)
244
+ sig = self._build_sig(func, include_async_prefix=True, language=module_language)
236
245
  lines.append(f"{sub}sig: {sig}")
237
246
 
238
247
  loc = self._build_loc(func)
@@ -323,9 +323,13 @@ class TOONGenerator:
323
323
 
324
324
  param_str = ';'.join(params)
325
325
 
326
- # Include return type
327
- ret = f.return_type if f.return_type else 'None'
328
- return f"({param_str})->{ret}"
326
+ ret = getattr(f, 'return_type', None)
327
+ if isinstance(ret, str):
328
+ ret = ret.strip()
329
+
330
+ if ret:
331
+ return f"({param_str})->{ret}"
332
+ return f"({param_str})"
329
333
 
330
334
  def _quote(self, value: Any) -> str:
331
335
  """Quote a value if necessary for TOON format."""
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "code2logic"
7
- version = "1.0.28"
7
+ version = "1.0.30"
8
8
  description = "Convert source code to logical representation for LLM analysis"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -183,7 +183,7 @@ module = [
183
183
  ignore_missing_imports = true
184
184
 
185
185
  [tool.bumpver]
186
- current_version = "1.0.28"
186
+ current_version = "1.0.30"
187
187
  version_pattern = "MAJOR.MINOR.PATCH"
188
188
  commit = false
189
189
  tag = false
File without changes
File without changes