Hi everyone,
Consider the following model:
package Package {
part def BasePart {
attribute attr1 default 5.0;
attribute attr2 default 42.0;
}
part def SpecialPart :> BasePart {
attribute :>> attr1 = 6.0;
}
part def Container {
part thePartUsage : BasePart;
}
part def SpecialContainer :> Container {
part :>> thePartUsage : SpecialPart;
attribute attrRef = thePartUsage.attr1;
}
}
What I would expect is SpecialContainer::thePartUsage to have 2 features: SpecialPart::attr1 and BasePart::attr2, and therefore that thePartUsage.attr1 refers to SpecialPart::attr1.
However, this seems to not be the case (I’m using Syside Automator 0.11.0rc1):
import syside
def _print_features(element: syside.Type, indent=''):
if indent == '':
print(f'{indent}Element: {element.qualified_name}')
for feature in element.features.collect():
if not feature.name or feature.is_library_element:
continue
is_owned = feature.owner == element
value = feature.feature_value_expression
if value is not None:
if isinstance(value, syside.LiteralRational):
value = value.value
elif isinstance(value, syside.FeatureChainExpression):
value = value.target_feature.qualified_name
else:
raise NotImplementedError(repr(value))
value = f' = {value}' if value else ''
print(f'{indent} {feature.qualified_name}{value} (owned feature = {is_owned})')
if isinstance(feature, syside.PartUsage):
_print_features(feature, indent+' ')
model, _ = syside.load_model(['model.sysml'])
with model.documents[-1].lock() as doc:
root_node = doc.root_node
package: syside.Package = root_node.children.elements[0]
for child_el in package.children.elements:
_print_features(child_el)
Output:
Element: Package::BasePart
Package::BasePart::attr1 = 5.0 (owned feature = True)
Package::BasePart::attr2 = 42.0 (owned feature = True)
Element: Package::SpecialPart
Package::SpecialPart::attr1 = 6.0 (owned feature = True)
Package::BasePart::attr2 = 42.0 (owned feature = False)
Element: Package::Container
Package::Container::thePartUsage (owned feature = True)
Package::BasePart::attr1 = 5.0 (owned feature = False)
Package::BasePart::attr2 = 42.0 (owned feature = False)
Element: Package::SpecialContainer
Package::SpecialContainer::thePartUsage (owned feature = True)
Package::BasePart::attr1 = 5.0 (owned feature = False)
Package::BasePart::attr2 = 42.0 (owned feature = False)
Package::SpecialPart::attr1 = 6.0 (owned feature = False)
Package::SpecialContainer::attrRef = Package::BasePart::attr1 (owned feature = True)
As you can see, the final thePartUsage has 3 feature, and the attrRef points to BasePart::attr1, not the redefined one…
This could be due to the fact that the the redefinition (part :>> thePartUsage : SpecialPart;) actually defines 2 inheritance “streams” (the redefinition and the feature typing), and when “merging” the two feature inheritance streams it is not taking redefinition into account.
What should be the expected behavior here? Is SysML v2 not precise enough in this case, or is this a parser bug/limitation?
Cheers,
Jasper