expressir 1.2.11-aarch64-linux → 2.4.29-aarch64-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 (467) hide show
  1. checksums.yaml +4 -4
  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 +10 -296
  9. data/.github/workflows/release.yml +26 -114
  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 +33 -1
  15. data/.rubocop.yml +11 -11
  16. data/.rubocop_todo.yml +297 -0
  17. data/CHANGELOG.md +159 -0
  18. data/Gemfile +15 -1
  19. data/README.adoc +2675 -47
  20. data/Rakefile +34 -10
  21. data/TODO.bugs/01-stale-transformer-autoload.md +39 -0
  22. data/TODO.bugs/02-parser-class-instance-vars.md +36 -0
  23. data/TODO.bugs/03-builder-mutable-state.md +43 -0
  24. data/TODO.bugs/04-formatter-public-send-dispatch.md +53 -0
  25. data/TODO.bugs/05-anonymous-formatter-subclass.md +45 -0
  26. data/TODO.bugs/06-collection-registry-single-source.md +53 -0
  27. data/TODO.bugs/07-require-relative-cleanup.md +42 -0
  28. data/TODO.bugs/08-require-expressir-in-commands.md +34 -0
  29. data/TODO.bugs/09-parser-split.md +53 -0
  30. data/TODO.bugs/10-to-s-override.md +42 -0
  31. data/TODO.bugs/11-parser-class-variables.md +39 -0
  32. data/TODO.bugs/12-marker-modules-vs-registry.md +64 -0
  33. data/TODO.bugs/13-string-literal-scanner-limitation.md +52 -0
  34. data/TODO.bugs/14-model-formatting-leak.md +30 -0
  35. data/TODO.bugs/15-expression-children-macro.md +27 -0
  36. data/TODO.bugs/16-pretty-formatter-duplication.md +28 -0
  37. data/TODO.bugs/17-snake-case-cache-mutable-constant.md +28 -0
  38. data/TODO.bugs/18-const-get-private-constants.md +30 -0
  39. data/TODO.bugs/19-format-methods-public.md +22 -0
  40. data/TODO.bugs/20-coverage-nested-entities-dedup.md +20 -0
  41. data/TODO.bugs/21-operator-tokens-secondary-dispatch.md +21 -0
  42. data/TODO.bugs/22-builder-fast-path-wrappers.md +32 -0
  43. data/TODO.bugs/23-coverage-inverse-maps.md +21 -0
  44. data/TODO.bugs/24-streaming-builder-complexity.md +19 -0
  45. data/TODO.bugs/25-debug-puts-in-production.md +21 -0
  46. data/TODO.bugs/26-generic-entity-children-misplaced.md +21 -0
  47. data/TODO.bugs/27-package-build-god-method.md +19 -0
  48. data/TODO.bugs/28-package-god-class.md +30 -0
  49. data/TODO.bugs/29-validate-ascii-god-class.md +24 -0
  50. data/TODO.bugs/30-unicode-map-extraction.md +19 -0
  51. data/TODO.bugs/README.md +43 -0
  52. data/TODO.max-perf/01-restore-ci-green.md +36 -0
  53. data/TODO.max-perf/02-streaming-parse-path.md +31 -0
  54. data/TODO.max-perf/03-cli-parallel-opt-in.md +27 -0
  55. data/TODO.max-perf/04-benchmark-harness.md +28 -0
  56. data/TODO.max-perf/05-parallel-fidelity-specs.md +22 -0
  57. data/TODO.max-perf/06-builder-cpu-audit.md +41 -0
  58. data/TODO.max-perf/07-upstream-parsanol-roadmap.md +27 -0
  59. data/TODO.max-perf/08-builder-build-perf.md +45 -0
  60. data/TODO.max-perf/09-grammar-cold-start.md +25 -0
  61. data/TODO.max-perf/10-parser-facade-hygiene.md +23 -0
  62. data/TODO.max-perf/11-ci-green-closeout.md +25 -0
  63. data/TODO.max-perf/12-require-boot-profile.md +25 -0
  64. data/TODO.max-perf/13-key-conversion-specs.md +26 -0
  65. data/TODO.max-perf/14-builder-call-handler-audit.md +28 -0
  66. data/TODO.parity-ee/00-overview.md +76 -0
  67. data/TODO.parity-ee/01-annex-g-rule-extraction.md +41 -0
  68. data/TODO.parity-ee/02-eeng-algorithm-inventory.md +8 -0
  69. data/TODO.parity-ee/03-eeng-oracle-harness.md +33 -0
  70. data/TODO.parity-ee/04-shtolo-concatenate.md +44 -0
  71. data/TODO.parity-ee/05-shtolo-longform-flatten.md +53 -0
  72. data/TODO.parity-ee/06-interface-scheduling-parity.md +47 -0
  73. data/TODO.parity-ee/07-semantic-checks-port.md +35 -0
  74. data/TODO.parity-ee/08-pretty-roundtrip-gate.md +27 -0
  75. data/TODO.parity-ee/09-smrl-index-and-listing.md +22 -0
  76. data/TODO.parity-ee/10-interface-dot-graph.md +21 -0
  77. data/TODO.parity-ee/11-import-eeng-tests.md +79 -0
  78. data/TODO.parity-ee/12-full-check-catalog.md +67 -0
  79. data/TODO.parity-ee/13-population-p21.md +54 -0
  80. data/TODO.parity-ee/14-shtolo-completion.md +44 -0
  81. data/TODO.parity-ee/15-part28-xml.md +51 -0
  82. data/TODO.parity-ee/16-compare-patch.md +48 -0
  83. data/TODO.parity-ee/17-official-tests.md +42 -0
  84. data/TODO.parity-ee/18-mim-mapping.md +47 -0
  85. data/TODO.parity-ee/19-architecture.md +97 -0
  86. data/TODO.parity-ee/parity-matrix.md +108 -0
  87. data/TODO.refpath-v2/00-overview.md +64 -0
  88. data/TODO.suma-improvements/00-overview.md +23 -0
  89. data/TODO.suma-improvements/01-prebuilt-platform-gems.md +33 -0
  90. data/TODO.suma-improvements/02-suma-e2e.md +39 -0
  91. data/TODO.suma-improvements/03-item-graph.md +22 -0
  92. data/TODO.suma-improvements/04-compiled-set-default.md +16 -0
  93. data/TODO.suma-improvements/05-validation-in-docs.md +17 -0
  94. data/TODO.suma-improvements/06-memory-remeasure.md +36 -0
  95. data/TODO.suma-improvements/07-part28-xml.md +15 -0
  96. data/TODO.suma-improvements/08-windows-gnu-toolchain.md +15 -0
  97. data/TODO.suma-improvements/09-checker-tranche3.md +13 -0
  98. data/TODO.suma-improvements/10-expressdoc.md +8 -0
  99. data/benchmark/srl_benchmark.rb +458 -0
  100. data/benchmark/srl_native_benchmark.rb +146 -0
  101. data/benchmark/srl_ruby_benchmark.rb +132 -0
  102. data/bin/rspec +2 -1
  103. data/docs/Gemfile +12 -0
  104. data/docs/_config.yml +141 -0
  105. data/docs/_guides/changes/changes-format.adoc +778 -0
  106. data/docs/_guides/changes/importing-eengine.adoc +898 -0
  107. data/docs/_guides/changes/index.adoc +396 -0
  108. data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
  109. data/docs/_guides/changes/validating-changes.adoc +681 -0
  110. data/docs/_guides/cli/benchmark-performance.adoc +834 -0
  111. data/docs/_guides/cli/coverage-analysis.adoc +921 -0
  112. data/docs/_guides/cli/format-schemas.adoc +547 -0
  113. data/docs/_guides/cli/index.adoc +8 -0
  114. data/docs/_guides/cli/managing-changes.adoc +927 -0
  115. data/docs/_guides/cli/validate-ascii.adoc +645 -0
  116. data/docs/_guides/cli/validate-schemas.adoc +534 -0
  117. data/docs/_guides/formatter/formatter-architecture.adoc +401 -0
  118. data/docs/_guides/index.adoc +165 -0
  119. data/docs/_guides/ler/creating-packages.adoc +664 -0
  120. data/docs/_guides/ler/index.adoc +305 -0
  121. data/docs/_guides/ler/loading-packages.adoc +707 -0
  122. data/docs/_guides/ler/package-formats.adoc +748 -0
  123. data/docs/_guides/ler/querying-packages.adoc +826 -0
  124. data/docs/_guides/ler/step-packages.adoc +385 -0
  125. data/docs/_guides/ler/validating-packages.adoc +750 -0
  126. data/docs/_guides/liquid/basic-templates.adoc +813 -0
  127. data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
  128. data/docs/_guides/liquid/drops-reference.adoc +829 -0
  129. data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
  130. data/docs/_guides/liquid/index.adoc +468 -0
  131. data/docs/_guides/manifests/creating-manifests.adoc +483 -0
  132. data/docs/_guides/manifests/index.adoc +307 -0
  133. data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
  134. data/docs/_guides/manifests/validating-manifests.adoc +713 -0
  135. data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
  136. data/docs/_guides/ruby-api/index.adoc +257 -0
  137. data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
  138. data/docs/_guides/ruby-api/search-engine.adoc +609 -0
  139. data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
  140. data/docs/_pages/data-model.adoc +665 -0
  141. data/docs/_pages/express-language.adoc +506 -0
  142. data/docs/_pages/getting-started.adoc +414 -0
  143. data/docs/_pages/index.adoc +116 -0
  144. data/docs/_pages/introduction.adoc +256 -0
  145. data/docs/_pages/ler-packages.adoc +837 -0
  146. data/docs/_pages/parsers.adoc +709 -0
  147. data/docs/_pages/schema-manifests.adoc +431 -0
  148. data/docs/_references/index.adoc +228 -0
  149. data/docs/_tutorials/creating-ler-package.adoc +735 -0
  150. data/docs/_tutorials/documentation-coverage.adoc +795 -0
  151. data/docs/_tutorials/formatting-schemas.adoc +89 -0
  152. data/docs/_tutorials/index.adoc +231 -0
  153. data/docs/_tutorials/liquid-templates.adoc +806 -0
  154. data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
  155. data/docs/_tutorials/querying-schemas.adoc +751 -0
  156. data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
  157. data/docs/index.adoc +242 -0
  158. data/docs/lychee.toml +90 -0
  159. data/examples/demo_ler_usage.sh +86 -0
  160. data/examples/ler/README.md +111 -0
  161. data/examples/ler/simple_example.ler +0 -0
  162. data/examples/ler/simple_schema.exp +33 -0
  163. data/examples/ler_build.rb +75 -0
  164. data/examples/ler_cli.rb +79 -0
  165. data/examples/ler_demo_complete.rb +276 -0
  166. data/examples/ler_query.rb +91 -0
  167. data/examples/ler_query_examples.rb +305 -0
  168. data/examples/ler_stats.rb +81 -0
  169. data/examples/phase3_demo.rb +159 -0
  170. data/examples/query_demo_simple.rb +131 -0
  171. data/exe/expressir +6 -17
  172. data/exe/expressir-format +14 -0
  173. data/exe/{format-test → expressir-format-test} +8 -7
  174. data/expressir.gemspec +50 -37
  175. data/lib/expressir/3.2/expressir_core.so +0 -0
  176. data/lib/expressir/3.3/expressir_core.so +0 -0
  177. data/lib/expressir/3.4/expressir_core.so +0 -0
  178. data/lib/expressir/4.0/expressir_core.so +0 -0
  179. data/lib/expressir/benchmark.rb +310 -0
  180. data/lib/expressir/changes/item_change.rb +20 -0
  181. data/lib/expressir/changes/mapping_change.rb +16 -0
  182. data/lib/expressir/changes/schema_change.rb +85 -0
  183. data/lib/expressir/changes/version_change.rb +26 -0
  184. data/lib/expressir/changes.rb +9 -0
  185. data/lib/expressir/cli.rb +138 -11
  186. data/lib/expressir/commands/base.rb +25 -0
  187. data/lib/expressir/commands/benchmark.rb +59 -0
  188. data/lib/expressir/commands/benchmark_cache.rb +80 -0
  189. data/lib/expressir/commands/changes.rb +34 -0
  190. data/lib/expressir/commands/changes_import_eengine.rb +146 -0
  191. data/lib/expressir/commands/changes_validate.rb +63 -0
  192. data/lib/expressir/commands/check.rb +56 -0
  193. data/lib/expressir/commands/clean.rb +20 -0
  194. data/lib/expressir/commands/coverage.rb +458 -0
  195. data/lib/expressir/commands/expand.rb +26 -0
  196. data/lib/expressir/commands/file_violations.rb +70 -0
  197. data/lib/expressir/commands/fix.rb +33 -0
  198. data/lib/expressir/commands/flatten.rb +29 -0
  199. data/lib/expressir/commands/format.rb +43 -0
  200. data/lib/expressir/commands/manifest.rb +420 -0
  201. data/lib/expressir/commands/mapping_validate.rb +68 -0
  202. data/lib/expressir/commands/non_ascii_character.rb +49 -0
  203. data/lib/expressir/commands/non_ascii_violation_collection.rb +301 -0
  204. data/lib/expressir/commands/package.rb +1222 -0
  205. data/lib/expressir/commands/parity_inputs.rb +160 -0
  206. data/lib/expressir/commands/validate.rb +106 -0
  207. data/lib/expressir/commands/validate_ascii.rb +94 -0
  208. data/lib/expressir/commands/validate_load.rb +91 -0
  209. data/lib/expressir/commands/version.rb +9 -0
  210. data/lib/expressir/commands/xsd.rb +23 -0
  211. data/lib/expressir/commands.rb +30 -0
  212. data/lib/expressir/config.rb +40 -3
  213. data/lib/expressir/coverage.rb +510 -0
  214. data/lib/expressir/eengine/arm_compare_report.rb +23 -0
  215. data/lib/expressir/eengine/changes_section.rb +16 -0
  216. data/lib/expressir/eengine/compare_report.rb +69 -0
  217. data/lib/expressir/eengine/mim_compare_report.rb +23 -0
  218. data/lib/expressir/eengine/modified_object.rb +21 -0
  219. data/lib/expressir/eengine.rb +9 -0
  220. data/lib/expressir/errors.rb +113 -0
  221. data/lib/expressir/express/adoc_hyperlink_formatter.rb +30 -0
  222. data/lib/expressir/express/adoc_source_formatter.rb +12 -0
  223. data/lib/expressir/express/ast_key_converter.rb +114 -0
  224. data/lib/expressir/express/builder.rb +277 -0
  225. data/lib/expressir/express/builder_context.rb +22 -0
  226. data/lib/expressir/express/builder_registry.rb +397 -0
  227. data/lib/expressir/express/builders/attribute_decl_builder.rb +32 -0
  228. data/lib/expressir/express/builders/built_in_builder.rb +75 -0
  229. data/lib/expressir/express/builders/constant_builder.rb +108 -0
  230. data/lib/expressir/express/builders/declaration_builder.rb +20 -0
  231. data/lib/expressir/express/builders/derive_clause_builder.rb +14 -0
  232. data/lib/expressir/express/builders/derived_attr_builder.rb +28 -0
  233. data/lib/expressir/express/builders/domain_rule_builder.rb +21 -0
  234. data/lib/expressir/express/builders/entity_decl_builder.rb +116 -0
  235. data/lib/expressir/express/builders/explicit_attr_builder.rb +49 -0
  236. data/lib/expressir/express/builders/expression_builder.rb +416 -0
  237. data/lib/expressir/express/builders/function_decl_builder.rb +86 -0
  238. data/lib/expressir/express/builders/helpers.rb +148 -0
  239. data/lib/expressir/express/builders/interface_builder.rb +151 -0
  240. data/lib/expressir/express/builders/inverse_attr_builder.rb +43 -0
  241. data/lib/expressir/express/builders/inverse_attr_type_builder.rb +30 -0
  242. data/lib/expressir/express/builders/inverse_clause_builder.rb +14 -0
  243. data/lib/expressir/express/builders/literal_builder.rb +93 -0
  244. data/lib/expressir/express/builders/procedure_decl_builder.rb +82 -0
  245. data/lib/expressir/express/builders/qualifier_builder.rb +102 -0
  246. data/lib/expressir/express/builders/reference_builder.rb +18 -0
  247. data/lib/expressir/express/builders/rule_decl_builder.rb +97 -0
  248. data/lib/expressir/express/builders/schema_body_decl_builder.rb +18 -0
  249. data/lib/expressir/express/builders/schema_decl_builder.rb +56 -0
  250. data/lib/expressir/express/builders/schema_version_builder.rb +34 -0
  251. data/lib/expressir/express/builders/simple_id_builder.rb +17 -0
  252. data/lib/expressir/express/builders/statement_builder.rb +243 -0
  253. data/lib/expressir/express/builders/subtype_constraint_builder.rb +166 -0
  254. data/lib/expressir/express/builders/syntax_builder.rb +30 -0
  255. data/lib/expressir/express/builders/type_builder.rb +238 -0
  256. data/lib/expressir/express/builders/type_decl_builder.rb +26 -0
  257. data/lib/expressir/express/builders/unique_clause_builder.rb +20 -0
  258. data/lib/expressir/express/builders/unique_rule_builder.rb +41 -0
  259. data/lib/expressir/express/builders/where_clause_builder.rb +20 -0
  260. data/lib/expressir/express/builders.rb +55 -0
  261. data/lib/expressir/express/cache.rb +43 -18
  262. data/lib/expressir/express/checker.rb +812 -0
  263. data/lib/expressir/express/concatenator.rb +79 -0
  264. data/lib/expressir/express/core.rb +95 -0
  265. data/lib/expressir/express/error.rb +124 -0
  266. data/lib/expressir/express/formatter.rb +89 -1548
  267. data/lib/expressir/express/formatters/data_types_formatter.rb +362 -0
  268. data/lib/expressir/express/formatters/declarations_formatter.rb +753 -0
  269. data/lib/expressir/express/formatters/expressions_formatter.rb +180 -0
  270. data/lib/expressir/express/formatters/literals_formatter.rb +55 -0
  271. data/lib/expressir/express/formatters/references_formatter.rb +53 -0
  272. data/lib/expressir/express/formatters/remark_formatter.rb +270 -0
  273. data/lib/expressir/express/formatters/remark_item_formatter.rb +28 -0
  274. data/lib/expressir/express/formatters/statements_formatter.rb +272 -0
  275. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +54 -0
  276. data/lib/expressir/express/formatters.rb +22 -0
  277. data/lib/expressir/express/grammar/parser.rb +712 -0
  278. data/lib/expressir/express/grammar.rb +11 -0
  279. data/lib/expressir/express/hyperlink_formatter.rb +4 -5
  280. data/lib/expressir/express/interface_dot.rb +105 -0
  281. data/lib/expressir/express/lazy_repository.rb +211 -0
  282. data/lib/expressir/express/line_map.rb +48 -0
  283. data/lib/expressir/express/listing.rb +174 -0
  284. data/lib/expressir/express/model_traversal.rb +42 -0
  285. data/lib/expressir/express/model_visitor.rb +11 -10
  286. data/lib/expressir/express/node_position_index.rb +342 -0
  287. data/lib/expressir/express/parallel_files.rb +229 -0
  288. data/lib/expressir/express/parser.rb +501 -62
  289. data/lib/expressir/express/pretty_formatter.rb +586 -0
  290. data/lib/expressir/express/pretty_gate.rb +61 -0
  291. data/lib/expressir/express/refs_overlay.rb +47 -0
  292. data/lib/expressir/express/remark_attacher.rb +1098 -0
  293. data/lib/expressir/express/remark_overlay.rb +86 -0
  294. data/lib/expressir/express/remark_scanner.rb +245 -0
  295. data/lib/expressir/express/resolve_references_model_visitor.rb +7 -9
  296. data/lib/expressir/express/schema_block_scanner.rb +137 -0
  297. data/lib/expressir/express/schema_head_formatter.rb +4 -5
  298. data/lib/expressir/express/schema_plain_source_formatter.rb +11 -0
  299. data/lib/expressir/express/schema_source_formatter.rb +15 -0
  300. data/lib/expressir/express/scope_resolver.rb +223 -0
  301. data/lib/expressir/express/self_schema_reference.rb +126 -0
  302. data/lib/expressir/express/shtolo.rb +679 -0
  303. data/lib/expressir/express/smrl_xml.rb +125 -0
  304. data/lib/expressir/express/source_formatter.rb +15 -0
  305. data/lib/expressir/express/streaming_builder.rb +435 -0
  306. data/lib/expressir/express/xsd.rb +259 -0
  307. data/lib/expressir/express.rb +53 -0
  308. data/lib/expressir/liquid.rb +1 -0
  309. data/lib/expressir/manifest/resolver.rb +210 -0
  310. data/lib/expressir/manifest/validator.rb +192 -0
  311. data/lib/expressir/manifest.rb +6 -0
  312. data/lib/expressir/mapping/refpath.rb +857 -0
  313. data/lib/expressir/mapping.rb +253 -0
  314. data/lib/expressir/model/cache.rb +10 -9
  315. data/lib/expressir/model/concerns.rb +42 -0
  316. data/lib/expressir/model/data_types/aggregate.rb +8 -13
  317. data/lib/expressir/model/data_types/array.rb +15 -21
  318. data/lib/expressir/model/data_types/bag.rb +11 -15
  319. data/lib/expressir/model/data_types/binary.rb +9 -12
  320. data/lib/expressir/model/data_types/boolean.rb +7 -2
  321. data/lib/expressir/model/data_types/enumeration.rb +11 -15
  322. data/lib/expressir/model/data_types/enumeration_item.rb +5 -7
  323. data/lib/expressir/model/data_types/generic.rb +6 -8
  324. data/lib/expressir/model/data_types/generic_entity.rb +11 -13
  325. data/lib/expressir/model/data_types/integer.rb +7 -2
  326. data/lib/expressir/model/data_types/list.rb +13 -18
  327. data/lib/expressir/model/data_types/logical.rb +7 -2
  328. data/lib/expressir/model/data_types/number.rb +7 -2
  329. data/lib/expressir/model/data_types/real.rb +7 -9
  330. data/lib/expressir/model/data_types/select.rb +13 -18
  331. data/lib/expressir/model/data_types/set.rb +11 -15
  332. data/lib/expressir/model/data_types/string.rb +9 -12
  333. data/lib/expressir/model/data_types.rb +25 -0
  334. data/lib/expressir/model/declarations/attribute.rb +19 -28
  335. data/lib/expressir/model/declarations/constant.rb +10 -16
  336. data/lib/expressir/model/declarations/derived_attribute.rb +25 -0
  337. data/lib/expressir/model/declarations/entity.rb +39 -30
  338. data/lib/expressir/model/declarations/function.rb +32 -40
  339. data/lib/expressir/model/declarations/informal_proposition_rule.rb +25 -0
  340. data/lib/expressir/model/declarations/interface.rb +25 -16
  341. data/lib/expressir/model/declarations/interface_item.rb +9 -11
  342. data/lib/expressir/model/declarations/interfaced_item.rb +15 -19
  343. data/lib/expressir/model/declarations/inverse_attribute.rb +25 -0
  344. data/lib/expressir/model/declarations/parameter.rb +10 -16
  345. data/lib/expressir/model/declarations/procedure.rb +30 -37
  346. data/lib/expressir/model/declarations/remark_item.rb +11 -11
  347. data/lib/expressir/model/declarations/rule.rb +38 -43
  348. data/lib/expressir/model/declarations/schema.rb +162 -64
  349. data/lib/expressir/model/declarations/schema_version.rb +8 -11
  350. data/lib/expressir/model/declarations/schema_version_item.rb +8 -11
  351. data/lib/expressir/model/declarations/subtype_constraint.rb +14 -22
  352. data/lib/expressir/model/declarations/type.rb +18 -18
  353. data/lib/expressir/model/declarations/unique_rule.rb +8 -13
  354. data/lib/expressir/model/declarations/variable.rb +10 -16
  355. data/lib/expressir/model/declarations/where_rule.rb +8 -13
  356. data/lib/expressir/model/declarations.rb +31 -0
  357. data/lib/expressir/model/dependency_resolver.rb +268 -0
  358. data/lib/expressir/model/exp_file.rb +42 -0
  359. data/lib/expressir/model/expressions/aggregate_initializer.rb +8 -9
  360. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +10 -12
  361. data/lib/expressir/model/expressions/binary_expression.rb +42 -36
  362. data/lib/expressir/model/expressions/entity_constructor.rb +10 -12
  363. data/lib/expressir/model/expressions/function_call.rb +10 -12
  364. data/lib/expressir/model/expressions/interval.rb +18 -23
  365. data/lib/expressir/model/expressions/query_expression.rb +11 -15
  366. data/lib/expressir/model/expressions/unary_expression.rb +13 -15
  367. data/lib/expressir/model/expressions.rb +18 -0
  368. data/lib/expressir/model/identifier.rb +18 -26
  369. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  370. data/lib/expressir/model/indexes/item_graph.rb +185 -0
  371. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  372. data/lib/expressir/model/indexes/type_index.rb +149 -0
  373. data/lib/expressir/model/indexes.rb +12 -0
  374. data/lib/expressir/model/interface_validator.rb +384 -0
  375. data/lib/expressir/model/literals/binary.rb +7 -9
  376. data/lib/expressir/model/literals/integer.rb +7 -9
  377. data/lib/expressir/model/literals/logical.rb +10 -12
  378. data/lib/expressir/model/literals/real.rb +7 -9
  379. data/lib/expressir/model/literals/string.rb +10 -12
  380. data/lib/expressir/model/literals.rb +13 -0
  381. data/lib/expressir/model/model_element.rb +286 -117
  382. data/lib/expressir/model/references/attribute_reference.rb +9 -12
  383. data/lib/expressir/model/references/group_reference.rb +9 -12
  384. data/lib/expressir/model/references/index_reference.rb +11 -15
  385. data/lib/expressir/model/references/simple_reference.rb +11 -14
  386. data/lib/expressir/model/references.rb +12 -0
  387. data/lib/expressir/model/remark_format.rb +17 -0
  388. data/lib/expressir/model/remark_info.rb +92 -0
  389. data/lib/expressir/model/remark_placement.rb +42 -0
  390. data/lib/expressir/model/repository.rb +472 -12
  391. data/lib/expressir/model/repository_validator.rb +293 -0
  392. data/lib/expressir/model/search_engine.rb +551 -0
  393. data/lib/expressir/model/statements/alias.rb +12 -16
  394. data/lib/expressir/model/statements/assignment.rb +12 -11
  395. data/lib/expressir/model/statements/case.rb +31 -14
  396. data/lib/expressir/model/statements/case_action.rb +9 -11
  397. data/lib/expressir/model/statements/compound.rb +10 -8
  398. data/lib/expressir/model/statements/escape.rb +10 -2
  399. data/lib/expressir/model/statements/if.rb +15 -14
  400. data/lib/expressir/model/statements/null.rb +10 -2
  401. data/lib/expressir/model/statements/procedure_call.rb +11 -11
  402. data/lib/expressir/model/statements/repeat.rb +21 -28
  403. data/lib/expressir/model/statements/return.rb +9 -8
  404. data/lib/expressir/model/statements/skip.rb +10 -2
  405. data/lib/expressir/model/statements.rb +20 -0
  406. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +13 -17
  407. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +7 -9
  408. data/lib/expressir/model/supertype_expressions.rb +12 -0
  409. data/lib/expressir/model.rb +38 -78
  410. data/lib/expressir/package/builder.rb +231 -0
  411. data/lib/expressir/package/metadata.rb +79 -0
  412. data/lib/expressir/package/reader.rb +149 -0
  413. data/lib/expressir/package.rb +8 -0
  414. data/lib/expressir/schema_manifest.rb +159 -0
  415. data/lib/expressir/schema_manifest_entry.rb +15 -0
  416. data/lib/expressir/version.rb +6 -1
  417. data/lib/expressir.rb +79 -9
  418. data/lib/tasks/verify_remarks.rake +16 -0
  419. data/rakelib/native.rake +24 -0
  420. data/rakelib/oracle.rake +52 -0
  421. data/rakelib/verify_remarks.rake +16 -0
  422. metadata +431 -129
  423. data/.cross_rubies +0 -20
  424. data/.gitmodules +0 -6
  425. data/.yardopts +0 -11
  426. data/docs/development.md +0 -90
  427. data/exe/format +0 -18
  428. data/exe/generate-parser +0 -51
  429. data/lib/expressir/cli/ui.rb +0 -36
  430. data/lib/expressir/express/2.7/express_parser.so +0 -0
  431. data/lib/expressir/express/3.0/express_parser.so +0 -0
  432. data/lib/expressir/express/3.1/express_parser.so +0 -0
  433. data/lib/expressir/express/3.2/express_parser.so +0 -0
  434. data/lib/expressir/express/visitor.rb +0 -2588
  435. data/lib/expressir/model/data_type.rb +0 -9
  436. data/lib/expressir/model/declaration.rb +0 -9
  437. data/lib/expressir/model/expression.rb +0 -9
  438. data/lib/expressir/model/literal.rb +0 -9
  439. data/lib/expressir/model/reference.rb +0 -9
  440. data/lib/expressir/model/statement.rb +0 -9
  441. data/lib/expressir/model/supertype_expression.rb +0 -9
  442. data/rakelib/antlr4-native.rake +0 -161
  443. data/rakelib/cross-ruby.rake +0 -368
  444. data/spec/acceptance/version_spec.rb +0 -27
  445. data/spec/expressir/express/cache_spec.rb +0 -89
  446. data/spec/expressir/express/formatter_spec.rb +0 -173
  447. data/spec/expressir/express/parser_spec.rb +0 -141
  448. data/spec/expressir/model/model_element_spec.rb +0 -318
  449. data/spec/spec_helper.rb +0 -24
  450. data/spec/support/console_helper.rb +0 -29
  451. data/spec/syntax/multiple.exp +0 -23
  452. data/spec/syntax/multiple.yaml +0 -198
  453. data/spec/syntax/multiple_formatted.exp +0 -71
  454. data/spec/syntax/multiple_hyperlink_formatted.exp +0 -71
  455. data/spec/syntax/multiple_schema_head_hyperlink_formatted.exp +0 -13
  456. data/spec/syntax/remark.exp +0 -193
  457. data/spec/syntax/remark.yaml +0 -471
  458. data/spec/syntax/remark_formatted.exp +0 -228
  459. data/spec/syntax/single.exp +0 -4
  460. data/spec/syntax/single.yaml +0 -18
  461. data/spec/syntax/single_formatted.exp +0 -10
  462. data/spec/syntax/single_formatted.yaml +0 -36
  463. data/spec/syntax/syntax.exp +0 -333
  464. data/spec/syntax/syntax.yaml +0 -3509
  465. data/spec/syntax/syntax_formatted.exp +0 -902
  466. data/spec/syntax/syntax_hyperlink_formatted.exp +0 -902
  467. data/spec/syntax/syntax_schema_head_formatted.exp +0 -18
