expressir 2.1.20 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0e1c52810ce3b1361d9f8327c0c270ac3a7f366f16d3b3236a0ed3e559155a9
4
- data.tar.gz: a852899cbf8d6a7747b8609ae7ec00736eddfcfad6a9fd8d410cd453811a4188
3
+ metadata.gz: 5523a9cdb1e5b8168a0d2d7262cdd8a5e849b066a3eeaaad90a3bcb3a640fe38
4
+ data.tar.gz: 293acbebeecc50a22ba8bc56aa8413f7e156dac17fa4fa872380aff5a9bf320c
5
5
  SHA512:
6
- metadata.gz: f8db59aa54a5a1edd29165ec3b79e9e98a35ebd51d8d0184735417c96bbd9d178328ddad2feef11f177bc140bd514913d5581f0c01ba8f9ee25b5a3cdf35a7d2
7
- data.tar.gz: fef82dcf757767e2a1eea5b252083f0b8f9db85226263f74c7979fde768caa25895df05cca29ac525b799f21ffd19dfd138e26087d3351e0a210b62746bd1867
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-05 12:41:11 UTC using RuboCop version 1.75.2.
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
@@ -27,11 +27,25 @@ Lint/DuplicateBranch:
27
27
  Exclude:
28
28
  - 'lib/expressir/coverage.rb'
29
29
 
30
+ # Offense count: 1
31
+ # This cop supports safe autocorrection (--autocorrect).
32
+ Lint/ScriptPermission:
33
+ Exclude:
34
+ - 'update_yaml_fixtures.rb'
35
+
30
36
  # Offense count: 3
31
37
  Lint/ShadowingOuterLocalVariable:
32
38
  Exclude:
33
39
  - 'lib/expressir/express/visitor.rb'
34
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
+
35
49
  # Offense count: 2
36
50
  # This cop supports safe autocorrection (--autocorrect).
37
51
  # Configuration parameters: AutoCorrect, AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods, NotImplementedExceptions.
@@ -41,7 +55,7 @@ Lint/UnusedMethodArgument:
41
55
  - 'lib/expressir/express/cache.rb'
42
56
  - 'lib/expressir/express/parser.rb'
43
57
 
44
- # Offense count: 75
58
+ # Offense count: 76
45
59
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
46
60
  Metrics/AbcSize:
47
61
  Exclude:
@@ -60,13 +74,13 @@ Metrics/AbcSize:
60
74
  - 'lib/expressir/model/declarations/schema.rb'
61
75
  - 'lib/expressir/model/model_element.rb'
62
76
 
63
- # Offense count: 1
77
+ # Offense count: 2
64
78
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
65
79
  # AllowedMethods: refine
66
80
  Metrics/BlockLength:
67
81
  Max: 143
68
82
 
69
- # Offense count: 54
83
+ # Offense count: 56
70
84
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
71
85
  Metrics/CyclomaticComplexity:
72
86
  Exclude:
@@ -81,12 +95,12 @@ Metrics/CyclomaticComplexity:
81
95
  - 'lib/expressir/model/model_element.rb'
82
96
  - 'spec/support/model_element_helper.rb'
83
97
 
84
- # Offense count: 99
98
+ # Offense count: 100
85
99
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
86
100
  Metrics/MethodLength:
87
101
  Max: 82
88
102
 
89
- # Offense count: 43
103
+ # Offense count: 44
90
104
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
91
105
  Metrics/PerceivedComplexity:
92
106
  Exclude:
@@ -98,19 +112,29 @@ Metrics/PerceivedComplexity:
98
112
  - 'lib/expressir/model/declarations/schema.rb'
99
113
  - 'lib/expressir/model/model_element.rb'
100
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
+
101
126
  # Offense count: 5
102
127
  Performance/FixedSize:
103
128
  Exclude:
104
129
  - 'lib/expressir/express/formatter.rb'
105
130
 
106
- # Offense count: 6
107
- # This cop supports unsafe autocorrection (--autocorrect-all).
108
- # Configuration parameters: AllowRegexpMatch.
109
- Performance/RedundantEqualityComparisonBlock:
110
- Exclude:
111
- - 'spec/expressir/coverage_spec.rb'
112
-
113
131
  # Offense count: 1
