expressir 2.3.6 → 2.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake.yml +1 -1
  3. data/.gitignore +2 -0
  4. data/.rubocop_todo.yml +17 -12
  5. data/CHANGELOG.md +159 -0
  6. data/docs/_guides/ler/step-packages.adoc +385 -0
  7. data/lib/expressir/coverage.rb +4 -4
  8. data/lib/expressir/express/builder_registry.rb +3 -1
  9. data/lib/expressir/express/builders/expression_builder.rb +2 -2
  10. data/lib/expressir/express/builders/helpers.rb +2 -8
  11. data/lib/expressir/express/builders/qualifier_builder.rb +2 -1
  12. data/lib/expressir/express/formatter.rb +32 -164
  13. data/lib/expressir/express/formatters/data_types_formatter.rb +39 -6
  14. data/lib/expressir/express/formatters/declarations_formatter.rb +47 -8
  15. data/lib/expressir/express/formatters/expressions_formatter.rb +20 -5
  16. data/lib/expressir/express/formatters/literals_formatter.rb +11 -1
  17. data/lib/expressir/express/formatters/references_formatter.rb +10 -1
  18. data/lib/expressir/express/formatters/remark_formatter.rb +1 -89
  19. data/lib/expressir/express/formatters/remark_item_formatter.rb +5 -4
  20. data/lib/expressir/express/formatters/statements_formatter.rb +32 -9
  21. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +7 -3
  22. data/lib/expressir/express/hyperlink_formatter.rb +1 -3
  23. data/lib/expressir/express/model_visitor.rb +1 -1
  24. data/lib/expressir/express/pretty_formatter.rb +31 -108
  25. data/lib/expressir/express/remark_attacher.rb +118 -88
  26. data/lib/expressir/express/schema_head_formatter.rb +1 -3
  27. data/lib/expressir/model/concerns.rb +6 -0
  28. data/lib/expressir/model/declarations/interface_item.rb +2 -0
  29. data/lib/expressir/model/declarations/interfaced_item.rb +3 -0
  30. data/lib/expressir/model/declarations/remark_item.rb +3 -0
  31. data/lib/expressir/model/declarations/schema.rb +7 -5
  32. data/lib/expressir/model/exp_file.rb +1 -0
  33. data/lib/expressir/model/identifier.rb +3 -1
  34. data/lib/expressir/model/model_element.rb +3 -3
  35. data/lib/expressir/model/repository.rb +8 -0
  36. data/lib/expressir/model/search_engine.rb +1 -1
  37. data/lib/expressir/package/reader.rb +9 -24
  38. data/lib/expressir/version.rb +1 -1
  39. metadata +4 -2
@@ -2,8 +2,6 @@ module Expressir
2
2
  module Express
3
3
  module Formatters
4
4
  module RemarkFormatter
5
- private
6
-
7
5
  def format_remark(node, remark)
8
6
  # Handle embedded remarks
9
7
  if remark.include?("\n")
@@ -142,7 +140,7 @@ module Expressir
142
140
  remarks = []
143
141
 
144
142
  # Add tagged remarks
145
- if node.class.method_defined?(:remarks) && !@no_remarks &&
143
+ if node.is_a?(Model::HasRemarks) && !@no_remarks &&
146
144
  !node.remarks.nil?