@@ -1,34 +1,197 @@
1
- require 'pathname'
1
+ require "pathname"
2
2
 
3
3
  module Expressir
4
4
  module Model
5
5
  # Base model element
6
- class ModelElement
7
- CLASS_KEY = '_class'
8
- FILE_KEY = 'file'
9
- SOURCE_KEY = 'source'
6
+ class ModelElement < Lutaml::Model::Serializable
7
+ # ---- Collection-attributes macro (TODO.bugs/12) ----
8
+ #
9
+ # Each model class declares which attributes hold child collections
10
+ # via `collection_attributes :foo, :bar, ...`. The declarations
11
+ # auto-register into the global registry, eliminating the need for
12
+ # a hand-maintained hash in NodePositionIndex.
13
+
14
+ # Returns the global registry: class → array of attr symbols.
15
+ def self.collection_registry
16
+ @collection_registry ||= {}
17
+ end
10
18
 
11
- private_constant :CLASS_KEY
12
- private_constant :FILE_KEY
13
- private_constant :SOURCE_KEY
19
+ # Returns the collection attributes declared on this class (empty
20
+ # if none declared).
21
+ def self.collection_attributes_list
22
+ @collection_attributes || []
23
+ end
14
24
 
15
- # @return [ModelElement]
25
+ # Declare which attributes on this model class hold child collections
26
+ # that should be traversed by tree-walkers (NodePositionIndex,
27
+ # RemarkAttacher, ScopeResolver). Also registers this class in the
28
+ # global collection registry so NodePositionIndex can derive its
29
+ # COLLECTION_REGISTRY from the model instead of duplicating it.
30
+ def self.collection_attributes(*attrs)
31
+ @collection_attributes = attrs.freeze
32
+ ModelElement.collection_registry[self] = attrs
33
+ end
34
+
35
+ # ---- End collection-attributes macro ----
36
+
37
+ # ---- Child-attributes macro (TODO.bugs/15) ----
38
+ #
39
+ # Similar to collection_attributes, but for single-value ModelElement
40
+ # children (non-collection attributes that hold a ModelElement, like
41
+ # BinaryExpression#operand1). Used by RemarkAttacher for query
42
+ # traversal so the EXPRESSION_CHILDREN hash lives on the model.
43
+
44
+ # Returns the global registry: class → array of attr symbols.
45
+ def self.child_attributes_registry
46
+ @child_attributes_registry ||= {}
47
+ end
48
+
49
+ # Returns the child attributes declared on this class (empty if none).
50
+ def self.child_attributes_list
51
+ @child_attributes || []
52
+ end
53
+
54
+ # Declare which attributes on this model class hold single-value
55
+ # ModelElement children that should be traversed by the remark
56
+ # attacher's query-search.
57
+ def self.child_attributes(*attrs)
58
+ @child_attributes = attrs.freeze
59
+ ModelElement.child_attributes_registry[self] = attrs
60
+ end
61
+
62
+ # ---- End child-attributes macro ----
63
+
64
+ # :source is skipped deliberately: its reader formats the node,
65
+ # and reading it during construction (attach_parent_to_children on
66
+ # a from_hash-built object whose attributes are not yet applied)
67
+ # would memoize an incomplete rendering forever.
68
+ SKIP_ATTRIBUTES = %i[parent _class source].freeze
69
+ # :parent is a special attribute that is used to store the parent of the current element
70
+ # It is not a real attribute
71
+ # attribute :parent, ModelElement
16
72
  attr_accessor :parent
