expressir 2.3.5 → 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 (46) 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.rb +1 -1
  9. data/lib/expressir/express/builder_registry.rb +12 -35
  10. data/lib/expressir/express/builders/constant_builder.rb +8 -2
  11. data/lib/expressir/express/builders/expression_builder.rb +2 -2
  12. data/lib/expressir/express/builders/helpers.rb +2 -8
  13. data/lib/expressir/express/builders/procedure_decl_builder.rb +2 -1
  14. data/lib/expressir/express/builders/qualifier_builder.rb +2 -1
  15. data/lib/expressir/express/builders/statement_builder.rb +18 -5
  16. data/lib/expressir/express/builders/type_builder.rb +20 -12
  17. data/lib/expressir/express/formatter.rb +32 -164
  18. data/lib/expressir/express/formatters/data_types_formatter.rb +51 -8
  19. data/lib/expressir/express/formatters/declarations_formatter.rb +47 -8
  20. data/lib/expressir/express/formatters/expressions_formatter.rb +27 -9
  21. data/lib/expressir/express/formatters/literals_formatter.rb +12 -5
  22. data/lib/expressir/express/formatters/references_formatter.rb +10 -1
  23. data/lib/expressir/express/formatters/remark_formatter.rb +1 -89
  24. data/lib/expressir/express/formatters/remark_item_formatter.rb +5 -4
  25. data/lib/expressir/express/formatters/statements_formatter.rb +32 -9
  26. data/lib/expressir/express/formatters/supertype_expressions_formatter.rb +7 -3
  27. data/lib/expressir/express/hyperlink_formatter.rb +1 -3
  28. data/lib/expressir/express/model_visitor.rb +1 -1
  29. data/lib/expressir/express/pretty_formatter.rb +31 -108
  30. data/lib/expressir/express/remark_attacher.rb +118 -88
  31. data/lib/expressir/express/schema_head_formatter.rb +1 -3
  32. data/lib/expressir/model/concerns.rb +6 -0
  33. data/lib/expressir/model/declarations/function.rb +0 -1
  34. data/lib/expressir/model/declarations/interface_item.rb +2 -0
  35. data/lib/expressir/model/declarations/interfaced_item.rb +3 -0
  36. data/lib/expressir/model/declarations/procedure.rb +0 -1
  37. data/lib/expressir/model/declarations/remark_item.rb +3 -0
  38. data/lib/expressir/model/declarations/schema.rb +7 -5
  39. data/lib/expressir/model/exp_file.rb +1 -0
  40. data/lib/expressir/model/identifier.rb +3 -1
  41. data/lib/expressir/model/model_element.rb +3 -3
  42. data/lib/expressir/model/repository.rb +8 -0
  43. data/lib/expressir/model/search_engine.rb +1 -1
  44. data/lib/expressir/package/reader.rb +9 -24
  45. data/lib/expressir/version.rb +1 -1
  46. metadata +4 -2
@@ -2,7 +2,46 @@ module Expressir
2
2
  module Express
3
3
  module Formatters
4
4
  module DeclarationsFormatter
5
- private
5
+ def self.included(base)
6
+ base.register_formatter Model::Declarations::Attribute,
7
+ :format_declarations_attribute
8
+ base.register_formatter Model::Declarations::Constant,
9
+ :format_declarations_constant
10
+ base.register_formatter Model::Declarations::Entity,
11
+ :format_declarations_entity
12
+ base.register_formatter Model::Declarations::Function,
13
+ :format_declarations_function
14
+ base.register_formatter Model::Declarations::Interface,
15
+ :format_declarations_interface
16
+ base.register_formatter Model::Declarations::InterfaceItem,
17
+ :format_declarations_interface_item
18
+ base.register_formatter Model::Declarations::Parameter,
19
+ :format_declarations_parameter
20
+ base.register_formatter Model::Declarations::Procedure,
21
+ :format_declarations_procedure
22
+ base.register_formatter Model::Declarations::Rule,
23
+ :format_declarations_rule
24
+ base.register_formatter Model::Declarations::Schema,
25
+ :format_declarations_schema
26
+ base.register_formatter Model::Declarations::SchemaVersion,
27
+ :format_declarations_schema_version
28
+ base.register_formatter Model::Declarations::SubtypeConstraint,
29
+ :format_declarations_subtype_constraint
30
+ base.register_formatter Model::Declarations::Type,
31
+ :format_declarations_type
32
+ base.register_formatter Model::Declarations::UniqueRule,
33
+ :format_declarations_unique_rule
34
+ base.register_formatter Model::Declarations::Variable,
35
+ :format_declarations_variable
36
+ base.register_formatter Model::Declarations::WhereRule,
37
+ :format_declarations_where_rule
38
+ base.register_formatter Model::Declarations::InformalPropositionRule,
39
+ :format_declarations_informal_proposition_rule
40
+ base.register_formatter Model::Declarations::DerivedAttribute,
41
+ :format_declarations_attribute
42
+ base.register_formatter Model::Declarations::InverseAttribute,
43
+ :format_declarations_attribute
44
+ end
6
45
 
