expressir 2.4.29-arm-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. checksums.yaml +7 -0
  2. data/.cargo/config.toml +3 -0
  3. data/.github/scripts/test_installed_gem.rb +34 -0
  4. data/.github/workflows/codeql.yml +35 -0
  5. data/.github/workflows/docs.yml +99 -0
  6. data/.github/workflows/links.yml +100 -0
  7. data/.github/workflows/native-gems.yml +201 -0
  8. data/.github/workflows/rake.yml +19 -0
  9. data/.github/workflows/release.yml +37 -0
  10. data/.github/workflows/rust-ext.yml +41 -0
  11. data/.github/workflows/stress.yml +36 -0
  12. data/.github/workflows/validate_schemas.yml +48 -0
  13. data/.github/workflows/verify_remarks.yml +33 -0
  14. data/.gitignore +55 -0
  15. data/.hound.yml +3 -0
  16. data/.rspec +2 -0
  17. data/.rubocop.yml +18 -0
  18. data/.rubocop_todo.yml +297 -0
  19. data/CHANGELOG.md +159 -0
  20. data/Gemfile +18 -0
  21. data/README.adoc +2783 -0
  22. data/Rakefile +41 -0
  23. data/TODO.bugs/01-stale-transformer-autoload.md +39 -0
  24. data/TODO.bugs/02-parser-class-instance-vars.md +36 -0
  25. data/TODO.bugs/03-builder-mutable-state.md +43 -0
  26. data/TODO.bugs/04-formatter-public-send-dispatch.md +53 -0
  27. data/TODO.bugs/05-anonymous-formatter-subclass.md +45 -0
  28. data/TODO.bugs/06-collection-registry-single-source.md +53 -0
  29. data/TODO.bugs/07-require-relative-cleanup.md +42 -0
  30. data/TODO.bugs/08-require-expressir-in-commands.md +34 -0
  31. data/TODO.bugs/09-parser-split.md +53 -0
  32. data/TODO.bugs/10-to-s-override.md +42 -0
  33. data/TODO.bugs/11-parser-class-variables.md +39 -0
  34. data/TODO.bugs/12-marker-modules-vs-registry.md +64 -0
  35. data/TODO.bugs/13-string-literal-scanner-limitation.md +52 -0
  36. data/TODO.bugs/14-model-formatting-leak.md +30 -0
  37. data/TODO.bugs/15-expression-children-macro.md +27 -0
  38. data/TODO.bugs/16-pretty-formatter-duplication.md +28 -0
  39. data/TODO.bugs/17-snake-case-cache-mutable-constant.md +28 -0
  40. data/TODO.bugs/18-const-get-private-constants.md +30 -0
  41. data/TODO.bugs/19-format-methods-public.md +22 -0
  42. data/TODO.bugs/20-coverage-nested-entities-dedup.md +20 -0
  43. data/TODO.bugs/21-operator-tokens-secondary-dispatch.md +21 -0
  44. data/TODO.bugs/22-builder-fast-path-wrappers.md +32 -0
  45. data/TODO.bugs/23-coverage-inverse-maps.md +21 -0
  46. data/TODO.bugs/24-streaming-builder-complexity.md +19 -0
  47. data/TODO.bugs/25-debug-puts-in-production.md +21 -0
  48. data/TODO.bugs/26-generic-entity-children-misplaced.md +21 -0
  49. data/TODO.bugs/27-package-build-god-method.md +19 -0
  50. data/TODO.bugs/28-package-god-class.md +30 -0
  51. data/TODO.bugs/29-validate-ascii-god-class.md +24 -0
  52. data/TODO.bugs/30-unicode-map-extraction.md +19 -0
  53. data/TODO.bugs/README.md +43 -0
  54. data/TODO.max-perf/01-restore-ci-green.md +36 -0
  55. data/TODO.max-perf/02-streaming-parse-path.md +31 -0
  56. data/TODO.max-perf/03-cli-parallel-opt-in.md +27 -0
  57. data/TODO.max-perf/04-benchmark-harness.md +28 -0
  58. data/TODO.max-perf/05-parallel-fidelity-specs.md +22 -0
  59. data/TODO.max-perf/06-builder-cpu-audit.md +41 -0
  60. data/TODO.max-perf/07-upstream-parsanol-roadmap.md +27 -0
  61. data/TODO.max-perf/08-builder-build-perf.md +45 -0
  62. data/TODO.max-perf/09-grammar-cold-start.md +25 -0
  63. data/TODO.max-perf/10-parser-facade-hygiene.md +23 -0
  64. data/TODO.max-perf/11-ci-green-closeout.md +25 -0
  65. data/TODO.max-perf/12-require-boot-profile.md +25 -0
  66. data/TODO.max-perf/13-key-conversion-specs.md +26 -0
  67. data/TODO.max-perf/14-builder-call-handler-audit.md +28 -0
  68. data/TODO.parity-ee/00-overview.md +76 -0
  69. data/TODO.parity-ee/01-annex-g-rule-extraction.md +41 -0
  70. data/TODO.parity-ee/02-eeng-algorithm-inventory.md +8 -0
  71. data/TODO.parity-ee/03-eeng-oracle-harness.md +33 -0
  72. data/TODO.parity-ee/04-shtolo-concatenate.md +44 -0
  73. data/TODO.parity-ee/05-shtolo-longform-flatten.md +53 -0
  74. data/TODO.parity-ee/06-interface-scheduling-parity.md +47 -0
  75. data/TODO.parity-ee/07-semantic-checks-port.md +35 -0
  76. data/TODO.parity-ee/08-pretty-roundtrip-gate.md +27 -0
  77. data/TODO.parity-ee/09-smrl-index-and-listing.md +22 -0
  78. data/TODO.parity-ee/10-interface-dot-graph.md +21 -0
  79. data/TODO.parity-ee/11-import-eeng-tests.md +79 -0
  80. data/TODO.parity-ee/12-full-check-catalog.md +67 -0
  81. data/TODO.parity-ee/13-population-p21.md +54 -0
  82. data/TODO.parity-ee/14-shtolo-completion.md +44 -0
  83. data/TODO.parity-ee/15-part28-xml.md +51 -0
  84. data/TODO.parity-ee/16-compare-patch.md +48 -0
  85. data/TODO.parity-ee/17-official-tests.md +42 -0
  86. data/TODO.parity-ee/18-mim-mapping.md +47 -0
  87. data/TODO.parity-ee/19-architecture.md +97 -0
  88. data/TODO.parity-ee/parity-matrix.md +108 -0
  89. data/TODO.refpath-v2/00-overview.md +64 -0
  90. data/TODO.suma-improvements/00-overview.md +23 -0
  91. data/TODO.suma-improvements/01-prebuilt-platform-gems.md +33 -0
  92. data/TODO.suma-improvements/02-suma-e2e.md +39 -0
  93. data/TODO.suma-improvements/03-item-graph.md +22 -0
  94. data/TODO.suma-improvements/04-compiled-set-default.md +16 -0
  95. data/TODO.suma-improvements/05-validation-in-docs.md +17 -0
  96. data/TODO.suma-improvements/06-memory-remeasure.md +36 -0
  97. data/TODO.suma-improvements/07-part28-xml.md +15 -0
  98. data/TODO.suma-improvements/08-windows-gnu-toolchain.md +15 -0
  99. data/TODO.suma-improvements/09-checker-tranche3.md +13 -0
  100. data/TODO.suma-improvements/10-expressdoc.md +8 -0
  101. data/benchmark/srl_benchmark.rb +458 -0
  102. data/benchmark/srl_native_benchmark.rb +146 -0
  103. data/benchmark/srl_ruby_benchmark.rb +132 -0
  104. data/bin/console +11 -0
  105. data/bin/rspec +30 -0
  106. data/bin/setup +8 -0
  107. data/docs/Gemfile +12 -0
  108. data/docs/_config.yml +141 -0
  109. data/docs/_guides/changes/changes-format.adoc +778 -0
  110. data/docs/_guides/changes/importing-eengine.adoc +898 -0
  111. data/docs/_guides/changes/index.adoc +396 -0
  112. data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
  113. data/docs/_guides/changes/validating-changes.adoc +681 -0
  114. data/docs/_guides/cli/benchmark-performance.adoc +834 -0
  115. data/docs/_guides/cli/coverage-analysis.adoc +921 -0
  116. data/docs/_guides/cli/format-schemas.adoc +547 -0
  117. data/docs/_guides/cli/index.adoc +8 -0
  118. data/docs/_guides/cli/managing-changes.adoc +927 -0
  119. data/docs/_guides/cli/validate-ascii.adoc +645 -0
  120. data/docs/_guides/cli/validate-schemas.adoc +534 -0
  121. data/docs/_guides/formatter/formatter-architecture.adoc +401 -0
  122. data/docs/_guides/index.adoc +165 -0
  123. data/docs/_guides/ler/creating-packages.adoc +664 -0
  124. data/docs/_guides/ler/index.adoc +305 -0
  125. data/docs/_guides/ler/loading-packages.adoc +707 -0
  126. data/docs/_guides/ler/package-formats.adoc +748 -0
  127. data/docs/_guides/ler/querying-packages.adoc +826 -0
  128. data/docs/_guides/ler/step-packages.adoc +385 -0
  129. data/docs/_guides/ler/validating-packages.adoc +750 -0
  130. data/docs/_guides/liquid/basic-templates.adoc +813 -0
  131. data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
  132. data/docs/_guides/liquid/drops-reference.adoc +829 -0
  133. data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
  134. data/docs/_guides/liquid/index.adoc +468 -0
  135. data/docs/_guides/manifests/creating-manifests.adoc +483 -0
  136. data/docs/_guides/manifests/index.adoc +307 -0
  137. data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
  138. data/docs/_guides/manifests/validating-manifests.adoc +713 -0
  139. data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
  140. data/docs/_guides/ruby-api/index.adoc +257 -0
  141. data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
  142. data/docs/_guides/ruby-api/search-engine.adoc +609 -0
  143. data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
  144. data/docs/_pages/data-model.adoc +665 -0
  145. data/docs/_pages/express-language.adoc +506 -0
  146. data/docs/_pages/getting-started.adoc +414 -0
  147. data/docs/_pages/index.adoc +116 -0
  148. data/docs/_pages/introduction.adoc +256 -0
  149. data/docs/_pages/ler-packages.adoc +837 -0
  150. data/docs/_pages/parsers.adoc +709 -0
  151. data/docs/_pages/schema-manifests.adoc +431 -0
  152. data/docs/_references/index.adoc +228 -0
  153. data/docs/_tutorials/creating-ler-package.adoc +735 -0
  154. data/docs/_tutorials/documentation-coverage.adoc +795 -0
  155. data/docs/_tutorials/formatting-schemas.adoc +89 -0
  156. data/docs/_tutorials/index.adoc +231 -0
  157. data/docs/_tutorials/liquid-templates.adoc +806 -0
  158. data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
  159. data/docs/_tutorials/querying-schemas.adoc +751 -0
  160. data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
  161. data/docs/index.adoc +242 -0
  162. data/docs/lychee.toml +90 -0
  163. data/examples/demo_ler_usage.sh +86 -0
  164. data/examples/ler/README.md +111 -0
  165. data/examples/ler/simple_example.ler +0 -0
  166. data/examples/ler/simple_schema.exp +33 -0
  167. data/examples/ler_build.rb +75 -0
  168. data/examples/ler_cli.rb +79 -0
  169. data/examples/ler_demo_complete.rb +276 -0
  170. data/examples/ler_query.rb +91 -0
  171. data/examples/ler_query_examples.rb +305 -0
  172. data/examples/ler_stats.rb +81 -0
  173. data/examples/phase3_demo.rb +159 -0
  174. data/examples/query_demo_simple.rb +131 -0
  175. data/exe/expressir +11 -0
  176. data/exe/expressir-format +14 -0
  177. data/exe/expressir-format-test +82 -0
  178. data/expressir.gemspec +61 -0
  179. data/lib/expressir/3.2/expressir_core.so +0 -0
  180. data/lib/expressir/3.3/expressir_core.so +0 -0
  181. data/lib/expressir/3.4/expressir_core.so +0 -0
  182. data/lib/expressir/4.0/expressir_core.so +0 -0
  183. data/lib/expressir/benchmark.rb +310 -0
  184. data/lib/expressir/changes/item_change.rb +20 -0
  185. data/lib/expressir/changes/mapping_change.rb +16 -0
  186. data/lib/expressir/changes/schema_change.rb +85 -0
  187. data/lib/expressir/changes/version_change.rb +26 -0
  188. data/lib/expressir/changes.rb +9 -0
  189. data/lib/expressir/cli.rb +148 -0
  190. data/lib/expressir/commands/base.rb +25 -0
  191. data/lib/expressir/commands/benchmark.rb +59 -0
  192. data/lib/expressir/commands/benchmark_cache.rb +80 -0
  193. data/lib/expressir/commands/changes.rb +34 -0
  194. data/lib/expressir/commands/changes_import_eengine.rb +146 -0
  195. data/lib/expressir/commands/changes_validate.rb +63 -0
  196. data/lib/expressir/commands/check.rb +56 -0
  197. data/lib/expressir/commands/clean.rb +20 -0
  198. data/lib/expressir/commands/coverage.rb +458 -0
  199. data/lib/expressir/commands/expand.rb +26 -0
  200. data/lib/expressir/commands/file_violations.rb +70 -0
  201. data/lib/expressir/commands/fix.rb +33 -0
  202. data/lib/expressir/commands/flatten.rb +29 -0
  203. data/lib/expressir/commands/format.rb +43 -0
  204. data/lib/expressir/commands/manifest.rb +420 -0
  205. data/lib/expressir/commands/mapping_validate.rb +68 -0
  206. data/lib/expressir/commands/non_ascii_character.rb +49 -0
  207. data/lib/expressir/commands/non_ascii_violation_collection.rb +301 -0
  208. data/lib/expressir/commands/package.rb +1222 -0
  209. data/lib/expressir/commands/parity_inputs.rb +160 -0
  210. data/lib/expressir/commands/validate.rb +106 -0
  211. data/lib/expressir/commands/validate_ascii.rb +94 -0
  212. data/lib/expressir/commands/validate_load.rb +91 -0
  213. data/lib/expressir/commands/version.rb +9 -0
  214. data/lib/expressir/commands/xsd.rb +23 -0
  215. data/lib/expressir/commands.rb +30 -0
  216. data/lib/expressir/config.rb +60 -0
  217. data/lib/expressir/coverage.rb +510 -0
  218. data/lib/expressir/eengine/arm_compare_report.rb +23 -0
  219. data/lib/expressir/eengine/changes_section.rb +16 -0
  220. data/lib/expressir/eengine/compare_report.rb +69 -0
  221. data/lib/expressir/eengine/mim_compare_report.rb +23 -0
  222. data/lib/expressir/eengine/modified_object.rb +21 -0
  223. data/lib/expressir/eengine.rb +9 -0
  224. data/lib/expressir/errors.rb +113 -0
  225. data/lib/expressir/express/adoc_hyperlink_formatter.rb +30 -0
  226. data/lib/expressir/express/adoc_source_formatter.rb +12 -0
  227. data/lib/expressir/express/ast_key_converter.rb +114 -0
  228. data/lib/expressir/express/builder.rb +277 -0
  229. data/lib/expressir/express/builder_context.rb +22 -0
  230. data/lib/expressir/express/builder_registry.rb +397 -0
  231. data/lib/expressir/express/builders/attribute_decl_builder.rb +32 -0
  232. data/lib/expressir/express/builders/built_in_builder.rb +75 -0
  233. data/lib/expressir/express/builders/constant_builder.rb +108 -0
  234. data/lib/expressir/express/builders/declaration_builder.rb +20 -0
  235. data/lib/expressir/express/builders/derive_clause_builder.rb +14 -0
  236. data/lib/expressir/express/builders/derived_attr_builder.rb +28 -0
  237. data/lib/expressir/express/builders/domain_rule_builder.rb +21 -0
  238. data/lib/expressir/express/builders/entity_decl_builder.rb +116 -0
  239. data/lib/expressir/express/builders/explicit_attr_builder.rb +49 -0
  240. data/lib/expressir/express/builders/expression_builder.rb +416 -0
  241. data/lib/expressir/express/builders/function_decl_builder.rb +86 -0
  242. data/lib/expressir/express/builders/helpers.rb +148 -0
  243. data/lib/expressir/express/builders/interface_builder.rb +151 -0
  244. data/lib/expressir/express/builders/inverse_attr_builder.rb +43 -0
  245. data/lib/expressir/express/builders/inverse_attr_type_builder.rb +30 -0
  246. data/lib/expressir/express/builders/inverse_clause_builder.rb +14 -0
  247. data/lib/expressir/express/builders/literal_builder.rb +93 -0
  248. data/lib/expressir/express/builders/procedure_decl_builder.rb +82 -0
  249. data/lib/expressir/express/builders/qualifier_builder.rb +102 -0
  250. data/lib/expressir/express/builders/reference_builder.rb +18 -0
  251. data/lib/expressir/express/builders/rule_decl_builder.rb +97 -0
  252. data/lib/expressir/express/builders/schema_body_decl_builder.rb +18 -0
  253. data/lib/expressir/express/builders/schema_decl_builder.rb +56 -0
  254. data/lib/expressir/express/builders/schema_version_builder.rb +34 -0
  255. data/lib/expressir/express/builders/simple_id_builder.rb +17 -0
  256. data/lib/expressir/express/builders/statement_builder.rb +243 -0
  257. data/lib/expressir/express/builders/subtype_constraint_builder.rb +166 -0
  258. data/lib/expressir/express/builders/syntax_builder.rb +30 -0
  259. data/lib/expressir/express/builders/type_builder.rb +238 -0
  260. data/lib/expressir/express/builders/type_decl_builder.rb +26 -0
  261. data/lib/expressir/express/builders/unique_clause_builder.rb +20 -0
  262. data/lib/expressir/express/builders/unique_rule_builder.rb +41 -0
  263. data/lib/expressir/express/builders/where_clause_builder.rb +20 -0
  264. data/lib/expressir/express/builders.rb +55 -0
  265. data/lib/expressir/express/cache.rb +76 -0
  266. data/lib/expressir/express/checker.rb +812 -0
  267. data/lib/expressir/express/concatenator.rb +79 -0
  268. data/lib/expressir/express/core.rb +95 -0
  269. data/lib/expressir/express/error.rb +124 -0
  270. data/lib/expressir/express/formatter.rb +149 -0
  271. data/lib/expressir/express/formatters/data_types_formatter.rb +362 -0
  272. data/lib/expressir/express/formatters/declarations_formatter.rb +753 -0
  273. data/lib/expressir/express/formatters/expressions_formatter.rb +180 -0
  274. data/lib/expressir/express/formatters/literals_formatter.rb +55 -0
  275. data/lib/expressir/express/formatters/references_formatter.rb +53 -0
  276. data/lib/expressir/express/formatters/remark_formatter.rb +270 -0
  277. data/lib/expressir/express/formatters/remark_item_formatter.rb +28 -0
  278. data/lib/expressir/express/formatters/statements_formatter.rb +272 -0
  279. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +54 -0
  280. data/lib/expressir/express/formatters.rb +22 -0
  281. data/lib/expressir/express/grammar/parser.rb +712 -0
  282. data/lib/expressir/express/grammar.rb +11 -0
  283. data/lib/expressir/express/hyperlink_formatter.rb +35 -0
  284. data/lib/expressir/express/interface_dot.rb +105 -0
  285. data/lib/expressir/express/lazy_repository.rb +211 -0
  286. data/lib/expressir/express/line_map.rb +48 -0
  287. data/lib/expressir/express/listing.rb +174 -0
  288. data/lib/expressir/express/model_traversal.rb +42 -0
  289. data/lib/expressir/express/model_visitor.rb +25 -0
  290. data/lib/expressir/express/node_position_index.rb +342 -0
  291. data/lib/expressir/express/parallel_files.rb +229 -0
  292. data/lib/expressir/express/parser.rb +523 -0
  293. data/lib/expressir/express/pretty_formatter.rb +586 -0
  294. data/lib/expressir/express/pretty_gate.rb +61 -0
  295. data/lib/expressir/express/refs_overlay.rb +47 -0
  296. data/lib/expressir/express/remark_attacher.rb +1098 -0
  297. data/lib/expressir/express/remark_overlay.rb +86 -0
  298. data/lib/expressir/express/remark_scanner.rb +245 -0
  299. data/lib/expressir/express/resolve_references_model_visitor.rb +29 -0
  300. data/lib/expressir/express/schema_block_scanner.rb +137 -0
  301. data/lib/expressir/express/schema_head_formatter.rb +22 -0
  302. data/lib/expressir/express/schema_plain_source_formatter.rb +11 -0
  303. data/lib/expressir/express/schema_source_formatter.rb +15 -0
  304. data/lib/expressir/express/scope_resolver.rb +223 -0
  305. data/lib/expressir/express/self_schema_reference.rb +126 -0
  306. data/lib/expressir/express/shtolo.rb +679 -0
  307. data/lib/expressir/express/smrl_xml.rb +125 -0
  308. data/lib/expressir/express/source_formatter.rb +15 -0
  309. data/lib/expressir/express/streaming_builder.rb +435 -0
  310. data/lib/expressir/express/xsd.rb +259 -0
  311. data/lib/expressir/express.rb +53 -0
  312. data/lib/expressir/liquid.rb +1 -0
  313. data/lib/expressir/manifest/resolver.rb +210 -0
  314. data/lib/expressir/manifest/validator.rb +192 -0
  315. data/lib/expressir/manifest.rb +6 -0
  316. data/lib/expressir/mapping/refpath.rb +857 -0
  317. data/lib/expressir/mapping.rb +253 -0
  318. data/lib/expressir/model/cache.rb +18 -0
  319. data/lib/expressir/model/concerns.rb +42 -0
  320. data/lib/expressir/model/data_types/aggregate.rb +26 -0
  321. data/lib/expressir/model/data_types/array.rb +25 -0
  322. data/lib/expressir/model/data_types/bag.rb +21 -0
  323. data/lib/expressir/model/data_types/binary.rb +19 -0
  324. data/lib/expressir/model/data_types/boolean.rb +15 -0
  325. data/lib/expressir/model/data_types/enumeration.rb +21 -0
  326. data/lib/expressir/model/data_types/enumeration_item.rb +24 -0
  327. data/lib/expressir/model/data_types/generic.rb +24 -0
  328. data/lib/expressir/model/data_types/generic_entity.rb +24 -0
  329. data/lib/expressir/model/data_types/integer.rb +15 -0
  330. data/lib/expressir/model/data_types/list.rb +23 -0
  331. data/lib/expressir/model/data_types/logical.rb +15 -0
  332. data/lib/expressir/model/data_types/number.rb +15 -0
  333. data/lib/expressir/model/data_types/real.rb +17 -0
  334. data/lib/expressir/model/data_types/select.rb +23 -0
  335. data/lib/expressir/model/data_types/set.rb +21 -0
  336. data/lib/expressir/model/data_types/string.rb +19 -0
  337. data/lib/expressir/model/data_types.rb +25 -0
  338. data/lib/expressir/model/declarations/attribute.rb +38 -0
  339. data/lib/expressir/model/declarations/constant.rb +28 -0
  340. data/lib/expressir/model/declarations/derived_attribute.rb +25 -0
  341. data/lib/expressir/model/declarations/entity.rb +62 -0
  342. data/lib/expressir/model/declarations/function.rb +59 -0
  343. data/lib/expressir/model/declarations/informal_proposition_rule.rb +25 -0
  344. data/lib/expressir/model/declarations/interface.rb +37 -0
  345. data/lib/expressir/model/declarations/interface_item.rb +21 -0
  346. data/lib/expressir/model/declarations/interfaced_item.rb +33 -0
  347. data/lib/expressir/model/declarations/inverse_attribute.rb +25 -0
  348. data/lib/expressir/model/declarations/parameter.rb +28 -0
  349. data/lib/expressir/model/declarations/procedure.rb +57 -0
  350. data/lib/expressir/model/declarations/remark_item.rb +21 -0
  351. data/lib/expressir/model/declarations/rule.rb +66 -0
  352. data/lib/expressir/model/declarations/schema.rb +215 -0
  353. data/lib/expressir/model/declarations/schema_version.rb +19 -0
  354. data/lib/expressir/model/declarations/schema_version_item.rb +19 -0
  355. data/lib/expressir/model/declarations/subtype_constraint.rb +32 -0
  356. data/lib/expressir/model/declarations/type.rb +45 -0
  357. data/lib/expressir/model/declarations/unique_rule.rb +26 -0
  358. data/lib/expressir/model/declarations/variable.rb +28 -0
  359. data/lib/expressir/model/declarations/where_rule.rb +26 -0
  360. data/lib/expressir/model/declarations.rb +31 -0
  361. data/lib/expressir/model/dependency_resolver.rb +268 -0
  362. data/lib/expressir/model/exp_file.rb +42 -0
  363. data/lib/expressir/model/expressions/aggregate_initializer.rb +18 -0
  364. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +20 -0
  365. data/lib/expressir/model/expressions/binary_expression.rb +59 -0
  366. data/lib/expressir/model/expressions/entity_constructor.rb +20 -0
  367. data/lib/expressir/model/expressions/function_call.rb +20 -0
  368. data/lib/expressir/model/expressions/interval.rb +29 -0
  369. data/lib/expressir/model/expressions/query_expression.rb +31 -0
  370. data/lib/expressir/model/expressions/unary_expression.rb +25 -0
  371. data/lib/expressir/model/expressions.rb +18 -0
  372. data/lib/expressir/model/identifier.rb +26 -0
  373. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  374. data/lib/expressir/model/indexes/item_graph.rb +185 -0
  375. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  376. data/lib/expressir/model/indexes/type_index.rb +149 -0
  377. data/lib/expressir/model/indexes.rb +12 -0
  378. data/lib/expressir/model/interface_validator.rb +384 -0
  379. data/lib/expressir/model/literals/binary.rb +17 -0
  380. data/lib/expressir/model/literals/integer.rb +17 -0
  381. data/lib/expressir/model/literals/logical.rb +21 -0
  382. data/lib/expressir/model/literals/real.rb +17 -0
  383. data/lib/expressir/model/literals/string.rb +20 -0
  384. data/lib/expressir/model/literals.rb +13 -0
  385. data/lib/expressir/model/model_element.rb +377 -0
  386. data/lib/expressir/model/references/attribute_reference.rb +19 -0
  387. data/lib/expressir/model/references/group_reference.rb +19 -0
  388. data/lib/expressir/model/references/index_reference.rb +23 -0
  389. data/lib/expressir/model/references/simple_reference.rb +21 -0
  390. data/lib/expressir/model/references.rb +12 -0
  391. data/lib/expressir/model/remark_format.rb +17 -0
  392. data/lib/expressir/model/remark_info.rb +92 -0
  393. data/lib/expressir/model/remark_placement.rb +42 -0
  394. data/lib/expressir/model/repository.rb +483 -0
  395. data/lib/expressir/model/repository_validator.rb +293 -0
  396. data/lib/expressir/model/search_engine.rb +551 -0
  397. data/lib/expressir/model/statements/alias.rb +31 -0
  398. data/lib/expressir/model/statements/assignment.rb +23 -0
  399. data/lib/expressir/model/statements/case.rb +42 -0
  400. data/lib/expressir/model/statements/case_action.rb +20 -0
  401. data/lib/expressir/model/statements/compound.rb +21 -0
  402. data/lib/expressir/model/statements/escape.rb +18 -0
  403. data/lib/expressir/model/statements/if.rb +26 -0
  404. data/lib/expressir/model/statements/null.rb +18 -0
  405. data/lib/expressir/model/statements/procedure_call.rb +22 -0
  406. data/lib/expressir/model/statements/repeat.rb +40 -0
  407. data/lib/expressir/model/statements/return.rb +20 -0
  408. data/lib/expressir/model/statements/skip.rb +18 -0
  409. data/lib/expressir/model/statements.rb +20 -0
  410. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +25 -0
  411. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +17 -0
  412. data/lib/expressir/model/supertype_expressions.rb +12 -0
  413. data/lib/expressir/model.rb +39 -0
  414. data/lib/expressir/package/builder.rb +231 -0
  415. data/lib/expressir/package/metadata.rb +79 -0
  416. data/lib/expressir/package/reader.rb +149 -0
  417. data/lib/expressir/package.rb +8 -0
  418. data/lib/expressir/schema_manifest.rb +159 -0
  419. data/lib/expressir/schema_manifest_entry.rb +15 -0
  420. data/lib/expressir/version.rb +8 -0
  421. data/lib/expressir.rb +94 -0
  422. data/lib/tasks/verify_remarks.rake +16 -0
  423. data/rakelib/native.rake +24 -0
  424. data/rakelib/oracle.rake +52 -0
  425. data/rakelib/verify_remarks.rake +16 -0
  426. metadata +692 -0
