xmi 0.5.1 → 0.5.3

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: d91bb8a1a4fa881e676c2ad0b0d62898c499fb608baadb435326384d473de46b
4
- data.tar.gz: 552a2485053742144bf72ad4830f65b026996ce1c2976c742b9ea5fb4c3741f5
3
+ metadata.gz: ea334f95069f7cc7ba3116b4bac7e57bfe56476c6803dd59c84b458b0f9549fc
4
+ data.tar.gz: a2c61004fa041d2956bbad2f141750ce7c654b552a20ada2040e68e495559f07
5
5
  SHA512:
6
- metadata.gz: 617e27289838fb3c263935833758d5750552911106008d6c7cccc998d596848889590e5cd4b1240c29936d79d0b34da6592d1de1968abd076ed16ebd1b2a77a2
7
- data.tar.gz: 3b5a984b005fa87f8a5f4a9ce7949d8adb0f9fe596d3d78a4558b1a05e190294c60e17b6de7cd909dd4c805e4a44e693647d7849e13e3830d06e0df3e67c3e50
6
+ metadata.gz: 6c26a6117f49257ec68b0934783cbae29265f79dce927232df36737af3c1076b9802d96d02bf864d76841c820a8ce03869a92af64f31405b6d00b508795b4eff
7
+ data.tar.gz: 88b6d2d73963616ce39ce6517cb7f2d0a6c3bd86d46e4d0c52a4463e6a2d1c2d6923863c174afac74205619d2a9d30f5edec2adc58c654915a3f361f85c635d5
@@ -9,6 +9,10 @@ on:
9
9
 
10
10
  jobs:
11
11
  rake:
12
- uses: metanorma/ci/.github/workflows/graphviz-rake.yml@main
12
+ uses: metanorma/ci/.github/workflows/generic-rake.yml@main
13
+ with:
14
+ setup-tools: graphviz
15
+ submodules: true
16
+ choco-cache: true
13
17
  secrets:
14
18
  pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-03-22 06:43:54 UTC using RuboCop version 1.85.1.
3
+ # on 2026-04-18 04:57:18 UTC using RuboCop version 1.86.1.
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
@@ -11,102 +11,27 @@ Gemspec/RequiredRubyVersion:
11
11
  Exclude:
12
12
  - 'xmi.gemspec'
13
13
 
14
- # Offense count: 12
14
+ # Offense count: 1
15
15
  # This cop supports safe autocorrection (--autocorrect).
16
16
  # Configuration parameters: EnforcedStyle, IndentationWidth.
17
17
  # SupportedStyles: with_first_argument, with_fixed_indentation
18
18
  Layout/ArgumentAlignment:
19
19
  Exclude:
