jaclang 0.8.8__py3-none-any.whl → 0.8.10__py3-none-any.whl

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.

Potentially problematic release.


This version of jaclang might be problematic. Click here for more details.

Files changed (114) hide show
  1. jaclang/cli/cli.py +194 -10
  2. jaclang/cli/cmdreg.py +144 -8
  3. jaclang/compiler/__init__.py +6 -1
  4. jaclang/compiler/codeinfo.py +16 -1
  5. jaclang/compiler/constant.py +33 -8
  6. jaclang/compiler/jac.lark +154 -62
  7. jaclang/compiler/larkparse/jac_parser.py +2 -2
  8. jaclang/compiler/parser.py +656 -149
  9. jaclang/compiler/passes/__init__.py +2 -1
  10. jaclang/compiler/passes/ast_gen/__init__.py +5 -0
  11. jaclang/compiler/passes/ast_gen/base_ast_gen_pass.py +54 -0
  12. jaclang/compiler/passes/ast_gen/jsx_processor.py +344 -0
  13. jaclang/compiler/passes/ecmascript/__init__.py +25 -0
  14. jaclang/compiler/passes/ecmascript/es_unparse.py +576 -0
  15. jaclang/compiler/passes/ecmascript/esast_gen_pass.py +2068 -0
  16. jaclang/compiler/passes/ecmascript/estree.py +972 -0
  17. jaclang/compiler/passes/ecmascript/tests/__init__.py +1 -0
  18. jaclang/compiler/passes/ecmascript/tests/fixtures/advanced_language_features.jac +170 -0
  19. jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.impl.jac +30 -0
  20. jaclang/compiler/passes/ecmascript/tests/fixtures/class_separate_impl.jac +14 -0
  21. jaclang/compiler/passes/ecmascript/tests/fixtures/client_jsx.jac +89 -0
  22. jaclang/compiler/passes/ecmascript/tests/fixtures/core_language_features.jac +195 -0
  23. jaclang/compiler/passes/ecmascript/tests/test_esast_gen_pass.py +167 -0
  24. jaclang/compiler/passes/ecmascript/tests/test_js_generation.py +239 -0
  25. jaclang/compiler/passes/main/__init__.py +0 -3
  26. jaclang/compiler/passes/main/annex_pass.py +23 -1
  27. jaclang/compiler/passes/main/def_use_pass.py +1 -0
  28. jaclang/compiler/passes/main/pyast_gen_pass.py +413 -255
  29. jaclang/compiler/passes/main/pyast_load_pass.py +48 -11
  30. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +2 -0
  31. jaclang/compiler/passes/main/sym_tab_build_pass.py +18 -1
  32. jaclang/compiler/passes/main/tests/fixtures/autoimpl.cl.jac +7 -0
  33. jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +3 -0
  34. jaclang/compiler/passes/main/tests/fixtures/checker_class_construct.jac +33 -0
  35. jaclang/compiler/passes/main/tests/fixtures/defuse_modpath.jac +7 -0
  36. jaclang/compiler/passes/main/tests/fixtures/member_access_type_resolve.jac +2 -1
  37. jaclang/compiler/passes/main/tests/test_checker_pass.py +31 -3
  38. jaclang/compiler/passes/main/tests/test_def_use_pass.py +12 -0
  39. jaclang/compiler/passes/main/tests/test_import_pass.py +23 -4
  40. jaclang/compiler/passes/main/tests/test_predynamo_pass.py +13 -14
  41. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +25 -0
  42. jaclang/compiler/passes/main/type_checker_pass.py +7 -0
  43. jaclang/compiler/passes/tool/doc_ir_gen_pass.py +219 -20
  44. jaclang/compiler/passes/tool/fuse_comments_pass.py +1 -10
  45. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
  46. jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +7 -1
  47. jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +135 -29
  48. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +4 -1
  49. jaclang/compiler/passes/transform.py +9 -1
  50. jaclang/compiler/passes/uni_pass.py +5 -7
  51. jaclang/compiler/program.py +27 -26
  52. jaclang/compiler/tests/test_client_codegen.py +113 -0
  53. jaclang/compiler/tests/test_importer.py +12 -10
  54. jaclang/compiler/tests/test_parser.py +249 -3
  55. jaclang/compiler/type_system/type_evaluator.jac +1078 -0
  56. jaclang/compiler/type_system/type_utils.py +1 -1
  57. jaclang/compiler/type_system/types.py +6 -0
  58. jaclang/compiler/unitree.py +438 -82
  59. jaclang/langserve/engine.jac +224 -288
  60. jaclang/langserve/sem_manager.jac +12 -8
  61. jaclang/langserve/server.jac +48 -48
  62. jaclang/langserve/tests/fixtures/greet.py +17 -0
  63. jaclang/langserve/tests/fixtures/md_path.jac +22 -0
  64. jaclang/langserve/tests/fixtures/user.jac +15 -0
  65. jaclang/langserve/tests/test_server.py +66 -371
  66. jaclang/lib.py +17 -0
  67. jaclang/runtimelib/archetype.py +25 -25
  68. jaclang/runtimelib/client_bundle.py +169 -0
  69. jaclang/runtimelib/client_runtime.jac +586 -0
  70. jaclang/runtimelib/constructs.py +4 -2
  71. jaclang/runtimelib/machine.py +308 -139
  72. jaclang/runtimelib/meta_importer.py +111 -22
  73. jaclang/runtimelib/mtp.py +15 -0
  74. jaclang/runtimelib/server.py +1089 -0
  75. jaclang/runtimelib/tests/fixtures/client_app.jac +18 -0
  76. jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
  77. jaclang/runtimelib/tests/fixtures/savable_object.jac +4 -5
  78. jaclang/runtimelib/tests/fixtures/serve_api.jac +75 -0
  79. jaclang/runtimelib/tests/test_client_bundle.py +55 -0
  80. jaclang/runtimelib/tests/test_client_render.py +63 -0
  81. jaclang/runtimelib/tests/test_serve.py +1069 -0
  82. jaclang/settings.py +0 -3
  83. jaclang/tests/fixtures/attr_pattern_case.jac +18 -0
  84. jaclang/tests/fixtures/funccall_genexpr.jac +7 -0
  85. jaclang/tests/fixtures/funccall_genexpr.py +5 -0
  86. jaclang/tests/fixtures/iife_functions.jac +142 -0
  87. jaclang/tests/fixtures/iife_functions_client.jac +143 -0
  88. jaclang/tests/fixtures/multistatement_lambda.jac +116 -0
  89. jaclang/tests/fixtures/multistatement_lambda_client.jac +113 -0
  90. jaclang/tests/fixtures/needs_import_dup.jac +6 -4
  91. jaclang/tests/fixtures/py2jac_empty.py +0 -0
  92. jaclang/tests/fixtures/py_run.py +7 -5
  93. jaclang/tests/fixtures/pyfunc_fstr.py +2 -2
  94. jaclang/tests/fixtures/simple_lambda_test.jac +12 -0
  95. jaclang/tests/test_cli.py +134 -18
  96. jaclang/tests/test_language.py +120 -32
  97. jaclang/tests/test_reference.py +20 -3
  98. jaclang/utils/NonGPT.py +375 -0
  99. jaclang/utils/helpers.py +64 -20
  100. jaclang/utils/lang_tools.py +31 -4
  101. jaclang/utils/tests/test_lang_tools.py +5 -16
  102. jaclang/utils/treeprinter.py +8 -3
  103. {jaclang-0.8.8.dist-info → jaclang-0.8.10.dist-info}/METADATA +3 -3
  104. {jaclang-0.8.8.dist-info → jaclang-0.8.10.dist-info}/RECORD +106 -71
  105. jaclang/compiler/passes/main/binder_pass.py +0 -594
  106. jaclang/compiler/passes/main/tests/fixtures/sym_binder.jac +0 -47
  107. jaclang/compiler/passes/main/tests/test_binder_pass.py +0 -111
  108. jaclang/compiler/type_system/type_evaluator.py +0 -844
  109. jaclang/langserve/tests/session.jac +0 -294
  110. jaclang/langserve/tests/test_dev_server.py +0 -80
  111. jaclang/runtimelib/importer.py +0 -351
  112. jaclang/tests/test_typecheck.py +0 -542
  113. {jaclang-0.8.8.dist-info → jaclang-0.8.10.dist-info}/WHEEL +0 -0
  114. {jaclang-0.8.8.dist-info → jaclang-0.8.10.dist-info}/entry_points.txt +0 -0
