expressir 2.1.19 → 2.1.21
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 +4 -4
- data/.rubocop_todo.yml +44 -7
- data/README.adoc +176 -11
- data/expressir.gemspec +0 -1
- data/lib/expressir/cli.rb +2 -1
- data/lib/expressir/commands/coverage.rb +53 -12
- data/lib/expressir/coverage.rb +261 -17
- data/lib/expressir/express/formatter.rb +40 -13
- data/lib/expressir/express/visitor.rb +53 -18
- data/lib/expressir/model/identifier.rb +2 -0
- data/lib/expressir/model/model_element.rb +1 -0
- data/lib/expressir/model.rb +94 -71
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +121 -6
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5523a9cdb1e5b8168a0d2d7262cdd8a5e849b066a3eeaaad90a3bcb3a640fe38
|
4
|
+
data.tar.gz: 293acbebeecc50a22ba8bc56aa8413f7e156dac17fa4fa872380aff5a9bf320c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b756fab7be254dc71ab78ce9ffdb220c727cc1ef8599c2e293ee2edb35d8fb7f2ab9e127683e7621d5a0ac2df4379efa5ff1c2aeaa8dd7623b94b18d5e778d7e
|
7
|
+
data.tar.gz: cb767afb4bef0a7555b9519a29b1cefa14ba3c96278d5154e2c2b5af29e813ba0824ffb7efbfd2e601f2e606f0a5800595b8a97b7998a83dd80c4d99448e7546
|
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2025-06-
|
3
|
+
# on 2025-06-07 05:08:55 UTC using RuboCop version 1.75.2.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -21,11 +21,31 @@ Layout/LineLength:
|
|
21
21
|
Exclude:
|
22
22
|
- 'lib/expressir/express/parser.rb'
|
23
23
|
|
24
|
+
# Offense count: 1
|
25
|
+
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
26
|
+
Lint/DuplicateBranch:
|
27
|
+
Exclude:
|
28
|
+
- 'lib/expressir/coverage.rb'
|
29
|
+
|
30
|
+
# Offense count: 1
|
31
|
+
# This cop supports safe autocorrection (--autocorrect).
|
32
|
+
Lint/ScriptPermission:
|
33
|
+
Exclude:
|
34
|
+
- 'update_yaml_fixtures.rb'
|
35
|
+
|
24
36
|
# Offense count: 3
|
25
37
|
Lint/ShadowingOuterLocalVariable:
|
26
38
|
Exclude:
|
27
39
|
- 'lib/expressir/express/visitor.rb'
|
28
40
|
|
41
|
+
# Offense count: 2
|
42
|
+
# This cop supports safe autocorrection (--autocorrect).
|
43
|
+
# Configuration parameters: AutoCorrect, IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
44
|
+
Lint/UnusedBlockArgument:
|
45
|
+
Exclude:
|
46
|
+
- 'lib/expressir/express/visitor.rb'
|
47
|
+
- 'spec/support/yaml_matchers.rb'
|
48
|
+
|
29
49
|
# Offense count: 2
|
30
50
|
# This cop supports safe autocorrection (--autocorrect).
|
31
51
|
# Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
|
@@ -35,7 +55,7 @@ Lint/UnusedMethodArgument:
|
|
35
55
|
- 'lib/expressir/express/cache.rb'
|
36
56
|
- 'lib/expressir/express/parser.rb'
|
37
57
|
|
38
|
-
# Offense count:
|
58
|
+
# Offense count: 76
|
39
59
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
40
60
|
Metrics/AbcSize:
|
41
61
|
Exclude:
|
@@ -54,13 +74,13 @@ Metrics/AbcSize:
|
|
54
74
|
- 'lib/expressir/model/declarations/schema.rb'
|
55
75
|
- 'lib/expressir/model/model_element.rb'
|
56
76
|
|
57
|
-
# Offense count:
|
77
|
+
# Offense count: 2
|
58
78
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
59
79
|
# AllowedMethods: refine
|
60
80
|
Metrics/BlockLength:
|
61
81
|
Max: 143
|
62
82
|
|
63
|
-
# Offense count:
|
83
|
+
# Offense count: 56
|
64
84
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
65
85
|
Metrics/CyclomaticComplexity:
|
66
86
|
Exclude:
|
@@ -75,12 +95,12 @@ Metrics/CyclomaticComplexity:
|
|
75
95
|
- 'lib/expressir/model/model_element.rb'
|
76
96
|
- 'spec/support/model_element_helper.rb'
|
77
97
|
|
78
|
-
# Offense count:
|
98
|
+
# Offense count: 100
|
79
99
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
80
100
|
Metrics/MethodLength:
|
81
|
-
Max:
|
101
|
+
Max: 82
|
82
102
|
|
83
|
-
# Offense count:
|
103
|
+
# Offense count: 44
|
84
104
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
85
105
|
Metrics/PerceivedComplexity:
|
86
106
|
Exclude:
|
@@ -92,6 +112,17 @@ Metrics/PerceivedComplexity:
|
|
92
112
|
- 'lib/expressir/model/declarations/schema.rb'
|
93
113
|
- 'lib/expressir/model/model_element.rb'
|
94
114
|
|
115
|
+
# Offense count: 1
|
116
|
+
# Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros, UseSorbetSigs.
|
117
|
+
# NamePrefix: is_, has_, have_, does_
|
118
|
+
# ForbiddenPrefixes: is_, has_, have_, does_
|
119
|
+
# AllowedMethods: is_a?
|
120
|
+
# MethodDefinitionMacros: define_method, define_singleton_method
|
121
|
+
Naming/PredicateName:
|
122
|
+
Exclude:
|
123
|
+
- 'spec/**/*'
|
124
|
+
- 'lib/expressir/coverage.rb'
|
125
|
+
|
95
126
|
# Offense count: 5
|
96
127
|
Performance/FixedSize:
|
97
128
|
Exclude:
|
@@ -101,3 +132,9 @@ Performance/FixedSize:
|
|
101
132
|
Style/MissingRespondToMissing:
|
102
133
|
Exclude:
|
103
134
|
- 'lib/expressir/express/visitor.rb'
|
135
|
+
|
136
|
+
# Offense count: 2
|
137
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
138
|
+
Style/SlicingWithRange:
|
139
|
+
Exclude:
|
140
|
+
- 'lib/expressir/express/visitor.rb'
|
data/README.adoc
CHANGED
@@ -286,25 +286,190 @@ such as TYPE entities whose descriptions are generated by template strings.
|
|
286
286
|
# Exclude TYPE entities from coverage analysis
|
287
287
|
expressir coverage --exclude=TYPE schemas/resources/action_schema/action_schema.exp
|
288
288
|
|
289
|
+
# Exclude only SELECT type definitions (useful since TYPE descriptions are often template-generated)
|
290
|
+
expressir coverage --exclude=TYPE:SELECT schemas/resources/action_schema/action_schema.exp
|
291
|
+
|
289
292
|
# Exclude multiple entity types
|
290
293
|
expressir coverage --exclude=TYPE,CONSTANT,FUNCTION schemas/resources/action_schema/action_schema.exp
|
291
294
|
|
295
|
+
# Exclude parameters and variables (often don't require individual documentation)
|
296
|
+
expressir coverage --exclude=PARAMETER,VARIABLE schemas/resources/action_schema/action_schema.exp
|
297
|
+
|
292
298
|
# Combine with output format options
|
293
|
-
expressir coverage --exclude=TYPE --format=json schemas/resources/action_schema/action_schema.exp
|
299
|
+
expressir coverage --exclude=TYPE:SELECT --format=json schemas/resources/action_schema/action_schema.exp
|
300
|
+
----
|
301
|
+
|
302
|
+
==== Elements checked in documentation coverage
|
303
|
+
|
304
|
+
Expressir checks documentation coverage for all EXPRESS elements (ModelElement
|
305
|
+
subclasses), including:
|
306
|
+
|
307
|
+
Schema-level entities:
|
308
|
+
|
309
|
+
`TYPE`:: Type definitions (supports subtype exclusion, see below)
|
310
|
+
`ENTITY`:: Entity definitions
|
311
|
+
`CONSTANT`:: Constant definitions
|
312
|
+
`FUNCTION`:: Function definitions
|
313
|
+
`RULE`:: Rule definitions
|
314
|
+
`PROCEDURE`:: Procedure definitions
|
315
|
+
`SUBTYPE_CONSTRAINT`:: Subtype constraint definitions
|
316
|
+
`INTERFACE`:: Interface definitions
|
317
|
+
|
318
|
+
Nested entities within other constructs:
|
319
|
+
|
320
|
+
`PARAMETER`:: Function and procedure parameters
|
321
|
+
`VARIABLE`:: Variables within functions, rules, and procedures
|
322
|
+
`ATTRIBUTE`:: Entity attributes
|
323
|
+
`DERIVED_ATTRIBUTE`:: Derived attributes in entities
|
324
|
+
`INVERSE_ATTRIBUTE`:: Inverse attributes in entities
|
325
|
+
`UNIQUE_RULE`:: Unique rules within entities
|
326
|
+
`WHERE_RULE`:: Where rules within entities and types
|
327
|
+
`ENUMERATION_ITEM`:: Items within enumeration types
|
328
|
+
`INTERFACE_ITEM`:: Items within interfaces
|
329
|
+
`INTERFACED_ITEM`:: Interfaced items
|
330
|
+
`SCHEMA_VERSION`:: Schema version information
|
331
|
+
`SCHEMA_VERSION_ITEM`:: Schema version items
|
332
|
+
|
333
|
+
==== TYPE subtype exclusion
|
334
|
+
|
335
|
+
For TYPE elements, you can exclude specific subtypes using the `TYPE:SUBTYPE`
|
336
|
+
syntax:
|
337
|
+
|
338
|
+
[source, sh]
|
339
|
+
----
|
340
|
+
# Exclude only SELECT types
|
341
|
+
expressir coverage --exclude=TYPE:SELECT schemas/resources/action_schema/action_schema.exp
|
342
|
+
|
343
|
+
# Exclude multiple TYPE subtypes
|
344
|
+
expressir coverage --exclude=TYPE:SELECT,TYPE:ENUMERATION schemas/resources/action_schema/action_schema.exp
|
345
|
+
----
|
346
|
+
|
347
|
+
==== FUNCTION subtype exclusion
|
348
|
+
|
349
|
+
For FUNCTION elements, you can exclude inner functions (functions nested within
|
350
|
+
other functions, rules, or procedures) using the `FUNCTION:INNER` syntax:
|
351
|
+
|
352
|
+
[source, sh]
|
353
|
+
----
|
354
|
+
# Exclude inner functions from coverage analysis
|
355
|
+
expressir coverage --exclude=FUNCTION:INNER schemas/resources/action_schema/action_schema.exp
|
356
|
+
|
357
|
+
# Combine with other exclusions
|
358
|
+
expressir coverage --exclude=TYPE:SELECT,FUNCTION:INNER schemas/resources/action_schema/action_schema.exp
|
359
|
+
----
|
360
|
+
|
361
|
+
This is useful when you want to focus documentation coverage on top-level
|
362
|
+
functions while excluding nested helper functions that may not require
|
363
|
+
individual documentation.
|
364
|
+
|
365
|
+
Valid FUNCTION subtypes that can be excluded:
|
366
|
+
|
367
|
+
`INNER`:: Inner functions nested within other functions, rules, or procedures
|
368
|
+
+
|
369
|
+
[example]
|
370
|
+
====
|
371
|
+
----
|
372
|
+
FUNCTION outer_function : BOOLEAN;
|
373
|
+
-- This inner function would be excluded with FUNCTION:INNER
|
374
|
+
FUNCTION inner_helper_function : BOOLEAN;
|
375
|
+
RETURN (TRUE);
|
376
|
+
END_FUNCTION;
|
377
|
+
|
378
|
+
RETURN (TRUE);
|
379
|
+
END_FUNCTION;
|
380
|
+
----
|
381
|
+
====
|
382
|
+
|
383
|
+
Valid TYPE subtypes that can be excluded:
|
384
|
+
|
385
|
+
`AGGREGATE`:: Aggregate type
|
386
|
+
`ARRAY`:: Array type
|
387
|
+
`BAG`:: Bag type
|
388
|
+
`BINARY`:: Binary type
|
389
|
+
`BOOLEAN`:: Boolean type
|
390
|
+
`ENUMERATION`:: Enumeration type
|
391
|
+
+
|
392
|
+
[example]
|
393
|
+
====
|
394
|
+
----
|
395
|
+
TYPE uuid_relationship_role = ENUMERATION OF
|
396
|
+
(supersedes,
|
397
|
+
merge,
|
398
|
+
split,
|
399
|
+
derive_from,
|
400
|
+
same_as,
|
401
|
+
similar_to);
|
402
|
+
END_TYPE;
|
403
|
+
----
|
404
|
+
====
|
405
|
+
|
406
|
+
`GENERIC`:: Generic type
|
407
|
+
`GENERIC_ENTITY`:: Generic entity type
|
408
|
+
+
|
409
|
+
[example]
|
410
|
+
====
|
411
|
+
----
|
412
|
+
TYPE uuid_attribute_select = EXTENSIBLE GENERIC_ENTITY SELECT;
|
413
|
+
END_TYPE;
|
414
|
+
----
|
415
|
+
====
|
416
|
+
|
417
|
+
`INTEGER`:: Integer type
|
418
|
+
`LIST`:: List type
|
419
|
+
+
|
420
|
+
[example]
|
421
|
+
====
|
422
|
+
----
|
423
|
+
TYPE uuid_list_item = LIST [1:?] OF UNIQUE LIST [1:?] OF UNIQUE uuid_attribute_select;
|
424
|
+
END_TYPE;
|
425
|
+
----
|
426
|
+
====
|
427
|
+
|
428
|
+
`LOGICAL`:: Logical type
|
429
|
+
`NUMBER`:: Number type
|
430
|
+
`REAL`:: Real type
|
431
|
+
`SELECT`:: Select type
|
432
|
+
+
|
433
|
+
[example]
|
434
|
+
====
|
435
|
+
----
|
436
|
+
TYPE uuid_set_or_list_attribute_select = SELECT
|
437
|
+
(uuid_list_item,
|
438
|
+
uuid_set_item);
|
439
|
+
END_TYPE;
|
440
|
+
----
|
441
|
+
====
|
442
|
+
|
443
|
+
`SET`:: Set type
|
444
|
+
+
|
445
|
+
[example]
|
446
|
+
====
|
294
447
|
----
|
448
|
+
TYPE uuid_set_item = SET [1:?] OF uuid_attribute_select;
|
449
|
+
END_TYPE;
|
450
|
+
----
|
451
|
+
====
|
452
|
+
|
453
|
+
`STRING`::
|
454
|
+
String type
|
455
|
+
+
|
456
|
+
[example]
|
457
|
+
====
|
458
|
+
----
|
459
|
+
TYPE uuid = STRING (36) FIXED;
|
460
|
+
END_TYPE;
|
461
|
+
----
|
462
|
+
====
|
295
463
|
|
296
|
-
|
464
|
+
This is particularly useful since TYPE entities with certain subtypes (like
|
465
|
+
SELECT) often have descriptions generated by template strings and may not
|
466
|
+
require individual remark item coverage.
|
297
467
|
|
298
|
-
|
299
|
-
|
300
|
-
* `CONSTANT` - Constant definitions
|
301
|
-
* `FUNCTION` - Function definitions
|
302
|
-
* `RULE` - Rule definitions
|
303
|
-
* `PROCEDURE` - Procedure definitions
|
304
|
-
* `SUBTYPE_CONSTRAINT` - Subtype constraint definitions
|
468
|
+
NOTE: ISO 10303 excludes documentation coverage for TYPE:SELECT and
|
469
|
+
TYPE:ENUMERATION.
|
305
470
|
|
306
|
-
If you specify an invalid entity type, the command will display an
|
307
|
-
with the list of valid
|
471
|
+
If you specify an invalid entity type or subtype, the command will display an
|
472
|
+
error message with the list of valid options.
|
308
473
|
|
309
474
|
.Example with JSON output:
|
310
475
|
[example]
|
data/expressir.gemspec
CHANGED
data/lib/expressir/cli.rb
CHANGED
@@ -55,7 +55,8 @@ module Expressir
|
|
55
55
|
|
56
56
|
desc "coverage *PATH", "List EXPRESS entities and check documentation coverage"
|
57
57
|
method_option :format, type: :string, desc: "Output format (text, json, yaml)", default: "text"
|
58
|
-
method_option :exclude, type: :string, desc: "Comma-separated list of EXPRESS entity types to skip from coverage (e.g., TYPE,CONSTANT)"
|
58
|
+
method_option :exclude, type: :string, desc: "Comma-separated list of EXPRESS entity types to skip from coverage (e.g., TYPE,CONSTANT,TYPE:SELECT)"
|
59
|
+
method_option :output, type: :string, desc: "Output file path for JSON/YAML formats (defaults to coverage_report.json/yaml)"
|
59
60
|
def coverage(*paths)
|
60
61
|
Commands::Coverage.new(options).run(paths)
|
61
62
|
end
|
@@ -275,33 +275,74 @@ module Expressir
|
|
275
275
|
end
|
276
276
|
|
277
277
|
def display_json_output(reports)
|
278
|
-
|
278
|
+
output_file = options[:output] || "coverage_report.json"
|
279
|
+
File.write(output_file, JSON.pretty_generate(build_structured_report(reports)))
|
280
|
+
say "JSON coverage report written to: #{output_file}"
|
279
281
|
end
|
280
282
|
|
281
283
|
def display_yaml_output(reports)
|
282
|
-
|
284
|
+
output_file = options[:output] || "coverage_report.yaml"
|
285
|
+
File.write(output_file, build_structured_report(reports).to_yaml)
|
286
|
+
say "YAML coverage report written to: #{output_file}"
|
283
287
|
end
|
284
288
|
|
285
289
|
# Parse and validate the skip_types option
|
286
290
|
# @return [Array<String>] Array of validated entity type names
|
287
291
|
def parse_skip_types
|
288
|
-
skip_types_option = options["exclude"]
|
292
|
+
skip_types_option = options["exclude"] || options[:exclude]
|
289
293
|
return [] unless skip_types_option
|
290
294
|
|
291
|
-
#
|
292
|
-
requested_types = skip_types_option.
|
295
|
+
# Handle both string (comma-separated) and array inputs
|
296
|
+
requested_types = if skip_types_option.is_a?(Array)
|
297
|
+
skip_types_option.map(&:to_s).map(&:strip).map(&:upcase)
|
298
|
+
else
|
299
|
+
skip_types_option.split(",").map(&:strip).map(&:upcase)
|
300
|
+
end
|
293
301
|
|
294
|
-
# Validate
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
unless invalid_types.empty?
|
299
|
-
exit_with_error "Invalid entity types: #{invalid_types.join(', ')}. " \
|
300
|
-
"Valid types are: #{valid_types.join(', ')}"
|
302
|
+
# Validate each type (supports both TYPE and TYPE:SUBTYPE formats)
|
303
|
+
requested_types.each do |type|
|
304
|
+
validate_skip_type(type)
|
301
305
|
end
|
302
306
|
|
303
307
|
requested_types
|
304
308
|
end
|
309
|
+
|
310
|
+
# Validate a single skip type (supports TYPE:SUBTYPE and FUNCTION:SUBTYPE syntax)
|
311
|
+
# @param type [String] The type to validate
|
312
|
+
def validate_skip_type(type)
|
313
|
+
if type.include?(":")
|
314
|
+
# Handle TYPE:SUBTYPE and FUNCTION:SUBTYPE format
|
315
|
+
main_type, subtype = type.split(":", 2)
|
316
|
+
|
317
|
+
# Validate main type
|
318
|
+
unless Expressir::Coverage::ENTITY_TYPE_MAP.key?(main_type)
|
319
|
+
exit_with_error "Invalid entity type: #{main_type}. " \
|
320
|
+
"Valid types are: #{Expressir::Coverage::ENTITY_TYPE_MAP.keys.join(', ')}"
|
321
|
+
end
|
322
|
+
|
323
|
+
# For TYPE, validate subtype
|
324
|
+
if main_type == "TYPE"
|
325
|
+
unless Expressir::Coverage::TYPE_SUBTYPES.include?(subtype)
|
326
|
+
exit_with_error "Invalid TYPE subtype: #{subtype}. " \
|
327
|
+
"Valid TYPE subtypes are: #{Expressir::Coverage::TYPE_SUBTYPES.join(', ')}"
|
328
|
+
end
|
329
|
+
# For FUNCTION, validate subtype
|
330
|
+
elsif main_type == "FUNCTION"
|
331
|
+
unless subtype == "INNER"
|
332
|
+
exit_with_error "Invalid FUNCTION subtype: #{subtype}. " \
|
333
|
+
"Valid FUNCTION subtypes are: INNER"
|
334
|
+
end
|
335
|
+
else
|
336
|
+
exit_with_error "Subtype syntax (#{type}) is only supported for TYPE and FUNCTION entities"
|
337
|
+
end
|
338
|
+
else
|
339
|
+
# Handle simple type format
|
340
|
+
unless Expressir::Coverage::ENTITY_TYPE_MAP.key?(type)
|
341
|
+
exit_with_error "Invalid entity type: #{type}. " \
|
342
|
+
"Valid types are: #{Expressir::Coverage::ENTITY_TYPE_MAP.keys.join(', ')}"
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
305
346
|
end
|
306
347
|
end
|
307
348
|
end
|
data/lib/expressir/coverage.rb
CHANGED
@@ -12,7 +12,50 @@ module Expressir
|
|
12
12
|
"RULE" => "Expressir::Model::Declarations::Rule",
|
13
13
|
"PROCEDURE" => "Expressir::Model::Declarations::Procedure",
|
14
14
|
"SUBTYPE_CONSTRAINT" => "Expressir::Model::Declarations::SubtypeConstraint",
|
15
|
+
"PARAMETER" => "Expressir::Model::Declarations::Parameter",
|
16
|
+
"VARIABLE" => "Expressir::Model::Declarations::Variable",
|
17
|
+
"ATTRIBUTE" => "Expressir::Model::Declarations::Attribute",
|
18
|
+
"DERIVED_ATTRIBUTE" => "Expressir::Model::Declarations::DerivedAttribute",
|
19
|
+
"INVERSE_ATTRIBUTE" => "Expressir::Model::Declarations::InverseAttribute",
|
20
|
+
"UNIQUE_RULE" => "Expressir::Model::Declarations::UniqueRule",
|
21
|
+
"WHERE_RULE" => "Expressir::Model::Declarations::WhereRule",
|
22
|
+
"ENUMERATION_ITEM" => "Expressir::Model::DataTypes::EnumerationItem",
|
23
|
+
"INTERFACE" => "Expressir::Model::Declarations::Interface",
|
24
|
+
"INTERFACE_ITEM" => "Expressir::Model::Declarations::InterfaceItem",
|
25
|
+
"INTERFACED_ITEM" => "Expressir::Model::Declarations::InterfacedItem",
|
26
|
+
"SCHEMA_VERSION" => "Expressir::Model::Declarations::SchemaVersion",
|
27
|
+
"SCHEMA_VERSION_ITEM" => "Expressir::Model::Declarations::SchemaVersionItem",
|
15
28
|
}.freeze
|
29
|
+
|
30
|
+
# Mapping of class names to EXPRESS entity type names (for proper formatting)
|
31
|
+
CLASS_TO_EXPRESS_TYPE_MAP = {
|
32
|
+
"Type" => "TYPE",
|
33
|
+
"Entity" => "ENTITY",
|
34
|
+
"Constant" => "CONSTANT",
|
35
|
+
"Function" => "FUNCTION",
|
36
|
+
"Rule" => "RULE",
|
37
|
+
"Procedure" => "PROCEDURE",
|
38
|
+
"SubtypeConstraint" => "SUBTYPE_CONSTRAINT",
|
39
|
+
"Parameter" => "PARAMETER",
|
40
|
+
"Variable" => "VARIABLE",
|
41
|
+
"Attribute" => "ATTRIBUTE",
|
42
|
+
"DerivedAttribute" => "DERIVED_ATTRIBUTE",
|
43
|
+
"InverseAttribute" => "INVERSE_ATTRIBUTE",
|
44
|
+
"UniqueRule" => "UNIQUE_RULE",
|
45
|
+
"WhereRule" => "WHERE_RULE",
|
46
|
+
"EnumerationItem" => "ENUMERATION_ITEM",
|
47
|
+
"Interface" => "INTERFACE",
|
48
|
+
"InterfaceItem" => "INTERFACE_ITEM",
|
49
|
+
"InterfacedItem" => "INTERFACED_ITEM",
|
50
|
+
"SchemaVersion" => "SCHEMA_VERSION",
|
51
|
+
"SchemaVersionItem" => "SCHEMA_VERSION_ITEM",
|
52
|
+
}.freeze
|
53
|
+
|
54
|
+
# Available TYPE subtypes based on data types
|
55
|
+
TYPE_SUBTYPES = %w[
|
56
|
+
AGGREGATE ARRAY BAG BINARY BOOLEAN ENUMERATION GENERIC GENERIC_ENTITY
|
57
|
+
INTEGER LIST LOGICAL NUMBER REAL SELECT SET STRING
|
58
|
+
].freeze
|
16
59
|
# Represents a documentation coverage report for EXPRESS schemas
|
17
60
|
class Report
|
18
61
|
attr_reader :repository, :schema_reports, :total_entities, :documented_entities,
|
@@ -173,8 +216,8 @@ module Expressir
|
|
173
216
|
# Get class name (e.g., "Type" from "Expressir::Model::Declarations::Type")
|
174
217
|
type_name = entity.class.name.split("::").last
|
175
218
|
|
176
|
-
#
|
177
|
-
express_type = type_name.upcase
|
219
|
+
# Use proper mapping to EXPRESS convention
|
220
|
+
express_type = CLASS_TO_EXPRESS_TYPE_MAP[type_name] || type_name.upcase
|
178
221
|
|
179
222
|
# Return structured format
|
180
223
|
{
|
@@ -209,11 +252,35 @@ module Expressir
|
|
209
252
|
end
|
210
253
|
end
|
211
254
|
|
212
|
-
# Find all entities in a schema
|
213
|
-
# @param
|
255
|
+
# Find all entities in a schema or repository
|
256
|
+
# @param schema_or_repo [Expressir::Model::Declarations::Schema, Expressir::Model::Repository] The schema or repository to analyze
|
214
257
|
# @param skip_types [Array<String>] Array of entity type names to skip from coverage
|
215
258
|
# @return [Array<Expressir::Model::ModelElement>] Array of entities
|
216
|
-
def self.find_entities(
|
259
|
+
def self.find_entities(schema_or_repo, skip_types = [])
|
260
|
+
entities = []
|
261
|
+
|
262
|
+
# Handle both repository and schema inputs
|
263
|
+
if schema_or_repo.is_a?(Expressir::Model::Repository)
|
264
|
+
# If it's a repository, process all schemas
|
265
|
+
schema_or_repo.schemas.each do |schema|
|
266
|
+
entities.concat(find_entities_in_schema(schema))
|
267
|
+
end
|
268
|
+
else
|
269
|
+
# If it's a schema, process it directly
|
270
|
+
entities.concat(find_entities_in_schema(schema_or_repo))
|
271
|
+
end
|
272
|
+
|
273
|
+
# Filter out any nil elements and ensure all have IDs
|
274
|
+
entities = entities.compact.select { |e| e.respond_to?(:id) && e.id }
|
275
|
+
|
276
|
+
# Filter out skipped entity types
|
277
|
+
apply_exclusions(entities, skip_types)
|
278
|
+
end
|
279
|
+
|
280
|
+
# Find all entities in a single schema
|
281
|
+
# @param schema [Expressir::Model::Declarations::Schema] The schema to analyze
|
282
|
+
# @return [Array<Expressir::Model::ModelElement>] Array of entities
|
283
|
+
def self.find_entities_in_schema(schema)
|
217
284
|
entities = []
|
218
285
|
|
219
286
|
# Add all schema-level entities
|
@@ -224,26 +291,203 @@ module Expressir
|
|
224
291
|
entities.concat(schema.rules) if schema.rules
|
225
292
|
entities.concat(schema.procedures) if schema.procedures
|
226
293
|
entities.concat(schema.subtype_constraints) if schema.subtype_constraints
|
294
|
+
entities.concat(schema.interfaces) if schema.interfaces
|
295
|
+
|
296
|
+
# Add nested entities recursively
|
297
|
+
entities.concat(find_nested_entities(schema))
|
298
|
+
|
299
|
+
entities
|
300
|
+
end
|
301
|
+
|
302
|
+
# Find all nested entities within a container (schema, entity, function, etc.)
|
303
|
+
# @param container [Expressir::Model::ModelElement] The container to search
|
304
|
+
# @return [Array<Expressir::Model::ModelElement>] Array of nested entities
|
305
|
+
def self.find_nested_entities(container)
|
306
|
+
entities = []
|
307
|
+
|
308
|
+
# Handle different container types
|
309
|
+
case container
|
310
|
+
when Expressir::Model::Declarations::Schema
|
311
|
+
# Schema-level nested entities
|
312
|
+
container.types&.each do |type|
|
313
|
+
entities.concat(find_nested_entities(type))
|
314
|
+
end
|
315
|
+
container.entities&.each do |entity|
|
316
|
+
entities.concat(find_nested_entities(entity))
|
317
|
+
end
|
318
|
+
container.functions&.each do |function|
|
319
|
+
entities.concat(find_nested_entities(function))
|
320
|
+
end
|
321
|
+
container.rules&.each do |rule|
|
322
|
+
entities.concat(find_nested_entities(rule))
|
323
|
+
end
|
324
|
+
container.procedures&.each do |procedure|
|
325
|
+
entities.concat(find_nested_entities(procedure))
|
326
|
+
end
|
327
|
+
container.interfaces&.each do |interface|
|
328
|
+
entities.concat(find_nested_entities(interface))
|
329
|
+
end
|
330
|
+
|
331
|
+
when Expressir::Model::Declarations::Type
|
332
|
+
# Type nested entities
|
333
|
+
if container.respond_to?(:enumeration_items) && container.enumeration_items
|
334
|
+
entities.concat(container.enumeration_items)
|
335
|
+
end
|
336
|
+
|
337
|
+
when Expressir::Model::Declarations::Entity
|
338
|
+
# Entity nested entities
|
339
|
+
entities.concat(container.attributes) if container.attributes
|
340
|
+
entities.concat(container.unique_rules) if container.unique_rules
|
341
|
+
entities.concat(container.where_rules) if container.where_rules
|
342
|
+
|
343
|
+
when Expressir::Model::Declarations::Function
|
344
|
+
# Function nested entities
|
345
|
+
entities.concat(container.parameters) if container.parameters
|
346
|
+
entities.concat(container.variables) if container.variables
|
347
|
+
entities.concat(container.constants) if container.constants
|
348
|
+
entities.concat(container.types) if container.types
|
349
|
+
entities.concat(container.entities) if container.entities
|
350
|
+
entities.concat(container.functions) if container.functions
|
351
|
+
entities.concat(container.procedures) if container.procedures
|
352
|
+
entities.concat(container.subtype_constraints) if container.subtype_constraints
|
353
|
+
|
354
|
+
# Recursively find nested entities in nested containers
|
355
|
+
container.types&.each { |type| entities.concat(find_nested_entities(type)) }
|
356
|
+
container.entities&.each { |entity| entities.concat(find_nested_entities(entity)) }
|
357
|
+
container.functions&.each { |function| entities.concat(find_nested_entities(function)) }
|
358
|
+
container.procedures&.each { |procedure| entities.concat(find_nested_entities(procedure)) }
|
359
|
+
|
360
|
+
when Expressir::Model::Declarations::Rule
|
361
|
+
# Rule nested entities
|
362
|
+
entities.concat(container.variables) if container.variables
|
363
|
+
entities.concat(container.constants) if container.constants
|
364
|
+
entities.concat(container.types) if container.types
|
365
|
+
entities.concat(container.entities) if container.entities
|
366
|
+
entities.concat(container.functions) if container.functions
|
367
|
+
entities.concat(container.procedures) if container.procedures
|
368
|
+
entities.concat(container.subtype_constraints) if container.subtype_constraints
|
369
|
+
|
370
|
+
# Recursively find nested entities in nested containers
|
371
|
+
container.types&.each { |type| entities.concat(find_nested_entities(type)) }
|
372
|
+
container.entities&.each { |entity| entities.concat(find_nested_entities(entity)) }
|
373
|
+
container.functions&.each { |function| entities.concat(find_nested_entities(function)) }
|
374
|
+
container.procedures&.each { |procedure| entities.concat(find_nested_entities(procedure)) }
|
375
|
+
|
376
|
+
when Expressir::Model::Declarations::Procedure
|
377
|
+
# Procedure nested entities
|
378
|
+
entities.concat(container.parameters) if container.parameters
|
379
|
+
entities.concat(container.variables) if container.variables
|
380
|
+
entities.concat(container.constants) if container.constants
|
381
|
+
entities.concat(container.types) if container.types
|
382
|
+
entities.concat(container.entities) if container.entities
|
383
|
+
entities.concat(container.functions) if container.functions
|
384
|
+
entities.concat(container.procedures) if container.procedures
|
385
|
+
entities.concat(container.subtype_constraints) if container.subtype_constraints
|
386
|
+
|
387
|
+
# Recursively find nested entities in nested containers
|
388
|
+
container.types&.each { |type| entities.concat(find_nested_entities(type)) }
|
389
|
+
container.entities&.each { |entity| entities.concat(find_nested_entities(entity)) }
|
390
|
+
container.functions&.each { |function| entities.concat(find_nested_entities(function)) }
|
391
|
+
container.procedures&.each { |procedure| entities.concat(find_nested_entities(procedure)) }
|
392
|
+
|
393
|
+
when Expressir::Model::Declarations::Interface
|
394
|
+
# Interface nested entities
|
395
|
+
entities.concat(container.items) if container.items
|
396
|
+
end
|
397
|
+
|
398
|
+
entities
|
399
|
+
end
|
400
|
+
|
401
|
+
# Apply exclusions to filter out entities based on skip_types (supports both simple and TYPE:SUBTYPE syntax)
|
402
|
+
# @param entities [Array<Expressir::Model::ModelElement>] The entities to filter
|
403
|
+
# @param exclusions [Array<String>] Array of entity type names to exclude from coverage
|
404
|
+
# @return [Array<Expressir::Model::ModelElement>] Filtered entities
|
405
|
+
def self.apply_exclusions(entities, exclusions)
|
406
|
+
filter_skipped_entities(entities, exclusions)
|
407
|
+
end
|
227
408
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
409
|
+
# Filter out entities based on skip_types (supports both simple and TYPE:SUBTYPE syntax)
|
410
|
+
# @param entities [Array<Expressir::Model::ModelElement>] The entities to filter
|
411
|
+
# @param skip_types [Array<String>] Array of entity type names to skip from coverage
|
412
|
+
# @return [Array<Expressir::Model::ModelElement>] Filtered entities
|
413
|
+
def self.filter_skipped_entities(entities, skip_types)
|
414
|
+
return entities if skip_types.empty?
|
415
|
+
|
416
|
+
# Parse skip_types into simple types, TYPE subtypes, and FUNCTION subtypes
|
417
|
+
simple_skips = []
|
418
|
+
type_subtype_skips = []
|
419
|
+
function_subtype_skips = []
|
420
|
+
|
421
|
+
skip_types.each do |skip_type|
|
422
|
+
if skip_type.include?(":")
|
423
|
+
# Handle TYPE:SUBTYPE and FUNCTION:SUBTYPE format
|
424
|
+
main_type, subtype = skip_type.split(":", 2)
|
425
|
+
if main_type == "TYPE" && TYPE_SUBTYPES.include?(subtype)
|
426
|
+
type_subtype_skips << subtype
|
427
|
+
elsif main_type == "FUNCTION" && subtype == "INNER"
|
428
|
+
function_subtype_skips << subtype
|
233
429
|
end
|
430
|
+
else
|
431
|
+
# Handle simple type format
|
432
|
+
simple_skips << skip_type
|
234
433
|
end
|
235
434
|
end
|
236
435
|
|
237
|
-
# Filter
|
238
|
-
entities
|
436
|
+
# Filter entities
|
437
|
+
entities.reject do |entity|
|
438
|
+
entity_class = entity.class.name
|
439
|
+
|
440
|
+
# Check simple type exclusions
|
441
|
+
# Convert entity class to EXPRESS type name for comparison
|
442
|
+
class_name = entity_class.split("::").last
|
443
|
+
express_type = CLASS_TO_EXPRESS_TYPE_MAP[class_name] || class_name.upcase
|
444
|
+
|
445
|
+
if simple_skips.include?(express_type)
|
446
|
+
true
|
447
|
+
# Check TYPE subtype exclusions
|
448
|
+
elsif entity_class == "Expressir::Model::Declarations::Type" && type_subtype_skips.any?
|
449
|
+
entity_subtype = get_type_subtype(entity)
|
450
|
+
type_subtype_skips.include?(entity_subtype)
|
451
|
+
# Check FUNCTION:INNER exclusions
|
452
|
+
elsif entity_class == "Expressir::Model::Declarations::Function" && function_subtype_skips.include?("INNER")
|
453
|
+
is_inner_function?(entity)
|
454
|
+
else
|
455
|
+
false
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
239
459
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
460
|
+
# Get the subtype of a TYPE entity based on its underlying_type
|
461
|
+
# @param type_entity [Expressir::Model::Declarations::Type] The TYPE entity
|
462
|
+
# @return [String] The subtype name (e.g., "SELECT", "ENUMERATION")
|
463
|
+
def self.get_type_subtype(type_entity)
|
464
|
+
return nil unless type_entity.respond_to?(:underlying_type) && type_entity.underlying_type
|
465
|
+
|
466
|
+
# Get the class name of the underlying type
|
467
|
+
underlying_class = type_entity.underlying_type.class.name
|
468
|
+
|
469
|
+
# Extract the data type name (e.g., "Select" from "Expressir::Model::DataTypes::Select")
|
470
|
+
if underlying_class.start_with?("Expressir::Model::DataTypes::")
|
471
|
+
data_type_name = underlying_class.split("::").last
|
472
|
+
# Convert to uppercase (e.g., "Select" -> "SELECT")
|
473
|
+
data_type_name.upcase
|
474
|
+
else
|
475
|
+
# For other types, try to extract the last part of the class name
|
476
|
+
underlying_class.split("::").last&.upcase
|
244
477
|
end
|
478
|
+
end
|
245
479
|
|
246
|
-
|
480
|
+
# Check if a function is an inner function (nested within another function, rule, or procedure)
|
481
|
+
# @param function_entity [Expressir::Model::Declarations::Function] The function entity to check
|
482
|
+
# @return [Boolean] True if the function is nested within another function, rule, or procedure
|
483
|
+
def self.is_inner_function?(function_entity)
|
484
|
+
return false unless function_entity.respond_to?(:parent) && function_entity.parent
|
485
|
+
|
486
|
+
# Check if the parent is a function, rule, or procedure (not a schema)
|
487
|
+
parent = function_entity.parent
|
488
|
+
parent.is_a?(Expressir::Model::Declarations::Function) ||
|
489
|
+
parent.is_a?(Expressir::Model::Declarations::Rule) ||
|
490
|
+
parent.is_a?(Expressir::Model::Declarations::Procedure)
|
247
491
|
end
|
248
492
|
end
|
249
493
|
end
|
@@ -208,7 +208,8 @@ module Expressir
|
|
208
208
|
private
|
209
209
|
|
210
210
|
def format_repository(node)
|
211
|
-
node.schemas&.map { |x| format(x) }&.join("\n\n")
|
211
|
+
result = node.schemas&.map { |x| format(x) }&.join("\n\n")
|
212
|
+
result ? "#{result}\n" : ""
|
212
213
|
end
|
213
214
|
|
214
215
|
def format_declarations_attribute(node)
|
@@ -1615,39 +1616,65 @@ module Expressir
|
|
1615
1616
|
end
|
1616
1617
|
|
1617
1618
|
def format_remark(node, remark)
|
1619
|
+
# Handle embedded remarks
|
1618
1620
|
if remark.include?("\n")
|
1619
1621
|
[
|
1620
1622
|
[
|
1621
|
-
"(
|
1622
|
-
'"',
|
1623
|
+
"(*\"",
|
1623
1624
|
node.path || node.id,
|
1624
|
-
|
1625
|
+
"\"",
|
1625
1626
|
].join,
|
1626
1627
|
remark,
|
1627
1628
|
"*)",
|
1628
1629
|
].join("\n")
|
1629
1630
|
else
|
1631
|
+
# Handle tail remarks
|
1630
1632
|
[
|
1631
|
-
"
|
1632
|
-
'"',
|
1633
|
+
"--\"",
|
1633
1634
|
node.path || node.id,
|
1634
|
-
|
1635
|
-
|
1635
|
+
"\" ",
|
1636
|
+
remark,
|
1637
|
+
].join
|
1638
|
+
end
|
1639
|
+
end
|
1640
|
+
|
1641
|
+
def format_untagged_remark(remark)
|
1642
|
+
# Handle embedded remarks
|
1643
|
+
if remark.include?("\n")
|
1644
|
+
[
|
1645
|
+
"(*",
|
1646
|
+
remark,
|
1647
|
+
"*)",
|
1648
|
+
].join("\n")
|
1649
|
+
else
|
1650
|
+
# Handle tail remarks
|
1651
|
+
[
|
1652
|
+
"-- ",
|
1636
1653
|
remark,
|
1637
1654
|
].join
|
1638
1655
|
end
|
1639
1656
|
end
|
1640
1657
|
|
1641
1658
|
def format_remarks(node)
|
1659
|
+
remarks = []
|
1660
|
+
|
1661
|
+
# Add tagged remarks
|
1642
1662
|
if node.class.method_defined?(:remarks) && !@no_remarks &&
|
1643
1663
|
!node.remarks.nil?
|
1644
|
-
|
1645
|
-
node.remarks.map do |remark|
|
1664
|
+
remarks.concat(node.remarks.map do |remark|
|
1646
1665
|
format_remark(node, remark)
|
1647
|
-
end
|
1648
|
-
|
1649
|
-
|
1666
|
+
end)
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
# Add untagged remarks
|
1670
|
+
if node.respond_to?(:untagged_remarks) && !@no_remarks &&
|
1671
|
+
!node.untagged_remarks.nil?
|
1672
|
+
remarks.concat(node.untagged_remarks.map do |remark|
|
1673
|
+
format_untagged_remark(remark)
|
1674
|
+
end)
|
1650
1675
|
end
|
1676
|
+
|
1677
|
+
remarks
|
1651
1678
|
end
|
1652
1679
|
|
1653
1680
|
def format_scope_remarks(node)
|
@@ -271,32 +271,67 @@ module Expressir
|
|
271
271
|
remark_tokens = remark_tokens.reject { |x| @attached_remark_tokens.include?(x) }
|
272
272
|
|
273
273
|
# parse remarks, find remark targets
|
274
|
-
tagged_remark_tokens =
|
274
|
+
tagged_remark_tokens = []
|
275
|
+
untagged_remark_tokens = []
|
276
|
+
|
277
|
+
remark_tokens.each do |span|
|
275
278
|
text = @source[span[0]..span[1] - 1]
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
if
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
279
|
+
remark_type = if text.start_with?("--")
|
280
|
+
:tail
|
281
|
+
else
|
282
|
+
:embedded
|
283
|
+
end
|
284
|
+
|
285
|
+
if text.start_with?("--\"") && text.include?("\"")
|
286
|
+
# Tagged tail remark: --"tag" content
|
287
|
+
quote_end = text.index("\"", 3)
|
288
|
+
if quote_end
|
289
|
+
remark_target_path = text[3...quote_end]
|
290
|
+
remark_text = text[(quote_end + 1)..].strip.force_encoding("UTF-8")
|
291
|
+
remark_target = find_remark_target(node, remark_target_path)
|
292
|
+
if remark_target
|
293
|
+
tagged_remark_tokens << [span, remark_target, remark_text]
|
294
|
+
end
|
295
|
+
end
|
296
|
+
elsif text.start_with?("(*\"") && text.include?("\"")
|
297
|
+
# Tagged embedded remark: (*"tag" content *)
|
298
|
+
quote_end = text.index("\"", 3)
|
299
|
+
if quote_end
|
300
|
+
remark_target_path = text[3...quote_end]
|
301
|
+
remark_text = text[(quote_end + 1)...-2].strip.force_encoding("UTF-8")
|
302
|
+
remark_target = find_remark_target(node, remark_target_path)
|
303
|
+
if remark_target
|
304
|
+
tagged_remark_tokens << [span, remark_target, remark_text]
|
305
|
+
end
|
306
|
+
end
|
307
|
+
elsif text.start_with?("--")
|
308
|
+
# Untagged tail remark: -- content
|
309
|
+
untagged_text = text[2..].strip.force_encoding("UTF-8")
|
310
|
+
untagged_remark_tokens << [span, untagged_text, remark_type]
|
311
|
+
else
|
312
|
+
# Untagged embedded remark: (* content *)
|
313
|
+
untagged_text = text[2...-2].strip.force_encoding("UTF-8")
|
314
|
+
untagged_remark_tokens << [span, untagged_text, remark_type]
|
287
315
|
end
|
316
|
+
end
|
288
317
|
|
289
|
-
|
290
|
-
end.select { |x| x[1] }
|
291
|
-
|
318
|
+
# Attach tagged remarks
|
292
319
|
tagged_remark_tokens.each do |span, remark_target, remark_text|
|
293
|
-
# attach remark
|
294
320
|
remark_target.remarks ||= []
|
295
321
|
remark_target.remarks << remark_text
|
296
|
-
|
297
|
-
# mark remark as attached, so that it is not attached again at higher nesting level
|
298
322
|
@attached_remark_tokens << span
|
299
323
|
end
|
324
|
+
|
325
|
+
# Attach untagged remarks to the current node if it supports them
|
326
|
+
# All ModelElements support untagged remarks, but we may get Arrays here
|
327
|
+
if node.respond_to?(:untagged_remarks) && !untagged_remark_tokens.empty?
|
328
|
+
node.untagged_remarks ||= []
|
329
|
+
untagged_remark_tokens.each do |span, untagged_text, _remark_type|
|
330
|
+
# Handle both embedded and tail remarks
|
331
|
+
node.untagged_remarks << untagged_text
|
332
|
+
@attached_remark_tokens << span
|
333
|
+
end
|
334
|
+
end
|
300
335
|
end
|
301
336
|
|
302
337
|
def visit_attribute_ref(ctx)
|
@@ -5,11 +5,13 @@ module Expressir
|
|
5
5
|
mod.attribute :id, :string
|
6
6
|
mod.attribute :remarks, :string, collection: true
|
7
7
|
mod.attribute :remark_items, ::Expressir::Model::Declarations::RemarkItem, collection: true
|
8
|
+
mod.attribute :untagged_remarks, :string, collection: true
|
8
9
|
|
9
10
|
mod.key_value do
|
10
11
|
map "id", to: :id
|
11
12
|
map "remarks", to: :remarks
|
12
13
|
map "remark_items", to: :remark_items
|
14
|
+
map "untagged_remarks", to: :untagged_remarks
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -13,6 +13,7 @@ module Expressir
|
|
13
13
|
attribute :_class, :string, default: -> { send(:name) },
|
14
14
|
polymorphic_class: true
|
15
15
|
attribute :source, :string
|
16
|
+
attribute :untagged_remarks, :string, collection: true
|
16
17
|
|
17
18
|
# TODO: Add basic mappings that can be inherited by all subclasses
|
18
19
|
key_value do
|
data/lib/expressir/model.rb
CHANGED
@@ -1,72 +1,95 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require_relative "model/repository"
|
1
|
+
# This file is kept for backward compatibility and to ensure all model classes are loaded
|
2
|
+
# when explicitly requiring 'expressir/model'. The actual autoload definitions are in the main
|
3
|
+
# expressir.rb file.
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
5
|
+
# Ensure all model classes are loaded by referencing them
|
6
|
+
# This triggers the autoload mechanism for each class
|
7
|
+
|
8
|
+
# Core model classes
|
9
|
+
Expressir::Model::ModelElement
|
10
|
+
Expressir::Model::Cache
|
11
|
+
Expressir::Model::Identifier
|
12
|
+
Expressir::Model::Repository
|
13
|
+
|
14
|
+
# Data types
|
15
|
+
Expressir::Model::DataTypes::Aggregate
|
16
|
+
Expressir::Model::DataTypes::Array
|
17
|
+
Expressir::Model::DataTypes::Bag
|
18
|
+
Expressir::Model::DataTypes::Binary
|
19
|
+
Expressir::Model::DataTypes::Boolean
|
20
|
+
Expressir::Model::DataTypes::Enumeration
|
21
|
+
Expressir::Model::DataTypes::EnumerationItem
|
22
|
+
Expressir::Model::DataTypes::GenericEntity
|
23
|
+
Expressir::Model::DataTypes::Generic
|
24
|
+
Expressir::Model::DataTypes::Integer
|
25
|
+
Expressir::Model::DataTypes::List
|
26
|
+
Expressir::Model::DataTypes::Logical
|
27
|
+
Expressir::Model::DataTypes::Number
|
28
|
+
Expressir::Model::DataTypes::Real
|
29
|
+
Expressir::Model::DataTypes::Select
|
30
|
+
Expressir::Model::DataTypes::Set
|
31
|
+
Expressir::Model::DataTypes::String
|
32
|
+
|
33
|
+
# Declarations
|
34
|
+
Expressir::Model::Declarations::Attribute
|
35
|
+
Expressir::Model::Declarations::Constant
|
36
|
+
Expressir::Model::Declarations::DerivedAttribute
|
37
|
+
Expressir::Model::Declarations::Entity
|
38
|
+
Expressir::Model::Declarations::Function
|
39
|
+
Expressir::Model::Declarations::Interface
|
40
|
+
Expressir::Model::Declarations::InterfaceItem
|
41
|
+
Expressir::Model::Declarations::InterfacedItem
|
42
|
+
Expressir::Model::Declarations::InverseAttribute
|
43
|
+
Expressir::Model::Declarations::Parameter
|
44
|
+
Expressir::Model::Declarations::Procedure
|
45
|
+
Expressir::Model::Declarations::RemarkItem
|
46
|
+
Expressir::Model::Declarations::Rule
|
47
|
+
Expressir::Model::Declarations::Schema
|
48
|
+
Expressir::Model::Declarations::SchemaVersion
|
49
|
+
Expressir::Model::Declarations::SchemaVersionItem
|
50
|
+
Expressir::Model::Declarations::SubtypeConstraint
|
51
|
+
Expressir::Model::Declarations::Type
|
52
|
+
Expressir::Model::Declarations::UniqueRule
|
53
|
+
Expressir::Model::Declarations::Variable
|
54
|
+
Expressir::Model::Declarations::WhereRule
|
55
|
+
|
56
|
+
# Expressions
|
57
|
+
Expressir::Model::Expressions::AggregateInitializer
|
58
|
+
Expressir::Model::Expressions::AggregateInitializerItem
|
59
|
+
Expressir::Model::Expressions::BinaryExpression
|
60
|
+
Expressir::Model::Expressions::EntityConstructor
|
61
|
+
Expressir::Model::Expressions::FunctionCall
|
62
|
+
Expressir::Model::Expressions::Interval
|
63
|
+
Expressir::Model::Expressions::QueryExpression
|
64
|
+
Expressir::Model::Expressions::UnaryExpression
|
65
|
+
|
66
|
+
# Literals
|
67
|
+
Expressir::Model::Literals::Binary
|
68
|
+
Expressir::Model::Literals::Integer
|
69
|
+
Expressir::Model::Literals::Logical
|
70
|
+
Expressir::Model::Literals::Real
|
71
|
+
Expressir::Model::Literals::String
|
72
|
+
|
73
|
+
# References
|
74
|
+
Expressir::Model::References::AttributeReference
|
75
|
+
Expressir::Model::References::GroupReference
|
76
|
+
Expressir::Model::References::IndexReference
|
77
|
+
Expressir::Model::References::SimpleReference
|
78
|
+
|
79
|
+
# Statements
|
80
|
+
Expressir::Model::Statements::Alias
|
81
|
+
Expressir::Model::Statements::Assignment
|
82
|
+
Expressir::Model::Statements::Case
|
83
|
+
Expressir::Model::Statements::CaseAction
|
84
|
+
Expressir::Model::Statements::Compound
|
85
|
+
Expressir::Model::Statements::Escape
|
86
|
+
Expressir::Model::Statements::If
|
87
|
+
Expressir::Model::Statements::Null
|
88
|
+
Expressir::Model::Statements::ProcedureCall
|
89
|
+
Expressir::Model::Statements::Repeat
|
90
|
+
Expressir::Model::Statements::Return
|
91
|
+
Expressir::Model::Statements::Skip
|
92
|
+
|
93
|
+
# Supertype expressions
|
94
|
+
Expressir::Model::SupertypeExpressions::BinarySupertypeExpression
|
95
|
+
Expressir::Model::SupertypeExpressions::OneofSupertypeExpression
|
data/lib/expressir/version.rb
CHANGED
data/lib/expressir.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require "zeitwerk"
|
2
1
|
require_relative "expressir/version"
|
3
2
|
require_relative "expressir/cli"
|
4
3
|
require_relative "expressir/config"
|
@@ -36,13 +35,129 @@ module Expressir
|
|
36
35
|
def self.root_path
|
37
36
|
@root_path ||= Pathname.new(Expressir.root)
|
38
37
|
end
|
39
|
-
end
|
40
38
|
|
41
|
-
|
42
|
-
|
39
|
+
# Autoload for Express module classes
|
40
|
+
module Express
|
41
|
+
autoload :Cache, "expressir/express/cache"
|
42
|
+
autoload :Error, "expressir/express/error"
|
43
|
+
autoload :Formatter, "expressir/express/formatter"
|
44
|
+
autoload :HyperlinkFormatter, "expressir/express/hyperlink_formatter"
|
45
|
+
autoload :ModelVisitor, "expressir/express/model_visitor"
|
46
|
+
autoload :Parser, "expressir/express/parser"
|
47
|
+
autoload :ResolveReferencesModelVisitor, "expressir/express/resolve_references_model_visitor"
|
48
|
+
autoload :SchemaHeadFormatter, "expressir/express/schema_head_formatter"
|
49
|
+
autoload :Visitor, "expressir/express/visitor"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Autoload for Model module classes
|
53
|
+
module Model
|
54
|
+
autoload :ModelElement, "expressir/model/model_element"
|
55
|
+
autoload :Cache, "expressir/model/cache"
|
56
|
+
autoload :Identifier, "expressir/model/identifier"
|
57
|
+
autoload :Repository, "expressir/model/repository"
|
58
|
+
|
59
|
+
module DataTypes
|
60
|
+
autoload :Aggregate, "expressir/model/data_types/aggregate"
|
61
|
+
autoload :Array, "expressir/model/data_types/array"
|
62
|
+
autoload :Bag, "expressir/model/data_types/bag"
|
63
|
+
autoload :Binary, "expressir/model/data_types/binary"
|
64
|
+
autoload :Boolean, "expressir/model/data_types/boolean"
|
65
|
+
autoload :Enumeration, "expressir/model/data_types/enumeration"
|
66
|
+
autoload :EnumerationItem, "expressir/model/data_types/enumeration_item"
|
67
|
+
autoload :GenericEntity, "expressir/model/data_types/generic_entity"
|
68
|
+
autoload :Generic, "expressir/model/data_types/generic"
|
69
|
+
autoload :Integer, "expressir/model/data_types/integer"
|
70
|
+
autoload :List, "expressir/model/data_types/list"
|
71
|
+
autoload :Logical, "expressir/model/data_types/logical"
|
72
|
+
autoload :Number, "expressir/model/data_types/number"
|
73
|
+
autoload :Real, "expressir/model/data_types/real"
|
74
|
+
autoload :Select, "expressir/model/data_types/select"
|
75
|
+
autoload :Set, "expressir/model/data_types/set"
|
76
|
+
autoload :String, "expressir/model/data_types/string"
|
77
|
+
end
|
78
|
+
|
79
|
+
module Declarations
|
80
|
+
autoload :Attribute, "expressir/model/declarations/attribute"
|
81
|
+
autoload :Constant, "expressir/model/declarations/constant"
|
82
|
+
autoload :DerivedAttribute, "expressir/model/declarations/derived_attribute"
|
83
|
+
autoload :Entity, "expressir/model/declarations/entity"
|
84
|
+
autoload :Function, "expressir/model/declarations/function"
|
85
|
+
autoload :Interface, "expressir/model/declarations/interface"
|
86
|
+
autoload :InterfaceItem, "expressir/model/declarations/interface_item"
|
87
|
+
autoload :InterfacedItem, "expressir/model/declarations/interfaced_item"
|
88
|
+
autoload :InverseAttribute, "expressir/model/declarations/inverse_attribute"
|
89
|
+
autoload :Parameter, "expressir/model/declarations/parameter"
|
90
|
+
autoload :Procedure, "expressir/model/declarations/procedure"
|
91
|
+
autoload :RemarkItem, "expressir/model/declarations/remark_item"
|
92
|
+
autoload :Rule, "expressir/model/declarations/rule"
|
93
|
+
autoload :Schema, "expressir/model/declarations/schema"
|
94
|
+
autoload :SchemaVersion, "expressir/model/declarations/schema_version"
|
95
|
+
autoload :SchemaVersionItem, "expressir/model/declarations/schema_version_item"
|
96
|
+
autoload :SubtypeConstraint, "expressir/model/declarations/subtype_constraint"
|
97
|
+
autoload :Type, "expressir/model/declarations/type"
|
98
|
+
autoload :UniqueRule, "expressir/model/declarations/unique_rule"
|
99
|
+
autoload :Variable, "expressir/model/declarations/variable"
|
100
|
+
autoload :WhereRule, "expressir/model/declarations/where_rule"
|
101
|
+
end
|
43
102
|
|
44
|
-
|
45
|
-
|
103
|
+
module Expressions
|
104
|
+
autoload :AggregateInitializer, "expressir/model/expressions/aggregate_initializer"
|
105
|
+
autoload :AggregateInitializerItem, "expressir/model/expressions/aggregate_initializer_item"
|
106
|
+
autoload :BinaryExpression, "expressir/model/expressions/binary_expression"
|
107
|
+
autoload :EntityConstructor, "expressir/model/expressions/entity_constructor"
|
108
|
+
autoload :FunctionCall, "expressir/model/expressions/function_call"
|
109
|
+
autoload :Interval, "expressir/model/expressions/interval"
|
110
|
+
autoload :QueryExpression, "expressir/model/expressions/query_expression"
|
111
|
+
autoload :UnaryExpression, "expressir/model/expressions/unary_expression"
|
112
|
+
end
|
113
|
+
|
114
|
+
module Literals
|
115
|
+
autoload :Binary, "expressir/model/literals/binary"
|
116
|
+
autoload :Integer, "expressir/model/literals/integer"
|
117
|
+
autoload :Logical, "expressir/model/literals/logical"
|
118
|
+
autoload :Real, "expressir/model/literals/real"
|
119
|
+
autoload :String, "expressir/model/literals/string"
|
120
|
+
end
|
121
|
+
|
122
|
+
module References
|
123
|
+
autoload :AttributeReference, "expressir/model/references/attribute_reference"
|
124
|
+
autoload :GroupReference, "expressir/model/references/group_reference"
|
125
|
+
autoload :IndexReference, "expressir/model/references/index_reference"
|
126
|
+
autoload :SimpleReference, "expressir/model/references/simple_reference"
|
127
|
+
end
|
128
|
+
|
129
|
+
module Statements
|
130
|
+
autoload :Alias, "expressir/model/statements/alias"
|
131
|
+
autoload :Assignment, "expressir/model/statements/assignment"
|
132
|
+
autoload :Case, "expressir/model/statements/case"
|
133
|
+
autoload :CaseAction, "expressir/model/statements/case_action"
|
134
|
+
autoload :Compound, "expressir/model/statements/compound"
|
135
|
+
autoload :Escape, "expressir/model/statements/escape"
|
136
|
+
autoload :If, "expressir/model/statements/if"
|
137
|
+
autoload :Null, "expressir/model/statements/null"
|
138
|
+
autoload :ProcedureCall, "expressir/model/statements/procedure_call"
|
139
|
+
autoload :Repeat, "expressir/model/statements/repeat"
|
140
|
+
autoload :Return, "expressir/model/statements/return"
|
141
|
+
autoload :Skip, "expressir/model/statements/skip"
|
142
|
+
end
|
143
|
+
|
144
|
+
module SupertypeExpressions
|
145
|
+
autoload :BinarySupertypeExpression, "expressir/model/supertype_expressions/binary_supertype_expression"
|
146
|
+
autoload :OneofSupertypeExpression, "expressir/model/supertype_expressions/oneof_supertype_expression"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# Autoload for Commands module classes
|
151
|
+
module Commands
|
152
|
+
autoload :Base, "expressir/commands/base"
|
153
|
+
autoload :Benchmark, "expressir/commands/benchmark"
|
154
|
+
autoload :BenchmarkCache, "expressir/commands/benchmark_cache"
|
155
|
+
autoload :Clean, "expressir/commands/clean"
|
156
|
+
autoload :Coverage, "expressir/commands/coverage"
|
157
|
+
autoload :Format, "expressir/commands/format"
|
158
|
+
autoload :Validate, "expressir/commands/validate"
|
159
|
+
autoload :Version, "expressir/commands/version"
|
160
|
+
end
|
46
161
|
end
|
47
162
|
|
48
163
|
require_relative "expressir/model"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: expressir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-06-
|
11
|
+
date: 2025-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base64
|
@@ -136,20 +136,6 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '1.0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: zeitwerk
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - "~>"
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '2.6'
|
146
|
-
type: :runtime
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - "~>"
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '2.6'
|
153
139
|
description: Expressir ("EXPRESS in Ruby") is a Ruby parser for EXPRESS and a set
|
154
140
|
of tools for accessing EXPRESS data models.
|
155
141
|
email:
|