17
73
 
74
+ attribute :_class, :string, default: -> { self.class.name },
75
+ polymorphic_class: true
76
+ attribute :source, :string
77
+ attribute :source_offset, :integer
78
+ attribute :untagged_remarks, RemarkInfo, collection: true
79
+
80
+ POLYMORPHIC_CLASS_MAP = {
81
+ "Expressir::Model::Cache" => "Expressir::Model::Cache",
82
+ "Expressir::Model::ExpFile" => "Expressir::Model::ExpFile",
83
+ "Expressir::Model::Repository" => "Expressir::Model::Repository",
84
+ "Expressir::Model::RemarkInfo" => "Expressir::Model::RemarkInfo",
85
+ "Expressir::Model::DataTypes::Aggregate" => "Expressir::Model::DataTypes::Aggregate",
86
+ "Expressir::Model::DataTypes::Array" => "Expressir::Model::DataTypes::Array",
87
+ "Expressir::Model::DataTypes::Bag" => "Expressir::Model::DataTypes::Bag",
88
+ "Expressir::Model::DataTypes::Binary" => "Expressir::Model::DataTypes::Binary",
89
+ "Expressir::Model::DataTypes::Boolean" => "Expressir::Model::DataTypes::Boolean",
90
+ "Expressir::Model::DataTypes::EnumerationItem" => "Expressir::Model::DataTypes::EnumerationItem",
91
+ "Expressir::Model::DataTypes::Enumeration" => "Expressir::Model::DataTypes::Enumeration",
92
+ "Expressir::Model::DataTypes::GenericEntity" => "Expressir::Model::DataTypes::GenericEntity",
93
+ "Expressir::Model::DataTypes::Generic" => "Expressir::Model::DataTypes::Generic",
94
+ "Expressir::Model::DataTypes::Integer" => "Expressir::Model::DataTypes::Integer",
95
+ "Expressir::Model::DataTypes::List" => "Expressir::Model::DataTypes::List",
96
+ "Expressir::Model::DataTypes::Logical" => "Expressir::Model::DataTypes::Logical",
97
+ "Expressir::Model::DataTypes::Number" => "Expressir::Model::DataTypes::Number",
98
+ "Expressir::Model::DataTypes::Real" => "Expressir::Model::DataTypes::Real",
99
+ "Expressir::Model::DataTypes::Select" => "Expressir::Model::DataTypes::Select",
100
+ "Expressir::Model::DataTypes::Set" => "Expressir::Model::DataTypes::Set",
101
+ "Expressir::Model::DataTypes::String" => "Expressir::Model::DataTypes::String",
102
+ "Expressir::Model::Declarations::DerivedAttribute" => "Expressir::Model::Declarations::DerivedAttribute",
103
+ "Expressir::Model::Declarations::Attribute" => "Expressir::Model::Declarations::Attribute",
104
+ "Expressir::Model::Declarations::Constant" => "Expressir::Model::Declarations::Constant",
105
+ "Expressir::Model::Declarations::Entity" => "Expressir::Model::Declarations::Entity",
106
+ "Expressir::Model::Declarations::Function" => "Expressir::Model::Declarations::Function",
107
+ "Expressir::Model::Declarations::InterfaceItem" => "Expressir::Model::Declarations::InterfaceItem",
108
+ "Expressir::Model::Declarations::InverseAttribute" => "Expressir::Model::Declarations::InverseAttribute",
109
+ "Expressir::Model::Declarations::Interface" => "Expressir::Model::Declarations::Interface",
110
+ "Expressir::Model::Declarations::InterfacedItem" => "Expressir::Model::Declarations::InterfacedItem",
111
+ "Expressir::Model::Declarations::Parameter" => "Expressir::Model::Declarations::Parameter",
112
+ "Expressir::Model::Declarations::Procedure" => "Expressir::Model::Declarations::Procedure",
113
+ "Expressir::Model::Declarations::RemarkItem" => "Expressir::Model::Declarations::RemarkItem",
114
+ "Expressir::Model::Declarations::InformalPropositionRule" => "Expressir::Model::Declarations::InformalPropositionRule",
115
+ "Expressir::Model::Declarations::Rule" => "Expressir::Model::Declarations::Rule",
116
+ "Expressir::Model::Declarations::SchemaVersionItem" => "Expressir::Model::Declarations::SchemaVersionItem",
117
+ "Expressir::Model::Declarations::SchemaVersion" => "Expressir::Model::Declarations::SchemaVersion",
118
+ "Expressir::Model::Declarations::Schema" => "Expressir::Model::Declarations::Schema",
119
+ "Expressir::Model::Declarations::SubtypeConstraint" => "Expressir::Model::Declarations::SubtypeConstraint",
120
+ "Expressir::Model::Declarations::Type" => "Expressir::Model::Declarations::Type",
121
+ "Expressir::Model::Declarations::UniqueRule" => "Expressir::Model::Declarations::UniqueRule",
122
+ "Expressir::Model::Declarations::Variable" => "Expressir::Model::Declarations::Variable",
123
+ "Expressir::Model::Declarations::WhereRule" => "Expressir::Model::Declarations::WhereRule",
124
+ "Expressir::Model::Expressions::AggregateInitializerItem" => "Expressir::Model::Expressions::AggregateInitializerItem",
125
+ "Expressir::Model::Expressions::AggregateInitializer" => "Expressir::Model::Expressions::AggregateInitializer",
126
+ "Expressir::Model::Expressions::BinaryExpression" => "Expressir::Model::Expressions::BinaryExpression",
127
+ "Expressir::Model::Expressions::EntityConstructor" => "Expressir::Model::Expressions::EntityConstructor",
128
+ "Expressir::Model::Expressions::FunctionCall" => "Expressir::Model::Expressions::FunctionCall",
129
+ "Expressir::Model::Expressions::Interval" => "Expressir::Model::Expressions::Interval",
130
+ "Expressir::Model::Expressions::QueryExpression" => "Expressir::Model::Expressions::QueryExpression",
131
+ "Expressir::Model::Expressions::UnaryExpression" => "Expressir::Model::Expressions::UnaryExpression",
132
+ "Expressir::Model::Literals::Binary" => "Expressir::Model::Literals::Binary",
133
+ "Expressir::Model::Literals::Integer" => "Expressir::Model::Literals::Integer",
134
+ "Expressir::Model::Literals::Logical" => "Expressir::Model::Literals::Logical",
135
+ "Expressir::Model::Literals::Real" => "Expressir::Model::Literals::Real",
136
+ "Expressir::Model::Literals::String" => "Expressir::Model::Literals::String",
137
+ "Expressir::Model::References::AttributeReference" => "Expressir::Model::References::AttributeReference",
138
+ "Expressir::Model::References::GroupReference" => "Expressir::Model::References::GroupReference",
139
+ "Expressir::Model::References::IndexReference" => "Expressir::Model::References::IndexReference",
140
+ "Expressir::Model::References::SimpleReference" => "Expressir::Model::References::SimpleReference",
141
+ "Expressir::Model::Statements::Alias" => "Expressir::Model::Statements::Alias",
142
+ "Expressir::Model::Statements::Assignment" => "Expressir::Model::Statements::Assignment",
143
+ "Expressir::Model::Statements::CaseAction" => "Expressir::Model::Statements::CaseAction",
144
+ "Expressir::Model::Statements::Case" => "Expressir::Model::Statements::Case",
145
+ "Expressir::Model::Statements::Compound" => "Expressir::Model::Statements::Compound",
146
+ "Expressir::Model::Statements::Escape" => "Expressir::Model::Statements::Escape",
147
+ "Expressir::Model::Statements::If" => "Expressir::Model::Statements::If",
148
+ "Expressir::Model::Statements::Null" => "Expressir::Model::Statements::Null",
149
+ "Expressir::Model::Statements::ProcedureCall" => "Expressir::Model::Statements::ProcedureCall",
150
+ "Expressir::Model::Statements::Repeat" => "Expressir::Model::Statements::Repeat",
151
+ "Expressir::Model::Statements::Return" => "Expressir::Model::Statements::Return",
152
+ "Expressir::Model::Statements::Skip" => "Expressir::Model::Statements::Skip",
153
+ "Expressir::Model::SupertypeExpressions::BinarySupertypeExpression" => "Expressir::Model::SupertypeExpressions::BinarySupertypeExpression",
154
+ "Expressir::Model::SupertypeExpressions::OneofSupertypeExpression" => "Expressir::Model::SupertypeExpressions::OneofSupertypeExpression",
155
+ }.freeze
156
+
157
+ key_value do
158
+ map "_class", to: :_class, render_default: true,
159
+ polymorphic_map: POLYMORPHIC_CLASS_MAP
160
+ # Hydrate-only: byte positions ride the wire (Rust core path)
161
+ # without ever appearing in to_hash — the serialized shape stays
162
+ # identical to the Ruby-built model.
163
+ map "source_offset", to: :source_offset, serialize: false
164
+ end
165
+
166
+ def source
167
+ # Formatting is not free and callers probe `source` repeatedly while
168
+ # walking the tree (position index, remark attachment), so the text is
169
+ # computed once per node. Deliberately NOT @source: that ivar holds
170
+ # the raw source span lutaml-model's `source=` stores when
171
+ # include_source is on, and readers must keep seeing formatted text.
172
+ @formatted_source ||= Expressir::Express::SourceFormatter.format(self) # rubocop:disable Naming/MemoizedInstanceVariableName
173
+ end
174
+
18
175
  # @param [Hash] options
