sysmlpy 0.48.0__tar.gz → 0.49.0__tar.gz

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.
Files changed (148) hide show
  1. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/__init__.py +1 -1
  4. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr_visitor.py +113 -2
  5. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/classes.py +12 -6
  6. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/LICENSE +0 -0
  7. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/README.md +0 -0
  8. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/__main__.py +0 -0
  9. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/README.md +0 -0
  10. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  11. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  12. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  13. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  14. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  15. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  16. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  17. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  18. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  19. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  20. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  21. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr_parser.py +0 -0
  22. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/boxes_view.py +0 -0
  23. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/definition.py +0 -0
  24. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  25. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  26. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  27. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/formatting.py +0 -0
  28. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  29. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  30. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  31. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  32. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  33. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  34. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  35. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  36. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  37. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  38. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  39. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  40. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  41. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  42. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  43. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  44. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/LICENSE +0 -0
  45. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/README.md +0 -0
  46. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/__init__.py +0 -0
  47. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  48. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  49. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  50. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  51. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  52. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  53. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  54. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  55. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  56. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  57. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  58. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  59. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  60. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  61. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  62. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  63. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  64. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  65. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  66. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  67. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  68. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  69. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  70. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  71. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  72. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  73. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  74. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  75. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  76. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  77. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  78. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  79. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  80. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  81. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  82. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  83. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  84. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  85. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  86. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  87. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  88. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  89. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  90. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  91. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  92. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  93. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  94. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  95. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  96. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  97. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  98. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  99. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  100. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  101. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  102. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  103. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  104. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  105. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  106. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  107. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  108. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  109. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  110. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  111. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  112. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  113. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  114. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  115. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  116. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  117. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  118. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  119. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  120. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  121. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  122. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  123. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  124. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  125. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  126. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  127. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  128. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  129. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  130. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  131. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  132. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  133. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  134. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  135. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  136. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  137. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  138. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  139. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  140. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  141. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/navigate.py +0 -0
  142. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/plantuml.py +0 -0
  143. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/project.py +0 -0
  144. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/semantic.py +0 -0
  145. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/store.py +0 -0
  146. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/us_customary_units.txt +0 -0
  147. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/usage.py +0 -0
  148. {sysmlpy-0.48.0 → sysmlpy-0.49.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.48.0
3
+ Version: 0.49.0
4
4
  Summary:
5
5
  License-File: LICENSE
6
6
  Author: Jon R. Fox (mycr0ft)
@@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api"
6
6
 
7
7
  [project]
8
8
  name = "sysmlpy"
9
- version = "0.48.0"
9
+ version = "0.49.0"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -25,7 +25,7 @@ __all__ = [
25
25
  "render_state_transition_view_svg", "boxes_view",
26
26
  ]
27
27
  __author__ = "Jon Fox"
28
- __version__ = "0.48.0"
28
+ __version__ = "0.49.0"
29
29
 
30
30
  from sysmlpy.usage import (
31
31
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -314,6 +314,7 @@ def _visit_metadata_feature_dict(ctx):
314
314
  })
315
315
 
316
316
  body = ""
317
+ body_features = []
317
318
  if ctx.metadataBody():
318
319
  if ctx.metadataBody().SEMI():
319
320
  body = ";"
@@ -323,14 +324,124 @@ def _visit_metadata_feature_dict(ctx):
323
324
  # the round-trip. Without this, every `key = value;` inside
324
325
  # a metadata application is silently dropped at visit time.
325
326
  body = ctx.metadataBody().getText()