114
132
  Style/MissingRespondToMissing:
115
133
  Exclude:
116
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
@@ -344,6 +344,42 @@ expressir coverage --exclude=TYPE:SELECT schemas/resources/action_schema/action_
344
344
  expressir coverage --exclude=TYPE:SELECT,TYPE:ENUMERATION schemas/resources/action_schema/action_schema.exp
345
345
  ----
346
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
+
347
383
  Valid TYPE subtypes that can be excluded:
348
384
 
349
385
  `AGGREGATE`:: Aggregate type
@@ -307,11 +307,11 @@ module Expressir
307
307
  requested_types
308
308
  end
309
309
 
310
- # Validate a single skip type (supports TYPE:SUBTYPE syntax)
310
+ # Validate a single skip type (supports TYPE:SUBTYPE and FUNCTION:SUBTYPE syntax)
311
311
  # @param type [String] The type to validate
312
312
  def validate_skip_type(type)
313
313
  if type.include?(":")
314
- # Handle TYPE:SUBTYPE format
314
+ # Handle TYPE:SUBTYPE and FUNCTION:SUBTYPE format
315
315
  main_type, subtype = type.split(":", 2)
316
316
 
317
317
  # Validate main type
@@ -326,8 +326,14 @@ module Expressir
326
326
  exit_with_error "Invalid TYPE subtype: #{subtype}. " \
327
327
  "Valid TYPE subtypes are: #{Expressir::Coverage::TYPE_SUBTYPES.join(', ')}"
328
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
329
335
  else
330
- exit_with_error "Subtype syntax (#{type}) is only supported for TYPE entities"
336
+ exit_with_error "Subtype syntax (#{type}) is only supported for TYPE and FUNCTION entities"
331
337
  end
332
338
  else
333
339
  # Handle simple type format
@@ -413,16 +413,19 @@ module Expressir
413
413
  def self.filter_skipped_entities(entities, skip_types)
414
414
  return entities if skip_types.empty?
415
415
 
416
- # Parse skip_types into simple types and TYPE subtypes
416
+ # Parse skip_types into simple types, TYPE subtypes, and FUNCTION subtypes
417
417
  simple_skips = []
418
418
  type_subtype_skips = []
419
+ function_subtype_skips = []
419
420
 
420
421
  skip_types.each do |skip_type|
421
422
  if skip_type.include?(":")
422
- # Handle TYPE:SUBTYPE format
423
+ # Handle TYPE:SUBTYPE and FUNCTION:SUBTYPE format
423
424
  main_type, subtype = skip_type.split(":", 2)
424
425
  if main_type == "TYPE" && TYPE_SUBTYPES.include?(subtype)
425
426
  type_subtype_skips << subtype
427
+ elsif main_type == "FUNCTION" && subtype == "INNER"
428
+ function_subtype_skips << subtype
426
429
  end
427
430
  else
428
431
  # Handle simple type format
@@ -445,6 +448,9 @@ module Expressir
445
448
  elsif entity_class == "Expressir::Model::Declarations::Type" && type_subtype_skips.any?
446
449
  entity_subtype = get_type_subtype(entity)
447
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)
448
454
  else
449
455
  false
450
456
  end
@@ -470,5 +476,18 @@ module Expressir
470
476
  underlying_class.split("::").last&.upcase
471
477
  end
472
478
  end
479
+
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)
491
+ end
473
492
  end
474
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
- else
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 = remark_tokens.map do |span|
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
- _, remark_tag, remark_text = if text.start_with?("--")
277
- text.match(/^--"([^"]*)"(.*)$/).to_a
278
- else
279
- text.match(/^\(\*"([^"]*)"(.*)\*\)$/m).to_a
280
- end
281
-
282
- if remark_tag
283
- remark_target = find_remark_target(node, remark_tag)
284
- end
285
- if remark_text
286
- remark_text = remark_text.strip.force_encoding("UTF-8")
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
- [span, remark_target, remark_text]
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
@@ -1,3 +1,3 @@
1
1
  module Expressir
2
- VERSION = "2.1.20".freeze
2
+ VERSION = "2.1.21".freeze
3
3
  end
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.20
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-05 00:00:00.000000000 Z
11
+ date: 2025-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64