19
- def initialize(options = {})
176
+ def initialize(_options = {})
177
+ super
20
178
  attach_parent_to_children
21
179
  end
22
180
 
23
181
  # @return [String]
24
182
  def path
25
183
  # this creates an implicit scope
26
- return if is_a? Statements::Alias or is_a? Statements::Repeat or is_a? Expressions::QueryExpression
184
+ return if is_a?(Statements::Alias) || is_a?(Statements::Repeat) || is_a?(Expressions::QueryExpression)
27
185
 
28
186
  current_node = self
29
187
  path_parts = []
30
188
  loop do
31
- if current_node.class.method_defined? :id and !(current_node.is_a? References::SimpleReference)
189
+ # Skip adding the id if this is a RemarkItem that belongs to an InformalPropositionRule
190
+ # and has the same id as its parent
191
+ if !(current_node.is_a? References::SimpleReference) && current_node.is_a?(HasId) &&
192
+ !(is_a?(Declarations::RemarkItem) &&
193
+ parent.is_a?(Declarations::InformalPropositionRule) &&
194
+ id == parent.id)
32
195
  path_parts << current_node.id
33
196
  end
34
197
 
@@ -44,9 +207,9 @@ module Expressir
44
207
  # @param [String] path
45
208
  # @return [ModelElement]