20
- - 'lib/tasks/benchmark_runner.rb'
21
- - 'lib/tasks/performance_helpers.rb'
22
- - 'lib/xmi/parsing.rb'
23
- - 'lib/xmi/version_registry.rb'
24
- - 'lib/xmi/versioned.rb'
25
- - 'scripts-xmi-profile/profile_xmi_simple.rb'
26
- - 'spec/xmi/sparx/sparx_root_xmi_parsing_spec.rb'
27
-
28
- # Offense count: 8
29
- # This cop supports safe autocorrection (--autocorrect).
30
- # Configuration parameters: EnforcedStyle, IndentationWidth.
31
- # SupportedStyles: with_first_element, with_fixed_indentation
32
- Layout/ArrayAlignment:
33
- Exclude:
34
- - 'spec/fixtures.rb'
35
- - 'spec/xmi/sparx/shared_contexts.rb'
36
-
37
- # Offense count: 5
38
- # This cop supports safe autocorrection (--autocorrect).
39
- # Configuration parameters: EnforcedStyleAlignWith.
40
- # SupportedStylesAlignWith: either, start_of_block, start_of_line
41
- Layout/BlockAlignment:
42
- Exclude:
43
- - 'lib/xmi/versioned.rb'
44
- - 'spec/performance/xmi_parsing_spec.rb'
45
- - 'spec/xmi/sparx/sparx_root_citygml_spec.rb'
46
- - 'spec/xmi/sparx/sparx_root_xmi_parsing_spec.rb'
47
-
48
- # Offense count: 7
49
- # This cop supports safe autocorrection (--autocorrect).
50
- Layout/BlockEndNewline:
51
- Exclude:
52
- - 'benchmark_parse.rb'
53
- - 'lib/xmi/versioned.rb'
54
- - 'scripts-xmi-profile/profile_xmi_simple.rb'
55
- - 'spec/performance/xmi_parsing_spec.rb'
56
- - 'spec/xmi/sparx/sparx_root_citygml_spec.rb'
57
- - 'spec/xmi/sparx/sparx_root_xmi_parsing_spec.rb'
58
-
59
- # Offense count: 2
60
- # This cop supports safe autocorrection (--autocorrect).
61
- # Configuration parameters: EnforcedStyle.
62
- # SupportedStyles: empty_lines, no_empty_lines
63
- Layout/EmptyLinesAroundBlockBody:
64
- Exclude:
65
- - 'scripts-xmi-profile/profile_xmi_simple.rb'
66
-
67
- # Offense count: 16
68
- # This cop supports safe autocorrection (--autocorrect).
69
- # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
70
- # SupportedStylesAlignWith: start_of_line, relative_to_receiver
71
- Layout/IndentationWidth:
72
- Exclude:
73
- - 'benchmark_parse.rb'
74
- - 'lib/xmi/versioned.rb'
75
- - 'scripts-xmi-profile/profile_xmi_simple.rb'
76
- - 'spec/performance/xmi_parsing_spec.rb'
77
- - 'spec/xmi/sparx/sparx_root_citygml_spec.rb'
78
- - 'spec/xmi/sparx/sparx_root_xmi_parsing_spec.rb'
20
+ - 'lib/xmi/index.rb'
79
21
 
80
- # Offense count: 101
22
+ # Offense count: 73
81
23
  # This cop supports safe autocorrection (--autocorrect).
82
24
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
83
25
  # URISchemes: http, https
84
26
  Layout/LineLength:
85
27
  Enabled: false
86
28
 
87
- # Offense count: 2
88
- # This cop supports safe autocorrection (--autocorrect).
89
- # Configuration parameters: EnforcedStyle, IndentationWidth.
90
- # SupportedStyles: aligned, indented, indented_relative_to_receiver
91
- Layout/MultilineMethodCallIndentation:
92
- Exclude:
93
- - 'spec/xmi/sparx/sparx_root_citygml_spec.rb'
94
-
95
- # Offense count: 24
29
+ # Offense count: 1
96
30
  # This cop supports safe autocorrection (--autocorrect).
97
31
  # Configuration parameters: AllowInHeredoc.
98
32
  Layout/TrailingWhitespace:
99
33
  Exclude:
100
- - 'lib/tasks/benchmark_runner.rb'
101
- - 'lib/tasks/performance_helpers.rb'
102
- - 'lib/xmi/parsing.rb'
103
- - 'lib/xmi/version_registry.rb'
104
- - 'lib/xmi/versioned.rb'
105
- - 'scripts-xmi-profile/profile_xmi_simple.rb'
106
- - 'spec/fixtures.rb'
107
- - 'spec/xmi/sparx/shared_contexts.rb'
108
- - 'spec/xmi/sparx/sparx_root_xmi_parsing_spec.rb'
109
- - 'spec/xmi/versioning_spec.rb'
34
+ - 'lib/xmi/index.rb'
110
35
 
111
36
  # Offense count: 5
112
37
  # Configuration parameters: AllowedMethods.
@@ -115,7 +40,16 @@ Lint/ConstantDefinitionInBlock:
115
40
  Exclude:
116
41
  - 'spec/performance/xmi_parsing_spec.rb'
117
42
 
