sysmlpy 0.61.0__tar.gz → 0.63.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 (150) hide show
  1. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/PKG-INFO +1 -1
  2. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/pyproject.toml +1 -1
  3. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/__init__.py +11 -1
  4. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/__main__.py +170 -1
  5. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr_visitor.py +242 -12
  6. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/definition.py +24 -0
  7. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/classes.py +85 -1
  8. sysmlpy-0.63.0/src/sysmlpy/interchange.py +294 -0
  9. sysmlpy-0.63.0/src/sysmlpy/traceability.py +441 -0
  10. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/usage.py +85 -1
  11. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/LICENSE +0 -0
  12. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/README.md +0 -0
  13. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/README.md +0 -0
  14. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
  15. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
  16. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
  17. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
  18. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
  19. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
  20. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
  21. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
  22. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  23. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  24. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  25. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr_parser.py +0 -0
  26. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/boxes_view.py +0 -0
  27. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/attribute_values.py +0 -0
  28. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/part_attributes.py +0 -0
  29. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
  30. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/formatting.py +0 -0
  31. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
  32. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
  33. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
  34. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
  35. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
  36. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
  37. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
  38. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
  39. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
  40. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
  41. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
  42. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
  43. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
  44. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
  45. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
  46. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
  47. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/LICENSE +0 -0
  48. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/README.md +0 -0
  49. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/__init__.py +0 -0
  50. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
  51. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
  52. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
  53. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
  54. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
  55. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
  56. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
  57. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
  58. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
  59. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
  60. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
  61. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
  62. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
  63. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
  64. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
  65. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
  66. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
  67. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
  68. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
  69. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
  70. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
  71. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
  72. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
  73. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
  74. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
  75. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
  76. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
  77. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
  78. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
  79. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
  80. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
  81. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
  82. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
  83. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
  84. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
  85. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
  86. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
  87. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
  88. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
  89. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
  90. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
  91. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
  92. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
  93. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
  94. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
  95. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
  96. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
  97. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
  98. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
  99. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
  100. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
  101. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
  102. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
  103. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
  104. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
  105. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
  106. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
  107. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
  108. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
  109. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
  110. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
  111. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
  112. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
  113. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
  114. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
  115. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
  116. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
  117. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
  118. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
  119. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
  120. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
  121. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
  122. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
  123. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
  124. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
  125. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
  126. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
  127. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
  128. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
  129. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
  130. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
  131. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
  132. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
  133. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
  134. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
  135. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
  136. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
  137. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
  138. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
  139. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/States.sysml +0 -0
  140. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
  141. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
  142. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
  143. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
  144. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/navigate.py +0 -0
  145. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/plantuml.py +0 -0
  146. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/project.py +0 -0
  147. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/semantic.py +0 -0
  148. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/store.py +0 -0
  149. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/us_customary_units.txt +0 -0
  150. {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysmlpy
3
- Version: 0.61.0
3
+ Version: 0.63.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.61.0"
9
+ version = "0.63.0"
10
10
  description = ""
11
11
  authors = [{ name = "Jon R. Fox (mycr0ft)", email = "jon.fox@drfox.com" }]
12
12
  readme = "README.md"
@@ -16,7 +16,10 @@ __all__ = [
16
16
  "as_action_flow_view", "as_interconnection_view", "as_state_transition_view",
17
17
  "as_general_view", "as_package_view",
18
18
  "as_tabular_view", "as_data_value_tabular_view", "as_relationship_matrix_view",
19
+ "as_traceability_matrix_view",
19
20
  "as_sequence_view", "as_case_view", "as_browser_view",
21
+ "extract_traceability", "TraceabilityReport", "RequirementTrace",
22
+ "to_interchange", "from_interchange", "interchange_to_json_text",
20
23
  "analyze", "AnalysisResult", "SemanticIssue", "SemanticAnalyzer",
21
24
  "SysMLSyntaxError", "PartialParseError",
22
25
  "loads_partial", "load_partial",
@@ -25,7 +28,7 @@ __all__ = [
25
28
  "render_state_transition_view_svg", "boxes_view",
26
29
  ]
27
30
  __author__ = "Jon Fox"
28
- __version__ = "0.61.0"
31
+ __version__ = "0.63.0"
29
32
 
30
33
  from sysmlpy.usage import (
31
34
  Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
@@ -41,6 +44,13 @@ from sysmlpy.store import Store, InMemoryStore, NetworkXStore, KuzuStore, Cayley
41
44
 
42
45
  from sysmlpy.usage import ureg
43
46
  from sysmlpy.antlr_parser import SysMLSyntaxError
47
+ from sysmlpy.traceability import (
48
+ extract_traceability, TraceabilityReport, RequirementTrace,
49
+ as_traceability_matrix_view,
50
+ )
51
+ from sysmlpy.interchange import (
52
+ to_interchange, from_interchange, interchange_to_json_text,
53
+ )
44
54
 
45
55
 
46
56
  class PartialParseError(Exception):
@@ -31,7 +31,7 @@ import sysmlpy
31
31
  from sysmlpy import loads
32
32
 
33
33
  # Subcommand table, also used to detect the legacy flat invocation form.
34
- SUBCOMMANDS = ("parse", "analyze", "view", "format", "fmt")
34
+ SUBCOMMANDS = ("parse", "analyze", "view", "trace", "export", "import", "format", "fmt")
35
35
 
36
36
 
37
37
  # ---------------------------------------------------------------------------
@@ -277,6 +277,111 @@ def cmd_format(args) -> int:
277
277
  return exit_code
278
278
 
279
279
 
280
+ def cmd_trace(args) -> int:
281
+ """Requirement traceability & verification coverage (v0.62.0, Goal 2)."""
282
+ from sysmlpy.traceability import extract_traceability
283
+
284
+ paths = [Path(f) for f in args.files]
285
+ for p in _missing_files(paths):
286
+ print(f"Error: File '{p}' not found.", file=sys.stderr)
287
+ return 2
288
+
289
+ try:
290
+ model = sysmlpy.load_files(paths, library=args.library)
291
+ except Exception as e:
292
+ print(f"Parse error: {e}", file=sys.stderr)
293
+ return 2
294
+
295
+ report = extract_traceability(model)
296
+
297
+ if args.format == "json":
298
+ output = json.dumps(report.to_json(), indent=2)
299
+ elif args.format == "markdown":
300
+ output = report.to_markdown()
301
+ else:
302
+ output = report.to_text()
303
+
304
+ if args.output:
305
+ Path(args.output).write_text(output + "\n", encoding="utf-8")
306
+ print(f"Wrote {args.output}")
307
+ else:
308
+ print(output)
309
+
310
+ if args.fail_on == "uncovered" and report.uncovered():
311
+ for trace in report.uncovered():
312
+ print(
313
+ f"uncovered: {trace.qualified_name or trace.name}",
314
+ file=sys.stderr,
315
+ )
316
+ return 1
317
+ return 0
318
+
319
+
320
+ def cmd_export(args) -> int:
321
+ """SysML text → JSON interchange document (v0.63.0, Goal 3)."""
322
+ from sysmlpy.interchange import to_interchange, interchange_to_json_text
323
+
324
+ paths = [Path(f) for f in args.files]
325
+ for p in _missing_files(paths):
326
+ print(f"Error: File '{p}' not found.", file=sys.stderr)
327
+ return 2
328
+
329
+ try:
330
+ model = sysmlpy.load_files(paths, library=args.library)
331
+ except Exception as e:
332
+ print(f"Parse error: {e}", file=sys.stderr)
333
+ return 2
334
+
335
+ try:
336
+ document = to_interchange(model)
337
+ except Exception as e:
338
+ print(f"Error: export failed on this model: {e}", file=sys.stderr)
339
+ return 1
340
+
341
+ output = interchange_to_json_text(document, indent=None if args.compact else 2)
342
+ if args.output:
343
+ Path(args.output).write_text(output + "\n", encoding="utf-8")
344
+ print(f"Wrote {args.output}")
345
+ else:
346
+ print(output)
347
+ return 0
348
+
349
+
350
+ def cmd_import(args) -> int:
351
+ """JSON interchange document → SysML text (v0.63.0, Goal 3)."""
352
+ from sysmlpy.interchange import from_interchange
353
+
354
+ path = Path(args.file)
355
+ if not path.exists():
356
+ print(f"Error: File '{path}' not found.", file=sys.stderr)
357
+ return 2
358
+
359
+ try:
360
+ content = path.read_text(encoding="utf-8")
361
+ except OSError as e:
362
+ print(f"Error reading file: {e}", file=sys.stderr)
363
+ return 2
364
+
365
+ try:
366
+ model = from_interchange(content)
367
+ except ValueError as e:
368
+ print(f"Error: invalid interchange document: {e}", file=sys.stderr)
369
+ return 2
370
+ except json.JSONDecodeError as e:
371
+ print(f"Error: not valid JSON: {e}", file=sys.stderr)
372
+ return 2
373
+
374
+ output = model.dump()
375
+ if args.output:
376
+ if not output.endswith("\n"):
377
+ output += "\n"
378
+ Path(args.output).write_text(output, encoding="utf-8")
379
+ print(f"Wrote {args.output}")
380
+ else:
381
+ print(output)
382
+ return 0
383
+
384
+
280
385
  # ---------------------------------------------------------------------------
281
386
  # legacy flat invocation (kept for backward compatibility)
282
387
  # ---------------------------------------------------------------------------
@@ -474,6 +579,70 @@ def build_parser() -> argparse.ArgumentParser:
474
579
  )
475
580
  p_format.set_defaults(func=cmd_format)
476
581
 
582
+ p_trace = sub.add_parser(
583
+ "trace",
584
+ help="Requirement traceability \u0026 verification coverage report",
585
+ description="Load the files as one merged model, extract satisfy "
586
+ "and verify relationships, and report requirement "
587
+ "coverage. Exit codes: 0 clean, 1 uncovered "
588
+ "requirements (--fail-on uncovered), 2 parse error.",
589
+ )
590
+ p_trace.add_argument("files", nargs="+", help="SysML v2 file(s)")
591
+ p_trace.add_argument(
592
+ "--format", choices=("text", "markdown", "json"), default="text",
593
+ help="Report format (default: text)",
594
+ )
595
+ p_trace.add_argument(
596
+ "--fail-on", choices=("uncovered", "none"), default="none",
597
+ help="Exit 1 when uncovered requirements exist (default: none)",
598
+ )
599
+ p_trace.add_argument(
600
+ "-o", "--output",
601
+ help="Write the report to a file instead of stdout",
602
+ )
603
+ p_trace.add_argument(
604
+ "-l", "--library",
605
+ help="Path to SysML v2 library files to use for parsing",
606
+ )
607
+ p_trace.set_defaults(func=cmd_trace)
608
+
609
+ p_export = sub.add_parser(
610
+ "export",
611
+ help="Export SysML to the JSON interchange format",
612
+ description="Load the files as one merged model and emit a "
613
+ "JSON-LD-style partition interchange document "
614
+ "(flat @graph of elements with @id/@type). Exit 2 "
615
+ "on parse failure.",
616
+ )
617
+ p_export.add_argument("files", nargs="+", help="SysML v2 file(s)")
618
+ p_export.add_argument(
619
+ "-o", "--output",
620
+ help="Write the JSON document to a file instead of stdout",
621
+ )
622
+ p_export.add_argument(
623
+ "--compact", action="store_true",
624
+ help="Emit compact JSON (no indentation)",
625
+ )
626
+ p_export.add_argument(
627
+ "-l", "--library",
628
+ help="Path to SysML v2 library files to use for parsing",
629
+ )
630
+ p_export.set_defaults(func=cmd_export)
631
+
632
+ p_import = sub.add_parser(
633
+ "import",
634
+ help="Import a JSON interchange document as SysML text",
635
+ description="Rebuild a model from a JSON interchange document "
636
+ "(sysmlpy export format) and print or write the "
637
+ "equivalent SysML v2 text. Exit 2 on invalid input.",
638
+ )
639
+ p_import.add_argument("file", help="Interchange JSON file")
640
+ p_import.add_argument(
641
+ "-o", "--output",
642
+ help="Write the SysML text to a file instead of stdout",
643
+ )
644
+ p_import.set_defaults(func=cmd_import)
645
+
477
646
  return parser
478
647
 
479
648
 
@@ -2311,6 +2311,8 @@ def _visit_behavior_usage_member(bum_ctx):
2311
2311
  return _make_assert_constraint_usage_dict(bue.assertConstraintUsage(), prefix)
2312
2312
  elif hasattr(bue, 'satisfyRequirementUsage') and bue.satisfyRequirementUsage():
2313
2313
  return _make_satisfy_requirement_usage_dict(bue.satisfyRequirementUsage(), prefix)
2314
+ elif hasattr(bue, 'verificationCaseUsage') and bue.verificationCaseUsage():
2315
+ return _make_nested_verification_case_usage_dict(bue.verificationCaseUsage(), prefix)
2314
2316
 
2315
2317
  return None
2316
2318
 
@@ -7850,12 +7852,10 @@ def _make_verification_case_definition_dict(ctx, member_prefix=None):
7850
7852
  """
7851
7853
  name, shortname = _get_definition_identification(ctx)
7852
7854
  occ_prefix = _get_occurrence_definition_prefix(ctx)
7853
- # Get body items from definition body
7854
- body_items = []
7855
- if hasattr(ctx, "definition") and ctx.definition():
7856
- defn = ctx.definition()
7857
- if hasattr(defn, "definitionBody") and defn.definitionBody():
7858
- body_items = _visit_definition_body_dict(defn.definitionBody())
7855
+ # Parse caseBody (subject members, action bodies, etc.) — v0.62.0
7856
+ case_body = {"name": "CaseBody", "item": [], "ownedRelationship": None}
7857
+ if hasattr(ctx, "caseBody") and ctx.caseBody():
7858
+ case_body = _visit_case_body_dict(ctx.caseBody())
7859
7859
  if not name and not shortname:
7860
7860
  name = "VerificationCase_" + str(uuid.uuid4())[:8]
7861
7861
  return {
@@ -7875,11 +7875,7 @@ def _make_verification_case_definition_dict(ctx, member_prefix=None):
7875
7875
  },
7876
7876
  "subclassificationpart": _get_subclassification_part(ctx)
7877
7877
  },
7878
- "body": {
7879
- "name": "CaseBody",
7880
- "item": [],
7881
- "ownedRelationship": None
7882
- }
7878
+ "body": case_body
7883
7879
  }
7884
7880
  }
7885
7881
  }
@@ -9258,11 +9254,140 @@ def _visit_requirement_body_item_dict(item_ctx):
9258
9254
  # Check for actorMember (skip for now)
9259
9255
  # Check for stakeholderMember (skip for now)
9260
9256
  # Check for framedConcernMember (skip for now)
9261
- # Check for requirementVerificationMember (skip for now)
9257
+ # requirementVerificationMember (v0.62.0: requirement traceability)
9258
+ if hasattr(item_ctx, 'requirementVerificationMember') and item_ctx.requirementVerificationMember():
9259
+ rvm = item_ctx.requirementVerificationMember()
9260
+ if isinstance(rvm, list):
9261
+ rvm = rvm[0]
9262
+ verify_dict = _visit_requirement_verification_member_dict(rvm)
9263
+ if verify_dict:
9264
+ return {
9265
+ "name": "RequirementBodyItem",
9266
+ "ownedRelationship": verify_dict
9267
+ }
9262
9268
 
9263
9269
  return None
9264
9270
 
9265
9271
 
9272
+ def _visit_requirement_verification_member_dict(rvm_ctx):
9273
+ """Visit a requirementVerificationMember and return its member dict.
9274
+
9275
+ Grammar:
9276
+ requirementVerificationMember : memberPrefix VERIFY requirementVerificationUsage ;
9277
+ """
9278
+ if rvm_ctx is None:
9279
+ return None
9280
+
9281
+ prefix = None
9282
+ if hasattr(rvm_ctx, 'memberPrefix') and rvm_ctx.memberPrefix():
9283
+ mp = rvm_ctx.memberPrefix()
9284
+ if hasattr(mp, 'visibilityIndicator') and mp.visibilityIndicator():
9285
+ prefix = {
9286
+ "name": "MemberPrefix",
9287
+ "visibility": _visit_visibility_indicator_dict(mp.visibilityIndicator())
9288
+ }
9289
+
9290
+ vru = None
9291
+ if hasattr(rvm_ctx, 'requirementVerificationUsage') and rvm_ctx.requirementVerificationUsage():
9292
+ vru = rvm_ctx.requirementVerificationUsage()
9293
+ if isinstance(vru, list):
9294
+ vru = vru[0]
9295
+ usage = _make_verify_requirement_usage_dict(vru)
9296
+ if usage:
9297
+ return {
9298
+ "name": "RequirementVerificationMember",
9299
+ "prefix": prefix,
9300
+ "ownedRelatedElement": usage
9301
+ }
9302
+ return None
9303
+
9304
+
9305
+ def _make_verify_requirement_usage_dict(vru_ctx, prefix=None):
9306
+ """Create a VerifyRequirementUsage dictionary.
9307
+
9308
+ Grammar:
9309
+ requirementVerificationUsage
9310
+ : ownedReferenceSubsetting featureSpecialization* requirementBody
9311
+ | ( usageExtensionKeyword* REQUIREMENT | usageExtensionKeyword+ )
9312
+ constraintUsageDeclaration requirementBody
9313
+ ;
9314
+
9315
+ ``verify <ref>;`` references an existing verification case; the
9316
+ requirement-keyword form declares an inline verification usage.
9317
+ """
9318
+ if vru_ctx is None:
9319
+ return None
9320
+
9321
+ ors = None
9322
+ fsp = None
9323
+ declaration = None
9324
+
9325
+ if hasattr(vru_ctx, 'ownedReferenceSubsetting') and vru_ctx.ownedReferenceSubsetting():
9326
+ ors = _build_owned_reference_subsetting_dict(vru_ctx.ownedReferenceSubsetting())
9327
+ if hasattr(vru_ctx, 'featureSpecialization') and vru_ctx.featureSpecialization():
9328
+ fs_list = vru_ctx.featureSpecialization()
9329
+ if not isinstance(fs_list, list):
9330
+ fs_list = [fs_list]
9331
+ specs = []
9332
+ for fs_ctx in fs_list:
9333
+ spec = _build_full_specialization_from_fsp(fs_ctx)
9334
+ if spec is not None:
9335
+ specs.append(spec)
9336
+ if specs:
9337
+ fsp = specs
9338
+ elif hasattr(vru_ctx, 'constraintUsageDeclaration') and vru_ctx.constraintUsageDeclaration():
9339
+ cud = vru_ctx.constraintUsageDeclaration()
9340
+ name = None
9341
+ shortname = None
9342
+ if hasattr(cud, 'usageDeclaration') and cud.usageDeclaration():
9343
+ ud = cud.usageDeclaration()
9344
+ if hasattr(ud, 'identification') and ud.identification():
9345
+ ident = ud.identification()
9346
+ if hasattr(ident, 'name'):
9347
+ name_list = ident.name()
9348
+ if name_list and isinstance(name_list, list):
9349
+ if len(name_list) == 2:
9350
+ shortname = name_list[0].getText()
9351
+ name = name_list[1].getText()
9352
+ elif len(name_list) == 1:
9353
+ name_text = name_list[0].getText()
9354
+ name, shortname = _extract_name_shortname(name_text)
9355
+
9356
+ typed_by = _get_action_usage_typed_by(cud)
9357
+ if typed_by is None:
9358
+ typed_by = _get_action_usage_subsetted_by(cud)
9359
+
9360
+ specialization = _build_specialization(typed_by) if typed_by else None
9361
+ declaration = {
9362
+ "name": "UsageDeclaration",
9363
+ "declaration": {
9364
+ "name": "FeatureDeclaration",
9365
+ "identification": {
9366
+ "name": "Identification",
9367
+ "declaredShortName": shortname,
9368
+ "declaredName": name
9369
+ },
9370
+ "specialization": specialization
9371
+ }
9372
+ }
9373
+
9374
+ body_items = []
9375
+ if hasattr(vru_ctx, 'requirementBody') and vru_ctx.requirementBody():
9376
+ body_items = _visit_requirement_body_dict(vru_ctx.requirementBody())
9377
+
9378
+ return {
9379
+ "name": "VerifyRequirementUsage",
9380
+ "prefix": prefix,
9381
+ "ors": ors,
9382
+ "fsp": fsp,
9383
+ "declaration": declaration,
9384
+ "body": {
9385
+ "name": "RequirementBody",
9386
+ "item": body_items
9387
+ }
9388
+ }
9389
+
9390
+
9266
9391
  def _visit_subject_member_dict(sm_ctx):
9267
9392
  """Visit a subjectMember and return a SubjectMember dict.
9268
9393
 
@@ -10150,6 +10275,9 @@ def _visit_nested_occurrence_usage(occ_elem):
10150
10275
  }
10151
10276
  }