46
209
  def find(path)
47
- return self if path.empty?
210
+ return self if path.nil? || path.empty?
48
211
 
49
- path_parts = path.downcase.split(/\./).map do |current_path|
212
+ path_parts = path.safe_downcase.split(".").map do |current_path|
50
213
  _, _, current_path = current_path.rpartition(":") # ignore prefix
51
214
  current_path
52
215
  end
@@ -54,16 +217,9 @@ module Expressir
54
217
  current_scope = self
55
218
  target_node = nil
56
219
  loop do
57
- # find in current scope
58
- current_node = current_scope
59
- path_parts.each do |current_path|
60
- current_node = current_node.children_by_id[current_path]
61
- break unless current_node
62
- end
63
- target_node = current_node
220
+ target_node = resolve_path_in_scope(current_scope, path_parts)
64
221
  break if target_node
65
222
 
66
- # retry search in parent scope
67
223
  current_scope = current_scope.parent
68
224
  break unless current_scope
69
225
  end
@@ -75,6 +231,80 @@ module Expressir
75
231
  target_node
76
232
  end
77
233
 
234
+ # Walk `path_parts` through `scope`, resolving one part at a time.
235
+ # Handles `SELF\<supertype>.<attr>` qualifiers inline: when a part
236
+ # starts with `self\`, the next part is matched against the scope's
237
+ # redeclared attributes and disambiguated by the supertype name
238
+ # (issues #130 and #267).
239
+ def resolve_path_in_scope(scope, path_parts)
240
+ current_node = scope
241
+ pending_supertype = nil
242
+
243
+ path_parts.each do |current_path|
244
+ if current_path.start_with?("self\\")
245
+ pending_supertype = current_path.split("\\", 2).last
246
+ next
247
+ end
248
+
249
+ if pending_supertype
250
+ child = find_redeclared_by_supertype(current_node, current_path,
251
+ pending_supertype)
252
+ return nil unless child
253
+
254
+ current_node = child
255
+ pending_supertype = nil
256
+ else
257
+ current_node = current_node.children_by_id[current_path]
258
+ return nil unless current_node
259
+ end
260
+ end
261
+
262
+ # If the path ended on a SELF qualifier (no attr name followed),
263
+ # resolution is incomplete.
264
+ pending_supertype ? nil : current_node
265
+ end
266
+
267
+ # Find a redeclared attribute among `scope`'s children whose id matches
268
+ # `attr_name` and whose supertype_attribute references the given
269
+ # `supertype` name. Returns nil if `scope` is not an Attribute container
270
+ # or no such child exists.
271
+ def find_redeclared_by_supertype(scope, attr_name, supertype)
272
+ attrs = scope.respond_to?(:attributes) ? scope.attributes : nil
273
+ return nil unless attrs
274
+
275
+ attrs.find do |child|
276
+ next false unless child.is_a?(Model::Declarations::Attribute)
277
+ next false unless child.id&.safe_downcase == attr_name
278
+
279
+ supertype_attr = child.supertype_attribute
280
+ next false unless supertype_attr.respond_to?(:ref)
281
+
282
+ group_ref = supertype_attr.ref
283
+ next false unless group_ref.respond_to?(:entity)
284
+
285
+ entity_ref = group_ref.entity
286
+ entity_ref&.id&.safe_downcase == supertype
287
+ end
288
+ end
289
+
290
+ # Wire the parent pointers of this node's entire subtree. Needed
291
+ # for models materialized outside the builders (e.g. hydrated
292
+ # from the Rust core path), whose parents start unset.
293
+ def wire_parents(parent = nil)
294
+ self.parent = parent
295
+ self.class.attributes.each_key do |attr|
296
+ next if SKIP_ATTRIBUTES.include?(attr) || attr == :parent
297
+
298
+ value = public_send(attr)
299
+ case value
300
+ when Array
301
+ value.each { |v| v.wire_parents(self) if v.is_a?(ModelElement) }
302
+ when ModelElement
303
+ value.wire_parents(self)
304
+ end
305
+ end
306
+ end
307
+
78
308
  # @return [Array<Declaration>]