326
-
327
+ # Issue #8: also surface each metadataBodyElement as a
328
+ # structured bodyFeatures entry so downstream consumers
329
+ # (sysml2kit, validators, etc.) can read individual
330
+ # key = value fields without re-parsing the raw text.
331
+ # Mirrors the per-endpoint capture introduced for issue #5.
332
+ body_features = _visit_metadata_body_features(ctx.metadataBody())
333
+
327
334
  return {
328
335
  "name": "MetadataFeature",
329
336
  "prefixMetadataMember": prefix_members,
330
337
  "identification": identification,
331
338
  "ownedFeatureTyping": owned_feature_typing,
332
339
  "ownedRelationship_about": annotations,
333
- "body": body
340
+ "body": body,
341
+ "bodyFeatures": body_features,
342
+ }
343
+
344
+
345
+ def _visit_metadata_body_features(mb_ctx):
346
+ """Capture each ``metadataBodyElement`` from a braced metadata body.
347
+
348
+ Issue #8: ``_visit_metadata_feature_dict`` previously emitted the
349
+ raw body text but never surfaced the individual ``key = value;``
350
+ items, so consumers of ``load_grammar_antlr`` had no way to read
351
+ the field assignments without re-parsing the raw text.
352
+
353
+ The emitted ``bodyFeatures`` list contains one dict per
354
+ ``metadataBodyElement``. For the common ``metadataBodyFeature``
355
+ case each entry carries ``name`` (the feature name from
356
+ ``ownedRedefinition``), ``value`` (the raw ``=value`` text from
357
+ ``valuePart``), and ``text`` (the full source text of the
358
+ element). For the heterogeneous alternative
359
+ (``definitionMember | metadataBodyUsageMember | aliasMember |
360
+ importRule``) only ``text`` is captured.
361
+ """
362
+ if mb_ctx is None:
363
+ return []
364
+
365
+ features = []
366
+
367
+ # First alternative: metadataBodyElement list (the common path).
368
+ if hasattr(mb_ctx, 'metadataBodyElement') and mb_ctx.metadataBodyElement():
369
+ for elem in mb_ctx.metadataBodyElement():
370
+ entry = _visit_metadata_body_element(elem)
371
+ if entry is not None:
372
+ features.append(entry)
373
+
374
+ # Second alternative: heterogeneous (definitionMember |
375
+ # metadataBodyUsageMember | aliasMember | importRule). ANTLR
376
+ # matches exactly one of the two alternatives; if the first
377
+ # alternative returned nothing, try the heterogeneous shapes.
378
+ if not features:
379
+ for attr in ('definitionMember', 'metadataBodyUsageMember',
380
+ 'aliasMember', 'importRule'):
381
+ if hasattr(mb_ctx, attr) and getattr(mb_ctx, attr)():
382
+ items = getattr(mb_ctx, attr)()
383
+ if not isinstance(items, list):
384
+ items = [items]
385
+ for item in items:
386
+ features.append({
387
+ "name": None,
388
+ "value": None,
389
+ "text": item.getText(),
390
+ })
391
+
392
+ return features
393
+
394
+
395
+ def _visit_metadata_body_element(elem_ctx):
396
+ """Capture a single ``metadataBodyElement`` as a bodyFeatures entry."""
397
+ if elem_ctx is None:
398
+ return None
399
+
400
+ text = elem_ctx.getText()
401
+
402
+ # Common case: metadataBodyFeatureMember -> metadataBodyFeature.
403
+ if hasattr(elem_ctx, 'metadataBodyFeatureMember') and elem_ctx.metadataBodyFeatureMember():
404
+ fbm = elem_ctx.metadataBodyFeatureMember()
405
+ if hasattr(fbm, 'metadataBodyFeature') and fbm.metadataBodyFeature():
406
+ f = fbm.metadataBodyFeature()
407
+ # Feature name from ownedRedefinition (qualifiedName).
408
+ name_text = None
409
+ if hasattr(f, 'ownedRedefinition') and f.ownedRedefinition():
410
+ name_text = f.ownedRedefinition().getText()
411
+ # Value text from valuePart (e.g. '="demo"' or '=0.5').
412
+ # Preserve the operator so downstream tools can decide
413
+ # whether '=' vs ':=' vs 'default =' was used.
414
+ value_text = None
415
+ if hasattr(f, 'valuePart') and f.valuePart():
416
+ value_text = f.valuePart().getText()
417
+ # Optional featureSpecializationPart (e.g. ': Type') and
418
+ # FEATURE keyword (redefinition marker). Capture for
419
+ # downstream consumers that need to distinguish redefines
420
+ # vs new feature declarations.
421
+ specialization = None
422
+ if hasattr(f, 'featureSpecializationPart') and f.featureSpecializationPart():
423
+ specialization = f.featureSpecializationPart().getText()
424
+ is_feature_keyword = (
425
+ hasattr(f, 'FEATURE') and f.FEATURE() is not None
426
+ )
427
+ is_redefines = (
428
+ hasattr(f, 'REDEFINES') and getattr(f, 'REDEFINES', lambda: None)() is not None
429
+ )
430
+ return {
431
+ "name": name_text,
432
+ "value": value_text,
433
+ "text": text,
434
+ "featureKeyword": is_feature_keyword,
435
+ "redefines": is_redefines,
436
+ "specialization": specialization,
437
+ }
438
+
439
+ # Fallback for non-feature metadataBodyElement shapes
440
+ # (aliasMember / importRule / nonFeatureMember).
441
+ return {
442
+ "name": None,
443
+ "value": None,
444
+ "text": text,
334
445
  }
335
446
 
336
447
 
@@ -4558,24 +4558,29 @@ class MetadataFeature:
4558
4558
  # )? metadataBody
4559
4559
  # ;
4560
4560
  def __init__(self, definition):
4561
- if valid_definition(definition, "MetadataFeature"):
4561
+ if valid_definition(definition, self.__class__.__name__):
4562
4562
  self.prefix = []
4563
4563
  for p in definition.get("prefixMetadataMember", []):
4564
4564
  self.prefix.append(PrefixMetadataMember(p))
4565
-
4565
+
4566
4566
  self.identification = None
4567
4567
  if definition.get("identification") is not None:
4568
4568
  self.identification = Identification(definition["identification"])
4569
-
4569
+
4570
4570
  self.typing = None
4571
4571
  if definition.get("ownedFeatureTyping") is not None:
4572
4572
  self.typing = OwnedFeatureTyping(definition["ownedFeatureTyping"])
4573
-
4573
+
4574
4574
  self.annotations = []
4575
4575
  for ann in definition.get("ownedRelationship_about", []):
4576
4576
  self.annotations.append(Annotation(ann))
4577
-
4577
+
4578
4578
  self.body = definition.get("body", "")
4579
+ # Issue #8: structured per-element capture so consumers can
4580
+ # read individual key = value features without re-parsing
4581
+ # the raw body text. ``dump()`` continues to use the raw
4582
+ # ``self.body`` so whitespace is preserved exactly.
4583
+ self.bodyFeatures = list(definition.get("bodyFeatures", []))
4579
4584
 
4580
4585
  def dump(self):
4581
4586
  output = []
@@ -4601,7 +4606,8 @@ class MetadataFeature:
4601
4606
  "identification": self.identification.get_definition() if self.identification else None,
4602
4607
  "ownedFeatureTyping": self.typing.get_definition() if self.typing else None,
4603
4608
  "ownedRelationship_about": [a.get_definition() for a in self.annotations],
4604
- "body": self.body
4609
+ "body": self.body,
4610
+ "bodyFeatures": list(self.bodyFeatures),
4605
4611
  }
4606
4612
  return output
4607
4613
 
File without changes
File without changes
File without changes
File without changes