expressir 2.4.61-arm-linux → 2.4.63-arm-linux

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: eed4408f7187afa171995f1e6efea55425822a5b3acb33ae7ed7b659532bf5c0
4
- data.tar.gz: a62e05ed6102e8374d51b1d6c0b387983daefe5f4aa606e0f7f8c853f68caade
3
+ metadata.gz: d6a7ac697ab324b957b79b990d5ffa290407be24404eb6327fee3c98af4d06fa
4
+ data.tar.gz: a90d722dd4adae788cd3a82c3c79bab75ef38f92e73704d9b3076649a4e37955
5
5
  SHA512:
6
- metadata.gz: c9d3045425d53fd50a3388c8832d06b83f6268e96f0ce07bf97a7e04fbcb21f11c1e5a68e13166b69a2a1cfa511db0542f2ca2662e5c58c5357d1337ce99c547
7
- data.tar.gz: 6aabee62b6b20af41a8a99e5576e0a24f0778f5bcde82b3d3027dc67d7e8a199f57c32d5e89eb060b3c3a844df069b233bbf1162a1aff49531e67a6b1703ba09
6
+ metadata.gz: 9ad070295b64fe439f1a138feb5603b19904e55f92b9fb6209b32451ddfb0b34990644cdeeec3b18401b264fbfac4cefe7b907c4f523fc78f91a60e763839a8b
7
+ data.tar.gz: 6ab8b7f53ca49b7b764f7f068a3f073cc4ea6774c356ca132a706521dca88e68216004b28f29b5cca95917f6a3e05b6d4716bf9d23868c45fdc9efdffdc876bc
Binary file
Binary file
Binary file
Binary file
@@ -69,12 +69,6 @@ module Expressir
69
69
  entries.sort_by { |n| node_order(n) }
70
70
  end
71
71
 
72
- # First node (in node order) that is_a?(type), memoized per type.
73
- def first_node_of_type(type)
74
- @first_of_type ||= {}
75
- @first_of_type[type] ||= @nodes.find { |n| n[:node].is_a?(type) }&.dig(:node)
76
- end
77
-
78
72
  def semantic_entries
79
73
  @semantic_entries ||=
80
74
  @nodes.select { |n| n[:line] && semantic?(n[:node]) }
@@ -200,7 +194,19 @@ module Expressir
200
194
  end
201
195
 
202
196
  candidates.min_by { |n| node_order(n) }&.dig(:node) ||
203
- first_node_of_type(node_type)
197
+ containing_node_of_type(node_type, remark_line)
198
+ end
199
+
200
+ # A comment on an END_XXX line whose scope's recorded end sits past
201
+ # the line — remark items live between declarations, and their spans
202
+ # push the owner's end_line beyond END_XXX — resolves by span
203
+ # containment. Falls back to nil, not the first node of the type:
204
+ # handing an unresolvable END_FUNCTION comment to the first function
205
+ # piled every stray tail onto one owner (#609).
206
+ def containing_node_of_type(type, line)
207
+ semantic_entries
208
+ .select { |n| n[:node].is_a?(type) && n[:end_line] && line.between?(n[:line], n[:end_line]) }
209
+ .min_by { |n| node_order(n) }&.dig(:node)
204
210
  end
205
211
 
206
212
  private
@@ -163,7 +163,13 @@ module Expressir
163
163
 
164
164
  # Strategy 3: Create implicit item for qualified paths only
165
165
  if target.nil? && tag.include?(".")
166
- if containing_scope && function_rule_procedure?(containing_scope)
166
+ # A tag whose first segment is a schema id is already
167
+ # absolute: prepending the containing scope's path would
168
+ # double-count it, and the implicit walk would then name
169
+ # the item after the schema (#609 — `(*"s.f.lv"` inside f
170
+ # must create `lv`, not `s`).
171
+ absolute_tag = get_schema_ids(@model).include?(tag.split(".").first)
172
+ if containing_scope && function_rule_procedure?(containing_scope) && !absolute_tag
167
173
  scope_path = build_scope_path(containing_scope)
