expressir 2.4.29-arm-linux-musl

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,377 @@
1
+ require "pathname"
2
+
3
+ module Expressir
4
+ module Model
5
+ # Base model element
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
18
+
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
24
+
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
72
+ attr_accessor :parent
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
+
175
+ # @param [Hash] options
176
+ def initialize(_options = {})
177
+ super
178
+ attach_parent_to_children
179
+ end
180
+
181
+ # @return [String]
182
+ def path
183
+ # this creates an implicit scope
184
+ return if is_a?(Statements::Alias) || is_a?(Statements::Repeat) || is_a?(Expressions::QueryExpression)
185
+
186
+ current_node = self
187
+ path_parts = []
188
+ loop do
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)
195
+ path_parts << current_node.id
196
+ end
197
+
198
+ current_node = current_node.parent
199
+ break unless current_node
200
+ end
201
+
202
+ return if path_parts.empty?
203
+
204
+ path_parts.reverse.join(".")
205
+ end
206
+
207
+ # @param [String] path
208
+ # @return [ModelElement]
209
+ def find(path)
210
+ return self if path.nil? || path.empty?
211
+
212
+ path_parts = path.safe_downcase.split(".").map do |current_path|
213
+ _, _, current_path = current_path.rpartition(":") # ignore prefix
214
+ current_path
215
+ end
216
+
217
+ current_scope = self
218
+ target_node = nil
219
+ loop do
220
+ target_node = resolve_path_in_scope(current_scope, path_parts)
221
+ break if target_node
222
+
223
+ current_scope = current_scope.parent
224
+ break unless current_scope
225
+ end
226
+
227
+ if target_node.is_a? Model::Declarations::InterfacedItem
228
+ target_node = target_node.base_item
229
+ end
230
+
231
+ target_node
232
+ end
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
+
308
+ # @return [Array<Declaration>]
309
+ def children
310
+ []
311
+ end
312
+
313
+ # @return [Hash<String, Declaration>]
314
+ def children_by_id
315
+ @children_by_id ||= children.select(&:id).to_h do |x|
316
+ [x.id.safe_downcase, x]
317
+ end
318
+ end
319
+
320
+ # @return [nil]
321
+ def reset_children_by_id
322
+ @children_by_id = nil
323
+ nil
324
+ end
325
+
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)
333
+ end
334
+
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
341
+ end
342
+
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)
348
+
349
+ untagged_remarks << remark_info
350
+ end
351
+
352
+ private
353
+
354
+ # @return [nil]
355
+ def attach_parent_to_children
356
+ self.class.attributes.each_pair do |symbol, _lutaml_attr|
357
+ next if SKIP_ATTRIBUTES.include?(symbol)
358
+
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
366
+ end
367
+ end
368
+ when ModelElement
369
+ value.parent = self
370
+ end
371
+ end
372
+
373
+ nil
374
+ end
375
+ end
376
+ end
377
+ end
@@ -0,0 +1,19 @@
1
+ module Expressir
2
+ module Model
3
+ module References
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 12.7.3 Attribute references
6
+ class AttributeReference < ModelElement
7
+ attribute :ref, ModelElement
8
+ attribute :attribute, ModelElement
9
+ attribute :_class, :string, default: -> { self.class.name }
10
+
11
+ key_value do
12
+ map "_class", to: :_class, render_default: true
13
+ map "ref", to: :ref
14
+ map "attribute", to: :attribute
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Expressir
2
+ module Model
3
+ module References
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 12.7.4 Group references
6
+ class GroupReference < ModelElement
7
+ attribute :ref, ModelElement
8
+ attribute :entity, ModelElement
9
+ attribute :_class, :string, default: -> { self.class.name }
10
+
11
+ key_value do
12
+ map "_class", to: :_class, render_default: true
13
+ map "ref", to: :ref
14
+ map "entity", to: :entity
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ module Expressir
2
+ module Model
3
+ module References
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 12.3.1 Binary indexing
6
+ # - section 12.5.1 String indexing
7
+ # - section 12.6.1 Aggregate indexing
8
+ class IndexReference < ModelElement
9
+ attribute :ref, ModelElement
10
+ attribute :index1, ModelElement
11
+ attribute :index2, ModelElement
12
+ attribute :_class, :string, default: -> { self.class.name }
13
+
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
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Expressir
2
+ module Model
3
+ module References
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 12.7.1 Simple references
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 }
11
+
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
17
+ end
18
+ end
19
+ end
20
+ 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
@@ -0,0 +1,92 @@
1
+ module Expressir
2
+ module Model
3
+ # Represents a remark with its format and optional tag
4
+ # Supports both tail remarks (-- ...) and embedded remarks ((* ... *))
5
+ # Can include optional tags for associating remarks with specific items
6
+ class RemarkInfo < Lutaml::Model::Serializable
7
+ attribute :text, :string
8
+ attribute :format, :string, default: RemarkFormat::EMBEDDED
9
+ attribute :tag, :string # optional remark tag like "entity.attr"
10
+ # See RemarkPlacement. nil = legacy placement.
11
+ attribute :placement, :string
12
+ # Qualifies the placement. For TRAILING, which body of the owner the
13
+ # remark closes, named by that body's attribute. For INLINE,
14
+ # RemarkPlacement::OPENER_REGION when it trailed a compound statement's
15
+ # opening line rather than a whole statement.
16
+ attribute :region, :string
17
+ attribute :source_offset, :integer # byte offset in source text
18
+
19
+ # Check if this is a tail remark
20
+ # @return [Boolean] True if format is 'tail'
21
+ def tail?
22
+ format == RemarkFormat::TAIL
23
+ end
24
+
25
+ # Check if this is an embedded remark
26
+ # @return [Boolean] True if format is 'embedded'
27
+ def embedded?
28
+ format == RemarkFormat::EMBEDDED
29
+ end
30
+
31
+ # Check if this remark has a tag
32
+ # @return [Boolean] True if tag is present
33
+ def tagged?
34
+ !tag.nil? && !tag.empty?
35
+ end
36
+
37
+ # Check if this remark should be emitted above its owning statement
38
+ # @return [Boolean] True if placement is 'leading'
39
+ def leading?
40
+ placement == RemarkPlacement::LEADING
41
+ end
42
+
43
+ # Check if this remark trails its owning statement on the same line
44
+ # @return [Boolean] True if placement is 'inline'
45
+ def inline?
46
+ placement == RemarkPlacement::INLINE
47
+ end
48
+
49
+ # Check if this remark trailed the opening line of a statement spanning
50
+ # several lines, as in `IF x THEN -- why`
51
+ # @return [Boolean]
52
+ def opener?
53
+ inline? && region == RemarkPlacement::OPENER_REGION
54
+ end
55
+
56
+ # Check if this INLINE remark belongs after a mid-construct keyword of
57
+ # its owning construct — `ELSE -- why`, `OTHERWISE : -- why` — rather
58
+ # than after the statement's closing keyword.
59
+ # @param name [Symbol, String] a RemarkPlacement region constant
60
+ # @return [Boolean]
61
+ def inline_region?(name)
62
+ inline? && region == name.to_s
63
+ end
64
+
65
+ # Check if this remark closes the given body of its owning node
66
+ # @param name [Symbol, String] region attribute name
67
+ # @return [Boolean]
68
+ def trailing_region?(name)
69
+ placement == RemarkPlacement::TRAILING && region == name.to_s
70
+ end
71
+
72
+ # YAML serialization
73
+ yaml do
74
+ map "text", to: :text
75
+ map "format", to: :format
76
+ map "tag", to: :tag
77
+ map "placement", to: :placement
78
+ map "region", to: :region
79
+ end
80
+
81
+ # XML serialization
82
+ xml do
83
+ element "remark_info"
84
+ map_element "text", to: :text
85
+ map_element "format", to: :format
86
+ map_element "tag", to: :tag
87
+ map_element "placement", to: :placement
88
+ map_element "region", to: :region
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Model
5
+ # Single source of truth for where a remark sits relative to the model
6
+ # element that owns it.
7
+ #
8
+ # The parser discards comments, so attachment reconstructs their position
9
+ # from source lines. Placement records that reconstruction, letting the
10
+ # formatter put the remark back where it was written:
11
+ #
12
+ # - LEADING — on its own line(s) directly above the owning statement.
13
+ # - TRAILING — on its own line(s) at the end of a body, before the closing
14
+ # keyword. The owner is the body's owner, and RemarkInfo#region names
15
+ # which body: an IF owns two, and they close at different keywords.
16
+ # - INLINE — on the same line as the owning statement, after its text.
17
+ # Emitted after the whole statement, which for a single-line one is the
18
+ # line it was written on. RemarkInfo#region separates the other case:
19
+ # OPENER_REGION means the remark trailed the opening line of a statement
20
+ # spanning several lines, as in `IF x THEN -- why`, and belongs back on
21
+ # that opener rather than after the closing keyword.
22
+ #
23
+ # `nil` means the remark was attached by a legacy path, or predates
24
+ # placement tracking. Those keep their historical emission and must not
25
+ # be rendered by placement-aware emitters.
26
+ module RemarkPlacement
27
+ LEADING = "leading"
28
+ TRAILING = "trailing"
29
+ INLINE = "inline"
30
+
31
+ # Region of an INLINE remark that trailed a compound statement's opener.
32
+ OPENER_REGION = "opener"
33
+
34
+ # Regions of INLINE remarks that trailed a mid-construct keyword line —
35
+ # `ELSE -- why` or `OTHERWISE : -- why`. The owning construct is the
36
+ # enclosing IF / CASE, and the remark belongs back after that keyword,
37
+ # not after the construct's closing END_.
38
+ ELSE_REGION = "else"
39
+ OTHERWISE_REGION = "otherwise"
40
+ end
41
+ end
42
+ end