10152
10277
  return None
10278
+ elif hasattr(behav_elem, 'verificationCaseUsage') and behav_elem.verificationCaseUsage():
10279
+ ctx = behav_elem.verificationCaseUsage()
10280
+ return _make_nested_verification_case_usage_dict(ctx, None)
10153
10281
  elif hasattr(behav_elem, 'analysisCaseUsage') and behav_elem.analysisCaseUsage():
10154
10282
  ctx = behav_elem.analysisCaseUsage()
10155
10283
  return _make_nested_analysis_case_usage_dict(ctx, None)
@@ -13009,6 +13137,16 @@ def _visit_usage_element_dict(usage_elem_ctx, prefix=None):
13009
13137
  }
13010
13138
  }
13011
13139
  return result
13140
+ elif hasattr(behav_elem, 'verificationCaseUsage') and behav_elem.verificationCaseUsage():
13141
+ ctx = behav_elem.verificationCaseUsage()
13142
+ inner = _make_nested_verification_case_usage_dict(ctx, prefix)
13143
+ if inner:
13144
+ return {
13145
+ "name": "PackageMember",
13146
+ "prefix": None,
13147
+ "ownedRelatedElement": inner
13148
+ }
13149
+ return None
13012
13150
  elif hasattr(behav_elem, 'viewpointUsage') and behav_elem.viewpointUsage():
