sysml-diagram 0.31.1 → 0.32.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
@@ -162710,6 +162710,11 @@ var FeaturePathResolver = class {
162710
162710
  linker;
162711
162711
  scopeProvider;
162712
162712
  snapshots = /* @__PURE__ */ new WeakMap();
162713
+ indexedSnapshot;
162714
+ // REQ-361 - Inheritance walks memoized against the snapshot they were read
162715
+ // from; a new snapshot answers fresh. Keyed weakly, so a re-parsed document
162716
+ // drops its entries with its nodes.
162717
+ owners = /* @__PURE__ */ new WeakMap();
162713
162718
  propertySegments = /* @__PURE__ */ new WeakMap();
162714
162719
  resolvingSpecializations = /* @__PURE__ */ new Set();
162715
162720
  enumerationPathDepth = 0;
@@ -162720,9 +162725,12 @@ var FeaturePathResolver = class {
162720
162725
  this.locator = services?.workspace.AstNodeLocator;
162721
162726
  this.linker = services?.references.Linker;
162722
162727
  this.scopeProvider = services?.references.ScopeProvider;
162723
- services?.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, () => {
162724
- this.snapshots = /* @__PURE__ */ new WeakMap();
162725
- });
162728
+ services?.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, () => this.dropSnapshots());
162729
+ services?.shared.workspace.DocumentBuilder.onUpdate(() => this.dropSnapshots());
162730
+ }
162731
+ dropSnapshots() {
162732
+ this.snapshots = /* @__PURE__ */ new WeakMap();
162733
+ this.indexedSnapshot = void 0;
162726
162734
  }
162727
162735
  // REQ-220/317 — resolve every independently clickable/diagnosable segment.
162728
162736
  resolve(node) {
@@ -163187,10 +163195,22 @@ var FeaturePathResolver = class {
163187
163195
  }
163188
163196
  return {};
163189
163197
  }
