sysml-diagram 0.21.1 → 0.22.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 CHANGED
@@ -162363,10 +162363,7 @@ function boundText(b) {
162363
162363
  return String(b.intVal);
162364
162364
  return b.bound;
162365
162365
  }
162366
- function multText(node) {
162367
- if (!node)
162368
- return void 0;
162369
- const m = node.multiplicity;
162366
+ function multiplicityText(m) {
162370
162367
  if (!m)
162371
162368
  return void 0;
162372
162369
  const lo = boundText(m.lower);
@@ -162375,6 +162372,11 @@ function multText(node) {
162375
162372
  return void 0;
162376
162373
  return hi == null || hi === lo ? `[${lo}]` : `[${lo}..${hi}]`;
162377
162374
  }
162375
+ function multText(node) {
162376
+ if (!node)
162377
+ return void 0;
162378
+ return multiplicityText(node.multiplicity);
162379
+ }
162378
162380
  var typeText = (node) => node.typing?.type?.$refText || void 0;
162379
162381
  var isConjugated = (node) => node.typing?.conjugate === true;
162380
162382
  var isAbstract = (node) => Array.isArray(node.modifiers) && node.modifiers.includes("abstract");
@@ -162505,6 +162507,18 @@ var modifiersOf = (node) => {
162505
162507
  const mods = node.modifiers;
162506
162508
  return Array.isArray(mods) ? mods : [];
162507
162509
  };
162510
+ var ANONYMOUS_INTERFACE_NAME = "(anonymous)";
162511
+ var isEndMember = (node) => node.$type === "EndDecl" || modifiersOf(node).includes("end");
162512
+ function endRowText(node) {
162513
+ const end = node;
162514
+ const name = nameOf2(node) ?? end.innerName;
162515
+ const type = typeText(node) ?? end.innerTyping?.type?.$refText;
162516
+ const mult = multText(node) ?? multiplicityText(end.innerMultiplicity) ?? multiplicityText(end.endMultiplicity);
162517
+ const head2 = `${name ?? ""}${type ? `${name ? " " : ""}: ${type}` : ""}`.trim();
162518
+ if (!head2)
162519
+ return void 0;
162520
+ return `${head2}${mult ? ` ${mult}` : ""}`;
162521
+ }
162508
162522
  var portionKindOf = (node) => modifiersOf(node).find((m) => m === "timeslice" || m === "snapshot");
162509
162523
  var isIndividualOccurrence = (node) => modifiersOf(node).includes("individual");
162510
162524
  var isOccurrenceModified = (node) => portionKindOf(node) !== void 0 || isIndividualOccurrence(node);
@@ -163088,7 +163102,10 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
163088
163102
  // and the feature it redefines. The latter can contribute its own body and its
163089
163103
  // type's complete inventory, so following only typing definitions turns an
163090
163104
  // anonymous `part :>> inheritedPart` into an empty leaf.
163091
- inheritedFeatureOwnersOf(node, index2) {
163105
+ inheritedFeatureOwnersOf(node, index2, resolving = /* @__PURE__ */ new Set()) {
163106
+ if (resolving.has(node))
163107
+ return [];
163108
+ resolving.add(node);
163092
163109
  const chain = [];
163093
163110
  const seen = /* @__PURE__ */ new Set([node]);
163094
163111
  const queue = [];
@@ -163101,22 +163118,26 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
163101
163118
  };
163102
163119
  const addTargets = (owner) => {
163103
163120
  for (const target of featureInheritanceTargets(owner)) {
163104
- add(this.resolveFeatureInheritanceTarget(owner, target, index2));
163121
+ add(this.resolveFeatureInheritanceTarget(owner, target, index2, resolving));
163105
163122
  }
163106
163123
  };
163107
- if (node.isDef === true)
163108
- addTargets(node);
163109
- else {
163110
- add(this.resolveType(node, index2));
163111
- addTargets(node);
163112
- }
163113
- while (queue.length > 0) {
163114
- const owner = queue.shift();
163115
- if (owner.isDef !== true)
163116
- add(this.resolveType(owner, index2));
163117
- addTargets(owner);
163124
+ try {
163125
+ if (node.isDef === true)
163126
+ addTargets(node);
163127
+ else {
163128
+ add(this.resolveType(node, index2));
163129
+ addTargets(node);
163130
+ }
163131
+ while (queue.length > 0) {
163132
+ const owner = queue.shift();
163133
+ if (owner.isDef !== true)
163134
+ add(this.resolveType(owner, index2));
163135
+ addTargets(owner);
163136
+ }
163137
+ return chain;
163138
+ } finally {
163139
+ resolving.delete(node);
163118
163140
  }
163119
- return chain;
163120
163141
  }
163121
163142
  /** Declaration that an anonymous local redefinition specializes. Direct edits
163122
163143
  * in definition-sync mode address this feature, while child insertion still
@@ -163131,7 +163152,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
163131
163152
  * names a sibling supplied by the containing usage or one of its types. A
163132
163153
  * global simple-name lookup can select the redeclaration itself or an
163133
163154
  * unrelated namesake, so the containing feature inventory is checked first. */
163134
- resolveFeatureInheritanceTarget(owner, target, index2) {
163155
+ resolveFeatureInheritanceTarget(owner, target, index2, resolving) {
163135
163156
  const path10 = this.resolvedFeatureInheritancePath(owner, target);
163136
163157
  if (path10.qualified) {
163137
163158
  return path10.target === owner ? void 0 : path10.target;
@@ -163140,7 +163161,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
163140
163161
  const wanted = lastSeg(target);
163141
163162
  const container = owner.$container;
163142
163163
  if (container) {
163143
- for (const source of [container, ...this.inheritedFeatureOwnersOf(container, index2)]) {
163164
+ for (const source of [container, ...this.inheritedFeatureOwnersOf(container, index2, resolving)]) {
163144
163165
  const inherited = membersOf(source).find((member) => member !== owner && effectiveNameOf(member) === wanted);
163145
163166
  if (inherited)
163146
163167
  return inherited;
@@ -163697,7 +163718,8 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
163697
163718
  const all = [...ast_utils_exports.streamAllContents(scope)];
163698
163719
  const defNodes = all.filter((n2) => isDefinitionNode(n2) && nameOf2(n2));
163699
163720
  const packageOverview = isPackage(ctx.anchor) || isDocument(ctx.anchor);
163700
- const hasOwnedMemberNode = all.some((n2) => isPackage(n2) && !!nameOf2(n2) || isDefinitionNode(n2) && !!nameOf2(n2) || this.isViewlessUsage(n2) && this.isDirectPackageMember(n2) || isPartDecl(n2) && n2.isDef !== true && !!nameOf2(n2) && this.isDirectPackageMember(n2));
163721
+ const isPackageInterfaceUsage = (n2) => isInterfaceDecl(n2) && n2.isDef !== true && !!nameOf2(n2) && this.isDirectPackageMember(n2);
163722
+ const hasOwnedMemberNode = all.some((n2) => isPackage(n2) && !!nameOf2(n2) || isDefinitionNode(n2) && !!nameOf2(n2) || this.isViewlessUsage(n2) && this.isDirectPackageMember(n2) || isPackageInterfaceUsage(n2) || isPartDecl(n2) && n2.isDef !== true && !!nameOf2(n2) && this.isDirectPackageMember(n2));
163701
163723
  const packageNodes = [
163702
163724
  ...packageOverview && hasOwnedMemberNode && isPackage(scope) && nameOf2(scope) ? [scope] : [],
163703
163725
  ...all.filter((p) => isPackage(p) && nameOf2(p))
@@ -163755,7 +163777,12 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
163755
163777
  meta: { gvPackageMember: true }
163756
163778
  });
163757
163779
  }
163758
- const packageUsageNodes = [...viewlessUsageNodes, ...packagePartUsageNodes];
163780
+ const packageInterfaceUsageNodes = all.filter(isPackageInterfaceUsage);
163781
+ for (const u of packageInterfaceUsageNodes) {
163782
+ const def = this.resolveType(u, index2);
163783
+ pushNode(u, "box", false, { type: def && ids.has(def) ? void 0 : typeText(u) });
163784
+ }
163785
+ const packageUsageNodes = [...viewlessUsageNodes, ...packagePartUsageNodes, ...packageInterfaceUsageNodes];
163759
163786
  for (const p of packageNodes) {
163760
163787
  const pn = p;
163761
163788
  pushNode(p, "package", false, {
@@ -164820,25 +164847,59 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
164820
164847
  } else if (isInterfaceDecl(m) && m.isDef !== true) {
164821
164848
  const clause = m.connect;
164822
164849
  if (clause) {
164823
- const from = resolveEnd(this.connectorEndPath(clause.source) ?? "");
164824
- const to = resolveEnd(this.connectorEndPath(clause.target) ?? "");
164825
- if (from && to && supportsEndpoints("interface", [from, to])) {
164826
- const name = nameOf2(m);
164827
- const type = typeText(m);
164828
- const label = ["\xABinterface\xBB", nameOf2(m) ?? "", typeText(m) ? `: ${typeText(m)}` : ""].filter(Boolean).join(" ").trim();
164850
+ const rawEnds = clause.ends?.length ? clause.ends : [clause.source, clause.target];
164851
+ const resolvedEnds = rawEnds.map((end) => ({ id: resolveEnd(this.connectorEndPath(end) ?? ""), end })).filter((x) => !!x.id);
164852
+ const name = nameOf2(m);
164853
+ const type = typeText(m);
164854
+ const label = ["\xABinterface\xBB", nameOf2(m) ?? "", typeText(m) ? `: ${typeText(m)}` : ""].filter(Boolean).join(" ").trim();
164855
+ const docks = resolvedEnds.length === rawEnds.length && supportsEndpoints("interface", resolvedEnds.map(({ id: id2 }) => id2));
164856
+ if (docks && resolvedEnds.length === 2) {
164829
164857
  edges.push({
164830
164858
  id: `e${eRef.n++}`,
164831
- from,
164832
- to,
164859
+ from: resolvedEnds[0].id,
164860
+ to: resolvedEnds[1].id,
164833
164861
  kind: "interface",
164834
164862
  name,
164835
164863
  type,
164836
164864
  isDef: false,
164837
164865
  label,
164838
- endLabelFrom: multText(clause.source),
164839
- endLabelTo: multText(clause.target),
164866
+ endLabelFrom: multText(resolvedEnds[0].end),
164867
+ endLabelTo: multText(resolvedEnds[1].end),
164840
164868
  ...relationshipFields(m)
164841
164869
  });
164870
+ } else if (docks && resolvedEnds.length > 2) {
164871
+ const dotId = `__nary_${eRef.n}__`;
164872
+ nodes.push(dot(dotId, label, m));
164873
+ for (const { id: endId, end } of resolvedEnds) {
164874
+ edges.push({
164875
+ id: `e${eRef.n++}`,
164876
+ from: dotId,
164877
+ to: endId,
164878
+ kind: "interface",
164879
+ name,
164880
+ type,
164881
+ isDef: false,
164882
+ label,
164883
+ endLabelTo: multText(end),
164884
+ ...relationshipFields(m)
164885
+ });
164886
+ }
164887
+ } else if (resolvedEnds.length < rawEnds.length) {
164888
+ nodes.push({
164889
+ id: `__interface_${eRef.n++}__`,
164890
+ // The box carries its type in its own `type` field, so
164891
+ // naming an anonymous usage after that type would read
164892
+ // as `FuelInterface : FuelInterface`.
164893
+ name: nameOf2(m) ?? ANONYMOUS_INTERFACE_NAME,
164894
+ keyword: "interface",
164895
+ isDef: false,
164896
+ shape: "box",
164897
+ type: typeText(m),
164898
+ multiplicity: multText(m),
164899
+ frame: frameId,
164900
+ compartments: this.interfaceFallbackCompartments(m, uri, index2),
164901
+ source: sourceOf2(m, uri)
164902
+ });
164842
164903
  }
164843
164904
  }
164844
164905
  } else if (isConnectionDecl(m) && m.isDef !== true) {
@@ -168915,6 +168976,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
168915
168976
  } else if (subjectMandatory) {
168916
168977
  add("subject", [{ text: "\u26A0 none declared" }]);
168917
168978
  }
168979
+ add("ends", members.filter(isEndMember).map((m) => item(m, endRowText(m) ?? statementText(m))));
168918
168980
  add("attributes", [
168919
168981
  ...usages(isAttributeDecl).map((a2) => item(a2)),
168920
168982
  ...inheritedRows((member) => isAttributeDecl(member) && isOrdinaryMember(member))
@@ -168924,6 +168986,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
168924
168986
  add("ports", usages(isPortDecl).map((m) => item(m)));
168925
168987
  add("parts", usages(isPartDecl).filter(notPortion).map((m) => item(m)));
168926
168988
  }
168989
+ add("interfaces", members.filter((m) => isInterfaceDecl(m) && m.isDef !== true && isOrdinaryMember(m)).map((m) => item(m, this.interfaceRowText(m))));
168927
168990
  add("features", members.filter((m) => m.$type === "FeatureShorthand" || m.$type === "FeatureRedefinitionShorthand").filter(isOrdinaryMember).filter((m) => !isOccurrenceModified(m)).map((m) => item(m, canonicalFeatureText(m))));
168928
168991
  const undirected = (guard) => usages(guard);
168929
168992
  add("items", undirected(isItemDecl).filter(notPortion).map((m) => item(m)));
@@ -169019,6 +169082,44 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
169019
169082
  add("satisfies", members.filter((m) => m.$type === "SatisfyStmt").map((m) => item(m, String(m.target ?? ""))));
169020
169083
  return out.length ? out : void 0;
169021
169084
  }
169085
+ // REQ-195 — Interface and binding guidance (`interfaces` row text)
169086
+ // issue #110 — the textual row (and node label) of an interface usage:
169087
+ // `name : Type connect a.p to b.q`. The connect ends are kept because this
169088
+ // row is the depiction a reader falls back to when the edge is not drawn, and
169089
+ // without them an anonymous typed usage would read as its type alone. The two
169090
+ // keyword-less shorthands (`interface a.p to b.q;` and an n-ary
169091
+ // `connect (a, b, c)`) are spelled the same way.
169092
+ interfaceRowText(node) {
169093
+ const n2 = node;
169094
+ const type = typeText(node);
169095
+ const mult = multText(node);
169096
+ const name = nameOf2(node) ?? ANONYMOUS_INTERFACE_NAME;
169097
+ const head2 = `${name}${type ? ` : ${type}` : ""}${mult ? ` ${mult}` : ""}`;
169098
+ const clause = n2.connect;
169099
+ const ends = clause?.ends?.length ? `connect (${clause.ends.map((end) => this.connectorEndPath(end) ?? "?").join(", ")})` : clause ? `connect ${this.connectorEndPath(clause.source) ?? "?"} to ${this.connectorEndPath(clause.target) ?? "?"}` : n2.target !== void 0 ? `${[nameOf2(node) ?? "", ...n2.srcSegs ?? []].filter(Boolean).join(".")} to ${this.featurePath(n2.target) ?? "?"}` : void 0;
169100
+ if (ends && !clause)
169101
+ return ends;
169102
+ return [head2, ends].filter(Boolean).join(" ");
169103
+ }
169104
+ // REQ-195 — Interface and binding guidance (usage-node fallback body)
169105
+ // issue #110 — the body of the `«interface»` usage node the IV draws when the
169106
+ // connect ends do not dock on the canvas. The written end paths ARE the
169107
+ // information the missing edge would have carried, so they read as the node's
169108
+ // `ends` compartment (OMG SysML 8.2.3.14), after any end members it declares.
169109
+ interfaceFallbackCompartments(node, uri, index2) {
169110
+ const clause = node.connect;
169111
+ const paths = clause?.ends?.length ? clause.ends.map((end) => this.connectorEndPath(end) ?? "?") : clause ? [this.connectorEndPath(clause.source) ?? "?", this.connectorEndPath(clause.target) ?? "?"] : [];
169112
+ const compartments = [...this.compartmentsFor(node, uri, index2) ?? []];
169113
+ if (!paths.length)
169114
+ return compartments.length ? compartments : void 0;
169115
+ const items = paths.map((text) => ({ text }));
169116
+ const existing = compartments.find((compartment) => compartment.title === "ends");
169117
+ if (existing)
169118
+ existing.items = [...existing.items, ...items];
169119
+ else
169120
+ compartments.push({ title: "ends", items });
169121
+ return compartments;
169122
+ }
169022
169123
  refText(v) {
169023
169124
  if (typeof v === "string")
169024
169125
  return v;
@@ -202278,7 +202379,7 @@ async function runExport(command) {
202278
202379
  }
202279
202380
 
202280
202381
  // src/main.ts
202281
- var VERSION2 = true ? "0.21.1" : "dev";
202382
+ var VERSION2 = true ? "0.22.0" : "dev";
202282
202383
  function display(file) {
202283
202384
  const rel2 = path9.relative(process.cwd(), file);
202284
202385
  return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;