expressir 2.1.22 → 2.1.23

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.
@@ -9,7 +9,8 @@ module Expressir
9
9
  # @!visibility private
10
10
  def self.included(mod)
11
11
  if !mod.superclass.private_method_defined?(:format_declarations_schema) || !mod.superclass.private_method_defined?(:format_declarations_schema_head)
12
- raise Error::FormatterMethodMissingError.new("SchemaHeadFormatter", "format_declarations_schema/format_declarations_schema_head")
12
+ raise Error::FormatterMethodMissingError.new("SchemaHeadFormatter",
13
+ "format_declarations_schema/format_declarations_schema_head")
13
14
  end
14
15
  end
15
16
 
@@ -41,7 +41,9 @@ module Expressir
41
41
  end
42
42
 
43
43
  def method_missing(name, *args)
44
- rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) { |m| m[1].upcase }.to_sym
44
+ rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) do |m|
45
+ m[1].upcase
46
+ end.to_sym
45
47
  self.class.define_method(name) { @data[rulename] }
46
48
  send name, *args
47
49
  end
@@ -84,28 +86,28 @@ module Expressir
84
86
 
85
87
  @attached_remark_tokens = Set.new
86
88
 
87
- @visit_methods = Hash[
88
- private_methods.grep(/^visit_/).map do |name|
89
- rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) { $1.upcase }
90
- [rulename.to_sym, name.to_sym]
91
- end,
92
- ]
89
+ @visit_methods = private_methods.grep(/^visit_/).to_h do |name|
90
+ rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) do
91
+ $1.upcase
92
+ end
93
+ [rulename.to_sym, name.to_sym]
94
+ end
93
95
  end
94
96
 
95
97
  def to_ctx(ast, name = :unnamed)
96
98
  case ast
97
99
  when Hash
98
- nodes = Hash[
99
- ast.map do |k, v|
100
- if k =~ /^listOf_(.*)$/
101
- itemkey = $1.to_sym
102
- ary = Array === v ? v : [v]
103
- [itemkey, to_ctx(ary.select { |v| v[itemkey] }.map { |v| v.slice(itemkey) })]
104
- else
105
- [k, to_ctx(v, k)]
106
- end
107
- end,
108
- ]
100
+ nodes = ast.to_h do |k, v|
101
+ if k =~ /^listOf_(.*)$/
102
+ itemkey = $1.to_sym
103
+ ary = Array === v ? v : [v]
104
+ [itemkey, to_ctx(ary.select do |v|
105
+ v[itemkey]
106
+ end.map { |v| v.slice(itemkey) })]
107
+ else
108
+ [k, to_ctx(v, k)]
109
+ end
110
+ end
109
111
  Ctx.new nodes, name
110
112
  when Array
111
113
  ast.map do |element|
@@ -151,7 +153,7 @@ module Expressir
151
153
 
152
154
  def get_source(ctx)
153
155
  a, b = get_source_pos ctx
154
- @source[a..b - 1].strip
156
+ @source[a..(b - 1)].strip
155
157
  end
156
158
 
157
159
  def visit_ast(ast, name)
@@ -177,7 +179,6 @@ module Expressir
177
179
  node
178
180
  end
179
181
 
180
- # ###########################################3
181
182
  private
182
183
 
183
184
  def visit_top(ctx)
@@ -226,25 +227,34 @@ module Expressir
226
227
  # check if path can create implicit remark item
227
228
  # see https://github.com/lutaml/expressir/issues/78
228
229
  rest, _, current_path = path.rpartition(".") # get last path part
229
- _, _, current_path = current_path.rpartition(":") # ignore prefix
230
+ path_prefix, _, current_path = current_path.rpartition(":")
230
231
  parent_node = node_find(node, rest)
231
232
  if parent_node&.class&.method_defined?(:remark_items)
232
233
  remark_item = Model::Declarations::RemarkItem.new(
233
234
  id: current_path,
234
235
  )
235
- remark_item.parent = parent_node
236
236
 