163198
+ // REQ-361 - The inheritance walk is the hot path of every written-path
163199
+ // resolution, and a document resolves the same owners over and over: once per
163200
+ // path that mentions them, and again for every reference tally a CodeLens
163201
+ // pass asks for. The answer only changes with the syntax (fixed for a parse)
163202
+ // and the index generation, so it is memoized against the snapshot that
163203
+ // produced it. A walk that ran INSIDE a specialization cycle sees the cycle
163204
+ // guard's empty answer, so only a top-level walk is cached.
163190
163205
  typedAndSpecializedOwners(node, snapshot) {
163191
163206
  const syntax = inheritanceSyntax(node);
163192
163207
  if (!syntax.hasSources)
163193
163208
  return [];
163209
+ const cacheable = this.resolvingSpecializations.size === 0;
163210
+ const depthZero = this.enumerationPathDepth === 0;
163211
+ const cached = this.owners.get(node);
163212
+ if (cached && cached.snapshot === snapshot && cached.depthZero === depthZero)
163213
+ return cached.owners;
163194
163214
  const result = [];
163195
163215
  const seen = /* @__PURE__ */ new Set();
163196
163216
  const visit = (candidate) => {
@@ -163221,6 +163241,8 @@ var FeaturePathResolver = class {
163221
163241
  visit(this.isEnumUsage(node) ? this.enumerationTypingTarget(node) : this.typingTarget(node, snapshot));
163222
163242
  for (const specialized of this.specializationTargets(node, snapshot))
163223
163243
  visit(specialized);
163244
+ if (cacheable)
163245
+ this.owners.set(node, { snapshot, depthZero, owners: result });
163224
163246
  return result;
163225
163247
  }
163226
163248
  inferredEnumerationTarget(node) {
@@ -163379,8 +163401,9 @@ var FeaturePathResolver = class {
163379
163401
  segment.target = target.node;
163380
163402
  segment.description = target.description;
163381
163403
  }
163404
+ // REQ-361/410 - One indexed workspace snapshot, or one per parse-only root.
163382
163405
  snapshot(root4) {
163383
- const cached = this.snapshots.get(root4);
163406
+ const cached = this.indexManager ? this.indexedSnapshot : this.snapshots.get(root4);
163384
163407
  if (cached)
163385
163408
  return cached;
163386
163409
  const byName = /* @__PURE__ */ new Map();
@@ -163412,7 +163435,10 @@ var FeaturePathResolver = class {
163412
163435
  }
163413
163436
  }
163414
163437
  const snapshot = { byName };
163415
- this.snapshots.set(root4, snapshot);
163438
+ if (this.indexManager)
163439
+ this.indexedSnapshot = snapshot;
163440
+ else
163441
+ this.snapshots.set(root4, snapshot);
163416
163442
  return snapshot;
163417
163443
  }
163418
163444
  };
@@ -164919,6 +164945,7 @@ function expressionKindOf(node) {
164919
164945
  }
164920
164946
  var ConformanceModel = class {
164921
164947
  resolve;
164948
+ implicitBases;
164922
164949
  closures = /* @__PURE__ */ new Map();
164923
164950
  /**
164924
164951
  * @param resolve A written type name → its declaration, or `undefined` when
@@ -164926,9 +164953,24 @@ var ConformanceModel = class {
164926
164953
  * validator supplies its `resolveUnique`, so an ambiguous name is treated
164927
164954
  * exactly as an unreadable one: it makes the walk incomplete rather than
164928
164955
  * resolving to an arbitrary same-named element.
164956
+ * @param implicitBases REQ-411 — issue #161: the standard-library names a
164957
+ * declaration's KEYWORD contributes, which the source never writes. A
164958
+ * `part def Vehicle;` is a `Parts::Part`, and without this the closure said
164959
+ * it was unrelated to one.
164960
+ *
164961
+ * The contribution is the WHOLE chain above the base, not the base alone,
164962
+ * and it reports whether that chain could be read. Both halves matter:
164963
+ * `Parts::Part :> Items::Item` in the vendored library is what makes a
164964
+ * `part def` a legitimate narrowing of an `Items::Item` feature, and a
164965
+ * contribution that named only `Part` while still calling the closure
164966
+ * COMPLETE would let SSM017 reject that narrowing on a picture it knew was
164967
+ * partial. An unreadable chain therefore makes the closure incomplete, and
164968
+ * every caller stays silent on `unknown` — the same rule the rest of this
164969
+ * file follows, applied to the edge the source does not write.
164929
164970
  */
164930
- constructor(resolve8) {
164971
+ constructor(resolve8, implicitBases) {
164931
164972
  this.resolve = resolve8;
164973
+ this.implicitBases = implicitBases;
164932
164974
  }
164933
164975
  /** The transitive supertype names of the type written as `name`. */
164934
164976
  closureOf(name) {
@@ -164961,6 +165003,12 @@ var ConformanceModel = class {
164961
165003
  for (const supertype of [...declaredTypesOf(node).map((t) => t.text), ...specializedNamesOf(node)]) {
164962
165004
  absorb(this.walk(supertype, visiting));
164963
165005
  }
165006
+ const implicit = this.implicitBases?.(node);
165007
+ if (implicit) {
165008
+ for (const base of implicit.names)
165009
+ names.add(simpleTypeName(base));
165010
+ complete &&= implicit.complete;
165011
+ }
164964
165012
  for (const group of compositionGroupsOf(node)) {
164965
165013
  if (group.kind === "intersects") {
164966
165014
  for (const operand of group.targets)
@@ -174333,7 +174381,6 @@ var sysmlInlayHintSettings = {
174333
174381
  dimension: false,
174334
174382
  visibility: false,
174335
174383
  modifiers: false,
174336
- specialization: false,
174337
174384
  redefinition: false,
174338
174385
  effectiveNames: false,
174339
174386
  importedNames: false,
@@ -174999,6 +175046,547 @@ function resolveEffectiveSubject(node) {
174999
175046
  return void 0;
175000
175047
  }
175001
175048
 
175049
+ // ../language-server/out/src/services/implicit-specialization.js
175050
+ var EXPLICIT_SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([
175051
+ ":>",
175052
+ ":>>",
175053
+ "::>",
175054
+ "=>",
175055
+ "specializes",
175056
+ "subsets",
175057
+ "redefines",
175058
+ "references",
175059
+ "crosses",
175060
+ "conjugates"
175061
+ ]);
175062
+ var IMPLICIT_BASES = Object.freeze({
175063
+ PartDecl: { def: "Parts::Part", usage: "Parts::parts" },
175064
+ ItemDecl: { def: "Items::Item", usage: "Items::items" },
175065
+ PortDecl: { def: "Ports::Port", usage: "Ports::ports" },
175066
+ ActionDecl: { def: "Actions::Action", usage: "Actions::actions" },
175067
+ StateDecl: { def: "States::StateAction", usage: "States::stateActions" },
175068
+ ConnectionDecl: { def: "Connections::Connection", usage: "Connections::connections" },
175069
+ InterfaceDecl: { def: "Interfaces::Interface", usage: "Interfaces::interfaces" },
175070
+ CaseDecl: { def: "Cases::Case", usage: "Cases::cases" },
175071
+ UseCaseDecl: { def: "UseCases::UseCase", usage: "UseCases::useCases" },
175072
+ AnalysisCaseDecl: { def: "AnalysisCases::AnalysisCase", usage: "AnalysisCases::analysisCases" },
175073
+ VerificationCaseDecl: { def: "VerificationCases::VerificationCase", usage: "VerificationCases::verificationCases" },
175074
+ ViewDecl: { def: "Views::View", usage: "Views::views" },
175075
+ ViewpointDecl: { def: "Views::ViewpointCheck", usage: "Views::viewpointChecks" },
175076
+ RenderingDecl: { def: "Views::Rendering", usage: "Views::renderings" },
175077
+ RequirementDecl: { def: "Requirements::RequirementCheck", usage: "Requirements::requirementChecks" },
175078
+ ConcernDecl: { def: "Requirements::ConcernCheck", usage: "Requirements::concernChecks" },
175079
+ ConstraintDecl: { def: "Constraints::ConstraintCheck", usage: "Constraints::constraintChecks" },
175080
+ CalcDecl: { def: "Calculations::Calculation", usage: "Calculations::calculations" },
175081
+ AllocationDecl: { def: "Allocations::Allocation", usage: "Allocations::allocations" },
175082
+ AttributeDecl: { def: "Attributes::AttributeValue", usage: "Attributes::attributeValues" },
175083
+ OccurrenceDecl: { def: "Occurrences::Occurrence", usage: "Occurrences::occurrences" },
175084
+ MetadataDecl: { def: "Metadata::MetadataItem", usage: "Metadata::metadataItems" }
175085
+ });
175086
+ var KERML_CLASSIFIER_BASES = Object.freeze({
175087
+ ClassDecl: "Occurrences::Occurrence",
175088
+ StructDecl: "Objects::Object",
175089
+ MetaclassDecl: "Metaobjects::Metaobject",
175090
+ BehaviorDecl: "Performances::Performance",
175091
+ DatatypeDecl: "Base::DataValue"
175092
+ });
175093
+ var KERML_FEATURE_BASES = Object.freeze({
175094
+ StepDecl: "Performances::performances"
175095
+ });
175096
+ var ASSOCIATION_BASES = Object.freeze({ link: "Links::Link", linkObject: "Objects::LinkObject" });
175097
+ var LIBRARY_BASE_CHAINS = Object.freeze({
175098
+ "Actions::Action": ["Performance", "Occurrence", "Anything"],
175099
+ "Actions::actions": ["Action", "Performance", "Occurrence", "Anything", "performances", "occurrences", "things"],
175100
+ "Allocations::Allocation": [
175101
+ "BinaryConnection",
175102
+ "BinaryLinkObject",
175103
+ "BinaryLink",
175104
+ "Link",
175105
+ "Anything",
175106
+ "LinkObject",
175107
+ "Object",
175108
+ "Occurrence",
175109
+ "Connection",
175110
+ "Part",
175111
+ "Item"
175112
+ ],
175113
+ "Allocations::allocations": [
175114
+ "Allocation",
175115
+ "BinaryConnection",
175116
+ "BinaryLinkObject",
175117
+ "BinaryLink",
175118
+ "Link",
175119
+ "Anything",
175120
+ "LinkObject",
175121
+ "Object",
175122
+ "Occurrence",
175123
+ "Connection",
175124
+ "Part",
175125
+ "Item",
175126
+ "binaryConnections",
175127
+ "connections",
175128
+ "linkObjects",
175129
+ "links",
175130
+ "things",
175131
+ "objects",
175132
+ "occurrences",
175133
+ "parts",
175134
+ "items",
175135
+ "binaryLinkObjects",
175136
+ "binaryLinks"
175137
+ ],
175138
+ "AnalysisCases::AnalysisCase": [
175139
+ "Case",
175140
+ "Calculation",
175141
+ "Action",
175142
+ "Performance",
175143
+ "Occurrence",
175144
+ "Anything",
175145
+ "Evaluation"
175146
+ ],
175147
+ "AnalysisCases::analysisCases": [
175148
+ "AnalysisCase",
175149
+ "Case",
175150
+ "Calculation",
175151
+ "Action",
175152
+ "Performance",
175153
+ "Occurrence",
175154
+ "Anything",
175155
+ "Evaluation",
175156
+ "cases",
175157
+ "calculations",
175158
+ "actions",
175159
+ "performances",
175160
+ "occurrences",
175161
+ "things",
175162
+ "evaluations"
175163
+ ],
175164
+ "Attributes::AttributeValue": ["DataValue", "Anything"],
175165
+ "Attributes::attributeValues": ["dataValues", "DataValue", "Anything", "things"],
175166
+ "Base::DataValue": ["Anything"],
175167
+ "Calculations::Calculation": ["Action", "Performance", "Occurrence", "Anything", "Evaluation"],
175168
+ "Calculations::calculations": [
175169
+ "Calculation",
175170
+ "Action",
175171
+ "Performance",
175172
+ "Occurrence",
175173
+ "Anything",
175174
+ "Evaluation",
175175
+ "actions",
175176
+ "performances",
175177
+ "occurrences",
175178
+ "things",
175179
+ "evaluations"
175180
+ ],
175181
+ "Cases::Case": ["Calculation", "Action", "Performance", "Occurrence", "Anything", "Evaluation"],
175182
+ "Cases::cases": [
175183
+ "Case",
175184
+ "Calculation",
175185
+ "Action",
175186
+ "Performance",
175187
+ "Occurrence",
175188
+ "Anything",
175189
+ "Evaluation",
175190
+ "calculations",
175191
+ "actions",
175192
+ "performances",
175193
+ "occurrences",
175194
+ "things",
175195
+ "evaluations"
175196
+ ],
175197
+ "Connections::Connection": ["LinkObject", "Link", "Anything", "Object", "Occurrence", "Part", "Item"],
175198
+ "Connections::connections": [
175199
+ "Connection",
175200
+ "LinkObject",
175201
+ "Link",
175202
+ "Anything",
175203
+ "Object",
175204
+ "Occurrence",
175205
+ "Part",
175206
+ "Item",
175207
+ "linkObjects",
175208
+ "links",
175209
+ "things",
175210
+ "objects",
175211
+ "occurrences",
175212
+ "parts",
175213
+ "items"
175214
+ ],
175215
+ "Constraints::ConstraintCheck": ["BooleanEvaluation", "Evaluation", "Performance", "Occurrence", "Anything"],
175216
+ "Constraints::constraintChecks": [
175217
+ "ConstraintCheck",
175218
+ "BooleanEvaluation",
175219
+ "Evaluation",
175220
+ "Performance",
175221
+ "Occurrence",
175222
+ "Anything",
175223
+ "booleanEvaluations",
175224
+ "evaluations",
175225
+ "performances",
175226
+ "occurrences",
175227
+ "things"
175228
+ ],
175229
+ "Interfaces::Interface": ["Connection", "LinkObject", "Link", "Anything", "Object", "Occurrence", "Part", "Item"],
175230
+ "Interfaces::interfaces": [
175231
+ "Interface",
175232
+ "Connection",
175233
+ "LinkObject",
175234
+ "Link",
175235
+ "Anything",
175236
+ "Object",
175237
+ "Occurrence",
175238
+ "Part",
175239
+ "Item",
175240
+ "connections",
175241
+ "linkObjects",
175242
+ "links",
175243
+ "things",
175244
+ "objects",
175245
+ "occurrences",
175246
+ "parts",
175247
+ "items"
175248
+ ],
175249
+ "Items::Item": ["Object", "Occurrence", "Anything"],
175250
+ "Items::items": ["Item", "Object", "Occurrence", "Anything", "objects", "occurrences", "things"],
175251
+ "Links::Link": ["Anything"],
175252
+ "Metadata::MetadataItem": ["Metaobject", "Object", "Occurrence", "Anything", "Item"],
175253
+ "Metadata::metadataItems": [
175254
+ "MetadataItem",
175255
+ "Metaobject",
175256
+ "Object",
175257
+ "Occurrence",
175258
+ "Anything",
175259
+ "Item",
175260
+ "metaobjects",
175261
+ "objects",
175262
+ "occurrences",
175263
+ "things",
175264
+ "items"
175265
+ ],
175266
+ "Metaobjects::Metaobject": ["Object", "Occurrence", "Anything"],
175267
+ "Objects::LinkObject": ["Link", "Anything", "Object", "Occurrence"],
175268
+ "Objects::Object": ["Occurrence", "Anything"],
175269
+ "Occurrences::Occurrence": ["Anything"],
175270
+ "Occurrences::occurrences": ["Occurrence", "Anything", "things"],
175271
+ "Parts::Part": ["Item", "Object", "Occurrence", "Anything"],
175272
+ "Parts::parts": ["Part", "Item", "Object", "Occurrence", "Anything", "items", "objects", "occurrences", "things"],
175273
+ "Performances::Performance": ["Occurrence", "Anything"],
175274
+ "Performances::performances": ["Performance", "Occurrence", "Anything", "occurrences", "things"],
175275
+ "Ports::Port": ["Object", "Occurrence", "Anything"],
175276
+ "Ports::ports": ["Port", "Object", "Occurrence", "Anything", "objects", "occurrences", "things"],
175277
+ "Requirements::ConcernCheck": [
175278
+ "RequirementCheck",
175279
+ "RequirementConstraintCheck",
175280
+ "ConstraintCheck",
175281
+ "BooleanEvaluation",
175282
+ "Evaluation",
175283
+ "Performance",
175284
+ "Occurrence",
175285
+ "Anything"
175286
+ ],
175287
+ "Requirements::RequirementCheck": [
175288
+ "RequirementConstraintCheck",
175289
+ "ConstraintCheck",
175290
+ "BooleanEvaluation",
175291
+ "Evaluation",
175292
+ "Performance",
175293
+ "Occurrence",
175294
+ "Anything"
175295
+ ],
175296
+ "Requirements::concernChecks": [
175297
+ "ConcernCheck",
175298
+ "RequirementCheck",
175299
+ "RequirementConstraintCheck",
175300
+ "ConstraintCheck",
175301
+ "BooleanEvaluation",
175302
+ "Evaluation",
175303
+ "Performance",
175304
+ "Occurrence",
175305
+ "Anything",
175306
+ "requirementChecks",
175307
+ "constraintChecks",
175308
+ "booleanEvaluations",
175309
+ "evaluations",
175310
+ "performances",
175311
+ "occurrences",
175312
+ "things"
175313
+ ],
175314
+ "Requirements::requirementChecks": [
175315
+ "RequirementCheck",
175316
+ "RequirementConstraintCheck",
175317
+ "ConstraintCheck",
175318
+ "BooleanEvaluation",
175319
+ "Evaluation",
175320
+ "Performance",
175321
+ "Occurrence",
175322
+ "Anything",
175323
+ "constraintChecks",
175324
+ "booleanEvaluations",
175325
+ "evaluations",
175326
+ "performances",
175327
+ "occurrences",
175328
+ "things"
175329
+ ],
175330
+ "States::StateAction": [
175331
+ "Action",
175332
+ "Performance",
175333
+ "Occurrence",
175334
+ "Anything",
175335
+ "StatePerformance",
175336
+ "DecisionPerformance"
175337
+ ],
175338
+ "States::stateActions": [
175339
+ "StateAction",
175340
+ "Action",
175341
+ "Performance",
175342
+ "Occurrence",
175343
+ "Anything",
175344
+ "StatePerformance",
175345
+ "DecisionPerformance",
175346
+ "actions",
175347
+ "performances",
175348
+ "occurrences",
175349
+ "things"
175350
+ ],
175351
+ "UseCases::UseCase": ["Case", "Calculation", "Action", "Performance", "Occurrence", "Anything", "Evaluation"],
175352
+ "UseCases::useCases": [
175353
+ "UseCase",
175354
+ "Case",
175355
+ "Calculation",
175356
+ "Action",
175357
+ "Performance",
175358
+ "Occurrence",
175359
+ "Anything",
175360
+ "Evaluation",
175361
+ "cases",
175362
+ "calculations",
175363
+ "actions",
175364
+ "performances",
175365
+ "occurrences",
175366
+ "things",
175367
+ "evaluations"
175368
+ ],
175369
+ "VerificationCases::VerificationCase": [
175370
+ "Case",
175371
+ "Calculation",
175372
+ "Action",
175373
+ "Performance",
175374
+ "Occurrence",
175375
+ "Anything",
175376
+ "Evaluation"
175377
+ ],
175378
+ "VerificationCases::verificationCases": [
175379
+ "VerificationCase",
175380
+ "Case",
175381
+ "Calculation",
175382
+ "Action",
175383
+ "Performance",
175384
+ "Occurrence",
175385
+ "Anything",
175386
+ "Evaluation",
175387
+ "cases",
175388
+ "calculations",
175389
+ "actions",
175390
+ "performances",
175391
+ "occurrences",
175392
+ "things",
175393
+ "evaluations"
175394
+ ],
175395
+ "Views::Rendering": ["Part", "Item", "Object", "Occurrence", "Anything"],
175396
+ "Views::View": ["Part", "Item", "Object", "Occurrence", "Anything"],
175397
+ "Views::ViewpointCheck": [
175398
+ "RequirementCheck",
175399
+ "RequirementConstraintCheck",
175400
+ "ConstraintCheck",
175401
+ "BooleanEvaluation",
175402
+ "Evaluation",
175403
+ "Performance",
175404
+ "Occurrence",
175405
+ "Anything"
175406
+ ],
175407
+ "Views::renderings": [
175408
+ "Rendering",
175409
+ "Part",
175410
+ "Item",
175411
+ "Object",
175412
+ "Occurrence",
175413
+ "Anything",
175414
+ "parts",
175415
+ "items",
175416
+ "objects",
175417
+ "occurrences",
175418
+ "things"
175419
+ ],
175420
+ "Views::viewpointChecks": [
175421
+ "ViewpointCheck",
175422
+ "RequirementCheck",
175423
+ "RequirementConstraintCheck",
175424
+ "ConstraintCheck",
175425
+ "BooleanEvaluation",
175426
+ "Evaluation",
175427
+ "Performance",
175428
+ "Occurrence",
175429
+ "Anything",
175430
+ "requirementChecks",
175431
+ "constraintChecks",
175432
+ "booleanEvaluations",
175433
+ "evaluations",
175434
+ "performances",
175435
+ "occurrences",
175436
+ "things"
175437
+ ],
175438
+ "Views::views": [
175439
+ "View",
175440
+ "Part",
175441
+ "Item",
175442
+ "Object",
175443
+ "Occurrence",
175444
+ "Anything",
175445
+ "parts",
175446
+ "items",
175447
+ "objects",
175448
+ "occurrences",
175449
+ "things"
175450
+ ]
175451
+ });
175452
+ function allRelationships(node) {
175453
+ return [...node.preRelationships ?? [], ...node.relationships ?? []];
175454
+ }
175455
+ function statesExplicitSpecialization(node) {
175456
+ const decl = node;
175457
+ if (decl.typing?.type?.$refText)
175458
+ return true;
175459
+ return allRelationships(decl).some((rel2) => (
175460
+ // The SYMBOLIC conjugation has no keyword: `port def In ~ Out;` parses as
175461
+ // a relationship with `conjugate: true` and NO `kind` at all (the
175462
+ // grammar's `conjugate?='~' targets+=RelationPath` alternative). Reading
175463
+ // `kind` alone therefore missed it and offered `Ports::Port` beside a
175464
+ // relationship that already says what the declaration is.
175465
+ rel2.conjugate === true || rel2.kind !== void 0 && EXPLICIT_SPECIALIZATION_KINDS.has(rel2.kind)
175466
+ ));
175467
+ }
175468
+ function implicitBaseOf(node) {
175469
+ const decl = node;
175470
+ const found = qualifiedBaseOf(decl);
175471
+ if (!found)
175472
+ return void 0;
175473
+ const [qualified, isUsage2] = found;
175474
+ return {
175475
+ qualified,
175476
+ simple: simpleTypeName(qualified),
175477
+ isUsage: isUsage2,
175478
+ metaclass: isUsage2 ? "Subsetting" : "Specialization"
175479
+ };
175480
+ }
175481
+ function qualifiedBaseOf(decl) {
175482
+ const classifier = decl.$type === "AssociationDecl" ? decl.isStruct === true ? ASSOCIATION_BASES.linkObject : ASSOCIATION_BASES.link : KERML_CLASSIFIER_BASES[decl.$type];
175483
+ if (classifier)
175484
+ return [classifier, false];
175485
+ const feature = KERML_FEATURE_BASES[decl.$type];
175486
+ if (feature)
175487
+ return [feature, true];
175488
+ const entry = IMPLICIT_BASES[decl.$type];
175489
+ if (!entry)
175490
+ return void 0;
175491
+ const isUsage2 = decl.isDef !== true;
175492
+ return [isUsage2 ? entry.usage : entry.def, isUsage2];
175493
+ }
175494
+ function impliedBaseOf(node) {
175495
+ if (statesExplicitSpecialization(node))
175496
+ return void 0;
175497
+ return implicitBaseOf(node);
175498
+ }
175499
+ var ImplicitSpecializationModel = class {
175500
+ lookup;
175501
+ /** Resolved bases, keyed by qualified name. A MISS is never cached: the
175502
+ * library index may still be loading, and a cached miss would outlive it. */
175503
+ bases = /* @__PURE__ */ new Map();
175504
+ constructor(lookup) {
175505
+ this.lookup = lookup;
175506
+ }
175507
+ /** Drop everything a rebuilt index could change. The chain table is a
175508
+ * constant and survives; only a resolved description can go stale. */
175509
+ invalidate() {
175510
+ this.bases.clear();
175511
+ }
175512
+ /** The implied base of one declaration, or `undefined` when there is none. */
175513
+ baseOf(node) {
175514
+ return impliedBaseOf(node);
175515
+ }
175516
+ /**
175517
+ * The index description of a base, so a consumer can link to it.
175518
+ *
175519
+ * The full qualified spelling must resolve inside the standard library.
175520
+ * A workspace namesake or an unrelated library element with the same simple
175521
+ * name cannot supply this relationship.
175522
+ */
175523
+ descriptionOf(base) {
175524
+ const cached = this.bases.get(base.qualified);
175525
+ if (cached)
175526
+ return cached;
175527
+ if (!this.lookup)
175528
+ return void 0;
175529
+ const exact = this.lookup.descriptions(base.qualified).find((description) => {
175530
+ const uri = description.documentUri instanceof URI2 ? description.documentUri : URI2.parse(String(description.documentUri));
175531
+ return isStandardLibraryUri(uri);
175532
+ });
175533
+ if (exact)
175534
+ this.bases.set(base.qualified, exact);
175535
+ return exact;
175536
+ }
175537
+ /**
175538
+ * The implied base of `node` and every library name above it.
175539
+ *
175540
+ * Answered from {@link LIBRARY_BASE_CHAINS}, so it needs no index, no parse
175541
+ * and no network of loaded documents: the desktop host, the web worker and
175542
+ * the headless CLIs all give the same answer, and a workspace with no
175543
+ * library loaded still gets the real hierarchy rather than a shrug. A
175544
+ * declaration with no implicit base has an empty closure, which is complete
175545
+ * in the only sense that matters: there is nothing missing from it.
175546
+ *
175547
+ * A base the table does not cover is reported INCOMPLETE rather than as a
175548
+ * bare name, because a caller may conclude nothing from a name's absence
175549
+ * when the hierarchy above it was never known.
175550
+ */
175551
+ closureOf(node) {
175552
+ const base = this.baseOf(node);
175553
+ if (!base)
175554
+ return { names: /* @__PURE__ */ new Set(), complete: true };
175555
+ const chain = LIBRARY_BASE_CHAINS[base.qualified];
175556
+ return {
175557
+ names: /* @__PURE__ */ new Set([base.simple, ...(chain ?? []).map(simpleTypeName)]),
175558
+ complete: chain !== void 0
175559
+ };
175560
+ }
175561
+ /**
175562
+ * The chain the library puts above one base, for a caller that wants to
175563
+ * check the table against the library it was read from.
175564
+ */
175565
+ static libraryChainOf(qualified) {
175566
+ return LIBRARY_BASE_CHAINS[qualified];
175567
+ }
175568
+ /** Every base the chain table covers, for the same reason. */
175569
+ static coveredBases() {
175570
+ return Object.keys(LIBRARY_BASE_CHAINS);
175571
+ }
175572
+ };
175573
+ var models = /* @__PURE__ */ new WeakMap();
175574
+ function implicitSpecializationsFor(shared) {
175575
+ if (!shared)
175576
+ return void 0;
175577
+ const existing = models.get(shared);
175578
+ if (existing)
175579
+ return existing;
175580
+ const created = new ImplicitSpecializationModel(nameLookupFor(shared));
175581
+ models.set(shared, created);
175582
+ shared.workspace.DocumentBuilder.onBuildPhase(
175583
+ // Indexing is the only phase that can change what a base resolves to.
175584
+ DocumentState.IndexedContent,
175585
+ () => created.invalidate()
175586
+ );
175587
+ return created;
175588
+ }
175589
+
175002
175590
  // ../language-server/out/src/messages.js
175003
175591
  var DIAGNOSTIC_MESSAGES = {
175004
175592
  // REQ-006 - a broad diagram anchor cannot prove which typed occurrence owns
@@ -175353,6 +175941,12 @@ var OPERATOR_TOOLTIPS = {
175353
175941
  "@": { desc: "**Metadata application** shorthand - applies a metadata definition to the next element.", precedence: 0, example: "@Safety\npart def Engine;", cite: "OMG SysML v2.0 Part 1 \xA78.2.2.27 (Metadata)" },
175354
175942
  "@@": { desc: "**Metaclass application** - applies a metaclass annotation.", precedence: 0, example: "@@StandardProfile", cite: "OMG SysML v2.0 Part 1 \xA78.2.2.27 (Metadata)" }
175355
175943
  };
175944
+ var IMPLICIT_SPECIALIZATION_MESSAGES = {
175945
+ makeExplicit: (base) => `Make implicit specialization explicit (':> ${base}')`,
175946
+ specializes: "implicitly specializes",
175947
+ subsets: "implicitly subsets",
175948
+ source: " Source: the standard library, through the declaration keyword (OMG SysML v2 Part 1 section 7.6.8)."
175949
+ };
175356
175950
 
175357
175951
  // ../language-server/out/src/services/hover-provider.js
175358
175952
  var MAX_HOVER_LINES = 30;
@@ -175447,7 +176041,7 @@ function directionLabel(node) {
175447
176041
  const dir = modifiers2.find((m) => m === "in" || m === "out" || m === "inout");
175448
176042
  return dir ? `${dir} ` : "";
175449
176043
  }
175450
- function allRelationships(node) {
176044
+ function allRelationships2(node) {
175451
176045
  return [...node.preRelationships ?? [], ...node.relationships ?? []];
175452
176046
  }
175453
176047
  function relationshipTargets(rel2) {
@@ -175511,7 +176105,7 @@ function declarationLine(node, resolver, enumResolver) {
175511
176105
  const name = externalVariantName(node) ?? identificationLabel(named2) ?? effectiveIdentificationLabel(named2) ?? "(anonymous)";
175512
176106
  let typing = typingLabel(named2.typing);
175513
176107
  const mult = multiplicityLabel(node, resolver);
175514
- let rels = relationshipLabel(allRelationships(named2));
176108
+ let rels = relationshipLabel(allRelationships2(named2));
175515
176109
  const implicitVariant = implicitVariantSpecialization(node);
175516
176110
  if (!typing && !implicitVariant && enumResolver && isEnumerationUsage(node)) {
175517
176111
  const types = effectiveEnumerationTypes(node, enumResolver);
@@ -175581,7 +176175,7 @@ function memberSummary(node, resolver) {
175581
176175
  const kind = kindLabel(node);
175582
176176
  const typing = typingLabel(named2.typing);
175583
176177
  const mult = multiplicityLabel(node, resolver);
175584
- const rels = relationshipLabel(allRelationships(named2));
176178
+ const rels = relationshipLabel(allRelationships2(named2));
175585
176179
  return `${dir}${kind} ${name}${typing}${mult}${rels}`;
175586
176180
  }
175587
176181
  function memberList(node, resolver) {
@@ -175754,7 +176348,7 @@ function supertypeCandidates(node) {
175754
176348
  if (more.$refText)
175755
176349
  out.push({ refText: more.$refText, ref: more.ref });
175756
176350
  }
175757
- for (const rel2 of allRelationships(named2)) {
176351
+ for (const rel2 of allRelationships2(named2)) {
175758
176352
  if (!rel2.kind || !DOC_SPECIALIZATION_KINDS.has(rel2.kind))
175759
176353
  continue;
175760
176354
  for (const target of rel2.targets ?? [])
@@ -176136,12 +176730,15 @@ var SysmlHoverProvider = class {
176136
176730
  enumerations;
176137
176731
  /** REQ-394 — the linker's lazy standard-library load, reused rather than duplicated. */
176138
176732
  linker;
176733
+ /** REQ-411 — issue #161: the shared implicit-specialization model. */
176734
+ implicit;
176139
176735
  constructor(services) {
176140
176736
  this.references = services.references.References;
176141
176737
  this.astNodeLocator = services.workspace.AstNodeLocator;
176142
176738
  this.documents = services.shared.workspace.LangiumDocuments;
176143
176739
  this.indexManager = services.shared.workspace.IndexManager;
176144
176740
  this.linker = services.references.Linker;
176741
+ this.implicit = implicitSpecializationsFor(services.shared);
176145
176742
  const paths = new FeaturePathResolver(services);
176146
176743
  this.featureProperties = featurePropertyResolver(paths);
176147
176744
  this.enumerations = enumerationResolver(paths);
@@ -176285,8 +176882,10 @@ var SysmlHoverProvider = class {
176285
176882
  // target kind, and target declaration line instead of only echoing `:>`/`:>>`.
176286
176883
  async relationshipDetailSection(node) {
176287
176884
  const named2 = node;
176288
- const rels = allRelationships(named2);
176289
- if (rels.length === 0)
176885
+ const rels = allRelationships2(named2);
176886
+ const implied = this.implicit?.baseOf(node);
176887
+ const impliedBase = implied && this.implicit?.descriptionOf(implied) ? implied : void 0;
176888
+ if (rels.length === 0 && !impliedBase)
176290
176889
  return void 0;
176291
176890
  const sourceKind = kindLabel(node);
176292
176891
  const sourceName = identificationLabel(named2) ?? "(anonymous)";
@@ -176308,6 +176907,10 @@ var SysmlHoverProvider = class {
176308
176907
  }
176309
176908
  }
176310
176909
  }
176910
+ if (impliedBase) {
176911
+ const phrase = impliedBase.isUsage ? IMPLICIT_SPECIALIZATION_MESSAGES.subsets : IMPLICIT_SPECIALIZATION_MESSAGES.specializes;
176912
+ lines.push(`- ${sourceKind} \`${sourceName}\` ${phrase} \`${impliedBase.qualified}\``, IMPLICIT_SPECIALIZATION_MESSAGES.source);
176913
+ }
176311
176914
  return lines.length > 0 ? `*Relationships:*
176312
176915
  ${lines.join("\n")}` : void 0;
176313
176916
  }
@@ -178871,12 +179474,18 @@ var SysmlValidator = class _SysmlValidator {
178871
179474
  // captured here. The two share one grammar today; this keeps that from becoming
178872
179475
  // load-bearing.
178873
179476
  serviceRegistry;
179477
+ // REQ-411 — issue #161: the shared implicit-specialization model. The walk
179478
+ // above a base needs a PARSED library declaration, so it goes through the
179479
+ // linker's own lazy single-file load rather than pulling the library into
179480
+ // the workspace; the model memoizes each chain for the whole session.
179481
+ implicit;
178874
179482
  constructor(services) {
178875
179483
  this.serviceRegistry = services.shared.ServiceRegistry;
178876
179484
  this.indexManager = services.shared.workspace.IndexManager;
178877
179485
  this.langiumDocuments = services.shared.workspace.LangiumDocuments;
178878
179486
  this.astNodeLocator = services.workspace.AstNodeLocator;
178879
179487
  this.featurePaths = new FeaturePathResolver(services);
179488
+ this.implicit = implicitSpecializationsFor(services.shared);
178880
179489
  this.featureProperties = featurePropertyResolver(this.featurePaths);
178881
179490
  this.compositionTypes = compositionTypeResolver(this.featurePaths);
178882
179491
  this.enumerations = enumerationResolver(this.featurePaths);
@@ -180602,7 +181211,7 @@ ${baseIndent}}`;
180602
181211
  // `unknown` and no diagnostic. That is what keeps the OMG corpus clean while
180603
181212
  // still catching the workspace-local mistakes these codes exist for.
180604
181213
  checkTypeConformance(decls, index2, accept) {
180605
- const model = new ConformanceModel((name) => this.resolveUnique(name, index2));
181214
+ const model = new ConformanceModel((name) => this.resolveUnique(name, index2), (node) => this.implicit?.closureOf(node) ?? { names: /* @__PURE__ */ new Set(), complete: true });
180606
181215
  for (const decl of decls) {
180607
181216
  this.checkRedefinitionTypeConformance(decl, model, index2, accept);
180608
181217
  this.checkValueAssignability(decl, model, accept);
@@ -183376,6 +183985,21 @@ function nearestDefAware(node) {
183376
183985
  }
183377
183986
  return void 0;
183378
183987
  }
183988
+ function nearestImplicitBaseOwner(node) {
183989
+ for (let cur = node; cur; cur = cur.$container) {
183990
+ if (implicitBaseOf(cur))
183991
+ return cur;
183992
+ }
183993
+ return void 0;
183994
+ }
183995
+ var DECLARATION_HEAD_ENDS = /* @__PURE__ */ new Set(["{", ";", "=", ":=", "default"]);
183996
+ function declarationTailPosition(node) {
183997
+ const leaves = cst_utils_exports.flattenCst(node).toArray().filter((leaf) => !leaf.hidden);
183998
+ const stop = leaves.findIndex((leaf) => DECLARATION_HEAD_ENDS.has(leaf.text));
183999
+ if (stop > 0)
184000
+ return leaves[stop - 1].range.end;
184001
+ return node.range.end;
184002
+ }
183379
184003
  function isSubjectBearing(node) {
183380
184004
  return !!node && (isRequirementDecl(node) || isCaseDecl(node) || isUseCaseDecl(node) || isVerificationCaseDecl(node) || isAnalysisCaseDecl(node) || isConcernDecl(node));
183381
184005
  }
@@ -183421,8 +184045,12 @@ function astNodeAtRange(document2, diagnostic) {
183421
184045
  }
183422
184046
  var SysmlCodeActionProvider = class {
183423
184047
  documents;
184048
+ /** REQ-411 — issue #161: the shared implicit-specialization model, so the
184049
+ * action offers only a base the loaded library actually holds. */
184050
+ implicit;
183424
184051
  constructor(services) {
183425
184052
  this.documents = services.shared.workspace.LangiumDocuments;
184053
+ this.implicit = implicitSpecializationsFor(services.shared);
183426
184054
  }
183427
184055
  getCodeActions(document2, params) {
183428
184056
  const actions = [];
@@ -183724,6 +184352,19 @@ ${indent}}`)]
183724
184352
  });
183725
184353
  }
183726
184354
  }
184355
+ const implicitOwner = nearestImplicitBaseOwner(rangeNode);
184356
+ const implicitBase = implicitOwner ? impliedBaseOf(implicitOwner) : void 0;
184357
+ if (implicitOwner?.$cstNode && implicitBase && this.implicit?.descriptionOf(implicitBase)) {
184358
+ actions.push({
184359
+ title: IMPLICIT_SPECIALIZATION_MESSAGES.makeExplicit(implicitBase.qualified),
184360
+ kind: import_vscode_languageserver18.CodeActionKind.RefactorRewrite,
184361
+ edit: {
184362
+ changes: {
184363
+ [uri]: [import_vscode_languageserver18.TextEdit.insert(declarationTailPosition(implicitOwner.$cstNode), ` :> ${implicitBase.qualified}`)]
184364
+ }
184365
+ }
184366
+ });
184367
+ }
183727
184368
  const importNode = nearestAncestor2(rangeNode, isImport);
183728
184369
  if (importNode?.$cstNode && importNode.alias && importNode.segs.every((s) => !s.star && s.name)) {
183729
184370
  const path10 = [importNode.head, ...importNode.segs.map((s) => s.name)].join("::");
@@ -185001,18 +185642,6 @@ function typeAnchor(node, refText) {
185001
185642
  }
185002
185643
  return void 0;
185003
185644
  }
185004
- var EXPLICIT_SPECIALIZATION_KINDS = /* @__PURE__ */ new Set([
185005
- ":>",
185006
- ":>>",
185007
- "::>",
185008
- "=>",
185009
- "specializes",
185010
- "subsets",
185011
- "redefines",
185012
- "references",
185013
- "crosses",
185014
- "conjugates"
185015
- ]);
185016
185645
  var REDEFINITION_KINDS4 = /* @__PURE__ */ new Set([":>>", "redefines"]);
185017
185646
  var CONSTANT_CARRYING_KINDS = /* @__PURE__ */ new Set([
185018
185647
  ":>",
@@ -185057,30 +185686,6 @@ var ACTION_KIND_USAGES = /* @__PURE__ */ new Set([
185057
185686
  "VerificationCaseDecl"
185058
185687
  ]);
185059
185688
  var KERML_FEATURE_DECLS = /* @__PURE__ */ new Set(["FeatureDecl", "StepDecl", "ExpressionDecl"]);
185060
- var IMPLICIT_BASES = Object.freeze({
185061
- PartDecl: { def: "Parts::Part", usage: "Parts::parts" },
185062
- ItemDecl: { def: "Items::Item", usage: "Items::items" },
185063
- PortDecl: { def: "Ports::Port", usage: "Ports::ports" },
185064
- ActionDecl: { def: "Actions::Action", usage: "Actions::actions" },
185065
- StateDecl: { def: "States::StateAction", usage: "States::stateActions" },
185066
- ConnectionDecl: { def: "Connections::Connection", usage: "Connections::connections" },
185067
- InterfaceDecl: { def: "Interfaces::Interface", usage: "Interfaces::interfaces" },
185068
- CaseDecl: { def: "Cases::Case", usage: "Cases::cases" },
185069
- UseCaseDecl: { def: "UseCases::UseCase", usage: "UseCases::useCases" },
185070
- AnalysisCaseDecl: { def: "AnalysisCases::AnalysisCase", usage: "AnalysisCases::analysisCases" },
185071
- VerificationCaseDecl: { def: "VerificationCases::VerificationCase", usage: "VerificationCases::verificationCases" },
185072
- ViewDecl: { def: "Views::View", usage: "Views::views" },
185073
- ViewpointDecl: { def: "Views::ViewpointCheck", usage: "Views::viewpointChecks" },
185074
- RenderingDecl: { def: "Views::Rendering", usage: "Views::renderings" },
185075
- RequirementDecl: { def: "Requirements::RequirementCheck", usage: "Requirements::requirementChecks" },
185076
- ConcernDecl: { def: "Requirements::ConcernCheck", usage: "Requirements::concernChecks" },
185077
- ConstraintDecl: { def: "Constraints::ConstraintCheck", usage: "Constraints::constraintChecks" },
185078
- CalcDecl: { def: "Calculations::Calculation", usage: "Calculations::calculations" },
185079
- AllocationDecl: { def: "Allocations::Allocation", usage: "Allocations::allocations" },
185080
- AttributeDecl: { def: "Attributes::AttributeValue", usage: "Attributes::attributeValues" },
185081
- OccurrenceDecl: { def: "Occurrences::Occurrence", usage: "Occurrences::occurrences" },
185082
- MetadataDecl: { def: "Metadata::MetadataItem", usage: "Metadata::metadataItems" }
185083
- });
185084
185689
  var OCCURRENCE_KIND_OWNERS = /* @__PURE__ */ new Set([
185085
185690
  ...Object.keys(IMPLICIT_BASES).filter((kind) => kind !== "AttributeDecl"),
185086
185691
  // KerML fixes a library base per classifier kind too, in the same way and in
@@ -185115,14 +185720,9 @@ var NON_VARYING_LIBRARY_TYPES = /* @__PURE__ */ new Set(["SelfLink", "HappensLin
185115
185720
  function markdown(value) {
185116
185721
  return { kind: import_vscode_languageserver20.MarkupKind.Markdown, value };
185117
185722
  }
185118
- function allRelationships2(node) {
185723
+ function allRelationships3(node) {
185119
185724
  return [...node.preRelationships ?? [], ...node.relationships ?? []];
185120
185725
  }
185121
- function hasExplicitSpecialization(node) {
185122
- if (node.typing?.type?.$refText)
185123
- return true;
185124
- return allRelationships2(node).some((rel2) => rel2.kind && EXPLICIT_SPECIALIZATION_KINDS.has(rel2.kind));
185125
- }
185126
185726
  function keywordLeaf(node, keyword) {
185127
185727
  const cst = node.$cstNode;
185128
185728
  if (!cst)
@@ -185146,7 +185746,7 @@ function specializesNonVaryingLibraryType(node) {
185146
185746
  const typing = node.typing?.type?.$refText;
185147
185747
  if (typing && NON_VARYING_LIBRARY_TYPES.has(lastSegment3(typing)))
185148
185748
  return true;
185149
- return allRelationships2(node).flatMap((rel2) => rel2.targets ?? []).some((target) => NON_VARYING_LIBRARY_TYPES.has(lastSegment3(target)));
185749
+ return allRelationships3(node).flatMap((rel2) => rel2.targets ?? []).some((target) => NON_VARYING_LIBRARY_TYPES.has(lastSegment3(target)));
185150
185750
  }
185151
185751
  function constantAnchor(node) {
185152
185752
  const cst = node.$cstNode;
@@ -185210,16 +185810,6 @@ function callArguments(node) {
185210
185810
  }
185211
185811
  var SysmlInlayHintProvider = class {
185212
185812
  services;
185213
- /**
185214
- * Resolved implicit bases, keyed by the qualified name in
185215
- * {@link IMPLICIT_BASES}. A base the index does not hold is NOT cached — the
185216
- * library may still be loading — and issue #240 made that miss cheap: two
185217
- * lookups in the shared name index rather than the full index scan it used
185218
- * to be, on a request VS Code re-issues on every scroll. A HIT is cached
185219
- * until the index is rebuilt, so the description a label links to always
185220
- * carries the ranges of the generation it was read from.
185221
- */
185222
- baseCache = /* @__PURE__ */ new Map();
185223
185813
  /**
185224
185814
  * REQ-395 — issue #240: the shared name lookup, built once per index
185225
185815
  * generation. Every category that resolves a WRITTEN name goes through it,
@@ -185264,7 +185854,6 @@ var SysmlInlayHintProvider = class {
185264
185854
  this.linker = services?.references.Linker;
185265
185855
  this.featureProperties = featurePropertyResolver(new FeaturePathResolver(services));
185266
185856
  services?.shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.IndexedContent, () => {
185267
- this.baseCache.clear();
185268
185857
  this.constantCache.clear();
185269
185858
  this.declaredNameCache.clear();
185270
185859
  this.effectiveNameResolvers = /* @__PURE__ */ new WeakMap();
@@ -185372,26 +185961,6 @@ var SysmlInlayHintProvider = class {
185372
185961
  ...node.$type === "VariantReference" || isOwnedEnumerationValue(node) ? {} : { textEdits: [{ range: { start: at, end: at }, newText: "ref " }] }
185373
185962
  });
185374
185963
  }
185375
- if (settings.specialization && node.$cstNode && decl.name && !hasExplicitSpecialization(decl)) {
185376
- const entry = IMPLICIT_BASES[node.$type];
185377
- const qualified = entry ? decl.isDef ? entry.def : entry.usage : void 0;
185378
- const description = qualified ? this.resolveImplicitBase(qualified, decl.isDef !== true) : void 0;
185379
- if (qualified && description) {
185380
- hints.push({
185381
- position: multiplicityAnchor(node.$cstNode),
185382
- label: [{
185383
- value: ` :> ${qualified}`,
185384
- location: {
185385
- uri: description.documentUri.toString(),
185386
- range: descriptionRange(description)
185387
- }
185388
- }],
185389
- kind: import_vscode_languageserver20.InlayHintKind.Type,
185390
- paddingLeft: true,
185391
- tooltip: markdown(`Implicitly specializes \`${qualified}\` from the standard library.`)
185392
- });
185393
- }
185394
- }
185395
185964
  if (settings.redefinition)
185396
185965
  hints.push(...this.parameterRedefinitionHints(decl));
185397
185966
  if (settings.effectiveNames) {
@@ -185462,7 +186031,7 @@ var SysmlInlayHintProvider = class {
185462
186031
  const parameter = mine[index2].node;
185463
186032
  if (!parameter.name || !parameter.$cstNode)
185464
186033
  continue;
185465
- if (allRelationships2(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind)))
186034
+ if (allRelationships3(parameter).some((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind)))
185466
186035
  continue;
185467
186036
  const target = theirs[index2].node;
185468
186037
  if (!target.name || target.name === parameter.name)
@@ -185657,7 +186226,7 @@ var SysmlInlayHintProvider = class {
185657
186226
  return void 0;
185658
186227
  if (specializesNonVaryingLibraryType(node))
185659
186228
  return void 0;
185660
- const carrier = allRelationships2(node).filter((rel2) => rel2.kind && CONSTANT_CARRYING_KINDS.has(rel2.kind)).flatMap((rel2) => rel2.targets ?? []).find((target) => this.isConstantFeature(target));
186229
+ const carrier = allRelationships3(node).filter((rel2) => rel2.kind && CONSTANT_CARRYING_KINDS.has(rel2.kind)).flatMap((rel2) => rel2.targets ?? []).find((target) => this.isConstantFeature(target));
185661
186230
  if (!carrier)
185662
186231
  return void 0;
185663
186232
  const anchor = constantAnchor(node);
@@ -185701,41 +186270,11 @@ var SysmlInlayHintProvider = class {
185701
186270
  this.constantCache.set(key2, answer);
185702
186271
  return answer;
185703
186272
  }
185704
- /**
185705
- * REQ-395 — Find one implicit base in the index.
185706
- *
185707
- * A description whose name is the full qualified spelling wins outright. The
185708
- * index otherwise keys library symbols by their simple name, so the fallback
185709
- * requires BOTH a standard-library document and the right side of the
185710
- * definition/usage split, which the precomputed index records — that is what
185711
- * keeps `Parts::Part` from matching a `part Part` somewhere else.
185712
- */
185713
- resolveImplicitBase(qualified, wantUsage) {
185714
- const cached = this.baseCache.get(qualified);
185715
- if (cached)
185716
- return cached;
185717
- if (!this.lookup)
185718
- return void 0;
185719
- const exact = this.lookup.descriptions(qualified).at(0);
185720
- if (exact) {
185721
- this.baseCache.set(qualified, exact);
185722
- return exact;
185723
- }
185724
- const fallback = this.lookup.descriptions(lastSegment3(qualified)).find((description) => {
185725
- const uri = description.documentUri instanceof URI2 ? description.documentUri : URI2.parse(String(description.documentUri));
185726
- if (!isStandardLibraryUri(uri))
185727
- return false;
185728
- return description.isUsage === true === wantUsage;
185729
- });
185730
- if (fallback)
185731
- this.baseCache.set(qualified, fallback);
185732
- return fallback;
185733
- }
185734
186273
  };
185735
186274
  function effectiveNameHint(node, resolver) {
185736
186275
  if (node.name || node.shortName?.name || !node.$cstNode)
185737
186276
  return void 0;
185738
- const redefinition = allRelationships2(node).find((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
186277
+ const redefinition = allRelationships3(node).find((rel2) => rel2.kind && REDEFINITION_KINDS4.has(rel2.kind) && (rel2.targets?.length ?? 0) > 0);
185739
186278
  if (!redefinition?.targets?.[0])
185740
186279
  return void 0;
185741
186280
  const names = effectiveNamesOf(node, resolver);
@@ -185822,10 +186361,26 @@ var SysmlCodeLensProvider = class {
185822
186361
  constructor(services) {
185823
186362
  this.services = services;
185824
186363
  }
185825
- // TSK_023 — A "N references" lens above a definition (find-references on click).
185826
- referencesLens(node, uri, range) {
186364
+ // TSK_023 — Every reference tally this pass needs, from one workspace sweep.
186365
+ // A sweep resolves every written path in every document, so one per lens made
186366
+ // a file with a dozen requirement definitions take seconds and the lenses
186367
+ // never reached the editor.
186368
+ referenceCounts(root4) {
186369
+ const targets = [];
186370
+ walkAst(root4, (node) => {
186371
+ if (isRequirementDecl(node) && node.isDef && node.name)
186372
+ targets.push(node);
186373
+ if (isVerificationCaseDecl(node) && node.isDef && node.name)
186374
+ targets.push(node);
186375
+ });
185827
186376
  const refProvider = this.services.lsp.ReferencesProvider;
185828
- const count = typeof refProvider?.referenceCount === "function" ? refProvider.referenceCount(node) : 0;
186377
+ if (typeof refProvider?.referenceCounts !== "function")
186378
+ return /* @__PURE__ */ new Map();
186379
+ return refProvider.referenceCounts(targets);
186380
+ }
186381
+ // TSK_023 — A "N references" lens above a definition (find-references on click).
186382
+ referencesLens(node, uri, range, counts) {
186383
+ const count = counts.get(node) ?? 0;
185829
186384
  return {
185830
186385
  range,
185831
186386
  command: {
@@ -185844,6 +186399,7 @@ var SysmlCodeLensProvider = class {
185844
186399
  const uri = document2.uri.toString();
185845
186400
  const requirements = indexByName(root4, "RequirementDecl");
185846
186401
  const parts = indexByName(root4, "PartDecl");
186402
+ const counts = this.referenceCounts(root4);
185847
186403
  walkAst(root4, (node) => {
185848
186404
  const cst = node.$cstNode;
185849
186405
  if (!cst)
@@ -185877,7 +186433,7 @@ var SysmlCodeLensProvider = class {
185877
186433
  });
185878
186434
  }
185879
186435
  if (isRequirementDecl(node) && node.isDef && node.name) {
185880
- lenses.push(this.referencesLens(node, uri, range));
186436
+ lenses.push(this.referencesLens(node, uri, range, counts));
185881
186437
  }
185882
186438
  if (isVerificationCaseDecl(node) && node.isDef && node.name) {
185883
186439
  const result = evaluateVerificationCase(node, (name) => requirements.get(name), (name) => parts.get(name));
@@ -185897,7 +186453,7 @@ var SysmlCodeLensProvider = class {
185897
186453
  arguments: [uri, node.name]
185898
186454
  }
185899
186455
  });
185900
- lenses.push(this.referencesLens(node, uri, range));
186456
+ lenses.push(this.referencesLens(node, uri, range, counts));
185901
186457
  }
185902
186458
  });
185903
186459
  return lenses;
@@ -186113,6 +186669,14 @@ var SysmlReferencesProvider = class extends DefaultReferencesProvider {
186113
186669
  referenceCount(target) {
186114
186670
  return this.references.findReferences(target, { includeDeclaration: false }).count();
186115
186671
  }
186672
+ // TSK_023 - One sweep answers every tally a CodeLens pass needs. Counting them
186673
+ // one at a time repeats the whole written-path scan per lens.
186674
+ referenceCounts(targets) {
186675
+ const references = this.references;
186676
+ if (typeof references?.referenceCounts === "function")
186677
+ return references.referenceCounts(targets);
186678
+ return new Map(targets.map((target) => [target, this.referenceCount(target)]));
186679
+ }
186116
186680
  };
186117
186681
 
186118
186682
  // ../language-server/out/src/services/written-path-references.js
@@ -186128,6 +186692,53 @@ var WrittenPathReferences = class extends DefaultReferences {
186128
186692
  const segment = this.paths.segmentAt(source);
186129
186693
  return segment ? segment.target : super.findDeclaration(source);
186130
186694
  }
186695
+ /**
186696
+ * TSK_023 - How many references each target has, in ONE workspace sweep.
186697
+ *
186698
+ * `findReferences` resolves every written path in every document, so asking
186699
+ * it per target multiplies that sweep by the number of targets. A CodeLens
186700
+ * pass over a file with a dozen requirement definitions paid it a dozen
186701
+ * times and took seconds, which reads in the editor as lenses that never
186702
+ * appear. The tally below answers all of them from a single sweep.
186703
+ */
186704
+ referenceCounts(targets) {
186705
+ const counts = new Map(targets.map((target) => [target, 0]));
186706
+ if (targets.length === 0)
186707
+ return counts;
186708
+ const seen = new Map(targets.map((target) => [target, /* @__PURE__ */ new Set()]));
186709
+ const byIdentity = /* @__PURE__ */ new Map();
186710
+ for (const target of targets) {
186711
+ const targetUri = ast_utils_exports.getDocument(target).uri.toString();
186712
+ byIdentity.set(`${targetUri}|${this.nodeLocator.getAstNodePath(target)}`, target);
186713
+ const found = seen.get(target);
186714
+ for (const reference of super.findReferences(target, { includeDeclaration: false })) {
186715
+ const key2 = `${reference.sourceUri}|${reference.segment.offset}`;
186716
+ if (found.has(key2))
186717
+ continue;
186718
+ found.add(key2);
186719
+ counts.set(target, (counts.get(target) ?? 0) + 1);
186720
+ }
186721
+ }
186722
+ for (const document2 of this.documents.all) {
186723
+ for (const node of ast_utils_exports.streamAllContents(document2.parseResult.value)) {
186724
+ for (const path10 of this.paths.writtenPaths(node)) {
186725
+ for (const segment of path10.segments) {
186726
+ const description = segment.description;
186727
+ const target = segment.target && counts.has(segment.target) ? segment.target : description ? byIdentity.get(`${description.documentUri.toString()}|${description.path}`) : void 0;
186728
+ if (!target)
186729
+ continue;
186730
+ const found = seen.get(target);
186731
+ const key2 = `${document2.uri}|${segment.cst.offset}`;
186732
+ if (found.has(key2))
186733
+ continue;
186734
+ found.add(key2);
186735
+ counts.set(target, (counts.get(target) ?? 0) + 1);
186736
+ }
186737
+ }
186738
+ }
186739
+ }
186740
+ return counts;
186741
+ }
186131
186742
  findReferences(target, options) {
186132
186743
  const result = super.findReferences(target, options).toArray();
186133
186744
  const targetUri = ast_utils_exports.getDocument(target).uri;
@@ -186996,6 +187607,8 @@ function ownedRelationshipTargets(element, typePattern) {
186996
187607
  for (const relationship of toArray(element.ownedRelationship)) {
186997
187608
  if (!isObject3(relationship))
186998
187609
  continue;
187610
+ if (relationship.isImplied === true)
187611
+ continue;
186999
187612
  const type = stringValue(relationship["@type"]) ?? "";
187000
187613
  if (!typePattern.test(type))
187001
187614
  continue;
@@ -209624,7 +210237,7 @@ async function runExport(command) {
209624
210237
  }
209625
210238
 
209626
210239
  // src/main.ts
209627
- var VERSION2 = true ? "0.31.1" : "dev";
210240
+ var VERSION2 = true ? "0.32.0" : "dev";
209628
210241
  function display(file) {
209629
210242
  const rel2 = path9.relative(process.cwd(), file);
209630
210243
  return rel2 && !rel2.startsWith("..") ? rel2.split(path9.sep).join("/") : file;