Skip to content

[Feature]: Implementation of MetadataAccessExpressionExtensions.ComputeMetaclassFeatureOperation #270

@antoineatstariongroup

Description

@antoineatstariongroup

What type of issue is this?

  • Bug report
  • Feature request

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of the SysML2.NET
  • I have searched open and closed issues to ensure it has not already been reported

Description

MetadataAccessExpressionExtensions.ComputeMetaclassFeatureOperation is currently stubbed because the spec body has no OCL — the operation requires reflective metamodel infrastructure that the SDK does not yet provide. Issue #153 ticks this method's siblings (ComputeReferencedElement, ComputeRedefinedModelLevelEvaluableOperation, ComputeRedefinedEvaluateOperation) and leaves this one deferred with a NotSupportedException and a code comment pointing here.

The spec text on the method:

Return a MetadataFeature whose annotatedElement is the referencedElement, whose metaclass is the reflective Metaclass corresponding to the MOF class of the referencedElement and whose ownedFeatures are bound to the values of the MOF properties of the referencedElement.

The intent is to mirror the SysML 2 Pilot Implementation (Java) mechanism — ElementAdapter.getMetaclassFeature() + the property-value-binding layer — adapted to .NET, building on the hybrid codegen + runtime cache design proposed in #256.

Dependency on #256

This issue depends on #256 (MetadataFeatureExtensions.ComputeSyntaxElementOperation):

If #256 PRs 1 + 2 land first, the work for this issue collapses to two components: re-using the cache and adding the MOF-property-to-owned-feature binding layer (which #256 does NOT need, because syntaxElement is a pure inverse lookup that doesn't materialise feature values).

What has to be done

Two components, suggested as two sequential PRs after #256 PRs 1 + 2 land:

  1. Extend MetaclassFeatureCache with property-value binding under SysML2.NET/Core/Reflection/:

    • The base cache from [Feature]: Implementation of MetadataFeatureExtensions.ComputeSyntaxElementOperation #256 PR 2 wires a shadow MetadataFeature with FeatureTyping → library Metaclass + Annotation → annotatedElement. That is sufficient for syntaxElement (reverse lookup), but ComputeMetaclassFeatureOperation per spec also needs ownedFeatures bound to the live values of the referenced element's MOF properties.
    • Add a MetaclassFeatureCache.GetOrCreateWithBoundProperties(IElement) overload (or upgrade the existing GetOrCreate to always bind). For each [Property(xmiId: ...)] attribute on the referenced element's POCO interface, synthesize an owned IFeature on the shadow whose value is read from the live property getter. Property-feature binding mirrors the pilot's ElementUtil.getMetaclassFeatureFor property-population loop (Java reflection over EMF EStructuralFeature; in .NET, reflection over the POCO's [Property]-decorated members).
    • Decision needed in the PR: whether to compute owned features lazily (on first ownedFeature access on the shadow) or eagerly at cache materialisation. Lazy is cheaper but harder to test; eager is more deterministic.
  2. Implement ComputeMetaclassFeatureOperation at SysML2.NET/Extend/MetadataAccessExpressionExtensions.cs:140 — replace the NotSupportedException stub with a single delegation:

    return metadataAccessExpressionSubject == null
        ? throw new ArgumentNullException(nameof(metadataAccessExpressionSubject))
        : MetaclassFeatureCache.GetOrCreateWithBoundProperties(metadataAccessExpressionSubject.referencedElement);

    Remove [ExcludeFromCodeCoverage]. Update MetadataAccessExpressionExtensionsTestFixture.cs to replace ComputeMetaclassFeatureOperation_ThrowsNotSupportedException with a real test that asserts:

    • Null guard → ArgumentNullException.
    • Empty subject → IncompleteModelException (propagated from ComputeReferencedElement, since referencedElement is [1..1]).
    • Valid subject with a referenced PortDefinition → the returned IMetadataFeature has the expected metaclass identity (KerML::Kernel::PortDefinition or whichever path the resolver produces), AnnotatedElement contains the referenced element, and at least one owned feature reflects a known live property value (e.g. name).
    • Calling MetaclassFeature() twice on the same subject returns the SAME instance (cache identity — proves the ConditionalWeakTable keys correctly on the referenced element).

    Also re-verify that ComputeRedefinedEvaluateOperation (now no longer transitively throwing) returns the expected list — the test fixture for Verify_ComputeRedefinedEvaluateOperation should be expanded to cover the previously-NotSupportedException valid-subject branch with a real list assertion.

Checklist

Out of scope (intentional follow-ups)

  • Reflective access to operations (not just properties) of the referenced element. MetadataFeature.ownedFeature per the spec only binds properties; operations stay opaque.
  • Caching strategy tuning beyond ConditionalWeakTable. If profiling shows the property-binding loop is hot, switch to lazy materialisation behind an IList<IFeature> proxy in a separate PR.
  • Validation of the synthesized feature graph against OCL invariants on MetadataFeature — implement when the relevant MetadataFeatureExtensions.Validate* methods exist.

System Configuration

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions