How to define the ends of a flow and flow direction in automator?

I wish to create a flow as part of an interface definition. I have added two PortUsages and defined the item that should flow (item usages, typed by the same item definition, used in the two port definitions, maybe I should reference the item instead?). In the following snippet you can see what I am trying to achieve:

example{
   item def someItemDef;

   port def portInDef {
      in item someItemUsage : someItemDef;
   }
   port def portOutDef {
      out item someItemUsage : someItemDef;
   }

   interface def someInterfaceDef {
   end port portIn : portInDef;
   end port portOut : portOutDef;
   
   // so far so good. The part I cannot figure out how to create and write with      Automator:
   flow portOut.someItemUsage to portIn.someItemUsage
   }
}

Is this the right syntax to begin with? And if not, what would be the correct syntax? Do I need to connect the two ports before creating a flow? If I so, I am also not sure what the syntax in Automator would be for that.

How can I create this flow with Automator? The idea is to then redefine the ports when creating an interface usage typed by the created interface definition, but leave the flow untouched, as I will only allow redefinition if all item flows are the same, and if the port is typed by the same definition.

Thanks!

Hi,

you just need to mimic the structure of the parse tree, e.g.

_, end = flow.declared_ends.append()
end.heritage.append(syside.ReferenceSubsetting, port_out)
_, ref = end.children.append(syside.FeatureMembership, syside.ReferenceUsage)
ref.heritage.append(syside.Redefinition, some_item_usage)

You can quickly see the parse tree by copying source to the Code panel at cst.syside.app

Hi,

Thanks for the quick answer. Is there some example of this somewhere? Or additional documentation? To be honest this just raises more questions for me: Why is only the PortOut mentioned? Or is that only to give an example and the same is necessary with the PortIn? And how is this connected to a specific item of the port (since a port can have multiple items)? Does the item in the port have to by reference only? Since it’s the same item on the in and out side it feels a bit odd to create item usages typed by the same definition on either side.

I am assuming that the second part of the code snippet in your answer is what you would use to redefine the flow ends (or actually the item in this case?) once I create an interface usage of the interface definition I am creating here?

Do I need to create a connection between the ports first? How is the flow direction fixed? Or is that automatically determined due to the item direction given in the port definitions?

I would greatly appreciate some additional clarification!

Is there some example of this somewhere? Or additional documentation?

Not exact example but potentially relevant Requirements from Excel Spreadsheet. You can also find API Reference, however we are working on improving it and making it easier to navigate.

Why is only the PortOut mentioned?

PortIn is identical

And how is this connected to a specific item of the port (since a port can have multiple items)?

The redefined feature in nested ReferenceUsage is the feature that is being connected.

Does the item in the port have to by reference only?

According to the specification, yes. Another reason is that because that is how textual syntax is parsed – if you want textual and synthetic models to match, they should have the same structure.

I am assuming that the second part of the code snippet in your answer is what you would use to redefine the flow ends (or actually the item in this case?) once I create an interface usage of the interface definition I am creating here?

Yes, generally child elements in the body, i.e. between { ... }, are created with

<parent namespace>.children.append(<relationship type>, <type for owned element or reference>)

e.g.

_, flow = example.children.append(syside.OwningMembership, syside.FlowUsage)

Do I need to create a connection between the ports first?

Create a flow as above, we generally try to prevent creation of orphan elements.

How is the flow direction fixed?

Flows are supposed to be only binary so direction is inferred from the order of end features, i.e. flow from source to target or from the first to the second end feature. At least that is how the specification describes it even if Pilot implementation propagates directions from the redefined features.