lutaml-xsd 1.2.109 → 1.2.111

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: 1b72159d7cf64cd93b73f0cc4e9801dfa46c57b4aba669421395ae0faa88cc6d
4
- data.tar.gz: c6b1f7d7ecf76b6d9deb32ec13a261d70c87d7292c01be0f61e9b5ed0a1d0646
3
+ metadata.gz: c211adda1289222691ae1cd3d77ee6482ed88f3076e036fbaaf0937124906669
4
+ data.tar.gz: ad8339c42573c9152a1a94ef409aad142b2db3a2f13d98975f8b70f650fb2f1a
5
5
  SHA512:
6
- metadata.gz: 6cfc032057ed3bbf9048ae3f0a8b8f9ff2b75eed8553e323089e3c79c1918ae883d3d16dd5dfb352e2f6ee63f2fee409865cbb93e7af36ed49d9ea41c9b1814f
7
- data.tar.gz: d140656abba61dd935ae4ecc166d8f0dafa612d65a011c9acc56cf17e59393381dbcc5fe6888431094255e4b0762546da3f8320651c36fb3bd0eb01dc54d3585
6
+ metadata.gz: f51b044be371db36a1df22a0dc961dfca6f3e4742407d21ca277329ddebc8df51e80313376aea4389b8773fc6dde346ce7be7a4a086ae54c49498a6f0bda5f58
7
+ data.tar.gz: 8ed8f68bc2de75248980a699b0a022216b6a328e55ebc3829d721dc63c9a7db079db22fefa4d42803b6b3d3d6563ac07c6b3ce531a7825d7f86dcb58c6c4f1e0
data/TODO.conformance.md CHANGED
@@ -546,26 +546,48 @@ tuple keys, node-set field violations and absent-field rows handled, cross-eleme
546
546
  and the schG1/G4/G7 drift (fail in fresh isolation on origin/main
547
547
  stash-verified — inputs/gems/ruby verified identical to the 4641
548
548
  era; mechanism not isolated in-round; owner follow-up).
549
- - SCH R2 STACK OVERFLOW (2026-11-11): Schema_w3c/schR2/schR2.i
550
- (expected invalid) crashes the assessment with a SystemStackError
551
- in lutaml-model 0.8.167's Base#resolved_element_order/
552
- delete_deletables — an unguarded recursion over the cyclic
553
- redefine graph schR2's documents build (called from our
554
- collect_particles). The crash ESCAPES measure()'s rescue
555
- (SystemStackError is not a StandardError); in every prior ledger
556
- the case silently recorded as a pass via the crash-as-invalid
557
- convention on its expected-invalid expectation, so the ledger
558
- number never moved. Files/gems/ruby verified identical to the
559
- baseline era; the crash reproduces in fresh single-case runs on
560
- origin/main on both trains today. Finding for lutaml-model: a
561
- cycle guard in resolved_element_order (our org's repo; owner
562
- decides the upstream action).
549
+ - NESTED-TYPE-CANDIDATES ROUND (2026-11-11): +2 (schG2 — a baseline
550
+ parked failure — and the schG1/G4/G7 "drift" trio resolved as REAL
551
+ DEFECTS, not environment: named_type_candidates appended only ONE
552
+ nested candidate per root schema — find_nested_named_type returned
553
+ the first depth-first match and stopped, so a composition importing
554
+ same-named types two levels deep (schG1: a→b→c) NEVER listed the
555
+ deepest candidate; the owner-ns preference missed and list.first
556
+ (ns-a's ct-A) typed the ns-c element — the '123'-is-not-boolean
557
+ swap. find_nested_named_types now collects EVERY match across the
558
+ whole nested tree in document order). SUITE 4637/4696 measured +
559
+ 5 budget exclusions (reZ nested-repeat, unchanged), ZERO
560
+ regressions (stash-attributed per row), rspec 1663 green,
561
+ rubocop clean. schR2 stack-overflow note unchanged (crash masked
562
+ by expected-invalid, counted per convention).
563
+ - SCH R2 STACK OVERFLOW FIXED (2026-11-12, round shipped): the
564
+ SystemStackError on Schema_w3c/schR2/schR2.i (expected invalid;
565
+ masked as pass by the crash-as-invalid convention) is OURS, not
566
+ lutaml-model's — the infinite recursion cycles between the
567
+ §4.2.2 redefined group body and the redefine TARGET (two DISTINCT
568
+ objects reachable by the same group name b-g2), so an OBJECT-keyed
569
+ guard misses it; the cut is NAME-keyed and PATH-scoped in both
570
+ walkers: leaf_particles marks the group name on its ancestry
571
+ (same name cannot expand within its own ancestry; sibling reuse
572
+ still expands fresh) and ContentModelMatcher#compile_group keeps
573
+ the same path discipline over resolved containers. LEDGER vs the
574
+ 1.2.110 baseline: 4637/4696 measured + the same 5 reZ budget
575
+ exclusions, ZERO regressions, and batch 4450's crash list is
576
+ EMPTY (schR2.i now assesses honestly to invalid instead of
577
+ overflowing). PROVENANCE: batch 03000 was carried over from the
578
+ 1.2.110 ledger — regex-pattern-only cases whose walk never
579
+ touches the guards (the batch's reI003 quadratic tax made a
580
+ re-run cost-prohibitive on the contended machine). Also filed
581
+ lutaml/moxml#540 this round (the 0.6.4 attribute char-ref
582
+ regression below; repro included).
563
583
  - TRAIN ADOPTION REGRESSION — CHARACTER REFERENCES (2026-11-11):
564
584
  the 2026-11-10 adoption verdict ("conformance-IDENTICAL") was