237
- # check if path can create implicit informal proposition
238
- # see https://github.com/lutaml/expressir/issues/50
239
- if parent_node.class.method_defined?(:informal_propositions) && current_path.match(/^IP\d+$/)
237
+ if parent_node.class.method_defined?(:informal_propositions) && (
238
+ current_path.match(/^IP\d+$/) || path_prefix.match(/^IP\d+$/)
239
+ )
240
+ id = /^IP\d+$/.match?(current_path) ? current_path : path_prefix
240
241
  parent_node.informal_propositions ||= []
241
- parent_node.informal_propositions << remark_item
242
+ informal_proposition = Model::Declarations::InformalPropositionRule.new(id: id)
243
+ informal_proposition.parent = parent_node
244
+ parent_node.informal_propositions << informal_proposition
245
+
246
+ # Reassign the informal proposition id to the remark item
247
+ remark_item.id = id
248
+ remark_item.parent = informal_proposition
249
+
250
+ informal_proposition.remark_items ||= []
251
+ informal_proposition.remark_items << remark_item
242
252
  else
243
253
  parent_node.remark_items ||= []
244
254
  parent_node.remark_items << remark_item
255
+ remark_item.parent = parent_node
245
256
  end
246
257
  parent_node.reset_children_by_id
247
-
248
258
  remark_item
249
259
  end
250
260
  end
@@ -268,14 +278,16 @@ module Expressir
268
278
  remark_tokens = get_remarks ctx
269
279
 
270
280
  # skip already attached remarks
271
- remark_tokens = remark_tokens.reject { |x| @attached_remark_tokens.include?(x) }
281
+ remark_tokens = remark_tokens.reject do |x|
282
+ @attached_remark_tokens.include?(x)
283
+ end
272
284
 
273
285
  # parse remarks, find remark targets
274
286
  tagged_remark_tokens = []
275
287
  untagged_remark_tokens = []
276
288
 
277
289
  remark_tokens.each do |span|
278
- text = @source[span[0]..span[1] - 1]
290
+ text = @source[span[0]..(span[1] - 1)]
279
291
  remark_type = if text.start_with?("--")
280
292
  :tail
281
293
  else
@@ -304,6 +316,15 @@ module Expressir
304
316
  tagged_remark_tokens << [span, remark_target, remark_text]
305
317
  end
306
318
  end
319
+ elsif text.match?(/^--IP\d+:/)
320
+ # Unquoted tagged tail remark: --IP1: content
321
+ remark_target_path = text[2..].strip
322
+ colon_end = text.index(":", 5)
323
+ remark_text = text[(colon_end + 1)...-2].strip.force_encoding("UTF-8")
324
+ remark_target = find_remark_target(node, remark_target_path)
325
+ if remark_target
326
+ tagged_remark_tokens << [span, remark_target, remark_text]
327
+ end
307
328
  elsif text.start_with?("--")
308
329
  # Untagged tail remark: -- content
309
330
  untagged_text = text[2..].strip.force_encoding("UTF-8")
@@ -563,7 +584,8 @@ module Expressir
563
584
  ctx__stmt = ctx.stmt
564
585
 
565
586
  id = visit_if(ctx__variable_id)
566
- expression = handle_qualified_ref(visit_if(ctx__general_ref), ctx__qualifier)
587
+ expression = handle_qualified_ref(visit_if(ctx__general_ref),
588
+ ctx__qualifier)
567
589
  statements = visit_if_map(ctx__stmt)
568
590
 
569
591
  Model::Statements::Alias.new(
@@ -935,7 +957,8 @@ module Expressir
935
957
  ctx__entity_head__subsuper__supertype_constraint__abstract_supertype_declaration) && true
936
958
  supertype_expression = visit_if(ctx__entity_head__subsuper__supertype_constraint__abstract_supertype_declaration ||
937
959
  ctx__entity_head__subsuper__supertype_constraint__supertype_rule)