@@ -1,351 +0,0 @@
1
- """Special Imports for Jac Code."""
2
-
3
- from __future__ import annotations
4
-
5
- import os
6
- import types
7
- from os import getcwd, path
8
- from typing import Optional, Union
9
-
10
- from jaclang.runtimelib.machine import JacMachineInterface
11
- from jaclang.runtimelib.utils import sys_path_context
12
- from jaclang.utils.helpers import dump_traceback
13
- from jaclang.utils.log import logging
14
- from jaclang.utils.module_resolver import get_jac_search_paths
15
-
16
- logger = logging.getLogger(__name__)
17
-
18
-
19
- class ImportPathSpec:
20
- """Import Specification."""
21
-
22
- def __init__(
23
- self,
24
- target: str,
25
- base_path: str,
26
- absorb: bool,
27
- mdl_alias: Optional[str],
28
- override_name: Optional[str],
29
- lng: Optional[str],
30
- items: Optional[dict[str, Union[str, Optional[str]]]],
31
- ) -> None:
32
- """Initialize the ImportPathSpec object."""
33
- self.target = target
34
- self.base_path = base_path
35
- self.absorb = absorb
36
- self.mdl_alias = mdl_alias
37
- self.override_name = override_name
38
- self.language = lng
39
- self.items = items
40
- self.dir_path, self.file_name = path.split(path.join(*(target.split("."))))
41
- self.module_name = path.splitext(self.file_name)[0]
42
- self.package_path = self.dir_path.replace(path.sep, ".")
43
- self.caller_dir = self.get_caller_dir()
44
- self.full_target = path.abspath(path.join(self.caller_dir, self.file_name))
45
-
46
- def get_caller_dir(self) -> str:
47
- """Get the directory of the caller."""
48
- caller_dir = (
49
- self.base_path
50
- if path.isdir(self.base_path)
51
- else path.dirname(self.base_path)
52
- )
53
- caller_dir = caller_dir if caller_dir else getcwd()
54
- chomp_target = self.target
55
- if chomp_target.startswith("."):
56
- chomp_target = chomp_target[1:]
57
- while chomp_target.startswith("."):
58
- caller_dir = path.dirname(caller_dir)
59
- chomp_target = chomp_target[1:]
60
- return path.join(caller_dir, self.dir_path)
61
-
62
-
63
- class ImportReturn:
64
- """Import Return Object."""
65
-
66
- def __init__(
67
- self,
68
- ret_mod: types.ModuleType,
69
- ret_items: list[types.ModuleType],
70
- importer: Importer,
71
- ) -> None:
72
- """Initialize the ImportReturn object."""
73
- self.ret_mod = ret_mod
74
- self.ret_items = ret_items
75
- self.importer = importer
76
-
77
- def process_items(
78
- self,
79
- module: types.ModuleType,
80
- items: dict[str, Union[str, Optional[str]]],
81
- lang: Optional[str],
82
- ) -> None:
83
- """Process items within a module by handling renaming and potentially loading missing attributes."""
84
-
85
- def handle_item_loading(
86
- item: types.ModuleType, alias: Union[str, Optional[str]]
87
- ) -> None:
88
- if item:
89
- self.ret_items.append(item)
90
- setattr(module, name, item)
91
- if alias and alias != name and not isinstance(alias, bool):
92
- setattr(module, alias, item)
93
-
94
- for name, alias in items.items():
95
- item = getattr(module, name)
96
- handle_item_loading(item, alias)
97
-
98
- def load_jac_mod_as_item(
99
- self,
100
- module: types.ModuleType,
101
- name: str,
102
- jac_file_path: str,
103
- ) -> Optional[types.ModuleType]:
104
- """Load a single .jac file into the specified module component."""
105
- from jaclang.runtimelib.machine import JacMachine
106
-
107
- try:
108
- package_name = (
109
- f"{module.__name__}.{name}"
110
- if hasattr(module, "__path__")
111
- else module.__name__
112
- )
113
- if isinstance(self.importer, JacImporter):
114
- new_module = JacMachine.loaded_modules.get(
115
- package_name,
116
- self.importer.create_jac_py_module(
117
- self.importer.get_sys_mod_name(jac_file_path),
118
- module.__name__,
119
- jac_file_path,
120
- ),
121
- )
122
- codeobj = JacMachine.program.get_bytecode(full_target=jac_file_path)
123
- if not codeobj:
124
- raise ImportError(f"No bytecode found for {jac_file_path}")
125
-
126
- exec(codeobj, new_module.__dict__)
127
- return getattr(new_module, name, new_module)
128
- except ImportError as e:
129
- logger.error(dump_traceback(e))
130
- return None
131
-
132
-
133
- class Importer:
134
- """Abstract base class for all importers."""
135
-
136
- def __init__(self) -> None:
137
- """Initialize the Importer object."""
138
- self.result: Optional[ImportReturn] = None
139
-
140
- def run_import(self, spec: ImportPathSpec) -> ImportReturn:
141
- """Run the import process."""
142
- raise NotImplementedError
143
-
144
-
145
- class PythonImporter(Importer):
146
- """Importer for Python modules using Jac AST conversion."""
147
-
148
- def __init__(self) -> None:
149
- """Initialize the Python importer."""
150
- super().__init__()
151
- from jaclang.utils.module_resolver import PythonModuleResolver
152
-
153
- self.resolver = PythonModuleResolver()
154
-
155
- def load_and_execute(self, file_path: str) -> types.ModuleType:
156
- """Convert Python file to Jac AST and create module."""
157
- module_name = os.path.splitext(os.path.basename(file_path))[0]
158
- module = types.ModuleType(module_name)
159
- module.__file__ = file_path
160
- module.__name__ = "__main__"
161
-
162
- from jaclang.runtimelib.machine import JacMachine
163
-
164
- codeobj = JacMachine.program.get_bytecode(full_target=file_path)
165
- if codeobj:
166
- exec(codeobj, module.__dict__)
167
- else:
168
- raise ImportError(f"Failed to generate bytecode for {file_path}")
169
-
170
- return module
171
-
172
- def run_import(self, spec: ImportPathSpec) -> ImportReturn:
173
- """Run the import process for Python modules using Jac AST."""
174
- try:
175
- python_file_path = self.resolver.resolve_module_path(
176
- target=spec.target,
177
- base_path=spec.base_path,
178
- )
179
- imported_module = self.load_and_execute(python_file_path)
180
- # JacMachineInterface.load_module(imported_module.__name__, imported_module)
181
-
182
- loaded_items: list = []
183
- self.result = ImportReturn(imported_module, loaded_items, self)
184
- return self.result
185
-
186
- except ImportError as e:
187
- raise e
188
-
189
-
190
- class JacImporter(Importer):
191
- """Importer for Jac modules."""
192
-
193
- def get_sys_mod_name(self, full_target: str) -> str:
194
- """Generate proper module names from file paths."""
195
- from jaclang.runtimelib.machine import JacMachine
196
-
197
- full_target = os.path.abspath(full_target)
198
-
199
- # If the file is located within a site-packages directory, strip that prefix.
200
- sp_index = full_target.find("site-packages")
201
- if sp_index != -1:
202
- # Remove the site-packages part and any leading separator.
203
- rel = full_target[sp_index + len("site-packages") :]
204
- rel = rel.lstrip(os.sep)
205
- else:
206
- rel = path.relpath(full_target, start=JacMachine.base_path_dir)
207
- rel = os.path.splitext(rel)[0]
208
- if os.path.basename(rel) == "__init__":
209
- rel = os.path.dirname(rel)
210
- mod_name = rel.replace(os.sep, ".").strip(".")
211
- return mod_name
212
-
213
- def handle_directory(
214
- self, module_name: str, full_mod_path: str
215
- ) -> types.ModuleType:
216
- """Import from a directory that potentially contains multiple Jac modules."""
217
- module_name = self.get_sys_mod_name(full_mod_path)
218
- module = types.ModuleType(module_name)
219
- module.__name__ = module_name
220
- module.__path__ = [full_mod_path]
221
- module.__file__ = None
222
-
223
- JacMachineInterface.load_module(module_name, module)
224
-
225
- # If the directory contains an __init__.jac, execute it so that the
226
- # package namespace is populated immediately (mirrors Python's own
227
- # package behaviour with __init__.py).
228
- init_jac = os.path.join(full_mod_path, "__init__.jac")
229
- if os.path.isfile(init_jac):
230
- from jaclang.runtimelib.machine import JacMachine
231
-
232
- # Point the package's __file__ to the init file for introspection
233
- module.__file__ = init_jac
234
-
235
- codeobj = JacMachine.program.get_bytecode(full_target=init_jac)
236
- if not codeobj:
237
- # Compilation should have provided bytecode for __init__.jac.
238
- # Raising ImportError here surfaces compile-time issues clearly.
239
- raise ImportError(f"No bytecode found for {init_jac}")
240
-
241
- try:
242
- # Ensure the directory is on sys.path while executing so that
243
- # relative imports inside __init__.jac resolve correctly.
244
- with sys_path_context(full_mod_path):
245
- exec(codeobj, module.__dict__)
246
- except Exception as e:
247
- # Log detailed traceback for easier debugging and re-raise.
248
- logger.error(e)
249
- logger.error(dump_traceback(e))
250
- raise e
251
-
252
- return module
253
-
254
- def create_jac_py_module(
255
- self,
256
- module_name: str,
257
- package_path: str,
258
- full_target: str,
259
- ) -> types.ModuleType:
260
- """Create a module."""
261
- from jaclang.runtimelib.machine import JacMachine
262
-
263
- module = types.ModuleType(module_name)
264
- module.__file__ = full_target
265
- module.__name__ = module_name
266
- if package_path:
267
- base_path = full_target.split(package_path.replace(".", path.sep))[0]
268
- parts = package_path.split(".")
269
- for i in range(len(parts)):
270
- package_name = ".".join(parts[: i + 1])
271
- if package_name not in JacMachine.loaded_modules:
272
- full_mod_path = path.join(
273
- base_path, package_name.replace(".", path.sep)
274
- )
275
- self.handle_directory(
276
- module_name=package_name,
277
- full_mod_path=full_mod_path,
278
- )
279
- JacMachineInterface.load_module(module_name, module)
280
- return module
281
-
282
- def run_import(
283
- self, spec: ImportPathSpec, reload: Optional[bool] = False
284
- ) -> ImportReturn:
285
- """Run the import process for Jac modules."""
286
- from jaclang.runtimelib.machine import JacMachine
287
-
288
- unique_loaded_items: list[types.ModuleType] = []
289
- module = None
290
- # Gather all possible search paths
291
- search_paths = get_jac_search_paths(spec.caller_dir)
292
-
293
- found_path = None
294
- target_path_components = spec.target.split(".")
295
- for search_path in search_paths:
296
- candidate = os.path.join(search_path, *target_path_components)
297
- # Check if the candidate is a directory or a .jac file
298
- if (os.path.isdir(candidate)) or (os.path.isfile(candidate + ".jac")):
299
- found_path = candidate
300
- break
301
-
302
- # If a suitable path was found, update spec.full_target; otherwise, raise an error
303
- if found_path:
304
- spec.full_target = os.path.abspath(found_path)
305
- elif os.path.exists(spec.full_target) or os.path.exists(
306
- spec.full_target + ".jac"
307
- ):
308
- pass
309
- else:
310
- raise ImportError(
311
- f"Unable to locate module '{spec.target}' in {search_paths}"
312
- )
313
- if os.path.isfile(spec.full_target + ".jac"):
314
- module_name = self.get_sys_mod_name(spec.full_target + ".jac")
315
- module_name = spec.override_name if spec.override_name else module_name
316
- else:
317
- module_name = self.get_sys_mod_name(spec.full_target)
318
-
319
- module = JacMachine.loaded_modules.get(module_name)
320
-
321
- if not module or module.__name__ == "__main__" or reload:
322
- if os.path.isdir(spec.full_target):
323
- module = self.handle_directory(spec.module_name, spec.full_target)
324
- else:
325
- spec.full_target += ".jac" if spec.language in ["jac", "jir"] else ".py"
326
- module = self.create_jac_py_module(
327
- module_name,
328
- spec.package_path,
329
- spec.full_target,
330
- )
331
- codeobj = JacMachine.program.get_bytecode(full_target=spec.full_target)
332
-
333
- # Since this is a compile time error, we can safely raise an exception here.
334
- if not codeobj:
335
- raise ImportError(f"No bytecode found for {spec.full_target}")
336
-
337
- try:
338
- with sys_path_context(spec.caller_dir):
339
- exec(codeobj, module.__dict__)
340
- except Exception as e:
341
- logger.error(e)
342
- logger.error(dump_traceback(e))
343
- raise e
344
-
345
- import_return = ImportReturn(module, unique_loaded_items, self)
346
- if spec.items:
347
- import_return.process_items(
348
- module=module, items=spec.items, lang=spec.language
349
- )
350
- self.result = import_return
351
- return self.result