147
145
  remarks.concat(node.remarks.compact.map do |remark|
148
146
  format_remark(node, remark)
@@ -169,92 +167,6 @@ module Expressir
169
167
 
170
168
  remarks
171
169
  end
172
-
173
- def format_scope_remarks(node)
174
- remarks = []
175
-
176
- # Collect tagged remarks using the standard format_remarks
177
- remarks.concat(format_remarks(node))
178
-
179
- # Special handling for Schema to get proper remark ordering
180
- if node.is_a?(Model::Declarations::Schema)
181
- # Schema's own remarks that need to be in specific positions
182
- schema_remarks = {}
183
- if !@no_remarks && node.is_a?(Model::ModelElement) && !node.untagged_remarks.nil?
184
- node.untagged_remarks.compact.each do |remark|
185
- next unless remark.is_a?(Model::RemarkInfo)
186
-
187
- text = remark.text
188
- schema_remarks[text] = remark unless text == "interfaces" # Skip "interfaces"
189
- end
190
- end
191
-
192
- # Add Schema remarks in the proper order relative to children
193
- # Declaration order: constants, types, entities, subtype_constraints, functions, rules, procedures
194
- remarks.concat(schema_remarks["constants"] ? [format_untagged_remark(schema_remarks["constants"])] : [])
195
-
196
- # Collect from children grouped by type
197
- if node.is_a?(Model::ModelElement) && node.children
198
- types_done = false
199
- entities_done = false
200
-
201
- node.children.select do |child|
202
- !child.is_a?(Model::DataTypes::EnumerationItem) || node.is_a?(Model::Declarations::Type)
203
- end.each do |child|
204
- # Add types section remarks
205
- if !types_done && child.is_a?(Model::Declarations::Type)
206
- types_done = true
207
- end
208
-
209
- # Add entities section remarks
210
- if !entities_done && child.is_a?(Model::Declarations::Entity)
211
- entities_done = true
212
- end
213
-
214
- # Add subtype constraints Schema remark after last entity, before first subtype constraint
215
- if entities_done && child.is_a?(Model::Declarations::SubtypeConstraint) && schema_remarks["subtype constraints"]
216
- remarks.push(format_untagged_remark(schema_remarks["subtype constraints"]))
217
- schema_remarks.delete("subtype constraints") # Only add once
218
- end
219
-
220
- # Recursively collect from child
221
- remarks.concat(format_scope_remarks(child))
222
- end
223
- end
224
- else
225
- # For non-Schema nodes, use standard logic
226
- skip_untagged_types = [
227
- Model::Declarations::Entity,
228
- Model::Declarations::Type,
229
- Model::Declarations::Function,
230
- Model::Declarations::Procedure,
231
- Model::Declarations::Rule,
232
- Model::Declarations::SubtypeConstraint,
233
- ]
234
-
235
- if !@no_remarks &&
236
- node.is_a?(Model::ModelElement) &&
237
- !node.untagged_remarks.nil? &&
238
- skip_untagged_types.any? { |type| node.is_a?(type) }
239
-
240
- remarks.concat(node.untagged_remarks.compact.grep(Model::RemarkInfo).map do |remark|
241
- format_untagged_remark(remark)
242
- end)
243
- end
244
-
245
- # Then recursively collect from children
246
- if node.is_a?(Model::ModelElement) && node.children
247
- node.children.select do |child|
248
- !child.is_a?(Model::DataTypes::EnumerationItem) || node.is_a?(Model::Declarations::Type)
249
- end.each do |child|
250
- # Recursively collect remarks from child and its descendants
251
- remarks.concat(format_scope_remarks(child))
252
- end
253
- end
254
- end
255
-
256
- remarks
257
- end
258
170
  end
259
171
  end
260
172
  end
@@ -1,11 +1,12 @@
1
1
  module Expressir
2
2
  module Express
3
3
  module Formatters
4
- # Formatter for RemarkItem declarations
5
4
  module RemarkItemFormatter
6
- # Format a RemarkItem as an EXPRESS remark
7
- # @param node [Model::Declarations::RemarkItem] The remark item to format
8
- # @return [String] Formatted remark
5
+ def self.included(base)
6
+ base.register_formatter Model::Declarations::RemarkItem,
7
+ :format_remark_item
8
+ end
9
+
9
10
  def format_remark_item(node)
10
11
  return "" unless node.remarks&.any?
11
12
 
@@ -2,7 +2,31 @@ module Expressir
2
2
  module Express
3
3
  module Formatters
4
4
  module StatementsFormatter
5
- private
5
+ def self.included(base)
6
+ base.register_formatter Model::Statements::Alias,
7
+ :format_statements_alias
8
+ base.register_formatter Model::Statements::Assignment,
9
+ :format_statements_assignment
10
+ base.register_formatter Model::Statements::Case,
11
+ :format_statements_case
12
+ base.register_formatter Model::Statements::CaseAction,
13
+ :format_statements_case_action
14
+ base.register_formatter Model::Statements::Compound,
15
+ :format_statements_compound
16
+ base.register_formatter Model::Statements::Escape,
17
+ :format_statements_escape
18
+ base.register_formatter Model::Statements::If, :format_statements_if
19
+ base.register_formatter Model::Statements::Null,
20
+ :format_statements_null
21
+ base.register_formatter Model::Statements::ProcedureCall,
22
+ :format_statements_procedure_call
23
+ base.register_formatter Model::Statements::Repeat,
24
+ :format_statements_repeat
25
+ base.register_formatter Model::Statements::Return,
26
+ :format_statements_return
27
+ base.register_formatter Model::Statements::Skip,
28
+ :format_statements_skip
29
+ end
6
30
 
7
31
  def format_statements_alias(node)
8
32
  [
@@ -82,10 +106,9 @@ module Expressir
82
106
  end
83
107
 
84
108
  def format_statements_case_action(node)
85
- node.labels ||= []
86
109
  [
87
110
  [
88
- node.labels.map { |x| format(x) }.join(", "),
111
+ Array(node.labels).map { |x| format(x) }.join(", "),
89
112
  " ",
90
113
  ":",
91
114
  ].join,
@@ -94,11 +117,11 @@ module Expressir
94
117
  end
95
118
 
96
119
  def format_statements_compound(node)
97
- node.statements ||= []
120
+ statements = Array(node.statements)
98
121
  [
99
122
  "BEGIN",
100
- *if node.statements&.length&.positive?
101
- indent(node.statements.map { |x| format(x) }.join("\n"))
123
+ *if statements.length.positive?
124
+ indent(statements.map { |x| format(x) }.join("\n"))
102
125
  end,
103
126
  [
104
127
  "END",
@@ -144,7 +167,7 @@ module Expressir
144
167
  end
145
168
 
146
169
  def format_statements_repeat(node)
147
- node.statements ||= []
170
+ statements = Array(node.statements)
148
171
  [
149
172
  [
150
173
  "REPEAT",
@@ -188,8 +211,8 @@ module Expressir
188
211
  end,
189
212
  ";",
190
213
  ].join,
191
- *if node.statements&.length&.positive?
192
- indent(node.statements.map { |x| format(x) }.join("\n"))
214
+ *if statements.length.positive?
215
+ indent(statements.map { |x| format(x) }.join("\n"))
193
216
  end,
194
217
  *format_remarks(node),
195
218
  [
@@ -2,7 +2,12 @@ module Expressir
2
2
  module Express
3
3
  module Formatters
4
4
  module SupertypeExpressionsFormatter
5
- private
5
+ def self.included(base)
6
+ base.register_formatter Model::SupertypeExpressions::BinarySupertypeExpression,
7
+ :format_supertype_expressions_binary_supertype_expression
8
+ base.register_formatter Model::SupertypeExpressions::OneofSupertypeExpression,
9
+ :format_supertype_expressions_oneof_supertype_expression
10
+ end
6
11
 
7
12
  def format_supertype_expressions_binary_supertype_expression(node)
8
13
  supertype_precedence = self.class.const_get(:SUPERTYPE_OPERATOR_PRECEDENCE)
@@ -36,11 +41,10 @@ module Expressir
36
41
  end
37
42
 
38
43
  def format_supertype_expressions_oneof_supertype_expression(node)
39
- node.operands ||= []
40
44
  [
41
45
  "ONEOF",
42
46
  "(",
43
- node.operands.map { |x| format(x) }.join(", "),
47
+ Array(node.operands).map { |x| format(x) }.join(", "),
44
48
  ")",
45
49
  ].join
46
50
  end
@@ -8,14 +8,12 @@ module Expressir
8
8
  module HyperlinkFormatter
9
9
  # @!visibility private
10
10
  def self.included(mod)
11
- if !mod.superclass.private_method_defined? :format_references_simple_reference
11
+ unless mod.superclass <= Expressir::Express::Formatter
12
12
  raise Error::FormatterMethodMissingError.new("HyperlinkFormatter",
13
13
  "format_references_simple_reference")
14
14
  end
15
15
  end
16
16
 
17
- private
18
-
19
17
  def format_references_simple_reference(node)
20
18
  return node.id unless node.base_path
21
19
 
@@ -6,7 +6,7 @@ module Expressir
6
6
  node.class.attributes.each_key do |symbol|
7
7
  next if ::Expressir::Model::ModelElement::SKIP_ATTRIBUTES.include?(symbol)
8
8
 
9
- value = node.send(symbol)
9
+ value = node.public_send(symbol)
10
10
 
11
11
  case value
12
12
  when Array
@@ -74,8 +74,6 @@ module Expressir
74
74
  super(no_remarks: options.fetch(:no_remarks, false))
75
75
  end
76
76
 
77
- private
78
-
79
77
  # Override indent to use configured width
80
78
  # @param str [String] String to indent
81
79
  # @return [String] Indented string
@@ -379,7 +377,6 @@ module Expressir
379
377
  def format_declarations_schema(node)
380
378
  indent_str = " " * @config.indent
381
379
  preamble = format_preamble_remarks(node, indent_str)
382
-
383
380
  schema_declarations = [
384
381
  *if node.constants&.length&.positive?
385
382
  [
@@ -435,8 +432,6 @@ module Expressir
435
432
  end
436
433
 
437
434
  # Override format_declarations_function to use aligned constants
438
- # @param node [Model::Declarations::Function] Function node
439
- # @return [String] Formatted function
440
435
  def format_declarations_function(node)
441
436
  [
442
437
  [
@@ -459,55 +454,12 @@ module Expressir
459
454
  format(node.return_type),
460
455
  ";",
461
456
  ].join,
462
- *if node.types&.length&.positive?
463
- indent(node.types.map { |x| format(x) }.join("\n"))
464
- end,
465
- *if node.entities&.length&.positive?
466
- indent(node.entities.map { |x| format(x) }.join("\n"))
467
- end,
468
- *if node.subtype_constraints&.length&.positive?
469
- indent(node.subtype_constraints.map { |x| format(x) }.join("\n"))
470
- end,
471
- *if node.functions&.length&.positive?
472
- indent(node.functions.map { |x| format(x) }.join("\n"))
473
- end,
474
- *if node.procedures&.length&.positive?
475
- indent(node.procedures.map { |x| format(x) }.join("\n"))
476
- end,
477
- *if node.constants&.length&.positive?
478
- indent([
479
- "CONSTANT",
480
- indent(format_constant_block(node.constants)),
481
- [
482
- "END_CONSTANT",
483
- ";",
484
- ].join,
485
- ].join("\n"))
486
- end,
487
- *if node.variables&.length&.positive?
488
- indent([
489
- "LOCAL",
490
- indent(node.variables.map { |x| format(x) }.join("\n")),
491
- [
492
- "END_LOCAL",
493
- ";",
494
- ].join,
495
- ].join("\n"))
496
- end,
497
- *if node.statements&.length&.positive?
498
- indent(node.statements.map { |x| format(x) }.join("\n"))
499
- end,
500
- [
501
- "END_FUNCTION",
502
- ";",
503
- format_end_scope_remark(node),
504
- ].join,
457
+ *format_scope_body(node),
458
+ format_scope_footer("END_FUNCTION", node),
505
459
  ].join("\n")
506
460
  end
507
461
 
508
462
  # Override format_declarations_procedure to use aligned constants
509
- # @param node [Model::Declarations::Procedure] Procedure node
510
- # @return [String] Formatted procedure
511
463
  def format_declarations_procedure(node)
512
464
  [
513
465
  [
@@ -526,57 +478,13 @@ module Expressir
526
478
  end,
527
479
  ";",
528
480
  ].join,
529
- *if node.types&.length&.positive?
530
- indent(node.types.map { |x| format(x) }.join("\n"))
531
- end,
532
- *if node.entities&.length&.positive?
533
- indent(node.entities.map { |x| format(x) }.join("\n"))
534
- end,
535
- *if node.subtype_constraints&.length&.positive?
536
- indent(node.subtype_constraints.map { |x| format(x) }.join("\n"))
537
- end,
538
- *if node.functions&.length&.positive?
539
- indent(node.functions.map { |x| format(x) }.join("\n"))
540
- end,
541
- *if node.procedures&.length&.positive?
542
- indent(node.procedures.map { |x| format(x) }.join("\n"))
543
- end,
544
- *if node.constants&.length&.positive?
545
- indent([
546
- "CONSTANT",
547
- indent(format_constant_block(node.constants)),
548
- [
549
- "END_CONSTANT",
550
- ";",
551
- ].join,
552
- ].join("\n"))
553
- end,
554
- *if node.variables&.length&.positive?
555
- indent([
556
- "LOCAL",
557
- indent(node.variables.map { |x| format(x) }.join("\n")),
558
- [
559
- "END_LOCAL",
560
- ";",
561
- ].join,
562
- ].join("\n"))
563
- end,
564
- *if node.statements&.length&.positive?
565
- indent(node.statements.map { |x| format(x) }.join("\n"))
566
- end,
567
- [
568
- "END_PROCEDURE",
569
- ";",
570
- format_end_scope_remark(node),
571
- ].join,
481
+ *format_scope_body(node),
482
+ format_scope_footer("END_PROCEDURE", node),
572
483
  ].join("\n")
573
484
  end
574
485
 
575
486
  # Override format_declarations_rule to use aligned constants
576
- # @param node [Model::Declarations::Rule] Rule node
577
- # @return [String] Formatted rule
578
487
  def format_declarations_rule(node)
579
- node.applies_to ||= []
580
488
  [
581
489
  [
582
490
  "RULE",
@@ -586,10 +494,27 @@ module Expressir
586
494
  "FOR",
587
495
  " ",
588
496
  "(",
589
- node.applies_to.map { |x| format(x) }.join(", "),
497
+ Array(node.applies_to).map { |x| format(x) }.join(", "),
590
498
  ")",
591
499
  ";",
592
500
  ].join,
501
+ *format_scope_body(node),
502
+ *if node.where_rules&.length&.positive?
503
+ [
504
+ "WHERE",
505
+ indent(node.where_rules.map { |x| format(x) }.join("\n")),
506
+ ]
507
+ end,
508
+ format_scope_footer("END_RULE", node),
509
+ ].join("\n")
510
+ end
511
+
512
+ # Shared scope body for function, procedure, and rule declarations.
513
+ # These declaration types share the same internal structure:
514
+ # types, entities, subtype_constraints, functions, procedures,
515
+ # constants, variables, statements.
516
+ def format_scope_body(node)
517
+ [
593
518
  *if node.types&.length&.positive?
594
519
  indent(node.types.map { |x| format(x) }.join("\n"))
595
520
  end,
@@ -628,17 +553,15 @@ module Expressir
628
553
  *if node.statements&.length&.positive?
629
554
  indent(node.statements.map { |x| format(x) }.join("\n"))
630
555
  end,
631
- *if node.where_rules&.length&.positive?
632
- [
633
- "WHERE",
634
- indent(node.where_rules.map { |x| format(x) }.join("\n")),
635
- ]
636
- end,
637
- [
638
- "END_RULE",
639
- ";",
640
- ].join,
641
- ].join("\n")
556
+ ]
557
+ end
558
+
559
+ def format_scope_footer(keyword, node)
560
+ [
561
+ keyword,
562
+ ";",
563
+ format_end_scope_remark(node),
564
+ ].join
642
565
  end
643
566
  end
644
567
  end