sysmlpy 0.71.0__tar.gz → 0.73.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.71.0 → sysmlpy-0.73.0}/PKG-INFO +1 -1
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/pyproject.toml +1 -1
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/__init__.py +1 -1
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/semantic.py +314 -16
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/traceability.py +73 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/usage.py +7 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/LICENSE +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/README.md +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/__main__.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/README.md +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2Parser.interp +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2Parser.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2Parser.tokens +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2ParserListener.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/SysMLv2ParserVisitor.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr_parser.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr_visitor.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/boxes_view.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/definition.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/evaluator.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/examples/attribute_values.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/examples/part_attributes.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/examples/tuples_sequences.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/formatting.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/README.md +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.interp +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/desc.xml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/examples/camera.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/examples/toaster-system.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/antlr4/pom.xml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/grammar/classes.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/interchange.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/LICENSE +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/README.md +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/__init__.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Analysis/TradeStudies.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Geometry/ShapeItems.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Geometry/SpatialItems.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Metadata/ImageMetadata.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Metadata/RiskMetadata.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQ.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/SI.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Base.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/BaseFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/BooleanFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Clocks.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/CollectionFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Collections.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/ComplexFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/ControlFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/ControlPerformances.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/DataFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/IntegerFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/KerML.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Links.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Metaobjects.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/NaturalFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/NumericalFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Objects.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Observation.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/OccurrenceFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Occurrences.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Performances.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/RationalFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/RealFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/ScalarFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/ScalarValues.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/SequenceFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/SpatialFrames.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/StatePerformances.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/StringFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Transfers.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/TransitionPerformances.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/TrigFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/Triggers.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/VectorFunctions.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/VectorValues.kerml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Actions.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Allocations.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/AnalysisCases.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Attributes.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Calculations.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Cases.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Connections.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Constraints.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Flows.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Interfaces.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Items.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Metadata.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Parts.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Ports.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Requirements.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/StandardViewDefinitions.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/States.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/SysML.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/UseCases.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/VerificationCases.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/systems/Views.sysml +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/lsp/__init__.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/lsp/__main__.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/lsp/protocol.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/lsp/server.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/lsp/stdio.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/navigate.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/plantuml.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/project.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/sim.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/spreadsheet.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/store.py +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/us_customary_units.txt +0 -0
- {sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/validator.py +0 -0
|
@@ -34,7 +34,7 @@ __all__ = [
|
|
|
34
34
|
"render_state_transition_view_svg", "boxes_view",
|
|
35
35
|
]
|
|
36
36
|
__author__ = "Jon Fox"
|
|
37
|
-
__version__ = "0.
|
|
37
|
+
__version__ = "0.73.0"
|
|
38
38
|
|
|
39
39
|
from sysmlpy.usage import (
|
|
40
40
|
Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
|
|
@@ -1236,6 +1236,26 @@ class ExpressionIdentifierCollector:
|
|
|
1236
1236
|
self._walk(child, results, child_scope)
|
|
1237
1237
|
|
|
1238
1238
|
|
|
1239
|
+
def _satisfy_by_ref(satisfy_dict: dict):
|
|
1240
|
+
"""The ``by <part>`` reference of a SatisfyRequirementUsage dict.
|
|
1241
|
+
|
|
1242
|
+
Shape: ``ssm`` = SatisfactionSubjectMember → SatisfactionParameter
|
|
1243
|
+
→ … → FeatureChainMember.memberElement (QualifiedName) whose last
|
|
1244
|
+
segment is the satisfying feature. ``ors.referencedFeature.names``
|
|
1245
|
+
carries the target requirement reference.
|
|
1246
|
+
"""
|
|
1247
|
+
ssm = satisfy_dict.get("ssm")
|
|
1248
|
+
if not isinstance(ssm, dict):
|
|
1249
|
+
return None
|
|
1250
|
+
members = _find_named_dicts(ssm, "FeatureChainMember")
|
|
1251
|
+
for m in members:
|
|
1252
|
+
me = m.get("memberElement") or {}
|
|
1253
|
+
names = me.get("names")
|
|
1254
|
+
if isinstance(names, list) and names:
|
|
1255
|
+
return "::".join(str(n) for n in names)
|
|
1256
|
+
return None
|
|
1257
|
+
|
|
1258
|
+
|
|
1239
1259
|
def _find_named_dicts(node: Any, name: str) -> list:
|
|
1240
1260
|
"""Locate every dict with ``dict["name"] == name`` in a tree."""
|
|
1241
1261
|
out: list = []
|
|
@@ -2495,6 +2515,7 @@ class SemanticAnalyzer:
|
|
|
2495
2515
|
issues.extend(self._check_requirement_coverage(model))
|
|
2496
2516
|
issues.extend(self._check_trace_targets(model, symtab, lib_roots))
|
|
2497
2517
|
issues.extend(self._check_verify_targets(model, symtab, lib_roots))
|
|
2518
|
+
issues.extend(self._check_satisfy_parts(model, symtab, lib_roots))
|
|
2498
2519
|
issues.extend(self._check_connector_directions(model))
|
|
2499
2520
|
|
|
2500
2521
|
# Step 6: Stylistic checks (warnings, not errors)
|
|
@@ -3294,6 +3315,193 @@ class SemanticAnalyzer:
|
|
|
3294
3315
|
return table.lookup(parts[-1])
|
|
3295
3316
|
return None
|
|
3296
3317
|
|
|
3318
|
+
def _check_satisfy_parts(
|
|
3319
|
+
self,
|
|
3320
|
+
model: Any,
|
|
3321
|
+
symtab: "SymbolTable",
|
|
3322
|
+
lib_roots: list,
|
|
3323
|
+
) -> list[SemanticIssue]:
|
|
3324
|
+
"""Resolve ``satisfy <req> by <part>`` subjects (Goal 9).
|
|
3325
|
+
|
|
3326
|
+
The ``by`` reference names the satisfying part; both
|
|
3327
|
+
package-level satisfies (grammar ``SatisfyRequirementUsage``
|
|
3328
|
+
wrappers yielded by ``_walk_usages``) and satisfies nested
|
|
3329
|
+
inside requirement bodies (extracted from the requirement's
|
|
3330
|
+
grammar dict — the visitor surfaces nested verify members but
|
|
3331
|
+
not satisfy members) are checked. An unresolved by-part is a
|
|
3332
|
+
UNRESOLVED_SATISFY_PART error.
|
|
3333
|
+
"""
|
|
3334
|
+
issues: list[SemanticIssue] = []
|
|
3335
|
+
|
|
3336
|
+
def issue(obj, ref):
|
|
3337
|
+
issues.append(SemanticIssue(
|
|
3338
|
+
severity="error",
|
|
3339
|
+
code="UNRESOLVED_SATISFY_PART",
|
|
3340
|
+
message=(
|
|
3341
|
+
f"satisfy 'by {ref}' does not resolve to a "
|
|
3342
|
+
"defined part"),
|
|
3343
|
+
element=obj,
|
|
3344
|
+
reference=ref,
|
|
3345
|
+
))
|
|
3346
|
+
|
|
3347
|
+
# superclassifier map for subject-type compatibility: walk
|
|
3348
|
+
# part/item definitions and collect ``:>`` targets
|
|
3349
|
+
supertypes: dict = {}
|
|
3350
|
+
for element, scope_path in self._walk_usages(model):
|
|
3351
|
+
if type(element).__name__ not in ("Part", "Item"):
|
|
3352
|
+
continue
|
|
3353
|
+
if not getattr(element, "is_definition", False):
|
|
3354
|
+
continue
|
|
3355
|
+
grammar = getattr(element, "grammar", None)
|
|
3356
|
+
if grammar is None:
|
|
3357
|
+
continue
|
|
3358
|
+
try:
|
|
3359
|
+
d = grammar.get_definition()
|
|
3360
|
+
except Exception:
|
|
3361
|
+
continue
|
|
3362
|
+
if not isinstance(d, dict):
|
|
3363
|
+
continue
|
|
3364
|
+
defn = d.get("definition") or {}
|
|
3365
|
+
decl = defn.get("declaration") or {}
|
|
3366
|
+
scp = decl.get("subclassificationpart") or {}
|
|
3367
|
+
sups = set()
|
|
3368
|
+
for rel in _as_list_dicts(scp.get("ownedRelationship")):
|
|
3369
|
+
if rel.get("name") != "OwnedSubclassification":
|
|
3370
|
+
continue
|
|
3371
|
+
sc = rel.get("superclassifier") or {}
|
|
3372
|
+
names = sc.get("names")
|
|
3373
|
+
if isinstance(names, list) and names:
|
|
3374
|
+
sups.add("::".join(str(n) for n in names))
|
|
3375
|
+
if sups and element.name:
|
|
3376
|
+
supertypes.setdefault(element.name, set()).update(sups)
|
|
3377
|
+
|
|
3378
|
+
def _is_subtype(sub: str, sup: str, seen=None) -> bool:
|
|
3379
|
+
if sub == sup:
|
|
3380
|
+
return True
|
|
3381
|
+
if seen is None:
|
|
3382
|
+
seen = set()
|
|
3383
|
+
if sub in seen:
|
|
3384
|
+
return False
|
|
3385
|
+
seen.add(sub)
|
|
3386
|
+
for st in supertypes.get(sub, ()):
|
|
3387
|
+
if _is_subtype(st, sup, seen):
|
|
3388
|
+
return True
|
|
3389
|
+
return False
|
|
3390
|
+
|
|
3391
|
+
def subject_issue(req_name, subj_type, part_name, part_type):
|
|
3392
|
+
issues.append(SemanticIssue(
|
|
3393
|
+
severity="warning",
|
|
3394
|
+
code="SATISFY_SUBJECT_TYPE_MISMATCH",
|
|
3395
|
+
message=(
|
|
3396
|
+
f"satisfy 'by {part_name}' ({part_type}) is not "
|
|
3397
|
+
f"related to requirement '{req_name}' subject "
|
|
3398
|
+
f"type '{subj_type}'"),
|
|
3399
|
+
reference=req_name,
|
|
3400
|
+
))
|
|
3401
|
+
|
|
3402
|
+
for element, scope_path in self._walk_usages(model):
|
|
3403
|
+
gname = (element.grammar.__class__.__name__
|
|
3404
|
+
if getattr(element, "grammar", None) is not None else "")
|
|
3405
|
+
if gname == "SatisfyRequirementUsage":
|
|
3406
|
+
# package-level wrapper; .ssm dump is the by reference,
|
|
3407
|
+
# .ors dump the target requirement
|
|
3408
|
+
g = element.grammar
|
|
3409
|
+
ssm = getattr(g, "ssm", None)
|
|
3410
|
+
if ssm is None:
|
|
3411
|
+
continue
|
|
3412
|
+
ref = ssm.dump().strip().rstrip(";").strip()
|
|
3413
|
+
if not ref:
|
|
3414
|
+
continue
|
|
3415
|
+
if not self._is_resolved(ref, symtab, scope_path, lib_roots):
|
|
3416
|
+
issue(element, ref)
|
|
3417
|
+
ors = getattr(g, "ors", None)
|
|
3418
|
+
target = ors.dump().strip().rstrip(";").strip() \
|
|
3419
|
+
if ors is not None else None
|
|
3420
|
+
if target:
|
|
3421
|
+
self._check_subject_type(
|
|
3422
|
+
element, target, ref, symtab, scope_path,
|
|
3423
|
+
lib_roots, supertypes, _is_subtype,
|
|
3424
|
+
subject_issue)
|
|
3425
|
+
continue
|
|
3426
|
+
if gname not in ("RequirementDefinition", "RequirementUsage"):
|
|
3427
|
+
continue
|
|
3428
|
+
# nested satisfy members: scan the requirement's grammar dict
|
|
3429
|
+
grammar = element.grammar
|
|
3430
|
+
if grammar is None:
|
|
3431
|
+
continue
|
|
3432
|
+
try:
|
|
3433
|
+
grammar_def = grammar.get_definition()
|
|
3434
|
+
except Exception:
|
|
3435
|
+
continue
|
|
3436
|
+
if not isinstance(grammar_def, dict):
|
|
3437
|
+
continue
|
|
3438
|
+
for sat in _find_named_dicts(
|
|
3439
|
+
grammar_def, "SatisfyRequirementUsage"):
|
|
3440
|
+
by_ref = _satisfy_by_ref(sat)
|
|
3441
|
+
if not by_ref:
|
|
3442
|
+
continue
|
|
3443
|
+
if not self._is_resolved(
|
|
3444
|
+
by_ref, symtab, scope_path, lib_roots):
|
|
3445
|
+
issue(element, by_ref)
|
|
3446
|
+
ors = sat.get("ors") or {}
|
|
3447
|
+
rf = ors.get("referencedFeature") or {}
|
|
3448
|
+
names = rf.get("names") if isinstance(rf, dict) else None
|
|
3449
|
+
if names:
|
|
3450
|
+
target = "::".join(str(n) for n in names)
|
|
3451
|
+
self._check_subject_type(
|
|
3452
|
+
element, target, by_ref, symtab, scope_path,
|
|
3453
|
+
lib_roots, supertypes, _is_subtype,
|
|
3454
|
+
subject_issue)
|
|
3455
|
+
return issues
|
|
3456
|
+
|
|
3457
|
+
def _check_subject_type(
|
|
3458
|
+
self,
|
|
3459
|
+
satisfy_obj: Any,
|
|
3460
|
+
target_ref: str,
|
|
3461
|
+
by_ref: str,
|
|
3462
|
+
symtab: "SymbolTable",
|
|
3463
|
+
scope_path: list[str],
|
|
3464
|
+
lib_roots: list,
|
|
3465
|
+
supertypes: dict,
|
|
3466
|
+
is_subtype,
|
|
3467
|
+
issue_fn,
|
|
3468
|
+
) -> None:
|
|
3469
|
+
"""SATISFY_SUBJECT_TYPE_MISMATCH (warning, conservative).
|
|
3470
|
+
|
|
3471
|
+
``satisfy <req> by <part>`` binds *part* as the satisfying
|
|
3472
|
+
element of *req*'s subject. When both the subject's type and
|
|
3473
|
+
the by-part's type are known model definitions and neither is
|
|
3474
|
+
a (transitive) specialization of the other, flag a warning.
|
|
3475
|
+
Anything unresolvable — library types, untyped parts,
|
|
3476
|
+
requirements without a typed subject — is skipped.
|
|
3477
|
+
"""
|
|
3478
|
+
target = self._resolve_element(target_ref, symtab, scope_path)
|
|
3479
|
+
if target is None:
|
|
3480
|
+
return
|
|
3481
|
+
subject = getattr(target, "subject", None)
|
|
3482
|
+
if not subject:
|
|
3483
|
+
return
|
|
3484
|
+
subj_type = subject[1]
|
|
3485
|
+
if not subj_type or subj_type not in supertypes and (
|
|
3486
|
+
subj_type not in getattr(symtab, "_definition_features",
|
|
3487
|
+
{})):
|
|
3488
|
+
return
|
|
3489
|
+
by_el = self._resolve_element(by_ref, symtab, scope_path)
|
|
3490
|
+
if by_el is None:
|
|
3491
|
+
return
|
|
3492
|
+
part_type = self._get_element_type(by_el)
|
|
3493
|
+
if not part_type:
|
|
3494
|
+
return
|
|
3495
|
+
# both sides must be model-known (skip library typings)
|
|
3496
|
+
if part_type not in supertypes and (
|
|
3497
|
+
part_type not in getattr(symtab, "_definition_features",
|
|
3498
|
+
{})):
|
|
3499
|
+
return
|
|
3500
|
+
if is_subtype(part_type, subj_type) or is_subtype(
|
|
3501
|
+
subj_type, part_type):
|
|
3502
|
+
return
|
|
3503
|
+
issue_fn(target_ref, subj_type, by_ref, part_type)
|
|
3504
|
+
|
|
3297
3505
|
def _check_verify_targets(
|
|
3298
3506
|
self,
|
|
3299
3507
|
model: Any,
|
|
@@ -3370,8 +3578,10 @@ class SemanticAnalyzer:
|
|
|
3370
3578
|
except Exception:
|
|
3371
3579
|
return issues
|
|
3372
3580
|
|
|
3373
|
-
scope_ports: dict = {} # def/usage name -> {port: direction}
|
|
3581
|
+
scope_ports: dict = {} # def/usage name -> {port: direction|None}
|
|
3374
3582
|
part_typing: dict = {} # part usage name -> typed-by name
|
|
3583
|
+
member_typing: dict = {} # (container name, member) -> typed-by
|
|
3584
|
+
supertypes: dict = {} # def name -> {superclassifier names}
|
|
3375
3585
|
connections: list = [] # (name, scope_stack, [chain, ...])
|
|
3376
3586
|
|
|
3377
3587
|
def walk2(node, scope_stack):
|
|
@@ -3383,11 +3593,39 @@ class SemanticAnalyzer:
|
|
|
3383
3593
|
nm.endswith("Usage") or nm.endswith("Definition")):
|
|
3384
3594
|
if nm != "PortUsage":
|
|
3385
3595
|
new_stack = scope_stack + [declared]
|
|
3596
|
+
if nm.endswith("Definition"):
|
|
3597
|
+
# superclassifiers (``part def A :> B``) ride the
|
|
3598
|
+
# definition dict's declaration.subclassificationpart
|
|
3599
|
+
sups = set()
|
|
3600
|
+
defn = node.get("definition") or {}
|
|
3601
|
+
decl = defn.get("declaration") or {}
|
|
3602
|
+
scp = decl.get("subclassificationpart") or {}
|
|
3603
|
+
for rel in _as_list_dicts(
|
|
3604
|
+
scp.get("ownedRelationship")):
|
|
3605
|
+
if rel.get("name") != "OwnedSubclassification":
|
|
3606
|
+
continue
|
|
3607
|
+
sc = rel.get("superclassifier") or {}
|
|
3608
|
+
names = sc.get("names")
|
|
3609
|
+
if isinstance(names, list) and names:
|
|
3610
|
+
sups.add("::".join(
|
|
3611
|
+
str(n) for n in names))
|
|
3612
|
+
if sups:
|
|
3613
|
+
supertypes.setdefault(declared, set()).update(
|
|
3614
|
+
sups)
|
|
3386
3615
|
if nm == "PortUsage":
|
|
3387
3616
|
d = _port_direction(node)
|
|
3388
|
-
if
|
|
3617
|
+
if scope_stack:
|
|
3618
|
+
# record even undirected ports: existence
|
|
3619
|
+
# drives end resolution, None direction
|
|
3620
|
+
# just skips the direction check
|
|
3389
3621
|
scope_ports.setdefault(
|
|
3390
3622
|
scope_stack[-1], {})[declared] = d
|
|
3623
|
+
t = _usage_typed_by(node)
|
|
3624
|
+
if t:
|
|
3625
|
+
part_typing[declared] = t
|
|
3626
|
+
if scope_stack:
|
|
3627
|
+
member_typing[(scope_stack[-1],
|
|
3628
|
+
declared)] = t
|
|
3391
3629
|
elif nm == "ConnectionUsage":
|
|
3392
3630
|
chains = []
|
|
3393
3631
|
part = node.get("part") or {}
|
|
@@ -3409,6 +3647,9 @@ class SemanticAnalyzer:
|
|
|
3409
3647
|
t = _usage_typed_by(node)
|
|
3410
3648
|
if t:
|
|
3411
3649
|
part_typing[declared] = t
|
|
3650
|
+
if scope_stack:
|
|
3651
|
+
member_typing[(scope_stack[-1],
|
|
3652
|
+
declared)] = t
|
|
3412
3653
|
for k, v in node.items():
|
|
3413
3654
|
if isinstance(v, (dict, list)):
|
|
3414
3655
|
walk2(v, new_stack)
|
|
@@ -3418,26 +3659,83 @@ class SemanticAnalyzer:
|
|
|
3418
3659
|
|
|
3419
3660
|
walk2(visit, [])
|
|
3420
3661
|
|
|
3421
|
-
def
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3662
|
+
def end_resolve(chain, scope_stack):
|
|
3663
|
+
"""(direction|None, fully_resolved) for an end chain.
|
|
3664
|
+
|
|
3665
|
+
``fully_resolved`` is False only when a segment provably
|
|
3666
|
+
does not exist in a *known, non-specializing* container —
|
|
3667
|
+
containers typed by library defs, unknown names and
|
|
3668
|
+
subclasses (inherited members) resolve as "present but
|
|
3669
|
+
direction-unknown" to stay conservative.
|
|
3670
|
+
"""
|
|
3671
|
+
if not chain:
|
|
3672
|
+
return None, True
|
|
3428
3673
|
if len(chain) == 1:
|
|
3429
3674
|
port_name = chain[0]
|
|
3430
3675
|
for scope in reversed(scope_stack):
|
|
3431
|
-
|
|
3432
|
-
|
|
3676
|
+
ports = scope_ports.get(scope)
|
|
3677
|
+
if ports is not None and port_name in ports:
|
|
3678
|
+
return ports[port_name], True
|
|
3433
3679
|
t = part_typing.get(scope)
|
|
3434
|
-
if t
|
|
3435
|
-
|
|
3436
|
-
|
|
3680
|
+
if t:
|
|
3681
|
+
ports = scope_ports.get(t)
|
|
3682
|
+
if ports is not None and port_name in ports:
|
|
3683
|
+
return ports[port_name], True
|
|
3684
|
+
if t not in supertypes and t not in scope_ports:
|
|
3685
|
+
# known library/external type: cannot
|
|
3686
|
+
# verify members
|
|
3687
|
+
return None, True
|
|
3688
|
+
return None, False
|
|
3689
|
+
first = chain[0]
|
|
3690
|
+
cur = part_typing.get(first)
|
|
3691
|
+
if cur is None:
|
|
3692
|
+
for scope in reversed(scope_stack):
|
|
3693
|
+
t = member_typing.get((scope, first))
|
|
3694
|
+
if t:
|
|
3695
|
+
cur = t
|
|
3696
|
+
break
|
|
3697
|
+
if cur is None:
|
|
3698
|
+
return None, False
|
|
3699
|
+
for seg in chain[1:-1]:
|
|
3700
|
+
t = member_typing.get((cur, seg))
|
|
3701
|
+
if t is None:
|
|
3702
|
+
# members declared on the seg0 *usage* itself
|
|
3703
|
+
t = member_typing.get((first, seg))
|
|
3704
|
+
if t is None:
|
|
3705
|
+
return None, cur in supertypes or (
|
|
3706
|
+
cur not in scope_ports
|
|
3707
|
+
and cur not in part_typing)
|
|
3708
|
+
cur = t
|
|
3709
|
+
ports = scope_ports.get(cur)
|
|
3710
|
+
if ports is not None and chain[-1] in ports:
|
|
3711
|
+
return ports[chain[-1]], True
|
|
3712
|
+
if cur in supertypes:
|
|
3713
|
+
return None, True # inherited port possible
|
|
3714
|
+
if cur in scope_ports:
|
|
3715
|
+
return None, False # known container, no such port
|
|
3716
|
+
return None, True # external/library type: skip
|
|
3437
3717
|
|
|
3438
3718
|
for cname, cstack, chains in connections:
|
|
3439
|
-
d1 =
|
|
3440
|
-
d2 =
|
|
3719
|
+
d1, r1 = end_resolve(chains[0], cstack)
|
|
3720
|
+
d2, r2 = end_resolve(chains[1], cstack)
|
|
3721
|
+
if not r1:
|
|
3722
|
+
issues.append(SemanticIssue(
|
|
3723
|
+
severity="error",
|
|
3724
|
+
code="UNRESOLVED_CONNECTOR_END",
|
|
3725
|
+
message=(
|
|
3726
|
+
f"Connection '{cname}' end "
|
|
3727
|
+
f"'{'.'.join(chains[0])}' does not resolve"),
|
|
3728
|
+
reference=cname,
|
|
3729
|
+
))
|
|
3730
|
+
if not r2:
|
|
3731
|
+
issues.append(SemanticIssue(
|
|
3732
|
+
severity="error",
|
|
3733
|
+
code="UNRESOLVED_CONNECTOR_END",
|
|
3734
|
+
message=(
|
|
3735
|
+
f"Connection '{cname}' end "
|
|
3736
|
+
f"'{'.'.join(chains[1])}' does not resolve"),
|
|
3737
|
+
reference=cname,
|
|
3738
|
+
))
|
|
3441
3739
|
if not d1 or not d2:
|
|
3442
3740
|
continue
|
|
3443
3741
|
if d1 == "inout" or d2 == "inout":
|
|
@@ -224,6 +224,59 @@ def _qualified_name(obj) -> str:
|
|
|
224
224
|
return "::".join(reversed(segments))
|
|
225
225
|
|
|
226
226
|
|
|
227
|
+
def _find_named_dicts_local(node, name: str) -> list:
|
|
228
|
+
"""Locate every dict with ``dict["name"] == name`` in a tree.
|
|
229
|
+
|
|
230
|
+
Local copy of the semantic-module helper (semantic imports this
|
|
231
|
+
module, so a shared util would be circular).
|
|
232
|
+
"""
|
|
233
|
+
out: list = []
|
|
234
|
+
|
|
235
|
+
def walk(n):
|
|
236
|
+
if isinstance(n, dict):
|
|
237
|
+
if n.get("name") == name:
|
|
238
|
+
out.append(n)
|
|
239
|
+
for v in n.values():
|
|
240
|
+
if isinstance(v, (dict, list)):
|
|
241
|
+
walk(v)
|
|
242
|
+
elif isinstance(n, list):
|
|
243
|
+
for item in n:
|
|
244
|
+
if isinstance(item, (dict, list)):
|
|
245
|
+
walk(item)
|
|
246
|
+
|
|
247
|
+
walk(node)
|
|
248
|
+
return out
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _nested_satisfy_ref(satisfy_dict: dict):
|
|
252
|
+
"""``(target, by_part)`` of a SatisfyRequirementUsage dict.
|
|
253
|
+
|
|
254
|
+
``ors.referencedFeature.names`` carries the target requirement;
|
|
255
|
+
``ssm`` (SatisfactionSubjectMember) nests
|
|
256
|
+
FeatureChainMember.memberElement (QualifiedName) whose last
|
|
257
|
+
segment is the satisfying feature.
|
|
258
|
+
"""
|
|
259
|
+
ors = satisfy_dict.get("ors")
|
|
260
|
+
if not isinstance(ors, dict):
|
|
261
|
+
return None
|
|
262
|
+
rf = ors.get("referencedFeature") or {}
|
|
263
|
+
names = rf.get("names") if isinstance(rf, dict) else None
|
|
264
|
+
if not names:
|
|
265
|
+
return None
|
|
266
|
+
target = "::".join(str(n) for n in names)
|
|
267
|
+
|
|
268
|
+
ssm = satisfy_dict.get("ssm")
|
|
269
|
+
by_ref = None
|
|
270
|
+
if isinstance(ssm, dict):
|
|
271
|
+
for m in _find_named_dicts_local(ssm, "FeatureChainMember"):
|
|
272
|
+
me = m.get("memberElement") or {}
|
|
273
|
+
mnames = me.get("names")
|
|
274
|
+
if isinstance(mnames, list) and mnames:
|
|
275
|
+
by_ref = "::".join(str(n) for n in mnames)
|
|
276
|
+
break
|
|
277
|
+
return target, by_ref
|
|
278
|
+
|
|
279
|
+
|
|
227
280
|
def _last_segment(ref: str) -> str:
|
|
228
281
|
"""Last segment of a dotted/qualified reference (``Pkg::r1`` → ``r1``)."""
|
|
229
282
|
for sep in ("::", "."):
|
|
@@ -300,6 +353,26 @@ def extract_traceability(model) -> TraceabilityReport:
|
|
|
300
353
|
is_definition=(gclass == "RequirementDefinition"),
|
|
301
354
|
)
|
|
302
355
|
traces.append(trace)
|
|
356
|
+
# Nested satisfy members (``requirement top { satisfy top by v;
|
|
357
|
+
# }``) parse as SatisfyRequirementUsage dicts inside the
|
|
358
|
+
# requirement's grammar — the visitor handles nested *verify*
|
|
359
|
+
# members but not satisfy, so they are invisible to pass 2 and
|
|
360
|
+
# the requirement would read as uncovered. Record the edge.
|
|
361
|
+
if grammar is not None:
|
|
362
|
+
try:
|
|
363
|
+
grammar_def = grammar.get_definition()
|
|
364
|
+
except Exception:
|
|
365
|
+
grammar_def = None
|
|
366
|
+
if isinstance(grammar_def, dict):
|
|
367
|
+
for sat in _find_named_dicts_local(
|
|
368
|
+
grammar_def, "SatisfyRequirementUsage"):
|
|
369
|
+
ref = _nested_satisfy_ref(sat)
|
|
370
|
+
if ref is None:
|
|
371
|
+
continue
|
|
372
|
+
target, by_part = ref
|
|
373
|
+
if by_part and _last_segment(target) == name and (
|
|
374
|
+
by_part not in trace.satisfied_by):
|
|
375
|
+
trace.satisfied_by.append(by_part)
|
|
303
376
|
# Index by both the bare name and every suffix of the qualified
|
|
304
377
|
# name so `Pkg::req` / `req` / `Sub::req` references all resolve.
|
|
305
378
|
traces_by_name.setdefault(name, trace)
|
|
@@ -3239,6 +3239,13 @@ class Requirement(Usage):
|
|
|
3239
3239
|
c = Requirement(definition=True).load_from_grammar(target)
|
|
3240
3240
|
c.parent = self
|
|
3241
3241
|
self.children.append(c)
|
|
3242
|
+
elif target_cls in ("SatisfyRequirementUsage",
|
|
3243
|
+
"VerifyRequirementUsage"):
|
|
3244
|
+
# satisfy members are extracted from the grammar
|
|
3245
|
+
# dicts by traceability/semantic (nested verify
|
|
3246
|
+
# members ride _extract_verification_member); no
|
|
3247
|
+
# Requirement child belongs here.
|
|
3248
|
+
pass
|
|
3242
3249
|
elif target_cls and "Requirement" in target_cls:
|
|
3243
3250
|
print(f"[Requirement] Unhandled nested requirement type: {target_cls}")
|
|
3244
3251
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp
RENAMED
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py
RENAMED
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Analysis/SampledFunctions.sysml
RENAMED
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Metadata/ModelingMetadata.sysml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml
RENAMED
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQBase.sysml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQLight.sysml
RENAMED
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml
RENAMED
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/Quantities.sysml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml
RENAMED
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/domain/Quantities and Units/Time.sysml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sysmlpy-0.71.0 → sysmlpy-0.73.0}/src/sysmlpy/library/kernel/FeatureReferencingPerformances.kerml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|