118
- # Offense count: 12
43
+ # Offense count: 1
44
+ # This cop supports unsafe autocorrection (--autocorrect-all).
45
+ # Configuration parameters: AllowedMethods, InferNonNilReceiver, AdditionalNilMethods.
46
+ # AllowedMethods: instance_of?, kind_of?, is_a?, eql?, respond_to?, equal?
47
+ # AdditionalNilMethods: present?, blank?, try, try!
48
+ Lint/RedundantSafeNavigation:
49
+ Exclude:
50
+ - 'lib/xmi/index.rb'
51
+
52
+ # Offense count: 14
119
53
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
120
54
  Metrics/AbcSize:
121
55
  Exclude:
@@ -123,6 +57,7 @@ Metrics/AbcSize:
123
57
  - 'lib/tasks/performance_comparator.rb'
124
58
  - 'lib/tasks/performance_helpers.rb'
125
59
  - 'lib/xmi/ea_root.rb'
60
+ - 'lib/xmi/index.rb'
126
61
  - 'lib/xmi/version_registry.rb'
127
62
  - 'spec/performance/xmi_parsing_spec.rb'
128
63
 
@@ -132,24 +67,33 @@ Metrics/AbcSize:
132
67
  Metrics/BlockLength:
133
68
  Max: 143
134
69
 
135
- # Offense count: 1
70
+ # Offense count: 4
136
71
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
137
72
  Metrics/CyclomaticComplexity:
138
73
  Exclude:
139
74
  - 'lib/tasks/performance_helpers.rb'
75
+ - 'lib/xmi/index.rb'
140
76
 
141
- # Offense count: 26
77
+ # Offense count: 28
142
78
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
143
79
  Metrics/MethodLength:
144
80
  Max: 33
145
81
 
146
- # Offense count: 2
82
+ # Offense count: 4
147
83
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
148
84
  Metrics/PerceivedComplexity:
149
85
  Exclude:
150
86
  - 'lib/tasks/performance_helpers.rb'
87
+ - 'lib/xmi/index.rb'
151
88
  - 'lib/xmi/version_registry.rb'
152
89
 
90
+ # Offense count: 3
91
+ # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
92
+ # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
93
+ Naming/MethodParameterName:
94
+ Exclude:
95
+ - 'lib/xmi/index.rb'
96
+
153
97
  # Offense count: 19
154
98
  # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
155
99
  # SupportedStyles: snake_case, normalcase, non_integer
@@ -163,12 +107,6 @@ Naming/VariableNumber:
163
107
  - 'spec/performance/xmi_parsing_spec.rb'
164
108
  - 'spec/xmi/versioning_spec.rb'
165
109
 
166
- # Offense count: 1
167
- # This cop supports unsafe autocorrection (--autocorrect-all).
168
- Performance/TimesMap:
169
- Exclude:
170
- - 'benchmark_parse.rb'
171
-
172
110
  # Offense count: 1
173
111
  RSpec/BeforeAfterAll:
174
112
  Exclude:
@@ -194,34 +132,17 @@ RSpec/DescribeClass:
194
132
  - 'spec/xmi/namespace_aliases_spec.rb'
195
133
  - 'spec/xmi/versioning_spec.rb'
196
134
 
197
- # Offense count: 4
198
- # This cop supports unsafe autocorrection (--autocorrect-all).
199
- # Configuration parameters: SkipBlocks, EnforcedStyle, OnlyStaticConstants.
200
- # SupportedStyles: described_class, explicit
201
- RSpec/DescribedClass:
202
- Exclude:
203
- - 'spec/xmi/sparx/sparx_root_citygml_spec.rb'
204
-
205
135
  # Offense count: 26
206
136
  # Configuration parameters: CountAsOne.
207
137
  RSpec/ExampleLength:
208
138
  Max: 33
209
139
 
210
- # Offense count: 2
211
- # This cop supports safe autocorrection (--autocorrect).
212
- # Configuration parameters: CustomTransform, IgnoredWords, DisallowedExamples.
213
- # DisallowedExamples: works
214
- RSpec/ExampleWording:
215
- Exclude:
216
- - 'spec/xmi/sparx/sparx_root_eauml_spec.rb'
217
- - 'spec/xmi/sparx/sparx_root_gml_spec.rb'
218
-
219
140
  # Offense count: 5
220
141
  RSpec/LeakyConstantDeclaration:
221
142
  Exclude:
222
143
  - 'spec/performance/xmi_parsing_spec.rb'
223
144
 
224
- # Offense count: 35
145
+ # Offense count: 36
225
146
  RSpec/MultipleExpectations:
226
147
  Max: 8
227
148
 
@@ -235,50 +156,16 @@ RSpec/MultipleMemoizedHelpers:
235
156
  RSpec/NestedGroups:
236
157
  Max: 4
237
158
 
238
- # Offense count: 6
239
- # This cop supports safe autocorrection (--autocorrect).
240
- # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
241
- # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
242
- # ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
243
- # FunctionalMethods: let, let!, subject, watch
244
- # AllowedMethods: lambda, proc, it
245
- Style/BlockDelimiters:
246
- Exclude:
247
- - 'benchmark_parse.rb'
248
- - 'lib/xmi/versioned.rb'
249
- - 'scripts-xmi-profile/profile_xmi_simple.rb'
250
- - 'spec/performance/xmi_parsing_spec.rb'
251
- - 'spec/xmi/sparx/sparx_root_citygml_spec.rb'
252
- - 'spec/xmi/sparx/sparx_root_xmi_parsing_spec.rb'
253
-
254
159
  # Offense count: 1
255
160
  # This cop supports safe autocorrection (--autocorrect).
256
- # Configuration parameters: EnforcedStyle.
257
- # SupportedStyles: trailing_conditional, ternary
258
- Style/EmptyStringInsideInterpolation:
259
- Exclude:
260
- - 'scripts-xmi-profile/profile_xmi_simple.rb'
261
-
262
- # Offense count: 2
263
- # This cop supports safe autocorrection (--autocorrect).
264
161
  Style/MultilineIfModifier:
265
162
  Exclude:
266
- - 'lib/xmi/parsing.rb'
267
- - 'lib/xmi/version_registry.rb'
163
+ - 'lib/xmi/index.rb'
268
164
 
269
- # Offense count: 6
165
+ # Offense count: 4
270
166
  # Configuration parameters: AllowedClasses.
271
167
  Style/OneClassPerFile:
272
168
  Exclude:
273
169
  - 'lib/tasks/benchmark_runner.rb'
274
170
  - 'lib/xmi.rb'
275
171
  - 'lib/xmi/namespace/dynamic.rb'
