xmi 0.6.2 → 0.7.0
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 +4 -4
- data/.rubocop_todo.yml +0 -1
- data/CHANGELOG.md +61 -0
- data/CLAUDE.md +2 -2
- data/lib/xmi/performance/comparator.rb +8 -8
- data/lib/xmi/performance/helpers.rb +3 -39
- data/lib/xmi/performance/runner.rb +4 -63
- data/lib/xmi/performance/term.rb +58 -0
- data/lib/xmi/performance.rb +12 -0
- data/lib/xmi/sparx/index.rb +1 -0
- data/lib/xmi/uml/owned_attribute.rb +3 -2
- data/lib/xmi/uml/owned_end.rb +3 -2
- data/lib/xmi/uml/owned_parameter.rb +20 -2
- data/lib/xmi/uml/packaged_element.rb +6 -0
- data/lib/xmi/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3a7a71b5331da8d8c45859ce5c634bd65bd2564ce76505bdeea512df0ffb5001
|
|
4
|
+
data.tar.gz: bceea821dc3bfc67feff1e43b4124288c02e1b0bf99351e32679e87f67594da3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a67bce4eef99e51ab0213309b2d24ddaf0170c01a1c5c3094f2ba3ae2436cf9c3052a828545516650bd321f2445081fd310233c8ddaa082ca0e8d653b299029
|
|
7
|
+
data.tar.gz: 7d7b2f66f23144d1c27809e2d471f430e98794681da8944305ee701b889ee612c486cc9a8a118c34ef3c6fef1091f89a08007e9139215fd8fb9b88378411996c
|
data/.rubocop_todo.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,67 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
12
|
+
- `PackagedElement#nested_classifier` with `<nestedClassifier>` mapping
|
|
13
|
+
(Sparx EA nesting for classifiers owned by classes), covered by
|
|
14
|
+
`Xmi::Sparx::Index` lookups
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `OwnedAttribute`/`OwnedEnd`/`OwnedParameter` serialize `lowerValue`
|
|
19
|
+
before `upperValue`, matching Sparx EA's element order. Serialization
|
|
20
|
+
only — parsing accepts either order and is unaffected
|
|
21
|
+
|
|
22
|
+
### Documented
|
|
23
|
+
|
|
24
|
+
- `OwnedParameter#type` keeps its xmi-namespaced mapping, and the
|
|
25
|
+
limitation is now stated in the code and pinned by specs.
|
|
26
|
+
`xmi:type` is the XMI metaclass discriminator and `type` is Sparx's
|
|
27
|
+
classifier reference — two different attributes. lutaml-model matches
|
|
28
|
+
by local name, so it collapses them into one slot and only the last
|
|
29
|
+
one read survives re-serialization. Keeping the slot namespaced
|
|
30
|
+
preserves the discriminator; restoring Sparx's classifier reference is
|
|
31
|
+
the Sparx exporter's job. Modelling both needs namespace-disjoint
|
|
32
|
+
attribute deserialization upstream (lutaml-model#744).
|
|
33
|
+
|
|
34
|
+
## [0.6.2] - 2026-07-18
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- `Xmi::Performance` namespace for benchmark tooling (`Helpers`, `Comparator`, `Runner`) with autoload
|
|
39
|
+
- Polymorphic dispatch contract specs asserting frozen + default-value behavior at the data level
|
|
40
|
+
- Fallback coverage for `OwnedAttribute#upper_value`, `OwnedEnd#upper_value`, `OwnedParameter#upper_value` (previously only `Slot#value` was tested)
|
|
41
|
+
- Round-trip coverage for `uml:Component` and unknown `xmi:type` discriminators
|
|
42
|
+
- `spec/xmi/performance_spec.rb` covering autoload, class cloning, and namespace independence
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Deep-freeze the inner `class_map` hash on both `PACKAGED_ELEMENT` and `VALUE_SPECIFICATION` polymorphic maps. The outer `.freeze` was shallow — the inner hash was mutable at runtime
|
|
47
|
+
- `cached_fixture` ivar caching bug: the cache lived on per-example `self` and was recreated empty on every call, defeating its purpose. Replaced with a top-level `FIXTURE_CONTENT_CACHE` constant
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- Performance task constants moved into `Xmi::Performance` namespace: `PerformanceComparator` → `Xmi::Performance::Comparator`, `PerformanceHelpers` → `Xmi::Performance::Helpers`, `BenchmarkRunner` → `Xmi::Performance::Runner`. Dual-load mechanism replaced with class cloning via `const_set`
|
|
52
|
+
- Data-drive dispatch and subclass-schema specs from the class_map so adding a subclass + map entry auto-gains coverage (OCP for the test layer)
|
|
53
|
+
- Replace `.send(...)` with `.public_send(...)` in sparx extension specs for safer dynamic dispatch
|
|
54
|
+
- Normalize `require_relative` to `require "xmi"` in 8 spec files for consistency with the rest of the suite
|
|
55
|
+
- Correct polymorphic map comment terminology (`default_proc` → `default value`) and document the two-path fallback
|
|
56
|
+
|
|
57
|
+
### Removed
|
|
58
|
+
|
|
59
|
+
- `lib/tasks/performance_helpers.rb`, `lib/tasks/performance_comparator.rb`, `lib/tasks/benchmark_runner.rb` (moved to `lib/xmi/performance/`)
|
|
60
|
+
- Top-level constants `PerformanceComparator`, `PerformanceHelpers`, `BenchmarkRunner`, `Term` (moved into `Xmi::Performance`)
|
|
61
|
+
- Stale `TODO.next/01` and `TODO 02` references from comments (scratchpads were deleted; Phase A explanations kept)
|
|
62
|
+
|
|
63
|
+
## [0.6.1] - 2026-07-09
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- `Xmi::Uml::Component` subclass for `<packagedElement xmi:type="uml:Component">` (UML 2.5 §12.3)
|
|
68
|
+
- `uml:Component` entry in `PACKAGED_ELEMENT_POLYMORPHIC_MAP`
|
|
69
|
+
- Polymorphic dispatch fallback: unknown or missing `xmi:type` resolves to the abstract base class via `Hash` default value, avoiding the lutaml-model `Object.const_get(nil)` `TypeError` on real Sparx XMI containing types not yet modelled
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
12
73
|
- Namespace-bound registers for version-aware type resolution
|
|
13
74
|
- `Register#bind_namespace` for binding registers to namespaces
|
|
14
75
|
- `Register#resolve_in_namespace` for namespace-aware type lookup
|
data/CLAUDE.md
CHANGED
|
@@ -150,7 +150,7 @@ Two attributes use lutaml-model's polymorphic dispatch on `xmi:type`:
|
|
|
150
150
|
- `PackagedElement.packaged_element` (and `UmlModel.packaged_element`) — dispatches to typed subclasses (`UmlClass`, `Association`, `Interface`, `InstanceSpecification`, etc.). Map: `Xmi::Uml::PACKAGED_ELEMENT_POLYMORPHIC_MAP` in `lib/xmi/uml/packaged_element.rb`.
|
|
151
151
|
- `Slot.value`, `OwnedAttribute.upper_value`/`lower_value`/`default_value`, `OwnedEnd.upper_value`/`lower_value`/`default_value`, `OwnedParameter.upper_value`/`lower_value`/`default_value` — dispatch to ValueSpecification subclasses (`OpaqueExpression`, `LiteralString`, `LiteralInteger`, etc.). Map: `Xmi::Uml::VALUE_SPECIFICATION_POLYMORPHIC_MAP` in `lib/xmi/uml/value_specification.rb`.
|
|
152
152
|
|
|
153
|
-
**
|
|
153
|
+
**Fallback contract:** unknown or missing `xmi:type` resolves to the abstract base (`PackagedElement` / `ValueSpecification`) via the class_map's Hash default value — no crash. Locked in by `spec/xmi/uml/polymorphic_map_contract_spec.rb` and `spec/xmi/uml/polymorphic_robustness_spec.rb`. Two paths land at the base: a missing discriminator short-circuits upstream (the declared attribute type is used); an unknown discriminator hits the Hash default. Residual upstream gap — modelling `xmi:type` and unprefixed `type` as separate slots on one element — is tracked in lutaml-model#744.
|
|
154
154
|
|
|
155
155
|
### Key Files
|
|
156
156
|
|
|
@@ -188,7 +188,7 @@ A shared constant is available at `Xmi::Sparx::VALUE_MAP`.
|
|
|
188
188
|
|
|
189
189
|
## Known Issues
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
Attribute deserialization in lutaml-model is not namespace-disjoint: same-local-name attributes in different namespaces collapse into one model slot, document-order dependent. This affects modelling `xmi:type` (the XMI discriminator) and unprefixed `type` (Sparx's classifier reference) as separate attributes on one element. Tracked in lutaml-model#744 with a repro. Serialization is not affected — it is already namespace-disjoint.
|
|
192
192
|
|
|
193
193
|
## Limitations
|
|
194
194
|
|
|
@@ -30,12 +30,12 @@ module Xmi
|
|
|
30
30
|
all_current = {}
|
|
31
31
|
all_base = {}
|
|
32
32
|
|
|
33
|
-
puts
|
|
33
|
+
puts Term.header("Performance Comparison", color: CYAN)
|
|
34
34
|
puts
|
|
35
|
-
puts " #{
|
|
36
|
-
puts " #{
|
|
37
|
-
puts " #{
|
|
38
|
-
puts " #{
|
|
35
|
+
puts " #{DIM}Comparing#{CLEAR}:"
|
|
36
|
+
puts " #{CYAN} Current#{CLEAR}: #{Helpers.current_branch}"
|
|
37
|
+
puts " #{CYAN} Base#{CLEAR}: #{DEFAULT_BASE}"
|
|
38
|
+
puts " #{CYAN} Threshold#{CLEAR}: #{(DEFAULT_THRESHOLD * 100).round(0)}% regression allowed"
|
|
39
39
|
puts
|
|
40
40
|
|
|
41
41
|
base_runner = Helpers::Base::Runner.new(
|
|
@@ -67,12 +67,12 @@ module Xmi
|
|
|
67
67
|
def handle_results(summary)
|
|
68
68
|
puts
|
|
69
69
|
if summary[:regressions].any?
|
|
70
|
-
puts " #{
|
|
71
|
-
puts " #{
|
|
70
|
+
puts " #{RED}#{BOLD}❌ PERFORMANCE REGRESSIONS DETECTED#{CLEAR}"
|
|
71
|
+
puts " #{RED}#{summary[:regressions].length} benchmark(s) regressed beyond threshold#{CLEAR}"
|
|
72
72
|
puts
|
|
73
73
|
exit(1)
|
|
74
74
|
else
|
|
75
|
-
puts " #{
|
|
75
|
+
puts " #{GREEN}#{BOLD}✅ ALL BENCHMARKS PASSED#{CLEAR}"
|
|
76
76
|
puts
|
|
77
77
|
end
|
|
78
78
|
end
|
|
@@ -8,45 +8,10 @@ require "fileutils"
|
|
|
8
8
|
module Xmi
|
|
9
9
|
module Performance
|
|
10
10
|
# Shared helpers for the performance benchmark rake tasks.
|
|
11
|
-
# Provides
|
|
12
|
-
#
|
|
11
|
+
# Provides git/process helpers and the dual-namespace Runner loader
|
|
12
|
+
# used by the comparison flow. Terminal formatting lives in
|
|
13
|
+
# Xmi::Performance::Term; color codes on Xmi::Performance.
|
|
13
14
|
module Helpers
|
|
14
|
-
# ANSI color codes for terminal output
|
|
15
|
-
CLEAR = "\e[0m"
|
|
16
|
-
BOLD = "\e[1m"
|
|
17
|
-
DIM = "\e[2m"
|
|
18
|
-
CYAN = "\e[36m"
|
|
19
|
-
GREEN = "\e[32m"
|
|
20
|
-
YELLOW = "\e[33m"
|
|
21
|
-
RED = "\e[31m"
|
|
22
|
-
GRAY = "\e[90m"
|
|
23
|
-
MAGENTA = "\e[35m"
|
|
24
|
-
|
|
25
|
-
# Terminal formatting helpers
|
|
26
|
-
module Term
|
|
27
|
-
extend self
|
|
28
|
-
|
|
29
|
-
HL = "─"
|
|
30
|
-
VL = "│"
|
|
31
|
-
TL = "┌"
|
|
32
|
-
TR = "┐"
|
|
33
|
-
BL = "└"
|
|
34
|
-
BR = "┘"
|
|
35
|
-
|
|
36
|
-
def header(title, color: Helpers::CYAN)
|
|
37
|
-
width = 78
|
|
38
|
-
line = HL * width
|
|
39
|
-
puts
|
|
40
|
-
puts "#{color}#{TL}#{line}#{TR}#{CLEAR}"
|
|
41
|
-
puts "#{color}#{VL}#{CLEAR} #{BOLD}#{color}#{title}#{CLEAR}#{' ' * (width - title.length - 4)}#{color}#{VL}#{CLEAR}"
|
|
42
|
-
puts "#{color}#{BL}#{line}#{BR}#{CLEAR}"
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def sep(char: HL, width: 78)
|
|
46
|
-
puts "#{DIM}#{char * width}#{CLEAR}"
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
15
|
# Dual-namespace containers. The Runner class is cloned into
|
|
51
16
|
# each so that Base and Current hold independent class objects
|
|
52
17
|
# (preserving the shape of the comparison API even though both
|
|
@@ -123,7 +88,6 @@ module Xmi
|
|
|
123
88
|
when "NEW" then YELLOW
|
|
124
89
|
else GREEN
|
|
125
90
|
end
|
|
126
|
-
row[:status] == "REGRESSED" ? RED : DIM
|
|
127
91
|
|
|
128
92
|
puts " #{row[:benchmark].ljust(40)} #{format('%-12.1f',
|
|
129
93
|
row[:base_ips] || 0)} #{format('%-12.1f',
|
|
@@ -5,65 +5,6 @@ require "stringio"
|
|
|
5
5
|
|
|
6
6
|
module Xmi
|
|
7
7
|
module Performance
|
|
8
|
-
# Pretty terminal formatting for benchmark output.
|
|
9
|
-
module Term
|
|
10
|
-
CLEAR = "\e[0m"
|
|
11
|
-
BOLD = "\e[1m"
|
|
12
|
-
DIM = "\e[2m"
|
|
13
|
-
RED = "\e[31m"
|
|
14
|
-
GREEN = "\e[32m"
|
|
15
|
-
YELLOW = "\e[33m"
|
|
16
|
-
CYAN = "\e[36m"
|
|
17
|
-
MAGENTA = "\e[35m"
|
|
18
|
-
|
|
19
|
-
HL = "─"
|
|
20
|
-
VL = "│"
|
|
21
|
-
TL = "┌"
|
|
22
|
-
TR = "┐"
|
|
23
|
-
BL = "└"
|
|
24
|
-
BR = "┘"
|
|
25
|
-
|
|
26
|
-
def self.header(title, color: CYAN)
|
|
27
|
-
width = 78
|
|
28
|
-
line = HL * width
|
|
29
|
-
puts
|
|
30
|
-
puts "#{color}#{TL}#{line}#{TR}#{CLEAR}"
|
|
31
|
-
puts "#{color}#{VL}#{CLEAR} #{BOLD}#{color}#{title}#{CLEAR}#{' ' * (width - title.length - 4)}#{color}#{VL}#{CLEAR}"
|
|
32
|
-
puts "#{color}#{BL}#{line}#{BR}#{CLEAR}"
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def self.sep(char: HL, width: 78)
|
|
36
|
-
puts "#{DIM}#{char * width}#{CLEAR}"
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def self.env_info(ruby_version, platform)
|
|
40
|
-
puts
|
|
41
|
-
puts " #{DIM}Environment:#{CLEAR}"
|
|
42
|
-
puts " #{VL} Ruby #{ruby_version} on #{platform}#{' ' * (60 - ruby_version.length - platform.length)}#{VL}"
|
|
43
|
-
puts " #{DIM}#{BL}#{HL * 76}#{BR}#{CLEAR}"
|
|
44
|
-
puts
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def self.category(title, icon:, description:, failure_means:,
|
|
48
|
-
compare_against: nil)
|
|
49
|
-
puts
|
|
50
|
-
puts "#{CYAN}#{VL}#{CLEAR} #{BOLD}#{MAGENTA}#{icon} #{title}#{CLEAR}"
|
|
51
|
-
puts
|
|
52
|
-
puts " #{DIM}#{description}#{CLEAR}"
|
|
53
|
-
puts
|
|
54
|
-
|
|
55
|
-
if compare_against
|
|
56
|
-
puts " #{CYAN}Comparing against:#{CLEAR} #{compare_against}"
|
|
57
|
-
puts
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
puts " #{YELLOW}⚠️ Failure means:#{CLEAR} #{failure_means}"
|
|
61
|
-
puts
|
|
62
|
-
sep(width: 76)
|
|
63
|
-
puts
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
8
|
# Runs XMI parsing benchmarks against fixture files and reports
|
|
68
9
|
# iterations-per-second with error margins.
|
|
69
10
|
class Runner
|
|
@@ -112,7 +53,7 @@ compare_against: nil)
|
|
|
112
53
|
end
|
|
113
54
|
|
|
114
55
|
def run_benchmarks
|
|
115
|
-
Term.header("XMI Performance Benchmarks", color:
|
|
56
|
+
Term.header("XMI Performance Benchmarks", color: CYAN)
|
|
116
57
|
|
|
117
58
|
unless @env_shown
|
|
118
59
|
Term.env_info(RUBY_VERSION, RUBY_PLATFORM)
|
|
@@ -154,7 +95,7 @@ compare_against: nil)
|
|
|
154
95
|
end
|
|
155
96
|
|
|
156
97
|
puts " #{'Benchmark'.ljust(40)} #{'IPS'.rjust(12)} #{'Deviation'.rjust(12)}"
|
|
157
|
-
puts " #{
|
|
98
|
+
puts " #{DIM}#{Term::HL * 66}#{CLEAR}"
|
|
158
99
|
|
|
159
100
|
category_results.each do |r|
|
|
160
101
|
ips = (r[:result][:lower] + r[:result][:upper]) / 2.0
|
|
@@ -246,7 +187,7 @@ compare_against: nil)
|
|
|
246
187
|
puts
|
|
247
188
|
Term.sep(width: 78)
|
|
248
189
|
puts
|
|
249
|
-
puts " #{
|
|
190
|
+
puts " #{BOLD}#{MAGENTA}SUMMARY#{CLEAR}"
|
|
250
191
|
puts
|
|
251
192
|
|
|
252
193
|
@all_results.each do |r|
|
|
@@ -254,7 +195,7 @@ compare_against: nil)
|
|
|
254
195
|
end
|
|
255
196
|
|
|
256
197
|
puts
|
|
257
|
-
puts " #{
|
|
198
|
+
puts " #{DIM}#{@all_results.length} benchmarks completed#{CLEAR}"
|
|
258
199
|
puts
|
|
259
200
|
end
|
|
260
201
|
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Xmi
|
|
4
|
+
module Performance
|
|
5
|
+
# Terminal formatting for benchmark output. Colors live on the
|
|
6
|
+
# parent Xmi::Performance module; box-drawing characters here.
|
|
7
|
+
module Term
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
HL = "─"
|
|
11
|
+
VL = "│"
|
|
12
|
+
TL = "┌"
|
|
13
|
+
TR = "┐"
|
|
14
|
+
BL = "└"
|
|
15
|
+
BR = "┘"
|
|
16
|
+
|
|
17
|
+
def header(title, color: CYAN)
|
|
18
|
+
width = 78
|
|
19
|
+
line = HL * width
|
|
20
|
+
puts
|
|
21
|
+
puts "#{color}#{TL}#{line}#{TR}#{CLEAR}"
|
|
22
|
+
puts "#{color}#{VL}#{CLEAR} #{BOLD}#{color}#{title}#{CLEAR}#{' ' * (width - title.length - 4)}#{color}#{VL}#{CLEAR}"
|
|
23
|
+
puts "#{color}#{BL}#{line}#{BR}#{CLEAR}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def sep(char: HL, width: 78)
|
|
27
|
+
puts "#{DIM}#{char * width}#{CLEAR}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def env_info(ruby_version, platform)
|
|
31
|
+
puts
|
|
32
|
+
puts " #{DIM}Environment:#{CLEAR}"
|
|
33
|
+
puts " #{VL} Ruby #{ruby_version} on #{platform}#{' ' * (60 - ruby_version.length - platform.length)}#{VL}"
|
|
34
|
+
puts " #{DIM}#{BL}#{HL * 76}#{BR}#{CLEAR}"
|
|
35
|
+
puts
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def category(title, icon:, description:, failure_means:,
|
|
39
|
+
compare_against: nil)
|
|
40
|
+
puts
|
|
41
|
+
puts "#{CYAN}#{VL}#{CLEAR} #{BOLD}#{MAGENTA}#{icon} #{title}#{CLEAR}"
|
|
42
|
+
puts
|
|
43
|
+
puts " #{DIM}#{description}#{CLEAR}"
|
|
44
|
+
puts
|
|
45
|
+
|
|
46
|
+
if compare_against
|
|
47
|
+
puts " #{CYAN}Comparing against:#{CLEAR} #{compare_against}"
|
|
48
|
+
puts
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
puts " #{YELLOW}⚠️ Failure means:#{CLEAR} #{failure_means}"
|
|
52
|
+
puts
|
|
53
|
+
sep(width: 76)
|
|
54
|
+
puts
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/xmi/performance.rb
CHANGED
|
@@ -11,5 +11,17 @@ module Xmi
|
|
|
11
11
|
autoload :Helpers, "xmi/performance/helpers"
|
|
12
12
|
autoload :Comparator, "xmi/performance/comparator"
|
|
13
13
|
autoload :Runner, "xmi/performance/runner"
|
|
14
|
+
autoload :Term, "xmi/performance/term"
|
|
15
|
+
|
|
16
|
+
# ANSI color codes shared by Term, Helpers, Comparator, and Runner.
|
|
17
|
+
CLEAR = "\e[0m"
|
|
18
|
+
BOLD = "\e[1m"
|
|
19
|
+
DIM = "\e[2m"
|
|
20
|
+
CYAN = "\e[36m"
|
|
21
|
+
GREEN = "\e[32m"
|
|
22
|
+
YELLOW = "\e[33m"
|
|
23
|
+
RED = "\e[31m"
|
|
24
|
+
GRAY = "\e[90m"
|
|
25
|
+
MAGENTA = "\e[35m"
|
|
14
26
|
end
|
|
15
27
|
end
|
data/lib/xmi/sparx/index.rb
CHANGED
|
@@ -35,10 +35,11 @@ module Xmi
|
|
|
35
35
|
map_attribute "aggregation", to: :aggregation
|
|
36
36
|
|
|
37
37
|
map_element "type", to: :uml_type
|
|
38
|
-
|
|
39
|
-
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
38
|
+
# Sparx EA emits lowerValue before upperValue.
|
|
40
39
|
map_element "lowerValue", to: :lower_value,
|
|
41
40
|
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
41
|
+
map_element "upperValue", to: :upper_value,
|
|
42
|
+
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
42
43
|
map_element "defaultValue", to: :default_value,
|
|
43
44
|
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
44
45
|
end
|
data/lib/xmi/uml/owned_end.rb
CHANGED
|
@@ -24,10 +24,11 @@ module Xmi
|
|
|
24
24
|
map_attribute "isComposite", to: :is_composite
|
|
25
25
|
|
|
26
26
|
map_element "type", to: :uml_type
|
|
27
|
-
|
|
28
|
-
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
27
|
+
# Sparx EA emits lowerValue before upperValue.
|
|
29
28
|
map_element "lowerValue", to: :lower_value,
|
|
30
29
|
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
30
|
+
map_element "upperValue", to: :upper_value,
|
|
31
|
+
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
31
32
|
map_element "defaultValue", to: :default_value,
|
|
32
33
|
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
33
34
|
end
|
|
@@ -4,6 +4,23 @@ module Xmi
|
|
|
4
4
|
module Uml
|
|
5
5
|
class OwnedParameter < Base
|
|
6
6
|
attribute :name, :string
|
|
7
|
+
# These are two DIFFERENT attributes that collide here:
|
|
8
|
+
# xmi:type="uml:Parameter" — the XMI metaclass discriminator
|
|
9
|
+
# type="EAnone_void" — Sparx's classifier reference
|
|
10
|
+
#
|
|
11
|
+
# Known limit: lutaml-model matches attributes by local name only,
|
|
12
|
+
# so both land in this one slot and whichever appears LAST in the
|
|
13
|
+
# input wins. They are not two spellings of one concept, and only
|
|
14
|
+
# one of them can survive a round trip.
|
|
15
|
+
#
|
|
16
|
+
# The slot stays xmi-namespaced, which keeps the discriminator —
|
|
17
|
+
# the general UML XMI shape this gem round-trips. Sparx's
|
|
18
|
+
# classifier reference still parses into it, but re-serializes as
|
|
19
|
+
# `xmi:type`. Restoring the Sparx spelling belongs to the Sparx
|
|
20
|
+
# exporter, not to this shared model: flipping it here would break
|
|
21
|
+
# the general case for every other consumer. Modelling both at
|
|
22
|
+
# once needs namespace-disjoint attribute deserialization
|
|
23
|
+
# upstream (lutaml-model#744).
|
|
7
24
|
attribute :type, ::Xmi::Type::XmiType
|
|
8
25
|
attribute :direction, :string
|
|
9
26
|
attribute :visibility, :string
|
|
@@ -24,10 +41,11 @@ module Xmi
|
|
|
24
41
|
map_attribute "isUnique", to: :is_unique
|
|
25
42
|
map_attribute "effect", to: :effect
|
|
26
43
|
|
|
27
|
-
|
|
28
|
-
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
44
|
+
# Sparx EA emits lowerValue before upperValue.
|
|
29
45
|
map_element "lowerValue", to: :lower_value,
|
|
30
46
|
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
47
|
+
map_element "upperValue", to: :upper_value,
|
|
48
|
+
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
31
49
|
map_element "defaultValue", to: :default_value,
|
|
32
50
|
polymorphic: VALUE_SPECIFICATION_POLYMORPHIC_MAP
|
|
33
51
|
end
|
|
@@ -64,6 +64,10 @@ module Xmi
|
|
|
64
64
|
|
|
65
65
|
attribute :packaged_element, PackagedElement, collection: true,
|
|
66
66
|
polymorphic: true
|
|
67
|
+
# Sparx EA nests child classifiers (a Class owned by a Class)
|
|
68
|
+
# as <nestedClassifier> rather than <packagedElement>.
|
|
69
|
+
attribute :nested_classifier, PackagedElement, collection: true,
|
|
70
|
+
polymorphic: true
|
|
67
71
|
attribute :owned_end, OwnedEnd, collection: true
|
|
68
72
|
attribute :owned_attribute, OwnedAttribute, collection: true
|
|
69
73
|
attribute :owned_comment, OwnedComment, collection: true
|
|
@@ -96,6 +100,8 @@ module Xmi
|
|
|
96
100
|
map_element "ownedOperation", to: :owned_operation, value_map: VALUE_MAP
|
|
97
101
|
map_element "packagedElement", to: :packaged_element,
|
|
98
102
|
polymorphic: PACKAGED_ELEMENT_POLYMORPHIC_MAP
|
|
103
|
+
map_element "nestedClassifier", to: :nested_classifier,
|
|
104
|
+
polymorphic: PACKAGED_ELEMENT_POLYMORPHIC_MAP
|
|
99
105
|
map_element "memberEnd", to: :member_ends, value_map: VALUE_MAP
|
|
100
106
|
map_element "slot", to: :slot, value_map: VALUE_MAP
|
|
101
107
|
map_element "specification", to: :specification
|
data/lib/xmi/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: xmi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: lutaml-model
|
|
@@ -98,6 +98,7 @@ files:
|
|
|
98
98
|
- lib/xmi/performance/comparator.rb
|
|
99
99
|
- lib/xmi/performance/helpers.rb
|
|
100
100
|
- lib/xmi/performance/runner.rb
|
|
101
|
+
- lib/xmi/performance/term.rb
|
|
101
102
|
- lib/xmi/replace.rb
|
|
102
103
|
- lib/xmi/root.rb
|
|
103
104
|
- lib/xmi/sparx.rb
|