sysmlpy 0.47.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.47.0 → sysmlpy-0.49.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/__init__.py +1 -1
  4. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr_visitor.py +141 -2
  5. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/classes.py +12 -6
  6. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/usage.py +142 -8
  7. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/LICENSE +0 -0
  8. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/README.md +0 -0
  9. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/__main__.py +0 -0
  10. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/README.md +0 -0
  11. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  12. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  13. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  14. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  15. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  16. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  17. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  18. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  19. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  20. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  21. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  22. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/antlr_parser.py +0 -0
  23. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/boxes_view.py +0 -0
  24. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/definition.py +0 -0
  25. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  26. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  27. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  28. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/formatting.py +0 -0
  29. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  30. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  31. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  32. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  33. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  34. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  35. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  36. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  37. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  38. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  39. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  40. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  41. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  42. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  43. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  44. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  45. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/LICENSE +0 -0
  46. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/README.md +0 -0
  47. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/__init__.py +0 -0
  48. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  49. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  50. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  51. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  52. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  53. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  54. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  55. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  56. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  57. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  58. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  59. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  60. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  61. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  62. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  63. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  64. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  65. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  66. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  67. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  68. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  69. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  70. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  71. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  72. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  73. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  74. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  75. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  76. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  77. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  78. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  79. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  80. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  81. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  82. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  83. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  84. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  85. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  86. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  87. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  88. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  89. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  90. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  91. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  92. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  93. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  94. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  95. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  96. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  97. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  98. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  99. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  100. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  101. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  102. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  103. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  104. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  105. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  106. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  107. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  108. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  109. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  110. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  111. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  112. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  113. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  114. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  115. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  116. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  117. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  118. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  119. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  120. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  121. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  122. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  123. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  124. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  125. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  126. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  127. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  128. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  129. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  130. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  131. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  132. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  133. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  134. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  135. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  136. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  137. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  138. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  139. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  140. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  141. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  142. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/navigate.py +0 -0
  143. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/plantuml.py +0 -0
  144. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/project.py +0 -0
  145. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/semantic.py +0 -0
  146. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/store.py +0 -0
  147. {sysmlpy-0.47.0 → sysmlpy-0.49.0}/src/sysmlpy/us_customary_units.txt +0 -0
  148. {sysmlpy-0.47.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.47.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.47.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.47.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
 
@@ -9802,6 +9913,16 @@ def _visit_nested_occurrence_usage(occ_elem):
9802
9913
  elif hasattr(struct_elem, 'connectionUsage') and struct_elem.connectionUsage():
9803
9914
  ctx = struct_elem.connectionUsage()
9804
9915
  return _make_nested_connection_usage_dict(ctx, None)
9916
+ elif hasattr(struct_elem, 'allocationUsage') and struct_elem.allocationUsage():
9917
+ # Phase 0: allocation usages inside a definition body.
9918
+ ctx = struct_elem.allocationUsage()
9919
+ result = _make_allocation_usage_dict(ctx, None)
9920
+ if result and result.get("name") == "PackageMember":
9921
+ # Unwrap the PackageMember -> UsageElement chain so the
9922
+ # body builder sees an OccurrenceUsageElement at the
9923
+ # expected position.
9924
+ return result.get("ownedRelatedElement")
9925
+ return result
9805
9926
  elif hasattr(struct_elem, 'portionUsage') and struct_elem.portionUsage():
9806
9927
  ctx = struct_elem.portionUsage()
9807
9928
  name, shortname = _get_usage_identification(ctx)
@@ -10021,6 +10142,24 @@ def _visit_nested_occurrence_usage(occ_elem):
10021
10142
  if result and result.get("name") == "PackageMember":
10022
10143
  return result.get("ownedRelatedElement")
10023
10144
  return result
10145
+ elif hasattr(behav_elem, 'stateUsage') and behav_elem.stateUsage():
10146
+ # Phase 0: state usages live in a BehaviorUsageElement too.
10147
+ ctx = behav_elem.stateUsage()
10148
+ result = _make_state_usage_dict(ctx, None)
10149
+ if result and result.get("name") == "PackageMember":
10150
+ inner = result.get("ownedRelatedElement", {})
10151
+ return inner
10152
+ return result
10153
+ elif hasattr(behav_elem, 'allocationUsage') and behav_elem.allocationUsage():
10154
+ # Phase 0: allocation usages inside a definition body.
10155
+ ctx = behav_elem.allocationUsage()
10156
+ result = _make_allocation_usage_dict(ctx, None)
10157
+ if result and result.get("name") == "PackageMember":
10158
+ # Unwrap the PackageMember -> UsageElement chain so the
10159
+ # body builder sees an OccurrenceUsageElement at the
10160
+ # expected position.
10161
+ return result.get("ownedRelatedElement")
10162
+ return result
10024
10163
 
10025
10164
  # print(f"DEBUG: No match found in _visit_nested_occurrence_usage")
10026
10165
  # Fall through to check structure usage elements
@@ -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
 
@@ -798,23 +798,23 @@ class Usage(Searchable):
798
798
  self.__init__()
799
799
  self.grammar = grammar
800
800
  children = []
801
-
801
+
802
802
  # Check if this is a definition or usage
803
803
  # Some definition types use 'definition' (PartDefinition, AttributeDefinition)
804
804
  # Others use 'declaration' directly (RequirementDefinition, UseCaseDefinition)
805
805
  # PartDefinition: has .definition which is a Definition object
806
806
  # Usage: has .declaration directly
807
-
807
+
808
808
  # First check if grammar has 'definition' (for definitions like PartDefinition)
809
809
  defn = getattr(grammar, 'definition', None)
810
810
  if defn:
811
811
  # This type uses 'definition' (PartDefinition, etc.)
812
812
  # Get name from definition.declaration.identification.declaredName
813
813
  u_name = defn.declaration.identification.declaredName
814
-
814
+
815
815
  # Get body from definition.body
816
816
  body = defn.body if hasattr(defn, 'body') else None
817
-
817
+
818
818
  # body is DefinitionBody with .children
819
819
  if body and hasattr(body, 'children') and body.children:
820
820
  children_list = []
@@ -847,7 +847,7 @@ class Usage(Searchable):
847
847
  u_name = None
848
848
  else:
849
849
  u_name = None
850
-
850
+
851
851
  # Extract children from usage body: grammar.usage.completion.body.body.children
852
852
  # This mirrors the PartDefinition path: grammar.definition.body.children
853
853
  try:
@@ -874,7 +874,7 @@ class Usage(Searchable):
874
874
  # This type uses 'declaration' directly (RequirementDefinition, UseCaseDefinition, some usages)
875
875
  decl = grammar.declaration
876
876
  u_name = None
877
-
877
+
878
878
  # Check nested declaration for Usage (UsageDeclaration -> FeatureDeclaration)
879
879
  nested_decl = getattr(decl, 'declaration', None)
880
880
  if nested_decl and hasattr(nested_decl, 'identification') and nested_decl.identification:
@@ -922,10 +922,10 @@ class Usage(Searchable):
922
922
  sc = child.children if hasattr(child, 'children') else child
923
923
  else:
924
924
  continue
925
-
925
+
926
926
  # Process the child
927
927
  class_name = sc.__class__.__name__ if not hasattr(sc, '__class__') else sc.__class__.__name__
928
-
928
+
929
929
  if class_name == "PartDefinition":
930
930
  c = Part(definition=True).load_from_grammar(sc)
931
931
  c.parent = self
@@ -977,10 +977,37 @@ class Usage(Searchable):
977
977
  c = Flow().load_from_grammar(inner)
978
978
  c.parent = self
979
979
  self.children.append(c)
980
+ elif inner.__class__.__name__ == "AllocationUsage":
981
+ # Phase 0: allocation usages inside a definition
982
+ # body live in StructureUsageElement -> AllocationUsage.
983
+ a = Allocation()
984
+ a.grammar = inner
985
+ a.parent = self
986
+ self.children.append(a)
980
987
  elif inner.__class__.__name__ == "PortionUsage":
981
988
  c = Part().load_from_grammar(inner)
982
989
  c.parent = self
983
990
  self.children.append(c)
991
+ elif class_name == "BehaviorUsageElement":
992
+ # Phase 0 of docs/v0.46.0_expression_capture_plan.md:
993
+ # assert / constraint / calc / state / action / requirement /
994
+ # satisfy / allocation usages live inside a BehaviorUsageElement
995
+ # when they appear in a definition body. The previous
996
+ # dispatch dropped the entire BehaviorUsageElement.
997
+ if hasattr(sc, 'children'):
998
+ inner = sc.children
999
+ inner_name = inner.__class__.__name__
1000
+ c = _load_behavior_child(self, inner, inner_name)
1001
+ if c is not None:
1002
+ c.parent = self
1003
+ self.children.append(c)
1004
+ elif class_name == "InterfaceUsage":
1005
+ # Same phase 0: interface usages are wrapped as
1006
+ # OccurrenceUsageElement -> InterfaceUsage directly (not
1007
+ # through StructureUsageElement).
1008
+ c = Interface().load_from_grammar(sc)
1009
+ c.parent = self
1010
+ self.children.append(c)
984
1011
  elif class_name == "StructureDefinitionElement":
985
1012
  if hasattr(sc, 'children'):
986
1013
  inner = sc.children
@@ -1039,6 +1066,113 @@ class Usage(Searchable):
1039
1066
  # raise AttributeError("Invalid Feature Name or Chain")
1040
1067
 
1041
1068
 
1069
+ def _load_behavior_child(parent, inner, inner_name):
1070
+ """Construct a public-API element for a usage that lives inside a
1071
+ ``BehaviorUsageElement`` when it appears in a definition body.
1072
+
1073
+ Phase 0 of docs/v0.46.0_expression_capture_plan.md: this helper
1074
+ closes the gap that caused ``assert constraint``, ``constraint``,
1075
+ ``calc``, ``state``, ``action``, ``requirement``, ``satisfy``, and
1076
+ ``allocate`` usages to be silently dropped when they appeared inside
1077
+ a ``part def``, ``item def``, etc. body.
1078
+
1079
+ Parameters
1080
+ ----------
1081
+ parent : Usage
1082
+ The Part / Item / / etc. that owns the new child (for ``.parent``).
1083
+ inner : object
1084
+ The inner grammar element (e.g. ``AssertConstraintUsage``,
1085
+ ``ConstraintUsage``, ``CalculationUsage`` ...). Used for
1086
+ ``.grammar`` so the existing round-trip machinery keeps working.
1087
+ inner_name : str
1088
+ Class name of ``inner`` — selects which public-API class to
1089
+ instantiate.
1090
+
1091
+ Returns
1092
+ -------
1093
+ Usage or None
1094
+ A fresh public-API element (e.g. ``Constraint``, ``Calculation``,
1095
+ ``State``, ``Action``, ``Requirement``, ``Allocation``) with
1096
+ ``.grammar`` wired up and ``.parent`` set. Returns ``None`` if
1097
+ the inner kind is unknown to this helper — the caller treats that
1098
+ as a no-op.
1099
+ """
1100
+ def _name_from_declaration(elem):
1101
+ """Extract a human-readable name from an element's declaration,
1102
+ mirroring the pattern at definition.py:1269-1290."""
1103
+ if not hasattr(elem, "declaration") or elem.declaration is None:
1104
+ return None
1105
+ decl = elem.declaration
1106
+ # AssertConstraintUsage has a different layout: declaration may
1107
+ # be wrapped under .usageDeclaration.
1108
+ if hasattr(decl, "usageDeclaration") and decl.usageDeclaration():
1109
+ inner_decl = decl.usageDeclaration()
1110
+ if hasattr(inner_decl, "identification") and inner_decl.identification:
1111
+ ident = inner_decl.identification
1112
+ if hasattr(ident, "declaredName"):
1113
+ return ident.declaredName
1114
+ if hasattr(ident, "name"):
1115
+ name_obj = ident.name()
1116
+ if name_obj:
1117
+ if isinstance(name_obj, list):
1118
+ return name_obj[-1].getText()
1119
+ return name_obj.getText()
1120
+ if hasattr(decl, "declaration") and decl.declaration:
1121
+ feat_decl = decl.declaration
1122
+ if hasattr(feat_decl, "identification") and feat_decl.identification:
1123
+ ident = feat_decl.identification
1124
+ if hasattr(ident, "declaredName"):
1125
+ return ident.declaredName
1126
+ if hasattr(ident, "name"):
1127
+ name_obj = ident.name()
1128
+ if name_obj:
1129
+ if isinstance(name_obj, list):
1130
+ return name_obj[-1].getText()
1131
+ return name_obj.getText()
1132
+ return None
1133
+
1134
+ if inner_name == "AssertConstraintUsage":
1135
+ c = Constraint()
1136
+ c.grammar = inner
1137
+ c.name = _name_from_declaration(inner)
1138
+ return c
1139
+ if inner_name == "ConstraintUsage":
1140
+ c = Constraint()
1141
+ c.grammar = inner
1142
+ c.name = _name_from_declaration(inner)
1143
+ return c
1144
+ if inner_name == "CalculationUsage":
1145
+ c = Calculation()
1146
+ c.grammar = inner
1147
+ c.name = _name_from_declaration(inner)
1148
+ return c
1149
+ if inner_name == "StateUsage":
1150
+ c = State()
1151
+ c.grammar = inner
1152
+ c.name = _name_from_declaration(inner)
1153
+ return c
1154
+ if inner_name == "ActionUsage":
1155
+ c = Action(grammar=inner).load_from_grammar(inner)
1156
+ return c
1157
+ if inner_name == "RequirementUsage":
1158
+ c = Requirement()
1159
+ c.grammar = inner
1160
+ c.name = _name_from_declaration(inner)
1161
+ return c
1162
+ if inner_name == "SatisfyRequirementUsage":
1163
+ c = Requirement()
1164
+ c.grammar = inner
1165
+ c.name = _name_from_declaration(inner)
1166
+ return c
1167
+ if inner_name == "AllocationUsage":
1168
+ c = Allocation()
1169
+ c.grammar = inner
1170
+ c.name = _name_from_declaration(inner)
1171
+ return c
1172
+ return None
1173
+
1174
+
1175
+
1042
1176
  class Attribute(Usage):
1043
1177
  """SysML v2 Attribute usage/definition.
1044
1178
 
File without changes
File without changes
File without changes