79
309
  def children
80
310
  []
@@ -82,7 +312,9 @@ module Expressir
82
312
 
83
313
  # @return [Hash<String, Declaration>]
84
314
  def children_by_id
85
- @children_by_id ||= children.select{|x| x.id}.map{|x| [x.id.downcase, x]}.to_h
315
+ @children_by_id ||= children.select(&:id).to_h do |x|
316
+ [x.id.safe_downcase, x]
317
+ end
86
318
  end
87
319
 
88
320
  # @return [nil]
@@ -90,119 +322,56 @@ module Expressir
90
322
  @children_by_id = nil
91
323
  nil
92
324
  end
93
-
94
- # @param [String] root_path
95
- # @param [Express::Formatter] formatter
96
- # @param [Boolean] include_empty
97
- # @return [Hash]
98
- def to_hash(root_path: nil, formatter: nil, include_empty: nil)
99
- hash = {}
100
- hash[CLASS_KEY] = self.class.name
101
-
102
- self.class.model_attrs.each do |variable|
103
- value = self.send(variable)
104
- empty = value.nil? || (value.is_a?(Array) && value.count == 0)
105
-
106
- # skip empty values
107
- if !empty or include_empty
108
- hash[variable.to_s] = if value.is_a? Array
109
- value.map do |value|
110
- if value.is_a? ModelElement
111
- value.to_hash(root_path: root_path, formatter: formatter, include_empty: include_empty)
112
- else
113
- value
114
- end
115
- end
116
- elsif value.is_a? ModelElement
117
- value.to_hash(root_path: root_path, formatter: formatter, include_empty: include_empty)
118
- else
119
- value
120
- end
121
- end
122
- end
123
-
124
- if self.is_a? Declarations::Schema and file
125
- hash[FILE_KEY] = root_path ? Pathname.new(file).relative_path_from(root_path).to_s : file
126
- end
127
-
128
- if self.class.method_defined? :source and formatter
129
- hash[SOURCE_KEY] = formatter.format(self)
130
- end
131
-
132
- hash
133
- end
134
-
135
- # @param [Hash] hash
136
- # @param [String] root_path
137
- # @return [ModelElement]
138
- def self.from_hash(hash, root_path: nil)
139
- node_class = Object.const_get(hash[CLASS_KEY])
140
- node_options = {}
141
-
142
- node_class.model_attrs.each do |variable|
143
- value = hash[variable.to_s]
144
-
145
- node_options[variable] = if value.is_a? Array
146
- value.map do |value|
147
- if value.is_a? Hash
148
- self.from_hash(value, root_path: root_path)
149
- else
150
- value
151
- end
152
- end
153
- elsif value.is_a? Hash
154
- self.from_hash(value, root_path: root_path)
155
- else
156
- value
157
- end
158
- end
159
-
160
- if node_class == Declarations::Schema and hash[FILE_KEY]
161
- node_options[FILE_KEY.to_sym] = root_path ? File.expand_path("#{root_path}/#{hash[FILE_KEY]}") : hash[FILE_KEY]
162
- end
163
325
 