7
46
  def format_declarations_attribute(node)
8
47
  [
@@ -187,8 +226,7 @@ module Expressir
187
226
  [
188
227
  "END_ENTITY",
189
228
  ";",
190
- # Only show end_scope_remark if entity has explicit attributes
191
- explicit_attributes&.length&.positive? ? format_end_scope_remark(node) : "",
229
+ format_end_scope_remark(node),
192
230
  ].join,
193
231
  ].join("\n")
194
232
  end
@@ -257,6 +295,7 @@ module Expressir
257
295
  [
258
296
  "END_FUNCTION",
259
297
  ";",
298
+ format_end_scope_remark(node),
260
299
  ].join,
261
300
  ].join("\n")
262
301
  end
@@ -377,13 +416,12 @@ module Expressir
377
416
  [
378
417
  "END_PROCEDURE",
379
418
  ";",
419
+ format_end_scope_remark(node),
380
420
  ].join,
381
421
  ].join("\n")
382
422
  end
383
423
 
384
424
  def format_declarations_rule(node)
385
- node.applies_to ||= []
386
-
387
425
  # Filter out statements that only exist to hold remarks in rules
388
426
  # (ALIAS/REPEAT with only Null sub-statements, query assignments, or Null statements)
389
427
  formatted_statements = []
@@ -414,7 +452,7 @@ module Expressir
414
452
  "FOR",
415
453
  " ",
416
454
  "(",
417
- node.applies_to.map { |x| format(x) }.join(", "),
455
+ Array(node.applies_to).map { |x| format(x) }.join(", "),
418
456
  ")",
419
457
  ";",
420
458
  ].join,
@@ -465,6 +503,7 @@ module Expressir
465
503
  [
466
504
  "END_RULE",
467
505
  ";",
506
+ format_end_scope_remark(node),
468
507
  ].join,
469
508
  ].join("\n")
470
509
  end
@@ -596,6 +635,7 @@ module Expressir
596
635
  [
597
636
  "END_SUBTYPE_CONSTRAINT",
598
637
  ";",
638
+ format_end_scope_remark(node),
599
639
  ].join,
600
640
  ].join("\n")
601
641
  end
@@ -627,7 +667,6 @@ module Expressir
627
667
  end
628
668
 
629
669
  def format_declarations_unique_rule(node)
630
- node.attributes ||= []
631
670
  [
632
671
  *if node.id
633
672
  [
@@ -636,7 +675,7 @@ module Expressir
636
675
  " ",
637
676
  ].join
638
677
  end,
639
- node.attributes.map { |x| format(x) }.join(", "),
678
+ Array(node.attributes).map { |x| format(x) }.join(", "),
640
679
  ";",
641
680
  ].join
642
681
  end
@@ -2,13 +2,29 @@ module Expressir
2
2
  module Express
3
3
  module Formatters
4
4
  module ExpressionsFormatter
5
- private
5
+ def self.included(base)
6
+ base.register_formatter Model::Expressions::AggregateInitializer,
7
+ :format_expressions_aggregate_initializer
8
+ base.register_formatter Model::Expressions::AggregateInitializerItem,
9
+ :format_expressions_aggregate_initializer_item
10
+ base.register_formatter Model::Expressions::BinaryExpression,
11
+ :format_expressions_binary_expression
12
+ base.register_formatter Model::Expressions::EntityConstructor,
13
+ :format_expressions_entity_constructor
14
+ base.register_formatter Model::Expressions::FunctionCall,
15
+ :format_expressions_function_call
16
+ base.register_formatter Model::Expressions::Interval,
17
+ :format_expressions_interval
18
+ base.register_formatter Model::Expressions::QueryExpression,
19
+ :format_expressions_query_expression
20
+ base.register_formatter Model::Expressions::UnaryExpression,
21
+ :format_expressions_unary_expression
22
+ end
6
23
 