13013
13151
  ctx = behav_elem.viewpointUsage()
13014
13152
  return _make_viewpoint_usage_dict(ctx, prefix)
@@ -13018,6 +13156,9 @@ def _visit_usage_element_dict(usage_elem_ctx, prefix=None):
13018
13156
  elif hasattr(behav_elem, 'analysisCaseUsage') and behav_elem.analysisCaseUsage():
13019
13157
  ctx = behav_elem.analysisCaseUsage()
13020
13158
  return _make_nested_analysis_case_usage_dict(ctx, prefix)
13159
+ elif hasattr(behav_elem, 'verificationCaseUsage') and behav_elem.verificationCaseUsage():
13160
+ ctx = behav_elem.verificationCaseUsage()
13161
+ return _make_nested_verification_case_usage_dict(ctx, prefix)
13021
13162
  elif hasattr(behav_elem, 'caseUsage') and behav_elem.caseUsage():
13022
13163
  ctx = behav_elem.caseUsage()
13023
13164
  return _make_nested_case_usage_dict(ctx, prefix)
@@ -14159,6 +14300,95 @@ def _build_full_specialization_from_fsp(fsp):
14159
14300
  }
14160
14301
 
14161
14302
 
14303
+ def _make_nested_verification_case_usage_dict(ctx, prefix=None):
14304
+ """Create a VerificationCaseUsage dict for nested usage (v0.62.0).
14305
+
14306
+ Grammar:
14307
+ verificationCaseUsage : occurrenceUsagePrefix VERIFICATION
14308
+ constraintUsageDeclaration caseBody ;
14309
+
14310
+ Mirrors _make_nested_analysis_case_usage_dict; the emitted
14311
+ BehaviorUsageElement/VerificationCaseUsage pair is dispatched to the
14312
+ existing VerificationCaseUsage grammar class.
14313
+ """
14314
+ if ctx is None:
14315
+ return None
14316
+
14317
+ # Extract name and specialization from constraintUsageDeclaration
14318
+ name = None
14319
+ shortname = None
14320
+ specialization = None
14321
+
14322
+ if hasattr(ctx, 'constraintUsageDeclaration') and ctx.constraintUsageDeclaration():
14323
+ cud = ctx.constraintUsageDeclaration()
14324
+ if isinstance(cud, list):
14325
+ cud = cud[0] if cud else None
14326
+ if cud is not None and hasattr(cud, 'usageDeclaration') and cud.usageDeclaration():
14327
+ ud = cud.usageDeclaration()
14328
+ if isinstance(ud, list):
14329
+ ud = ud[0] if ud else None
14330
+ if ud is not None and hasattr(ud, 'identification') and ud.identification():
14331
+ ident = ud.identification()
14332
+ if isinstance(ident, list):
14333
+ ident = ident[0] if ident else None
14334
+ if ident is not None and hasattr(ident, 'name'):
14335
+ name_list = ident.name()
14336
+ if name_list and isinstance(name_list, list):
14337
+ if len(name_list) == 2:
14338
+ shortname = name_list[0].getText()
14339
+ name = name_list[1].getText()
14340
+ elif len(name_list) == 1:
14341
+ name_text = name_list[0].getText()
14342
+ name, shortname = _extract_name_shortname(name_text)
14343
+
14344
+ # Extract specialization (typing) from constraintUsageDeclaration
14345
+ typed_by = _get_action_usage_typed_by(cud)
14346
+ if typed_by:
14347
+ specialization = _build_specialization(typed_by)
14348
+
14349
+ occ_prefix = _get_occurrence_usage_prefix(ctx) if ctx else None
14350
+
14351
+ # Get body items from caseBody
14352
+ body_items = []
14353
+ if hasattr(ctx, 'caseBody') and ctx.caseBody():
14354
+ cb = ctx.caseBody()
14355
+ body_items = _visit_case_body_items(cb)
14356
+
14357
+ return {
14358
+ "name": "UsageElement",
14359
+ "ownedRelatedElement": {
14360
+ "name": "OccurrenceUsageElement",
14361
+ "ownedRelatedElement": {
14362
+ "name": "BehaviorUsageElement",
14363
+ "ownedRelationship": {
14364
+ "name": "VerificationCaseUsage",
14365
+ "prefix": occ_prefix or prefix,
14366
+ "declaration": {
14367
+ "name": "CalculationUsageDeclaration",
14368
+ "declaration": {
14369
+ "name": "UsageDeclaration",
14370
+ "declaration": {
14371
+ "name": "FeatureDeclaration",
14372
+ "identification": {
14373
+ "name": "Identification",
14374
+ "declaredShortName": shortname,
14375
+ "declaredName": name
14376
+ },
14377
+ "specialization": specialization
14378
+ }
14379
+ },
14380
+ "valuepart": None
14381
+ },
14382
+ "body": {
14383
+ "name": "CaseBody",
14384
+ "item": body_items
14385
+ }
14386
+ }
14387
+ }
14388
+ }
14389
+ }
14390
+
14391
+
14162
14392
  def _make_nested_analysis_case_usage_dict(ctx, prefix=None):