164
- node = node_class.new(node_options)
165
-
166
- node
326
+ # Format this element back into EXPRESS source text.
327
+ # @param no_remarks [Boolean] omit remarks from the output
328
+ # @param formatter [Express::Formatter, nil] use a specific formatter
329
+ # @return [String]
330
+ def format(no_remarks: false, formatter: nil)
331
+ f = formatter || Express::Formatter.new(no_remarks: no_remarks)
332
+ f.format(self)
167
333
  end
168
334
 
169
- # @return [Array<Symbol>]
170
- def self.model_attrs
171
- @model_attrs ||= []
335
+ # No-arg delegator so string interpolation ("#{element}") still
336
+ # produces EXPRESS source rather than the default Object#to_s.
337
+ # Remark-free output is requested explicitly through
338
+ # #format(no_remarks: true); it is not this method's default.
339
+ def to_s
340
+ format
172
341
  end
173
342
 
174
- # Define a new model attribute
175
- # @param attr_name [Symbol] attribute name
176
- # @param attr_type [Symbol] attribute type
177
- # @!macro [attach] model_attr_accessor
178
- # @!attribute $1
179
- # @return [$2]
180
- def self.model_attr_accessor(attr_name, attr_type = nil)
181
- @model_attrs ||= []
182
- @model_attrs << attr_name
343
+ # Add a remark to this element
344
+ # @param remark_info [RemarkInfo] Remark to add
345
+ def add_remark(remark_info)
346
+ self.untagged_remarks ||= []
347
+ return unless remark_info.is_a?(RemarkInfo)
183
348
 