7
24
  def format_expressions_aggregate_initializer(node)
8
- node.items ||= []
9
25
  [
10
26
  "[",
11
- node.items.map { |x| format(x) }.join(", "),
27
+ Array(node.items).map { |x| format(x) }.join(", "),
12
28
  "]",
13
29
  ].join
14
30
  end
@@ -24,9 +40,9 @@ module Expressir
24
40
  def format_expressions_binary_expression(node)
25
41
  operator_precedence = self.class.const_get(:OPERATOR_PRECEDENCE)
26
42
  op1_bin_exp = node.operand1.is_a?(Model::Expressions::BinaryExpression) &&
27
- (operator_precedence[node.operand1.operator] > operator_precedence[node.operator])
43
+ (operator_precedence[node.operand1.operator] >= operator_precedence[node.operator])
28
44
  op2_bin_exp = node.operand2.is_a?(Model::Expressions::BinaryExpression) &&
29
- (operator_precedence[node.operand2.operator] > operator_precedence[node.operator])
45
+ (operator_precedence[node.operand2.operator] >= operator_precedence[node.operator])
30
46
 
31
47
  [
32
48
  *if op1_bin_exp
@@ -72,11 +88,10 @@ module Expressir
72
88
  end
73
89
 
74
90
  def format_expressions_entity_constructor(node)
75
- node.parameters ||= []
76
91
  [
77
92
  format(node.entity),
78
93
  "(",
79
- node.parameters.map { |x| format(x) }.join(", "),
94
+ Array(node.parameters).map { |x| format(x) }.join(", "),
80
95
  ")",
81
96
  ].join
82
97
  end
@@ -138,6 +153,9 @@ module Expressir
138
153
  end
139
154
 
140
155
  def format_expressions_unary_expression(node)
156
+ needs_parens = node.operand.is_a?(Model::Expressions::BinaryExpression) ||
157
+ node.operand.is_a?(Model::Expressions::Interval)
158
+
141
159
  [
142
160
  case node.operator
143
161
  when Model::Expressions::UnaryExpression::MINUS then "-"
@@ -147,11 +165,11 @@ module Expressir
147
165
  if node.operator == Model::Expressions::UnaryExpression::NOT
148
166
  " "
149
167
  end,
150
- *if node.operand.is_a? Model::Expressions::BinaryExpression
168
+ *if needs_parens
151
169
  "("
152
170
  end,
153
171
  format(node.operand),
154
- *if node.operand.is_a? Model::Expressions::BinaryExpression
172
+ *if needs_parens
155
173
  ")"
156
174
  end,
157
175
  ].join
@@ -2,13 +2,20 @@ module Expressir
2
2
  module Express
3
3
  module Formatters
4
4
  module LiteralsFormatter
5
- private
5
+ def self.included(base)
6
+ base.register_formatter Model::Literals::Binary,
7
+ :format_literals_binary
8
+ base.register_formatter Model::Literals::Integer,
9
+ :format_literals_integer
10
+ base.register_formatter Model::Literals::Logical,
11
+ :format_literals_logical
12
+ base.register_formatter Model::Literals::Real, :format_literals_real
13
+ base.register_formatter Model::Literals::String,
14
+ :format_literals_string
15
+ end
6
16
 
7
17
  def format_literals_binary(node)
8
- [
9
- "%",
10
- node.value,
11
- ].join
18
+ node.value
12
19
  end
13
20
 
14
21
  def format_literals_integer(node)
@@ -2,7 +2,16 @@ module Expressir
2
2
  module Express
3
3
  module Formatters
4
4
  module ReferencesFormatter
5
- private
5
+ def self.included(base)
6
+ base.register_formatter Model::References::AttributeReference,
7
+ :format_references_attribute_reference
8
+ base.register_formatter Model::References::GroupReference,
9
+ :format_references_group_reference
10
+ base.register_formatter Model::References::IndexReference,
11
+ :format_references_index_reference
12
+ base.register_formatter Model::References::SimpleReference,
13
+ :format_references_simple_reference
14
+ end
6
15
 
7
16
  def format_references_attribute_reference(node)
8
17
  [
@@ -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