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,551 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Expressir
4
+ module Model
5
+ # SearchEngine for querying EXPRESS elements in a repository
6
+ # Handles pattern matching, wildcards, regex, and element collection
7
+ class SearchEngine
8
+ # Element types that can be searched
9
+ ELEMENT_TYPES = %w[
10
+ schema entity type attribute derived_attribute inverse_attribute
11
+ function procedure rule constant parameter variable
12
+ where_rule unique_rule enumeration_item interface
13
+ ].freeze
14
+
15
+ # Type categories for filtering
16
+ TYPE_CATEGORIES = %w[select enumeration aggregate defined].freeze
17
+
18
+ attr_reader :repository
19
+
20
+ # Initialize search engine with a repository
21
+ # @param repository [Repository] Repository to search
22
+ def initialize(repository)
23
+ @repository = repository
24
+ @repository.build_indexes if @repository.entity_index.nil?
25
+ end
26
+
27
+ # List all elements of a specific type
28
+ # @param type [String] Element type to list
29
+ # @param schema [String, nil] Filter by schema name
30
+ # @param category [String, nil] Type category filter (for type elements)
31
+ # @return [Array<Hash>] List of elements
32
+ def list(type:, schema: nil, category: nil)
33
+ elements = collect_elements(type: type, schema: schema,
34
+ category: category)
35
+ elements.map { |elem| element_to_hash(elem, type) }
36
+ end
37
+
38
+ # Search for elements matching a pattern
39
+ # @param pattern [String] Search pattern
40
+ # @param type [String, nil] Filter by element type
41
+ # @param schema [String, nil] Limit to specific schema
42
+ # @param category [String, nil] Type category filter
43
+ # @param case_sensitive [Boolean] Enable case-sensitive matching
44
+ # @param regex [Boolean] Treat pattern as regex
45
+ # @param exact [Boolean] Exact match only
46
+ # @return [Array<Hash>] Matching elements
47
+ def search(pattern:, type: nil, schema: nil, category: nil,
48
+ case_sensitive: false, regex: false, exact: false)
49
+ # Parse pattern
50
+ pattern_parts = parse_pattern(pattern, case_sensitive: case_sensitive)
51
+
52
+ # Determine types to search
53
+ types_to_search = type ? [type] : ELEMENT_TYPES
54
+
55
+ # Collect all matching elements
56
+ results = []
57
+ types_to_search.each do |elem_type|
58
+ elements = collect_elements(type: elem_type, schema: schema,
59
+ category: category)
60
+
61
+ elements.each do |elem|
62
+ if matches_pattern?(elem, pattern_parts, elem_type,
63
+ case_sensitive: case_sensitive,
64
+ regex: regex, exact: exact)
65
+ results << element_to_hash(elem, elem_type)
66
+ end
67
+ end
68
+ end
69
+
70
+ results
71
+ end
72
+
73
+ # Count elements matching criteria
74
+ # @param type [String] Element type
75
+ # @param schema [String, nil] Filter by schema
76
+ # @param category [String, nil] Type category filter
77
+ # @return [Integer] Count of elements
78
+ def count(type:, schema: nil, category: nil)
79
+ collect_elements(type: type, schema: schema, category: category).size
80
+ end
81
+
82
+ # Search with depth filtering
83
+ # @param pattern [String] Search pattern
84
+ # @param max_depth [Integer] Maximum path depth (1=schema, 2=entity, 3=attribute)
85
+ # @param options [Hash] Additional search options
86
+ # @return [Array<Hash>] Filtered results
87
+ def search_with_depth(pattern:, max_depth:, **)
88
+ return [] if max_depth <= 0
89
+
90
+ results = search(pattern: pattern, **)
91
+ filter_by_depth(results, max_depth)
92
+ end
93
+
94
+ # Search with relevance ranking
95
+ # @param pattern [String] Search pattern
96
+ # @param boost_exact [Integer] Score boost for exact matches
97
+ # @param boost_prefix [Integer] Score boost for prefix matches
98
+ # @param options [Hash] Additional search options
99
+ # @return [Array<Hash>] Ranked results with :relevance_score
100
+ def search_ranked(pattern:, boost_exact: 10, boost_prefix: 5, **)
101
+ results = search(pattern: pattern, **)
102
+ rank_results(results, pattern, boost_exact, boost_prefix)
103
+ end
104
+
105
+ # Advanced search with multiple filters
106
+ # @param pattern [String] Search pattern
107
+ # @param max_depth [Integer, nil] Maximum path depth
108
+ # @param ranked [Boolean] Enable relevance ranking
109
+ # @param options [Hash] Additional filters and search options
110
+ # @return [Array<Hash>] Filtered and optionally ranked results
111
+ def search_advanced(pattern:, max_depth: nil, ranked: false, **)
112
+ results = search(pattern: pattern, **)
113
+
114
+ results = filter_by_depth(results, max_depth) if max_depth
115
+ results = rank_results(results, pattern, 10, 5) if ranked
116
+
117
+ results
118
+ end
119
+
120
+ private
121
+
122
+ # Parse search pattern into components
123
+ # @param pattern [String] Pattern to parse
124
+ # @param case_sensitive [Boolean] Case sensitivity
125
+ # @return [Hash] Parsed pattern with parts
126
+ def parse_pattern(pattern, case_sensitive: false)
127
+ normalized = case_sensitive ? pattern : pattern.downcase
128
+ parts = normalized.split(".")
129
+
130
+ {
131
+ raw: pattern,
132
+ normalized: normalized,
133
+ parts: parts,
134
+ schema_part: parts[0],
135
+ element_parts: parts[1..] || [],
136
+ }
137
+ end
138
+
139
+ # Check if element matches pattern
140
+ # @param element [ModelElement] Element to check
141
+ # @param pattern_parts [Hash] Parsed pattern
142
+ # @param element_type [String] Type of element
143
+ # @param case_sensitive [Boolean] Case sensitivity
144
+ # @param regex [Boolean] Use regex matching
145
+ # @param exact [Boolean] Exact match only
146
+ # @return [Boolean] True if matches
147
+ def matches_pattern?(element, pattern_parts, _element_type,
148
+ case_sensitive: false, regex: false, exact: false)
149
+ # Duck typing - check if element responds to path/id
150
+ element_path = begin
151
+ element.path
152
+ rescue StandardError
153
+ element.id
154
+ end
155
+ return false unless element_path
156
+
157
+ element_id = begin
158
+ element.id
159
+ rescue StandardError
160
+ nil
161
+ end
162
+
163
+ search_path = case_sensitive ? element_path : element_path.downcase
164
+ search_id = element_id && !case_sensitive ? element_id.downcase : element_id
165
+ pattern = pattern_parts[:normalized]
166
+
167
+ if regex
168
+ match_regex(search_path,
169
+ pattern) || (search_id && match_regex(search_id, pattern))
170
+ elsif exact
171
+ search_path == pattern
172
+ elsif pattern_parts[:parts].size == 1
173
+ # For simple patterns (no dots or single part), also match against just the element ID
174
+ match_wildcard(search_path, pattern_parts) ||
175
+ (search_id && match_part(search_id, pattern))
176
+ else
177
+ match_wildcard(search_path, pattern_parts)
178
+ end
179
+ end
180
+
181
+ # Match using regex
182
+ # @param path [String] Element path
183
+ # @param pattern [String] Regex pattern
184
+ # @return [Boolean] True if matches
185
+ def match_regex(path, pattern)
186
+ Regexp.new(pattern).match?(path)
187
+ rescue RegexpError
188
+ false
189
+ end
190
+
191
+ # Match using wildcard pattern
192
+ # @param path [String] Element path
193
+ # @param pattern_parts [Hash] Parsed pattern
194
+ # @return [Boolean] True if matches
195
+ def match_wildcard(path, pattern_parts)
196
+ path_parts = path.split(".")
197
+ pattern_array = pattern_parts[:parts]
198
+
199
+ # Handle different wildcard scenarios
200
+ match_wildcard_parts(path_parts, pattern_array)
201
+ end
202
+
203
+ # Match path parts against pattern parts with wildcards
204
+ # @param path_parts [Array<String>] Path components
205
+ # @param pattern_parts [Array<String>] Pattern components
206
+ # @return [Boolean] True if matches
207
+ def match_wildcard_parts(path_parts, pattern_parts)
208
+ # If pattern has no wildcards and different length, no match
209
+ unless pattern_parts.include?("*")
210
+ return false if path_parts.size != pattern_parts.size
211
+
212
+ return path_parts.zip(pattern_parts).all? do |path_part, pattern_part|
213
+ match_part(path_part, pattern_part)
214
+ end
215
+ end
216
+
217
+ # Handle wildcards
218
+ match_with_wildcards(path_parts, pattern_parts)
219
+ end
220
+
221
+ # Match individual part with potential prefix/suffix wildcards
222
+ # @param part [String] Path part
223
+ # @param pattern [String] Pattern part
224
+ # @return [Boolean] True if matches
225
+ def match_part(part, pattern)
226
+ return true if pattern == "*"
227
+
228
+ if pattern.include?("*")
229
+ # Convert wildcard to regex
230
+ regex_pattern = "^#{Regexp.escape(pattern).gsub('\\*', '.*')}$"
231
+ Regexp.new(regex_pattern).match?(part)
232
+ else
233
+ # Support substring matching for simple patterns
234
+ part.include?(pattern)
235
+ end
236
+ end
237
+
238
+ # Match path with wildcard patterns
239
+ # @param path_parts [Array<String>] Path components
240
+ # @param pattern_parts [Array<String>] Pattern components with wildcards
241
+ # @return [Boolean] True if matches
242
+ def match_with_wildcards(path_parts, pattern_parts)
243
+ # Simple implementation: match each level
244
+ # If pattern is shorter but has *, try to match flexibly
245
+
246
+ pi = 0 # pattern index
247
+ li = 0 # path index
248
+
249
+ while pi < pattern_parts.size && li < path_parts.size
250
+ if pattern_parts[pi] == "*"
251
+ # Wildcard matches one element
252
+ pi += 1
253
+ li += 1
254
+ elsif match_part(path_parts[li], pattern_parts[pi])
255
+ pi += 1
256
+ li += 1
257
+ else
258
+ return false
259
+ end
260
+ end
261
+
262
+ # Check if we consumed both arrays
263
+ pi == pattern_parts.size && li == path_parts.size
264
+ end
265
+
266
+ # Collect elements of a specific type
267
+ # @param type [String] Element type
268
+ # @param schema [String, nil] Schema filter
269
+ # @param category [String, nil] Category filter
270
+ # @return [Array<ModelElement>] Collected elements
271
+ def collect_elements(type:, schema: nil, category: nil)
272
+ # Guard against nil schemas collection
273
+ return [] unless @repository.schemas
274
+
275
+ schemas_to_search = if schema
276
+ [@repository.schemas.find do |s|
277
+ s.id == schema
278
+ end].compact
279
+ else
280
+ @repository.schemas
281
+ end
282
+
283
+ case type
284
+ when "schema"
285
+ schemas_to_search
286
+ when "entity"
287
+ collect_from_schemas(schemas_to_search, :entities)
288
+ when "type"
289
+ types = collect_from_schemas(schemas_to_search, :types)
290
+ category ? filter_types_by_category(types, category) : types
291
+ when "attribute"
292
+ collect_attributes(schemas_to_search)
293
+ when "derived_attribute"
294
+ collect_derived_attributes(schemas_to_search)
295
+ when "inverse_attribute"
296
+ collect_inverse_attributes(schemas_to_search)
297
+ when "function"
298
+ collect_from_schemas(schemas_to_search, :functions)
299
+ when "procedure"
300
+ collect_from_schemas(schemas_to_search, :procedures)
301
+ when "rule"
302
+ collect_from_schemas(schemas_to_search, :rules)
303
+ when "constant"
304
+ collect_from_schemas(schemas_to_search, :constants)
305
+ when "parameter"
306
+ collect_parameters(schemas_to_search)
307
+ when "variable"
308
+ collect_variables(schemas_to_search)
309
+ when "where_rule"
310
+ collect_where_rules(schemas_to_search)
311
+ when "unique_rule"
312
+ collect_unique_rules(schemas_to_search)
313
+ when "enumeration_item"
314
+ collect_enumeration_items(schemas_to_search)
315
+ when "interface"
316
+ collect_from_schemas(schemas_to_search, :interfaces)
317
+ else
318
+ []
319
+ end
320
+ end
321
+
322
+ # Collect elements from schemas using a method
323
+ # @param schemas [Array<Schema>] Schemas to search
324
+ # @param method [Symbol] Method to call on schema
325
+ # @return [Array] Collected elements
326
+ def collect_from_schemas(schemas, method)
327
+ # Guard against nil schemas array
328
+ return [] unless schemas
329
+
330
+ schemas.flat_map { |s| s.public_send(method) || [] }
331
+ end
332
+
333
+ # Collect all attributes from entities
334
+ # @param schemas [Array<Schema>] Schemas to search
335
+ # @return [Array<Attribute>] All attributes
336
+ def collect_attributes(schemas)
337
+ # Guard against nil schemas
338
+ return [] unless schemas
339
+
340
+ entities = collect_from_schemas(schemas, :entities)
341
+ entities.flat_map { |e| e.attributes || [] }.select do |attr|
342
+ !attr.is_a?(Declarations::DerivedAttribute) &&
343
+ !attr.is_a?(Declarations::InverseAttribute)
344
+ end
345
+ end
346
+
347
+ # Collect derived attributes from entities
348
+ # @param schemas [Array<Schema>] Schemas to search
349
+ # @return [Array<DerivedAttribute>] Derived attributes
350
+ def collect_derived_attributes(schemas)
351
+ # Guard against nil schemas
352
+ return [] unless schemas
353
+
354
+ entities = collect_from_schemas(schemas, :entities)
355
+ entities.flat_map { |e| e.attributes || [] }.grep(Declarations::DerivedAttribute)
356
+ end
357
+
358
+ # Collect inverse attributes from entities
359
+ # @param schemas [Array<Schema>] Schemas to search
360
+ # @return [Array<InverseAttribute>] Inverse attributes
361
+ def collect_inverse_attributes(schemas)
362
+ # Guard against nil schemas
363
+ return [] unless schemas
364
+
365
+ entities = collect_from_schemas(schemas, :entities)
366
+ entities.flat_map { |e| e.attributes || [] }.grep(Declarations::InverseAttribute)
367
+ end
368
+
369
+ # Collect parameters from functions and procedures
370
+ # @param schemas [Array<Schema>] Schemas to search
371
+ # @return [Array<Parameter>] All parameters
372
+ def collect_parameters(schemas)
373
+ # Guard against nil schemas
374
+ return [] unless schemas
375
+
376
+ functions = collect_from_schemas(schemas, :functions)
377
+ procedures = collect_from_schemas(schemas, :procedures)
378
+ (functions + procedures).flat_map { |f| f.parameters || [] }
379
+ end
380
+
381
+ # Collect variables from functions and procedures
382
+ # @param schemas [Array<Schema>] Schemas to search
383
+ # @return [Array<Variable>] All variables
384
+ def collect_variables(schemas)
385
+ # Guard against nil schemas
386
+ return [] unless schemas
387
+
388
+ functions = collect_from_schemas(schemas, :functions)
389
+ procedures = collect_from_schemas(schemas, :procedures)
390
+ (functions + procedures).flat_map { |f| f.variables || [] }
391
+ end
392
+
393
+ # Collect where rules from entities and types
394
+ # @param schemas [Array<Schema>] Schemas to search
395
+ # @return [Array<WhereRule>] All where rules
396
+ def collect_where_rules(schemas)
397
+ # Guard against nil schemas
398
+ return [] unless schemas
399
+
400
+ entities = collect_from_schemas(schemas, :entities)
401
+ types = collect_from_schemas(schemas, :types)
402
+ (entities + types).flat_map { |e| e.where_rules || [] }
403
+ end
404
+
405
+ # Collect unique rules from entities
406
+ # @param schemas [Array<Schema>] Schemas to search
407
+ # @return [Array<UniqueRule>] All unique rules
408
+ def collect_unique_rules(schemas)
409
+ # Guard against nil schemas
410
+ return [] unless schemas
411
+
412
+ entities = collect_from_schemas(schemas, :entities)
413
+ entities.flat_map { |e| e.unique_rules || [] }
414
+ end
415
+
416
+ # Collect enumeration items from enumeration types
417
+ # @param schemas [Array<Schema>] Schemas to search
418
+ # @return [Array<EnumerationItem>] All enumeration items
419
+ def collect_enumeration_items(schemas)
420
+ # Guard against nil schemas
421
+ return [] unless schemas
422
+
423
+ types = collect_from_schemas(schemas, :types)
424
+ types.flat_map { |t| t.enumeration_items || [] }
425
+ end
426
+
427
+ # Filter types by category
428
+ # @param types [Array<Type>] Types to filter
429
+ # @param category [String] Category to filter by
430
+ # @return [Array<Type>] Filtered types
431
+ def filter_types_by_category(types, category)
432
+ types.select do |type|
433
+ @repository.type_index.categorize(type) == category
434
+ end
435
+ end
436
+
437
+ # Convert element to hash representation
438
+ # @param element [ModelElement] Element to convert
439
+ # @param type [String] Element type
440
+ # @return [Hash] Element data
441
+ def element_to_hash(element, type)
442
+ # Duck typing - try to get id/path from element
443
+ element_id = begin
444
+ element.id
445
+ rescue StandardError
446
+ nil
447
+ end
448
+
449
+ element_path = begin
450
+ element.path
451
+ rescue StandardError
452
+ nil
453
+ end
454
+
455
+ hash = {
456
+ id: element_id,
457
+ type: type,
458
+ path: element_path,
459
+ }
460
+
461
+ # Add schema for non-schema elements
462
+ if type != "schema"
463
+ begin
464
+ if element.parent
465
+ schema = find_parent_schema(element)
466
+ hash[:schema] = schema.id if schema
467
+ end
468
+ rescue StandardError
469
+ # Element doesn't have parent or parent chain
470
+ end
471
+ end
472
+
473
+ # Add category for types
474
+ if type == "type"
475
+ hash[:category] = @repository.type_index.categorize(element)
476
+ end
477
+
478
+ hash
479
+ end
480
+
481
+ # Find parent schema of an element
482
+ # @param element [ModelElement] Element to find schema for
483
+ # @return [Schema, nil] Parent schema
484
+ def find_parent_schema(element)
485
+ current = element
486
+ while current
487
+ return current if current.is_a?(Declarations::Schema)
488
+
489
+ current = current.parent
490
+ end
491
+ rescue StandardError
492
+ # Handle objects that don't fully implement the interface
493
+ nil
494
+ end
495
+
496
+ # Filter results by maximum path depth
497
+ # @param results [Array<Hash>] Search results
498
+ # @param max_depth [Integer] Maximum depth
499
+ # @return [Array<Hash>] Filtered results
500
+ def filter_by_depth(results, max_depth)
501
+ results.select do |result|
502
+ next true unless result[:path]
503
+
504
+ result[:path].split(".").size <= max_depth
505
+ end
506
+ end
507
+
508
+ # Rank results by relevance
509
+ # @param results [Array<Hash>] Search results
510
+ # @param pattern [String] Search pattern
511
+ # @param boost_exact [Integer] Exact match boost
512
+ # @param boost_prefix [Integer] Prefix match boost
513
+ # @return [Array<Hash>] Sorted results with scores
514
+ def rank_results(results, pattern, boost_exact, boost_prefix)
515
+ normalized_pattern = pattern.downcase
516
+
517
+ results.map do |result|
518
+ score = calculate_relevance_score(result, normalized_pattern,
519
+ boost_exact, boost_prefix)
520
+ result.merge(relevance_score: score)
521
+ end.sort_by { |r| -r[:relevance_score] }
522
+ end
523
+
524
+ # Calculate relevance score for a result
525
+ # @param result [Hash] Search result
526
+ # @param pattern [String] Normalized search pattern
527
+ # @param boost_exact [Integer] Exact match boost
528
+ # @param boost_prefix [Integer] Prefix match boost
529
+ # @return [Integer] Relevance score
530
+ def calculate_relevance_score(result, pattern, boost_exact, boost_prefix)
531
+ score = 0
532
+ id = (result[:id] || "").downcase
533
+
534
+ # Exact match gets highest score
535
+ score += boost_exact if id == pattern
536
+
537
+ # Prefix match gets medium score
538
+ score += boost_prefix if id.start_with?(pattern)
539
+
540
+ # Shorter paths rank higher (max 10 points)
541
+ path_depth = result[:path]&.split(".")&.size || 1
542
+ score += [10 - path_depth, 0].max
543
+
544
+ # Schema-level results rank higher
545
+ score += 5 if result[:type] == "schema"
546
+
547
+ score
548
+ end
549
+ end
550
+ end
551
+ end
@@ -0,0 +1,31 @@
1
+ module Expressir
2
+ module Model
3
+ module Statements
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 13.2 Alias statement
6
+ class Alias < ModelElement
7
+ include Statement
8
+ include Identifier
9
+
10
+ collection_attributes :statements
11
+ attribute :expression, ModelElement
12
+ attribute :statements, ModelElement, collection: true
13
+ attribute :_class, :string, default: -> { self.class.name }
14
+
15
+ key_value do
16
+ map "_class", to: :_class, render_default: true
17
+ map "expression", to: :expression
18
+ map "statements", to: :statements
19
+ end
20
+
21
+ # @return [Array<Declaration>]
22
+ def children
23
+ [
24
+ self,
25
+ *remark_items,
26
+ ]
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module Expressir
2
+ module Model
3
+ module Statements
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 13.3 Assignment
6
+ class Assignment < ModelElement
7
+ include Statement
8
+
9
+ child_attributes :expression
10
+ attribute :ref, ModelElement
11
+ attribute :expression, ModelElement
12
+ attribute :_class, :string, default: -> { self.class.name }
13
+
14
+ key_value do
15
+ map "_class", to: :_class, render_default: true
16
+ map "untagged_remarks", to: :untagged_remarks
17
+ map "ref", to: :ref
18
+ map "expression", to: :expression
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ module Expressir
2
+ module Model
3
+ module Statements
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 13.4 Case statement
6
+ class Case < ModelElement
7
+ include Statement
8
+
9
+ # The executable bodies of a CASE, exposed as ordered statement
10
+ # lists. Tree-walkers traverse these rather than `actions`, because
11
+ # a CaseAction is a label wrapper the parser gives no usable source
12
+ # position — the statement inside it carries the position that
13
+ # matters for placing comments.
14
+ collection_attributes :action_statements, :otherwise_statements
15
+
16
+ child_attributes :expression
17
+ attribute :expression, ModelElement
18
+ attribute :actions, CaseAction, collection: true
19
+ attribute :otherwise_statement, ModelElement
20
+ attribute :_class, :string, default: -> { self.class.name }
21
+
22
+ # @return [Array<ModelElement>] each action's statement, in order
23
+ def action_statements
24
+ Array(actions).filter_map(&:statement)
25
+ end
26
+
27
+ # @return [Array<ModelElement>] the OTHERWISE body, if present
28
+ def otherwise_statements
29
+ [otherwise_statement].compact
30
+ end
31
+
32
+ key_value do
33
+ map "_class", to: :_class, render_default: true
34
+ map "untagged_remarks", to: :untagged_remarks
35
+ map "expression", to: :expression
36
+ map "actions", to: :actions
37
+ map "otherwise_statement", to: :otherwise_statement
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,20 @@
1
+ module Expressir
2
+ module Model
3
+ module Statements
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 13.4 Case statement
6
+ class CaseAction < ModelElement
7
+ child_attributes :expression
8
+ attribute :labels, ModelElement, collection: true
9
+ attribute :statement, ModelElement
10
+ attribute :_class, :string, default: -> { self.class.name }
11
+
12
+ key_value do
13
+ map "_class", to: :_class, render_default: true
14
+ map "labels", to: :labels
15
+ map "statement", to: :statement
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module Expressir
2
+ module Model
3
+ module Statements
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 13.5 Compound statement
6
+ class Compound < ModelElement
7
+ include Statement
8
+
9
+ collection_attributes :statements
10
+ attribute :statements, ModelElement, collection: true
11
+ attribute :_class, :string, default: -> { self.class.name }
12
+
13
+ key_value do
14
+ map "_class", to: :_class, render_default: true
15
+ map "untagged_remarks", to: :untagged_remarks
16
+ map "statements", to: :statements
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end