184
- attr_accessor attr_name
349
+ untagged_remarks << remark_info
185
350
  end
186
351
 
187
352
  private
188
353
 
189
354
  # @return [nil]
190
355
  def attach_parent_to_children
191
- self.class.model_attrs.each do |variable|
192
- value = self.send(variable)
356
+ self.class.attributes.each_pair do |symbol, _lutaml_attr|
357
+ next if SKIP_ATTRIBUTES.include?(symbol)
193
358
 
194
- if value.is_a? Array
195
- value.each do |value|
196
- if value.is_a? ModelElement
197
- value.parent = self
359
+ value = public_send(symbol)
360
+
361
+ case value
362
+ when Array
363
+ value.each do |val|
364
+ if val.is_a?(ModelElement)
365
+ val.parent = self
198
366
  end
199
367
  end
200
- elsif value.is_a? ModelElement
368
+ when ModelElement
201
369
  value.parent = self
202
370
  end
203
371
  end
372
+
204
373
  nil
205
374
  end
206
375
  end
207
376
  end
208
- end
377
+ end
@@ -3,20 +3,17 @@ module Expressir
3
3
  module References
4
4
  # Specified in ISO 10303-11:2004
5
5
  # - section 12.7.3 Attribute references
6
- class AttributeReference < Reference
7
- model_attr_accessor :ref, 'Reference'
8
- model_attr_accessor :attribute, 'Reference'
6
+ class AttributeReference < ModelElement
7
+ attribute :ref, ModelElement
8
+ attribute :attribute, ModelElement
9
+ attribute :_class, :string, default: -> { self.class.name }
9
10
 
10
- # @param [Hash] options
11
- # @option options [Reference] :ref
12
- # @option options [Reference] :attribute
13
- def initialize(options = {})
14
- @ref = options[:ref]
15
- @attribute = options[:attribute]
16
-
17
- super
11
+ key_value do
12
+ map "_class", to: :_class, render_default: true
13
+ map "ref", to: :ref
14
+ map "attribute", to: :attribute
18
15
  end
19
16
  end
20
17
  end
21
18
  end
22
- end
19
+ end
@@ -3,20 +3,17 @@ module Expressir
3
3
  module References
4
4
  # Specified in ISO 10303-11:2004
5
5
  # - section 12.7.4 Group references
6
- class GroupReference < Reference
7
- model_attr_accessor :ref, 'Reference'
8
- model_attr_accessor :entity, 'Reference'
6
+ class GroupReference < ModelElement
7
+ attribute :ref, ModelElement
8
+ attribute :entity, ModelElement
9
+ attribute :_class, :string, default: -> { self.class.name }
9
10
 
10
- # @param [Hash] options
11
- # @option options [Reference] :ref
12
- # @option options [Reference] :entity
13
- def initialize(options = {})
14
- @ref = options[:ref]
15
- @entity = options[:entity]
16
-
17
- super
11
+ key_value do
12
+ map "_class", to: :_class, render_default: true
13
+ map "ref", to: :ref
14
+ map "entity", to: :entity
18
15
  end
19
16
  end
20
17
  end
21
18
  end
22
- end
19
+ end
@@ -5,23 +5,19 @@ module Expressir
5
5
  # - section 12.3.1 Binary indexing
6
6
  # - section 12.5.1 String indexing
7
7
  # - section 12.6.1 Aggregate indexing
8
- class IndexReference < Reference
9
- model_attr_accessor :ref, 'Reference'
10
- model_attr_accessor :index1, 'Expression'
11
- model_attr_accessor :index2, 'Expression'
8
+ class IndexReference < ModelElement
9
+ attribute :ref, ModelElement
10
+ attribute :index1, ModelElement
11
+ attribute :index2, ModelElement
12
+ attribute :_class, :string, default: -> { self.class.name }
12
13
 
13
- # @param [Hash] options
14
- # @option options [Reference] :ref
15
- # @option options [Expression] :index1
16
- # @option options [Expression] :index2
17
- def initialize(options = {})
18
- @ref = options[:ref]
19
- @index1 = options[:index1]
20
- @index2 = options[:index2]
21
-
22
- super
14
+ key_value do
15
+ map "_class", to: :_class, render_default: true
16
+ map "ref", to: :ref
17
+ map "index1", to: :index1
18
+ map "index2", to: :index2
23
19
  end
24
20
  end
25
21
  end
26
22
  end
27
- end
23
+ end
@@ -3,22 +3,19 @@ module Expressir
3
3
  module References
4
4
  # Specified in ISO 10303-11:2004
5
5
  # - section 12.7.1 Simple references
6
- class SimpleReference < Reference
7
- model_attr_accessor :id, 'String'
6
+ class SimpleReference < ModelElement
7
+ attribute :id, :string
8
+ attribute :ref, ModelElement
9
+ attribute :base_path, :string
10
+ attribute :_class, :string, default: -> { self.class.name }
8
11
 
9
- model_attr_accessor :base_path, 'String'
10
-
11
- # @param [Hash] options
12
- # @option options [String] :id
13
- # @option options [String] :base_path
14
- def initialize(options = {})
15
- @id = options[:id]
16
-
17
- @base_path = options[:base_path]
18
-
19
- super
12
+ key_value do
13
+ map "_class", to: :_class, render_default: true
14
+ map "id", to: :id
15
+ map "ref", to: :ref
16
+ map "base_path", to: :base_path
20
17
  end
21
18
  end
22
19
  end
23
20
  end
24
- end
21
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Model
5
+ module References
6
+ autoload :AttributeReference, "#{__dir__}/references/attribute_reference"
7
+ autoload :GroupReference, "#{__dir__}/references/group_reference"
8
+ autoload :IndexReference, "#{__dir__}/references/index_reference"
9
+ autoload :SimpleReference, "#{__dir__}/references/simple_reference"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Model
5
+ # Single source of truth for the remark-format vocabulary.
6
+ #
7
+ # Reference: ISO 10303-11 §7.1.6 defines exactly two remark forms:
8
+ # the tail remark (`-- ... \n`) and the embedded remark (`(* ... *)`).
9
+ # Both the model (RemarkInfo) and the express-side scanner/attacher
10
+ # reference these constants instead of bare string literals, so a
11
+ # rename or extension lands in one place.
12
+ module RemarkFormat
13
+ TAIL = "tail"
14
+ EMBEDDED = "embedded"
15
+ end
16
+ end
17
+ end