@@ -0,0 +1,180 @@
1
+ module Expressir
2
+ module Express
3
+ module Formatters
4
+ module ExpressionsFormatter
5
+ def self.included(base)
6
+ base.register_formatter Model::Expressions::AggregateInitializer,
7
+ :format_expressions_aggregate_initializer
8
+ base.register_formatter Model::Expressions::AggregateInitializerItem,
9
+ :format_expressions_aggregate_initializer_item
10
+ base.register_formatter Model::Expressions::BinaryExpression,
11
+ :format_expressions_binary_expression
12
+ base.register_formatter Model::Expressions::EntityConstructor,
13
+ :format_expressions_entity_constructor
14
+ base.register_formatter Model::Expressions::FunctionCall,
15
+ :format_expressions_function_call
16
+ base.register_formatter Model::Expressions::Interval,
17
+ :format_expressions_interval
18
+ base.register_formatter Model::Expressions::QueryExpression,
19
+ :format_expressions_query_expression
20
+ base.register_formatter Model::Expressions::UnaryExpression,
21
+ :format_expressions_unary_expression
22
+ end
23
+
24
+ def format_expressions_aggregate_initializer(node)
25
+ [
26
+ "[",
27
+ Array(node.items).map { |x| format(x) }.join(", "),
28
+ "]",
29
+ ].join
30
+ end
31
+
32
+ def format_expressions_aggregate_initializer_item(node)
33
+ [
34
+ format(node.expression),
35
+ ":",
36
+ format(node.repetition),
37
+ ].join
38
+ end
39
+
40
+ def format_expressions_binary_expression(node)
41
+ operator_precedence = self.class.const_get(:OPERATOR_PRECEDENCE)
42
+ op1_bin_exp = node.operand1.is_a?(Model::Expressions::BinaryExpression) &&
43
+ (operator_precedence[node.operand1.operator] >= operator_precedence[node.operator])
44
+ op2_bin_exp = node.operand2.is_a?(Model::Expressions::BinaryExpression) &&
45
+ (operator_precedence[node.operand2.operator] >= operator_precedence[node.operator])
46
+
47
+ [
48
+ *if op1_bin_exp
49
+ "("
50
+ end,
51
+ format(node.operand1),
52
+ *if op1_bin_exp
53
+ ")"
54
+ end,
55
+ " ",
56
+ case node.operator
57
+ when Model::Expressions::BinaryExpression::ADDITION then "+"
58
+ when Model::Expressions::BinaryExpression::AND then "AND"
59
+ when Model::Expressions::BinaryExpression::COMBINE then "||"
60
+ when Model::Expressions::BinaryExpression::EQUAL then "="
61
+ when Model::Expressions::BinaryExpression::EXPONENTIATION then "**"
62
+ when Model::Expressions::BinaryExpression::GREATER_THAN then ">"
63
+ when Model::Expressions::BinaryExpression::GREATER_THAN_OR_EQUAL then ">="
64
+ when Model::Expressions::BinaryExpression::IN then "IN"
65
+ when Model::Expressions::BinaryExpression::INSTANCE_EQUAL then ":=:"
66
+ when Model::Expressions::BinaryExpression::INSTANCE_NOT_EQUAL then ":<>:"
67
+ when Model::Expressions::BinaryExpression::INTEGER_DIVISION then "DIV"
68
+ when Model::Expressions::BinaryExpression::LESS_THAN then "<"
69
+ when Model::Expressions::BinaryExpression::LESS_THAN_OR_EQUAL then "<="
70
+ when Model::Expressions::BinaryExpression::LIKE then "LIKE"
71
+ when Model::Expressions::BinaryExpression::MODULO then "MOD"
72
+ when Model::Expressions::BinaryExpression::MULTIPLICATION then "*"
73
+ when Model::Expressions::BinaryExpression::NOT_EQUAL then "<>"
74
+ when Model::Expressions::BinaryExpression::OR then "OR"
75
+ when Model::Expressions::BinaryExpression::REAL_DIVISION then "/"
76
+ when Model::Expressions::BinaryExpression::SUBTRACTION then "-"
77
+ when Model::Expressions::BinaryExpression::XOR then "XOR"
78
+ end,
79
+ " ",
80
+ *if op2_bin_exp
81
+ "("
82
+ end,
83
+ format(node.operand2),
84
+ *if op2_bin_exp
85
+ ")"
86
+ end,
87
+ ].join
88
+ end
89
+
90
+ def format_expressions_entity_constructor(node)
91
+ [
92
+ format(node.entity),
93
+ "(",
94
+ Array(node.parameters).map { |x| format(x) }.join(", "),
95
+ ")",
96
+ ].join
97
+ end
98
+
99
+ def format_expressions_function_call(node)
100
+ params = if node.parameters.nil?
101
+ []
102
+ else
103
+ [
104
+ "(",
105
+ node.parameters.map { |x| format(x) }.join(", "),
106
+ ")",
107
+ ]
108
+ end
109
+
110
+ [format(node.function), params].join
111
+ end
112
+
113
+ def format_expressions_interval(node)
114
+ [
115
+ "{",
116
+ format(node.low),
117
+ " ",
118
+ case node.operator1
119
+ when Model::Expressions::Interval::LESS_THAN then "<"
120
+ when Model::Expressions::Interval::LESS_THAN_OR_EQUAL then "<="
121
+ end,
122
+ " ",
123
+ format(node.item),
124
+ " ",
125
+ case node.operator2
126
+ when Model::Expressions::Interval::LESS_THAN then "<"
127
+ when Model::Expressions::Interval::LESS_THAN_OR_EQUAL then "<="
128
+ end,
129
+ " ",
130
+ format(node.high),
131
+ "}",
132
+ ].join
133
+ end
134
+
135
+ def format_expressions_query_expression(node)
136
+ [
137
+ "QUERY",
138
+ "(",
139
+ node.id,
140
+ " ",
141
+ "<*",
142
+ " ",
143
+ format(node.aggregate_source),
144
+ " ",
145
+ "|",
146
+ " ",
147
+ format(node.expression),
148
+ *format_remarks(node).instance_eval do |x|
149
+ x&.length&.positive? ? ["\n", *x, "\n"] : x
150
+ end,
151
+ ")",
152
+ ].join
153
+ end
154
+
155
+ def format_expressions_unary_expression(node)
156
+ needs_parens = node.operand.is_a?(Model::Expressions::BinaryExpression) ||
157
+ node.operand.is_a?(Model::Expressions::Interval)
158
+
159
+ [
160
+ case node.operator
161
+ when Model::Expressions::UnaryExpression::MINUS then "-"
162
+ when Model::Expressions::UnaryExpression::NOT then "NOT"
163
+ when Model::Expressions::UnaryExpression::PLUS then "+"
164
+ end,
165
+ if node.operator == Model::Expressions::UnaryExpression::NOT
166
+ " "
167
+ end,
168
+ *if needs_parens
169
+ "("
170
+ end,
171
+ format(node.operand),
172
+ *if needs_parens
173
+ ")"
174
+ end,
175
+ ].join
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,55 @@
1
+ module Expressir
2
+ module Express
3
+ module Formatters
4
+ module LiteralsFormatter
5
+ def self.included(base)
6
+ base.register_formatter Model::Literals::Binary,
7
+ :format_literals_binary
8
+ base.register_formatter Model::Literals::Integer,
9
+ :format_literals_integer
10
+ base.register_formatter Model::Literals::Logical,
11
+ :format_literals_logical
12
+ base.register_formatter Model::Literals::Real, :format_literals_real
13
+ base.register_formatter Model::Literals::String,
14
+ :format_literals_string
15
+ end
16
+
17
+ def format_literals_binary(node)
18
+ node.value
19
+ end
20
+
21
+ def format_literals_integer(node)
22
+ node.value
23
+ end
24
+
25
+ def format_literals_logical(node)
26
+ case node.value
27
+ when Model::Literals::Logical::TRUE then "TRUE"
28
+ when Model::Literals::Logical::FALSE then "FALSE"
29
+ when Model::Literals::Logical::UNKNOWN then "UNKNOWN"
30
+ end
31
+ end
32
+
33
+ def format_literals_real(node)
34
+ node.value
35
+ end
36
+
37
+ def format_literals_string(node)
38
+ if node.encoded
39
+ [
40
+ "\"",
41
+ node.value,
42
+ "\"",
43
+ ].join
44
+ else
45
+ [
46
+ "'",
47
+ node.value,
48
+ "'",
49
+ ].join
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,53 @@
1
+ module Expressir
2
+ module Express
3
+ module Formatters
4
+ module ReferencesFormatter
5
+ def self.included(base)
6
+ base.register_formatter Model::References::AttributeReference,
7
+ :format_references_attribute_reference
8
+ base.register_formatter Model::References::GroupReference,
9
+ :format_references_group_reference
10
+ base.register_formatter Model::References::IndexReference,
11
+ :format_references_index_reference
12
+ base.register_formatter Model::References::SimpleReference,
13
+ :format_references_simple_reference
14
+ end
15
+
16
+ def format_references_attribute_reference(node)
17
+ [
18
+ format(node.ref),
19
+ ".",
20
+ format(node.attribute),
21
+ ].join
22
+ end
23
+
24
+ def format_references_group_reference(node)
25
+ [
26
+ format(node.ref),
27
+ "\\",
28
+ format(node.entity),
29
+ ].join
30
+ end
31
+
32
+ def format_references_index_reference(node)
33
+ [
34
+ format(node.ref),
35
+ "[",
36
+ format(node.index1),
37
+ *if node.index2
38
+ [
39
+ ":",
40
+ format(node.index2),
41
+ ].join
42
+ end,
43
+ "]",
44
+ ].join
45
+ end
46
+
47
+ def format_references_simple_reference(node)
48
+ node.id
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,270 @@
1
+ module Expressir
2
+ module Express
3
+ module Formatters
4
+ module RemarkFormatter
5
+ def format_remark(node, remark)
6
+ # Handle embedded remarks
7
+ if remark.include?("\n")
8
+ [
9
+ [
10
+ "(*\"",
11
+ node.path || node.id,
12
+ "\"",
13
+ ].join,
14
+ remark,
15
+ "*)",
16
+ ].join("\n")
17
+ elsif node.path.nil? && node.id.include?("IP")
18
+ # Handle immediate informal propositions
19
+ [
20
+ "--",
21
+ node.id,
22
+ " ",
23
+ remark,
24
+ ].join
25
+ else
26
+ # Handle tail remarks
27
+ [
28
+ "--\"",
29
+ node.path || node.id,
30
+ "\" ",
31
+ remark,
32
+ ].join
33
+ end
34
+ end
35
+
36
+ def format_untagged_remark(remark)
37
+ return "" unless remark.is_a?(Model::RemarkInfo)
38
+
39
+ text = remark.text
40
+ return "" if text.nil? || text.empty?
41
+
42
+ formatted_text = remark.tagged? ? "\"#{remark.tag}\" #{text}" : text
43
+
44
+ if remark.tail?
45
+ "-- #{formatted_text}"
46
+ elsif text.include?("\n")
47
+ ["(*", formatted_text, "*)"].join("\n")
48
+ else
49
+ "(* #{formatted_text} *)"
50
+ end
51
+ end
52
+
53
+ def format_inline_tail_remark(node)
54
+ return "" if @no_remarks
55
+ return "" unless node.is_a?(Model::ModelElement)
56
+ return "" if node.untagged_remarks.nil? || node.untagged_remarks.empty?
57
+
58
+ remark = node.untagged_remarks.first
59
+ return "" unless remark.is_a?(Model::RemarkInfo)
60
+
61
+ text = remark.text
62
+ return "" if text.nil? || text.empty?
63
+
64
+ formatted_text = remark.tagged? ? "\"#{remark.tag}\" #{text}" : text
65
+ remark.tail? ? " -- #{formatted_text}" : " (* #{formatted_text} *)"
66
+ end
67
+
68
+ def format_end_scope_remark(node)
69
+ return "" if @no_remarks
70
+ return "" unless node.is_a?(Model::ModelElement)
71
+
72
+ # Only legacy (unplaced) remarks belong after the END_* keyword.
73
+ # Remarks carrying an explicit placement are rendered by the
74
+ # placement-aware emitters, and must not be emitted twice.
75
+ remark = Array(node.untagged_remarks).reject(&:placement).last
76
+ return "" unless remark.is_a?(Model::RemarkInfo)
77
+
78
+ text = remark.text
79
+ return "" if text.nil? || text.empty?
80
+
81
+ # Only output if it's a tail remark (END_* scope remarks are always tail)
82
+ return "" unless remark.tail?
83
+
84
+ formatted_text = remark.tagged? ? "\"#{remark.tag}\" #{text}" : text
85
+ " -- #{formatted_text}"
86
+ end
87
+
88
+ def format_preamble_remark(remark, indent_str = "")
89
+ return "" unless remark.is_a?(Model::RemarkInfo)
90
+
91
+ text = remark.text
92
+ text = "\"#{remark.tag}\" #{text}" if remark.tagged?
93
+
94
+ if remark.tail?
95
+ "#{indent_str}-- #{text}"
96
+ elsif text.include?("\n")
97
+ lines = text.split("\n")
98
+ [
99
+ "#{indent_str}(*",
100
+ *lines.map { |line| "#{indent_str} #{line.strip}" },
101
+ "#{indent_str}*)",
102
+ ].join("\n")
103
+ else
104
+ "#{indent_str}(* #{text} *)"
105
+ end
106
+ end
107
+
108
+ def format_preamble_remarks(node, indent_str = "")
109
+ return nil if @no_remarks
110
+ return nil unless node.is_a?(Model::ModelElement)
111
+ return nil if node.untagged_remarks.nil? || node.untagged_remarks.empty?
112
+
113
+ # For scope containers, exclude the last tail remark as it's the END_* remark
114
+ # but keep all embedded remarks
115
+ is_scope_container = node.is_a?(Model::Declarations::Schema) ||
116
+ node.is_a?(Model::Declarations::Entity) ||
117
+ node.is_a?(Model::Declarations::Type) ||
118
+ node.is_a?(Model::Declarations::Function) ||
119
+ node.is_a?(Model::Declarations::Procedure) ||
120
+ node.is_a?(Model::Declarations::Rule)
121
+
122
+ preamble_remarks = node.untagged_remarks.select do |remark|
123
+ remark.is_a?(Model::RemarkInfo) && !remark.text.nil? && !remark.text.empty?
124
+ end
125
+
126
+ # For scope containers: exclude last remark ONLY if it's a tail remark (END_* remark)
127
+ # Keep all embedded remarks
128
+ if is_scope_container && preamble_remarks.length >= 1
129
+ last_remark = preamble_remarks.last
130
+ # Only exclude if it's a tail remark
131
+ preamble_remarks = preamble_remarks[0..-2] if last_remark.tail?
132
+ end
133
+
134
+ return nil if preamble_remarks.empty?
135
+
136
+ preamble_remarks.map do |remark|
137
+ format_preamble_remark(remark, indent_str)
138
+ end.join("\n")
139
+ end
140
+
141
+ # Remarks that close one body of `node`, emitted just before that
142
+ # body's closing keyword. Only explicit TRAILING remarks for the named
143
+ # region qualify: legacy (nil) remarks keep their historical emission
144
+ # path so old caches render exactly as they did before.
145
+ def format_trailing_region_remarks(node, region)
146
+ return [] if @no_remarks
147
+ return [] unless node.is_a?(Model::ModelElement)
148
+
149
+ Array(node.untagged_remarks).filter_map do |remark|
150
+ next unless remark.trailing_region?(region)
151
+
152
+ formatted = format_untagged_remark(remark)
153
+ formatted unless formatted.empty?
154
+ end
155
+ end
156
+
157
+ # Remarks written after their statement on the same line, which for a
158
+ # single-line statement is where appending puts them back. Opener
159
+ # remarks are excluded: those belong on the first line rather than
160
+ # after the closing keyword, and {#format_opener_remarks} emits them.
161
+ # Mid-keyword remarks (ELSE / OTHERWISE regions) are excluded too:
162
+ # {#format_mid_keyword_remarks} emits them after their keyword.
163
+ def format_inline_statement_remarks(node)
164
+ formatted_inline_remarks(node) { |remark| remark.region.nil? }
165
+ end
166
+
167
+ # Remarks that trailed the opening line of a statement spanning
168
+ # several lines, as in `IF x THEN -- why`. Where they are written back
169
+ # is Formatter#format's business, not this method's.
170
+ def format_opener_remarks(node)
171
+ formatted_inline_remarks(node, &:opener?)
172
+ end
173
+
174
+ # Remarks that trailed a mid-construct keyword of `node` — the ELSE
175
+ # line of an IF, the OTHERWISE line of a CASE — emitted after that
176
+ # keyword, where they were written.
177
+ def format_mid_keyword_remarks(node, region)
178
+ formatted_inline_remarks(node) { |remark| remark.inline_region?(region) }
179
+ end
180
+
181
+ # The inline remarks of a node that the given block accepts, formatted
182
+ # and joined. The callers partition the same collection, so every
183
+ # inline remark is emitted by exactly one of them.
184
+ def formatted_inline_remarks(node, &)
185
+ return "" if @no_remarks
186
+ return "" unless node.is_a?(Model::TakesInlineRemark)
187
+
188
+ Array(node.untagged_remarks).filter_map do |remark|
189
+ next unless remark.inline? && yield(remark)
190
+
191
+ formatted = format_untagged_remark(remark)
192
+ formatted unless formatted.empty?
193
+ end.map { |text| " #{text}" }.join
194
+ end
195
+
196
+ def format_leading_statement_remarks(node)
197
+ return [] if @no_remarks
198
+ return [] unless node.is_a?(Model::Statement)
199
+
200
+ Array(node.untagged_remarks).filter_map do |remark|
201
+ next unless remark.leading?
202
+
203
+ formatted = format_untagged_remark(remark)
204
+ formatted unless formatted.empty?
205
+ end
206
+ end
207
+
208
+ # Block-end emission for ALIAS/REPEAT bodies. Tagged remarks are
209
+ # stored as bare text in node.remarks alongside a mirror of every
210
+ # untagged text (add_remark dual-store), so "genuinely tagged" is
211
+ # derivable only by multiset-subtracting the untagged texts.
212
+ def format_block_end_remarks(node)
213
+ return [] if @no_remarks
214
+
215
+ untagged = Array(node.untagged_remarks)
216
+ remaining = untagged.map(&:text).tally
217
+ tagged = Array(node.remarks).compact.reject do |text|
218
+ next false unless remaining[text]&.positive?
219
+
220
+ remaining[text] -= 1
221
+ true
222
+ end
223
+
224
+ [
225
+ *tagged.map { |text| format_remark(node, text) },
226
+ # Leading and inline remarks are emitted by their own paths;
227
+ # including them here would render them a second time.
228
+ *untagged.reject { |r| r.leading? || r.inline? }
229
+ .filter_map do |remark|
230
+ formatted = format_untagged_remark(remark)
231
+ formatted unless formatted.empty?
232
+ end,
233
+ ]
234
+ end
235
+
236
+ def format_remarks(node)
237
+ remarks = []
238
+
239
+ # Add tagged remarks
240
+ if node.is_a?(Model::HasRemarks) && !@no_remarks &&
241
+ !node.remarks.nil?
242
+ remarks.concat(node.remarks.compact.map do |remark|
243
+ format_remark(node, remark)
244
+ end)
245
+ end
246
+
247
+ # Skip untagged remarks for nodes that handle them separately
248
+ skip_untagged = node.is_a?(Model::Declarations::Attribute) ||
249
+ node.is_a?(Model::DataTypes::EnumerationItem) ||
250
+ node.is_a?(Model::Declarations::Schema) ||
251
+ node.is_a?(Model::Declarations::Entity) ||
252
+ node.is_a?(Model::Declarations::Type) ||
253
+ node.is_a?(Model::Declarations::Function) ||
254
+ node.is_a?(Model::Declarations::Procedure) ||
255
+ node.is_a?(Model::Declarations::Rule)
256
+
257
+ # Add untagged remarks only for nodes that don't handle them specially
258
+ if !skip_untagged && node.is_a?(Model::ModelElement) && !@no_remarks &&
259
+ !node.untagged_remarks.nil?
260
+ remarks.concat(node.untagged_remarks.map do |remark|
261
+ format_untagged_remark(remark)
262
+ end)
263
+ end
264
+
265
+ remarks
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,28 @@
1
+ module Expressir
2
+ module Express
3
+ module Formatters
4
+ module RemarkItemFormatter
5
+ def self.included(base)
6
+ base.register_formatter Model::Declarations::RemarkItem,
7
+ :format_remark_item
8
+ end
9
+
10
+ def format_remark_item(node)
11
+ return "" unless node.remarks&.any?
12
+
13
+ # Check if any remark contains newlines
14
+ has_newlines = node.remarks.any? { |r| r.to_s.include?("\n") }
15
+
16
+ if has_newlines
17
+ # Multi-line format: (*"path" remarks *)
18
+ remarks_text = node.remarks.join("\n")
19
+ "(*\"#{node.path}\"\n#{remarks_text}\n*)"
20
+ else
21
+ # Single-line format: --"path"
22
+ "--\"#{node.path}\""
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end