Repository navigation
[Feature]: Implementation of MetadataAccessExpressionExtensions.ComputeMetaclassFeatureOperation #270
Description
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
annotatedElementis thereferencedElement, whosemetaclassis the reflective Metaclass corresponding to the MOF class of thereferencedElementand whoseownedFeaturesare bound to the values of the MOF properties of thereferencedElement.
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):
- [Feature]: Implementation of
MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 1 emitsStandardLibrary.csexposing a realLibraryPackagegraph withIMetaclassnodes for every metaclass in the XMI. Required here to resolve themetaclassreference on the synthesizedMetadataFeature. - [Feature]: Implementation of
MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 2 introducesMetaclassFeatureCache.GetOrCreate(IElement)andMetaclassNameResolverunderSysML2.NET/Core/Reflection/. Required here as the foundation —ComputeMetaclassFeatureOperationreturns a cached shadowMetadataFeaturekeyed on thereferencedElement.
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:
-
Extend
MetaclassFeatureCachewith property-value binding underSysML2.NET/Core/Reflection/:- The base cache from [Feature]: Implementation of
MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 2 wires a shadowMetadataFeaturewithFeatureTyping → library Metaclass+Annotation → annotatedElement. That is sufficient forsyntaxElement(reverse lookup), butComputeMetaclassFeatureOperationper spec also needsownedFeaturesbound to the live values of the referenced element's MOF properties. - Add a
MetaclassFeatureCache.GetOrCreateWithBoundProperties(IElement)overload (or upgrade the existingGetOrCreateto always bind). For each[Property(xmiId: ...)]attribute on the referenced element's POCO interface, synthesize an ownedIFeatureon the shadow whose value is read from the live property getter. Property-feature binding mirrors the pilot'sElementUtil.getMetaclassFeatureForproperty-population loop (Java reflection over EMFEStructuralFeature; in .NET, reflection over the POCO's[Property]-decorated members). - Decision needed in the PR: whether to compute owned features lazily (on first
ownedFeatureaccess on the shadow) or eagerly at cache materialisation. Lazy is cheaper but harder to test; eager is more deterministic.
- The base cache from [Feature]: Implementation of
-
Implement
ComputeMetaclassFeatureOperationatSysML2.NET/Extend/MetadataAccessExpressionExtensions.cs:140— replace theNotSupportedExceptionstub with a single delegation:return metadataAccessExpressionSubject == null ? throw new ArgumentNullException(nameof(metadataAccessExpressionSubject)) : MetaclassFeatureCache.GetOrCreateWithBoundProperties(metadataAccessExpressionSubject.referencedElement);
Remove
[ExcludeFromCodeCoverage]. UpdateMetadataAccessExpressionExtensionsTestFixture.csto replaceComputeMetaclassFeatureOperation_ThrowsNotSupportedExceptionwith a real test that asserts:- Null guard →
ArgumentNullException. - Empty subject →
IncompleteModelException(propagated fromComputeReferencedElement, sincereferencedElementis[1..1]). - Valid subject with a referenced
PortDefinition→ the returnedIMetadataFeaturehas the expected metaclass identity (KerML::Kernel::PortDefinitionor whichever path the resolver produces),AnnotatedElementcontains 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 theConditionalWeakTablekeys correctly on the referenced element).
Also re-verify that
ComputeRedefinedEvaluateOperation(now no longer transitively throwing) returns the expected list — the test fixture forVerify_ComputeRedefinedEvaluateOperationshould be expanded to cover the previously-NotSupportedExceptionvalid-subject branch with a real list assertion. - Null guard →
Checklist
- Depends on [Feature]: Implementation of
MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 1 —StandardLibrary.csgeneration - Depends on [Feature]: Implementation of
MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 2 —MetaclassFeatureCache.cs+MetaclassNameResolver.csbase implementation - PR A: extend
MetaclassFeatureCachewith MOF-property-to-owned-feature binding + unit tests asserting cache identity AND property-value reflection - PR B: replace the
ComputeMetaclassFeatureOperationstub inMetadataAccessExpressionExtensions.cs:140; updateMetadataAccessExpressionExtensionsTestFixture.cs; expand theVerify_ComputeRedefinedEvaluateOperationtest now that the chain no longer throws; tick the corresponding item on issue [Feature]: Implement MetadataAccessExpressionExtension #153
Out of scope (intentional follow-ups)
- Reflective access to operations (not just properties) of the referenced element.
MetadataFeature.ownedFeatureper 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 anIList<IFeature>proxy in a separate PR. - Validation of the synthesized feature graph against OCL invariants on
MetadataFeature— implement when the relevantMetadataFeatureExtensions.Validate*methods exist.
System Configuration
- SysML2.NET version: 0.19.0
- Source file:
SysML2.NET/Extend/MetadataAccessExpressionExtensions.cs - Reference (Java pilot):
org.omg.sysml/src/org/omg/sysml/util/ElementUtil.java(thegetMetaclassFeatureForfamily + property-population loop),org.omg.sysml/src/org/omg/sysml/adapter/ElementAdapter.java(lines 92-109 for the cache pattern) - Blocks:
ComputeMetaclassFeatureOperationitem on issue [Feature]: Implement MetadataAccessExpressionExtension #153 - Depends on: [Feature]: Implementation of
MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 (PRs 1 + 2)
Activity