276
- - 'spec/xmi/sparx/shared_contexts.rb'
277
-
278
- # Offense count: 1
279
- # This cop supports safe autocorrection (--autocorrect).
280
- # Configuration parameters: EnforcedStyleForMultiline.
281
- # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
282
- Style/TrailingCommaInArguments:
283
- Exclude:
284
- - 'spec/xmi/sparx/sparx_root_citygml_spec.rb'
data/lib/xmi/index.rb ADDED
@@ -0,0 +1,243 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xmi
4
+ # Builds all commonly needed indexes from a parsed SparxRoot in a single
5
+ # targeted walk, avoiding the generic map_id_name approach that visits every
6
+ # attribute of every node.
7
+ #
8
+ # Indexes built:
9
+ # - id_name_map: { xmi_id => name } for all nodes with both id and name
10
+ # - packaged_elements: flat array of all PackagedElement instances
11
+ # - packaged_by_id: { xmi_id => PackagedElement }
12
+ # - packaged_by_type: { "uml:Class" => [...], "uml:Package" => [...], ... }
13
+ # - upper_level_map: { xmi_id => parent PackagedElement }
14
+ # - elements_by_idref: { idref => Extension::Element::Element }
15
+ # - connectors_by_idref: { idref => Connector::Connector }
16
+ # - attributes_by_idref: { idref => Extension::Element::Attribute }
17
+ # - owned_attrs_by_type_idref: { type_idref => [OwnedAttribute, ...] }
18
+ class Index
19
+ attr_reader :id_name_map, :packaged_elements, :packaged_by_id,
20
+ :packaged_by_type, :upper_level_map, :elements_by_idref,
21
+ :connectors_by_idref, :attributes_by_idref,
22
+ :owned_attrs_by_type_idref
23
+
24
+ PackagedElement = ::Xmi::Uml::PackagedElement
25
+
26
+ # @param root [Xmi::Sparx::SparxRoot] parsed XMI model
27
+ def initialize(root)
28
+ @id_name_map = {}
29
+ @packaged_elements = []
30
+ @packaged_by_id = {}
31
+ @packaged_by_type = {}
32
+ @upper_level_map = {}
33
+ @elements_by_idref = {}
34
+ @connectors_by_idref = {}
35
+ @attributes_by_idref = {}
36
+ @owned_attrs_by_type_idref = {}
37
+
38
+ build(root)
39
+ freeze
40
+ end
41
+
42
+ # Lookup name by XMI ID
43
+ # @param xmi_id [String] XMI identifier
44
+ # @return [String, nil]
45
+ def lookup_name(xmi_id)
46
+ @id_name_map[xmi_id]
47
+ end
48
+
49
+ # Find packaged element by XMI ID
50
+ # @param id [String]
51
+ # @return [Xmi::Uml::PackagedElement, nil]
52
+ def find_packaged_element(id)
53
+ @packaged_by_id[id]
54
+ end
55
+
56
+ # Find parent of a packaged element
57
+ # @param id [String] child XMI ID
58
+ # @return [Xmi::Uml::PackagedElement, nil]
59
+ def find_parent(id)
60
+ @upper_level_map[id]
61
+ end
62
+
63
+ # Find extension element by idref
64
+ # @param idref [String]
65
+ # @return [Xmi::Sparx::Element::Element, nil]
66
+ def find_element(idref)
67
+ @elements_by_idref[idref]
68
+ end
69
+
70
+ # Find connector by idref
71
+ # @param idref [String]
72
+ # @return [Xmi::Sparx::Connector::Connector, nil]
73
+ def find_connector(idref)
74
+ @connectors_by_idref[idref]
75
+ end
76
+
77
+ # Find extension attribute by idref
78
+ # @param idref [String]
79
+ # @return [Xmi::Sparx::Element::Attribute, nil]
80
+ def find_attribute(idref)
81
+ @attributes_by_idref[idref]
82
+ end
83
+
84
+ # Find owned attributes whose uml_type.idref matches
85
+ # @param type_idref [String]
86
+ # @return [Array<Xmi::Uml::OwnedAttribute>]
87
+ def find_owned_attrs_by_type(type_idref)
88
+ @owned_attrs_by_type_idref[type_idref] || []
89
+ end
90
+
91
+ # Find packaged elements by UML type
92
+ # @param type [String] e.g. "uml:Class", "uml:Package"
93
+ # @return [Array<Xmi::Uml::PackagedElement>]
94
+ def packaged_elements_of_type(type)
95
+ @packaged_by_type[type] || []
96
+ end
97
+
98
+ # Find first packaged element by name and allowed types
99
+ # @param name [String]
100
+ # @param types [Array<String>] e.g. ["uml:Class", "uml:AssociationClass"]
101
+ # @return [Xmi::Uml::PackagedElement, nil]
102
+ def find_packaged_by_name_and_types(name, types)
103
+ types.each do |type|
104
+ elements = @packaged_by_type[type]
105
+ next unless elements
106
+
107
+ found = elements.find { |e| e.name == name }
108
+ return found if found
109
+ end
110
+ nil
111
+ end
112
+
113
+ private
114
+
115
+ def build(root)
116
+ model = root.model
117
+ if model
118
+ id = model.id if model.respond_to?(:id)
119
+ @id_name_map[id] = model.name if id && model.name
120
+ walk_packaged_elements(model.packaged_element, nil)
121
+ end
122
+
123
+ ext = root.extension
124
+ return unless ext
125
+
126
+ index_extension_elements(ext.elements)
127
+ index_extension_connectors(ext.connectors)
128
+
129
+ primitives = ext.primitive_types
130
+ walk_packaged_elements(primitives.packaged_element, nil) if primitives
131
+
132
+ index_extension_profiles(ext.profiles)
133
+ end
134
+
135
+ def walk_packaged_elements(elements, parent) # rubocop:disable Metrics/MethodLength
136
+ return unless elements
137
+
138
+ id_name_map = @id_name_map
139
+ packaged_by_id = @packaged_by_id
140
+ packaged_by_type = @packaged_by_type
141
+ upper_level_map = @upper_level_map
142
+ packaged_elements = @packaged_elements
143
+ owned_attrs_by_type = @owned_attrs_by_type_idref
144
+
145
+ elements.each do |pe|
146
+ next unless pe.is_a?(PackagedElement)
147
+
148
+ pe_id = pe.id
149
+ pe_type = pe.type
150
+ pe_name = pe.name
151
+
152
+ packaged_elements << pe
153
+ packaged_by_id[pe_id] = pe if pe_id
154
+ (packaged_by_type[pe_type] ||= []) << pe if pe_type
155
+ upper_level_map[pe_id] = parent if parent && pe_id
156
+ id_name_map[pe_id] = pe_name if pe_id && pe_name
157
+
158
+ # Inline owned attribute indexing
159
+ attrs = pe.owned_attribute
160
+ if attrs && !attrs.empty?
161
+ attrs.each do |oa|
162
+ oa_id = oa.id
163
+ id_name_map[oa_id] = oa.name if oa_id && oa.name
164
+ oa_type = oa.uml_type
165
+ if oa.association && oa_type && oa_type.idref
166
+ (owned_attrs_by_type[oa_type.idref] ||= []) << oa
167
+ end
168
+ end
169
+ end
170
+
171
+ # Inline owned operation indexing
172
+ ops = pe.owned_operation
173
+ if ops && !ops.empty?
174
+ ops.each do |oo|
175
+ oo_id = oo.id
176
+ id_name_map[oo_id] = oo.name if oo_id && oo.name
177
+ end
178
+ end
179
+
180
+ # Inline owned literal indexing
181
+ lits = pe.owned_literal
182
+ if lits && !lits.empty?
183
+ lits.each do |ol|
184
+ ol_id = ol.id
185
+ id_name_map[ol_id] = ol.name if ol_id && ol.name
186
+ end
187
+ end
188
+
189
+ # Recurse into children
190
+ walk_packaged_elements(pe.packaged_element, pe)
191
+ end
192
+ end
193
+
194
+ def index_extension_elements(elements)
195
+ return unless elements
196
+
197
+ element_list = elements.element
198
+ return unless element_list
199
+
200
+ element_list.each do |e|
201
+ idref = e.idref
202
+ next unless idref
203
+
204
+ @elements_by_idref[idref] = e
205
+
206
+ props = e.properties
207
+ @id_name_map[idref] = props.name if props&.name
208
+
209
+ attrs_obj = e.attributes
210
+ next unless attrs_obj
211
+
212
+ attr_list = attrs_obj.attribute
213
+ next unless attr_list
214
+
215
+ attr_list.each do |a|
216
+ @attributes_by_idref[a.idref] = a if a.idref
217
+ end
218
+ end
219
+ end
220
+
221
+ def index_extension_connectors(connectors)
222
+ return unless connectors
223
+
224
+ conn_list = connectors.connector
225
+ return unless conn_list
226
+
227
+ conn_list.each do |c|
228
+ @connectors_by_idref[c.idref] = c if c.idref
229
+ end
230
+ end
231
+
232
+ def index_extension_profiles(profiles)
233
+ return unless profiles
234
+
235
+ profile_list = profiles.profile
236
+ return unless profile_list
237
+
238
+ profile_list.each do |profile|
239
+ walk_packaged_elements(profile.packaged_element, nil) if profile.respond_to?(:packaged_element)
240
+ end
241
+ end
242
+ end
243
+ end
@@ -194,7 +194,7 @@ module Xmi
194
194
 
