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.
- checksums.yaml +7 -0
- data/.cargo/config.toml +3 -0
- data/.github/scripts/test_installed_gem.rb +34 -0
- data/.github/workflows/codeql.yml +35 -0
- data/.github/workflows/docs.yml +99 -0
- data/.github/workflows/links.yml +100 -0
- data/.github/workflows/native-gems.yml +201 -0
- data/.github/workflows/rake.yml +19 -0
- data/.github/workflows/release.yml +37 -0
- data/.github/workflows/rust-ext.yml +41 -0
- data/.github/workflows/stress.yml +36 -0
- data/.github/workflows/validate_schemas.yml +48 -0
- data/.github/workflows/verify_remarks.yml +33 -0
- data/.gitignore +55 -0
- data/.hound.yml +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +297 -0
- data/CHANGELOG.md +159 -0
- data/Gemfile +18 -0
- data/README.adoc +2783 -0
- data/Rakefile +41 -0
- data/TODO.bugs/01-stale-transformer-autoload.md +39 -0
- data/TODO.bugs/02-parser-class-instance-vars.md +36 -0
- data/TODO.bugs/03-builder-mutable-state.md +43 -0
- data/TODO.bugs/04-formatter-public-send-dispatch.md +53 -0
- data/TODO.bugs/05-anonymous-formatter-subclass.md +45 -0
- data/TODO.bugs/06-collection-registry-single-source.md +53 -0
- data/TODO.bugs/07-require-relative-cleanup.md +42 -0
- data/TODO.bugs/08-require-expressir-in-commands.md +34 -0
- data/TODO.bugs/09-parser-split.md +53 -0
- data/TODO.bugs/10-to-s-override.md +42 -0
- data/TODO.bugs/11-parser-class-variables.md +39 -0
- data/TODO.bugs/12-marker-modules-vs-registry.md +64 -0
- data/TODO.bugs/13-string-literal-scanner-limitation.md +52 -0
- data/TODO.bugs/14-model-formatting-leak.md +30 -0
- data/TODO.bugs/15-expression-children-macro.md +27 -0
- data/TODO.bugs/16-pretty-formatter-duplication.md +28 -0
- data/TODO.bugs/17-snake-case-cache-mutable-constant.md +28 -0
- data/TODO.bugs/18-const-get-private-constants.md +30 -0
- data/TODO.bugs/19-format-methods-public.md +22 -0
- data/TODO.bugs/20-coverage-nested-entities-dedup.md +20 -0
- data/TODO.bugs/21-operator-tokens-secondary-dispatch.md +21 -0
- data/TODO.bugs/22-builder-fast-path-wrappers.md +32 -0
- data/TODO.bugs/23-coverage-inverse-maps.md +21 -0
- data/TODO.bugs/24-streaming-builder-complexity.md +19 -0
- data/TODO.bugs/25-debug-puts-in-production.md +21 -0
- data/TODO.bugs/26-generic-entity-children-misplaced.md +21 -0
- data/TODO.bugs/27-package-build-god-method.md +19 -0
- data/TODO.bugs/28-package-god-class.md +30 -0
- data/TODO.bugs/29-validate-ascii-god-class.md +24 -0
- data/TODO.bugs/30-unicode-map-extraction.md +19 -0
- data/TODO.bugs/README.md +43 -0
- data/TODO.max-perf/01-restore-ci-green.md +36 -0
- data/TODO.max-perf/02-streaming-parse-path.md +31 -0
- data/TODO.max-perf/03-cli-parallel-opt-in.md +27 -0
- data/TODO.max-perf/04-benchmark-harness.md +28 -0
- data/TODO.max-perf/05-parallel-fidelity-specs.md +22 -0
- data/TODO.max-perf/06-builder-cpu-audit.md +41 -0
- data/TODO.max-perf/07-upstream-parsanol-roadmap.md +27 -0
- data/TODO.max-perf/08-builder-build-perf.md +45 -0
- data/TODO.max-perf/09-grammar-cold-start.md +25 -0
- data/TODO.max-perf/10-parser-facade-hygiene.md +23 -0
- data/TODO.max-perf/11-ci-green-closeout.md +25 -0
- data/TODO.max-perf/12-require-boot-profile.md +25 -0
- data/TODO.max-perf/13-key-conversion-specs.md +26 -0
- data/TODO.max-perf/14-builder-call-handler-audit.md +28 -0
- data/TODO.parity-ee/00-overview.md +76 -0
- data/TODO.parity-ee/01-annex-g-rule-extraction.md +41 -0
- data/TODO.parity-ee/02-eeng-algorithm-inventory.md +8 -0
- data/TODO.parity-ee/03-eeng-oracle-harness.md +33 -0
- data/TODO.parity-ee/04-shtolo-concatenate.md +44 -0
- data/TODO.parity-ee/05-shtolo-longform-flatten.md +53 -0
- data/TODO.parity-ee/06-interface-scheduling-parity.md +47 -0
- data/TODO.parity-ee/07-semantic-checks-port.md +35 -0
- data/TODO.parity-ee/08-pretty-roundtrip-gate.md +27 -0
- data/TODO.parity-ee/09-smrl-index-and-listing.md +22 -0
- data/TODO.parity-ee/10-interface-dot-graph.md +21 -0
- data/TODO.parity-ee/11-import-eeng-tests.md +79 -0
- data/TODO.parity-ee/12-full-check-catalog.md +67 -0
- data/TODO.parity-ee/13-population-p21.md +54 -0
- data/TODO.parity-ee/14-shtolo-completion.md +44 -0
- data/TODO.parity-ee/15-part28-xml.md +51 -0
- data/TODO.parity-ee/16-compare-patch.md +48 -0
- data/TODO.parity-ee/17-official-tests.md +42 -0
- data/TODO.parity-ee/18-mim-mapping.md +47 -0
- data/TODO.parity-ee/19-architecture.md +97 -0
- data/TODO.parity-ee/parity-matrix.md +108 -0
- data/TODO.refpath-v2/00-overview.md +64 -0
- data/TODO.suma-improvements/00-overview.md +23 -0
- data/TODO.suma-improvements/01-prebuilt-platform-gems.md +33 -0
- data/TODO.suma-improvements/02-suma-e2e.md +39 -0
- data/TODO.suma-improvements/03-item-graph.md +22 -0
- data/TODO.suma-improvements/04-compiled-set-default.md +16 -0
- data/TODO.suma-improvements/05-validation-in-docs.md +17 -0
- data/TODO.suma-improvements/06-memory-remeasure.md +36 -0
- data/TODO.suma-improvements/07-part28-xml.md +15 -0
- data/TODO.suma-improvements/08-windows-gnu-toolchain.md +15 -0
- data/TODO.suma-improvements/09-checker-tranche3.md +13 -0
- data/TODO.suma-improvements/10-expressdoc.md +8 -0
- data/benchmark/srl_benchmark.rb +458 -0
- data/benchmark/srl_native_benchmark.rb +146 -0
- data/benchmark/srl_ruby_benchmark.rb +132 -0
- data/bin/console +11 -0
- data/bin/rspec +30 -0
- data/bin/setup +8 -0
- data/docs/Gemfile +12 -0
- data/docs/_config.yml +141 -0
- data/docs/_guides/changes/changes-format.adoc +778 -0
- data/docs/_guides/changes/importing-eengine.adoc +898 -0
- data/docs/_guides/changes/index.adoc +396 -0
- data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
- data/docs/_guides/changes/validating-changes.adoc +681 -0
- data/docs/_guides/cli/benchmark-performance.adoc +834 -0
- data/docs/_guides/cli/coverage-analysis.adoc +921 -0
- data/docs/_guides/cli/format-schemas.adoc +547 -0
- data/docs/_guides/cli/index.adoc +8 -0
- data/docs/_guides/cli/managing-changes.adoc +927 -0
- data/docs/_guides/cli/validate-ascii.adoc +645 -0
- data/docs/_guides/cli/validate-schemas.adoc +534 -0
- data/docs/_guides/formatter/formatter-architecture.adoc +401 -0
- data/docs/_guides/index.adoc +165 -0
- data/docs/_guides/ler/creating-packages.adoc +664 -0
- data/docs/_guides/ler/index.adoc +305 -0
- data/docs/_guides/ler/loading-packages.adoc +707 -0
- data/docs/_guides/ler/package-formats.adoc +748 -0
- data/docs/_guides/ler/querying-packages.adoc +826 -0
- data/docs/_guides/ler/step-packages.adoc +385 -0
- data/docs/_guides/ler/validating-packages.adoc +750 -0
- data/docs/_guides/liquid/basic-templates.adoc +813 -0
- data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
- data/docs/_guides/liquid/drops-reference.adoc +829 -0
- data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
- data/docs/_guides/liquid/index.adoc +468 -0
- data/docs/_guides/manifests/creating-manifests.adoc +483 -0
- data/docs/_guides/manifests/index.adoc +307 -0
- data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
- data/docs/_guides/manifests/validating-manifests.adoc +713 -0
- data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
- data/docs/_guides/ruby-api/index.adoc +257 -0
- data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
- data/docs/_guides/ruby-api/search-engine.adoc +609 -0
- data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
- data/docs/_pages/data-model.adoc +665 -0
- data/docs/_pages/express-language.adoc +506 -0
- data/docs/_pages/getting-started.adoc +414 -0
- data/docs/_pages/index.adoc +116 -0
- data/docs/_pages/introduction.adoc +256 -0
- data/docs/_pages/ler-packages.adoc +837 -0
- data/docs/_pages/parsers.adoc +709 -0
- data/docs/_pages/schema-manifests.adoc +431 -0
- data/docs/_references/index.adoc +228 -0
- data/docs/_tutorials/creating-ler-package.adoc +735 -0
- data/docs/_tutorials/documentation-coverage.adoc +795 -0
- data/docs/_tutorials/formatting-schemas.adoc +89 -0
- data/docs/_tutorials/index.adoc +231 -0
- data/docs/_tutorials/liquid-templates.adoc +806 -0
- data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
- data/docs/_tutorials/querying-schemas.adoc +751 -0
- data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
- data/docs/index.adoc +242 -0
- data/docs/lychee.toml +90 -0
- data/examples/demo_ler_usage.sh +86 -0
- data/examples/ler/README.md +111 -0
- data/examples/ler/simple_example.ler +0 -0
- data/examples/ler/simple_schema.exp +33 -0
- data/examples/ler_build.rb +75 -0
- data/examples/ler_cli.rb +79 -0
- data/examples/ler_demo_complete.rb +276 -0
- data/examples/ler_query.rb +91 -0
- data/examples/ler_query_examples.rb +305 -0
- data/examples/ler_stats.rb +81 -0
- data/examples/phase3_demo.rb +159 -0
- data/examples/query_demo_simple.rb +131 -0
- data/exe/expressir +11 -0
- data/exe/expressir-format +14 -0
- data/exe/expressir-format-test +82 -0
- data/expressir.gemspec +61 -0
- data/lib/expressir/3.2/expressir_core.so +0 -0
- data/lib/expressir/3.3/expressir_core.so +0 -0
- data/lib/expressir/3.4/expressir_core.so +0 -0
- data/lib/expressir/4.0/expressir_core.so +0 -0
- data/lib/expressir/benchmark.rb +310 -0
- data/lib/expressir/changes/item_change.rb +20 -0
- data/lib/expressir/changes/mapping_change.rb +16 -0
- data/lib/expressir/changes/schema_change.rb +85 -0
- data/lib/expressir/changes/version_change.rb +26 -0
- data/lib/expressir/changes.rb +9 -0
- data/lib/expressir/cli.rb +148 -0
- data/lib/expressir/commands/base.rb +25 -0
- data/lib/expressir/commands/benchmark.rb +59 -0
- data/lib/expressir/commands/benchmark_cache.rb +80 -0
- data/lib/expressir/commands/changes.rb +34 -0
- data/lib/expressir/commands/changes_import_eengine.rb +146 -0
- data/lib/expressir/commands/changes_validate.rb +63 -0
- data/lib/expressir/commands/check.rb +56 -0
- data/lib/expressir/commands/clean.rb +20 -0
- data/lib/expressir/commands/coverage.rb +458 -0
- data/lib/expressir/commands/expand.rb +26 -0
- data/lib/expressir/commands/file_violations.rb +70 -0
- data/lib/expressir/commands/fix.rb +33 -0
- data/lib/expressir/commands/flatten.rb +29 -0
- data/lib/expressir/commands/format.rb +43 -0
- data/lib/expressir/commands/manifest.rb +420 -0
- data/lib/expressir/commands/mapping_validate.rb +68 -0
- data/lib/expressir/commands/non_ascii_character.rb +49 -0
- data/lib/expressir/commands/non_ascii_violation_collection.rb +301 -0
- data/lib/expressir/commands/package.rb +1222 -0
- data/lib/expressir/commands/parity_inputs.rb +160 -0
- data/lib/expressir/commands/validate.rb +106 -0
- data/lib/expressir/commands/validate_ascii.rb +94 -0
- data/lib/expressir/commands/validate_load.rb +91 -0
- data/lib/expressir/commands/version.rb +9 -0
- data/lib/expressir/commands/xsd.rb +23 -0
- data/lib/expressir/commands.rb +30 -0
- data/lib/expressir/config.rb +60 -0
- data/lib/expressir/coverage.rb +510 -0
- data/lib/expressir/eengine/arm_compare_report.rb +23 -0
- data/lib/expressir/eengine/changes_section.rb +16 -0
- data/lib/expressir/eengine/compare_report.rb +69 -0
- data/lib/expressir/eengine/mim_compare_report.rb +23 -0
- data/lib/expressir/eengine/modified_object.rb +21 -0
- data/lib/expressir/eengine.rb +9 -0
- data/lib/expressir/errors.rb +113 -0
- data/lib/expressir/express/adoc_hyperlink_formatter.rb +30 -0
- data/lib/expressir/express/adoc_source_formatter.rb +12 -0
- data/lib/expressir/express/ast_key_converter.rb +114 -0
- data/lib/expressir/express/builder.rb +277 -0
- data/lib/expressir/express/builder_context.rb +22 -0
- data/lib/expressir/express/builder_registry.rb +397 -0
- data/lib/expressir/express/builders/attribute_decl_builder.rb +32 -0
- data/lib/expressir/express/builders/built_in_builder.rb +75 -0
- data/lib/expressir/express/builders/constant_builder.rb +108 -0
- data/lib/expressir/express/builders/declaration_builder.rb +20 -0
- data/lib/expressir/express/builders/derive_clause_builder.rb +14 -0
- data/lib/expressir/express/builders/derived_attr_builder.rb +28 -0
- data/lib/expressir/express/builders/domain_rule_builder.rb +21 -0
- data/lib/expressir/express/builders/entity_decl_builder.rb +116 -0
- data/lib/expressir/express/builders/explicit_attr_builder.rb +49 -0
- data/lib/expressir/express/builders/expression_builder.rb +416 -0
- data/lib/expressir/express/builders/function_decl_builder.rb +86 -0
- data/lib/expressir/express/builders/helpers.rb +148 -0
- data/lib/expressir/express/builders/interface_builder.rb +151 -0
- data/lib/expressir/express/builders/inverse_attr_builder.rb +43 -0
- data/lib/expressir/express/builders/inverse_attr_type_builder.rb +30 -0
- data/lib/expressir/express/builders/inverse_clause_builder.rb +14 -0
- data/lib/expressir/express/builders/literal_builder.rb +93 -0
- data/lib/expressir/express/builders/procedure_decl_builder.rb +82 -0
- data/lib/expressir/express/builders/qualifier_builder.rb +102 -0
- data/lib/expressir/express/builders/reference_builder.rb +18 -0
- data/lib/expressir/express/builders/rule_decl_builder.rb +97 -0
- data/lib/expressir/express/builders/schema_body_decl_builder.rb +18 -0
- data/lib/expressir/express/builders/schema_decl_builder.rb +56 -0
- data/lib/expressir/express/builders/schema_version_builder.rb +34 -0
- data/lib/expressir/express/builders/simple_id_builder.rb +17 -0
- data/lib/expressir/express/builders/statement_builder.rb +243 -0
- data/lib/expressir/express/builders/subtype_constraint_builder.rb +166 -0
- data/lib/expressir/express/builders/syntax_builder.rb +30 -0
- data/lib/expressir/express/builders/type_builder.rb +238 -0
- data/lib/expressir/express/builders/type_decl_builder.rb +26 -0
- data/lib/expressir/express/builders/unique_clause_builder.rb +20 -0
- data/lib/expressir/express/builders/unique_rule_builder.rb +41 -0
- data/lib/expressir/express/builders/where_clause_builder.rb +20 -0
- data/lib/expressir/express/builders.rb +55 -0
- data/lib/expressir/express/cache.rb +76 -0
- data/lib/expressir/express/checker.rb +812 -0
- data/lib/expressir/express/concatenator.rb +79 -0
- data/lib/expressir/express/core.rb +95 -0
- data/lib/expressir/express/error.rb +124 -0
- data/lib/expressir/express/formatter.rb +149 -0
- data/lib/expressir/express/formatters/data_types_formatter.rb +362 -0
- data/lib/expressir/express/formatters/declarations_formatter.rb +753 -0
- data/lib/expressir/express/formatters/expressions_formatter.rb +180 -0
- data/lib/expressir/express/formatters/literals_formatter.rb +55 -0
- data/lib/expressir/express/formatters/references_formatter.rb +53 -0
- data/lib/expressir/express/formatters/remark_formatter.rb +270 -0
- data/lib/expressir/express/formatters/remark_item_formatter.rb +28 -0
- data/lib/expressir/express/formatters/statements_formatter.rb +272 -0
- data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +54 -0
- data/lib/expressir/express/formatters.rb +22 -0
- data/lib/expressir/express/grammar/parser.rb +712 -0
- data/lib/expressir/express/grammar.rb +11 -0
- data/lib/expressir/express/hyperlink_formatter.rb +35 -0
- data/lib/expressir/express/interface_dot.rb +105 -0
- data/lib/expressir/express/lazy_repository.rb +211 -0
- data/lib/expressir/express/line_map.rb +48 -0
- data/lib/expressir/express/listing.rb +174 -0
- data/lib/expressir/express/model_traversal.rb +42 -0
- data/lib/expressir/express/model_visitor.rb +25 -0
- data/lib/expressir/express/node_position_index.rb +342 -0
- data/lib/expressir/express/parallel_files.rb +229 -0
- data/lib/expressir/express/parser.rb +523 -0
- data/lib/expressir/express/pretty_formatter.rb +586 -0
- data/lib/expressir/express/pretty_gate.rb +61 -0
- data/lib/expressir/express/refs_overlay.rb +47 -0
- data/lib/expressir/express/remark_attacher.rb +1098 -0
- data/lib/expressir/express/remark_overlay.rb +86 -0
- data/lib/expressir/express/remark_scanner.rb +245 -0
- data/lib/expressir/express/resolve_references_model_visitor.rb +29 -0
- data/lib/expressir/express/schema_block_scanner.rb +137 -0
- data/lib/expressir/express/schema_head_formatter.rb +22 -0
- data/lib/expressir/express/schema_plain_source_formatter.rb +11 -0
- data/lib/expressir/express/schema_source_formatter.rb +15 -0
- data/lib/expressir/express/scope_resolver.rb +223 -0
- data/lib/expressir/express/self_schema_reference.rb +126 -0
- data/lib/expressir/express/shtolo.rb +679 -0
- data/lib/expressir/express/smrl_xml.rb +125 -0
- data/lib/expressir/express/source_formatter.rb +15 -0
- data/lib/expressir/express/streaming_builder.rb +435 -0
- data/lib/expressir/express/xsd.rb +259 -0
- data/lib/expressir/express.rb +53 -0
- data/lib/expressir/liquid.rb +1 -0
- data/lib/expressir/manifest/resolver.rb +210 -0
- data/lib/expressir/manifest/validator.rb +192 -0
- data/lib/expressir/manifest.rb +6 -0
- data/lib/expressir/mapping/refpath.rb +857 -0
- data/lib/expressir/mapping.rb +253 -0
- data/lib/expressir/model/cache.rb +18 -0
- data/lib/expressir/model/concerns.rb +42 -0
- data/lib/expressir/model/data_types/aggregate.rb +26 -0
- data/lib/expressir/model/data_types/array.rb +25 -0
- data/lib/expressir/model/data_types/bag.rb +21 -0
- data/lib/expressir/model/data_types/binary.rb +19 -0
- data/lib/expressir/model/data_types/boolean.rb +15 -0
- data/lib/expressir/model/data_types/enumeration.rb +21 -0
- data/lib/expressir/model/data_types/enumeration_item.rb +24 -0
- data/lib/expressir/model/data_types/generic.rb +24 -0
- data/lib/expressir/model/data_types/generic_entity.rb +24 -0
- data/lib/expressir/model/data_types/integer.rb +15 -0
- data/lib/expressir/model/data_types/list.rb +23 -0
- data/lib/expressir/model/data_types/logical.rb +15 -0
- data/lib/expressir/model/data_types/number.rb +15 -0
- data/lib/expressir/model/data_types/real.rb +17 -0
- data/lib/expressir/model/data_types/select.rb +23 -0
- data/lib/expressir/model/data_types/set.rb +21 -0
- data/lib/expressir/model/data_types/string.rb +19 -0
- data/lib/expressir/model/data_types.rb +25 -0
- data/lib/expressir/model/declarations/attribute.rb +38 -0
- data/lib/expressir/model/declarations/constant.rb +28 -0
- data/lib/expressir/model/declarations/derived_attribute.rb +25 -0
- data/lib/expressir/model/declarations/entity.rb +62 -0
- data/lib/expressir/model/declarations/function.rb +59 -0
- data/lib/expressir/model/declarations/informal_proposition_rule.rb +25 -0
- data/lib/expressir/model/declarations/interface.rb +37 -0
- data/lib/expressir/model/declarations/interface_item.rb +21 -0
- data/lib/expressir/model/declarations/interfaced_item.rb +33 -0
- data/lib/expressir/model/declarations/inverse_attribute.rb +25 -0
- data/lib/expressir/model/declarations/parameter.rb +28 -0
- data/lib/expressir/model/declarations/procedure.rb +57 -0
- data/lib/expressir/model/declarations/remark_item.rb +21 -0
- data/lib/expressir/model/declarations/rule.rb +66 -0
- data/lib/expressir/model/declarations/schema.rb +215 -0
- data/lib/expressir/model/declarations/schema_version.rb +19 -0
- data/lib/expressir/model/declarations/schema_version_item.rb +19 -0
- data/lib/expressir/model/declarations/subtype_constraint.rb +32 -0
- data/lib/expressir/model/declarations/type.rb +45 -0
- data/lib/expressir/model/declarations/unique_rule.rb +26 -0
- data/lib/expressir/model/declarations/variable.rb +28 -0
- data/lib/expressir/model/declarations/where_rule.rb +26 -0
- data/lib/expressir/model/declarations.rb +31 -0
- data/lib/expressir/model/dependency_resolver.rb +268 -0
- data/lib/expressir/model/exp_file.rb +42 -0
- data/lib/expressir/model/expressions/aggregate_initializer.rb +18 -0
- data/lib/expressir/model/expressions/aggregate_initializer_item.rb +20 -0
- data/lib/expressir/model/expressions/binary_expression.rb +59 -0
- data/lib/expressir/model/expressions/entity_constructor.rb +20 -0
- data/lib/expressir/model/expressions/function_call.rb +20 -0
- data/lib/expressir/model/expressions/interval.rb +29 -0
- data/lib/expressir/model/expressions/query_expression.rb +31 -0
- data/lib/expressir/model/expressions/unary_expression.rb +25 -0
- data/lib/expressir/model/expressions.rb +18 -0
- data/lib/expressir/model/identifier.rb +26 -0
- data/lib/expressir/model/indexes/entity_index.rb +103 -0
- data/lib/expressir/model/indexes/item_graph.rb +185 -0
- data/lib/expressir/model/indexes/reference_index.rb +148 -0
- data/lib/expressir/model/indexes/type_index.rb +149 -0
- data/lib/expressir/model/indexes.rb +12 -0
- data/lib/expressir/model/interface_validator.rb +384 -0
- data/lib/expressir/model/literals/binary.rb +17 -0
- data/lib/expressir/model/literals/integer.rb +17 -0
- data/lib/expressir/model/literals/logical.rb +21 -0
- data/lib/expressir/model/literals/real.rb +17 -0
- data/lib/expressir/model/literals/string.rb +20 -0
- data/lib/expressir/model/literals.rb +13 -0
- data/lib/expressir/model/model_element.rb +377 -0
- data/lib/expressir/model/references/attribute_reference.rb +19 -0
- data/lib/expressir/model/references/group_reference.rb +19 -0
- data/lib/expressir/model/references/index_reference.rb +23 -0
- data/lib/expressir/model/references/simple_reference.rb +21 -0
- data/lib/expressir/model/references.rb +12 -0
- data/lib/expressir/model/remark_format.rb +17 -0
- data/lib/expressir/model/remark_info.rb +92 -0
- data/lib/expressir/model/remark_placement.rb +42 -0
- data/lib/expressir/model/repository.rb +483 -0
- data/lib/expressir/model/repository_validator.rb +293 -0
- data/lib/expressir/model/search_engine.rb +551 -0
- data/lib/expressir/model/statements/alias.rb +31 -0
- data/lib/expressir/model/statements/assignment.rb +23 -0
- data/lib/expressir/model/statements/case.rb +42 -0
- data/lib/expressir/model/statements/case_action.rb +20 -0
- data/lib/expressir/model/statements/compound.rb +21 -0
- data/lib/expressir/model/statements/escape.rb +18 -0
- data/lib/expressir/model/statements/if.rb +26 -0
- data/lib/expressir/model/statements/null.rb +18 -0
- data/lib/expressir/model/statements/procedure_call.rb +22 -0
- data/lib/expressir/model/statements/repeat.rb +40 -0
- data/lib/expressir/model/statements/return.rb +20 -0
- data/lib/expressir/model/statements/skip.rb +18 -0
- data/lib/expressir/model/statements.rb +20 -0
- data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +25 -0
- data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +17 -0
- data/lib/expressir/model/supertype_expressions.rb +12 -0
- data/lib/expressir/model.rb +39 -0
- data/lib/expressir/package/builder.rb +231 -0
- data/lib/expressir/package/metadata.rb +79 -0
- data/lib/expressir/package/reader.rb +149 -0
- data/lib/expressir/package.rb +8 -0
- data/lib/expressir/schema_manifest.rb +159 -0
- data/lib/expressir/schema_manifest_entry.rb +15 -0
- data/lib/expressir/version.rb +8 -0
- data/lib/expressir.rb +94 -0
- data/lib/tasks/verify_remarks.rake +16 -0
- data/rakelib/native.rake +24 -0
- data/rakelib/oracle.rake +52 -0
- data/rakelib/verify_remarks.rake +16 -0
- metadata +692 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Expressir
|
|
4
|
+
module Express
|
|
5
|
+
# Remarks are deterministic given the sources, so the batch path
|
|
6
|
+
# persists them as an overlay next to the compiled-set artifact;
|
|
7
|
+
# warm loads re-apply the overlay instead of re-running the
|
|
8
|
+
# {RemarkAttacher}.
|
|
9
|
+
#
|
|
10
|
+
# Nodes are keyed structurally — attribute path plus array index —
|
|
11
|
+
# because {Model::ModelElement#path} is empty for id-less nodes
|
|
12
|
+
# (statements), and the wire is byte-identical between the cold
|
|
13
|
+
# write and the warm apply, so structural keys match exactly.
|
|
14
|
+
module RemarkOverlay
|
|
15
|
+
CAPTURED = %w[remarks remark_items informal_propositions untagged_remarks header].freeze
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
def write(set_path, models)
|
|
19
|
+
overlay = {}
|
|
20
|
+
ModelTraversal.each_model(models) do |node, key|
|
|
21
|
+
entry = {}
|
|
22
|
+
CAPTURED.each do |attr|
|
|
23
|
+
next unless node.respond_to?(attr)
|
|
24
|
+
|
|
25
|
+
value = node.public_send(attr)
|
|
26
|
+
entry[attr] = value if attr == "header" ? value : value&.any?
|
|
27
|
+
end
|
|
28
|
+
overlay[key] = entry if entry.any?
|
|
29
|
+
end
|
|
30
|
+
return if overlay.empty?
|
|
31
|
+
|
|
32
|
+
require "json"
|
|
33
|
+
File.write("#{set_path}.remarks.json", JSON.generate(overlay))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Recursively parent restored nodes and invalidate id-memos so
|
|
37
|
+
# find()/resolve_path_in_scope sees them, exactly as the
|
|
38
|
+
# RemarkAttacher's own bookkeeping does.
|
|
39
|
+
def wire_overlay_value(parent, value)
|
|
40
|
+
case value
|
|
41
|
+
when Array
|
|
42
|
+
value.each { |item| wire_overlay_value(parent, item) }
|
|
43
|
+
when Model::ModelElement
|
|
44
|
+
parent_value = parent.is_a?(Model::ModelElement) ? parent : nil
|
|
45
|
+
value.parent = parent_value if value.respond_to?(:parent=)
|
|
46
|
+
if parent_value.respond_to?(:reset_children_by_id)
|
|
47
|
+
parent_value.reset_children_by_id
|
|
48
|
+
end
|
|
49
|
+
value.class.attributes.each_key do |attr|
|
|
50
|
+
next if Model::ModelElement::SKIP_ATTRIBUTES.include?(attr) || attr == :parent
|
|
51
|
+
|
|
52
|
+
inner = value.public_send(attr)
|
|
53
|
+
next unless inner.is_a?(Model::ModelElement) || inner.is_a?(Array)
|
|
54
|
+
|
|
55
|
+
wire_overlay_value(value, inner)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def apply(set_path, models)
|
|
61
|
+
overlay_path = "#{set_path}.remarks.json"
|
|
62
|
+
return unless File.exist?(overlay_path)
|
|
63
|
+
|
|
64
|
+
require "json"
|
|
65
|
+
overlay = JSON.parse(File.read(overlay_path))
|
|
66
|
+
ModelTraversal.each_model(models) do |node, key|
|
|
67
|
+
entry = overlay[key]
|
|
68
|
+
next unless entry
|
|
69
|
+
|
|
70
|
+
CAPTURED.each do |attr|
|
|
71
|
+
setter = :"#{attr}="
|
|
72
|
+
next unless entry[attr] && node.respond_to?(setter)
|
|
73
|
+
|
|
74
|
+
node.public_send(setter, entry[attr])
|
|
75
|
+
# The writer casts JSON hashes into model objects; wire
|
|
76
|
+
# the cast collection (the attacher parents every
|
|
77
|
+
# created node and resets the child-id memo — reference
|
|
78
|
+
# resolution relies on both).
|
|
79
|
+
wire_overlay_value(node, node.public_send(attr))
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Expressir
|
|
4
|
+
module Express
|
|
5
|
+
# Scans EXPRESS source text and extracts all remarks (tail and embedded),
|
|
6
|
+
# correctly tracking embedded-remark nesting so that inline `--` inside
|
|
7
|
+
# a `(* ... *)` documentation block is NOT mistaken for a tail remark.
|
|
8
|
+
#
|
|
9
|
+
# Single responsibility: source string -> Array<Remark>. The scanner has
|
|
10
|
+
# no knowledge of the model; attaching remarks to model elements is the
|
|
11
|
+
# job of {RemarkAttacher}.
|
|
12
|
+
#
|
|
13
|
+
# Reference: ISO 10303-11 §7.1.6.
|
|
14
|
+
# tail_remark = '--' [ remark_tag ] { <any char except newline> } '\n'
|
|
15
|
+
# embedded_remark = '(*' [ remark_tag ]
|
|
16
|
+
# { <any char> | nested embedded_remark } '*)'
|
|
17
|
+
#
|
|
18
|
+
# The scanner is a single-pass state machine with four states:
|
|
19
|
+
# :top — outside any remark/string; look for `--`, `(*`, or `'`.
|
|
20
|
+
# :in_tail — inside a tail remark; look only for the next newline.
|
|
21
|
+
# :in_embedded — inside one or more nested embedded remarks; look
|
|
22
|
+
# for the matching `*)` or a nested `(*`, ignoring `--`.
|
|
23
|
+
# :in_string — inside a simple string literal; look for the closing
|
|
24
|
+
# `'`, treating `''` as an escaped quote (ISO 10303-11
|
|
25
|
+
# §7.1.6.5). `--` and `(*` inside a string are content.
|
|
26
|
+
class RemarkScanner
|
|
27
|
+
# Immutable value object describing a single extracted remark.
|
|
28
|
+
# `position` is the byte offset of the opener (`--` or `(*`).
|
|
29
|
+
# `end_position` is the byte offset one past the closer (the newline
|
|
30
|
+
# byte for tail remarks, the byte after `*)` for embedded remarks).
|
|
31
|
+
# `[position, end_position)` is the full byte range the remark
|
|
32
|
+
# occupied in the original source.
|
|
33
|
+
Remark = Struct.new(:position, :end_position, :line, :text, :tag,
|
|
34
|
+
:format, keyword_init: true) do
|
|
35
|
+
def tail?
|
|
36
|
+
format == Model::RemarkFormat::TAIL
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def embedded?
|
|
40
|
+
format == Model::RemarkFormat::EMBEDDED
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def tagged?
|
|
44
|
+
!tag.nil? && !tag.empty?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Byte length of the full remark (opener + content + closer).
|
|
48
|
+
def bytesize
|
|
49
|
+
end_position - position
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Lexical markers recognised by EXPRESS.
|
|
54
|
+
TAIL_MARKER = "--"
|
|
55
|
+
EMBEDDED_OPEN = "(*"
|
|
56
|
+
EMBEDDED_CLOSE = "*)"
|
|
57
|
+
STRING_QUOTE = "'"
|
|
58
|
+
|
|
59
|
+
# Byte value of `)` — used to detect the `(*)` overlap pattern where
|
|
60
|
+
# the embedded-remark opener `(*` and closer `*)` share the `*`.
|
|
61
|
+
RPAREN_BYTE = ")".ord
|
|
62
|
+
|
|
63
|
+
# Tag forms (see ISO 10303-11 §7.1.6.3 Remark tag).
|
|
64
|
+
# IP-style informal-proposition tags are recognised only in tail remarks
|
|
65
|
+
# (matching historic behaviour); embedded remarks use the quoted form.
|
|
66
|
+
INFORMAL_PROPOSITION_TAG = /\A(IP\d+):\s*(.*)\z/m
|
|
67
|
+
QUOTED_TAG = /\A"([^"]*)"\s*(.*)\z/m
|
|
68
|
+
|
|
69
|
+
# @param source [String] EXPRESS source text (any encoding).
|
|
70
|
+
def initialize(source)
|
|
71
|
+
@source = source
|
|
72
|
+
@source_bytes = source.b
|
|
73
|
+
@line_map = LineMap.new(@source_bytes)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Returns an Array of {Remark}, in source order (by byte position).
|
|
77
|
+
# @return [Array<Remark>]
|
|
78
|
+
def scan
|
|
79
|
+
run_state_machine
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
alias call scan
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
# Detects the `(*)` overlap pattern: opener `(*` (positions pos, pos+1)
|
|
87
|
+
# and closer `*)` (positions pos+1, pos+2) share the `*` character.
|
|
88
|
+
# Per strict ISO 10303-11 §7.1.6 grammar the opener and closer are
|
|
89
|
+
# distinct tokens that cannot share characters, so `(*)` is technically
|
|
90
|
+
# invalid; we accept it as a 3-character empty embedded remark for
|
|
91
|
+
# robustness (issue #126).
|
|
92
|
+
def empty_overlap_remark?(pos)
|
|
93
|
+
pos + 2 < @source_bytes.bytesize &&
|
|
94
|
+
@source_bytes.getbyte(pos + 2) == RPAREN_BYTE
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def run_state_machine
|
|
98
|
+
remarks = []
|
|
99
|
+
src = @source_bytes
|
|
100
|
+
pos = 0
|
|
101
|
+
|
|
102
|
+
state = :top
|
|
103
|
+
embedded_depth = 0
|
|
104
|
+
tail_start = nil # byte position of first content char after "--"
|
|
105
|
+
tail_line = nil
|
|
106
|
+
embedded_start = nil # byte position of first content char after "(*"
|
|
107
|
+
embedded_line = nil
|
|
108
|
+
|
|
109
|
+
while pos < src.bytesize
|
|
110
|
+
case state
|
|
111
|
+
when :in_tail
|
|
112
|
+
nl = src.index("\n", pos)
|
|
113
|
+
if nl
|
|
114
|
+
emit_tail(remarks, tail_start, nl, tail_line)
|
|
115
|
+
pos = nl + 1
|
|
116
|
+
state = :top
|
|
117
|
+
else
|
|
118
|
+
emit_tail(remarks, tail_start, src.bytesize, tail_line)
|
|
119
|
+
return remarks
|
|
120
|
+
end
|
|
121
|
+
when :in_embedded
|
|
122
|
+
closing = src.index(EMBEDDED_CLOSE, pos)
|
|
123
|
+
nesting = src.index(EMBEDDED_OPEN, pos)
|
|
124
|
+
if nesting && (!closing || nesting < closing)
|
|
125
|
+
if empty_overlap_remark?(nesting)
|
|
126
|
+
# `(*)` opens and closes immediately; depth unchanged.
|
|
127
|
+
pos = nesting + 3
|
|
128
|
+
else
|
|
129
|
+
embedded_depth += 1
|
|
130
|
+
pos = nesting + EMBEDDED_OPEN.bytesize
|
|
131
|
+
end
|
|
132
|
+
elsif closing
|
|
133
|
+
embedded_depth -= 1
|
|
134
|
+
pos = closing + EMBEDDED_CLOSE.bytesize
|
|
135
|
+
if embedded_depth.zero?
|
|
136
|
+
emit_embedded(remarks, embedded_start, closing, embedded_line)
|
|
137
|
+
state = :top
|
|
138
|
+
end
|
|
139
|
+
else
|
|
140
|
+
# Unclosed embedded remark — terminate scan gracefully.
|
|
141
|
+
return remarks
|
|
142
|
+
end
|
|
143
|
+
when :in_string
|
|
144
|
+
# ISO 10303-11 §7.1.6.5: `''` inside a string is an escaped quote.
|
|
145
|
+
# Find the next `'`; if followed by another `'`, skip both; else
|
|
146
|
+
# the string closes.
|
|
147
|
+
quote_pos = src.index(STRING_QUOTE, pos)
|
|
148
|
+
if quote_pos.nil?
|
|
149
|
+
# Unclosed string — malformed EXPRESS; terminate scan gracefully.
|
|
150
|
+
return remarks
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
if quote_pos + 1 < src.bytesize && src.getbyte(quote_pos + 1) == STRING_QUOTE.ord
|
|
154
|
+
pos = quote_pos + 2
|
|
155
|
+
else
|
|
156
|
+
pos = quote_pos + 1
|
|
157
|
+
state = :top
|
|
158
|
+
end
|
|
159
|
+
else # :top
|
|
160
|
+
next_embed = src.index(EMBEDDED_OPEN, pos)
|
|
161
|
+
next_tail = src.index(TAIL_MARKER, pos)
|
|
162
|
+
next_quote = src.index(STRING_QUOTE, pos)
|
|
163
|
+
if next_embed.nil? && next_tail.nil? && next_quote.nil?
|
|
164
|
+
return remarks
|
|
165
|
+
elsif next_quote && (next_embed.nil? || next_quote < next_embed) &&
|
|
166
|
+
(next_tail.nil? || next_quote < next_tail)
|
|
167
|
+
# String opener wins — enter :in_string and skip the quote.
|
|
168
|
+
pos = next_quote + STRING_QUOTE.bytesize
|
|
169
|
+
state = :in_string
|
|
170
|
+
elsif next_embed && (next_tail.nil? || next_embed <= next_tail)
|
|
171
|
+
if empty_overlap_remark?(next_embed)
|
|
172
|
+
# Standalone `(*)`: empty embedded remark, opener and closer
|
|
173
|
+
# share the `*`. Emit with empty content and continue.
|
|
174
|
+
emit_embedded(remarks, next_embed + EMBEDDED_OPEN.bytesize,
|
|
175
|
+
next_embed + EMBEDDED_OPEN.bytesize,
|
|
176
|
+
@line_map.line_number(next_embed))
|
|
177
|
+
pos = next_embed + 3
|
|
178
|
+
state = :top
|
|
179
|
+
else
|
|
180
|
+
embedded_start = next_embed + EMBEDDED_OPEN.bytesize
|
|
181
|
+
embedded_line = @line_map.line_number(next_embed)
|
|
182
|
+
embedded_depth = 1
|
|
183
|
+
state = :in_embedded
|
|
184
|
+
pos = next_embed + EMBEDDED_OPEN.bytesize
|
|
185
|
+
end
|
|
186
|
+
else
|
|
187
|
+
tail_start = next_tail + TAIL_MARKER.bytesize
|
|
188
|
+
tail_line = @line_map.line_number(next_tail)
|
|
189
|
+
state = :in_tail
|
|
190
|
+
pos = next_tail + TAIL_MARKER.bytesize
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
remarks
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def emit_tail(remarks, content_start, content_end, line)
|
|
199
|
+
# Slice content from the original (UTF-8) source so the returned text
|
|
200
|
+
# preserves the source encoding. Byte offsets come from the BINARY copy.
|
|
201
|
+
raw = @source.byteslice(content_start...content_end)
|
|
202
|
+
tag, content = parse_tail(raw.strip)
|
|
203
|
+
remarks << Remark.new(
|
|
204
|
+
position: content_start - TAIL_MARKER.bytesize,
|
|
205
|
+
end_position: content_end,
|
|
206
|
+
line: line,
|
|
207
|
+
text: content,
|
|
208
|
+
tag: tag,
|
|
209
|
+
format: Model::RemarkFormat::TAIL,
|
|
210
|
+
)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def emit_embedded(remarks, content_start, content_end, line)
|
|
214
|
+
raw = @source.byteslice(content_start...content_end)
|
|
215
|
+
tag, content = parse_embedded(raw)
|
|
216
|
+
remarks << Remark.new(
|
|
217
|
+
position: content_start - EMBEDDED_OPEN.bytesize,
|
|
218
|
+
end_position: content_end + EMBEDDED_CLOSE.bytesize,
|
|
219
|
+
line: line,
|
|
220
|
+
text: content,
|
|
221
|
+
tag: tag,
|
|
222
|
+
format: Model::RemarkFormat::EMBEDDED,
|
|
223
|
+
)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Tail remarks support both quoted tags ("schema.entity" ...) and the
|
|
227
|
+
# shorthand IP-tag form (IP1: ...). Returns [tag, content]; for untagged
|
|
228
|
+
# remarks tag is nil and content is the stripped text.
|
|
229
|
+
def parse_tail(text)
|
|
230
|
+
match = text.match(INFORMAL_PROPOSITION_TAG) || text.match(QUOTED_TAG)
|
|
231
|
+
match ? match.captures : [nil, text]
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Embedded remarks only use the quoted tag form.
|
|
235
|
+
def parse_embedded(content)
|
|
236
|
+
stripped = content.strip
|
|
237
|
+
if (m = stripped.match(QUOTED_TAG))
|
|
238
|
+
[m[1], m[2]]
|
|
239
|
+
else
|
|
240
|
+
[nil, stripped]
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Expressir
|
|
2
|
+
module Express
|
|
3
|
+
class ResolveReferencesModelVisitor < ModelVisitor
|
|
4
|
+
def visit(node)
|
|
5
|
+
if node.is_a? Model::References::SimpleReference
|
|
6
|
+
visit_references_simple_reference(node)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def visit_references_simple_reference(node)
|
|
15
|
+
return if node.parent.is_a? Model::References::AttributeReference
|
|
16
|
+
return unless node.id # Skip if no id to resolve
|
|
17
|
+
|
|
18
|
+
base_item = if node.parent.is_a? Model::Declarations::InterfaceItem
|
|
19
|
+
node.find("#{node.parent.parent.schema.id}.#{node.parent.ref.id}")
|
|
20
|
+
else
|
|
21
|
+
node.find(node.id)
|
|
22
|
+
end
|
|
23
|
+
return unless base_item
|
|
24
|
+
|
|
25
|
+
node.base_path = base_item.path
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Expressir
|
|
4
|
+
module Express
|
|
5
|
+
# Splits multi-schema EXPRESS source into individual schema blocks.
|
|
6
|
+
#
|
|
7
|
+
# A hand-rolled state machine that skips comments (`(* ... *)`) and
|
|
8
|
+
# string literals, tracks SCHEMA/END_SCHEMA depth, and returns one
|
|
9
|
+
# block per schema declaration. Retained for the future streaming
|
|
10
|
+
# parse path (see TODO.max-perf/02) that parses each schema
|
|
11
|
+
# independently with a fresh memory arena.
|
|
12
|
+
#
|
|
13
|
+
# Extracted from the outer Parser class (TODO.bugs/09) so block-
|
|
14
|
+
# scanning logic lives in one focused module behind one interface.
|
|
15
|
+
module SchemaBlockScanner
|
|
16
|
+
END_SCHEMA_KEYWORD = "END_SCHEMA"
|
|
17
|
+
SCHEMA_KEYWORD = "SCHEMA"
|
|
18
|
+
WHITESPACE_CHARS = [" ", "\t", "\n", "\r"].freeze
|
|
19
|
+
|
|
20
|
+
module_function
|
|
21
|
+
|
|
22
|
+
# Extract individual schema blocks from EXPRESS source.
|
|
23
|
+
#
|
|
24
|
+
# Uses a state machine to properly handle nested comments and strings.
|
|
25
|
+
#
|
|
26
|
+
# @param source [String] EXPRESS source
|
|
27
|
+
# @return [Array<Hash>] Array of {name:, source:, start_pos:, end_pos:}
|
|
28
|
+
# for each schema block found.
|
|
29
|
+
def extract_schema_blocks(source)
|
|
30
|
+
blocks = []
|
|
31
|
+
pos = 0
|
|
32
|
+
len = source.length
|
|
33
|
+
|
|
34
|
+
while pos < len
|
|
35
|
+
pos = skip_ws_and_comments(source, pos)
|
|
36
|
+
break if pos >= len
|
|
37
|
+
|
|
38
|
+
if source[pos..].start_with?(SCHEMA_KEYWORD)
|
|
39
|
+
result = parse_schema_block(source, pos)
|
|
40
|
+
if result
|
|
41
|
+
blocks << result
|
|
42
|
+
pos = result[:end_pos]
|
|
43
|
+
next
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
pos += 1
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
blocks
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def parse_schema_block(source, start_pos)
|
|
54
|
+
return nil unless source[start_pos..].start_with?(SCHEMA_KEYWORD)
|
|
55
|
+
|
|
56
|
+
pos = start_pos + SCHEMA_KEYWORD.length
|
|
57
|
+
pos = skip_spaces(source, pos)
|
|
58
|
+
|
|
59
|
+
name_start = pos
|
|
60
|
+
while pos < source.length && (source[pos] =~ /[a-zA-Z0-9_]/ || source[pos] == "_")
|
|
61
|
+
pos += 1
|
|
62
|
+
end
|
|
63
|
+
schema_name = source[name_start...pos]
|
|
64
|
+
return nil if schema_name.empty?
|
|
65
|
+
|
|
66
|
+
depth = 1
|
|
67
|
+
search_pos = pos
|
|
68
|
+
end_pos = nil
|
|
69
|
+
|
|
70
|
+
while search_pos < source.length
|
|
71
|
+
if source[search_pos] == '"'
|
|
72
|
+
search_pos += 1
|
|
73
|
+
while search_pos < source.length && source[search_pos] != '"'
|
|
74
|
+
search_pos += 1
|
|
75
|
+
end
|
|
76
|
+
search_pos += 1
|
|
77
|
+
elsif source[search_pos] == "(" && source[search_pos + 1] == "*"
|
|
78
|
+
search_pos += 2
|
|
79
|
+
while search_pos < source.length && !(source[search_pos] == "*" && source[search_pos + 1] == ")")
|
|
80
|
+
search_pos += 1
|
|
81
|
+
end
|
|
82
|
+
search_pos += 2
|
|
83
|
+
elsif source[search_pos..].start_with?(END_SCHEMA_KEYWORD)
|
|
84
|
+
depth -= 1
|
|
85
|
+
if depth.zero?
|
|
86
|
+
end_pos = search_pos + END_SCHEMA_KEYWORD.length
|
|
87
|
+
pos = end_pos
|
|
88
|
+
pos = skip_spaces(source, pos)
|
|
89
|
+
pos += 1 if source[pos] == ";"
|
|
90
|
+
break
|
|
91
|
+
end
|
|
92
|
+
search_pos += END_SCHEMA_KEYWORD.length
|
|
93
|
+
else
|
|
94
|
+
search_pos += 1
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
return nil unless end_pos
|
|
99
|
+
|
|
100
|
+
{
|
|
101
|
+
name: schema_name,
|
|
102
|
+
source: source[start_pos...end_pos],
|
|
103
|
+
start_pos: start_pos,
|
|
104
|
+
end_pos: pos,
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def skip_spaces(source, pos)
|
|
109
|
+
while pos < source.length && WHITESPACE_CHARS.include?(source[pos])
|
|
110
|
+
pos += 1
|
|
111
|
+
end
|
|
112
|
+
pos
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def skip_ws_and_comments(source, pos)
|
|
116
|
+
len = source.length
|
|
117
|
+
while pos < len
|
|
118
|
+
c = source[pos]
|
|
119
|
+
if WHITESPACE_CHARS.include?(c)
|
|
120
|
+
pos += 1
|
|
121
|
+
elsif c == "(" && source[pos + 1] == "*"
|
|
122
|
+
pos += 2
|
|
123
|
+
while pos < len - 1 && !(source[pos] == "*" && source[pos + 1] == ")")
|
|
124
|
+
pos += 1
|
|
125
|
+
end
|
|
126
|
+
pos += 2
|
|
127
|
+
else
|
|
128
|
+
break
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
pos
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
private_class_method :parse_schema_block, :skip_spaces, :skip_ws_and_comments
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Expressir
|
|
2
|
+
module Express
|
|
3
|
+
# Formatter module - format schema as schema head only
|
|
4
|
+
# @example Include into Formatter subclass
|
|
5
|
+
# formatter = Class.new(Expressir::Express::Formatter) do
|
|
6
|
+
# include Expressir::Express::SchemaHeadFormatter
|
|
7
|
+
# end
|
|
8
|
+
module SchemaHeadFormatter
|
|
9
|
+
# @!visibility private
|
|
10
|
+
def self.included(mod)
|
|
11
|
+
unless mod.superclass <= Expressir::Express::Formatter
|
|
12
|
+
raise Error::FormatterMethodMissingError.new("SchemaHeadFormatter",
|
|
13
|
+
"format_declarations_schema/format_declarations_schema_head")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def format_declarations_schema(node)
|
|
18
|
+
format_declarations_schema_head(node)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Expressir
|
|
4
|
+
module Express
|
|
5
|
+
# Pre-built Formatter subclass rendering the schema head without
|
|
6
|
+
# hyperlinks — the plain `source` face of Schema (#255).
|
|
7
|
+
class SchemaPlainSourceFormatter < Formatter
|
|
8
|
+
include SchemaHeadFormatter
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Expressir
|
|
4
|
+
module Express
|
|
5
|
+
# Pre-built Formatter subclass rendering the schema head with
|
|
6
|
+
# hyperlinks: SchemaHeadFormatter + HyperlinkFormatter. Allocated
|
|
7
|
+
# once at load time rather than per call. It backs
|
|
8
|
+
# Schema#source_hyperlinked; Schema#source uses
|
|
9
|
+
# SchemaPlainSourceFormatter, the unlinked counterpart (#255).
|
|
10
|
+
class SchemaSourceFormatter < Formatter
|
|
11
|
+
include SchemaHeadFormatter
|
|
12
|
+
include HyperlinkFormatter
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|