938
- subtype_of = visit_if(ctx__entity_head__subsuper__subtype_declaration, [])
960
+ subtype_of = visit_if(ctx__entity_head__subsuper__subtype_declaration,
961
+ [])
939
962
  attributes = [
940
963
  *visit_if_map_flatten(ctx__entity_body__explicit_attr),
941
964
  *visit_if(ctx__entity_body__derive_clause),
@@ -1017,7 +1040,9 @@ module Expressir
1017
1040
 
1018
1041
  extensible = ctx__EXTENSIBLE && true
1019
1042
  based_on = visit_if(ctx__enumeration_extension__type_ref)
1020
- items = visit_if(ctx__enumeration_items || ctx__enumeration_extension__enumeration_items, [])
1043
+ items = visit_if(
1044
+ ctx__enumeration_items || ctx__enumeration_extension__enumeration_items, []
1045
+ )
1021
1046
 
1022
1047
  Model::DataTypes::Enumeration.new(
1023
1048
  extensible: extensible,
@@ -1134,10 +1159,18 @@ module Expressir
1134
1159
  return_type = visit_if(ctx__function_head__parameter_type)
1135
1160
  declarations = visit_if_map(ctx__algorithm_head__declaration)
1136
1161
  types = declarations.select { |x| x.is_a? Model::Declarations::Type }
1137
- entities = declarations.select { |x| x.is_a? Model::Declarations::Entity }
1138
- subtype_constraints = declarations.select { |x| x.is_a? Model::Declarations::SubtypeConstraint }
1139
- functions = declarations.select { |x| x.is_a? Model::Declarations::Function }
1140
- procedures = declarations.select { |x| x.is_a? Model::Declarations::Procedure }
1162
+ entities = declarations.select do |x|
1163
+ x.is_a? Model::Declarations::Entity
1164
+ end
1165
+ subtype_constraints = declarations.select do |x|
1166
+ x.is_a? Model::Declarations::SubtypeConstraint
1167
+ end
1168
+ functions = declarations.select do |x|
1169
+ x.is_a? Model::Declarations::Function
1170
+ end
1171
+ procedures = declarations.select do |x|
1172
+ x.is_a? Model::Declarations::Procedure
1173
+ end
1141
1174
  constants = visit_if(ctx__algorithm_head__constant_decl, [])
1142
1175
  variables = visit_if(ctx__algorithm_head__local_decl, [])
1143
1176
  statements = visit_if_map(ctx__stmt)
@@ -1756,10 +1789,18 @@ module Expressir
1756
1789
  parameters = visit_if_map_flatten(ctx__procedure_head__procedure_head_parameter)
1757
1790
  declarations = visit_if_map(ctx__algorithm_head__declaration)
1758
1791
  types = declarations.select { |x| x.is_a? Model::Declarations::Type }
1759
- entities = declarations.select { |x| x.is_a? Model::Declarations::Entity }
1760
- subtype_constraints = declarations.select { |x| x.is_a? Model::Declarations::SubtypeConstraint }
1761
- functions = declarations.select { |x| x.is_a? Model::Declarations::Function }
1762
- procedures = declarations.select { |x| x.is_a? Model::Declarations::Procedure }
1792
+ entities = declarations.select do |x|
1793
+ x.is_a? Model::Declarations::Entity
1794
+ end
1795
+ subtype_constraints = declarations.select do |x|
1796
+ x.is_a? Model::Declarations::SubtypeConstraint
1797
+ end
1798
+ functions = declarations.select do |x|
1799
+ x.is_a? Model::Declarations::Function
1800
+ end
1801
+ procedures = declarations.select do |x|
1802
+ x.is_a? Model::Declarations::Procedure
1803
+ end
1763
1804
  constants = visit_if(ctx__algorithm_head__constant_decl, [])
1764
1805
  variables = visit_if(ctx__algorithm_head__local_decl, [])
1765
1806
  statements = visit_if_map(ctx__stmt)
@@ -2041,10 +2082,18 @@ module Expressir
2041
2082
  applies_to = visit_if_map(ctx__rule_head__entity_ref)
2042
2083
  declarations = visit_if_map(ctx__algorithm_head__declaration)
2043
2084
  types = declarations.select { |x| x.is_a? Model::Declarations::Type }
2044
- entities = declarations.select { |x| x.is_a? Model::Declarations::Entity }
2045
- subtype_constraints = declarations.select { |x| x.is_a? Model::Declarations::SubtypeConstraint }
2046
- functions = declarations.select { |x| x.is_a? Model::Declarations::Function }
2047
- procedures = declarations.select { |x| x.is_a? Model::Declarations::Procedure }
2085
+ entities = declarations.select do |x|
2086
+ x.is_a? Model::Declarations::Entity
2087
+ end
2088
+ subtype_constraints = declarations.select do |x|
2089
+ x.is_a? Model::Declarations::SubtypeConstraint
2090
+ end
2091
+ functions = declarations.select do |x|
2092
+ x.is_a? Model::Declarations::Function
2093
+ end
2094
+ procedures = declarations.select do |x|
2095
+ x.is_a? Model::Declarations::Procedure
2096
+ end
2048
2097
  constants = visit_if(ctx__algorithm_head__constant_decl, [])
2049
2098
  variables = visit_if(ctx__algorithm_head__local_decl, [])
2050
2099
  statements = visit_if_map(ctx__stmt)
@@ -2106,11 +2155,19 @@ module Expressir
2106
2155
  constants = visit_if(ctx__schema_body__constant_decl, [])
2107
2156
  declarations = visit_if_map(ctx__schema_body__schema_body_declaration)
2108
2157
  types = declarations.select { |x| x.is_a? Model::Declarations::Type }
2109
- entities = declarations.select { |x| x.is_a? Model::Declarations::Entity }
2110
- subtype_constraints = declarations.select { |x| x.is_a? Model::Declarations::SubtypeConstraint }
2111
- functions = declarations.select { |x| x.is_a? Model::Declarations::Function }
2158
+ entities = declarations.select do |x|
2159
+ x.is_a? Model::Declarations::Entity
2160
+ end
2161
+ subtype_constraints = declarations.select do |x|
2162
+ x.is_a? Model::Declarations::SubtypeConstraint
2163
+ end
2164
+ functions = declarations.select do |x|
2165
+ x.is_a? Model::Declarations::Function
2166
+ end
2112
2167
  rules = declarations.select { |x| x.is_a? Model::Declarations::Rule }
2113
- procedures = declarations.select { |x| x.is_a? Model::Declarations::Procedure }
2168
+ procedures = declarations.select do |x|
2169
+ x.is_a? Model::Declarations::Procedure
2170
+ end
2114
2171
 
2115
2172
  Model::Declarations::Schema.new(
2116
2173
  id: id,
@@ -2191,7 +2248,9 @@ module Expressir
2191
2248
  extensible = ctx__EXTENSIBLE && true
2192
2249
  generic_entity = ctx__GENERIC_ENTITY && true
2193
2250
  based_on = visit_if(ctx__select_extension__type_ref)
2194
- items = visit_if(ctx__select_list || ctx__select_extension__select_list, [])
2251
+ items = visit_if(
2252
+ ctx__select_list || ctx__select_extension__select_list, []
2253
+ )
2195
2254
 
2196
2255
  Model::DataTypes::Select.new(
2197
2256
  extensible: extensible,
@@ -2405,7 +2464,9 @@ module Expressir
2405
2464
  if ctx__supertype_factor.length >= 2
2406
2465
  if ctx__ANDOR && (ctx__ANDOR.length == ctx__supertype_factor.length - 1)
2407
2466
  operands = ctx__supertype_factor.map { |item| visit(item) }
2408
- operators = ctx__ANDOR.map { Model::SupertypeExpressions::BinarySupertypeExpression::ANDOR }
2467
+ operators = ctx__ANDOR.map do
2468
+ Model::SupertypeExpressions::BinarySupertypeExpression::ANDOR
2469
+ end
2409
2470
 
2410
2471
  handle_binary_supertype_expression(operands, operators)
2411
2472
  else
@@ -2427,7 +2488,9 @@ module Expressir
2427
2488
  if ctx__supertype_term.length >= 2
2428
2489
  if ctx__AND && (ctx__AND.length == ctx__supertype_term.length - 1)
2429
2490
  operands = ctx__supertype_term.map { |item| visit(item) }
2430
- operators = ctx__AND.map { Model::SupertypeExpressions::BinarySupertypeExpression::AND }
2491
+ operators = ctx__AND.map do
2492
+ Model::SupertypeExpressions::BinarySupertypeExpression::AND
2493
+ end
2431
2494
 
2432
2495
  handle_binary_supertype_expression(operands, operators)
2433
2496
  else
@@ -12,7 +12,8 @@ module Expressir
12
12
  attribute :attributes, Attribute, collection: true
13
13
  attribute :unique_rules, UniqueRule, collection: true
14
14
  attribute :where_rules, WhereRule, collection: true
15
- attribute :informal_propositions, RemarkItem, collection: true
15
+ attribute :informal_propositions, InformalPropositionRule,
16
+ collection: true
16
17
  attribute :_class, :string, default: -> { send(:name) }
17
18
 
18
19
  key_value do
@@ -0,0 +1,24 @@
1
+ module Expressir
2
+ module Model
3
+ module Declarations
4
+ # Informal proposition rules are used to specify constraints that cannot be formally expressed
5
+ class InformalPropositionRule < ModelElement
6
+ include Identifier
7
+
8
+ attribute :expression, ModelElement
9
+ attribute :_class, :string, default: -> { send(:name) }
10
+
11
+ key_value do
12
+ map "_class", to: :_class, render_default: true
13
+ map "expression", to: :expression
14
+ end
15
+
16
+ def children
17
+ [
18
+ *remark_items,
19
+ ]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -16,7 +16,8 @@ module Expressir
16
16
  attribute :variables, Variable, collection: true
17
17
  attribute :statements, ModelElement, collection: true
18
18
  attribute :where_rules, WhereRule, collection: true
19
- attribute :informal_propositions, RemarkItem, collection: true
19
+ attribute :informal_propositions, InformalPropositionRule,
20
+ collection: true
20
21
  attribute :_class, :string, default: -> { send(:name) }
21
22
 
22
23
  key_value do
@@ -108,7 +108,10 @@ module Expressir
108
108
  else
109
109
  interface.items.filter_map do |item|
110
110
  base_item = children_by_id[item.ref.id.safe_downcase]
111
- create_interfaced_item(item.id || base_item.id, base_item) if base_item
111
+ if base_item
112
+ create_interfaced_item(item.id || base_item.id,
113
+ base_item)
114
+ end
112
115
  end
113
116
  end
114
117
  end.compact
@@ -8,7 +8,8 @@ module Expressir
8
8
 
9
9
  attribute :underlying_type, ModelElement
10
10
  attribute :where_rules, WhereRule, collection: true
11
- attribute :informal_propositions, RemarkItem, collection: true
11
+ attribute :informal_propositions, InformalPropositionRule,
12
+ collection: true
12
13
  attribute :_class, :string, default: -> { send(:name) }
13
14
 
14
15
  key_value do
@@ -4,7 +4,8 @@ module Expressir
4
4
  def self.included(mod)
5
5
  mod.attribute :id, :string
6
6
  mod.attribute :remarks, :string, collection: true
7
- mod.attribute :remark_items, ::Expressir::Model::Declarations::RemarkItem, collection: true
7
+ mod.attribute :remark_items,
8
+ ::Expressir::Model::Declarations::RemarkItem, collection: true
8
9
  mod.attribute :untagged_remarks, :string, collection: true
9
10
 
10
11
  mod.key_value do
@@ -10,7 +10,8 @@ module Expressir
10
10
 
11
11
  key_value do
12
12
  map "_class", to: :_class, render_default: true
13
- map "value", to: :value, value_map: { to: { nil: :empty, empty: :empty } }
13
+ map "value", to: :value,
14
+ value_map: { to: { nil: :empty, empty: :empty } }
14
15
  map "encoded", to: :encoded
15
16
  end
16
17
  end