sysml-diagram 0.28.1 → 0.29.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
@@ -162052,8 +162052,8 @@ var FeaturePathResolver = class {
162052
162052
  }
162053
162053
  }
162054
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)) {
162055
+ const declaredName3 = owner.name;
162056
+ if (typeof declaredName3 === "string" && canonicalEscapedName(declaredName3) === name && !isSelfReference(owner, node)) {
162057
162057
  return this.targetForNode(owner, this.memberInventoryKnown(owner, snapshot));
162058
162058
  }
162059
162059
  if (boundVariableName(owner) === name)
@@ -162433,6 +162433,377 @@ function memberSeparator(owner) {
162433
162433
  return isDocument(owner) || isNamespaceOnlyDecl(owner) ? "::" : ".";
162434
162434
  }
162435
162435
 
162436
+ // ../language-server/out/src/services/name-lookup.js
162437
+ function unquoteName(name) {
162438
+ return name.replace(/^'(.*)'$/u, "$1");
162439
+ }
162440
+ function pathSegments(path10) {
162441
+ const segments = [];
162442
+ let current2 = "";
162443
+ let quoted = false;
162444
+ for (let index2 = 0; index2 < path10.length; index2++) {
162445
+ const char = path10[index2];
162446
+ if (char === "'") {
162447
+ quoted = !quoted;
162448
+ current2 += char;
162449
+ continue;
162450
+ }
162451
+ if (!quoted && char === ":" && path10[index2 + 1] === ":") {
162452
+ segments.push(current2);
162453
+ current2 = "";
162454
+ index2++;
162455
+ continue;
162456
+ }
162457
+ if (!quoted && char === ".") {
162458
+ segments.push(current2);
162459
+ current2 = "";
162460
+ continue;
162461
+ }
162462
+ current2 += char;
162463
+ }
162464
+ segments.push(current2);
162465
+ return segments;
162466
+ }
162467
+ function simpleNameOf(name) {
162468
+ return pathSegments(name).at(-1) ?? name;
162469
+ }
162470
+ var ELEMENT_SEPARATOR = "\0";
162471
+ function elementKey(description) {
162472
+ return `${description.documentUri.toString()}${ELEMENT_SEPARATOR}${description.path}`;
162473
+ }
162474
+ function isDeclaredSpelling(description) {
162475
+ const kind = description.derivedKind;
162476
+ if (kind === "reexport" || kind === "inherited")
162477
+ return false;
162478
+ return pathSegments(description.name).length === 1;
162479
+ }
162480
+ var SysmlNameLookup = class {
162481
+ shared;
162482
+ byName;
162483
+ /** Element key → the declared spellings the index holds for that element. */
162484
+ spellings;
162485
+ constructor(shared) {
162486
+ this.shared = shared;
162487
+ this.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, () => {
162488
+ this.byName = void 0;
162489
+ this.spellings = void 0;
162490
+ });
162491
+ }
162492
+ /** Every description indexed under `name`, in either spelling of an escaped name. */
162493
+ descriptions(name) {
162494
+ return this.index().get(name) ?? [];
162495
+ }
162496
+ /**
162497
+ * The ONE element `name` names, or `undefined` when the answer is not
162498
+ * certain: no element, or more than one. `accept` narrows the candidates
162499
+ * before ambiguity is judged, so "the only CALLABLE called `f`" is a
162500
+ * decidable question even where a part shares the name.
162501
+ */
162502
+ unique(name, accept) {
162503
+ const candidates = this.descriptions(name).filter((candidate) => !accept || accept(candidate));
162504
+ let found;
162505
+ let key;
162506
+ for (const candidate of candidates) {
162507
+ const candidateKey = elementKey(candidate);
162508
+ if (found === void 0) {
162509
+ found = candidate;
162510
+ key = candidateKey;
162511
+ continue;
162512
+ }
162513
+ if (candidateKey !== key)
162514
+ return void 0;
162515
+ }
162516
+ return found;
162517
+ }
162518
+ /**
162519
+ * Resolve a written path: the spelling the index holds verbatim first, then
162520
+ * its final segment. Both readings must name exactly one element.
162521
+ */
162522
+ uniqueForPath(path10, accept) {
162523
+ return this.unique(path10, accept) ?? this.unique(simpleNameOf(path10), accept);
162524
+ }
162525
+ /**
162526
+ * The declared spellings of the element `description` names — its regular
162527
+ * name and its `<short>` name — minus `written`.
162528
+ */
162529
+ otherNames(description, written) {
162530
+ const all = this.spellingIndex().get(elementKey(description)) ?? [];
162531
+ const seen = unquoteName(written);
162532
+ return all.filter((name) => unquoteName(name) !== seen);
162533
+ }
162534
+ index() {
162535
+ if (!this.byName)
162536
+ this.build();
162537
+ return this.byName;
162538
+ }
162539
+ spellingIndex() {
162540
+ if (!this.spellings)
162541
+ this.build();
162542
+ return this.spellings;
162543
+ }
162544
+ /** One pass over the index feeds both maps; neither is worth a second. */
162545
+ build() {
162546
+ const byName = /* @__PURE__ */ new Map();
162547
+ const spellings = /* @__PURE__ */ new Map();
162548
+ const add = (key, description) => {
162549
+ const bucket = byName.get(key);
162550
+ if (bucket)
162551
+ bucket.push(description);
162552
+ else
162553
+ byName.set(key, [description]);
162554
+ };
162555
+ for (const description of this.shared.workspace.IndexManager.allElements()) {
162556
+ add(description.name, description);
162557
+ const unquoted = unquoteName(description.name);
162558
+ if (unquoted !== description.name)
162559
+ add(unquoted, description);
162560
+ if (!isDeclaredSpelling(description))
162561
+ continue;
162562
+ const key = elementKey(description);
162563
+ const names = spellings.get(key);
162564
+ if (names) {
162565
+ if (!names.includes(description.name))
162566
+ names.push(description.name);
162567
+ } else {
162568
+ spellings.set(key, [description.name]);
162569
+ }
162570
+ }
162571
+ this.byName = byName;
162572
+ this.spellings = spellings;
162573
+ }
162574
+ };
162575
+ var lookups = /* @__PURE__ */ new WeakMap();
162576
+ function nameLookupFor(shared) {
162577
+ if (!shared)
162578
+ return void 0;
162579
+ const existing = lookups.get(shared);
162580
+ if (existing)
162581
+ return existing;
162582
+ const created = new SysmlNameLookup(shared);
162583
+ lookups.set(shared, created);
162584
+ return created;
162585
+ }
162586
+
162587
+ // ../language-server/out/src/services/effective-name.js
162588
+ var REDEFINITION_KINDS = /* @__PURE__ */ new Set([":>>", "redefines"]);
162589
+ var NO_CANDIDATES = [];
162590
+ var NO_RESOLVER = () => NO_CANDIDATES;
162591
+ var nameable = /* @__PURE__ */ new Map();
162592
+ function canBeNamed(node) {
162593
+ const known2 = nameable.get(node.$type);
162594
+ if (known2 !== void 0)
162595
+ return known2;
162596
+ let answer = false;
162597
+ try {
162598
+ answer = reflection2.getTypeMetaData(node.$type).properties.some((property3) => property3.name === "name");
162599
+ } catch {
162600
+ answer = false;
162601
+ }
162602
+ nameable.set(node.$type, answer);
162603
+ return answer;
162604
+ }
162605
+ function declaredName(node) {
162606
+ const value = node.name;
162607
+ return typeof value === "string" && value.length > 0 ? value : void 0;
162608
+ }
162609
+ function declaredShortName(node) {
162610
+ const value = node.shortName?.name;
162611
+ return typeof value === "string" && value.length > 0 ? value : void 0;
162612
+ }
162613
+ function firstRedefinitionPath(node) {
162614
+ const decl = node;
162615
+ const groups = [decl.preRelationships, decl.relationships];
162616
+ for (const group of groups) {
162617
+ if (!Array.isArray(group))
162618
+ continue;
162619
+ for (const relationship of group) {
162620
+ if (typeof relationship?.kind !== "string")
162621
+ continue;
162622
+ if (!REDEFINITION_KINDS.has(relationship.kind))
162623
+ continue;
162624
+ const targets = relationship.targets;
162625
+ if (!Array.isArray(targets))
162626
+ continue;
162627
+ for (const target of targets) {
162628
+ if (typeof target === "string" && target.length > 0)
162629
+ return target;
162630
+ }
162631
+ }
162632
+ }
162633
+ return void 0;
162634
+ }
162635
+ function writtenNameOf(path10) {
162636
+ const segment = simpleNameOf(path10).replace(/\s*\[[^\]]*\]\s*$/u, "").trim();
162637
+ return segment.length > 0 ? segment : void 0;
162638
+ }
162639
+ var memos = /* @__PURE__ */ new WeakMap();
162640
+ function memoFor(resolver) {
162641
+ const existing = memos.get(resolver);
162642
+ if (existing)
162643
+ return existing;
162644
+ const created = /* @__PURE__ */ new WeakMap();
162645
+ memos.set(resolver, created);
162646
+ return created;
162647
+ }
162648
+ function effectiveNamesOf(node, resolver = NO_RESOLVER) {
162649
+ const memo3 = memoFor(resolver);
162650
+ const cached = memo3.get(node);
162651
+ if (cached)
162652
+ return cached;
162653
+ const computed = derive(node, resolver, /* @__PURE__ */ new Set());
162654
+ memo3.set(node, computed);
162655
+ return computed;
162656
+ }
162657
+ function derive(node, resolver, seen) {
162658
+ const name = declaredName(node);
162659
+ const shortName = declaredShortName(node);
162660
+ if (name !== void 0 || shortName !== void 0) {
162661
+ return { name, shortName, origin: "declared" };
162662
+ }
162663
+ const path10 = canBeNamed(node) ? firstRedefinitionPath(node) : void 0;
162664
+ if (path10 === void 0)
162665
+ return { origin: "none" };
162666
+ if (seen.has(node))
162667
+ return { origin: "none", redefines: path10, problem: "cycle" };
162668
+ seen.add(node);
162669
+ try {
162670
+ const inherited = resolveNames(path10, node, resolver, seen);
162671
+ if (inherited?.problem) {
162672
+ return { origin: "none", redefines: path10, problem: inherited.problem };
162673
+ }
162674
+ if (inherited?.name !== void 0 || inherited?.shortName !== void 0) {
162675
+ return {
162676
+ name: inherited.name,
162677
+ shortName: inherited.shortName,
162678
+ origin: "derived",
162679
+ redefines: path10
162680
+ };
162681
+ }
162682
+ const written = writtenNameOf(path10);
162683
+ return written === void 0 ? { origin: "none", redefines: path10 } : { name: written, origin: "written", redefines: path10 };
162684
+ } finally {
162685
+ seen.delete(node);
162686
+ }
162687
+ }
162688
+ function resolveNames(path10, from, resolver, seen) {
162689
+ const candidates = resolver(path10, from);
162690
+ if (candidates.length === 0)
162691
+ return void 0;
162692
+ let names;
162693
+ for (const candidate of candidates) {
162694
+ const resolved = candidate.node ? derive(candidate.node, resolver, seen) : { name: candidate.name, shortName: candidate.shortName, origin: "declared" };
162695
+ if (resolved.problem)
162696
+ return resolved;
162697
+ if (resolved.name === void 0 && resolved.shortName === void 0)
162698
+ continue;
162699
+ if (!names) {
162700
+ names = resolved;
162701
+ continue;
162702
+ }
162703
+ if (differ(names.name, resolved.name) || differ(names.shortName, resolved.shortName)) {
162704
+ return { origin: "none", problem: "ambiguous" };
162705
+ }
162706
+ names = {
162707
+ name: names.name ?? resolved.name,
162708
+ shortName: names.shortName ?? resolved.shortName,
162709
+ origin: names.origin
162710
+ };
162711
+ }
162712
+ return names;
162713
+ }
162714
+ function differ(left, right) {
162715
+ return left !== void 0 && right !== void 0 && left !== right;
162716
+ }
162717
+ var localResolvers = /* @__PURE__ */ new WeakMap();
162718
+ function documentLocalResolver(root4) {
162719
+ const existing = localResolvers.get(root4);
162720
+ if (existing)
162721
+ return existing;
162722
+ let index2;
162723
+ const resolver = (path10, from) => {
162724
+ index2 ??= buildLocalNameIndex(root4);
162725
+ const simple = writtenNameOf(path10) ?? path10;
162726
+ const declared = index2.declared.qualified.get(path10) ?? index2.declared.simple.get(simple);
162727
+ const found = declared?.filter((candidate) => candidate !== from) ?? [];
162728
+ if (found.length > 0)
162729
+ return found.map((node) => ({ node }));
162730
+ if (path10 === simple)
162731
+ return NO_CANDIDATES;
162732
+ const nested = index2.effective.qualified.get(path10)?.filter((candidate) => candidate !== from);
162733
+ return nested && nested.length > 0 ? nested.map((node) => ({ node })) : NO_CANDIDATES;
162734
+ };
162735
+ localResolvers.set(root4, resolver);
162736
+ return resolver;
162737
+ }
162738
+ function localResolverFor(node) {
162739
+ return documentLocalResolver(ast_utils_exports.findRootNode(node));
162740
+ }
162741
+ function emptyTier() {
162742
+ return { qualified: /* @__PURE__ */ new Map(), simple: /* @__PURE__ */ new Map() };
162743
+ }
162744
+ function buildLocalNameIndex(root4) {
162745
+ const index2 = { declared: emptyTier(), effective: emptyTier() };
162746
+ const add = (map3, key, node) => {
162747
+ const bucket = map3.get(key);
162748
+ if (bucket) {
162749
+ if (!bucket.includes(node))
162750
+ bucket.push(node);
162751
+ } else {
162752
+ map3.set(key, [node]);
162753
+ }
162754
+ };
162755
+ for (const node of ast_utils_exports.streamAllContents(root4)) {
162756
+ if (node.$type === "ShortName" || node.$type === "ImportSeg")
162757
+ continue;
162758
+ const declared = [declaredName(node), declaredShortName(node)].filter((value) => value !== void 0);
162759
+ const written = declared.length === 0 && canBeNamed(node) ? writtenNameOf(firstRedefinitionPath(node) ?? "") : void 0;
162760
+ const tier = declared.length > 0 ? index2.declared : index2.effective;
162761
+ for (const name of declared.length > 0 ? declared : [written].filter((v) => v !== void 0)) {
162762
+ add(tier.simple, name, node);
162763
+ for (const path10 of qualifiedPathsOf(node, name))
162764
+ add(tier.qualified, path10, node);
162765
+ }
162766
+ }
162767
+ return index2;
162768
+ }
162769
+ function qualifiedPathsOf(node, name) {
162770
+ const owners = [];
162771
+ for (let owner = node.$container; owner; owner = owner.$container) {
162772
+ const ownerName = declaredName(owner) ?? declaredShortName(owner);
162773
+ if (ownerName !== void 0)
162774
+ owners.unshift(ownerName);
162775
+ }
162776
+ const paths = [];
162777
+ for (let start2 = 0; start2 < owners.length; start2++) {
162778
+ paths.push([...owners.slice(start2), name].join("::"));
162779
+ }
162780
+ return paths;
162781
+ }
162782
+ function indexResolver(lookup, astNode) {
162783
+ if (!lookup)
162784
+ return void 0;
162785
+ return (path10) => {
162786
+ const description = lookup.uniqueForPath(path10);
162787
+ if (!description)
162788
+ return NO_CANDIDATES;
162789
+ const node = description.node ?? astNode?.(description);
162790
+ return node ? [{ node }] : NO_CANDIDATES;
162791
+ };
162792
+ }
162793
+ function chainResolvers(...resolvers) {
162794
+ const active = resolvers.filter((resolver) => !!resolver);
162795
+ if (active.length === 1)
162796
+ return active[0];
162797
+ return (path10, from) => {
162798
+ for (const resolver of active) {
162799
+ const found = resolver(path10, from);
162800
+ if (found.length > 0)
162801
+ return found;
162802
+ }
162803
+ return NO_CANDIDATES;
162804
+ };
162805
+ }
162806
+
162436
162807
  // ../language-server/out/src/services/diagram-model-provider.js
