You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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 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.
Implement ComputeMetaclassFeatureOperation at SysML2.NET/Extend/MetadataAccessExpressionExtensions.cs:140 — replace the NotSupportedException stub with a single delegation:
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.
PR A: extend MetaclassFeatureCache with MOF-property-to-owned-feature binding + unit tests asserting cache identity AND property-value reflection
PR B: replace the ComputeMetaclassFeatureOperation stub in MetadataAccessExpressionExtensions.cs:140; update MetadataAccessExpressionExtensionsTestFixture.cs; expand the Verify_ComputeRedefinedEvaluateOperation test 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.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.
Reference (Java pilot): org.omg.sysml/src/org/omg/sysml/util/ElementUtil.java (the getMetaclassFeatureFor family + property-population loop), org.omg.sysml/src/org/omg/sysml/adapter/ElementAdapter.java (lines 92-109 for the cache pattern)
What type of issue is this?
Prerequisites
Description
MetadataAccessExpressionExtensions.ComputeMetaclassFeatureOperationis 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 aNotSupportedExceptionand a code comment pointing here.The spec text on the method:
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):MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 1 emitsStandardLibrary.csexposing a realLibraryPackagegraph withIMetaclassnodes for every metaclass in the XMI. Required here to resolve themetaclassreference on the synthesizedMetadataFeature.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
syntaxElementis 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/: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.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).ownedFeatureaccess on the shadow) or eagerly at cache materialisation. Lazy is cheaper but harder to test; eager is more deterministic.Implement
ComputeMetaclassFeatureOperationatSysML2.NET/Extend/MetadataAccessExpressionExtensions.cs:140— replace theNotSupportedExceptionstub with a single delegation:Remove
[ExcludeFromCodeCoverage]. UpdateMetadataAccessExpressionExtensionsTestFixture.csto replaceComputeMetaclassFeatureOperation_ThrowsNotSupportedExceptionwith a real test that asserts:ArgumentNullException.IncompleteModelException(propagated fromComputeReferencedElement, sincereferencedElementis[1..1]).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).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.Checklist
MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 1 —StandardLibrary.csgenerationMetadataFeatureExtensions.ComputeSyntaxElementOperation#256 PR 2 —MetaclassFeatureCache.cs+MetaclassNameResolver.csbase implementationMetaclassFeatureCachewith MOF-property-to-owned-feature binding + unit tests asserting cache identity AND property-value reflectionComputeMetaclassFeatureOperationstub inMetadataAccessExpressionExtensions.cs:140; updateMetadataAccessExpressionExtensionsTestFixture.cs; expand theVerify_ComputeRedefinedEvaluateOperationtest now that the chain no longer throws; tick the corresponding item on issue [Feature]: Implement MetadataAccessExpressionExtension #153Out of scope (intentional follow-ups)
MetadataFeature.ownedFeatureper the spec only binds properties; operations stay opaque.ConditionalWeakTable. If profiling shows the property-binding loop is hot, switch to lazy materialisation behind anIList<IFeature>proxy in a separate PR.MetadataFeature— implement when the relevantMetadataFeatureExtensions.Validate*methods exist.System Configuration
SysML2.NET/Extend/MetadataAccessExpressionExtensions.csorg.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)ComputeMetaclassFeatureOperationitem on issue [Feature]: Implement MetadataAccessExpressionExtension #153MetadataFeatureExtensions.ComputeSyntaxElementOperation#256 (PRs 1 + 2)