sysml-diagram 0.25.0 → 0.26.0
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.
- package/out/main.js +344 -33
- package/out/main.js.map +2 -2
- package/package.json +1 -1
- package/resources/sysml.dimension-table.json +1 -1
package/out/main.js
CHANGED
|
@@ -162649,7 +162649,12 @@ function keywordFor(node) {
|
|
|
162649
162649
|
JoinNode: "join",
|
|
162650
162650
|
TerminateNode: "terminate",
|
|
162651
162651
|
PerformStmt: "perform action",
|
|
162652
|
-
EventDecl: "event occurrence"
|
|
162652
|
+
EventDecl: "event occurrence",
|
|
162653
|
+
// REQ-198, issue #113: a state sub-action drawn as a state-transition
|
|
162654
|
+
// node keeps the keyword that says WHEN it runs (OMG 8.2.2.18.1).
|
|
162655
|
+
EntryAction: "entry action",
|
|
162656
|
+
DoAction: "do action",
|
|
162657
|
+
ExitAction: "exit action"
|
|
162653
162658
|
};
|
|
162654
162659
|
if (t === "ActionDecl" && n2.inlineBody?.$type === "AcceptNode") {
|
|
162655
162660
|
return "accept action";
|
|
@@ -167625,7 +167630,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167625
167630
|
const def = this.resolveType(holder, index2);
|
|
167626
167631
|
return def && def !== holder && def.isDef === true ? def : void 0;
|
|
167627
167632
|
};
|
|
167628
|
-
const ownStates = (holder) => membersOf(holder).filter((member) => isStateDecl(member) && nameOf2(member) !== void 0);
|
|
167633
|
+
const ownStates = (holder) => membersOf(holder).map((member) => this.thenActionMemberNode(member) ?? member).filter((member) => isStateDecl(member) && nameOf2(member) !== void 0);
|
|
167629
167634
|
const nestedStates = (holder) => {
|
|
167630
167635
|
const out = ownStates(holder);
|
|
167631
167636
|
const def = definitionOf(holder);
|
|
@@ -167664,9 +167669,28 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167664
167669
|
drawnStates.push({ node: anchor, id: anchorFrameId });
|
|
167665
167670
|
idByState.set(anchor, anchorFrameId);
|
|
167666
167671
|
}
|
|
167672
|
+
const drawnRowKeys = /* @__PURE__ */ new Set();
|
|
167673
|
+
const rowKey = (source) => source ? `${source.uri} ${source.range.start.line} ${source.range.start.character}` : void 0;
|
|
167674
|
+
const registerDrawn = (member) => {
|
|
167675
|
+
const key = rowKey(sourceOf2(member, uri));
|
|
167676
|
+
if (key)
|
|
167677
|
+
drawnRowKeys.add(key);
|
|
167678
|
+
};
|
|
167679
|
+
const namesByFrame = /* @__PURE__ */ new Map();
|
|
167680
|
+
const namesIn = (frameId) => {
|
|
167681
|
+
const key = frameId ?? "";
|
|
167682
|
+
const existing = namesByFrame.get(key);
|
|
167683
|
+
if (existing)
|
|
167684
|
+
return existing;
|
|
167685
|
+
const created = /* @__PURE__ */ new Map();
|
|
167686
|
+
namesByFrame.set(key, created);
|
|
167687
|
+
return created;
|
|
167688
|
+
};
|
|
167667
167689
|
const renderState = (s, parentFrame, depth, seen) => {
|
|
167668
167690
|
const id2 = qnameOf(s) || nameOf2(s);
|
|
167669
167691
|
byName.set(nameOf2(s), id2);
|
|
167692
|
+
namesIn(parentFrame).set(nameOf2(s), id2);
|
|
167693
|
+
registerDrawn(s);
|
|
167670
167694
|
drawnStates.push({ node: s, id: id2 });
|
|
167671
167695
|
idByState.set(s, id2);
|
|
167672
167696
|
const def = s.isDef === true ? void 0 : this.resolveType(s, index2);
|
|
@@ -167704,6 +167728,75 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167704
167728
|
};
|
|
167705
167729
|
for (const s of topStates)
|
|
167706
167730
|
renderState(s, anchorFrameId, 0, /* @__PURE__ */ new Set());
|
|
167731
|
+
const endpointName = (path10) => typeof path10 === "string" ? path10.split(/::|\./).pop() || void 0 : void 0;
|
|
167732
|
+
const controlNodeInfo = (m) => {
|
|
167733
|
+
switch (m.$type) {
|
|
167734
|
+
case "ActionDecl":
|
|
167735
|
+
return m.isDef === true || !nameOf2(m) ? void 0 : { shape: "action", label: nameOf2(m) };
|
|
167736
|
+
// A `perform` names the action it performs, which for a feature
|
|
167737
|
+
// chain (`perform machine.selfTest;`) is the LAST segment.
|
|
167738
|
+
case "PerformStmt": {
|
|
167739
|
+
const segments = [nameOf2(m), ...m.chainSegs ?? []].filter((segment) => !!segment);
|
|
167740
|
+
return { shape: "action", label: segments.at(-1) ?? typeText(m) ?? "perform" };
|
|
167741
|
+
}
|
|
167742
|
+
// User direction 2026-08-30: fork and join only. They express
|
|
167743
|
+
// concurrency, which a transition cannot say: nothing about a
|
|
167744
|
+
// guard or a trigger splits control into parallel regions or
|
|
167745
|
+
// gathers it again. `decide` and `merge` are dropped because a
|
|
167746
|
+
// branch between states IS a guarded transition, which this
|
|
167747
|
+
// view already draws and labels, so a diamond would say the
|
|
167748
|
+
// same thing a second time in the action-flow idiom.
|
|
167749
|
+
// `terminate` is dropped with them: the node carries no name,
|
|
167750
|
+
// so no succession can reach it and it could only ever stand
|
|
167751
|
+
// alone. All three remain in the OMG 8.2.3.18 node set.
|
|
167752
|
+
case "JoinNode":
|
|
167753
|
+
return { shape: "join", label: nameOf2(m) ?? "" };
|
|
167754
|
+
case "ForkNode":
|
|
167755
|
+
return { shape: "fork", label: nameOf2(m) ?? "" };
|
|
167756
|
+
default:
|
|
167757
|
+
return void 0;
|
|
167758
|
+
}
|
|
167759
|
+
};
|
|
167760
|
+
const isInitialMarker = (member) => {
|
|
167761
|
+
const entry = member;
|
|
167762
|
+
return !!entry && entry.$type === "EntryAction" && !entry.name && !entry.actionKw && !entry.send && !entry.accept && !entry.assign;
|
|
167763
|
+
};
|
|
167764
|
+
const machineNodeIds = /* @__PURE__ */ new Map();
|
|
167765
|
+
const machineNodeMembers = [];
|
|
167766
|
+
let anonymousNodes = 0;
|
|
167767
|
+
const emitMachineNodes = (holder, frameId) => {
|
|
167768
|
+
const members = membersOf(holder);
|
|
167769
|
+
const drawnHere = namesIn(frameId);
|
|
167770
|
+
for (const raw of members) {
|
|
167771
|
+
const member = this.thenActionMemberNode(raw) ?? raw;
|
|
167772
|
+
const info = controlNodeInfo(member);
|
|
167773
|
+
if (!info)
|
|
167774
|
+
continue;
|
|
167775
|
+
const name = nameOf2(member);
|
|
167776
|
+
if (name && drawnHere.has(name))
|
|
167777
|
+
continue;
|
|
167778
|
+
const id2 = name ? qnameOf(member) || `${frameId}::${name}` : `${frameId}::__stv_${member.$type}_${anonymousNodes++}__`;
|
|
167779
|
+
if (nodes.some((n2) => n2.id === id2) || frames.some((f) => f.id === id2))
|
|
167780
|
+
continue;
|
|
167781
|
+
if (name) {
|
|
167782
|
+
drawnHere.set(name, id2);
|
|
167783
|
+
if (!byName.has(name))
|
|
167784
|
+
byName.set(name, id2);
|
|
167785
|
+
}
|
|
167786
|
+
machineNodeIds.set(member, id2);
|
|
167787
|
+
machineNodeMembers.push({ member, id: id2 });
|
|
167788
|
+
nodes.push({
|
|
167789
|
+
id: id2,
|
|
167790
|
+
name: info.label,
|
|
167791
|
+
keyword: keywordFor(member),
|
|
167792
|
+
isDef: false,
|
|
167793
|
+
shape: info.shape,
|
|
167794
|
+
compartments: this.compartmentsFor(member, uri, index2),
|
|
167795
|
+
frame: frameId,
|
|
167796
|
+
source: sourceOf2(member, uri)
|
|
167797
|
+
});
|
|
167798
|
+
}
|
|
167799
|
+
};
|
|
167707
167800
|
const edges = [];
|
|
167708
167801
|
let e = 0;
|
|
167709
167802
|
const resolveState = (nm) => {
|
|
@@ -167719,53 +167812,201 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167719
167812
|
}
|
|
167720
167813
|
return void 0;
|
|
167721
167814
|
};
|
|
167722
|
-
const
|
|
167723
|
-
|
|
167724
|
-
|
|
167725
|
-
|
|
167726
|
-
|
|
167727
|
-
|
|
167728
|
-
|
|
167815
|
+
const drawnEdges = /* @__PURE__ */ new Set();
|
|
167816
|
+
const stateLike = /* @__PURE__ */ new Set(["state", "initial", "final"]);
|
|
167817
|
+
const isStateEndpoint = (id2) => {
|
|
167818
|
+
const node = nodes.find((n2) => n2.id === id2);
|
|
167819
|
+
return node ? stateLike.has(node.shape) : frames.some((f) => f.id === id2);
|
|
167820
|
+
};
|
|
167821
|
+
const link = (from, to, label, src) => {
|
|
167729
167822
|
if (!from || !to)
|
|
167730
|
-
|
|
167823
|
+
return;
|
|
167824
|
+
const kind = isStateEndpoint(from) && isStateEndpoint(to) ? "transition" : "succession";
|
|
167825
|
+
const key = `${from}\0${to}\0${label ?? ""}`;
|
|
167826
|
+
if (drawnEdges.has(key))
|
|
167827
|
+
return;
|
|
167828
|
+
drawnEdges.add(key);
|
|
167829
|
+
if (src)
|
|
167830
|
+
registerDrawn(src);
|
|
167731
167831
|
edges.push({
|
|
167732
167832
|
id: `e${e++}`,
|
|
167733
167833
|
from,
|
|
167734
167834
|
to,
|
|
167735
|
-
kind
|
|
167736
|
-
label
|
|
167737
|
-
source: sourceOf2(
|
|
167835
|
+
kind,
|
|
167836
|
+
label,
|
|
167837
|
+
source: src ? sourceOf2(src, uri) : void 0
|
|
167738
167838
|
});
|
|
167839
|
+
};
|
|
167840
|
+
const guardText = (guard) => {
|
|
167841
|
+
const text = guard?.$cstNode?.text?.replace(/\s+/g, " ").trim();
|
|
167842
|
+
return text ? `[${text}]` : void 0;
|
|
167843
|
+
};
|
|
167844
|
+
const resolveEndpoint = (path10, initialId, frameId) => {
|
|
167845
|
+
if (typeof path10 !== "string")
|
|
167846
|
+
return void 0;
|
|
167847
|
+
const short = endpointName(path10);
|
|
167848
|
+
const local = namesByFrame.get(frameId ?? "");
|
|
167849
|
+
return (short ? local?.get(short) : void 0) ?? resolveState(path10) ?? resolveState(short) ?? (short === "start" ? initialId : void 0);
|
|
167850
|
+
};
|
|
167851
|
+
const transitionScope = [anchor, ...definitionOf(anchor) ? [definitionOf(anchor)] : []];
|
|
167852
|
+
for (const t of transitionScope.flatMap((holder) => [...ast_utils_exports.streamAllContents(holder)])) {
|
|
167853
|
+
if (t.$type !== "TransitionDecl")
|
|
167854
|
+
continue;
|
|
167855
|
+
const tn = t;
|
|
167856
|
+
link(resolveState(tn.from), resolveState(tn.to), this.transitionLabel(t), t);
|
|
167739
167857
|
}
|
|
167740
|
-
const designatedInitial = (owner) => {
|
|
167858
|
+
const designatedInitial = (owner, frameId) => {
|
|
167741
167859
|
const members = owner.members;
|
|
167742
167860
|
if (!Array.isArray(members))
|
|
167743
167861
|
return void 0;
|
|
167744
|
-
for (let i = 0; i < members.length
|
|
167745
|
-
const
|
|
167746
|
-
if (
|
|
167862
|
+
for (let i = 0; i < members.length; i++) {
|
|
167863
|
+
const member = members[i];
|
|
167864
|
+
if (member.$type === "FirstThenChain") {
|
|
167865
|
+
const chain = member;
|
|
167866
|
+
if (endpointName(chain.head) !== "start")
|
|
167867
|
+
continue;
|
|
167868
|
+
const target2 = resolveEndpoint((chain.steps ?? [])[0], void 0, frameId);
|
|
167869
|
+
if (target2) {
|
|
167870
|
+
registerDrawn(member);
|
|
167871
|
+
return target2;
|
|
167872
|
+
}
|
|
167873
|
+
continue;
|
|
167874
|
+
}
|
|
167875
|
+
if (!isInitialMarker(member))
|
|
167747
167876
|
continue;
|
|
167748
167877
|
const then = members[i + 1];
|
|
167749
167878
|
if (then?.$type !== "ThenActionMember" || typeof then.target !== "string")
|
|
167750
167879
|
continue;
|
|
167751
167880
|
const target = resolveState(lastSeg(then.target));
|
|
167752
|
-
if (target)
|
|
167881
|
+
if (target) {
|
|
167882
|
+
registerDrawn(then);
|
|
167753
167883
|
return target;
|
|
167884
|
+
}
|
|
167754
167885
|
}
|
|
167755
167886
|
return void 0;
|
|
167756
167887
|
};
|
|
167757
|
-
const
|
|
167758
|
-
|
|
167759
|
-
|
|
167760
|
-
|
|
167888
|
+
const machineScope = (holder) => {
|
|
167889
|
+
const def = definitionOf(holder);
|
|
167890
|
+
return def ? [holder, def] : [holder];
|
|
167891
|
+
};
|
|
167892
|
+
if (anchorFrameId) {
|
|
167893
|
+
for (const holder of machineScope(anchor))
|
|
167894
|
+
emitMachineNodes(holder, anchorFrameId);
|
|
167761
167895
|
}
|
|
167762
167896
|
for (const { state, frameId } of compositeFrames) {
|
|
167763
|
-
const
|
|
167897
|
+
for (const holder of machineScope(state))
|
|
167898
|
+
emitMachineNodes(holder, frameId);
|
|
167899
|
+
}
|
|
167900
|
+
const anchorDefinition = definitionOf(anchor);
|
|
167901
|
+
const firstStateId = designatedInitial(anchor, anchorFrameId) ?? (anchorDefinition ? designatedInitial(anchorDefinition, anchorFrameId) : void 0) ?? (topStates.length ? byName.get(nameOf2(topStates[0])) : void 0);
|
|
167902
|
+
if (firstStateId)
|
|
167903
|
+
link("__initial__", firstStateId, void 0, void 0);
|
|
167904
|
+
const compositeInitial = /* @__PURE__ */ new Map();
|
|
167905
|
+
for (const { state, frameId } of compositeFrames) {
|
|
167906
|
+
const target = designatedInitial(state, frameId);
|
|
167764
167907
|
if (!target)
|
|
167765
167908
|
continue;
|
|
167766
167909
|
const id2 = `__initial__${frameId}`;
|
|
167767
167910
|
nodes.push({ id: id2, name: "", keyword: "initial", isDef: false, shape: "initial", frame: frameId });
|
|
167768
|
-
|
|
167911
|
+
compositeInitial.set(state, id2);
|
|
167912
|
+
link(id2, target, void 0, void 0);
|
|
167913
|
+
}
|
|
167914
|
+
const sequentialTransitions = (holder, initialId, frameId) => {
|
|
167915
|
+
let cursor;
|
|
167916
|
+
const idOf = (member) => machineNodeIds.get(member) ?? idByState.get(member) ?? (nameOf2(member) ? resolveEndpoint(nameOf2(member), void 0, frameId) : void 0);
|
|
167917
|
+
const endpoint = (path10) => resolveEndpoint(path10, initialId, frameId);
|
|
167918
|
+
for (const member of membersOf(holder)) {
|
|
167919
|
+
switch (member.$type) {
|
|
167920
|
+
case "StateDecl": {
|
|
167921
|
+
cursor = idOf(member) ?? cursor;
|
|
167922
|
+
break;
|
|
167923
|
+
}
|
|
167924
|
+
// `entry;` IS the start pseudostate, so the succession written
|
|
167925
|
+
// after it leaves that pseudostate rather than the last state.
|
|
167926
|
+
case "EntryAction": {
|
|
167927
|
+
if (isInitialMarker(member)) {
|
|
167928
|
+
cursor = initialId;
|
|
167929
|
+
break;
|
|
167930
|
+
}
|
|
167931
|
+
cursor = machineNodeIds.get(member) ?? cursor;
|
|
167932
|
+
break;
|
|
167933
|
+
}
|
|
167934
|
+
// OMG 8.2.3.18 names this edge `st-succession`, so the
|
|
167935
|
+
// keyworded form is a first-class state-transition edge,
|
|
167936
|
+
// not action-language sugar the state view may skip.
|
|
167937
|
+
// Its ends are ConnectorEnds, not bare paths.
|
|
167938
|
+
case "SuccessionStmt": {
|
|
167939
|
+
const succession = member;
|
|
167940
|
+
let previous = endpoint(this.connectorEndPath(succession.first));
|
|
167941
|
+
let firstHop = true;
|
|
167942
|
+
for (const step of succession.steps ?? []) {
|
|
167943
|
+
const to = endpoint(this.connectorEndPath(step));
|
|
167944
|
+
link(previous, to, firstHop ? guardText(succession.guard) : void 0, member);
|
|
167945
|
+
previous = to;
|
|
167946
|
+
firstHop = false;
|
|
167947
|
+
}
|
|
167948
|
+
if (previous)
|
|
167949
|
+
cursor = previous;
|
|
167950
|
+
break;
|
|
167951
|
+
}
|
|
167952
|
+
case "FirstThenChain": {
|
|
167953
|
+
const chain = member;
|
|
167954
|
+
let previous = endpoint(chain.head);
|
|
167955
|
+
let firstHop = true;
|
|
167956
|
+
for (const step of chain.steps ?? []) {
|
|
167957
|
+
const to = endpoint(step);
|
|
167958
|
+
link(previous, to, firstHop ? guardText(chain.guard) : void 0, member);
|
|
167959
|
+
previous = to;
|
|
167960
|
+
firstHop = false;
|
|
167961
|
+
}
|
|
167962
|
+
if (previous)
|
|
167963
|
+
cursor = previous;
|
|
167964
|
+
break;
|
|
167965
|
+
}
|
|
167966
|
+
case "AcceptNode": {
|
|
167967
|
+
const accept = member;
|
|
167968
|
+
if (typeof accept.thenTarget !== "string")
|
|
167969
|
+
break;
|
|
167970
|
+
link(cursor, endpoint(accept.thenTarget), this.acceptShorthandLabel(member), member);
|
|
167971
|
+
break;
|
|
167972
|
+
}
|
|
167973
|
+
case "ThenActionMember": {
|
|
167974
|
+
const then = member;
|
|
167975
|
+
const declared = this.thenActionMemberNode(member);
|
|
167976
|
+
const to = (declared ? idOf(declared) : void 0) ?? endpoint(then.target);
|
|
167977
|
+
link(cursor, to, void 0, member);
|
|
167978
|
+
if (to)
|
|
167979
|
+
cursor = to;
|
|
167980
|
+
break;
|
|
167981
|
+
}
|
|
167982
|
+
// issue #113: a guarded or default target succession fans out
|
|
167983
|
+
// of the SAME source (a decision node, normally), so neither
|
|
167984
|
+
// branch may advance the cursor past its siblings.
|
|
167985
|
+
case "IfActionNode": {
|
|
167986
|
+
const branch = member;
|
|
167987
|
+
if (typeof branch.thenTarget !== "string")
|
|
167988
|
+
break;
|
|
167989
|
+
link(cursor, endpoint(branch.thenTarget), guardText(branch.cond), member);
|
|
167990
|
+
break;
|
|
167991
|
+
}
|
|
167992
|
+
case "ElseSuccessionMember": {
|
|
167993
|
+
link(cursor, endpoint(member.target), "else", member);
|
|
167994
|
+
break;
|
|
167995
|
+
}
|
|
167996
|
+
default: {
|
|
167997
|
+
cursor = machineNodeIds.get(member) ?? cursor;
|
|
167998
|
+
break;
|
|
167999
|
+
}
|
|
168000
|
+
}
|
|
168001
|
+
}
|
|
168002
|
+
};
|
|
168003
|
+
for (const holder of machineScope(anchor)) {
|
|
168004
|
+
sequentialTransitions(holder, hostsStateMachine ? "__initial__" : void 0, anchorFrameId);
|
|
168005
|
+
}
|
|
168006
|
+
for (const { state, frameId } of compositeFrames) {
|
|
168007
|
+
for (const holder of machineScope(state)) {
|
|
168008
|
+
sequentialTransitions(holder, compositeInitial.get(state), frameId);
|
|
168009
|
+
}
|
|
167769
168010
|
}
|
|
167770
168011
|
const exhibitorsByState = /* @__PURE__ */ new Map();
|
|
167771
168012
|
const exhibitScope = this.packageScopeOf(anchor);
|
|
@@ -167847,6 +168088,37 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
167847
168088
|
edges.push({ id: `e${e++}`, from, to, kind: "causation", label: "\xABcausation\xBB", source: sourceOf2(c, uri) });
|
|
167848
168089
|
}
|
|
167849
168090
|
}
|
|
168091
|
+
const wired = /* @__PURE__ */ new Set();
|
|
168092
|
+
for (const edge of edges) {
|
|
168093
|
+
wired.add(edge.from);
|
|
168094
|
+
wired.add(edge.to);
|
|
168095
|
+
}
|
|
168096
|
+
const stranded = new Set(machineNodeMembers.filter(({ id: id2 }) => !wired.has(id2)).map(({ id: id2 }) => id2));
|
|
168097
|
+
if (stranded.size) {
|
|
168098
|
+
for (let at = nodes.length - 1; at >= 0; at--) {
|
|
168099
|
+
if (stranded.has(nodes[at].id))
|
|
168100
|
+
nodes.splice(at, 1);
|
|
168101
|
+
}
|
|
168102
|
+
}
|
|
168103
|
+
for (const { member, id: id2 } of machineNodeMembers) {
|
|
168104
|
+
if (!stranded.has(id2))
|
|
168105
|
+
registerDrawn(member);
|
|
168106
|
+
}
|
|
168107
|
+
for (const frame2 of frames) {
|
|
168108
|
+
const full = frame2.compartments;
|
|
168109
|
+
if (!full?.length)
|
|
168110
|
+
continue;
|
|
168111
|
+
const kept = full.map((compartment) => ({
|
|
168112
|
+
title: compartment.title,
|
|
168113
|
+
items: compartment.items.filter((row) => {
|
|
168114
|
+
const key = rowKey(row.source);
|
|
168115
|
+
return !key || !drawnRowKeys.has(key);
|
|
168116
|
+
})
|
|
168117
|
+
})).filter((compartment) => compartment.items.length > 0);
|
|
168118
|
+
if (kept.length === full.length && kept.every((c, at) => c.items.length === full[at].items.length))
|
|
168119
|
+
continue;
|
|
168120
|
+
frame2.compartments = kept.length ? kept : void 0;
|
|
168121
|
+
}
|
|
167850
168122
|
const model = this.model("stv", anchor, nodes, edges);
|
|
167851
168123
|
if (frames.length) {
|
|
167852
168124
|
model.frames = frames;
|
|
@@ -170032,9 +170304,25 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
170032
170304
|
return item(m, val ? `= ${val}` : "(value)");
|
|
170033
170305
|
}));
|
|
170034
170306
|
add("states", usages(isStateDecl).map((m) => item(m)));
|
|
170035
|
-
const
|
|
170036
|
-
|
|
170307
|
+
const isInitialStateMarker = (m, at) => {
|
|
170308
|
+
const entry = m;
|
|
170309
|
+
if (m.$type !== "EntryAction" || entry.name || entry.actionKw || entry.send || entry.accept || entry.assign)
|
|
170310
|
+
return false;
|
|
170311
|
+
const next = members[at + 1];
|
|
170312
|
+
return next?.$type === "ThenActionMember" || next?.$type === "FirstThenChain";
|
|
170313
|
+
};
|
|
170314
|
+
const stateActionTitle = {
|
|
170315
|
+
EntryAction: "entry",
|
|
170316
|
+
DoAction: "during",
|
|
170317
|
+
ExitAction: "exit"
|
|
170318
|
+
};
|
|
170319
|
+
const stateActionText = (m) => nameOf2(m) ?? (m.$cstNode?.text ?? "").replace(/\s+/g, " ").replace(/;$/, "").replace(/^(entry|do|exit)\s+(action\s+)?/, "").trim();
|
|
170320
|
+
for (const title of ["entry", "during", "exit"]) {
|
|
170321
|
+
add(title, members.filter((m, at) => stateActionTitle[m.$type] === title && !isInitialStateMarker(m, at)).map((m) => item(m, stateActionText(m))).filter((row) => !!row.text));
|
|
170322
|
+
}
|
|
170037
170323
|
add("state transition", members.filter((m) => m.$type === "TransitionDecl").map((m) => item(m, `${m.from ?? ""} \u2192 ${m.to ?? ""}`)));
|
|
170324
|
+
const successionText = (m) => (m.$cstNode?.text ?? "").replace(/\s+/g, " ").replace(/;$/, "").trim();
|
|
170325
|
+
add("successions", members.filter((m) => m.$type === "FirstThenChain" || m.$type === "SuccessionStmt" || m.$type === "ThenActionMember" && typeof m.target === "string" || m.$type === "ElseSuccessionMember" || (m.$type === "AcceptNode" || m.$type === "IfActionNode") && typeof m.thenTarget === "string").map((m) => item(m, successionText(m))).filter((row) => !!row.text));
|
|
170038
170326
|
add("assert constraints", members.filter((m) => m.$type === "AssertConstraintStmt").map((m) => item(m, exprText3(m) || nameOf2(m) || "assert constraint")));
|
|
170039
170327
|
add("invariants", members.filter((m) => m.$type === "InvShorthand").map((m) => {
|
|
170040
170328
|
const inv = m;
|
|
@@ -170125,9 +170413,19 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
|
|
|
170125
170413
|
// REQ-186/REQ-198 — transition label: `trigger [guard] / effect`.
|
|
170126
170414
|
transitionLabel(t) {
|
|
170127
170415
|
const tn = t;
|
|
170128
|
-
|
|
170129
|
-
|
|
170130
|
-
|
|
170416
|
+
return this.transitionLabelOf(tn.accept, tn.guard, tn.effect);
|
|
170417
|
+
}
|
|
170418
|
+
// REQ-198: the label of a source-less transition shorthand (`accept Sig if g
|
|
170419
|
+
// do effect then t;`, OMG SysML 8.2.2.18.3). The accept node itself carries
|
|
170420
|
+
// the trigger, so it reads exactly like an explicit `transition`.
|
|
170421
|
+
acceptShorthandLabel(accept) {
|
|
170422
|
+
const node = accept;
|
|
170423
|
+
return this.transitionLabelOf(accept, node.guard, node.effect);
|
|
170424
|
+
}
|
|
170425
|
+
transitionLabelOf(accept, guardExpr, effectClause) {
|
|
170426
|
+
const trigger = this.acceptTriggerLabel(accept);
|
|
170427
|
+
const guard = guardExpr?.$cstNode?.text?.replace(/\s+/g, " ").trim();
|
|
170428
|
+
const effect = this.effectLabel(effectClause);
|
|
170131
170429
|
const parts = [];
|
|
170132
170430
|
if (trigger)
|
|
170133
170431
|
parts.push(String(trigger));
|
|
@@ -196775,7 +197073,7 @@ var AFV_LAYOUT_EDGE_KINDS = /* @__PURE__ */ new Set([
|
|
|
196775
197073
|
"succession",
|
|
196776
197074
|
"successionFlow"
|
|
196777
197075
|
]);
|
|
196778
|
-
var STV_LAYOUT_EDGE_KINDS = /* @__PURE__ */ new Set(["transition"]);
|
|
197076
|
+
var STV_LAYOUT_EDGE_KINDS = /* @__PURE__ */ new Set(["transition", "succession"]);
|
|
196779
197077
|
function behaviorLayoutEdgeKinds(kind) {
|
|
196780
197078
|
return kind === "afv" ? AFV_LAYOUT_EDGE_KINDS : kind === "stv" ? STV_LAYOUT_EDGE_KINDS : void 0;
|
|
196781
197079
|
}
|
|
@@ -201984,6 +202282,10 @@ var TOOLBOX = {
|
|
|
201984
202282
|
],
|
|
201985
202283
|
relations: [
|
|
201986
202284
|
rel("transition", "transition", "\u2192", "click the source state, then the target state"),
|
|
202285
|
+
// issue #113 - a machine's action and control nodes are sequenced by
|
|
202286
|
+
// a succession, not by a transition: `transition` needs a state at
|
|
202287
|
+
// both ends (OMG SysML 8.2.2.18.3), while `first a then b` does not.
|
|
202288
|
+
rel("succession", "succession", "\u21E2", "click the source node, then the target node"),
|
|
201987
202289
|
// issue #115 — nothing could mark the initial state, so a state
|
|
201988
202290
|
// machine could not be STARTED from a blank canvas. The gesture runs
|
|
201989
202291
|
// from the always-drawn initial pseudostate to the first state.
|
|
@@ -202142,7 +202444,11 @@ function normalizedElementKeyword(keyword) {
|
|
|
202142
202444
|
"loop action",
|
|
202143
202445
|
"for-loop action",
|
|
202144
202446
|
"perform action",
|
|
202145
|
-
"assign"
|
|
202447
|
+
"assign",
|
|
202448
|
+
// issue #113 — a state sub-action drawn as a node is an action node.
|
|
202449
|
+
"entry action",
|
|
202450
|
+
"do action",
|
|
202451
|
+
"exit action"
|
|
202146
202452
|
].includes(base)) {
|
|
202147
202453
|
base = "action";
|
|
202148
202454
|
} else if (["fork", "join", "merge", "decide", "decision"].includes(base)) {
|
|
@@ -202244,7 +202550,12 @@ function relationToolsForNode(keyword, viewKind, shape) {
|
|
|
202244
202550
|
if (base === "port") return false;
|
|
202245
202551
|
return base === "pin" && (tool.kind === "flow" || tool.kind === "successionFlow" || tool.kind === "bind");
|
|
202246
202552
|
}
|
|
202247
|
-
if (viewKind === "stv")
|
|
202553
|
+
if (viewKind === "stv") {
|
|
202554
|
+
if (base === "action" || base === "control") {
|
|
202555
|
+
return tool.kind === "succession" || tool.kind === TERMINAL_RELATION;
|
|
202556
|
+
}
|
|
202557
|
+
return base === "state" && tool.kind !== "initial";
|
|
202558
|
+
}
|
|
202248
202559
|
if (viewKind === "sv") return shape === "lifeline" && (base === "part" || base === "lifeline");
|
|
202249
202560
|
if (viewKind === "cv") {
|
|
202250
202561
|
if (base === "actor") return tool.kind === "actor";
|
|
@@ -204707,7 +205018,7 @@ async function runExport(command) {
|
|
|
204707
205018
|
}
|
|
204708
205019
|
|
|
204709
205020
|
// src/main.ts
|
|
204710
|
-
var VERSION2 = true ? "0.
|
|
205021
|
+
var VERSION2 = true ? "0.26.0" : "dev";
|
|
204711
205022
|
function display(file) {
|
|
204712
205023
|
const rel2 = path9.relative(process.cwd(), file);
|
|
204713
205024
|
return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;
|