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.
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/PKG-INFO +1 -1
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/pyproject.toml +1 -1
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/__init__.py +11 -1
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/__main__.py +170 -1
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr_visitor.py +242 -12
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/definition.py +24 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/classes.py +85 -1
- sysmlpy-0.63.0/src/sysmlpy/interchange.py +294 -0
- sysmlpy-0.63.0/src/sysmlpy/traceability.py +441 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/usage.py +85 -1
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/LICENSE +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/README.md +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/README.md +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/antlr_parser.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/boxes_view.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/attribute_values.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/part_attributes.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/formatting.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/LICENSE +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/README.md +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/__init__.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/States.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/navigate.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/plantuml.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/project.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/semantic.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/store.py +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/us_customary_units.txt +0 -0
- {sysmlpy-0.61.0 → sysmlpy-0.63.0}/src/sysmlpy/validator.py +0 -0
|
@@ -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.
|
|
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
|
-
#
|
|
7854
|
-
|
|
7855
|
-
if hasattr(ctx, "
|
|
7856
|
-
|
|
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
|
-
#
|
|
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
|