168
174
  if scope_path
169
175
  target = create_implicit_remark_item(@model, "#{scope_path}.#{tag}",
@@ -205,7 +211,8 @@ module Expressir
205
211
 
206
212
  line_content = line_content_for(remark.line)
207
213
  if end_scope_line?(line_content)
208
- matched_node = @node_index.node_for_end_scope_at(remark.line, line_content)
214
+ matched_node = @node_index.node_for_end_scope_at(remark.line, line_content) ||
215
+ scope_owner_for_end_line(remark.line, line_content)
209
216
  if matched_node
210
217
  add_remark(matched_node, remark.text, format: remark.format, tag: nil,
211
218
  source_offset: remark.position)
@@ -235,6 +242,34 @@ module Expressir
235
242
  line_content =~ /END_(SCHEMA|ENTITY|TYPE|FUNCTION|PROCEDURE|RULE)/i
236
243
  end
237
244
 
245
+ # A comment on an END_XXX line belongs to the scope that XXX closes.
246
+ # Spans can miss on the grammar lane — source strings there are
247
+ # reconstructions whose lengths undershoot the node's real extent,
248
+ # so neither the end-window nor containment reaches the END line
249
+ # (expressir#609 drift) — so this falls back to the scope walk: the
250
+ # construct open at the START of the END line is the scope being
251
+ # closed, by construction of the map.
252
+ def scope_owner_for_end_line(line, line_content)
253
+ type = case line_content
254
+ when /END_SCHEMA/i then Model::Declarations::Schema
255
+ when /END_ENTITY/i then Model::Declarations::Entity
256
+ when /END_TYPE/i then Model::Declarations::Type
257
+ when /END_FUNCTION/i then Model::Declarations::Function
258
+ when /END_PROCEDURE/i then Model::Declarations::Procedure
259
+ when /END_RULE/i then Model::Declarations::Rule
260
+ end
261
+ active = active_scope_map[line]
262
+ return nil unless type.is_a?(Class) && active.is_a?(Array)
263
+
264
+ klass, opener_line = active
265
+ # ENTITY/TYPE openers are tracked as :other — the walk is
266
+ # line-accurate, so trust it for those ends.
267
+ return nil unless klass == type || (klass == :other && [Model::Declarations::Entity, Model::Declarations::Type].include?(type))
268
+
269
+ @node_index.starting_at(opener_line)
270
+ .find { |n| n[:node].is_a?(type) }&.dig(:node)
271
+ end
272
+
238
273
  # Own-line body comments belong to the next statement in the same
239
274
  # statement region (Function body, THEN branch, ELSE branch, loop body):
240
275
  # attached there with LEADING placement. A comment with no following
@@ -553,6 +588,19 @@ module Expressir
553
588
  # from its closing keyword by an empty line still closes that body.
554
589
  while probe <= source_line_count
555
590
  content = line_content_for(probe).to_s.strip
591
+ # Embedded remark blocks (`(*"tag" ... *)`) that the renderer
592
+ # emits between a trailing comment and the closing keyword:
593
+ # skip the whole block, the keyword lies beyond it (#609).
594
+ if content.start_with?("(*")
595
+ # A single-line block carries its own "*)": only hunt for a
596
+ # closer when the start line does not have one.
597
+ unless content.include?("*)")
598
+ probe += 1
599
+ probe += 1 while probe <= source_line_count && !line_content_for(probe).to_s.include?("*)")
600
+ end
601
+ probe += 1
602
+ next
603
+ end
556
604
  break unless content.empty? || content.start_with?("--")
557
605
 
558
606
  probe += 1
@@ -3,6 +3,6 @@ module Expressir
3
3
  # autoload it (Ruby autoload only works for module/class constants, not
4
4
  # for string constants like `Expressir::VERSION`).
5
5
  module Version
6
- VERSION = "2.4.61".freeze
6
+ VERSION = "2.4.63".freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressir
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.61
4
+ version: 2.4.63
5
5
  platform: arm-linux
6
6
  authors:
7
7
  - Ribose Inc.