195
195
  class Connector < Lutaml::Model::Serializable
196
196
  attribute :name, :string
197
- attribute :idref, :string
197
+ attribute :idref, ::Xmi::Type::XmiIdRef
198
198
  attribute :source, Source
199
199
  attribute :target, Target
200
200
  attribute :model, Model
@@ -27,13 +27,15 @@ module Xmi
27
27
  # their corresponding UML versions.
28
28
  #
29
29
  # @param xml_content [String] The raw XMI XML content
30
- # @return [SparxRoot] The parsed Ruby object
30
+ # @return [SparxRoot] The parsed Ruby object with index built
31
31
  #
32
32
  # @see Xmi.parse
33
33
  def parse_xml(xml_content)
34
34
  xml_content = fix_encoding(xml_content)
35
35
  Xmi.init_versioning!
36
- Xmi::VersionRegistry.parse_with_detected_version(xml_content, self)
36
+ root = Xmi::VersionRegistry.parse_with_detected_version(xml_content, self)
37
+ root.build_index
38
+ root
37
39
  end
38
40
 
39
41
  # Fix invalid UTF-8 encoding in the XML content.
@@ -55,6 +57,18 @@ module Xmi
55
57
 
56
58
  # Use the reusable BaseMapping class instead of eval hack
57
59
  xml SparxMappings::BaseMapping
