onec-interactive-runtime-core 0.1.19__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.
- onec_interactive_runtime_core-0.1.19.dist-info/METADATA +12 -0
- onec_interactive_runtime_core-0.1.19.dist-info/RECORD +87 -0
- onec_interactive_runtime_core-0.1.19.dist-info/WHEEL +4 -0
- onec_interactive_runtime_core-0.1.19.dist-info/licenses/COPYRIGHT +9 -0
- onec_interactive_runtime_core-0.1.19.dist-info/licenses/LICENSE +232 -0
- onec_interactive_runtime_core-0.1.19.dist-info/licenses/THIRD_PARTY_NOTICES.txt +32 -0
- onec_runtime/AGENTS.md +7 -0
- onec_runtime/__init__.py +3 -0
- onec_runtime/artifacts.py +59 -0
- onec_runtime/bootstrap.py +310 -0
- onec_runtime/breakpoint_workspace.py +249 -0
- onec_runtime/bsl/__init__.py +139 -0
- onec_runtime/bsl/diagnostics.py +1046 -0
- onec_runtime/bsl/full_ast_worker_projection.py +522 -0
- onec_runtime/bsl/generated_semantic_parser.py +6322 -0
- onec_runtime/bsl/lexer.py +164 -0
- onec_runtime/bsl/module_catalog.py +420 -0
- onec_runtime/bsl/module_delta.py +1079 -0
- onec_runtime/bsl/module_universe.py +1877 -0
- onec_runtime/bsl/notebook_cells.py +232 -0
- onec_runtime/bsl/notebook_method_globals.py +74 -0
- onec_runtime/bsl/notebook_methods.py +175 -0
- onec_runtime/bsl/parser_artifact_identity.py +119 -0
- onec_runtime/bsl/parser_target.py +388 -0
- onec_runtime/bsl/preprocessor.py +16 -0
- onec_runtime/bsl/semantic_lowering.py +1539 -0
- onec_runtime/bsl/source_maps.py +2411 -0
- onec_runtime/bsl/worker_dependency_resolver.py +289 -0
- onec_runtime/bsl/worker_preprocessor.py +247 -0
- onec_runtime/bsl/worker_projection_model.py +137 -0
- onec_runtime/bsl/worker_reload_source_map.py +1697 -0
- onec_runtime/capture.py +113 -0
- onec_runtime/capture_source.py +453 -0
- onec_runtime/compact_table.py +376 -0
- onec_runtime/compact_table_backend.py +500 -0
- onec_runtime/config.py +198 -0
- onec_runtime/configurator_agent.py +520 -0
- onec_runtime/controller_worker.py +400 -0
- onec_runtime/credentials.py +18 -0
- onec_runtime/epf_container.py +196 -0
- onec_runtime/errors.py +205 -0
- onec_runtime/experiment.py +130 -0
- onec_runtime/extension_bundle.py +944 -0
- onec_runtime/extension_lifecycle.py +402 -0
- onec_runtime/extension_state.py +222 -0
- onec_runtime/fault_injection.py +30 -0
- onec_runtime/kernel.py +179 -0
- onec_runtime/lease.py +123 -0
- onec_runtime/observation.py +287 -0
- onec_runtime/performance_profile.py +245 -0
- onec_runtime/privacy.py +263 -0
- onec_runtime/processes.py +265 -0
- onec_runtime/prototype_runtime.py +2644 -0
- onec_runtime/rdbg/__init__.py +1 -0
- onec_runtime/rdbg/models.py +130 -0
- onec_runtime/rdbg/reconnect.py +59 -0
- onec_runtime/rdbg/session.py +913 -0
- onec_runtime/rdbg/transport.py +138 -0
- onec_runtime/rdbg/xml_codec.py +980 -0
- onec_runtime/recovery.py +106 -0
- onec_runtime/recovery_journal.py +79 -0
- onec_runtime/resources/extension/OnecInteractiveRuntime.cfe +0 -0
- onec_runtime/resources/extension/extension-manifest.json +108 -0
- onec_runtime/runtime_api.py +5272 -0
- onec_runtime/runtime_contracts.py +196 -0
- onec_runtime/server_worker.py +2034 -0
- onec_runtime/session.py +2123 -0
- onec_runtime/startup_diagnostics.py +45 -0
- onec_runtime/stop_routing.py +65 -0
- onec_runtime/supervised_processes.py +232 -0
- onec_runtime/supervised_runtime.py +512 -0
- onec_runtime/supervisor.py +363 -0
- onec_runtime/supervisor_model.py +148 -0
- onec_runtime/supervisor_protocol.py +77 -0
- onec_runtime/table_materialization.py +471 -0
- onec_runtime/table_transfer_backend.py +203 -0
- onec_runtime/table_value.py +311 -0
- onec_runtime/toolchain.py +730 -0
- onec_runtime/value_materialization.py +432 -0
- onec_runtime/value_transfer_backend.py +199 -0
- onec_runtime/worker_breakpoints.py +1431 -0
- onec_runtime/worker_epf.py +313 -0
- onec_runtime/worker_epf_template.py +53 -0
- onec_runtime/worker_stage_protocol.py +516 -0
- onec_runtime/worker_universe.py +3772 -0
- onec_runtime_build/__init__.py +1 -0
- onec_runtime_build/parser_target_development.py +116 -0
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
"""Project the generated full BSL AST into the Worker-facing module model."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from bisect import bisect_left
|
|
6
|
+
from collections.abc import Iterable, Mapping
|
|
7
|
+
from dataclasses import dataclass, fields
|
|
8
|
+
|
|
9
|
+
from onec_runtime.bsl import generated_semantic_parser as generated
|
|
10
|
+
from onec_runtime.bsl.lexer import Token, tokenize
|
|
11
|
+
from onec_runtime.bsl.parser_target import BslParseError, PythonParserTarget
|
|
12
|
+
from onec_runtime.bsl.source_maps import SourceSpan, source_sha256
|
|
13
|
+
from onec_runtime.bsl.worker_preprocessor import select_server_effective_tokens
|
|
14
|
+
from onec_runtime.bsl.worker_projection_model import (
|
|
15
|
+
BareName,
|
|
16
|
+
BareNameKind,
|
|
17
|
+
ParsedMethodModel,
|
|
18
|
+
ParsedModuleModel,
|
|
19
|
+
)
|
|
20
|
+
from onec_runtime.performance_profile import PhaseRecorder
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_IGNORED = 0
|
|
24
|
+
_ONE = 1
|
|
25
|
+
_MANY = 2
|
|
26
|
+
_POSTFIX = 3
|
|
27
|
+
_HOT = 4
|
|
28
|
+
_CARRIER = 5
|
|
29
|
+
|
|
30
|
+
# Every generated dataclass field is explicit: typed semantic child edge,
|
|
31
|
+
# direct hot-path responsibility, linked carrier, or intentionally ignored
|
|
32
|
+
# scalar/non-fact field. Field order mirrors the generated dataclasses.
|
|
33
|
+
_NODE_FIELD_SCHEMA: dict[str, tuple[tuple[str, int], ...]] = {
|
|
34
|
+
"Module": (("Declarations", _MANY), ("Elements", _ONE), ("span", _IGNORED)),
|
|
35
|
+
"ModuleElements": (("Item", _CARRIER), ("Rest", _CARRIER), ("span", _IGNORED)),
|
|
36
|
+
"NotebookCell": (("Elements", _ONE), ("span", _IGNORED)),
|
|
37
|
+
"ModuleVariableDeclaration": (("Variables", _MANY), ("span", _IGNORED)),
|
|
38
|
+
"ModuleVariable": (("Name", _IGNORED), ("Export", _IGNORED), ("span", _IGNORED)),
|
|
39
|
+
"Method": (
|
|
40
|
+
("Decorations", _MANY), ("Async", _IGNORED),
|
|
41
|
+
("Declaration", _ONE), ("span", _IGNORED),
|
|
42
|
+
),
|
|
43
|
+
"ProcedureDeclaration": (
|
|
44
|
+
("Name", _IGNORED), ("Parameters", _ONE), ("Export", _IGNORED),
|
|
45
|
+
("Body", _ONE), ("span", _IGNORED),
|
|
46
|
+
),
|
|
47
|
+
"FunctionDeclaration": (
|
|
48
|
+
("Name", _IGNORED), ("Parameters", _ONE), ("Export", _IGNORED),
|
|
49
|
+
("Body", _ONE), ("span", _IGNORED),
|
|
50
|
+
),
|
|
51
|
+
"MethodBody": (("LocalDeclarations", _MANY), ("Code", _ONE), ("span", _IGNORED)),
|
|
52
|
+
"LocalVariableDeclaration": (("Names", _HOT), ("span", _IGNORED)),
|
|
53
|
+
"ParameterList": (("Items", _MANY), ("span", _IGNORED)),
|
|
54
|
+
"Parameter": (
|
|
55
|
+
("Decorations", _HOT), ("ByValue", _IGNORED), ("Name", _HOT),
|
|
56
|
+
("Default", _HOT), ("span", _IGNORED),
|
|
57
|
+
),
|
|
58
|
+
"SignedConstant": (("Sign", _IGNORED), ("Value", _IGNORED), ("span", _IGNORED)),
|
|
59
|
+
"Decoration": (("Name", _IGNORED), ("Parameters", _ONE), ("span", _IGNORED)),
|
|
60
|
+
"AnnotationParameters": (("Items", _MANY), ("span", _IGNORED)),
|
|
61
|
+
"NamedAnnotationParameter": (("Name", _IGNORED), ("Value", _ONE), ("span", _IGNORED)),
|
|
62
|
+
"PositionalAnnotationParameter": (("Value", _ONE), ("span", _IGNORED)),
|
|
63
|
+
"CodeBlock": (("First", _CARRIER), ("Rest", _CARRIER), ("span", _IGNORED)),
|
|
64
|
+
"LabeledStatement": (("Label", _IGNORED), ("Statement", _ONE), ("span", _IGNORED)),
|
|
65
|
+
"Label": (("Name", _IGNORED), ("span", _IGNORED)),
|
|
66
|
+
"ContinueStatement": (("span", _IGNORED),),
|
|
67
|
+
"BreakStatement": (("span", _IGNORED),),
|
|
68
|
+
"GotoStatement": (("Label", _IGNORED), ("span", _IGNORED)),
|
|
69
|
+
"IfStatement": (
|
|
70
|
+
("Condition", _ONE), ("Then", _ONE), ("ElseIf", _MANY),
|
|
71
|
+
("Else", _ONE), ("span", _IGNORED),
|
|
72
|
+
),
|
|
73
|
+
"ElseIfClause": (("Condition", _ONE), ("Body", _ONE), ("span", _IGNORED)),
|
|
74
|
+
"ElseClause": (("Body", _ONE), ("span", _IGNORED)),
|
|
75
|
+
"WhileStatement": (("Condition", _ONE), ("Body", _ONE), ("span", _IGNORED)),
|
|
76
|
+
"ForEachStatement": (
|
|
77
|
+
("Variable", _HOT), ("Iterable", _HOT), ("Body", _HOT),
|
|
78
|
+
("span", _IGNORED),
|
|
79
|
+
),
|
|
80
|
+
"ForRangeStatement": (
|
|
81
|
+
("Variable", _HOT), ("Start", _HOT), ("End", _HOT),
|
|
82
|
+
("Body", _HOT), ("span", _IGNORED),
|
|
83
|
+
),
|
|
84
|
+
"TryStatement": (("TryBody", _ONE), ("ExceptBody", _ONE), ("span", _IGNORED)),
|
|
85
|
+
"ReturnStatement": (("Value", _ONE), ("span", _IGNORED)),
|
|
86
|
+
"RaiseStatement": (("Parameters", _ONE), ("span", _IGNORED)),
|
|
87
|
+
"RaiseCallParameters": (
|
|
88
|
+
("Arguments", _ONE), ("Postfix", _POSTFIX), ("Tail", _ONE),
|
|
89
|
+
("span", _IGNORED),
|
|
90
|
+
),
|
|
91
|
+
"ContinuedExpression": (
|
|
92
|
+
("PrefixOperators", _IGNORED), ("Primary", _ONE),
|
|
93
|
+
("Tail", _ONE), ("span", _IGNORED),
|
|
94
|
+
),
|
|
95
|
+
"PostfixedPrimary": (("Base", _ONE), ("Postfix", _POSTFIX), ("span", _IGNORED)),
|
|
96
|
+
"ExpressionTail": (
|
|
97
|
+
("MultiplicativeOperators", _IGNORED),
|
|
98
|
+
("MultiplicativeOperands", _MANY),
|
|
99
|
+
("AdditiveOperators", _IGNORED), ("AdditiveOperands", _MANY),
|
|
100
|
+
("ComparisonOperators", _IGNORED), ("ComparisonOperands", _MANY),
|
|
101
|
+
("AndOperands", _MANY), ("OrOperands", _MANY),
|
|
102
|
+
("span", _IGNORED),
|
|
103
|
+
),
|
|
104
|
+
"ExecuteStatement": (("Value", _ONE), ("span", _IGNORED)),
|
|
105
|
+
"AddHandlerStatement": (("Event", _ONE), ("Handler", _ONE), ("span", _IGNORED)),
|
|
106
|
+
"RemoveHandlerStatement": (("Event", _ONE), ("Handler", _ONE), ("span", _IGNORED)),
|
|
107
|
+
"AwaitStatement": (("Value", _ONE), ("span", _IGNORED)),
|
|
108
|
+
"SimpleStatement": (("Target", _HOT), ("Value", _HOT), ("span", _IGNORED)),
|
|
109
|
+
"OrExpression": (("First", _HOT), ("Operands", _HOT), ("span", _IGNORED)),
|
|
110
|
+
"AndExpression": (("First", _HOT), ("Operands", _HOT), ("span", _IGNORED)),
|
|
111
|
+
"ComparisonExpression": (
|
|
112
|
+
("First", _HOT), ("Operators", _IGNORED), ("Operands", _HOT),
|
|
113
|
+
("span", _IGNORED),
|
|
114
|
+
),
|
|
115
|
+
"AdditiveExpression": (
|
|
116
|
+
("First", _HOT), ("Operators", _IGNORED), ("Operands", _HOT),
|
|
117
|
+
("span", _IGNORED),
|
|
118
|
+
),
|
|
119
|
+
"MultiplicativeExpression": (
|
|
120
|
+
("First", _HOT), ("Operators", _IGNORED), ("Operands", _HOT),
|
|
121
|
+
("span", _IGNORED),
|
|
122
|
+
),
|
|
123
|
+
"UnaryExpression": (("Operators", _IGNORED), ("Value", _HOT), ("span", _IGNORED)),
|
|
124
|
+
"ParenthesizedExpression": (("Value", _ONE), ("Postfix", _POSTFIX), ("span", _IGNORED)),
|
|
125
|
+
"AccessChain": (("Root", _HOT), ("Arguments", _HOT), ("Postfix", _HOT), ("span", _IGNORED)),
|
|
126
|
+
"MemberAccess": (("Name", _IGNORED), ("Arguments", _ONE), ("span", _IGNORED)),
|
|
127
|
+
"IndexAccess": (("Index", _ONE), ("span", _IGNORED)),
|
|
128
|
+
"CallArguments": (("Items", _ONE), ("span", _IGNORED)),
|
|
129
|
+
"ArgumentList": (("Items", _MANY), ("span", _IGNORED)),
|
|
130
|
+
"OmittedArgument": (("span", _IGNORED),),
|
|
131
|
+
"NewExpression": (("Type", _IGNORED), ("Arguments", _ONE), ("span", _IGNORED)),
|
|
132
|
+
"TernaryExpression": (("Condition", _ONE), ("Then", _ONE), ("Else", _ONE), ("span", _IGNORED)),
|
|
133
|
+
"ConstantLiteral": (("Value", _IGNORED), ("span", _IGNORED)),
|
|
134
|
+
"RegionDirective": (("Name", _IGNORED), ("span", _IGNORED)),
|
|
135
|
+
"EndRegionDirective": (("span", _IGNORED),),
|
|
136
|
+
"PreprocessorIfDirective": (("Condition", _ONE), ("span", _IGNORED)),
|
|
137
|
+
"PreprocessorElseIfDirective": (("Condition", _ONE), ("span", _IGNORED)),
|
|
138
|
+
"PreprocessorElseDirective": (("span", _IGNORED),),
|
|
139
|
+
"PreprocessorEndIfDirective": (("span", _IGNORED),),
|
|
140
|
+
"UseDirective": (("Library", _ONE), ("span", _IGNORED)),
|
|
141
|
+
"NativeDirective": (("span", _IGNORED),),
|
|
142
|
+
"StackDirective": (("span", _IGNORED),),
|
|
143
|
+
"UsedLibrary": (("Value", _IGNORED), ("span", _IGNORED)),
|
|
144
|
+
"PreprocessorOr": (("First", _ONE), ("Operands", _MANY), ("span", _IGNORED)),
|
|
145
|
+
"PreprocessorAnd": (("First", _ONE), ("Operands", _MANY), ("span", _IGNORED)),
|
|
146
|
+
"PreprocessorNot": (("Value", _ONE), ("span", _IGNORED)),
|
|
147
|
+
"PreprocessorIdentifier": (("Name", _IGNORED), ("span", _IGNORED)),
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _validate_node_field_schema(
|
|
152
|
+
ast_classes: Mapping[str, type[object]],
|
|
153
|
+
) -> None:
|
|
154
|
+
actual_types = frozenset(ast_classes)
|
|
155
|
+
classified_types = frozenset(_NODE_FIELD_SCHEMA)
|
|
156
|
+
if actual_types != classified_types:
|
|
157
|
+
raise ValueError(
|
|
158
|
+
"generated AST type schema mismatch: "
|
|
159
|
+
f"generated={sorted(actual_types)!r}, "
|
|
160
|
+
f"classified={sorted(classified_types)!r}"
|
|
161
|
+
)
|
|
162
|
+
valid_kinds = {_IGNORED, _ONE, _MANY, _POSTFIX, _HOT, _CARRIER}
|
|
163
|
+
for node_name, node_type in ast_classes.items():
|
|
164
|
+
actual_fields = tuple(field.name for field in fields(node_type))
|
|
165
|
+
classified = _NODE_FIELD_SCHEMA[node_name]
|
|
166
|
+
classified_fields = tuple(field_name for field_name, _kind in classified)
|
|
167
|
+
if actual_fields != classified_fields:
|
|
168
|
+
raise ValueError(
|
|
169
|
+
f"generated AST field schema mismatch for {node_name}: "
|
|
170
|
+
f"generated={actual_fields!r}, classified={classified_fields!r}"
|
|
171
|
+
)
|
|
172
|
+
if any(kind not in valid_kinds for _field_name, kind in classified):
|
|
173
|
+
raise ValueError(f"invalid AST field classification for {node_name}")
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
_validate_node_field_schema(generated.AST_CLASSES)
|
|
177
|
+
_TYPED_CHILD_EDGES: dict[type[object], tuple[tuple[str, int], ...]] = {
|
|
178
|
+
generated.AST_CLASSES[node_name]: tuple(
|
|
179
|
+
(field_name, kind)
|
|
180
|
+
for field_name, kind in field_schema
|
|
181
|
+
if kind in {_ONE, _MANY, _POSTFIX}
|
|
182
|
+
)
|
|
183
|
+
for node_name, field_schema in _NODE_FIELD_SCHEMA.items()
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@dataclass(frozen=True, slots=True)
|
|
188
|
+
class _ScopeFacts:
|
|
189
|
+
declared_names: tuple[str, ...]
|
|
190
|
+
bare_names: tuple[BareName, ...]
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _linked_items(value: object) -> tuple[object, ...]:
|
|
194
|
+
"""Flatten generated linked sequence nodes without recursive Python calls."""
|
|
195
|
+
result: list[object] = []
|
|
196
|
+
current = value
|
|
197
|
+
while isinstance(current, generated.ModuleElements):
|
|
198
|
+
if current.Item is not None:
|
|
199
|
+
result.append(current.Item)
|
|
200
|
+
current = current.Rest
|
|
201
|
+
if current is not None:
|
|
202
|
+
if isinstance(current, tuple):
|
|
203
|
+
result.extend(current)
|
|
204
|
+
else:
|
|
205
|
+
result.append(current)
|
|
206
|
+
return tuple(result)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _collect_scope_facts(roots: Iterable[object]) -> _ScopeFacts:
|
|
210
|
+
declared_names: set[str] = set()
|
|
211
|
+
# normalized -> [first span start, source-order tie-breaker, spelling, flags]
|
|
212
|
+
names: dict[str, list[object]] = {}
|
|
213
|
+
sequence = 0
|
|
214
|
+
read_kind = int(BareNameKind.READ)
|
|
215
|
+
write_kind = int(BareNameKind.BARE_WRITE)
|
|
216
|
+
stack = list(reversed(tuple(roots)))
|
|
217
|
+
|
|
218
|
+
while stack:
|
|
219
|
+
value = stack.pop()
|
|
220
|
+
value_type = type(value)
|
|
221
|
+
|
|
222
|
+
# These six precedence wrappers are over 60% of a real ZUP AST. Keep
|
|
223
|
+
# their typed edges at the front of the dispatch chain.
|
|
224
|
+
if (
|
|
225
|
+
value_type is generated.OrExpression
|
|
226
|
+
or value_type is generated.AndExpression
|
|
227
|
+
or value_type is generated.ComparisonExpression
|
|
228
|
+
or value_type is generated.AdditiveExpression
|
|
229
|
+
or value_type is generated.MultiplicativeExpression
|
|
230
|
+
):
|
|
231
|
+
if value.Operands:
|
|
232
|
+
stack.extend(reversed(value.Operands))
|
|
233
|
+
if value.First is not None:
|
|
234
|
+
stack.append(value.First)
|
|
235
|
+
continue
|
|
236
|
+
if value_type is generated.UnaryExpression:
|
|
237
|
+
if value.Value is not None:
|
|
238
|
+
stack.append(value.Value)
|
|
239
|
+
continue
|
|
240
|
+
if (
|
|
241
|
+
value_type is generated.SimpleStatement
|
|
242
|
+
or value_type is generated.AccessChain
|
|
243
|
+
):
|
|
244
|
+
if value_type is generated.SimpleStatement:
|
|
245
|
+
target = value.Target
|
|
246
|
+
if type(target) is not generated.AccessChain:
|
|
247
|
+
raise TypeError(
|
|
248
|
+
"generated SimpleStatement has an unsupported target"
|
|
249
|
+
)
|
|
250
|
+
if value.Value is None:
|
|
251
|
+
has_call = target.Arguments is not None or any(
|
|
252
|
+
type(marker) is generated.MemberAccess
|
|
253
|
+
and marker.Arguments is not None
|
|
254
|
+
for marker in target.Postfix
|
|
255
|
+
)
|
|
256
|
+
if not has_call:
|
|
257
|
+
raise BslParseError(
|
|
258
|
+
"bare access-chain statement is forbidden at "
|
|
259
|
+
f"{target.span.start}",
|
|
260
|
+
span=target.span,
|
|
261
|
+
code="bare_access_chain_statement",
|
|
262
|
+
)
|
|
263
|
+
else:
|
|
264
|
+
stack.append(value.Value)
|
|
265
|
+
direct_write = bool(
|
|
266
|
+
value.Value is not None
|
|
267
|
+
and target.Root
|
|
268
|
+
and target.Arguments is None
|
|
269
|
+
and not target.Postfix
|
|
270
|
+
)
|
|
271
|
+
else:
|
|
272
|
+
target = value
|
|
273
|
+
direct_write = False
|
|
274
|
+
|
|
275
|
+
name = str(target.Root)
|
|
276
|
+
normalized = name.casefold()
|
|
277
|
+
fact_kind = write_kind if direct_write else read_kind
|
|
278
|
+
fact = names.get(normalized)
|
|
279
|
+
if fact is None:
|
|
280
|
+
names[normalized] = [
|
|
281
|
+
target.span.start, sequence, name, fact_kind,
|
|
282
|
+
]
|
|
283
|
+
else:
|
|
284
|
+
fact[3] = int(fact[3]) | fact_kind
|
|
285
|
+
if (target.span.start, sequence) < (int(fact[0]), int(fact[1])):
|
|
286
|
+
fact[0] = target.span.start
|
|
287
|
+
fact[1] = sequence
|
|
288
|
+
fact[2] = name
|
|
289
|
+
sequence += 1
|
|
290
|
+
|
|
291
|
+
if not direct_write:
|
|
292
|
+
for marker in reversed(target.Postfix):
|
|
293
|
+
if type(marker) is generated.MemberAccess:
|
|
294
|
+
if marker.Arguments is not None:
|
|
295
|
+
stack.append(marker.Arguments)
|
|
296
|
+
elif type(marker) is generated.IndexAccess:
|
|
297
|
+
stack.append(marker.Index)
|
|
298
|
+
else:
|
|
299
|
+
raise TypeError(
|
|
300
|
+
"generated AccessChain has an unsupported postfix"
|
|
301
|
+
)
|
|
302
|
+
if target.Arguments is not None:
|
|
303
|
+
stack.append(target.Arguments)
|
|
304
|
+
continue
|
|
305
|
+
|
|
306
|
+
if value_type is generated.Parameter:
|
|
307
|
+
declared_names.add(str(value.Name).casefold())
|
|
308
|
+
if value.Default is not None:
|
|
309
|
+
stack.append(value.Default)
|
|
310
|
+
if value.Decorations:
|
|
311
|
+
stack.extend(reversed(value.Decorations))
|
|
312
|
+
elif value_type is generated.LocalVariableDeclaration:
|
|
313
|
+
declared_names.update(str(name).casefold() for name in value.Names)
|
|
314
|
+
elif value_type is generated.ForEachStatement:
|
|
315
|
+
declared_names.add(str(value.Variable).casefold())
|
|
316
|
+
if value.Body is not None:
|
|
317
|
+
stack.append(value.Body)
|
|
318
|
+
if value.Iterable is not None:
|
|
319
|
+
stack.append(value.Iterable)
|
|
320
|
+
elif value_type is generated.ForRangeStatement:
|
|
321
|
+
declared_names.add(str(value.Variable).casefold())
|
|
322
|
+
if value.Body is not None:
|
|
323
|
+
stack.append(value.Body)
|
|
324
|
+
if value.End is not None:
|
|
325
|
+
stack.append(value.End)
|
|
326
|
+
if value.Start is not None:
|
|
327
|
+
stack.append(value.Start)
|
|
328
|
+
elif value_type is generated.CodeBlock:
|
|
329
|
+
items: list[object] = []
|
|
330
|
+
current: object = value
|
|
331
|
+
while isinstance(current, generated.CodeBlock):
|
|
332
|
+
if current.First is not None:
|
|
333
|
+
items.append(current.First)
|
|
334
|
+
current = current.Rest
|
|
335
|
+
if current is not None:
|
|
336
|
+
items.append(current)
|
|
337
|
+
if items:
|
|
338
|
+
stack.extend(reversed(items))
|
|
339
|
+
elif value_type is generated.ModuleElements:
|
|
340
|
+
items = list(_linked_items(value))
|
|
341
|
+
if items:
|
|
342
|
+
stack.extend(reversed(items))
|
|
343
|
+
else:
|
|
344
|
+
child_edges = _TYPED_CHILD_EDGES.get(value_type)
|
|
345
|
+
if child_edges is None:
|
|
346
|
+
raise TypeError(
|
|
347
|
+
f"unclassified generated AST node: {value_type.__name__}"
|
|
348
|
+
)
|
|
349
|
+
for field_name, edge_kind in reversed(child_edges):
|
|
350
|
+
child = getattr(value, field_name)
|
|
351
|
+
if child is None:
|
|
352
|
+
continue
|
|
353
|
+
if edge_kind == _ONE:
|
|
354
|
+
stack.append(child)
|
|
355
|
+
elif edge_kind == _MANY:
|
|
356
|
+
if child:
|
|
357
|
+
stack.extend(reversed(child))
|
|
358
|
+
else:
|
|
359
|
+
for marker in reversed(child):
|
|
360
|
+
if type(marker) is generated.MemberAccess:
|
|
361
|
+
if marker.Arguments is not None:
|
|
362
|
+
stack.append(marker.Arguments)
|
|
363
|
+
elif type(marker) is generated.IndexAccess:
|
|
364
|
+
stack.append(marker.Index)
|
|
365
|
+
else:
|
|
366
|
+
raise TypeError(
|
|
367
|
+
"generated expression has an unsupported postfix"
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
ordered_names = sorted(names.items(), key=lambda item: (item[1][0], item[1][1]))
|
|
371
|
+
result = tuple(
|
|
372
|
+
BareName(str(fact[2]), normalized, BareNameKind(int(fact[3])))
|
|
373
|
+
for normalized, fact in ordered_names
|
|
374
|
+
)
|
|
375
|
+
return _ScopeFacts(tuple(sorted(declared_names)), tuple(result))
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def _initializer_offset(
|
|
379
|
+
body: generated.MethodBody,
|
|
380
|
+
tokens: tuple[Token, ...],
|
|
381
|
+
token_starts: tuple[int, ...],
|
|
382
|
+
) -> int:
|
|
383
|
+
declarations = body.LocalDeclarations
|
|
384
|
+
if not declarations:
|
|
385
|
+
return body.span.start
|
|
386
|
+
declaration_end = declarations[-1].span.end
|
|
387
|
+
token_index = bisect_left(token_starts, declaration_end)
|
|
388
|
+
if token_index >= len(tokens) or tokens[token_index].type != ";":
|
|
389
|
+
raise BslParseError(
|
|
390
|
+
f"local declaration terminator is missing at {declaration_end}",
|
|
391
|
+
span=SourceSpan(declaration_end, declaration_end),
|
|
392
|
+
code="projection_invariant",
|
|
393
|
+
)
|
|
394
|
+
return tokens[token_index].end
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def _project_method(
|
|
398
|
+
method: generated.Method,
|
|
399
|
+
tokens: tuple[Token, ...],
|
|
400
|
+
token_starts: tuple[int, ...],
|
|
401
|
+
) -> ParsedMethodModel:
|
|
402
|
+
declaration = method.Declaration
|
|
403
|
+
if not isinstance(
|
|
404
|
+
declaration,
|
|
405
|
+
(generated.ProcedureDeclaration, generated.FunctionDeclaration),
|
|
406
|
+
):
|
|
407
|
+
raise TypeError("generated Method has an unsupported declaration")
|
|
408
|
+
body = declaration.Body
|
|
409
|
+
if not isinstance(body, generated.MethodBody):
|
|
410
|
+
raise TypeError("generated method declaration has an unsupported body")
|
|
411
|
+
name = str(declaration.Name)
|
|
412
|
+
scope = _collect_scope_facts((declaration,))
|
|
413
|
+
return ParsedMethodModel(
|
|
414
|
+
name=name,
|
|
415
|
+
normalized_name=name.casefold(),
|
|
416
|
+
exported=declaration.Export is not None,
|
|
417
|
+
declaration_span=method.span,
|
|
418
|
+
alias_declaration_offset=body.span.start,
|
|
419
|
+
alias_initializer_offset=_initializer_offset(body, tokens, token_starts),
|
|
420
|
+
declared_names=scope.declared_names,
|
|
421
|
+
bare_names=scope.bare_names,
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def project_full_ast_module(
|
|
426
|
+
source: str,
|
|
427
|
+
root: object,
|
|
428
|
+
tokens: tuple[Token, ...],
|
|
429
|
+
*,
|
|
430
|
+
parser_identity: tuple[str, str],
|
|
431
|
+
) -> ParsedModuleModel:
|
|
432
|
+
"""Build the exact immutable Worker model without retaining AST or tokens."""
|
|
433
|
+
if not isinstance(root, generated.Module):
|
|
434
|
+
raise TypeError("root must be a generated Module")
|
|
435
|
+
if type(tokens) is not tuple:
|
|
436
|
+
raise TypeError("tokens must be an immutable tuple")
|
|
437
|
+
|
|
438
|
+
module_variables = {
|
|
439
|
+
str(variable.Name).casefold()
|
|
440
|
+
for declaration in root.Declarations
|
|
441
|
+
for variable in declaration.Variables
|
|
442
|
+
}
|
|
443
|
+
module_roots: list[object] = []
|
|
444
|
+
methods: list[generated.Method] = []
|
|
445
|
+
for item in _linked_items(root.Elements):
|
|
446
|
+
if isinstance(item, generated.Method):
|
|
447
|
+
methods.append(item)
|
|
448
|
+
else:
|
|
449
|
+
module_roots.append(item)
|
|
450
|
+
|
|
451
|
+
token_starts = tuple(token.start for token in tokens)
|
|
452
|
+
module_scope = _collect_scope_facts(module_roots)
|
|
453
|
+
module_variables.update(module_scope.declared_names)
|
|
454
|
+
return ParsedModuleModel(
|
|
455
|
+
source_sha256=source_sha256(source),
|
|
456
|
+
module_variables=tuple(sorted(module_variables)),
|
|
457
|
+
module_bare_names=module_scope.bare_names,
|
|
458
|
+
methods=tuple(
|
|
459
|
+
_project_method(method, tokens, token_starts) for method in methods
|
|
460
|
+
),
|
|
461
|
+
parser_identity=parser_identity,
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def _target_parser_identity(target: PythonParserTarget) -> tuple[str, str]:
|
|
466
|
+
package_sha256 = target.metadata.parsergen_package_sha256
|
|
467
|
+
if package_sha256 is None:
|
|
468
|
+
raise RuntimeError("full AST parser package identity is unavailable")
|
|
469
|
+
return target.metadata.parser_identity_sha256, package_sha256
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
def full_ast_parser_identity() -> tuple[str, str]:
|
|
473
|
+
"""Return provenance embedded in the committed full-AST parser artifact."""
|
|
474
|
+
return _target_parser_identity(PythonParserTarget.from_generated())
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def parse_full_ast_module(
|
|
478
|
+
source: str,
|
|
479
|
+
*,
|
|
480
|
+
profiler: PhaseRecorder | None = None,
|
|
481
|
+
) -> ParsedModuleModel:
|
|
482
|
+
"""Tokenize and parse once, then retain only the hot-reload module model."""
|
|
483
|
+
tokens = tuple(tokenize(source))
|
|
484
|
+
effective = select_server_effective_tokens(source, tokens)
|
|
485
|
+
target = PythonParserTarget.from_generated()
|
|
486
|
+
parser_identity = _target_parser_identity(target)
|
|
487
|
+
|
|
488
|
+
def parse_root() -> object:
|
|
489
|
+
return target.parse_tokens_ast(effective, "Модуль")
|
|
490
|
+
|
|
491
|
+
root = (
|
|
492
|
+
parse_root()
|
|
493
|
+
if profiler is None
|
|
494
|
+
else profiler.measure_parser("full_module_parses", parse_root)
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
def extract() -> ParsedModuleModel:
|
|
498
|
+
return project_full_ast_module(
|
|
499
|
+
source,
|
|
500
|
+
root,
|
|
501
|
+
effective,
|
|
502
|
+
parser_identity=parser_identity,
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
return extract() if profiler is None else profiler.measure("ast_model_extract", extract)
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def parse_full_ast_projected_module(
|
|
509
|
+
source: str,
|
|
510
|
+
*,
|
|
511
|
+
profiler: PhaseRecorder | None = None,
|
|
512
|
+
) -> ParsedModuleModel:
|
|
513
|
+
"""Compatibility name for benchmarks that compare full AST with Worker."""
|
|
514
|
+
return parse_full_ast_module(source, profiler=profiler)
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
__all__ = [
|
|
518
|
+
"full_ast_parser_identity",
|
|
519
|
+
"parse_full_ast_module",
|
|
520
|
+
"parse_full_ast_projected_module",
|
|
521
|
+
"project_full_ast_module",
|
|
522
|
+
]
|