ambitgraph 0.3.0__tar.gz → 0.4.0__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.
- {ambitgraph-0.3.0/ambitgraph.egg-info → ambitgraph-0.4.0}/PKG-INFO +1 -1
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/langmirror.py +163 -24
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/library.py +26 -31
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/orchestrate.py +8 -7
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/registry.py +128 -7
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/unitpage.py +20 -2
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/__init__.py +1 -1
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/codelib.py +146 -6
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/edges.py +1079 -16
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/langs.py +61 -29
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/symbols.py +823 -43
- {ambitgraph-0.3.0 → ambitgraph-0.4.0/ambitgraph.egg-info}/PKG-INFO +1 -1
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/pyproject.toml +1 -1
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/LICENSE +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/MANIFEST.in +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/README.md +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/__init__.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/__main__.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/ambit-map-enrich.md +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/ambit-mapllm-contract.md +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/cli.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/daemon.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/dialects/__init__.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/dialects/contract.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/dialects/express_pack.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/dialects/fastapi_pack.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/dialects/flask_pack.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/dialects/nextjs_pack.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/dialects/supabase_pack.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/export.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/families.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/graph.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/island_layout.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/islands.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/judged.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/kitdemo.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/load.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/mapllm.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/matched.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/model.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/objects.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/page.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/paths.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/serve.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambit_map/theme.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/WALKTHROUGH.md +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/__main__.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/cli.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/cockpit.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/config.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/console.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/demo.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/docs_discovery.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/doctor.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/duplication.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/emit.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/engine_identity.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/estimate.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/eval.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/feeds.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/gate.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/gate_check.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/gate_server.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/harvest.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/inventory.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/jscalls.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/mds.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/merge.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/merge_jsp.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/parameterize.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/pipeline.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/portal.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/pycalls.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/ratify.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/report.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/reports.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/sample.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/secretary.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/shell.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/stages.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/tables.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/tasks.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph/urcode.py +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph.egg-info/SOURCES.txt +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph.egg-info/dependency_links.txt +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph.egg-info/entry_points.txt +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph.egg-info/requires.txt +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/ambitgraph.egg-info/top_level.txt +0 -0
- {ambitgraph-0.3.0 → ambitgraph-0.4.0}/setup.cfg +0 -0
|
@@ -5,7 +5,7 @@ CENSUS.md).
|
|
|
5
5
|
ONE file replacing five scatterings: ambit_map/orchestrate.py's admission
|
|
6
6
|
copy + MAPLLM_EXTRA_INCLUDE_EXT, ambit_map/registry.py's JS_LANGS/PY_LANGS/
|
|
7
7
|
ROUTEDNESS_LANGS, ambit_map/paths.py's KIND_READER_LANGS/_GRAMMAR_EXTS, and
|
|
8
|
-
ambit_map/library.py's
|
|
8
|
+
ambit_map/library.py's own blind-sentence language vocabulary. Every value
|
|
9
9
|
below is UNCHANGED from what its scattered original held -- this module
|
|
10
10
|
only gives them one address; see each field's own comment for its prior
|
|
11
11
|
location, and the module-docstring note below for R4's "no member
|
|
@@ -31,7 +31,9 @@ module's own admission field below continues rather than replaces.
|
|
|
31
31
|
|
|
32
32
|
Unlike ambitgraph/langs.py (which imports `re` and `dataclasses` for its
|
|
33
33
|
own LangSpec declarations), this module is a pure, dependency-free LEAF:
|
|
34
|
-
no imports at all, not even stdlib
|
|
34
|
+
no imports at all, not even stdlib. Every value below is a literal, and
|
|
35
|
+
the single function here (`blind_langs`) reads only the table declared
|
|
36
|
+
directly above it, so it needs no import either. Every
|
|
35
37
|
consumer inside this package (orchestrate.py, paths.py, registry.py,
|
|
36
38
|
library.py) imports IT; it imports NONE of them, so no existing consumer
|
|
37
39
|
of registry.py/paths.py/library.py/orchestrate.py risks a cycle by their
|
|
@@ -67,16 +69,19 @@ writes.
|
|
|
67
69
|
ENGINE_DEFAULT_INCLUDE_EXT = (
|
|
68
70
|
".py", ".js", ".ts", ".tsx", ".jsx", ".java", ".jsp", ".jspf",
|
|
69
71
|
".css", ".html", ".go", ".rb", ".php", ".cs", ".sql", ".sh",
|
|
72
|
+
".c", ".h",
|
|
70
73
|
)
|
|
71
74
|
|
|
72
75
|
# The extra extensions a mapllm run admits beyond the shared engine default
|
|
73
|
-
# above -- world-popularity order per the founder's list, the C
|
|
76
|
+
# above -- world-popularity order per the founder's list, the C++
|
|
74
77
|
# foundation first (formerly ambit_map/orchestrate.py's own
|
|
75
78
|
# MAPLLM_EXTRA_INCLUDE_EXT literal; this constant is not part of
|
|
76
79
|
# ambitgraph/langs.py at all -- it is this product's OWN scope extension,
|
|
77
80
|
# mirrored here only so orchestrate.py can source every admission fact
|
|
78
|
-
# from this one file).
|
|
79
|
-
|
|
81
|
+
# from this one file). ".c"/".h" left this tuple once they gained a real
|
|
82
|
+
# LangSpec: they are ENGINE_DEFAULT_INCLUDE_EXT members above now, not a
|
|
83
|
+
# mapllm-only widening.
|
|
84
|
+
MAPLLM_EXTRA_INCLUDE_EXT = (".cpp", ".hpp", ".rs")
|
|
80
85
|
|
|
81
86
|
|
|
82
87
|
# ===========================================================================
|
|
@@ -104,6 +109,14 @@ MAPLLM_EXTRA_INCLUDE_EXT = (".c", ".h", ".cpp", ".hpp", ".rs")
|
|
|
104
109
|
JS_LANGS = ("js", "jsx", "mjs", "cjs", "ts", "tsx")
|
|
105
110
|
PY_LANGS = ("py",)
|
|
106
111
|
JAVA_LANGS = ("java",)
|
|
112
|
+
# C_LANGS: the identical one-tag grouping shape as PY_LANGS/JAVA_LANGS --
|
|
113
|
+
# "c" is the only tag ambitgraph/langs.py's "c" LangSpec ever declares
|
|
114
|
+
# (its naming_exts {".c", ".h"} both fold to that one tag), so this
|
|
115
|
+
# carries no reader-tolerance member either. Read by kind_key's include
|
|
116
|
+
# branch, which maps a C preprocessor include onto the include/static row
|
|
117
|
+
# (see registry.py's own comment there), and by the unit story's type-kind
|
|
118
|
+
# count gate.
|
|
119
|
+
C_LANGS = ("c",)
|
|
107
120
|
|
|
108
121
|
# TYPE_SYMBOL_KINDS (Java W1 repair -- the wall-legal PRODUCT-side
|
|
109
122
|
# mirror of ambitgraph/codelib.py's own _TYPE_SYMBOL_KINDS): the literal
|
|
@@ -120,6 +133,22 @@ JAVA_LANGS = ("java",)
|
|
|
120
133
|
# independently-declared copies, never a cross-wall import.
|
|
121
134
|
TYPE_SYMBOL_KINDS = ("class", "interface", "enum", "record")
|
|
122
135
|
|
|
136
|
+
# C_TYPE_SYMBOL_KINDS (the wall-legal PRODUCT-side mirror of
|
|
137
|
+
# ambitgraph/codelib.py's own _C_TYPE_SYMBOL_KINDS): the literal kind
|
|
138
|
+
# strings symbols.py's extract_c_symbols emits for a C type declaration --
|
|
139
|
+
# a tagged bodied "struct"/"union"/"enum", and "typedef". "function" is
|
|
140
|
+
# deliberately not a member (it is the callable half, the same boundary
|
|
141
|
+
# TYPE_SYMBOL_KINDS draws against "constructor"). Consumed by
|
|
142
|
+
# ambit_map/unitpage.py's class-count bucket under the C_LANGS gate above:
|
|
143
|
+
# "enum" is a member of BOTH this tuple and TYPE_SYMBOL_KINDS, and the two
|
|
144
|
+
# language gates are disjoint, so a TypeScript enum still renders as
|
|
145
|
+
# "other named symbol(s)" while a C enum counts as a type. Diffed against
|
|
146
|
+
# ambitgraph.codelib._C_TYPE_SYMBOL_KINDS by tests/test_langs_mirror_diff.py
|
|
147
|
+
# (DIFFED_FACT_NAMES entry "c_type_symbol_kinds") -- one origin
|
|
148
|
+
# (symbols.py's own kind literals), two independently-declared copies,
|
|
149
|
+
# never a cross-wall import.
|
|
150
|
+
C_TYPE_SYMBOL_KINDS = ("struct", "union", "enum", "typedef")
|
|
151
|
+
|
|
123
152
|
# NAMESPACE_LANGS (Java W1 repair -- the wall-legal PRODUCT-side mirror of
|
|
124
153
|
# ambitgraph/langs.py's own NAMESPACE_LANGS): the `lang` tags whose units
|
|
125
154
|
# get the java-namespace treatment (the languages whose LangSpec declares
|
|
@@ -183,7 +212,15 @@ ROUTEDNESS_LANGS = ("jsp", "jspf", "java")
|
|
|
183
212
|
# flask_pack) to have DETECTED this run.
|
|
184
213
|
# ===========================================================================
|
|
185
214
|
KIND_READER_LANGS = {
|
|
186
|
-
"
|
|
215
|
+
# "c" joins this row rather than opening a twentieth: the C
|
|
216
|
+
# preprocessor's own `#include` IS a static include -- the target is a
|
|
217
|
+
# literal read from the source text and never varies at runtime, which
|
|
218
|
+
# is this row's whole claim -- so registry.kind_key maps a C include
|
|
219
|
+
# edge here instead of minting a row whose sentence would repeat
|
|
220
|
+
# include/static's word for word. A C repo's include reader is
|
|
221
|
+
# therefore named as having run, where a missing member would report
|
|
222
|
+
# the include plane unmeasured on every C repo forever.
|
|
223
|
+
"include/static": frozenset({"jsp", "c"}),
|
|
187
224
|
"include/import.py": frozenset({"py"}),
|
|
188
225
|
"include/import.js": frozenset({"js"}),
|
|
189
226
|
# Java W1 (2026-09-02), additive: langs.py's java LangSpec gains
|
|
@@ -195,7 +232,29 @@ KIND_READER_LANGS = {
|
|
|
195
232
|
"include/reexport": frozenset({"js"}),
|
|
196
233
|
"include/dynamic-import": frozenset({"js"}),
|
|
197
234
|
"include/member-resolved": frozenset({"js"}),
|
|
198
|
-
|
|
235
|
+
# The Java exact-evidence call tiers (constructor resolution,
|
|
236
|
+
# static-receiver resolution, static-import binding) record PROVEN
|
|
237
|
+
# rows into this same "calls" kind: no new kind key, no new lang
|
|
238
|
+
# tag, no new symbol kind, and no new blind-prose word crosses the
|
|
239
|
+
# wall for them, so nothing about them enters this mirror or the
|
|
240
|
+
# DIFFED_FACT_NAMES set. Their twelve coverage keys -- the nine
|
|
241
|
+
# refusal/correction counters (java_ctor_target_missing,
|
|
242
|
+
# java_ctor_qualified_unresolved, java_expr_new_refused,
|
|
243
|
+
# java_static_receiver_undeclared,
|
|
244
|
+
# java_static_receiver_multisegment, java_static_import_overrides,
|
|
245
|
+
# java_static_import_target_missing,
|
|
246
|
+
# java_declaration_window_refused, java_annotation_window_refused)
|
|
247
|
+
# and the java_call_counter_samples/_files/_samples_omitted
|
|
248
|
+
# attribution trio -- are engine-side coverage keys with no
|
|
249
|
+
# product-side reader. A matched-marked calls carrier, if one
|
|
250
|
+
# ever lands, arrives as its OWN registry kind row and gains its
|
|
251
|
+
# own entry here beside this one.
|
|
252
|
+
# "c" joins this row with the C call lane (langs.py's c LangSpec
|
|
253
|
+
# declares call_lane=True and edges.py builds C its own definer pool):
|
|
254
|
+
# without the member a C repo would be told the calls reader never
|
|
255
|
+
# heard of C, the exact defect this table's own NAMESPACE_LANGS
|
|
256
|
+
# comment records for java.
|
|
257
|
+
"calls": frozenset({"jsp", "java", "py", "js", "c"}),
|
|
199
258
|
"reference/script": frozenset({"jsp"}),
|
|
200
259
|
"route/mount": frozenset({"py", "js"}),
|
|
201
260
|
"ui/component-use": frozenset({"js"}),
|
|
@@ -219,25 +278,105 @@ KIND_READER_LANGS = {
|
|
|
219
278
|
# ===========================================================================
|
|
220
279
|
_GRAMMAR_EXTS = frozenset({
|
|
221
280
|
".jsp", ".jspf", ".java", ".js", ".mjs", ".cjs", ".jsx", ".ts", ".tsx",
|
|
222
|
-
".py", ".sh", ".sql",
|
|
281
|
+
".py", ".sh", ".sql", ".c", ".h",
|
|
223
282
|
})
|
|
224
283
|
|
|
225
284
|
|
|
226
285
|
# ===========================================================================
|
|
227
|
-
# CENSUS fact 8's disclosure-gate vocabulary --
|
|
228
|
-
# ambit_map/library.py's own
|
|
229
|
-
#
|
|
230
|
-
#
|
|
231
|
-
#
|
|
232
|
-
#
|
|
233
|
-
#
|
|
234
|
-
#
|
|
235
|
-
#
|
|
236
|
-
#
|
|
237
|
-
#
|
|
238
|
-
#
|
|
239
|
-
#
|
|
240
|
-
#
|
|
241
|
-
#
|
|
286
|
+
# CENSUS fact 8's disclosure-gate vocabulary -- THE PER-SENTENCE LANGUAGE
|
|
287
|
+
# TAG, product side. Formerly ambit_map/library.py's own
|
|
288
|
+
# _BLIND_SENTENCE_LANGS/_blind_langs pair; it lives here, with every other
|
|
289
|
+
# cross-wall copy, and library.py aliases the reader.
|
|
290
|
+
#
|
|
291
|
+
# The engine declares each blind sentence's own languages AT the sentence
|
|
292
|
+
# (ambitgraph.symbols.BlindSentence's `langs`, empty meaning the sentence
|
|
293
|
+
# holds for every run). That attribute cannot reach this side of the wall:
|
|
294
|
+
# this package reads a run's ARTIFACT FILES, and json.loads hands back
|
|
295
|
+
# plain strings, so the tag is mirrored here -- the same shape
|
|
296
|
+
# ambit_map/registry.py's CALL_BLIND_MATCH already uses, an opening
|
|
297
|
+
# fragment of one engine sentence held as a stable anchor.
|
|
298
|
+
# tests/test_blind_sentence_langs.py diffs the two declarations entry by
|
|
299
|
+
# entry, in both directions, so a sentence tagged on one side and not the
|
|
300
|
+
# other is red, never a page quietly telling a reader a law about a
|
|
301
|
+
# language it never scanned.
|
|
302
|
+
#
|
|
303
|
+
# Each row is (anchor, langs): the anchor is a fragment no other blind
|
|
304
|
+
# sentence contains, and `langs` is that sentence's own `lang` tags. A
|
|
305
|
+
# sentence no row matches is universal and renders on every run.
|
|
306
|
+
#
|
|
307
|
+
# TWO KINDS OF ANCHOR, one shape. The static sentences
|
|
308
|
+
# (ambitgraph.symbols.BLIND_SENTENCES) are anchored on their opening
|
|
309
|
+
# words. The C include lane's four sentences are built per scan and carry
|
|
310
|
+
# their counts at the END, so each is anchored on the FIXED OPENING PREFIX
|
|
311
|
+
# ambitgraph/edges.py declares beside it -- retyped here by value, exactly
|
|
312
|
+
# as this module retypes every other engine literal, because the wall
|
|
313
|
+
# forbids asking the engine for it. The prefix constants and these rows are
|
|
314
|
+
# held equal by the seam tests, never by an import.
|
|
315
|
+
#
|
|
316
|
+
# The prose-word sniffing this field used to carry (BLIND_LANG_PROSE_WORDS
|
|
317
|
+
# plus library.py's compiled _BLIND_LANG_FILTER) is retired: it was an
|
|
318
|
+
# all-or-nothing guess read off a sentence's English, wrong in both
|
|
319
|
+
# directions (Java-only pages rendering C sentences, C-only pages dropping
|
|
320
|
+
# their own call-coverage note), and the tag rows below are the declared
|
|
321
|
+
# answer that replaces it.
|
|
242
322
|
# ===========================================================================
|
|
243
|
-
|
|
323
|
+
_JSP_JAVA = frozenset({"jsp", "jspf", "java"})
|
|
324
|
+
_C = frozenset({"c"})
|
|
325
|
+
BLIND_SENTENCE_LANGS = (
|
|
326
|
+
("Java declarations inside JSP scriptlet blocks", _JSP_JAVA),
|
|
327
|
+
("A Java class whose modifiers are written on their own line", _JSP_JAVA),
|
|
328
|
+
("A Java method declared inside an ANONYMOUS class body", _JSP_JAVA),
|
|
329
|
+
("A Java annotation-type declaration", _JSP_JAVA),
|
|
330
|
+
("A Java declaration with an annotation ANYWHERE on the declaration",
|
|
331
|
+
_JSP_JAVA),
|
|
332
|
+
("In Java, a constructor or static-receiver call can bind", _JSP_JAVA),
|
|
333
|
+
("A Java method inherited from a supertype", _JSP_JAVA),
|
|
334
|
+
("An anonymous class creation over a Java interface or class", _JSP_JAVA),
|
|
335
|
+
("A Java receiver separated from its method call by a line break",
|
|
336
|
+
_JSP_JAVA),
|
|
337
|
+
("Java call and type names under four characters", _JSP_JAVA),
|
|
338
|
+
("For Java, three exact-evidence tiers run before the name-match",
|
|
339
|
+
_JSP_JAVA),
|
|
340
|
+
# The call-coverage sentence names the C lane beside the JSP/Java one:
|
|
341
|
+
# a C-only run draws call edges and must keep the note that says how
|
|
342
|
+
# they were read. Anchor duplicated by value from
|
|
343
|
+
# ambit_map/registry.py's CALL_BLIND_MATCH (this module imports
|
|
344
|
+
# nothing, not even its own package's registry, which imports IT).
|
|
345
|
+
("call sites are read for the JSP/Java namespace", _JSP_JAVA | _C),
|
|
346
|
+
# The C declaration grammar's own gaps (ambitgraph.symbols.
|
|
347
|
+
# BLIND_SENTENCES), anchored on their opening words.
|
|
348
|
+
("A C `#define` is never read as a symbol", _C),
|
|
349
|
+
("A function that a macro DEFINES is not read at all", _C),
|
|
350
|
+
("Conditional and macro-body text is read exactly as written", _C),
|
|
351
|
+
("A K&R-style C definition", _C),
|
|
352
|
+
("A C definition is read at column 0 and brace depth 0 only", _C),
|
|
353
|
+
("A bodied `struct`/`union`/`enum` with no tag", _C),
|
|
354
|
+
("Only C definitions are read, never declarations", _C),
|
|
355
|
+
# The C include lane's four per-scan sentences, anchored on
|
|
356
|
+
# ambitgraph/edges.py's C_ANGLE_INCLUDE_SENTENCE_PREFIX,
|
|
357
|
+
# C_QUOTED_UNRESOLVED_SYSTEM_SENTENCE_PREFIX,
|
|
358
|
+
# C_QUOTED_UNRESOLVED_ABSENT_SENTENCE_PREFIX and
|
|
359
|
+
# C_QUOTED_UNRESOLVED_SENTENCE_PREFIX, in that order.
|
|
360
|
+
("Angle-bracket C includes are never drawn", _C),
|
|
361
|
+
("A quoted C include naming a C standard library header", _C),
|
|
362
|
+
("A quoted C include with no candidate anywhere in this scan", _C),
|
|
363
|
+
("A quoted C include this scan does hold a file for, but position "
|
|
364
|
+
"does not license,", _C),
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def blind_langs(sentence):
|
|
369
|
+
"""The `lang` tags one blind sentence is about -- the union of every
|
|
370
|
+
anchor it carries, empty when it names no language at all. Empty is
|
|
371
|
+
the universal answer, not the unknown one: a sentence this vocabulary
|
|
372
|
+
does not describe is a sentence about the instrument, true on every
|
|
373
|
+
run, so it is kept rather than guessed at.
|
|
374
|
+
|
|
375
|
+
The one function in this module: it reads only the table right above
|
|
376
|
+
it and the string handed to it, so it stays as dependency-free as
|
|
377
|
+
every literal here."""
|
|
378
|
+
out = set()
|
|
379
|
+
for anchor, tags in BLIND_SENTENCE_LANGS:
|
|
380
|
+
if anchor in sentence:
|
|
381
|
+
out |= tags
|
|
382
|
+
return frozenset(out)
|
|
@@ -22,7 +22,6 @@ per (model, dialects) OBJECT IDENTITY, file-local to this module -- see the
|
|
|
22
22
|
comment above `_MOUNTS_CACHE_MAXSIZE` below for the full argument.
|
|
23
23
|
"""
|
|
24
24
|
import collections
|
|
25
|
-
import re
|
|
26
25
|
import threading
|
|
27
26
|
|
|
28
27
|
from . import registry as reg
|
|
@@ -890,42 +889,38 @@ def _method_note1(dialects):
|
|
|
890
889
|
return ob.note(lead + "".join(clauses))
|
|
891
890
|
|
|
892
891
|
|
|
893
|
-
#
|
|
894
|
-
#
|
|
895
|
-
#
|
|
896
|
-
#
|
|
897
|
-
#
|
|
898
|
-
|
|
899
|
-
#
|
|
900
|
-
# R4: the two words themselves now live at ambit_map/langmirror.py's own
|
|
901
|
-
# BLIND_LANG_PROSE_WORDS, declared as their OWN field rather than derived
|
|
902
|
-
# from ROUTEDNESS_LANGS/JS_LANGS above (that module's own comment states
|
|
903
|
-
# why: a vocabulary of English disclosure words, not of `lang` tags). The
|
|
904
|
-
# compiled pattern is byte-identical to the literal it replaces,
|
|
905
|
-
# r"\bjsp\b|\bjava\b".
|
|
906
|
-
_BLIND_LANG_FILTER = re.compile(
|
|
907
|
-
"|".join(r"\b%s\b" % re.escape(w) for w in langm.BLIND_LANG_PROSE_WORDS),
|
|
908
|
-
re.IGNORECASE)
|
|
892
|
+
# THE PER-SENTENCE LANGUAGE TAG's product-side reader. The table it reads
|
|
893
|
+
# (langmirror.BLIND_SENTENCE_LANGS) and this function are declared together
|
|
894
|
+
# in ambit_map/langmirror.py, beside every other copy of an engine fact
|
|
895
|
+
# that crosses the wall; this alias is what `_blind_for_run` below calls,
|
|
896
|
+
# the same alias-only shape registry.py's JS_LANGS/PY_LANGS already use.
|
|
897
|
+
_blind_langs = langm.blind_langs
|
|
909
898
|
|
|
910
899
|
|
|
911
900
|
def _blind_for_run(cov, model):
|
|
912
901
|
"""`_combined_blind` (DATA/LOGIC, kept verbatim -- other call sites in
|
|
913
902
|
this module still want the RAW list) always carries the engine's
|
|
914
|
-
static, always-present disclosures,
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
903
|
+
static, always-present disclosures, whatever the scanned tree happens
|
|
904
|
+
to contain -- the comment above ambitgraph.symbols.BLIND_SENTENCES
|
|
905
|
+
says so explicitly. A sentence naming a language is a true statement
|
|
906
|
+
only about a run that holds a unit of that language, so this caller
|
|
907
|
+
keeps a sentence when it is universal (no tag) or its tags meet the
|
|
908
|
+
run's own languages, and drops it otherwise.
|
|
909
|
+
|
|
910
|
+
Per sentence, not per run: a run holding one tagged language keeps
|
|
911
|
+
that language's sentences and still drops another language's, which
|
|
912
|
+
an all-or-nothing gate on the run could not express. The RAW list
|
|
913
|
+
still reaches `_find_blind`'s other callers unfiltered -- the graph
|
|
914
|
+
page's no-edges note states the call-graph law on runs of every
|
|
915
|
+
language mix."""
|
|
925
916
|
blind = _combined_blind(cov)
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
917
|
+
run_langs = {u.lang for u in model.units.values()}
|
|
918
|
+
out = []
|
|
919
|
+
for s in blind:
|
|
920
|
+
tags = _blind_langs(s)
|
|
921
|
+
if not tags or (tags & run_langs):
|
|
922
|
+
out.append(s)
|
|
923
|
+
return out
|
|
929
924
|
|
|
930
925
|
|
|
931
926
|
def _method_note2(model, envelope, grammarless_table=False):
|
|
@@ -106,13 +106,14 @@ MEASURED_SECONDS_PER_FILE = 0.080
|
|
|
106
106
|
ENGINE_DEFAULT_INCLUDE_EXT = langm.ENGINE_DEFAULT_INCLUDE_EXT
|
|
107
107
|
# C2 (mapllm wave): the extra extensions a mapllm run admits beyond the
|
|
108
108
|
# shared engine default above -- world-popularity order per the founder's
|
|
109
|
-
# list, the C
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
109
|
+
# list, the C++ foundation first (C itself moved into the shared engine
|
|
110
|
+
# default above once it gained a real LangSpec). `map`'s and `scan`'s own
|
|
111
|
+
# defaults stay BYTE-UNTOUCHED (the ENGINE_DEFAULT_INCLUDE_EXT equality
|
|
112
|
+
# pin just above stays green, unchanged): this list only ever widens a
|
|
113
|
+
# mapllm run's OWN generated product config (product_config()/
|
|
114
|
+
# write_product_config()/plan()'s own extra_include_ext argument, below),
|
|
115
|
+
# never ENGINE_DEFAULT_INCLUDE_EXT itself. R4: sourced from langmirror.py,
|
|
116
|
+
# same posture as the admission tuple above.
|
|
116
117
|
MAPLLM_EXTRA_INCLUDE_EXT = langm.MAPLLM_EXTRA_INCLUDE_EXT
|
|
117
118
|
FAIL_TAIL_CHARS = 1200
|
|
118
119
|
DIALECT_FILENAME = "product-dialect.json"
|
|
@@ -116,10 +116,20 @@ PY_LANGS = langm.PY_LANGS
|
|
|
116
116
|
# include/import.py and include/import.js. Same alias-only shape as the
|
|
117
117
|
# two lines above.
|
|
118
118
|
JAVA_LANGS = langm.JAVA_LANGS
|
|
119
|
+
# The fourth src_lang bucket, same alias-only shape as the three above:
|
|
120
|
+
# kind_key's include branch reads it to route a C preprocessor include,
|
|
121
|
+
# and unitpage.py's class-count bucket reads it as the gate on
|
|
122
|
+
# C_TYPE_SYMBOL_KINDS below.
|
|
123
|
+
C_LANGS = langm.C_LANGS
|
|
119
124
|
# Java W1 repair (2026-09-02), additive: the same alias-only
|
|
120
125
|
# shape, for unitpage.py's own class-count bucket -- see langmirror.py's
|
|
121
126
|
# own comment on this field for the producer/consumer/diff story.
|
|
122
127
|
TYPE_SYMBOL_KINDS = langm.TYPE_SYMBOL_KINDS
|
|
128
|
+
# The C half of the same bucket -- the kind strings extract_c_symbols
|
|
129
|
+
# emits for a type declaration; see langmirror.py's own comment on this
|
|
130
|
+
# field for the producer/consumer/diff story, and for why "enum" being a
|
|
131
|
+
# member of both sets is safe (the two language gates are disjoint).
|
|
132
|
+
C_TYPE_SYMBOL_KINDS = langm.C_TYPE_SYMBOL_KINDS
|
|
123
133
|
# Java W1 repair, additive: the language gate that
|
|
124
134
|
# TYPE_SYMBOL_KINDS' unitpage consumer needs -- same alias-only shape;
|
|
125
135
|
# see langmirror.py's own comment on this field.
|
|
@@ -263,8 +273,13 @@ _TEMPLATES = {
|
|
|
263
273
|
"reference/script": (
|
|
264
274
|
"{A} loads {B} as a script tag — a browser-side reference, not "
|
|
265
275
|
"a server-side include."),
|
|
276
|
+
# One sentence for every row on the calls plane, so it names a
|
|
277
|
+
# BINDING rather than a match: Java's exact-evidence tiers bind a
|
|
278
|
+
# site through the caller's own imports and package, while every
|
|
279
|
+
# lane's fallback tier matches a repo-unique name -- both are static
|
|
280
|
+
# reads of source text, and neither traces execution.
|
|
266
281
|
"calls": (
|
|
267
|
-
"{A} calls {B} at {n} site(s) — a static name
|
|
282
|
+
"{A} calls {B} at {n} site(s) — a static name binding, not a "
|
|
268
283
|
"traced call."),
|
|
269
284
|
"table/read": "{A} reads the {t} table.",
|
|
270
285
|
"table/write": "{A} writes the {t} table.",
|
|
@@ -365,9 +380,17 @@ _EPISTEMIC = {
|
|
|
365
380
|
"reference/script": (
|
|
366
381
|
"this is a <script src> tag read from markup; a tag injected by "
|
|
367
382
|
"client-side JS is not seen."),
|
|
383
|
+
# ambit_map/matched.py's _definer_name_index docstring cites this
|
|
384
|
+
# string by the exact phrase "unique-name static match" -- that
|
|
385
|
+
# phrase stays, as the fallback tier's own name, whatever else this
|
|
386
|
+
# string carries.
|
|
368
387
|
"calls": (
|
|
369
|
-
"unique-name static match
|
|
370
|
-
"defined in two places is dropped rather than guessed
|
|
388
|
+
"every lane ends in the same unique-name static match — a name "
|
|
389
|
+
"defined in two places is dropped rather than guessed; a Java "
|
|
390
|
+
"site may first bind proven on exact evidence: a constructor "
|
|
391
|
+
"resolved through the caller's own imports and package, a static "
|
|
392
|
+
"receiver resolved there whose method the target file declares, "
|
|
393
|
+
"or a static import whose target declares the member."),
|
|
371
394
|
"table/read": (
|
|
372
395
|
"a SQL SELECT (or equivalent read) naming a validated table, read "
|
|
373
396
|
"from the source text."),
|
|
@@ -493,6 +516,20 @@ def kind_key(plane, kind="", src_lang=""):
|
|
|
493
516
|
if plane == "include":
|
|
494
517
|
if kind == "static":
|
|
495
518
|
return "include/static"
|
|
519
|
+
# The C preprocessor's own edge kind, "include". It lands on
|
|
520
|
+
# the include/static row deliberately, not on a row of its
|
|
521
|
+
# own: that row's sentence and epistemic text -- a literal
|
|
522
|
+
# path read from the source text, spliced in at include time,
|
|
523
|
+
# never varying at runtime -- is exactly what a C `#include`
|
|
524
|
+
# is, and a twentieth row would repeat it word for word. The
|
|
525
|
+
# src_lang gate is what keeps the reuse honest: without it,
|
|
526
|
+
# any producer's edge spelled kind "include" would inherit
|
|
527
|
+
# JSP's row by accident. langmirror.KIND_READER_LANGS'
|
|
528
|
+
# include/static row carries "c" beside "jsp" for the same
|
|
529
|
+
# reason, and tests/test_langs_mirror_diff.py's include-rows
|
|
530
|
+
# union check is what holds the two together.
|
|
531
|
+
if kind == "include" and src_lang in C_LANGS:
|
|
532
|
+
return "include/static"
|
|
496
533
|
if kind == "import":
|
|
497
534
|
if src_lang in PY_LANGS:
|
|
498
535
|
return "include/import.py"
|
|
@@ -1011,6 +1048,66 @@ def importer_root_underivable_sentence(A, raw):
|
|
|
1011
1048
|
{"A": A, "raw": raw})
|
|
1012
1049
|
|
|
1013
1050
|
|
|
1051
|
+
# The C include lane's four reason tokens, one sentence each -- the same
|
|
1052
|
+
# dispatch the three above ride. EDGE_KINDS["unresolved"]'s own template
|
|
1053
|
+
# ("{A} names a target this scan never read...") is false for all four:
|
|
1054
|
+
# an angle include is HELD, never searched for; a quoted system header is
|
|
1055
|
+
# the toolchain's to find; an absent target may sit in a directory this
|
|
1056
|
+
# scan excludes, which is a scope fact, not an unread file; and the last
|
|
1057
|
+
# names a file this scan DID read and refused to draw for position. Each
|
|
1058
|
+
# sentence says which of those it is, in the same words the run's own
|
|
1059
|
+
# coverage sentence uses, so the chip and the disclosure never disagree.
|
|
1060
|
+
C_ANGLE_INCLUDE_HELD_SENTENCE = (
|
|
1061
|
+
"{A} names {raw} in angle brackets — the toolchain search path decides "
|
|
1062
|
+
"what that reaches, so the connection is held rather than drawn: a name "
|
|
1063
|
+
"matching inside this scan is not evidence the compiler reached that "
|
|
1064
|
+
"file.")
|
|
1065
|
+
_C_ANGLE_INCLUDE_HELD_SLOT_NAMES = ("A", "raw")
|
|
1066
|
+
|
|
1067
|
+
|
|
1068
|
+
def c_angle_include_held_sentence(A, raw):
|
|
1069
|
+
return _fill(C_ANGLE_INCLUDE_HELD_SENTENCE,
|
|
1070
|
+
_C_ANGLE_INCLUDE_HELD_SLOT_NAMES, {"A": A, "raw": raw})
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
C_QUOTED_INCLUDE_SYSTEM_SENTENCE = (
|
|
1074
|
+
"{A} names {raw} — a C standard library header, resolved by the "
|
|
1075
|
+
"toolchain search path rather than by position. Held, not an error "
|
|
1076
|
+
"row: imported third-party code quotes its own system headers.")
|
|
1077
|
+
_C_QUOTED_INCLUDE_SYSTEM_SLOT_NAMES = ("A", "raw")
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
def c_quoted_include_system_sentence(A, raw):
|
|
1081
|
+
return _fill(C_QUOTED_INCLUDE_SYSTEM_SENTENCE,
|
|
1082
|
+
_C_QUOTED_INCLUDE_SYSTEM_SLOT_NAMES, {"A": A, "raw": raw})
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
C_QUOTED_INCLUDE_ABSENT_SENTENCE = (
|
|
1086
|
+
"{A} names {raw} — this scan holds no candidate for it anywhere: the "
|
|
1087
|
+
"target is generated at build time, or it lives in a directory this "
|
|
1088
|
+
"scan excludes, or it is a header from outside this repository that "
|
|
1089
|
+
"the C standard list does not name.")
|
|
1090
|
+
_C_QUOTED_INCLUDE_ABSENT_SLOT_NAMES = ("A", "raw")
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
def c_quoted_include_absent_sentence(A, raw):
|
|
1094
|
+
return _fill(C_QUOTED_INCLUDE_ABSENT_SENTENCE,
|
|
1095
|
+
_C_QUOTED_INCLUDE_ABSENT_SLOT_NAMES, {"A": A, "raw": raw})
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
C_QUOTED_INCLUDE_UNRESOLVED_SENTENCE = (
|
|
1099
|
+
"{A} names {raw} — this scan does hold a file for it, but position "
|
|
1100
|
+
"does not license the edge: a one-segment name is licensed only from "
|
|
1101
|
+
"the including directory, and a multi-segment path must end exactly "
|
|
1102
|
+
"one file in the scan.")
|
|
1103
|
+
_C_QUOTED_INCLUDE_UNRESOLVED_SLOT_NAMES = ("A", "raw")
|
|
1104
|
+
|
|
1105
|
+
|
|
1106
|
+
def c_quoted_include_unresolved_sentence(A, raw):
|
|
1107
|
+
return _fill(C_QUOTED_INCLUDE_UNRESOLVED_SENTENCE,
|
|
1108
|
+
_C_QUOTED_INCLUDE_UNRESOLVED_SLOT_NAMES, {"A": A, "raw": raw})
|
|
1109
|
+
|
|
1110
|
+
|
|
1014
1111
|
def unresolved_reason_sentence(reason, A, raw):
|
|
1015
1112
|
"""The reason-token dispatch every unresolved-ref caption site shares
|
|
1016
1113
|
(graph.py's _quarantine_note, unitpage.py's connections block): maps
|
|
@@ -1025,6 +1122,14 @@ def unresolved_reason_sentence(reason, A, raw):
|
|
|
1025
1122
|
return wildcard_import_sentence(A=A, raw=raw)
|
|
1026
1123
|
if reason == "importer_root_underivable":
|
|
1027
1124
|
return importer_root_underivable_sentence(A=A, raw=raw)
|
|
1125
|
+
if reason == "c_angle_include_held":
|
|
1126
|
+
return c_angle_include_held_sentence(A=A, raw=raw)
|
|
1127
|
+
if reason == "c_quoted_include_unresolved_system":
|
|
1128
|
+
return c_quoted_include_system_sentence(A=A, raw=raw)
|
|
1129
|
+
if reason == "c_quoted_include_unresolved_absent":
|
|
1130
|
+
return c_quoted_include_absent_sentence(A=A, raw=raw)
|
|
1131
|
+
if reason == "c_quoted_include_unresolved":
|
|
1132
|
+
return c_quoted_include_unresolved_sentence(A=A, raw=raw)
|
|
1028
1133
|
return ""
|
|
1029
1134
|
|
|
1030
1135
|
|
|
@@ -1142,6 +1247,14 @@ UNIT_STORY_LEAD_NOLANG = "{name} — {lines} lines"
|
|
|
1142
1247
|
UNIT_STORY_HOLDS = "the scan read {parts}"
|
|
1143
1248
|
UNIT_STORY_FNS = "{n} function(s)"
|
|
1144
1249
|
UNIT_STORY_CLASSES = "{n} class(es)"
|
|
1250
|
+
# The same bucket, worded for a language that has no classes. C's type
|
|
1251
|
+
# declarations are structs, unions, enums and typedefs, and counting them
|
|
1252
|
+
# under a word C does not have is a false statement about the file in the
|
|
1253
|
+
# first sentence of its page -- so the CALLER, which is where the language
|
|
1254
|
+
# gate on this count already lives, names the word and unit_story renders
|
|
1255
|
+
# whichever one it is handed. "type" is registered in _COUNT_NOUNS below,
|
|
1256
|
+
# without which "1 type(s)" would ship its inflection marker to a reader.
|
|
1257
|
+
UNIT_STORY_TYPES = "{n} type(s)"
|
|
1145
1258
|
# review fix (blocker, 2026-08-26): a unit whose symbols are all a kind
|
|
1146
1259
|
# other than function/method/class (a SQL table/index/trigger/sql_function,
|
|
1147
1260
|
# a TS interface/type/const...) used to fall through to UNIT_STORY_NO_SYMS
|
|
@@ -1237,8 +1350,16 @@ def _pos(n):
|
|
|
1237
1350
|
return isinstance(n, int) and not isinstance(n, bool) and n > 0
|
|
1238
1351
|
|
|
1239
1352
|
|
|
1240
|
-
def unit_story(name, lang, lines, f, c, t, inbound, edges_damaged=False, other=0
|
|
1241
|
-
|
|
1353
|
+
def unit_story(name, lang, lines, f, c, t, inbound, edges_damaged=False, other=0,
|
|
1354
|
+
class_word=UNIT_STORY_CLASSES):
|
|
1355
|
+
"""One sentence, no language-specific CLAUSE ever. `class_word` is the
|
|
1356
|
+
one language-shaped choice, and it is the caller's: the type-count
|
|
1357
|
+
bucket is filled under a per-language gate that lives there, and a
|
|
1358
|
+
language with no classes must not have its types counted under that
|
|
1359
|
+
word. The default renders the sentence every non-C page has always
|
|
1360
|
+
rendered, so a caller that never passes it is byte-unchanged.
|
|
1361
|
+
|
|
1362
|
+
Every zero clause is
|
|
1242
1363
|
OMITTED by the builder -- never a bare 0. `edges_damaged` replaces the
|
|
1243
1364
|
touches/inbound clauses with one honest "unknown" clause instead of a
|
|
1244
1365
|
false zero. `other` (review fix, blocker) is every symbol counted
|
|
@@ -1252,7 +1373,7 @@ def unit_story(name, lang, lines, f, c, t, inbound, edges_damaged=False, other=0
|
|
|
1252
1373
|
if _pos(f):
|
|
1253
1374
|
holds_parts.append(UNIT_STORY_FNS.format(n=f))
|
|
1254
1375
|
if _pos(c):
|
|
1255
|
-
holds_parts.append(
|
|
1376
|
+
holds_parts.append(class_word.format(n=c))
|
|
1256
1377
|
if _pos(other):
|
|
1257
1378
|
holds_parts.append(UNIT_STORY_OTHER.format(n=other))
|
|
1258
1379
|
segments = []
|
|
@@ -1676,7 +1797,7 @@ _COUNT_NOUNS = ("bucket", "class", "column", "day", "directory", "edge",
|
|
|
1676
1797
|
"match", "minute", "name", "neighbour", "node", "note",
|
|
1677
1798
|
"noun", "one", "origin", "page", "path", "reader",
|
|
1678
1799
|
"reference", "route", "self-reference", "site", "subtree",
|
|
1679
|
-
"symbol", "table", "unit")
|
|
1800
|
+
"symbol", "table", "type", "unit")
|
|
1680
1801
|
# Two inflection markers: "(s)" (plural adds "s") and "(es)" (plural adds
|
|
1681
1802
|
# "es", e.g. "class(es)" -> "class" / "classes"). One alternation, one
|
|
1682
1803
|
# capture group naming which suffix a hit's own noun takes.
|
|
@@ -834,16 +834,34 @@ def render_unit(model, uid, now_iso, uncap=frozenset(), dialects=None, judged=No
|
|
|
834
834
|
# and a TS interface/enum renders "class(es)" again; revert to
|
|
835
835
|
# the bare "class" check and a Java interface/enum/record falls
|
|
836
836
|
# into "other" -- both directions pinned through a real render.
|
|
837
|
+
#
|
|
838
|
+
# The C half of the same bucket, gated the identical way: a C unit
|
|
839
|
+
# counts its struct/union/enum/typedef declarations as types
|
|
840
|
+
# (reg.C_TYPE_SYMBOL_KINDS under the reg.C_LANGS gate, both
|
|
841
|
+
# diffed against ambitgraph.codelib's own sets). The gate is what
|
|
842
|
+
# keeps "enum" -- a member of BOTH kind sets -- from re-counting a
|
|
843
|
+
# TypeScript enum: the java and C gates are disjoint and a
|
|
844
|
+
# non-C, non-java unit meets neither, so every page of every other
|
|
845
|
+
# language renders byte-identically to before this branch existed.
|
|
837
846
|
java_ns = u.lang in reg.NAMESPACE_LANGS
|
|
847
|
+
c_ns = u.lang in reg.C_LANGS
|
|
838
848
|
c = sum(1 for s in u.symbols
|
|
839
849
|
if s.kind == "class"
|
|
840
|
-
or (java_ns and s.kind in reg.TYPE_SYMBOL_KINDS)
|
|
850
|
+
or (java_ns and s.kind in reg.TYPE_SYMBOL_KINDS)
|
|
851
|
+
or (c_ns and s.kind in reg.C_TYPE_SYMBOL_KINDS))
|
|
852
|
+
# ... and the WORD that bucket is counted under is decided by the
|
|
853
|
+
# SAME gate. C has no classes at all -- what it declares is
|
|
854
|
+
# structs, unions, enums and typedefs -- so a C unit's first
|
|
855
|
+
# sentence would otherwise state a construct the language does not
|
|
856
|
+
# have, about a file that cannot contain one. Every other language
|
|
857
|
+
# keeps reg.UNIT_STORY_CLASSES, the default, byte for byte.
|
|
858
|
+
class_word = reg.UNIT_STORY_TYPES if c_ns else reg.UNIT_STORY_CLASSES
|
|
841
859
|
other = len(u.symbols) - f - c
|
|
842
860
|
t = len({op.table for op in u.table_ops})
|
|
843
861
|
inbound = (len(model.included_by.get(u.uid, ())) + len(model.referenced_by.get(u.uid, ()))
|
|
844
862
|
+ len(model.called_by.get(u.uid, ())))
|
|
845
863
|
story = reg.unit_story(u.uid, u.lang, u.lines, f, c, t, inbound, model.edges_damaged,
|
|
846
|
-
other=other)
|
|
864
|
+
other=other, class_word=class_word)
|
|
847
865
|
|
|
848
866
|
hero = ob.hero(
|
|
849
867
|
crumbs=[("AmbitGraph", "/library"), ("Library", "/library"),
|