expressir 2.4.29-arm-linux

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 (426) hide show
  1. checksums.yaml +7 -0
  2. data/.cargo/config.toml +3 -0
  3. data/.github/scripts/test_installed_gem.rb +34 -0
  4. data/.github/workflows/codeql.yml +35 -0
  5. data/.github/workflows/docs.yml +99 -0
  6. data/.github/workflows/links.yml +100 -0
  7. data/.github/workflows/native-gems.yml +201 -0
  8. data/.github/workflows/rake.yml +19 -0
  9. data/.github/workflows/release.yml +37 -0
  10. data/.github/workflows/rust-ext.yml +41 -0
  11. data/.github/workflows/stress.yml +36 -0
  12. data/.github/workflows/validate_schemas.yml +48 -0
  13. data/.github/workflows/verify_remarks.yml +33 -0
  14. data/.gitignore +55 -0
  15. data/.hound.yml +3 -0
  16. data/.rspec +2 -0
  17. data/.rubocop.yml +18 -0
  18. data/.rubocop_todo.yml +297 -0
  19. data/CHANGELOG.md +159 -0
  20. data/Gemfile +18 -0
  21. data/README.adoc +2783 -0
  22. data/Rakefile +41 -0
  23. data/TODO.bugs/01-stale-transformer-autoload.md +39 -0
  24. data/TODO.bugs/02-parser-class-instance-vars.md +36 -0
  25. data/TODO.bugs/03-builder-mutable-state.md +43 -0
  26. data/TODO.bugs/04-formatter-public-send-dispatch.md +53 -0
  27. data/TODO.bugs/05-anonymous-formatter-subclass.md +45 -0
  28. data/TODO.bugs/06-collection-registry-single-source.md +53 -0
  29. data/TODO.bugs/07-require-relative-cleanup.md +42 -0
  30. data/TODO.bugs/08-require-expressir-in-commands.md +34 -0
  31. data/TODO.bugs/09-parser-split.md +53 -0
  32. data/TODO.bugs/10-to-s-override.md +42 -0
  33. data/TODO.bugs/11-parser-class-variables.md +39 -0
  34. data/TODO.bugs/12-marker-modules-vs-registry.md +64 -0
  35. data/TODO.bugs/13-string-literal-scanner-limitation.md +52 -0
  36. data/TODO.bugs/14-model-formatting-leak.md +30 -0
  37. data/TODO.bugs/15-expression-children-macro.md +27 -0
  38. data/TODO.bugs/16-pretty-formatter-duplication.md +28 -0
  39. data/TODO.bugs/17-snake-case-cache-mutable-constant.md +28 -0
  40. data/TODO.bugs/18-const-get-private-constants.md +30 -0
  41. data/TODO.bugs/19-format-methods-public.md +22 -0
  42. data/TODO.bugs/20-coverage-nested-entities-dedup.md +20 -0
  43. data/TODO.bugs/21-operator-tokens-secondary-dispatch.md +21 -0
  44. data/TODO.bugs/22-builder-fast-path-wrappers.md +32 -0
  45. data/TODO.bugs/23-coverage-inverse-maps.md +21 -0
  46. data/TODO.bugs/24-streaming-builder-complexity.md +19 -0
  47. data/TODO.bugs/25-debug-puts-in-production.md +21 -0
  48. data/TODO.bugs/26-generic-entity-children-misplaced.md +21 -0
  49. data/TODO.bugs/27-package-build-god-method.md +19 -0
  50. data/TODO.bugs/28-package-god-class.md +30 -0
  51. data/TODO.bugs/29-validate-ascii-god-class.md +24 -0
  52. data/TODO.bugs/30-unicode-map-extraction.md +19 -0
  53. data/TODO.bugs/README.md +43 -0
  54. data/TODO.max-perf/01-restore-ci-green.md +36 -0
  55. data/TODO.max-perf/02-streaming-parse-path.md +31 -0
  56. data/TODO.max-perf/03-cli-parallel-opt-in.md +27 -0
  57. data/TODO.max-perf/04-benchmark-harness.md +28 -0
  58. data/TODO.max-perf/05-parallel-fidelity-specs.md +22 -0
  59. data/TODO.max-perf/06-builder-cpu-audit.md +41 -0
  60. data/TODO.max-perf/07-upstream-parsanol-roadmap.md +27 -0
  61. data/TODO.max-perf/08-builder-build-perf.md +45 -0
  62. data/TODO.max-perf/09-grammar-cold-start.md +25 -0
  63. data/TODO.max-perf/10-parser-facade-hygiene.md +23 -0
  64. data/TODO.max-perf/11-ci-green-closeout.md +25 -0
  65. data/TODO.max-perf/12-require-boot-profile.md +25 -0
  66. data/TODO.max-perf/13-key-conversion-specs.md +26 -0
  67. data/TODO.max-perf/14-builder-call-handler-audit.md +28 -0
  68. data/TODO.parity-ee/00-overview.md +76 -0
  69. data/TODO.parity-ee/01-annex-g-rule-extraction.md +41 -0
  70. data/TODO.parity-ee/02-eeng-algorithm-inventory.md +8 -0
  71. data/TODO.parity-ee/03-eeng-oracle-harness.md +33 -0
  72. data/TODO.parity-ee/04-shtolo-concatenate.md +44 -0
  73. data/TODO.parity-ee/05-shtolo-longform-flatten.md +53 -0
  74. data/TODO.parity-ee/06-interface-scheduling-parity.md +47 -0
  75. data/TODO.parity-ee/07-semantic-checks-port.md +35 -0
  76. data/TODO.parity-ee/08-pretty-roundtrip-gate.md +27 -0
  77. data/TODO.parity-ee/09-smrl-index-and-listing.md +22 -0
  78. data/TODO.parity-ee/10-interface-dot-graph.md +21 -0
  79. data/TODO.parity-ee/11-import-eeng-tests.md +79 -0
  80. data/TODO.parity-ee/12-full-check-catalog.md +67 -0
  81. data/TODO.parity-ee/13-population-p21.md +54 -0
  82. data/TODO.parity-ee/14-shtolo-completion.md +44 -0
  83. data/TODO.parity-ee/15-part28-xml.md +51 -0
  84. data/TODO.parity-ee/16-compare-patch.md +48 -0
  85. data/TODO.parity-ee/17-official-tests.md +42 -0
  86. data/TODO.parity-ee/18-mim-mapping.md +47 -0
  87. data/TODO.parity-ee/19-architecture.md +97 -0
  88. data/TODO.parity-ee/parity-matrix.md +108 -0
  89. data/TODO.refpath-v2/00-overview.md +64 -0
  90. data/TODO.suma-improvements/00-overview.md +23 -0
  91. data/TODO.suma-improvements/01-prebuilt-platform-gems.md +33 -0
  92. data/TODO.suma-improvements/02-suma-e2e.md +39 -0
  93. data/TODO.suma-improvements/03-item-graph.md +22 -0
  94. data/TODO.suma-improvements/04-compiled-set-default.md +16 -0
  95. data/TODO.suma-improvements/05-validation-in-docs.md +17 -0
  96. data/TODO.suma-improvements/06-memory-remeasure.md +36 -0
  97. data/TODO.suma-improvements/07-part28-xml.md +15 -0
  98. data/TODO.suma-improvements/08-windows-gnu-toolchain.md +15 -0
  99. data/TODO.suma-improvements/09-checker-tranche3.md +13 -0
  100. data/TODO.suma-improvements/10-expressdoc.md +8 -0
  101. data/benchmark/srl_benchmark.rb +458 -0
  102. data/benchmark/srl_native_benchmark.rb +146 -0
  103. data/benchmark/srl_ruby_benchmark.rb +132 -0
  104. data/bin/console +11 -0
  105. data/bin/rspec +30 -0
  106. data/bin/setup +8 -0
  107. data/docs/Gemfile +12 -0
  108. data/docs/_config.yml +141 -0
  109. data/docs/_guides/changes/changes-format.adoc +778 -0
  110. data/docs/_guides/changes/importing-eengine.adoc +898 -0
  111. data/docs/_guides/changes/index.adoc +396 -0
  112. data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
  113. data/docs/_guides/changes/validating-changes.adoc +681 -0
  114. data/docs/_guides/cli/benchmark-performance.adoc +834 -0
  115. data/docs/_guides/cli/coverage-analysis.adoc +921 -0
  116. data/docs/_guides/cli/format-schemas.adoc +547 -0
  117. data/docs/_guides/cli/index.adoc +8 -0
  118. data/docs/_guides/cli/managing-changes.adoc +927 -0
  119. data/docs/_guides/cli/validate-ascii.adoc +645 -0
  120. data/docs/_guides/cli/validate-schemas.adoc +534 -0
  121. data/docs/_guides/formatter/formatter-architecture.adoc +401 -0
  122. data/docs/_guides/index.adoc +165 -0
  123. data/docs/_guides/ler/creating-packages.adoc +664 -0
  124. data/docs/_guides/ler/index.adoc +305 -0
  125. data/docs/_guides/ler/loading-packages.adoc +707 -0
  126. data/docs/_guides/ler/package-formats.adoc +748 -0
  127. data/docs/_guides/ler/querying-packages.adoc +826 -0
  128. data/docs/_guides/ler/step-packages.adoc +385 -0
  129. data/docs/_guides/ler/validating-packages.adoc +750 -0
  130. data/docs/_guides/liquid/basic-templates.adoc +813 -0
  131. data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
  132. data/docs/_guides/liquid/drops-reference.adoc +829 -0
  133. data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
  134. data/docs/_guides/liquid/index.adoc +468 -0
  135. data/docs/_guides/manifests/creating-manifests.adoc +483 -0
  136. data/docs/_guides/manifests/index.adoc +307 -0
  137. data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
  138. data/docs/_guides/manifests/validating-manifests.adoc +713 -0
  139. data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
  140. data/docs/_guides/ruby-api/index.adoc +257 -0
  141. data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
  142. data/docs/_guides/ruby-api/search-engine.adoc +609 -0
  143. data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
  144. data/docs/_pages/data-model.adoc +665 -0
  145. data/docs/_pages/express-language.adoc +506 -0
  146. data/docs/_pages/getting-started.adoc +414 -0
  147. data/docs/_pages/index.adoc +116 -0
  148. data/docs/_pages/introduction.adoc +256 -0
  149. data/docs/_pages/ler-packages.adoc +837 -0
  150. data/docs/_pages/parsers.adoc +709 -0
  151. data/docs/_pages/schema-manifests.adoc +431 -0
  152. data/docs/_references/index.adoc +228 -0
  153. data/docs/_tutorials/creating-ler-package.adoc +735 -0
  154. data/docs/_tutorials/documentation-coverage.adoc +795 -0
  155. data/docs/_tutorials/formatting-schemas.adoc +89 -0
  156. data/docs/_tutorials/index.adoc +231 -0
  157. data/docs/_tutorials/liquid-templates.adoc +806 -0
  158. data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
  159. data/docs/_tutorials/querying-schemas.adoc +751 -0
  160. data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
  161. data/docs/index.adoc +242 -0
  162. data/docs/lychee.toml +90 -0
  163. data/examples/demo_ler_usage.sh +86 -0
  164. data/examples/ler/README.md +111 -0
  165. data/examples/ler/simple_example.ler +0 -0
  166. data/examples/ler/simple_schema.exp +33 -0
  167. data/examples/ler_build.rb +75 -0
  168. data/examples/ler_cli.rb +79 -0
  169. data/examples/ler_demo_complete.rb +276 -0
  170. data/examples/ler_query.rb +91 -0
  171. data/examples/ler_query_examples.rb +305 -0
  172. data/examples/ler_stats.rb +81 -0
  173. data/examples/phase3_demo.rb +159 -0
  174. data/examples/query_demo_simple.rb +131 -0
  175. data/exe/expressir +11 -0
  176. data/exe/expressir-format +14 -0
  177. data/exe/expressir-format-test +82 -0
  178. data/expressir.gemspec +61 -0
  179. data/lib/expressir/3.2/expressir_core.so +0 -0
  180. data/lib/expressir/3.3/expressir_core.so +0 -0
  181. data/lib/expressir/3.4/expressir_core.so +0 -0
  182. data/lib/expressir/4.0/expressir_core.so +0 -0
  183. data/lib/expressir/benchmark.rb +310 -0
  184. data/lib/expressir/changes/item_change.rb +20 -0
  185. data/lib/expressir/changes/mapping_change.rb +16 -0
  186. data/lib/expressir/changes/schema_change.rb +85 -0
  187. data/lib/expressir/changes/version_change.rb +26 -0
  188. data/lib/expressir/changes.rb +9 -0
  189. data/lib/expressir/cli.rb +148 -0
  190. data/lib/expressir/commands/base.rb +25 -0
  191. data/lib/expressir/commands/benchmark.rb +59 -0
  192. data/lib/expressir/commands/benchmark_cache.rb +80 -0
  193. data/lib/expressir/commands/changes.rb +34 -0
  194. data/lib/expressir/commands/changes_import_eengine.rb +146 -0
  195. data/lib/expressir/commands/changes_validate.rb +63 -0
  196. data/lib/expressir/commands/check.rb +56 -0
  197. data/lib/expressir/commands/clean.rb +20 -0
  198. data/lib/expressir/commands/coverage.rb +458 -0
  199. data/lib/expressir/commands/expand.rb +26 -0
  200. data/lib/expressir/commands/file_violations.rb +70 -0
  201. data/lib/expressir/commands/fix.rb +33 -0
  202. data/lib/expressir/commands/flatten.rb +29 -0
  203. data/lib/expressir/commands/format.rb +43 -0
  204. data/lib/expressir/commands/manifest.rb +420 -0
  205. data/lib/expressir/commands/mapping_validate.rb +68 -0
  206. data/lib/expressir/commands/non_ascii_character.rb +49 -0
  207. data/lib/expressir/commands/non_ascii_violation_collection.rb +301 -0
  208. data/lib/expressir/commands/package.rb +1222 -0
  209. data/lib/expressir/commands/parity_inputs.rb +160 -0
  210. data/lib/expressir/commands/validate.rb +106 -0
  211. data/lib/expressir/commands/validate_ascii.rb +94 -0
  212. data/lib/expressir/commands/validate_load.rb +91 -0
  213. data/lib/expressir/commands/version.rb +9 -0
  214. data/lib/expressir/commands/xsd.rb +23 -0
  215. data/lib/expressir/commands.rb +30 -0
  216. data/lib/expressir/config.rb +60 -0
  217. data/lib/expressir/coverage.rb +510 -0
  218. data/lib/expressir/eengine/arm_compare_report.rb +23 -0
  219. data/lib/expressir/eengine/changes_section.rb +16 -0
  220. data/lib/expressir/eengine/compare_report.rb +69 -0
  221. data/lib/expressir/eengine/mim_compare_report.rb +23 -0
  222. data/lib/expressir/eengine/modified_object.rb +21 -0
  223. data/lib/expressir/eengine.rb +9 -0
  224. data/lib/expressir/errors.rb +113 -0
  225. data/lib/expressir/express/adoc_hyperlink_formatter.rb +30 -0
  226. data/lib/expressir/express/adoc_source_formatter.rb +12 -0
  227. data/lib/expressir/express/ast_key_converter.rb +114 -0
  228. data/lib/expressir/express/builder.rb +277 -0
  229. data/lib/expressir/express/builder_context.rb +22 -0
  230. data/lib/expressir/express/builder_registry.rb +397 -0
  231. data/lib/expressir/express/builders/attribute_decl_builder.rb +32 -0
  232. data/lib/expressir/express/builders/built_in_builder.rb +75 -0
  233. data/lib/expressir/express/builders/constant_builder.rb +108 -0
  234. data/lib/expressir/express/builders/declaration_builder.rb +20 -0
  235. data/lib/expressir/express/builders/derive_clause_builder.rb +14 -0
  236. data/lib/expressir/express/builders/derived_attr_builder.rb +28 -0
  237. data/lib/expressir/express/builders/domain_rule_builder.rb +21 -0
  238. data/lib/expressir/express/builders/entity_decl_builder.rb +116 -0
  239. data/lib/expressir/express/builders/explicit_attr_builder.rb +49 -0
  240. data/lib/expressir/express/builders/expression_builder.rb +416 -0
  241. data/lib/expressir/express/builders/function_decl_builder.rb +86 -0
  242. data/lib/expressir/express/builders/helpers.rb +148 -0
  243. data/lib/expressir/express/builders/interface_builder.rb +151 -0
  244. data/lib/expressir/express/builders/inverse_attr_builder.rb +43 -0
  245. data/lib/expressir/express/builders/inverse_attr_type_builder.rb +30 -0
  246. data/lib/expressir/express/builders/inverse_clause_builder.rb +14 -0
  247. data/lib/expressir/express/builders/literal_builder.rb +93 -0
  248. data/lib/expressir/express/builders/procedure_decl_builder.rb +82 -0
  249. data/lib/expressir/express/builders/qualifier_builder.rb +102 -0
  250. data/lib/expressir/express/builders/reference_builder.rb +18 -0
  251. data/lib/expressir/express/builders/rule_decl_builder.rb +97 -0
  252. data/lib/expressir/express/builders/schema_body_decl_builder.rb +18 -0
  253. data/lib/expressir/express/builders/schema_decl_builder.rb +56 -0
  254. data/lib/expressir/express/builders/schema_version_builder.rb +34 -0
  255. data/lib/expressir/express/builders/simple_id_builder.rb +17 -0
  256. data/lib/expressir/express/builders/statement_builder.rb +243 -0
  257. data/lib/expressir/express/builders/subtype_constraint_builder.rb +166 -0
  258. data/lib/expressir/express/builders/syntax_builder.rb +30 -0
  259. data/lib/expressir/express/builders/type_builder.rb +238 -0
  260. data/lib/expressir/express/builders/type_decl_builder.rb +26 -0
  261. data/lib/expressir/express/builders/unique_clause_builder.rb +20 -0
  262. data/lib/expressir/express/builders/unique_rule_builder.rb +41 -0
  263. data/lib/expressir/express/builders/where_clause_builder.rb +20 -0
  264. data/lib/expressir/express/builders.rb +55 -0
  265. data/lib/expressir/express/cache.rb +76 -0
  266. data/lib/expressir/express/checker.rb +812 -0
  267. data/lib/expressir/express/concatenator.rb +79 -0
  268. data/lib/expressir/express/core.rb +95 -0
  269. data/lib/expressir/express/error.rb +124 -0
  270. data/lib/expressir/express/formatter.rb +149 -0
  271. data/lib/expressir/express/formatters/data_types_formatter.rb +362 -0
  272. data/lib/expressir/express/formatters/declarations_formatter.rb +753 -0
  273. data/lib/expressir/express/formatters/expressions_formatter.rb +180 -0
  274. data/lib/expressir/express/formatters/literals_formatter.rb +55 -0
  275. data/lib/expressir/express/formatters/references_formatter.rb +53 -0
  276. data/lib/expressir/express/formatters/remark_formatter.rb +270 -0
  277. data/lib/expressir/express/formatters/remark_item_formatter.rb +28 -0
  278. data/lib/expressir/express/formatters/statements_formatter.rb +272 -0
  279. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +54 -0
  280. data/lib/expressir/express/formatters.rb +22 -0
  281. data/lib/expressir/express/grammar/parser.rb +712 -0
  282. data/lib/expressir/express/grammar.rb +11 -0
  283. data/lib/expressir/express/hyperlink_formatter.rb +35 -0
  284. data/lib/expressir/express/interface_dot.rb +105 -0
  285. data/lib/expressir/express/lazy_repository.rb +211 -0
  286. data/lib/expressir/express/line_map.rb +48 -0
  287. data/lib/expressir/express/listing.rb +174 -0
  288. data/lib/expressir/express/model_traversal.rb +42 -0
  289. data/lib/expressir/express/model_visitor.rb +25 -0
  290. data/lib/expressir/express/node_position_index.rb +342 -0
  291. data/lib/expressir/express/parallel_files.rb +229 -0
  292. data/lib/expressir/express/parser.rb +523 -0
  293. data/lib/expressir/express/pretty_formatter.rb +586 -0
  294. data/lib/expressir/express/pretty_gate.rb +61 -0
  295. data/lib/expressir/express/refs_overlay.rb +47 -0
  296. data/lib/expressir/express/remark_attacher.rb +1098 -0
  297. data/lib/expressir/express/remark_overlay.rb +86 -0
  298. data/lib/expressir/express/remark_scanner.rb +245 -0
  299. data/lib/expressir/express/resolve_references_model_visitor.rb +29 -0
  300. data/lib/expressir/express/schema_block_scanner.rb +137 -0
  301. data/lib/expressir/express/schema_head_formatter.rb +22 -0
  302. data/lib/expressir/express/schema_plain_source_formatter.rb +11 -0
  303. data/lib/expressir/express/schema_source_formatter.rb +15 -0
  304. data/lib/expressir/express/scope_resolver.rb +223 -0
  305. data/lib/expressir/express/self_schema_reference.rb +126 -0
  306. data/lib/expressir/express/shtolo.rb +679 -0
  307. data/lib/expressir/express/smrl_xml.rb +125 -0
  308. data/lib/expressir/express/source_formatter.rb +15 -0
  309. data/lib/expressir/express/streaming_builder.rb +435 -0
  310. data/lib/expressir/express/xsd.rb +259 -0
  311. data/lib/expressir/express.rb +53 -0
  312. data/lib/expressir/liquid.rb +1 -0
  313. data/lib/expressir/manifest/resolver.rb +210 -0
  314. data/lib/expressir/manifest/validator.rb +192 -0
  315. data/lib/expressir/manifest.rb +6 -0
  316. data/lib/expressir/mapping/refpath.rb +857 -0
  317. data/lib/expressir/mapping.rb +253 -0
  318. data/lib/expressir/model/cache.rb +18 -0
  319. data/lib/expressir/model/concerns.rb +42 -0
  320. data/lib/expressir/model/data_types/aggregate.rb +26 -0
  321. data/lib/expressir/model/data_types/array.rb +25 -0
  322. data/lib/expressir/model/data_types/bag.rb +21 -0
  323. data/lib/expressir/model/data_types/binary.rb +19 -0
  324. data/lib/expressir/model/data_types/boolean.rb +15 -0
  325. data/lib/expressir/model/data_types/enumeration.rb +21 -0
  326. data/lib/expressir/model/data_types/enumeration_item.rb +24 -0
  327. data/lib/expressir/model/data_types/generic.rb +24 -0
  328. data/lib/expressir/model/data_types/generic_entity.rb +24 -0
  329. data/lib/expressir/model/data_types/integer.rb +15 -0
  330. data/lib/expressir/model/data_types/list.rb +23 -0
  331. data/lib/expressir/model/data_types/logical.rb +15 -0
  332. data/lib/expressir/model/data_types/number.rb +15 -0
  333. data/lib/expressir/model/data_types/real.rb +17 -0
  334. data/lib/expressir/model/data_types/select.rb +23 -0
  335. data/lib/expressir/model/data_types/set.rb +21 -0
  336. data/lib/expressir/model/data_types/string.rb +19 -0
  337. data/lib/expressir/model/data_types.rb +25 -0
  338. data/lib/expressir/model/declarations/attribute.rb +38 -0
  339. data/lib/expressir/model/declarations/constant.rb +28 -0
  340. data/lib/expressir/model/declarations/derived_attribute.rb +25 -0
  341. data/lib/expressir/model/declarations/entity.rb +62 -0
  342. data/lib/expressir/model/declarations/function.rb +59 -0
  343. data/lib/expressir/model/declarations/informal_proposition_rule.rb +25 -0
  344. data/lib/expressir/model/declarations/interface.rb +37 -0
  345. data/lib/expressir/model/declarations/interface_item.rb +21 -0
  346. data/lib/expressir/model/declarations/interfaced_item.rb +33 -0
  347. data/lib/expressir/model/declarations/inverse_attribute.rb +25 -0
  348. data/lib/expressir/model/declarations/parameter.rb +28 -0
  349. data/lib/expressir/model/declarations/procedure.rb +57 -0
  350. data/lib/expressir/model/declarations/remark_item.rb +21 -0
  351. data/lib/expressir/model/declarations/rule.rb +66 -0
  352. data/lib/expressir/model/declarations/schema.rb +215 -0
  353. data/lib/expressir/model/declarations/schema_version.rb +19 -0
  354. data/lib/expressir/model/declarations/schema_version_item.rb +19 -0
  355. data/lib/expressir/model/declarations/subtype_constraint.rb +32 -0
  356. data/lib/expressir/model/declarations/type.rb +45 -0
  357. data/lib/expressir/model/declarations/unique_rule.rb +26 -0
  358. data/lib/expressir/model/declarations/variable.rb +28 -0
  359. data/lib/expressir/model/declarations/where_rule.rb +26 -0
  360. data/lib/expressir/model/declarations.rb +31 -0
  361. data/lib/expressir/model/dependency_resolver.rb +268 -0
  362. data/lib/expressir/model/exp_file.rb +42 -0
  363. data/lib/expressir/model/expressions/aggregate_initializer.rb +18 -0
  364. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +20 -0
  365. data/lib/expressir/model/expressions/binary_expression.rb +59 -0
  366. data/lib/expressir/model/expressions/entity_constructor.rb +20 -0
  367. data/lib/expressir/model/expressions/function_call.rb +20 -0
  368. data/lib/expressir/model/expressions/interval.rb +29 -0
  369. data/lib/expressir/model/expressions/query_expression.rb +31 -0
  370. data/lib/expressir/model/expressions/unary_expression.rb +25 -0
  371. data/lib/expressir/model/expressions.rb +18 -0
  372. data/lib/expressir/model/identifier.rb +26 -0
  373. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  374. data/lib/expressir/model/indexes/item_graph.rb +185 -0
  375. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  376. data/lib/expressir/model/indexes/type_index.rb +149 -0
  377. data/lib/expressir/model/indexes.rb +12 -0
  378. data/lib/expressir/model/interface_validator.rb +384 -0
  379. data/lib/expressir/model/literals/binary.rb +17 -0
  380. data/lib/expressir/model/literals/integer.rb +17 -0
  381. data/lib/expressir/model/literals/logical.rb +21 -0
  382. data/lib/expressir/model/literals/real.rb +17 -0
  383. data/lib/expressir/model/literals/string.rb +20 -0
  384. data/lib/expressir/model/literals.rb +13 -0
  385. data/lib/expressir/model/model_element.rb +377 -0
  386. data/lib/expressir/model/references/attribute_reference.rb +19 -0
  387. data/lib/expressir/model/references/group_reference.rb +19 -0
  388. data/lib/expressir/model/references/index_reference.rb +23 -0
  389. data/lib/expressir/model/references/simple_reference.rb +21 -0
  390. data/lib/expressir/model/references.rb +12 -0
  391. data/lib/expressir/model/remark_format.rb +17 -0
  392. data/lib/expressir/model/remark_info.rb +92 -0
  393. data/lib/expressir/model/remark_placement.rb +42 -0
  394. data/lib/expressir/model/repository.rb +483 -0
  395. data/lib/expressir/model/repository_validator.rb +293 -0
  396. data/lib/expressir/model/search_engine.rb +551 -0
  397. data/lib/expressir/model/statements/alias.rb +31 -0
  398. data/lib/expressir/model/statements/assignment.rb +23 -0
  399. data/lib/expressir/model/statements/case.rb +42 -0
  400. data/lib/expressir/model/statements/case_action.rb +20 -0
  401. data/lib/expressir/model/statements/compound.rb +21 -0
  402. data/lib/expressir/model/statements/escape.rb +18 -0
  403. data/lib/expressir/model/statements/if.rb +26 -0
  404. data/lib/expressir/model/statements/null.rb +18 -0
  405. data/lib/expressir/model/statements/procedure_call.rb +22 -0
  406. data/lib/expressir/model/statements/repeat.rb +40 -0
  407. data/lib/expressir/model/statements/return.rb +20 -0
  408. data/lib/expressir/model/statements/skip.rb +18 -0
  409. data/lib/expressir/model/statements.rb +20 -0
  410. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +25 -0
  411. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +17 -0
  412. data/lib/expressir/model/supertype_expressions.rb +12 -0
  413. data/lib/expressir/model.rb +39 -0
  414. data/lib/expressir/package/builder.rb +231 -0
  415. data/lib/expressir/package/metadata.rb +79 -0
  416. data/lib/expressir/package/reader.rb +149 -0
  417. data/lib/expressir/package.rb +8 -0
  418. data/lib/expressir/schema_manifest.rb +159 -0
  419. data/lib/expressir/schema_manifest_entry.rb +15 -0
  420. data/lib/expressir/version.rb +8 -0
  421. data/lib/expressir.rb +94 -0
  422. data/lib/tasks/verify_remarks.rake +16 -0
  423. data/rakelib/native.rake +24 -0
  424. data/rakelib/oracle.rake +52 -0
  425. data/rakelib/verify_remarks.rake +16 -0
  426. metadata +692 -0
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ # Base error class with details support
5
+ class Error < StandardError
6
+ attr_reader :details
7
+
8
+ def initialize(message = nil, details: nil)
9
+ @details = details
10
+ super(message)
11
+ end
12
+ end
13
+
14
+ # File/Resource Errors
15
+ class FileNotFoundError < Error
16
+ attr_reader :file_path, :file_type
17
+
18
+ def initialize(file_path, file_type: nil)
19
+ @file_path = file_path
20
+ @file_type = file_type
21
+ super("#{file_type || 'File'} not found: #{file_path}")
22
+ end
23
+ end
24
+
25
+ class ManifestNotFoundError < FileNotFoundError
26
+ def initialize(file_path)
27
+ super(file_path, file_type: "Manifest file")
28
+ end
29
+ end
30
+
31
+ class PackageNotFoundError < FileNotFoundError
32
+ def initialize(file_path)
33
+ super(file_path, file_type: "Package file")
34
+ end
35
+ end
36
+
37
+ class SchemaNotFoundError < FileNotFoundError
38
+ def initialize(file_path)
39
+ super(file_path, file_type: "Schema file")
40
+ end
41
+ end
42
+
43
+ # Usage/Argument Errors
44
+ class UsageError < Error
45
+ attr_reader :usage_hint
46
+
47
+ def initialize(message, usage_hint: nil)
48
+ @usage_hint = usage_hint
49
+ super(message)
50
+ end
51
+ end
52
+
53
+ class MissingRequiredArgumentError < UsageError; end
54
+
55
+ class InvalidOptionError < UsageError
56
+ attr_reader :option_name, :valid_options
57
+
58
+ def initialize(option_name, value, valid_options: nil)
59
+ @option_name = option_name
60
+ @valid_options = valid_options
61
+ msg = "Invalid value '#{value}' for #{option_name}"
62
+ msg += ". Valid options: #{valid_options.join(', ')}" if valid_options
63
+ super(msg)
64
+ end
65
+ end
66
+
67
+ # Validation Errors
68
+ class ValidationError < Error
69
+ attr_reader :errors
70
+
71
+ def initialize(message, errors: [])
72
+ @errors = errors
73
+ super(message)
74
+ end
75
+ end
76
+
77
+ class ManifestValidationError < ValidationError; end
78
+ class SchemaValidationError < ValidationError; end
79
+
80
+ class ReferentialIntegrityError < ValidationError
81
+ attr_reader :unresolved_references
82
+
83
+ def initialize(unresolved_references,
84
+ message: "Referential integrity check failed")
85
+ @unresolved_references = unresolved_references
86
+ super(message)
87
+ end
88
+ end
89
+
90
+ class NoValidSchemaPathsError < ValidationError
91
+ def initialize(message = "No valid schema paths found")
92
+ super
93
+ end
94
+ end
95
+
96
+ # Command Errors (for rescue blocks)
97
+ class CommandError < Error
98
+ attr_reader :command_name
99
+
100
+ def initialize(message, command_name: nil)
101
+ @command_name = command_name
102
+ super(message)
103
+ end
104
+ end
105
+
106
+ class PackageBuildError < CommandError; end
107
+ class PackageReadError < CommandError; end
108
+ class PackageExtractError < CommandError; end
109
+ class PackageValidationError < CommandError; end
110
+ class PackageListError < CommandError; end
111
+ class PackageSearchError < CommandError; end
112
+ class PackageTreeError < CommandError; end
113
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Express
5
+ # HyperlinkFormatter variant emitting AsciiDoc xref macros instead
6
+ # of the legacy stepmod +{{{<<express:...>>}}}+ markup: a reference
7
+ # to schema.item renders as +<<schema.item,item>>+, the anchor
8
+ # namespace schema document pages emit (expressir #255 / iso-10303
9
+ # #41). With +subs="+macros"+ source blocks the links go live.
10
+ module AdocHyperlinkFormatter
11
+ # @!visibility private
12
+ def self.included(mod)
13
+ unless mod.superclass <= Expressir::Express::Formatter
14
+ raise Error::FormatterMethodMissingError.new("AdocHyperlinkFormatter",
15
+ "format_references_simple_reference")
16
+ end
17
+ end
18
+
19
+ def format_references_simple_reference(node)
20
+ return node.id unless node.base_path
21
+
22
+ parts = node.base_path.split(".")
23
+ return node.id if parts.size < 2
24
+
25
+ anchor = parts[-2, 2].join(".")
26
+ "<<#{anchor},#{node.id}>>"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Express
5
+ # Pre-built Formatter subclass rendering the FULL schema with
6
+ # cross-references as AsciiDoc xref macros — the document-page
7
+ # counterpart of SourceFormatter (Schema#formatted_hyperlinked_adoc).
8
+ class AdocSourceFormatter < Formatter
9
+ include AdocHyperlinkFormatter
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Express
5
+ # Converts native-AST CamelCase keys to the snake_case keys the
6
+ # builders consume.
7
+ #
8
+ # build() descends into child nodes whose subtrees the parent already
9
+ # converted, so unchanged containers are marked with an invisible
10
+ # instance variable and skipped on re-visits — without it, every
11
+ # subtree is re-scanned once per ancestor level (~60 convert calls per
12
+ # model node on real schemas). The marker is invisible to equality,
13
+ # hashing, and inspection.
14
+ class AstKeyConverter
15
+ SNAKED_MARKER = :@_expressir_keys_snaked
16
+ UPPERCASE_PATTERN = /[A-Z]/
17
+
18
+ class << self
19
+ # Thread-local snake_case conversion cache. Thread-local avoids the
20
+ # mutable-constant anti-pattern while remaining thread-safe. The
21
+ # cache is bounded by the number of unique AST node-type names.
22
+ def snake_case(name)
23
+ cache[name] ||= begin
24
+ str = name.to_s
25
+ if /^[a-z_]+$/.match?(str)
26
+ str.to_sym
27
+ else
28
+ str
29
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
30
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
31
+ .downcase
32
+ .to_sym
33
+ end
34
+ end
35
+ end
36
+
37
+ # Returns the original object when no conversion is needed; the
38
+ # common no-conversion case allocates nothing and the conversion
39
+ # case walks the keys once.
40
+ def convert(obj)
41
+ case obj
42
+ when Hash
43
+ return obj if obj.empty?
44
+ return obj if obj.instance_variable_defined?(SNAKED_MARKER)
45
+
46
+ keys = obj.keys
47
+ converted_values = nil
48
+ new_keys = nil
49
+
50
+ keys.each_with_index do |k, i|
51
+ val = obj[k]
52
+ case val
53
+ when Hash, Array
54
+ unless val.empty?
55
+ converted_val = convert(val)
56
+ (converted_values ||= {})[k] = converted_val unless converted_val.equal?(val)
57
+ end
58
+ end
59
+
60
+ if k.match?(UPPERCASE_PATTERN)
61
+ (new_keys ||= keys.dup)[i] = snake_case(k)
62
+ end
63
+ end
64
+
65
+ return mark_snaked(obj) unless new_keys || converted_values
66
+
67
+ result = {}
68
+ keys.each_with_index do |k, i|
69
+ key = new_keys&.[](i) || k
70
+ result[key] = converted_values&.key?(k) ? converted_values[k] : obj[k]
71
+ end
72
+ mark_snaked(result)
73
+ when Array
74
+ return obj if obj.empty?
75
+ return obj if obj.instance_variable_defined?(SNAKED_MARKER)
76
+
77
+ needs_conversion = false
78
+ result = []
79
+
80
+ obj.each do |item|
81
+ case item
82
+ when Hash, Array
83
+ next if item.empty?
84
+
85
+ converted = convert(item)
86
+ result << converted
87
+ needs_conversion = true unless converted.equal?(item)
88
+ else
89
+ result << item
90
+ end
91
+ end
92
+
93
+ needs_conversion ? mark_snaked(result) : mark_snaked(obj)
94
+ else
95
+ obj
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ def cache
102
+ Thread.current[:expressir_snake_case_cache] ||= {}
103
+ end
104
+
105
+ def mark_snaked(obj)
106
+ obj.instance_variable_set(SNAKED_MARKER, true)
107
+ obj
108
+ rescue FrozenError
109
+ obj
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,277 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Express
5
+ # Builder registry for AST node type handlers.
6
+ # Each builder is a callable object that transforms AST data into Model objects.
7
+ # This is the ONLY way to build models from AST - no Transformer fallback.
8
+ module Builder
9
+ class << self
10
+ # Thread-local key under which the current BuilderContext is stored
11
+ # for the duration of a build_with_remarks call. Recursive build
12
+ # calls read source/include_source from here instead of from
13
+ # class-level mutable state.
14
+ CONTEXT_KEY = :expressir_builder_context
15
+
16
+ # Returns the BuilderContext for the current thread, or nil if no
17
+ # build is in progress.
18
+ def current_context
19
+ Thread.current[CONTEXT_KEY]
20
+ end
21
+
22
+ # Convenience accessors — read from the current context.
23
+ def source
24
+ current_context&.source
25
+ end
26
+
27
+ def include_source
28
+ current_context&.include_source
29
+ end
30
+
31
+ # Register a builder for a node type.
32
+ # @param node_type [Symbol] The AST node type
33
+ # @param builder [#call] Optional callable that takes (ast_data)
34
+ # @yield Block that takes (ast_data) if builder not provided
35
+ def register(node_type, builder = nil, &block)
36
+ @register ||= {}
37
+ @register[node_type] = builder || block
38
+ end
39
+
40
+ # Build a Model object from AST data.
41
+ # @param ast [Hash] The AST with node type as key
42
+ # @return [Model::ModelElement] The built model object
43
+ def build(ast)
44
+ return nil unless ast
45
+
46
+ # Optimized: Hash is 90%+ of cases, check it first
47
+ case ast
48
+ when Hash
49
+ node_type = ast.keys.first
50
+ node_data = ast[node_type]
51
+
52
+ handler_key = AstKeyConverter.snake_case(node_type)
53
+ snake_data = AstKeyConverter.convert(node_data)
54
+
55
+ builder = @register[handler_key]
56
+ if builder
57
+ result = builder.call(snake_data)
58
+
59
+ # Fast path: single-key hash or non-nil result
60
+ if !result.nil? || ast.keys.length <= 1
61
+ attach_source_info(result, node_data)
62
+ return result
63
+ end
64
+
65
+ # Slow path: first-key builder returned nil in a multi-key
66
+ # hash. Try remaining keys for actual content. This handles
67
+ # grammar patterns like `element >> (op_comma >> element).repeat`
68
+ # which produce {:op_comma => ..., :element => {...}} where
69
+ # the first key is an operator separator.
70
+ # Previously gated by a hand-maintained OPERATOR_TOKENS set;
71
+ # now tries all remaining keys unconditionally (TODO.bugs/21).
72
+ ast.each_key do |key|
73
+ next if key == node_type
74
+
75
+ h_key = AstKeyConverter.snake_case(key)
76
+ h_builder = @register[h_key]
77
+ next unless h_builder
78
+
79
+ n_data = ast[key]
80
+ s_data = AstKeyConverter.convert(n_data)
81
+ result = h_builder.call(s_data)
82
+
83
+ unless result.nil?
84
+ attach_source_info(result, n_data)
85
+ return result
86
+ end
87
+ end
88
+ else
89
+ raise Error::UnknownNodeTypeError, node_type
90
+ end
91
+ nil
92
+ when Array
93
+ ast.map do |item|
94
+ build(item)
95
+ end
96
+ when Parsanol::Slice
97
+ ast.to_s
98
+ else
99
+ ast
100
+ end
101
+ end
102
+
103
+ # Build with remark attachment.
104
+ #
105
+ # Sets up a BuilderContext as a thread-local for the duration of the
106
+ # build so recursive build calls can read source/include_source via
107
+ # `Builder.source` / `Builder.include_source`. The previous context
108
+ # (if any) is restored on exit so nested builds are reentrant.
109
+ def build_with_remarks(ast, source: nil, include_source: nil)
110
+ # Trigger BuilderRegistry autoload so all AST node type handlers
111
+ # are registered before build() runs. The reference to
112
+ # BuilderRegistry resolves the autoload defined in express.rb.
113
+ BuilderRegistry
114
+
115
+ previous = Thread.current[CONTEXT_KEY]
116
+ Thread.current[CONTEXT_KEY] = BuilderContext.new(
117
+ source: source,
118
+ include_source: include_source,
119
+ )
120
+
121
+ result = build(ast)
122
+
123
+ # Only attach remarks if include_source is explicitly true
124
+ # (nil means use default behavior - attach remarks)
125
+ if source && result && include_source != false
126
+ attacher = RemarkAttacher.new(source)
127
+ attacher.attach(result)
128
+ end
129
+
130
+ result
131
+ ensure
132
+ Thread.current[CONTEXT_KEY] = previous
133
+ end
134
+
135
+ # Check if a builder is registered for a node type.
136
+ def registered?(node_type)
137
+ @register&.key?(node_type)
138
+ end
139
+
140
+ # Get all registered node types.
141
+ def registered_types
142
+ @register&.keys || []
143
+ end
144
+
145
+ # Build optional (returns nil if ast is nil)
146
+ def build_optional(ast)
147
+ return nil unless ast
148
+
149
+ build(ast)
150
+ end
151
+
152
+ # Normalize a value to an Array for iteration.
153
+ # Handles: nil → [], Parsanol::Slice → [], Array → Array, other → [other]
154
+ def ensure_array(value)
155
+ return [] if value.nil?
156
+ return [] if value.is_a?(Parsanol::Slice)
157
+
158
+ value.is_a?(Array) ? value : [value]
159
+ end
160
+
161
+ # Build children (array of AST nodes)
162
+ # Optimized to avoid intermediate array allocations
163
+ def build_children(ast_array)
164
+ return [] if ast_array.nil?
165
+
166
+ # Handle Parsanol::Slice (empty Slices from optional rules)
167
+ # Convert to empty Array
168
+ if ast_array.is_a?(Parsanol::Slice)
169
+ return []
170
+ end
171
+
172
+ # Handle single element (common case)
173
+ unless ast_array.is_a?(Array)
174
+ return [build(ast_array)].compact
175
+ end
176
+
177
+ # Build result in single pass, avoiding flatten/compact/map chain
178
+ result = []
179
+ ast_array.each do |item|
180
+ next if item.nil?
181
+
182
+ # Empty Slices from optional rules should be treated as empty arrays
183
+ if item.is_a?(Parsanol::Slice)
184
+ next
185
+ end
186
+
187
+ case item
188
+ when Array
189
+ item.each do |sub|
190
+ result << build(sub) unless sub.nil?
191
+ end
192
+ else
193
+ built = build(item)
194
+ result << built if built
195
+ end
196
+ end
197
+ result
198
+ end
199
+
200
+ # Fast build methods - call registered builder directly without hash wrapping
201
+ # These are optimized for hot paths in expression building
202
+ # NOTE: These assume data is already snake_case (no key conversion needed)
203
+
204
+ # Call a registered builder directly with data (avoids hash wrapper allocation)
205
+ # @param node_type [Symbol] The node type key
206
+ # @param data The data to pass to the builder (already snake_case)
207
+ def build_node(node_type, data)
208
+ builder = @register&.[](node_type)
209
+ raise Error::UnknownNodeTypeError, node_type unless builder
210
+
211
+ builder.call(data)
212
+ end
213
+
214
+ # Keys containing uppercase need snake-casing; testing the key
215
+ # directly avoids allocating `to_s` strings per key per pass.
216
+ # Key conversion lives in AstKeyConverter (MECE: converting AST
217
+ # keys is not building models).
218
+ def extract_source_info(data)
219
+ return nil unless data
220
+
221
+ src = source
222
+ return nil unless src
223
+
224
+ slice = find_slice(data)
225
+ return nil unless slice
226
+
227
+ {
228
+ text: src[slice.offset...(slice.offset + slice.length)]&.strip,
229
+ offset: slice.offset,
230
+ }
231
+ end
232
+
233
+ def attach_source_info(result, data)
234
+ return unless source && result.is_a?(Expressir::Model::ModelElement)
235
+
236
+ source_info = extract_source_info(data)
237
+ return unless source_info
238
+
239
+ result.source_offset = source_info[:offset]
240
+ result.source = source_info[:text] if include_source
241
+ end
242
+
243
+ def find_slice(data, depth = 0)
244
+ return nil if depth > 10
245
+
246
+ case data
247
+ when Parsanol::Slice
248
+ data
249
+ when Hash
250
+ # Skip 'spaces' key which contains whitespace/comments before content
251
+ # Look for 'str' key first as it usually contains the actual content
252
+ if data.key?(:str) && data[:str].is_a?(Parsanol::Slice)
253
+ return data[:str]
254
+ end
255
+
256
+ # Then look in other keys, skipping 'spaces'
257
+ data.each do |key, value|
258
+ next if key == :spaces
259
+
260
+ return value if value.is_a?(Parsanol::Slice)
261
+
262
+ result = find_slice(value, depth + 1)
263
+ return result if result
264
+ end
265
+ nil
266
+ when Array
267
+ data.each do |item|
268
+ result = find_slice(item, depth + 1)
269
+ return result if result
270
+ end
271
+ nil
272
+ end
273
+ end
274
+ end
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Express
5
+ # Value object carrying the per-build context that Builder needs to
6
+ # attach source info to model elements.
7
+ #
8
+ # Stored as a thread-local by Builder.build_with_remarks so that recursive
9
+ # build calls can read `Builder.source` / `Builder.include_source` without
10
+ # the module mutating class-level state. Thread-local means concurrent
11
+ # builds in different threads don't corrupt each other; the save/restore
12
+ # pattern in build_with_remarks means nested builds are reentrant.
13
+ class BuilderContext
14
+ attr_reader :source, :include_source
15
+
16
+ def initialize(source:, include_source:)
17
+ @source = source
18
+ @include_source = include_source
19
+ end
20
+ end
21
+ end
22
+ end