60
+
61
+ # Build index for fast lookups
62
+ # @return [Xmi::Index]
63
+ def build_index
64
+ @index = Xmi::Index.new(self)
65
+ end
66
+
67
+ # Access the index (builds on first access if needed)
68
+ # @return [Xmi::Index]
69
+ def index
70
+ @index || build_index
71
+ end
58
72
  end
59
73
  end
60
74
  end
data/lib/xmi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Xmi
4
- VERSION = "0.5.1"
4
+ VERSION = "0.5.3"
5
5
  end
@@ -158,7 +158,8 @@ module Xmi
158
158
  # Extend fallback chain only if it won't create a cycle.
159
159
  # A cycle would occur if reg's fallback chain includes primary_register.
160
160
  # We check this by seeing if primary_register.id appears in reg's fallback.
161
- primary_register.fallback << reg.id unless reg.fallback.include?(primary_register.id)
161
+ # Use add_fallback to keep Register and TypeContext in sync and invalidate caches.
162
+ primary_register.add_fallback(reg.id) unless reg.fallback.include?(primary_register.id)
162
163
  end
163
164
  end
164
165
  # rubocop:enable Metrics/CyclomaticComplexity
data/lib/xmi.rb CHANGED
@@ -55,6 +55,7 @@ require_relative "xmi/uml"
55
55
  require_relative "xmi/custom_profile"
56
56
  require_relative "xmi/root"
57
57
  require_relative "xmi/sparx"
58
+ require_relative "xmi/index"
58
59
 
59
60
  # Unified parsing API
60
61
  require_relative "xmi/parsing"
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.5.1
4
+ version: 0.5.3
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-04-12 00:00:00.000000000 Z
11
+ date: 2026-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lutaml-model
@@ -72,6 +72,7 @@ files:
72
72
  - lib/xmi/documentation.rb
73
73
  - lib/xmi/ea_root.rb
74
74
  - lib/xmi/extension.rb
75
+ - lib/xmi/index.rb
75
76
  - lib/xmi/namespace.rb
76
77
  - lib/xmi/namespace/dynamic.rb
77
78
  - lib/xmi/namespace/omg.rb