Skip to content

[Feature] Resolve positional @feature.index and bare xmi:id URI fragments (#106)#111

Merged
samatstariongroup merged 2 commits into
developmentfrom
GH106
Jul 5, 2026
Merged

[Feature] Resolve positional @feature.index and bare xmi:id URI fragments (#106)#111
samatstariongroup merged 2 commits into
developmentfrom
GH106

Conversation

@samatstariongroup

Copy link
Copy Markdown
Member

What

Closes #106. Adds the two EMF URI-fragment-resolution forms that Resource.GetEObject did not previously support:

  1. Positional @feature.index fragments — e.g. #//@eClassifiers.3/@eStructuralFeatures.1. Resolved by structural navigation from the resource root, indexing into the containment feature named by each segment (mirrors EMF's eObjectForURIFragmentSegment). Works same-file and cross-file.
  2. Bare xmi:id fragments — a fragment without a leading slash (e.g. #_node), which EMF resolves via getEObjectByID. Any element carrying an xmi:id is now recorded in a per-resource id→object map during ReadXml, and consulted when the fragment is not a /-rooted path.

(The name-based name.N disambiguation form already resolved since #96, since the disambiguated identifier is the cache key.)

How

  • EObject.ReadXml now calls a small RegisterXmiId() after saving attributes: if the element has an xmi:id, it registers itself with the resource. Covers named and unnamed (EGenericType) objects alike.
  • Resource gains an idToEObject map + RegisterEObjectId (first-writer-wins; a duplicate xmi:id is invalid but must not abort the load).
  • Resource.GetEObject tail is restructured: after the cache and built-in-type lookups miss, it computes the in-document fragment and delegates to a new ResolveInDocumentFragment:
    • /-rooted and contains @ResolveStructuralFragment (positional navigation).
    • /-rooted, no @ → returns null (pure name paths are already covered by the identifier cache).
    • otherwise → xmi:id lookup.
      This runs for the owning resource, which is this resource for a same-file positional reference (rewritten to file.ecore#//@…) and a sibling for cross-file references. It is evaluated before the cross-resource delegation, so it never trips the cycle guard.
  • Structural navigation maps each @feature name to the owning object's containment list (eClassifiers, eSubpackages, eStructuralFeatures, eOperations, eGenericSuperTypes, eLiterals, eParameters, eGenericExceptions, eTypeParameters, eBounds, eAnnotations) and indexes into it.

No existing behaviour changes: name-based and file-delegated resolution paths are unchanged; the new paths only fire on fragments that previously returned null.

Tests

New ECoreNetto.Tests/Resource/PositionalAndIdFragmentTestFixture.cs (6 tests, synthetic models):

  • same-file positional eType references;
  • a deep positional path resolving to a structural feature via GetEObject;
  • a comprehensive test navigating every supported containment feature;
  • same-file xmi:id (including the duplicate-id first-wins case);
  • cross-file positional and xmi:id;
  • negatives: out-of-range index, unknown/missing feature, non-@ segment, @feature without index, non-numeric index, missing name path, empty fragment, unknown xmi:id.

Full solution builds with 0 warnings; entire suite green (281 tests, +6).

Scope

Splits from #106 as agreed; EAnnotation.contents (needs a dynamic EObject) remains tracked separately in #109.

@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor
Package Line Rate Branch Rate Complexity Health
ECoreNetto 91% 87% 690
ECoreNetto.Extensions 99% 92% 101
ECoreNetto.HandleBars 99% 97% 60
ECoreNetto.Reporting 83% 71% 181
ECoreNetto.Tools 95% 92% 58
Summary 91% (2590 / 2835) 85% (741 / 870) 1090

@sonarqubecloud

sonarqubecloud Bot commented Jul 5, 2026

Copy link
Copy Markdown

@samatstariongroup
samatstariongroup merged commit f09d0c9 into development Jul 5, 2026
14 checks passed
@samatstariongroup
samatstariongroup deleted the GH106 branch July 5, 2026 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EMF reading-compatibility follow-ups: @feature.N positional fragments, xmi:id resolution

1 participant