565
585
  WRONG for one class: moxml 0.6.4 stopped decoding numeric
566
586
  character references in attribute values. Minimal repro:
567
587
  `Moxml::Context.new.parse('<x a="&#x2190;"/>').root.attributes.
568
588
  first.value` → "←" on moxml 0.6.2, literal "&#x2190;" on 0.6.4.
589
+ FILED lutaml/moxml#540 (2026-11-12; repro: attribute values keep
590
+ the reference literal while element text decodes on 0.6.4).
569
591
  Downstream this breaks the whole UNICODE-BLOCK pattern-facet
570
592
  class — Regex_w3c Arrows/MathematicalOperators/
571
593
  ArabicPresentationForms-A/CJKCompatibilityForms/
@@ -225,7 +225,20 @@ module Lutaml
225
225
  container = Array(@group_particles.call(particle)).first
226
226
  return empty_fragment unless container
227
227
 
228
- with_occurrence(particle) { compile_container_body(container) }
228
+ # §4.2.2 redefine bodies self-reference by name; the body and
229
+ # the redefine target are distinct objects, so the compile
230
+ # path set keys on the resolved container's identity — a
231
+ # container may not compile within its own ancestry, while
232
+ # sibling reuse still compiles fresh.
233
+ @group_path ||= []
234
+ return empty_fragment if @group_path.include?(container)
235
+
236
+ @group_path.push(container)
237
+ fragment = with_occurrence(particle) do
238
+ compile_container_body(container)
239
+ end
240
+ @group_path.pop
241
+ fragment
229
242
  end
230
243
 
231
244
  # A group ref expands to its declaration's container, whose own
@@ -368,14 +368,31 @@ module Lutaml
368
368
  end
369
369
  end
370
370
 
371
- def leaf_particles(particles, repository)
371
+ def leaf_particles(particles, repository, ancestors = nil)
372
+ ancestors ||= {}
372
373
  particles.flat_map do |particle|
373
374
  case particle
374
375
  when Lutaml::Xml::Schema::Xsd::Group
375
- leaf_particles(expand_group_container(particle, repository),
376
- repository)
376
+ # §4.2.2 redefine bodies self-reference by NAME; the
377
+ # body and the redefine target are DISTINCT objects, so
378
+ # the path set keys on the group name — the same name
379
+ # cannot expand within its own ancestry, while sibling
380
+ # reuse still expands fresh.
381
+ group_name = if particle.name.to_s.empty?
382
+ particle.ref.to_s
383
+ else
384
+ particle.name.to_s
385
+ end
386
+ next [] if group_name.empty? || ancestors.key?(group_name)
387
+
388
+ ancestors[group_name] = true
389
+ body = expand_group_container(particle, repository)
390
+ leaves = body.nil? ? [] : leaf_particles(body, repository, ancestors)
391
+ ancestors.delete(group_name)
392
+ leaves
377
393
  when Lutaml::Xsd::Sequence, Lutaml::Xsd::Choice, Lutaml::Xsd::All
378
- leaf_particles(collect_particles(particle), repository)
394
+ leaf_particles(collect_particles(particle), repository,
395
+ ancestors)
379
396
  else
380
397
  [particle]
381
398
  end
@@ -290,8 +290,8 @@ module Lutaml
290
290
  end
291
291
  list << found if found
292
292
 
293
- nested = find_nested_named_type(local_name, schema)
294
- list << nested if nested
293
+ nested = find_nested_named_types(local_name, schema)
294
+ list.concat(nested)
295
295
  end
296
296
  unless @redefined_body_names.include?(local_name)
297
297
  @redefined_targets.each do |schema|
@@ -307,16 +307,18 @@ module Lutaml
307
307
  cache[local_name] = list.uniq
308
308
  end
309
309
 
310
- # Named types declared in documents reached through resolved
311
- # includes/imports — chameleon types (ctE018) live in a
312
- # no-namespace include target.
310
+ # EVERY same-named type across the whole nested include/import
311
+ # tree, in document order. The single-match walk stopped at the
312
+ # FIRST hit (schG1: ns-b's ct-A shadowed ns-c's two imports
313
+ # deep, so the owner-ns preference missed and ns-a's type won
314
+ # for the ns-c element — a same-local-name swap).
313
315
  #
314
- # @return [Object, nil]
315
- def find_nested_named_type(local_name, schema, depth = 0)
316
- return nil if depth > 8
316
+ # @return [Array<Object>]
317
+ def find_nested_named_types(local_name, schema, depth = 0)
318
+ return [] if depth > 8
317
319
 
318
- (Array(schema.include) + Array(schema.import)).each do |nested|
319
- next unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
320
+ (Array(schema.include) + Array(schema.import)).flat_map do |nested|
321
+ next [] unless nested.is_a?(Lutaml::Xml::Schema::Xsd::Schema)
320
322
 
321
323
  found = Array(nested.complex_type).find do |ct|
322
324
  ct.name == local_name
@@ -324,12 +326,9 @@ module Lutaml
324
326
  found ||= Array(nested.simple_type).find do |st|
325
327
  st.name == local_name
326
328
  end
327
- return found if found
328
-
329
- found = find_nested_named_type(local_name, nested, depth + 1)
330
- return found if found
329
+ [found, *find_nested_named_types(local_name, nested, depth + 1)]
330
+ .compact
331
331
  end
332
- nil
333
332
  end
334
333
 
335
334
  # Builtin numeric types: values compare in the numeric value
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Xsd
5
- VERSION = "1.2.109"
5
+ VERSION = "1.2.111"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-xsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.109
4
+ version: 1.2.111
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.