sysml-diagram 0.28.0 → 0.28.1

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
@@ -161786,6 +161786,14 @@ function directNamedChildren(node) {
161786
161786
  }
161787
161787
  return result;
161788
161788
  }
161789
+ function boundVariableName(node) {
161790
+ if (!node || node.$type !== "ForLoopNode" && node.$type !== "AcceptNode")
161791
+ return void 0;
161792
+ const binding = node;
161793
+ if (binding.varSegs?.length)
161794
+ return void 0;
161795
+ return typeof binding.varName === "string" && binding.varName.length > 0 ? canonicalEscapedName(binding.varName) : void 0;
161796
+ }
161789
161797
  function isAncestor(candidate, node) {
161790
161798
  if (!candidate)
161791
161799
  return false;
@@ -161798,7 +161806,25 @@ function isAncestor(candidate, node) {
161798
161806
  function isSelfReference(candidate, node) {
161799
161807
  if (!candidate || !isAncestor(candidate, node))
161800
161808
  return false;
161801
- return !isPackage(candidate) && candidate.$type !== "NamespaceDecl";
161809
+ if (candidate === node)
161810
+ return true;
161811
+ if (isPackage(candidate) || candidate.$type === "NamespaceDecl")
161812
+ return false;
161813
+ const initializer = candidate.value;
161814
+ if (initializer && isAncestor(initializer, node))
161815
+ return true;
161816
+ const header = candidate;
161817
+ if (typeof header.name === "string" && header.name.length > 0)
161818
+ return false;
161819
+ for (const part of [
161820
+ ...header.preRelationships ?? [],
161821
+ ...header.relationships ?? [],
161822
+ ...header.typing ? [header.typing] : []
161823
+ ]) {
161824
+ if (isAncestor(part, node))
161825
+ return true;
161826
+ }
161827
+ return false;
161802
161828
  }
161803
161829
  function lastSegment(path10) {
161804
161830
  return path10.split(/::|\./u).pop() ?? path10;
@@ -161872,7 +161898,8 @@ var FeaturePathResolver = class {
161872
161898
  let current2 = this.resolveRoot(node, segments[0].text, snapshot);
161873
161899
  this.applyTarget(segments[0], current2);
161874
161900
  if (!current2.node && !current2.description) {
161875
- return { segments, indeterminateIndex: 0 };
161901
+ const under = node.$type === "Relationship" || node.$type === "LeadingRelationship" ? node : void 0;
161902
+ return this.lexicalInventoryComplete(node, snapshot, under) ? { segments, unresolvedIndex: 0 } : { segments, indeterminateIndex: 0 };
161876
161903
  }
161877
161904
  for (let index2 = 1; index2 < segments.length; index2 += 1) {
161878
161905
  const segment = segments[index2];
@@ -162025,12 +162052,77 @@ var FeaturePathResolver = class {
162025
162052
  }
162026
162053
  }
162027
162054
  for (let owner = node.$container; owner; owner = owner.$container) {
162055
+ const declaredName2 = owner.name;
162056
+ if (typeof declaredName2 === "string" && canonicalEscapedName(declaredName2) === name && !isSelfReference(owner, node)) {
162057
+ return this.targetForNode(owner, this.memberInventoryKnown(owner, snapshot));
162058
+ }
162059
+ if (boundVariableName(owner) === name)
162060
+ return this.targetForNode(owner, true);
162028
162061
  const local = directNamedChildren(owner).find((candidate) => nameOf(candidate) === name && !isSelfReference(candidate, node));
162029
162062
  if (local)
162030
162063
  return this.targetForNode(local, this.memberInventoryKnown(local, snapshot));
162064
+ for (const inheritedOwner of this.typedAndSpecializedOwners(owner, snapshot)) {
162065
+ const inherited = directNamedChildren(inheritedOwner).find((candidate) => nameOf(candidate) === name && !isSelfReference(candidate, node));
162066
+ if (inherited) {
162067
+ return this.targetForNode(inherited, this.memberInventoryKnown(inherited, snapshot));
162068
+ }
162069
+ }
162031
162070
  }
162032
162071
  return this.targetFromDescriptions(snapshot.byName.get(name), node);
162033
162072
  }
162073
+ // REQ-317 — issue #259. Whether the scope chain around `node` has a member
162074
+ // inventory this resolver can enumerate COMPLETELY. A type or supertype it
162075
+ // could not resolve carries members it cannot list, so a name missing from
162076
+ // what it can see is then no proof the name is absent, and reporting it
162077
+ // would be a false positive rather than a diagnosis.
162078
+ //
162079
+ // `under` is the relationship whose own target is being resolved. It is the
162080
+ // claim under test, so it must not also count as evidence that the scope is
162081
+ // unknowable — otherwise every unresolved target would silence the very
162082
+ // check that should report it.
162083
+ lexicalInventoryComplete(node, snapshot, under) {
162084
+ for (let owner = node.$container; owner; owner = owner.$container) {
162085
+ if (this.inheritsImplicitly(owner, snapshot, under))
162086
+ return false;
162087
+ if (!this.declaredTypesResolve(owner, snapshot, under))
162088
+ return false;
162089
+ for (const inheritedOwner of this.typedAndSpecializedOwners(owner, snapshot)) {
162090
+ if (!this.declaredTypesResolve(inheritedOwner, snapshot, under))
162091
+ return false;
162092
+ }
162093
+ }
162094
+ return true;
162095
+ }
162096
+ // issue #259 — OMG SysML gives a case its single `objective` and `subject`,
162097
+ // so a usage of a typed case IMPLICITLY redefines the one its definition
162098
+ // declares, whatever either is named, and inherits that one's members
162099
+ // (`verify vehicleMassRequirement :>> massRequirement` reaches
162100
+ // `massRequirement` through exactly that). This resolver does not evaluate
162101
+ // implicit redefinition, so where one applies it cannot enumerate the scope
162102
+ // and must not call a name absent.
162103
+ inheritsImplicitly(node, snapshot, under) {
162104
+ if (node.$type !== "ObjectiveDecl" && node.$type !== "SubjectDecl")
162105
+ return false;
162106
+ if (this.typedAndSpecializedOwners(node, snapshot).length > 0)
162107
+ return false;
162108
+ const owner = node.$container;
162109
+ return !!owner && (this.typedAndSpecializedOwners(owner, snapshot).length > 0 || !this.declaredTypesResolve(owner, snapshot, under));
162110
+ }
162111
+ // Every type and specialization target this element WRITES resolves to a node
162112
+ // whose own members are readable. An unresolved one is an unknown inventory.
162113
+ declaredTypesResolve(node, snapshot, under) {
162114
+ const record = node;
162115
+ if (record.typing?.type?.$refText && !this.typingTarget(node, snapshot))
162116
+ return false;
162117
+ const declared = [
162118
+ ...record.preRelationships ?? [],
162119
+ ...record.relationships ?? []
162120
+ ].filter((relation) => relation !== under && relation.kind && SPECIALIZATION_KINDS.has(relation.kind));
162121
+ if (declared.length === 0)
162122
+ return true;
162123
+ const written = declared.reduce((total, relation) => total + (relation.targets?.length ?? 0), 0);
162124
+ return this.specializationTargets(node, snapshot).length >= written;
162125
+ }
162034
162126
  resolveChild(current2, name, segments, index2, snapshot) {
162035
162127
  const owner = this.followAlias(current2, snapshot);
162036
162128
  if (owner.node) {
@@ -165304,16 +165396,16 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
165304
165396
  };
165305
165397
  const performedActions = depth < 8 && !(typeQ !== void 0 && seenTypes.has(typeQ)) ? effectiveMembersOf(part).filter((m) => m.$type === "PerformStmt" && !!nameOf2(m)).map((act) => {
165306
165398
  const pinSource = this.performTargetOf(act, index2) ?? act;
165307
- const pathSegments2 = this.isAnonymousBehaviorReference(act) ? this.featurePaths.resolveDeclarationPath(act).segments.map((segment) => segment.text) : [nameOf2(act)];
165399
+ const pathSegments3 = this.isAnonymousBehaviorReference(act) ? this.featurePaths.resolveDeclarationPath(act).segments.map((segment) => segment.text) : [nameOf2(act)];
165308
165400
  return {
165309
165401
  act,
165310
165402
  pinSource,
165311
- pathSegments: pathSegments2,
165312
- name: pathSegments2.at(-1) ?? nameOf2(act),
165403
+ pathSegments: pathSegments3,
165404
+ name: pathSegments3.at(-1) ?? nameOf2(act),
165313
165405
  key: concretePerformPath(act, pinSource)
165314
165406
  };
165315
165407
  }).filter((entry, i, list) => list.findIndex((other) => other.key === entry.key) === i) : [];
165316
- const performedActionInfos = performedActions.map(({ act, pinSource, pathSegments: pathSegments2, name, key }) => {
165408
+ const performedActionInfos = performedActions.map(({ act, pinSource, pathSegments: pathSegments3, name, key }) => {
165317
165409
  const id2 = `${instanceId}::__perform_${key}`;
165318
165410
  const inheritedFromDefinition = !!localUsage && !isAstDescendantOrSelf(act, localUsage);
165319
165411
  const syncDeclaration2 = this.synchronizationDeclarationOf(act, index2);
@@ -165321,7 +165413,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
165321
165413
  act,
165322
165414
  name,
165323
165415
  id: id2,
165324
- pathSegments: pathSegments2,
165416
+ pathSegments: pathSegments3,
165325
165417
  pins: this.actionPinPorts(pinSource, id2, index2, uri),
165326
165418
  meta: {
165327
165419
  ...ivEditMeta(act, id2, void 0, localUsage, [...localPath, name], uri),
@@ -171433,7 +171525,6 @@ var SysmlFoldingRangeProvider = class extends DefaultFoldingRangeProvider {
171433
171525
  continue;
171434
171526
  }
171435
171527
  let groupStart = -1;
171436
- let groupEnd = -1;
171437
171528
  let startLine = -1;
171438
171529
  let endLine = -1;
171439
171530
  const flushGroup = () => {
@@ -171445,7 +171536,6 @@ var SysmlFoldingRangeProvider = class extends DefaultFoldingRangeProvider {
171445
171536
  });
171446
171537
  }
171447
171538
  groupStart = -1;
171448
- groupEnd = -1;
171449
171539
  startLine = -1;
171450
171540
  endLine = -1;
171451
171541
  };
@@ -171457,7 +171547,6 @@ var SysmlFoldingRangeProvider = class extends DefaultFoldingRangeProvider {
171457
171547
  groupStart = i;
171458
171548
  startLine = range.start.line;
171459
171549
  }
171460
- groupEnd = i;
171461
171550
  endLine = range.end.line;
171462
171551
  } else {
171463
171552
  flushGroup();
@@ -174812,7 +174901,7 @@ function evaluateFilterCondition(condition, element, options) {
174812
174901
  return value.kind === "boolean" ? value.value : void 0;
174813
174902
  }
174814
174903
  function extensionFor(ctx) {
174815
- const ext = (node, evaluate2) => {
174904
+ const ext = (node, _evaluate) => {
174816
174905
  switch (node.$type) {
174817
174906
  case "SelfClassifyExpr":
174818
174907
  return classify(node, ctx);
@@ -175974,6 +176063,22 @@ var ConformanceModel = class {
175974
176063
  };
175975
176064
 
175976
176065
  // ../language-server/out/src/services/validator.js
176066
+ var REDEFINITION_KINDS2 = /* @__PURE__ */ new Set([
176067
+ ":>>",
176068
+ "redefines",
176069
+ ":>",
176070
+ "subsets",
176071
+ "specializes"
176072
+ ]);
176073
+ function isBoundReferencePart(node) {
176074
+ let declaration = node.$container;
176075
+ while (declaration && !isPartDecl(declaration))
176076
+ declaration = declaration.$container;
176077
+ if (!declaration)
176078
+ return false;
176079
+ const modifiers2 = declaration.modifiers ?? [];
176080
+ return modifiers2.includes("ref");
176081
+ }
175977
176082
  var severityOverrides = {};
175978
176083
  function severity(code, defaultSeverity) {
175979
176084
  return severityOverrides[code] ?? defaultSeverity;
@@ -176172,15 +176277,11 @@ var SysmlValidator = class _SysmlValidator {
176172
176277
  // dispatches `checkPathExpr`, so without a shared decision the two would drift
176173
176278
  // and a body would quietly escape a diagnostic the surrounding model receives.
176174
176279
  featurePathFault(node) {
176175
- let declaration = node.$container;
176176
- while (declaration && !isPartDecl(declaration))
176177
- declaration = declaration.$container;
176178
- const modifiers2 = declaration?.modifiers ?? [];
176179
- if (!declaration || !modifiers2.includes("ref"))
176180
- return void 0;
176181
176280
  const resolution = this.featurePaths.resolve(node);
176182
176281
  if (resolution.unresolvedIndex === void 0)
176183
176282
  return void 0;
176283
+ if (resolution.unresolvedIndex > 0 && !isBoundReferencePart(node))
176284
+ return void 0;
176184
176285
  const invalid = resolution.segments[resolution.unresolvedIndex];
176185
176286
  return {
176186
176287
  segment: invalid.text,
@@ -176188,6 +176289,28 @@ var SysmlValidator = class _SysmlValidator {
176188
176289
  range: invalid.cst.range
176189
176290
  };
176190
176291
  }
176292
+ // REQ-317 — issue #259. A redefinition or subsetting target is a written path
176293
+ // too (`attribute :>> maxMass`, `attribute other :> maxMass`), and the grammar
176294
+ // stores it as a plain `RelationPath` STRING rather than a Langium
176295
+ // cross-reference, so nothing else can diagnose it either: a target that names
176296
+ // nothing linked silently, and the model kept a relationship to an element that
176297
+ // does not exist.
176298
+ //
176299
+ // Only the ROOT segment is judged, on the same terms `checkPathExpr` uses: the
176300
+ // resolver reports an absent root only when it could enumerate the surrounding
176301
+ // inventory completely. A later segment depends on the KerML semantic model
176302
+ // this resolver does not evaluate.
176303
+ checkRelationshipTargets(node, accept) {
176304
+ if (!node.kind || !REDEFINITION_KINDS2.has(node.kind))
176305
+ return;
176306
+ for (let ordinal = 0; ordinal < node.targets.length; ordinal += 1) {
176307
+ const resolution = this.featurePaths.resolvePropertyPath(node, "targets", ordinal);
176308
+ if (resolution.unresolvedIndex !== 0)
176309
+ continue;
176310
+ const invalid = resolution.segments[0];
176311
+ accept(severity("RES001", "error"), DIAGNOSTIC_MESSAGES.RES001_FEATURE_PATH_SEGMENT(invalid.text, "the current scope"), { node, range: invalid.cst.range, code: "RES001", data: { featurePathSegment: true } });
176312
+ }
176313
+ }
176191
176314
  // REQ-389 — Namespace qualification versus feature chaining in every written path
176192
176315
  // issue #213 — RES019: `::` binds tighter than `.`. Each dot-separated link of
176193
176316
  // a KerML FeatureChain is a complete QualifiedName, and an
@@ -178753,6 +178876,10 @@ ${baseIndent}}`;
178753
178876
  Document: this.checkDocument.bind(this),
178754
178877
  PartDecl: this.checkPartDecl.bind(this),
178755
178878
  PathExpr: this.checkPathExpr.bind(this),
178879
+ // issue #259 — the same absent-name rule on a redefinition or
178880
+ // subsetting target, which is a written path string as well.
178881
+ Relationship: this.checkRelationshipTargets.bind(this),
178882
+ LeadingRelationship: this.checkRelationshipTargets.bind(this),
178756
178883
  // issue #213 — RES019: the `::` vs `.` rule on the reference-form
178757
178884
  // declarations that reach their target through OwnedReferenceSubsetting.
178758
178885
  PerformStmt: this.checkChainSeparators.bind(this),
@@ -180110,9 +180237,13 @@ var SysmlLinker = class extends DefaultLinker {
180110
180237
  // ../language-server/out/src/services/rename-provider.js
180111
180238
  var SysmlRenameProvider = class extends DefaultRenameProvider {
180112
180239
  langiumDocuments;
180240
+ locator;
180241
+ featurePaths;
180113
180242
  constructor(services) {
180114
180243
  super(services);
180115
180244
  this.langiumDocuments = services.shared.workspace.LangiumDocuments;
180245
+ this.locator = services.workspace.AstNodeLocator;
180246
+ this.featurePaths = new FeaturePathResolver(services);
180116
180247
  }
180117
180248
  // REQ-261 — reject a rename request whose cursor resolves to a library
180118
180249
  // declaration: such a symbol has no meaningful "prepare rename" range
@@ -180131,7 +180262,8 @@ var SysmlRenameProvider = class extends DefaultRenameProvider {
180131
180262
  const target = this.resolveDeclarationAt(document2, params.position);
180132
180263
  if (target && isLibraryDocument(ast_utils_exports.getDocument(target)))
180133
180264
  return void 0;
180134
- const edit = await super.rename(document2, { ...params, newName: encodeUnrestrictedName(params.newName) }, cancelToken);
180265
+ const newName = encodeUnrestrictedName(params.newName);
180266
+ const edit = await super.rename(document2, { ...params, newName }, cancelToken);
180135
180267
  if (!edit?.changes)
180136
180268
  return edit;
180137
180269
  const changes = {};
@@ -180141,8 +180273,121 @@ var SysmlRenameProvider = class extends DefaultRenameProvider {
180141
180273
  continue;
180142
180274
  changes[uri] = textEdits;
180143
180275
  }
180276
+ if (target)
180277
+ this.addWrittenPathEdits(changes, target, newName);
180144
180278
  return { ...edit, changes };
180145
180279
  }
180280
+ // issue #255 — the references Langium cannot see. An expression operand
180281
+ // (`require constraint { maxMass > 0 }`) and a redefinition or subsetting
180282
+ // target (`attribute :>> maxMass`) are written as PLAIN PATH STRINGS in the
180283
+ // grammar (PathExpr / RelationPath), not as Langium cross-references, so
180284
+ // `findReferences` reports none of them and a rename left every one of them
180285
+ // spelling the old name.
180286
+ //
180287
+ // They are resolved here the same way go-to-definition resolves them
180288
+ // (`FeaturePathResolver`, the one path-resolution rule in the server), and a
180289
+ // segment is edited ONLY when it resolves to this exact declaration. Matching
180290
+ // by resolution rather than by spelling is what keeps a same-named feature of
180291
+ // another element untouched.
180292
+ // REQ-262 — Rename: workspace edit, library not renamable
180293
+ addWrittenPathEdits(changes, declaration, newName) {
180294
+ const oldName = canonicalEscapedName(declaration.name ?? "");
180295
+ if (!oldName)
180296
+ return;
180297
+ const spelledVerbatim = encodeUnrestrictedName(oldName) === oldName;
180298
+ for (const doc of this.langiumDocuments.all) {
180299
+ if (isLibraryDocument(doc))
180300
+ continue;
180301
+ const root4 = doc.parseResult?.value;
180302
+ if (!root4)
180303
+ continue;
180304
+ if (spelledVerbatim && !doc.textDocument.getText().includes(oldName))
180305
+ continue;
180306
+ const uri = doc.uri.toString();
180307
+ const edits = changes[uri] ?? [];
180308
+ const claimed = new Set(edits.map((edit) => `${edit.range.start.line}:${edit.range.start.character}`));
180309
+ const added = [];
180310
+ for (const segment of this.writtenPathSegments(root4, oldName)) {
180311
+ const resolved = this.resolvedNodeOf(segment);
180312
+ if (!resolved || !this.denotes(resolved, declaration))
180313
+ continue;
180314
+ const key = `${segment.cst.range.start.line}:${segment.cst.range.start.character}`;
180315
+ if (claimed.has(key))
180316
+ continue;
180317
+ claimed.add(key);
180318
+ added.push({ range: segment.cst.range, newText: newName });
180319
+ }
180320
+ if (added.length)
180321
+ changes[uri] = [...edits, ...added];
180322
+ }
180323
+ }
180324
+ // Every written-path segment of one document that SPELLS the old name. The
180325
+ // spelling test comes first because resolving a path is the expensive half.
180326
+ // `FeaturePathResolver` already canonicalises each segment it returns, so the
180327
+ // comparison is against `oldName` directly.
180328
+ *writtenPathSegments(root4, oldName) {
180329
+ const matching = (segments) => segments.filter((segment) => segment.text === oldName);
180330
+ const spellsName = (path10) => !!path10 && pathSegments(path10).some((step) => canonicalEscapedName(step) === oldName);
180331
+ for (const node of [root4, ...ast_utils_exports.streamAllContents(root4)]) {
180332
+ if (isPathExpr(node)) {
180333
+ if (!spellsName(node.path))
180334
+ continue;
180335
+ yield* matching(this.featurePaths.resolve(node).segments);
180336
+ continue;
180337
+ }
180338
+ if (!isRelationship(node) && !isLeadingRelationship(node))
180339
+ continue;
180340
+ for (let ordinal = 0; ordinal < node.targets.length; ordinal += 1) {
180341
+ if (!spellsName(node.targets[ordinal]))
180342
+ continue;
180343
+ yield* matching(this.featurePaths.resolvePropertyPath(node, "targets", ordinal).segments);
180344
+ }
180345
+ }
180346
+ }
180347
+ // An anonymous redefinition (`attribute :>> maxMass = 1500.0;`) declares NO
180348
+ // name of its own — it carries the name of what it redefines. A later
180349
+ // `other :> maxMass` in the same body therefore resolves to that redefinition
180350
+ // rather than to the original declaration, yet it still spells the renamed
180351
+ // name and still has to be rewritten. Follow the redefinition chain, which is
180352
+ // exactly the chain the name itself travels.
180353
+ denotes(node, declaration, seen = /* @__PURE__ */ new Set()) {
180354
+ if (node === declaration)
180355
+ return true;
180356
+ if (seen.has(node))
180357
+ return false;
180358
+ seen.add(node);
180359
+ const own = node.name;
180360
+ if (typeof own === "string" && own.length > 0)
180361
+ return false;
180362
+ const relational = node;
180363
+ for (const relationship of [
180364
+ ...relational.preRelationships ?? [],
180365
+ ...relational.relationships ?? []
180366
+ ]) {
180367
+ if (relationship.kind !== ":>>" && relationship.kind !== "redefines")
180368
+ continue;
180369
+ const targets = relationship.targets ?? [];
180370
+ for (let ordinal = 0; ordinal < targets.length; ordinal += 1) {
180371
+ const segments = this.featurePaths.resolvePropertyPath(relationship, "targets", ordinal).segments;
180372
+ const last2 = segments[segments.length - 1];
180373
+ const resolved = last2 ? this.resolvedNodeOf(last2) : void 0;
180374
+ if (resolved && this.denotes(resolved, declaration, seen))
180375
+ return true;
180376
+ }
180377
+ }
180378
+ return false;
180379
+ }
180380
+ resolvedNodeOf(segment) {
180381
+ if (segment.target)
180382
+ return segment.target;
180383
+ const description = segment.description;
180384
+ if (!description)
180385
+ return void 0;
180386
+ if (description.node)
180387
+ return description.node;
180388
+ const root4 = this.langiumDocuments.getDocument(description.documentUri)?.parseResult.value;
180389
+ return root4 ? this.locator.getAstNode(root4, description.path) : void 0;
180390
+ }
180146
180391
  // Mirrors DefaultRenameProvider's own leaf-node → declaration resolution
180147
180392
  // (langium/src/lsp/rename-provider.ts) so the library check runs against
180148
180393
  // the SAME target prepareRename/rename would otherwise act on.
@@ -180157,6 +180402,39 @@ var SysmlRenameProvider = class extends DefaultRenameProvider {
180157
180402
  return this.references.findDeclaration(leafNode);
180158
180403
  }
180159
180404
  };
180405
+ function pathSegments(path10) {
180406
+ const out = [];
180407
+ let current2 = "";
180408
+ let quoted = false;
180409
+ for (let at = 0; at < path10.length; at += 1) {
180410
+ const ch = path10[at];
180411
+ if (quoted) {
180412
+ current2 += ch;
180413
+ if (ch === "\\" && at + 1 < path10.length) {
180414
+ current2 += path10[at + 1];
180415
+ at += 1;
180416
+ } else if (ch === "'") {
180417
+ quoted = false;
180418
+ }
180419
+ continue;
180420
+ }
180421
+ if (ch === "'") {
180422
+ quoted = true;
180423
+ current2 += ch;
180424
+ } else if (ch === ":" && path10[at + 1] === ":") {
180425
+ out.push(current2);
180426
+ current2 = "";
180427
+ at += 1;
180428
+ } else if (ch === ".") {
180429
+ out.push(current2);
180430
+ current2 = "";
180431
+ } else {
180432
+ current2 += ch;
180433
+ }
180434
+ }
180435
+ out.push(current2);
180436
+ return out;
180437
+ }
180160
180438
 
180161
180439
  // ../language-server/out/src/services/code-action-provider.js
180162
180440
  var import_vscode_languageserver18 = __toESM(require_main4(), 1);
@@ -181583,7 +181861,7 @@ var import_vscode_languageserver20 = __toESM(require_main4(), 1);
181583
181861
  function unquoteName3(name) {
181584
181862
  return name.replace(/^'(.*)'$/u, "$1");
181585
181863
  }
181586
- function pathSegments(path10) {
181864
+ function pathSegments2(path10) {
181587
181865
  const segments = [];
181588
181866
  let current2 = "";
181589
181867
  let quoted = false;
@@ -181611,7 +181889,7 @@ function pathSegments(path10) {
181611
181889
  return segments;
181612
181890
  }
181613
181891
  function simpleNameOf2(name) {
181614
- return pathSegments(name).at(-1) ?? name;
181892
+ return pathSegments2(name).at(-1) ?? name;
181615
181893
  }
181616
181894
  var ELEMENT_SEPARATOR = "\0";
181617
181895
  function elementKey2(description) {
@@ -181621,7 +181899,7 @@ function isDeclaredSpelling(description) {
181621
181899
  const kind = description.derivedKind;
181622
181900
  if (kind === "reexport" || kind === "inherited")
181623
181901
  return false;
181624
- return pathSegments(description.name).length === 1;
181902
+ return pathSegments2(description.name).length === 1;
181625
181903
  }
181626
181904
  var SysmlNameLookup = class {
181627
181905
  shared;
@@ -181958,7 +182236,7 @@ var EXPLICIT_SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([
181958
182236
  "crosses",
181959
182237
  "conjugates"
181960
182238
  ]);
181961
- var REDEFINITION_KINDS2 = /* @__PURE__ */ new Set([":>>", "redefines"]);
182239
+ var REDEFINITION_KINDS3 = /* @__PURE__ */ new Set([":>>", "redefines"]);
181962
182240
  var CONSTANT_CARRYING_KINDS = /* @__PURE__ */ new Set([
181963
182241
  ":>",
181964
182242
  "subsets",
@@ -182353,7 +182631,7 @@ var SysmlInlayHintProvider = class {
182353
182631
  const parameter = mine[index2].node;
182354
182632
  if (!parameter.name || !parameter.$cstNode)
182355
182633
  continue;
182356
- if (allRelationships2(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS2.has(rel2.kind)))
182634
+ if (allRelationships2(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS3.has(rel2.kind)))
182357
182635
  continue;
182358
182636
  const target = theirs[index2].node;
182359
182637
  if (!target.name || target.name === parameter.name)
@@ -182626,7 +182904,7 @@ var SysmlInlayHintProvider = class {
182626
182904
  function effectiveNameHint(node) {
182627
182905
  if (node.name || node.shortName?.name || !node.$cstNode)
182628
182906
  return void 0;
182629
- const redefinition = allRelationships2(node).find((rel2) => rel2.kind && REDEFINITION_KINDS2.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
182907
+ const redefinition = allRelationships2(node).find((rel2) => rel2.kind && REDEFINITION_KINDS3.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
182630
182908
  const target = redefinition?.targets?.[0];
182631
182909
  if (!target)
182632
182910
  return void 0;
@@ -185248,7 +185526,26 @@ function compartmentWidth(node) {
185248
185526
  }
185249
185527
  return w;
185250
185528
  }
185529
+ var RELATIONSHIP_COMPARTMENTS = /* @__PURE__ */ new Set([
185530
+ "connections",
185531
+ "interfaces",
185532
+ "flows",
185533
+ "state transition",
185534
+ "successions"
185535
+ ]);
185536
+ function withoutRelationshipCompartments(carrier) {
185537
+ const comps = carrier.compartments;
185538
+ if (!comps?.some((compartment) => RELATIONSHIP_COMPARTMENTS.has(compartment.title))) return carrier;
185539
+ const kept = comps.filter((compartment) => !RELATIONSHIP_COMPARTMENTS.has(compartment.title));
185540
+ return { ...carrier, compartments: kept.length ? kept : void 0 };
185541
+ }
185542
+ function frameForCanvas(frame2) {
185543
+ return withoutRelationshipCompartments(frame2);
185544
+ }
185251
185545
  function nodeForCanvas(node) {
185546
+ return withoutRelationshipCompartments(nodeBlockForCanvas(node));
185547
+ }
185548
+ function nodeBlockForCanvas(node) {
185252
185549
  if (node.meta?.connectionUsage === true || node.meta?.interfaceUsage === true) {
185253
185550
  const compartments2 = node.compartments?.filter((compartment) => compartment.title === "doc" || compartment.title === "flows");
185254
185551
  return {
@@ -185782,7 +186079,7 @@ function hideExplicitRelationshipBoxes(model, relationship) {
185782
186079
  bindings: explicitRelationshipBindings(usage, model),
185783
186080
  endCount: usage.ports?.length ?? 0
185784
186081
  }));
185785
- const blocksCompaction = ({ usage, endCount }) => (nodeForCanvas(usage).compartments ?? []).some((compartment) => endCount !== 2 || compartment.title !== "flows");
186082
+ const blocksCompaction = ({ usage, endCount }) => (nodeBlockForCanvas(usage).compartments ?? []).some((compartment) => endCount !== 2 || compartment.title !== "flows");
185786
186083
  const retainedIds = new Set(projections.filter((projection2) => blocksCompaction(projection2) || annotatedUsageIds.has(projection2.usage.id) || projection2.endCount < 2 || projection2.bindings.length !== projection2.endCount).map(({ usage }) => usage.id));
185787
186084
  const hiddenIds = /* @__PURE__ */ new Set();
185788
186085
  for (const { usage } of projections) {
@@ -186365,10 +186662,11 @@ function modelToFlow(model, opts) {
186365
186662
  const visualDepth = (frame2) => frameDepth(frame2.id) + (visualPerformerParent.has(frame2.id) ? 1 : 0);
186366
186663
  const orderedFrames = [...frames].sort((a2, b) => visualDepth(a2) - visualDepth(b));
186367
186664
  for (const f of orderedFrames) {
186368
- const natural = frameMinSize(f);
186369
- const featureH = frameFeatureCompartmentHeight(f);
186370
- const frameHeaderHeight = isBehaviorPartitionLane(f) ? performerLaneHeaderHeight(f) : structuredControlHeaderHeight(f);
186371
- const frameBottomHeight = frameBottomCompartmentHeight(f);
186665
+ const canvasFrame = frameForCanvas(f);
186666
+ const natural = frameMinSize(canvasFrame);
186667
+ const featureH = frameFeatureCompartmentHeight(canvasFrame);
186668
+ const frameHeaderHeight = isBehaviorPartitionLane(canvasFrame) ? performerLaneHeaderHeight(canvasFrame) : structuredControlHeaderHeight(canvasFrame);
186669
+ const frameBottomHeight = frameBottomCompartmentHeight(canvasFrame);
186372
186670
  const size = sizeWithOverride(
186373
186671
  natural,
186374
186672
  ov[f.layoutKey ?? f.id],
@@ -186380,7 +186678,7 @@ function modelToFlow(model, opts) {
186380
186678
  position: { x: 0, y: 0 },
186381
186679
  data: {
186382
186680
  kind: model.kind,
186383
- frame: f,
186681
+ frame: canvasFrame,
186384
186682
  layoutKey: f.layoutKey ?? f.id,
186385
186683
  ports: isBehaviorPartitionLane(f) ? [] : assignPortHandles(f.ports, opts.portOverrides),
186386
186684
  w: size.w,
@@ -186422,7 +186720,7 @@ function modelToFlow(model, opts) {
186422
186720
  position: { x: 0, y: 0 },
186423
186721
  data: {
186424
186722
  kind: model.kind,
186425
- frame: boundary,
186723
+ frame: frameForCanvas(boundary),
186426
186724
  layoutKey: boundary.layoutKey ?? boundary.id,
186427
186725
  ports: assignPortHandles(boundary.ports, opts.portOverrides),
186428
186726
  w: size.w,
@@ -203679,7 +203977,6 @@ function PortGlyph({ ph, w, h, topReserve = 0, showLabels, selected: selected2,
203679
203977
  const x = rect.cx;
203680
203978
  const y = rect.cy;
203681
203979
  const half = rect.across / 2;
203682
- const size = rect.across;
203683
203980
  const d = ph.port.direction;
203684
203981
  const v = ph.side === "top" ? { x: 0, y: -1 } : ph.side === "bottom" ? { x: 0, y: 1 } : ph.side === "left" ? { x: -1, y: 0 } : { x: 1, y: 0 };
203685
203982
  const perp = { x: -v.y, y: v.x };
@@ -205182,7 +205479,7 @@ async function runExport(command) {
205182
205479
  }
205183
205480
 
205184
205481
  // src/main.ts
205185
- var VERSION2 = true ? "0.28.0" : "dev";
205482
+ var VERSION2 = true ? "0.28.1" : "dev";
205186
205483
  function display(file) {
205187
205484
  const rel2 = path9.relative(process.cwd(), file);
205188
205485
  return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;