162437
162808
  var lastSeg = (name) => {
162438
162809
  const i = Math.max(name.lastIndexOf("::"), name.lastIndexOf("."));
@@ -162820,18 +163191,11 @@ var portionKindOf = (node) => modifiersOf(node).find((m) => m === "timeslice" ||
162820
163191
  var isIndividualOccurrence = (node) => modifiersOf(node).includes("individual");
162821
163192
  var isOccurrenceModified = (node) => portionKindOf(node) !== void 0 || isIndividualOccurrence(node);
162822
163193
  var redefinedNameOf = (node) => {
162823
- const n2 = node;
162824
- for (const rel2 of [...n2.preRelationships ?? [], ...n2.relationships ?? []]) {
162825
- if (rel2.kind === ":>>" || rel2.kind === "redefines") {
162826
- const target = (rel2.targets ?? [])[0];
162827
- if (target)
162828
- return lastSeg(target);
162829
- }
162830
- }
162831
- return void 0;
163194
+ const names = effectiveNamesOf(node, localResolverFor(node));
163195
+ return names.origin === "derived" || names.origin === "written" ? names.name ?? names.shortName : void 0;
162832
163196
  };
162833
163197
  var effectiveNameOf = (node) => nameOf2(node) ?? redefinedNameOf(node);
162834
- var portionLabelOf = (node) => nameOf2(node) ?? (isOccurrenceModified(node) ? redefinedNameOf(node) : void 0);
163198
+ var portionLabelOf = (node) => effectiveNameOf(node);
162835
163199
  function diagramNodeId(node) {
162836
163200
  const name = nameOf2(node);
162837
163201
  if (name)
@@ -166878,10 +167242,10 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
166878
167242
  };
166879
167243
  const emitFlowNode = (m, frameId, executionContext, occurrence, laneParts) => {
166880
167244
  const info = flowNodeInfo(m);
166881
- const declaredName2 = localFlowName(m);
167245
+ const declaredName3 = localFlowName(m);
166882
167246
  const id2 = occurrence;
166883
167247
  idByNode.set(m, id2);
166884
- registerStep(occurrence, id2, [declaredName2]);
167248
+ registerStep(occurrence, id2, [declaredName3]);
166885
167249
  if (info.shape === "action" || info.shape === "send" || info.shape === "accept")
166886
167250
  actionCount++;
166887
167251
  const pins = actionPinsOf(m, id2);
@@ -166913,9 +167277,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
166913
167277
  source: sourceOf2(m, uri),
166914
167278
  meta: {
166915
167279
  ...occurrenceEditMeta(occurrence),
166916
- ...declaredName2 ? {
166917
- declarationId: qnameOf(m) || declaredName2,
166918
- declarationName: declaredName2,
167280
+ ...declaredName3 ? {
167281
+ declarationId: qnameOf(m) || declaredName3,
167282
+ declarationName: declaredName3,
166919
167283
  declarationSource: sourceOf2(m, uri)
166920
167284
  } : {},
166921
167285
  ...isPromotablePerform(m) ? { promotablePerform: true } : {},
@@ -167027,9 +167391,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167027
167391
  return;
167028
167392
  }
167029
167393
  const id2 = occurrence;
167030
- const declaredName2 = localFlowName(action);
167394
+ const declaredName3 = localFlowName(action);
167031
167395
  idByNode.set(action, id2);
167032
- registerStep(occurrence, id2, [declaredName2]);
167396
+ registerStep(occurrence, id2, [declaredName3]);
167033
167397
  if (content !== action) {
167034
167398
  idByNode.set(content, id2);
167035
167399
  if (isPartDecl(this.declaringOwnerOf(action)) && nameOf2(content)) {
@@ -167044,7 +167408,7 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167044
167408
  registerPins(action, id2, pins, false);
167045
167409
  frames.push({
167046
167410
  id: id2,
167047
- label: declaredName2 ?? (action.$type === "PerformStmt" ? performLabel(action) : lastSeg(id2)),
167411
+ label: declaredName3 ?? (action.$type === "PerformStmt" ? performLabel(action) : lastSeg(id2)),
167048
167412
  keyword: keywordFor(action),
167049
167413
  parent: parentFrameId,
167050
167414
  isDef: action.isDef === true,
@@ -167056,9 +167420,9 @@ var SysmlDiagramModelProvider = class _SysmlDiagramModelProvider {
167056
167420
  meta: {
167057
167421
  compositeAction: true,
167058
167422
  ...isPromotablePerform(action) ? { promotablePerform: true } : {},
167059
- ...declaredName2 ? {
167060
- declarationId: qnameOf(action) || declaredName2,
167061
- declarationName: declaredName2,
167423
+ ...declaredName3 ? {
167424
+ declarationId: qnameOf(action) || declaredName3,
167425
+ declarationName: declaredName3,
167062
167426
  declarationSource: sourceOf2(action, uri)
167063
167427
  } : {},
167064
167428
  // REQ-196 — the body a lane added here writes its `perform` against.
@@ -171174,7 +171538,7 @@ function outlineGroupForType(astType) {
171174
171538
 
171175
171539
  // ../language-server/out/src/services/document-symbol-provider.js
171176
171540
  var SPECIALIZATION_KINDS2 = /* @__PURE__ */ new Set([":>", "specializes"]);
171177
- var REDEFINITION_KINDS = /* @__PURE__ */ new Set([":>>", "redefines"]);
171541
+ var REDEFINITION_KINDS2 = /* @__PURE__ */ new Set([":>>", "redefines"]);
171178
171542
  var INHERITABLE_FEATURE_TYPES = /* @__PURE__ */ new Set([
171179
171543
  "ActionDecl",
171180
171544
  "AttributeDecl",
@@ -171215,7 +171579,10 @@ function symbolNameFor(node) {
171215
171579
  return "rep";
171216
171580
  }
171217
171581
  const redefined = redefinitionTargets(node)[0];
171218
- return redefined ? `:>> ${lastNameSegment(redefined)}` : void 0;
171582
+ if (!redefined)
171583
+ return void 0;
171584
+ const effective = effectiveNamesOf(node, localResolverFor(node));
171585
+ return `:>> ${effective.name ?? effective.shortName ?? lastNameSegment(redefined)}`;
171219
171586
  }
171220
171587
  function isDefinitionNode2(node) {
171221
171588
  return node.isDef === true;
@@ -171251,7 +171618,7 @@ function redefinitionTargets(node) {
171251
171618
  const n2 = node;
171252
171619
  const out = [];
171253
171620
  for (const rel2 of [...n2.preRelationships ?? [], ...n2.relationships ?? []]) {
171254
- if (rel2.kind && REDEFINITION_KINDS.has(rel2.kind))
171621
+ if (rel2.kind && REDEFINITION_KINDS2.has(rel2.kind))
171255
171622
  out.push(...rel2.targets ?? []);
171256
171623
  }
171257
171624
  return out;
@@ -171343,6 +171710,11 @@ function locallyDeclaredOrRedefinedFeatureNames(node) {
171343
171710
  for (const target of redefinitionTargets(child)) {
171344
171711
  names.add(lastNameSegment(target));
171345
171712
  }
171713
+ const effective = effectiveNamesOf(child, localResolverFor(child));
171714
+ if (effective.name)
171715
+ names.add(effective.name);
171716
+ if (effective.shortName)
171717
+ names.add(effective.shortName);
171346
171718
  }
171347
171719
  return names;
171348
171720
  }
@@ -171560,11 +171932,22 @@ var SysmlFoldingRangeProvider = class extends DefaultFoldingRangeProvider {
171560
171932
  // ../language-server/out/src/services/name-provider.js
171561
171933
  var SysmlNameProvider = class extends DefaultNameProvider {
171562
171934
  getName(node) {
171563
- return super.getName(node) ?? this.shortNameOf(node);
171935
+ return super.getName(node) ?? this.shortNameOf(node) ?? this.effectiveNameOf(node);
171564
171936
  }
171937
+ /**
171938
+ * REQ-404 — deliberately NOT extended to the effective name. There is no
171939
+ * text to select, and a rename that reported one would offer to edit a name
171940
+ * the declaration never writes.
171941
+ */
171565
171942
  getNameNode(node) {
171566
171943
  return super.getNameNode(node) ?? this.shortNameNodeOf(node);
171567
171944
  }
171945
+ // REQ-404 — one shared derivation (effective-name.ts), resolved against this
171946
+ // document's declarations; the same answer scope computation indexes.
171947
+ effectiveNameOf(node) {
171948
+ const names = effectiveNamesOf(node, localResolverFor(node));
171949
+ return names.origin === "derived" || names.origin === "written" ? names.name ?? names.shortName : void 0;
171950
+ }
171568
171951
  shortNameOf(node) {
171569
171952
  const value = node.shortName?.name;
171570
171953
  return typeof value === "string" && value.length > 0 ? value : void 0;
@@ -171590,21 +171973,21 @@ function getDimensionTable() {
171590
171973
  function isDimensionTableLoaded() {
171591
171974
  return table !== void 0;
171592
171975
  }
171593
- function unquoteName(name) {
171976
+ function unquoteName2(name) {
171594
171977
  return name.replace(/^'(.*)'$/, "$1");
171595
171978
  }
171596
171979
  function lastSegment2(name) {
171597
171980
  const idx = name.lastIndexOf("::");
171598
- return unquoteName(idx >= 0 ? name.slice(idx + 2) : name);
171981
+ return unquoteName2(idx >= 0 ? name.slice(idx + 2) : name);
171599
171982
  }
171600
171983
  function directUnitDimension(symbol) {
171601
171984
  if (!table)
171602
171985
  return void 0;
171603
- const unquoted = unquoteName(symbol);
171986
+ const unquoted = unquoteName2(symbol);
171604
171987
  return table.unitDims[unquoted] ?? table.unitDims[lastSegment2(unquoted)];
171605
171988
  }
171606
171989
  function isDirectKnownUnit(symbol) {
171607
- const unquoted = unquoteName(symbol);
171990
+ const unquoted = unquoteName2(symbol);
171608
171991
  return unitSymbolSet.has(unquoted) || unitSymbolSet.has(lastSegment2(unquoted));
171609
171992
  }
171610
171993
  function unitDimension(symbol) {
@@ -171625,7 +172008,7 @@ function unitQuantityKind(symbol) {
171625
172008
  function unitQuantityKinds(symbol) {
171626
172009
  if (!table)
171627
172010
  return [];
171628
- const unquoted = unquoteName(symbol);
172011
+ const unquoted = unquoteName2(symbol);
171629
172012
  const kinds = table.unitKind[unquoted] ?? table.unitKind[lastSegment2(unquoted)];
171630
172013
  if (Array.isArray(kinds))
171631
172014
  return kinds;
@@ -171692,7 +172075,7 @@ function superscript(n2) {
171692
172075
  return String(n2).split("").map((c) => SUPERSCRIPT[c] ?? c).join("");
171693
172076
  }
171694
172077
  function compoundUnitDimension(symbol) {
171695
- const factors = splitUnitFactors(unquoteName(symbol));
172078
+ const factors = splitUnitFactors(unquoteName2(symbol));
171696
172079
  if (!factors)
171697
172080
  return void 0;
171698
172081
  const parsed = factors.map((factor) => ({ op: factor.op, factor: parseUnitFactor(factor.text) }));
@@ -171828,7 +172211,7 @@ function contextUnitDimension(symbol, ctx) {
171828
172211
  const directLocal = ctx.unitDim?.(lastSegment2(symbol));
171829
172212
  if (directLocal)
171830
172213
  return resultDimension(directLocal);
171831
- const factors = splitUnitFactors(unquoteName(symbol));
172214
+ const factors = splitUnitFactors(unquoteName2(symbol));
171832
172215
  if (!factors || factors.length === 0)
171833
172216
  return void 0;
171834
172217
  let result = {};
@@ -171849,7 +172232,7 @@ function contextUnitDimension(symbol, ctx) {
171849
172232
  function isKnownUnitInContext(symbol, ctx) {
171850
172233
  if (ctx.unitDim?.(lastSegment2(symbol)))
171851
172234
  return true;
171852
- const factors = splitUnitFactors(unquoteName(symbol));
172235
+ const factors = splitUnitFactors(unquoteName2(symbol));
171853
172236
  return !!factors && factors.length > 0 && factors.every((token) => {
171854
172237
  const factor = parseUnitFactor(token.text);
171855
172238
  return !!factor && (!!ctx.unitDim?.(lastSegment2(factor.name)) || isDirectKnownUnit(factor.name));
@@ -172061,7 +172444,7 @@ function isComparison(op) {
172061
172444
  return op === "==" || op === "!=" || op === "===" || op === "!==" || op === "<" || op === ">" || op === "<=" || op === ">=";
172062
172445
  }
172063
172446
  function reportUnknownUnit(node, property3, symbol, ctx) {
172064
- const display2 = unquoteName(symbol);
172447
+ const display2 = unquoteName2(symbol);
172065
172448
  const suggestions = nearestUnits(display2, 3);
172066
172449
  const hint = suggestions.length > 0 ? ` Did you mean ${suggestions.map((s) => `'${s}'`).join(", ")}?` : "";
172067
172450
  ctx.issues.push({
@@ -172308,6 +172691,16 @@ var DIAGNOSTIC_MESSAGES = {
172308
172691
  // there, and rewriting it is mechanical — the import keeps working exactly
172309
172692
  // as it did, since a root import was never re-exported to begin with.
172310
172693
  RES021_ROOT_IMPORT_VISIBILITY: (visibility) => `An import in a file's root namespace must be 'private' \u2014 nothing can import the root namespace, so '${visibility}' re-exports to no one.`,
172694
+ // REQ-404 — issue #155. OMG SysML v2 Part 1 §7.6.5 (Usage Names) derives the
172695
+ // names of an unnamed redefining usage from the feature it redefines. Two
172696
+ // things stop that derivation dead: a chain that comes back to the usage
172697
+ // itself, and a target answered by elements that do not agree on the name.
172698
+ // Neither may be settled by picking one, because the name decides what the
172699
+ // feature IS - what it shadows, what resolves to it, what the diagram draws.
172700
+ // The fix is in the source: give the usage a name of its own, or write the
172701
+ // redefinition target so it names one feature.
172702
+ RES022_EFFECTIVE_NAME_CYCLE: (target) => `This usage declares no name, and the redefinition of '${target}' leads back to it, so it has no name to take. Name the usage, or redefine a feature outside the cycle.`,
172703
+ RES022_EFFECTIVE_NAME_AMBIGUOUS: (target) => `This usage declares no name, and '${target}' is answered by elements with different names, so which name it takes is undecided. Name the usage, or qualify the redefinition target.`,
172311
172704
  // issue #153 — OMG SysML v2 Part 1 §7.5.4 (Filtered Packages) puts an element
172312
172705
  // filter in a package, where it restricts that package's imported memberships;
172313
172706
  // a view body is the one other place it is defined for (it restricts what the
@@ -172620,6 +173013,15 @@ function identificationLabel(node) {
172620
173013
  return `<${shortName}>`;
172621
173014
  return node.name;
172622
173015
  }
173016
+ function effectiveIdentificationLabel(node) {
173017
+ const names = effectiveNamesOf(node, localResolverFor(node));
173018
+ if (names.problem)
173019
+ return void 0;
173020
+ const name = names.name ?? names.shortName;
173021
+ if (!name)
173022
+ return void 0;
173023
+ return names.shortName && names.shortName !== name ? `<${names.shortName}> ${name}` : name;
173024
+ }
172623
173025
  function typingLabel(typing) {
172624
173026
  if (!typing)
172625
173027
  return "";
@@ -172695,7 +173097,7 @@ function declarationLine(node) {
172695
173097
  const named2 = node;
172696
173098
  const dir = directionLabel(node);
172697
173099
  const kind = kindLabel(node);
172698
- const name = identificationLabel(named2) ?? "(anonymous)";
173100
+ const name = identificationLabel(named2) ?? effectiveIdentificationLabel(named2) ?? "(anonymous)";
172699
173101
  const typing = typingLabel(named2.typing);
172700
173102
  const mult = multiplicityLabel(node);
172701
173103
  const rels = relationshipLabel(allRelationships(named2));
@@ -172952,7 +173354,7 @@ function buildHoverMarkdown(node, relationshipDetails, documentation) {
172952
173354
  const named2 = node;
172953
173355
  const dir = directionLabel(node);
172954
173356
  const kind = kindLabel(node);
172955
- const name = identificationLabel(named2) ?? "(anonymous)";
173357
+ const name = identificationLabel(named2) ?? effectiveIdentificationLabel(named2) ?? "(anonymous)";
172956
173358
  const typing = typingLabel(named2.typing);
172957
173359
  const mult = multiplicityLabel(node);
172958
173360
  const multHint = multiplicityPlainEnglish(node);
@@ -174295,7 +174697,7 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
174295
174697
  qualifiedNameFor(desc) {
174296
174698
  if (desc.name.includes("::"))
174297
174699
  return desc.name;
174298
- const candidates = this.qualifiedNamesByElement().get(elementKey(desc));
174700
+ const candidates = this.qualifiedNamesByElement().get(elementKey2(desc));
174299
174701
  return candidates?.find((name) => simpleName(name) === desc.name);
174300
174702
  }
174301
174703
  // REQ-245, REQ-268 — An element's qualified names, shortest first, keyed by
@@ -174311,7 +174713,7 @@ var SysmlCompletionProvider = class extends DefaultCompletionProvider {
174311
174713
  for (const desc of this.indexManager.allElements()) {
174312
174714
  if (!desc.name.includes("::"))
174313
174715
  continue;
174314
- const key = elementKey(desc);
174716
+ const key = elementKey2(desc);
174315
174717
  const names = byElement.get(key);
174316
174718
  if (names)
174317
174719
  names.push(desc.name);
@@ -174556,7 +174958,7 @@ function isPackageBody(prefix) {
174556
174958
  return true;
174557
174959
  return /\bpackage\s+(?:<[^>]+>\s*)?[\p{L}_'][^;{}]*$/u.test(prefix.slice(Math.max(0, open - 160), open));
174558
174960
  }
174559
- function elementKey(desc) {
174961
+ function elementKey2(desc) {
174560
174962
  return `${desc.documentUri.toString()}#${desc.path}#${desc.type}`;
174561
174963
  }
174562
174964
  function isArrowInvocableName(name) {
@@ -174614,7 +175016,7 @@ function isDefined(value) {
174614
175016
  }
174615
175017
  function nodeName(node) {
174616
175018
  const value = node?.name;
174617
- return typeof value === "string" && value.length > 0 ? unquoteName2(value) : void 0;
175019
+ return typeof value === "string" && value.length > 0 ? unquoteName3(value) : void 0;
174618
175020
  }
174619
175021
  function nodeMembers(node) {
174620
175022
  const members = node?.members;
@@ -174633,7 +175035,7 @@ function receiverSteps(receiver) {
174633
175035
  let match;
174634
175036
  while ((match = pattern.exec(receiver)) !== null) {
174635
175037
  steps.push({
174636
- text: unquoteName2(match[2]),
175038
+ text: unquoteName3(match[2]),
174637
175039
  separator: steps.length === 0 ? void 0 : match[1]
174638
175040
  });
174639
175041
  }
@@ -174690,7 +175092,7 @@ function simpleName(name) {
174690
175092
  if (!name)
174691
175093
  return void 0;
174692
175094
  const parts = name.split(/::|\./u);
174693
- return unquoteName2(parts.at(-1) ?? name);
175095
+ return unquoteName3(parts.at(-1) ?? name);
174694
175096
  }
174695
175097
  function importCovers(text, importPath) {
174696
175098
  const packagePath = importPath.split("::").slice(0, -1).join("::");
@@ -174805,7 +175207,7 @@ function importSortKey(line2) {
174805
175207
  function escapeRegExp3(value) {
174806
175208
  return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
174807
175209
  }
174808
- function unquoteName2(name) {
175210
+ function unquoteName3(name) {
174809
175211
  return name.replace(/^'(.*)'$/u, "$1");
174810
175212
  }
174811
175213
  function unitInsertText(symbol) {
@@ -175410,7 +175812,7 @@ function selectMemberships(path10, form, globalDescriptions) {
175410
175812
  const index2 = GlobalDescriptionIndex.from(globalDescriptions);
175411
175813
  const entries = [];
175412
175814
  if (form.includesSelf) {
175413
- const simple = simpleNameOf(path10);
175815
+ const simple = simpleNameOf2(path10);
175414
175816
  const self2 = index2.named(path10).find((desc) => form.importAll || !isPrivateDescription(desc));
175415
175817
  if (self2)
175416
175818
  entries.push({ name: simple, targetName: self2.name, description: self2 });
@@ -175429,7 +175831,7 @@ function selectMemberships(path10, form, globalDescriptions) {
175429
175831
  }
175430
175832
  return entries;
175431
175833
  }
175432
- function simpleNameOf(path10) {
175834
+ function simpleNameOf2(path10) {
175433
175835
  return path10.includes("::") ? path10.slice(path10.lastIndexOf("::") + 2) : path10;
175434
175836
  }
175435
175837
  function isOwnedMembership(desc) {
@@ -176063,7 +176465,7 @@ var ConformanceModel = class {
176063
176465
  };
176064
176466
 
176065
176467
  // ../language-server/out/src/services/validator.js
176066
- var REDEFINITION_KINDS2 = /* @__PURE__ */ new Set([
176468
+ var REDEFINITION_KINDS3 = /* @__PURE__ */ new Set([
176067
176469
  ":>>",
176068
176470
  "redefines",
176069
176471
  ":>",
@@ -176301,7 +176703,7 @@ var SysmlValidator = class _SysmlValidator {
176301
176703
  // inventory completely. A later segment depends on the KerML semantic model
176302
176704
  // this resolver does not evaluate.
176303
176705
  checkRelationshipTargets(node, accept) {
176304
- if (!node.kind || !REDEFINITION_KINDS2.has(node.kind))
176706
+ if (!node.kind || !REDEFINITION_KINDS3.has(node.kind))
176305
176707
  return;
176306
176708
  for (let ordinal = 0; ordinal < node.targets.length; ordinal += 1) {
176307
176709
  const resolution = this.featurePaths.resolvePropertyPath(node, "targets", ordinal);
@@ -177702,6 +178104,7 @@ ${baseIndent}}`;
177702
178104
  for (const decl of decls) {
177703
178105
  this.checkCyclicSpecialization(decl, index2, accept);
177704
178106
  this.checkSelfContainment(decl, accept);
178107
+ this.checkEffectiveName(decl, accept);
177705
178108
  }
177706
178109
  for (const stmt of verifyStmts)
177707
178110
  this.checkRelationshipTargetKind(stmt, stmt.target, "verify", index2, aliasMap, accept);
@@ -178336,6 +178739,30 @@ ${baseIndent}}`;
178336
178739
  "PrefixMetadataMember",
178337
178740
  "MetadataAnnotation"
178338
178741
  ]);
178742
+ /**
178743
+ * REQ-404 — RES022: an unnamed redefining usage whose effective name cannot
178744
+ * be derived (issue #155).
178745
+ *
178746
+ * OMG SysML v2 Part 1 §7.6.5 gives such a usage the names of the feature its
178747
+ * first owned redefinition names. Two shapes leave it nameless: a chain that
178748
+ * returns to the usage, and a target answered by elements that disagree
178749
+ * about the name. Both are reported rather than settled, because a name
178750
+ * decides what the feature shadows, what resolves to it and what a diagram
178751
+ * draws it as - a picked one would read as authoritative and be wrong.
178752
+ *
178753
+ * A usage that writes any name of its own is not in question, and a target
178754
+ * that simply does not resolve is not either: the written spelling stands,
178755
+ * and an unresolvable path is RES001's to report.
178756
+ */
178757
+ checkEffectiveName(decl, accept) {
178758
+ if (declName(decl) !== void 0 || shortNameOf(decl) !== void 0)
178759
+ return;
178760
+ const names = effectiveNamesOf(decl, localResolverFor(decl));
178761
+ if (!names.problem)
178762
+ return;
178763
+ const target = names.redefines ?? "";
178764
+ accept(severity("RES022", "error"), names.problem === "cycle" ? DIAGNOSTIC_MESSAGES.RES022_EFFECTIVE_NAME_CYCLE(target) : DIAGNOSTIC_MESSAGES.RES022_EFFECTIVE_NAME_AMBIGUOUS(target), { node: decl, code: "RES022" });
178765
+ }
178339
178766
  // REQ-378 — RES017: indistinguishable members within a namespace (issue #183).
178340
178767
  //
178341
178768
  // KerML's validateNamespaceDistinguishability (Pilot KerMLValidator.checkNamespace)
@@ -180053,7 +180480,10 @@ var SysmlScopeComputation = class extends DefaultScopeComputation {
180053
180480
  result.push({
180054
180481
  ...ownAliases[0],
180055
180482
  name,
180056
- derived: start2 > 0 || separator === "." || void 0
180483
+ derived: start2 > 0 || separator === "." || void 0,
180484
+ // REQ-404 — a path THROUGH an effective name is itself
180485
+ // derived from a redefinition, however it is spelled.
180486
+ effective: suffix.some((segment) => segment.aliases.every((alias) => alias.effective)) || void 0
180057
180487
  });
180058
180488
  }
180059
180489
  }
@@ -180073,13 +180503,18 @@ var SysmlScopeComputation = class extends DefaultScopeComputation {
180073
180503
  this.addAlias(aliases, seen, node.name, this.nameNodeOf(node));
180074
180504
  const shortName = node.shortName;
180075
180505
  this.addAlias(aliases, seen, shortName?.name, grammar_utils_exports.findNodeForProperty(shortName?.$cstNode, "name"));
180506
+ const effective = effectiveNamesOf(node, localResolverFor(node));
180507
+ if (effective.origin !== "declared" && effective.origin !== "none") {
180508
+ this.addAlias(aliases, seen, effective.name, void 0, true);
180509
+ this.addAlias(aliases, seen, effective.shortName, void 0, true);
180510
+ }
180076
180511
  return aliases;
180077
180512
  }
180078
- addAlias(aliases, seen, value, cstNode) {
180513
+ addAlias(aliases, seen, value, cstNode, effective = false) {
180079
180514
  if (typeof value !== "string" || value.length === 0 || seen.has(value))
180080
180515
  return;
180081
180516
  seen.add(value);
180082
- aliases.push({ name: value, cstNode });
180517
+ aliases.push({ name: value, cstNode, ...effective ? { effective: true } : {} });
180083
180518
  }
180084
180519
  nameNodeOf(node) {
180085
180520
  return grammar_utils_exports.findNodeForProperty(node.$cstNode, "name");
@@ -180091,6 +180526,10 @@ var SysmlScopeComputation = class extends DefaultScopeComputation {
180091
180526
  ...visibility ? { visibility } : {},
180092
180527
  ...visibility === "private" ? { isPrivate: true } : {},
180093
180528
  ...alias.derived ? { isDerivedAlias: true, derivedKind: "relative" } : {},
180529
+ // REQ-404 — issue #155: the name is the model's, not the text's, so
180530
+ // auto-import must not offer it as a written spelling. It still names
180531
+ // an OWNED member, so a recursive import descends through it.
180532
+ ...alias.effective ? { isDerivedAlias: true, derivedKind: "effective" } : {},
180094
180533
  // REQ-242 — issue #103 — mirrors what the precomputed library index
180095
180534
  // records, so consumers read def-ness the same way for workspace and
180096
180535
  // library symbols.
@@ -180327,7 +180766,7 @@ var SysmlRenameProvider = class extends DefaultRenameProvider {
180327
180766
  // comparison is against `oldName` directly.
180328
180767
  *writtenPathSegments(root4, oldName) {
180329
180768
  const matching = (segments) => segments.filter((segment) => segment.text === oldName);
180330
- const spellsName = (path10) => !!path10 && pathSegments(path10).some((step) => canonicalEscapedName(step) === oldName);
180769
+ const spellsName = (path10) => !!path10 && pathSegments2(path10).some((step) => canonicalEscapedName(step) === oldName);
180331
180770
  for (const node of [root4, ...ast_utils_exports.streamAllContents(root4)]) {
180332
180771
  if (isPathExpr(node)) {
180333
180772
  if (!spellsName(node.path))
@@ -180402,7 +180841,7 @@ var SysmlRenameProvider = class extends DefaultRenameProvider {
180402
180841
  return this.references.findDeclaration(leafNode);
180403
180842
  }
180404
180843
  };
180405
- function pathSegments(path10) {
180844
+ function pathSegments2(path10) {
180406
180845
  const out = [];
180407
180846
  let current2 = "";
180408
180847
  let quoted = false;
@@ -181857,157 +182296,6 @@ var SysmlSemanticTokenProvider = class extends AbstractSemanticTokenProvider {
181857
182296
  // ../language-server/out/src/services/inlay-hint-provider.js
181858
182297
  var import_vscode_languageserver20 = __toESM(require_main4(), 1);
181859
182298
 
181860
- // ../language-server/out/src/services/name-lookup.js
181861
- function unquoteName3(name) {
181862
- return name.replace(/^'(.*)'$/u, "$1");
181863
- }
181864
- function pathSegments2(path10) {
181865
- const segments = [];
181866
- let current2 = "";
181867
- let quoted = false;
181868
- for (let index2 = 0; index2 < path10.length; index2++) {
181869
- const char = path10[index2];
181870
- if (char === "'") {
181871
- quoted = !quoted;
181872
- current2 += char;
181873
- continue;
181874
- }
181875
- if (!quoted && char === ":" && path10[index2 + 1] === ":") {
181876
- segments.push(current2);
181877
- current2 = "";
181878
- index2++;
181879
- continue;
181880
- }
181881
- if (!quoted && char === ".") {
181882
- segments.push(current2);
181883
- current2 = "";
181884
- continue;
181885
- }
181886
- current2 += char;
181887
- }
181888
- segments.push(current2);
181889
- return segments;
181890
- }
181891
- function simpleNameOf2(name) {
181892
- return pathSegments2(name).at(-1) ?? name;
181893
- }
181894
- var ELEMENT_SEPARATOR = "\0";
181895
- function elementKey2(description) {
181896
- return `${description.documentUri.toString()}${ELEMENT_SEPARATOR}${description.path}`;
181897
- }
181898
- function isDeclaredSpelling(description) {
181899
- const kind = description.derivedKind;
181900
- if (kind === "reexport" || kind === "inherited")
181901
- return false;
181902
- return pathSegments2(description.name).length === 1;
181903
- }
181904
- var SysmlNameLookup = class {
181905
- shared;
181906
- byName;
181907
- /** Element key → the declared spellings the index holds for that element. */
181908
- spellings;
181909
- constructor(shared) {
181910
- this.shared = shared;
181911
- this.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, () => {
181912
- this.byName = void 0;
181913
- this.spellings = void 0;
181914
- });
181915
- }
181916
- /** Every description indexed under `name`, in either spelling of an escaped name. */
181917
- descriptions(name) {
181918
- return this.index().get(name) ?? [];
181919
- }
181920
- /**
181921
- * The ONE element `name` names, or `undefined` when the answer is not
181922
- * certain: no element, or more than one. `accept` narrows the candidates
181923
- * before ambiguity is judged, so "the only CALLABLE called `f`" is a
181924
- * decidable question even where a part shares the name.
181925
- */
181926
- unique(name, accept) {
181927
- const candidates = this.descriptions(name).filter((candidate) => !accept || accept(candidate));
181928
- let found;
181929
- let key;
181930
- for (const candidate of candidates) {
181931
- const candidateKey = elementKey2(candidate);
181932
- if (found === void 0) {
181933
- found = candidate;
181934
- key = candidateKey;
181935
- continue;
181936
- }
181937
- if (candidateKey !== key)
181938
- return void 0;
181939
- }
181940
- return found;
181941
- }
181942
- /**
181943
- * Resolve a written path: the spelling the index holds verbatim first, then
181944
- * its final segment. Both readings must name exactly one element.
181945
- */
181946
- uniqueForPath(path10, accept) {
181947
- return this.unique(path10, accept) ?? this.unique(simpleNameOf2(path10), accept);
181948
- }
181949
- /**
181950
- * The declared spellings of the element `description` names — its regular
181951
- * name and its `<short>` name — minus `written`.
181952
- */
181953
- otherNames(description, written) {
181954
- const all = this.spellingIndex().get(elementKey2(description)) ?? [];
181955
- const seen = unquoteName3(written);
181956
- return all.filter((name) => unquoteName3(name) !== seen);
181957
- }
181958
- index() {
181959
- if (!this.byName)
181960
- this.build();
181961
- return this.byName;
181962
- }
181963
- spellingIndex() {
181964
- if (!this.spellings)
181965
- this.build();
181966
- return this.spellings;
181967
- }
181968
- /** One pass over the index feeds both maps; neither is worth a second. */
181969
- build() {
181970
- const byName = /* @__PURE__ */ new Map();
181971
- const spellings = /* @__PURE__ */ new Map();
181972
- const add = (key, description) => {
181973
- const bucket = byName.get(key);
181974
- if (bucket)
181975
- bucket.push(description);
181976
- else
181977
- byName.set(key, [description]);
181978
- };
181979
- for (const description of this.shared.workspace.IndexManager.allElements()) {
181980
- add(description.name, description);
181981
- const unquoted = unquoteName3(description.name);
181982
- if (unquoted !== description.name)
181983
- add(unquoted, description);
181984
- if (!isDeclaredSpelling(description))
181985
- continue;
181986
- const key = elementKey2(description);
181987
- const names = spellings.get(key);
181988
- if (names) {
181989
- if (!names.includes(description.name))
181990
- names.push(description.name);
181991
- } else {
181992
- spellings.set(key, [description.name]);
181993
- }
181994
- }
181995
- this.byName = byName;
181996
- this.spellings = spellings;
181997
- }
181998
- };
181999
- var lookups = /* @__PURE__ */ new WeakMap();
182000
- function nameLookupFor(shared) {
182001
- if (!shared)
182002
- return void 0;
182003
- const existing = lookups.get(shared);
182004
- if (existing)
182005
- return existing;
182006
- const created = new SysmlNameLookup(shared);
182007
- lookups.set(shared, created);
182008
- return created;
182009
- }
182010
-
182011
182299
  // ../language-server/out/src/services/callable-resolver.js
182012
182300
  var CALLABLE_TYPES = /* @__PURE__ */ new Set([
182013
182301
  "CalcDecl",
@@ -182034,7 +182322,7 @@ var CallableResolver = class {
182034
182322
  * candidate only when it is the ONLY element with that name.
182035
182323
  */
182036
182324
  candidates(name) {
182037
- const simple = simpleNameOf2(name);
182325
+ const simple = simpleNameOf(name);
182038
182326
  return (this.lookup?.descriptions(simple) ?? []).filter((description) => CALLABLE_TYPES.has(description.type));
182039
182327
  }
182040
182328
  /**
@@ -182050,7 +182338,7 @@ var CallableResolver = class {
182050
182338
  const root4 = document2.parseResult?.value;
182051
182339
  if (!root4)
182052
182340
  return void 0;
182053
- return collectCallables([root4, ...ast_utils_exports.streamAllContents(root4).toArray()]).get(unquoteName3(simpleNameOf2(name)));
182341
+ return collectCallables([root4, ...ast_utils_exports.streamAllContents(root4).toArray()]).get(unquoteName(simpleNameOf(name)));
182054
182342
  }
182055
182343
  /**
182056
182344
  * SYNCHRONOUS resolution: a qualified spelling the index holds verbatim,
@@ -182066,7 +182354,7 @@ var CallableResolver = class {
182066
182354
  if (node)
182067
182355
  return node;
182068
182356
  }
182069
- const found = local ? local(unquoteName3(simpleNameOf2(name))) : this.findLocal(document2, name);
182357
+ const found = local ? local(unquoteName(simpleNameOf(name))) : this.findLocal(document2, name);
182070
182358
  if (found)
182071
182359
  return found;
182072
182360
  const candidate = this.uniqueCandidate(name);
@@ -182163,11 +182451,11 @@ function isAstNode3(value) {
182163
182451
  }
182164
182452
  function nodeName2(node) {
182165
182453
  const value = node?.name;
182166
- return typeof value === "string" && value.length > 0 ? unquoteName3(value) : void 0;
182454
+ return typeof value === "string" && value.length > 0 ? unquoteName(value) : void 0;
182167
182455
  }
182168
182456
  function shortNameOf2(node) {
182169
182457
  const value = node?.shortName?.name;
182170
- return typeof value === "string" && value.length > 0 ? unquoteName3(value) : void 0;
182458
+ return typeof value === "string" && value.length > 0 ? unquoteName(value) : void 0;
182171
182459
  }
182172
182460
  function typingText(node) {
182173
182461
  const text = node?.typing?.type?.$refText;
@@ -182236,7 +182524,7 @@ var EXPLICIT_SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([
182236
182524
  "crosses",
182237
182525
  "conjugates"
182238
182526
  ]);
182239
- var REDEFINITION_KINDS3 = /* @__PURE__ */ new Set([":>>", "redefines"]);
182527
+ var REDEFINITION_KINDS4 = /* @__PURE__ */ new Set([":>>", "redefines"]);
182240
182528
  var CONSTANT_CARRYING_KINDS = /* @__PURE__ */ new Set([
182241
182529
  ":>",
182242
182530
  "subsets",
@@ -182471,6 +182759,15 @@ var SysmlInlayHintProvider = class {
182471
182759
  * the index is rebuilt.
182472
182760
  */
182473
182761
  declaredNameCache = /* @__PURE__ */ new Map();
182762
+ /**
182763
+ * REQ-404 — issue #155: the effective-name resolver for one document, built
182764
+ * once so the shared derivation memoizes across the whole request instead of
182765
+ * once per hint. It reads the document's own declarations first and the
182766
+ * workspace index second, which is what lets a redefinition of a feature in
182767
+ * ANOTHER file, written by that feature's `<short>` name, still print the
182768
+ * regular name. Dropped with the other index-generation caches.
182769
+ */
182770
+ effectiveNameResolvers = /* @__PURE__ */ new WeakMap();
182474
182771
  constructor(services) {
182475
182772
  this.services = services;
182476
182773
  this.lookup = nameLookupFor(services?.shared);
@@ -182480,8 +182777,18 @@ var SysmlInlayHintProvider = class {
182480
182777
  this.baseCache.clear();
182481
182778
  this.constantCache.clear();
182482
182779
  this.declaredNameCache.clear();
182780
+ this.effectiveNameResolvers = /* @__PURE__ */ new WeakMap();
182483
182781
  });
182484
182782
  }
182783
+ /** REQ-404 — issue #155: the shared effective-name derivation for `root`. */
182784
+ effectiveNameResolver(root4) {
182785
+ const existing = this.effectiveNameResolvers.get(root4);
182786
+ if (existing)
182787
+ return existing;
182788
+ const created = chainResolvers(documentLocalResolver(root4), indexResolver(this.lookup, (description) => this.linker?.resolveIndexedNode?.(description)));
182789
+ this.effectiveNameResolvers.set(root4, created);
182790
+ return created;
182791
+ }
182485
182792
  getInlayHints(document2, _params) {
182486
182793
  const root4 = document2.parseResult?.value;
182487
182794
  if (!root4 || !sysmlInlayHintSettings.enabled)
@@ -182564,7 +182871,7 @@ var SysmlInlayHintProvider = class {
182564
182871
  if (settings.redefinition)
182565
182872
  hints.push(...this.parameterRedefinitionHints(decl));
182566
182873
  if (settings.effectiveNames) {
182567
- const effective = effectiveNameHint(decl);
182874
+ const effective = effectiveNameHint(decl, this.effectiveNameResolver(root4));
182568
182875
  if (effective)
182569
182876
  hints.push(effective);
182570
182877
  }
@@ -182631,7 +182938,7 @@ var SysmlInlayHintProvider = class {
182631
182938
  const parameter = mine[index2].node;
182632
182939
  if (!parameter.name || !parameter.$cstNode)
182633
182940
  continue;
182634
- if (allRelationships2(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS3.has(rel2.kind)))
182941
+ if (allRelationships2(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind)))
182635
182942
  continue;
182636
182943
  const target = theirs[index2].node;
182637
182944
  if (!target.name || target.name === parameter.name)
@@ -182693,7 +183000,7 @@ var SysmlInlayHintProvider = class {
182693
183000
  * has more than one name, and memoized until the index is rebuilt.
182694
183001
  */
182695
183002
  declaredNames(description) {
182696
- const key = elementKey2(description);
183003
+ const key = elementKey(description);
182697
183004
  const cached = this.declaredNameCache.get(key);
182698
183005
  if (cached)
182699
183006
  return cached;
@@ -182860,7 +183167,7 @@ var SysmlInlayHintProvider = class {
182860
183167
  const description = this.lookup.uniqueForPath(target);
182861
183168
  if (!description)
182862
183169
  return false;
182863
- const key = elementKey2(description);
183170
+ const key = elementKey(description);
182864
183171
  const cached = this.constantCache.get(key);
182865
183172
  if (cached !== void 0)
182866
183173
  return cached;
@@ -182901,25 +183208,26 @@ var SysmlInlayHintProvider = class {
182901
183208
  return fallback;
182902
183209
  }
182903
183210
  };
182904
- function effectiveNameHint(node) {
183211
+ function effectiveNameHint(node, resolver) {
182905
183212
  if (node.name || node.shortName?.name || !node.$cstNode)
182906
183213
  return void 0;
182907
- const redefinition = allRelationships2(node).find((rel2) => rel2.kind && REDEFINITION_KINDS3.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
182908
- const target = redefinition?.targets?.[0];
182909
- if (!target)
183214
+ const redefinition = allRelationships2(node).find((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
183215
+ if (!redefinition?.targets?.[0])
182910
183216
  return void 0;
182911
- const effective = lastSegment3(target);
182912
- if (!effective)
183217
+ const names = effectiveNamesOf(node, resolver);
183218
+ const effective = names.name ?? names.shortName;
183219
+ if (!effective || names.problem)
182913
183220
  return void 0;
182914
- const operator = cst_utils_exports.flattenCst(node.$cstNode).find((leaf) => !leaf.hidden && redefinition?.kind !== void 0 && leaf.text === redefinition.kind);
183221
+ const operator = cst_utils_exports.flattenCst(node.$cstNode).find((leaf) => !leaf.hidden && redefinition.kind !== void 0 && leaf.text === redefinition.kind);
182915
183222
  if (!operator)
182916
183223
  return void 0;
183224
+ const short = names.shortName && names.shortName !== effective ? ` It is also known by the short name \`<${names.shortName}>\`.` : "";
182917
183225
  return {
182918
183226
  position: operator.range.start,
182919
183227
  label: effective,
182920
183228
  kind: import_vscode_languageserver20.InlayHintKind.Parameter,
182921
183229
  paddingRight: true,
182922
- tooltip: markdown(`Effective name: \`${effective}\`, taken from the feature this one redefines.`)
183230
+ tooltip: markdown(`Effective name: \`${effective}\`, taken from the feature this one redefines.${short}`)
182923
183231
  };
182924
183232
  }
182925
183233
 
@@ -184187,7 +184495,7 @@ function buildIdNameIndex(value, sourceName) {
184187
184495
  const id2 = stringValue(object["@id"]);
184188
184496
  if (!id2)
184189
184497
  return;
184190
- const declared = declaredName(object);
184498
+ const declared = declaredName2(object);
184191
184499
  if (declared) {
184192
184500
  out.set(id2, safeName(declared));
184193
184501
  } else if (!out.has(id2)) {
@@ -184204,7 +184512,7 @@ function renderJsonElement(element, context, depth) {
184204
184512
  if (!spec)
184205
184513
  return [];
184206
184514
  const indent = " ".repeat(depth);
184207
- const rawName = declaredName(element) ?? (element["@id"] ? fallbackNameFromId(String(element["@id"])) : void 0) ?? `${context.sourceName}_${context.seen.size}`;
184515
+ const rawName = declaredName2(element) ?? (element["@id"] ? fallbackNameFromId(String(element["@id"])) : void 0) ?? `${context.sourceName}_${context.seen.size}`;
184208
184516
  const name = safeName(rawName);
184209
184517
  const children2 = ownedRenderableChildren(element);
184210
184518
  const tail = declarationTail(element, context);
@@ -184283,7 +184591,7 @@ function referenceName(value, context) {
184283
184591
  const id2 = stringValue(value["@id"]);
184284
184592
  if (id2 && context.idToName.has(id2))
184285
184593
  return context.idToName.get(id2);
184286
- const name = declaredName(value) ?? stringValue(value.qualifiedName);
184594
+ const name = declaredName2(value) ?? stringValue(value.qualifiedName);
184287
184595
  if (name)
184288
184596
  return safeQualifiedName(name);
184289
184597
  return referenceName(value.target, context);
@@ -184351,7 +184659,7 @@ function dedupeJsonElements(elements) {
184351
184659
  }
184352
184660
  return out;
184353
184661
  }
184354
- function declaredName(value) {
184662
+ function declaredName2(value) {
184355
184663
  return firstString(value.declaredName, value.name, value.effectiveName, value.qualifiedName);
184356
184664
  }
184357
184665
  function firstString(...values2) {
@@ -205479,7 +205787,7 @@ async function runExport(command) {
205479
205787
  }
205480
205788
 
205481
205789
  // src/main.ts
205482
- var VERSION2 = true ? "0.28.1" : "dev";
205790
+ var VERSION2 = true ? "0.29.0" : "dev";
205483
205791
  function display(file) {
205484
205792
  const rel2 = path9.relative(process.cwd(), file);
205485
205793
  return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;