14163
14393
  """Create an AnalysisCaseUsage dict for nested usage."""
14164
14394
  if ctx is None:
@@ -93,7 +93,15 @@ class Model(Searchable):
93
93
  raise ValueError("Base Model must be encapsulated by a package.")
94
94
 
95
95
  definition = load_grammar_antlr(s, library=library)["ownedRelationship"]
96
+ return self._load_definition(definition)
96
97
 
98
+ def _load_definition(self: type[ModelType], definition) -> ModelType:
99
+ """Build the model from a parsed definition-dict member list.
100
+
101
+ Shared by :meth:`load` (fresh parse) and the JSON interchange
102
+ importer (v0.63.0 — ``from_interchange`` feeds the rebuilt dict
103
+ straight into this path).
104
+ """
97
105
  member_grammar = []
98
106
  found_package = False
99
107
  for member in definition:
@@ -1281,6 +1289,22 @@ class Package(Searchable):
1281
1289
  c.name = decl.identification.declaredName
1282
1290
  c.parent = self
1283
1291
  self.children.append(c)
1292
+ elif inner_class == "VerificationCaseUsage":
1293
+ # v0.62.0: `verification <name> : <Type>` usage at package
1294
+ # level (requirement traceability support).
1295
+ c = VerificationCase()
1296
+ c.grammar = inner_element
1297
+ if hasattr(inner_element, 'declaration') and inner_element.declaration:
1298
+ decl = inner_element.declaration
1299
+ # CalculationUsageDeclaration → UsageDeclaration →
1300
+ # FeatureDeclaration → Identification
1301
+ usage_decl = getattr(decl, 'declaration', None)
1302
+ if usage_decl := getattr(usage_decl, 'declaration', None) or usage_decl:
1303
+ feat_decl = usage_decl
1304
+ if hasattr(feat_decl, 'identification') and feat_decl.identification:
1305
+ c.name = feat_decl.identification.declaredName
1306
+ c.parent = self
1307
+ self.children.append(c)
1284
1308
  elif inner_class == "AnnotatingElement":
1285
1309
  wrapper = _GrammarAnnotationWrapper(inner_element)
1286
1310
  wrapper.parent = self