sysml-v2-lsp 0.34.0 → 0.36.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.
@@ -3362,7 +3362,7 @@ ${JSON.stringify(message, null, 4)}`);
3362
3362
  }
3363
3363
  uinteger3.is = is;
3364
3364
  })(uinteger || (uinteger = {}));
3365
- (function(Position4) {
3365
+ (function(Position5) {
3366
3366
  function create(line, character) {
3367
3367
  if (line === Number.MAX_VALUE) {
3368
3368
  line = uinteger.MAX_VALUE;
@@ -3372,14 +3372,14 @@ ${JSON.stringify(message, null, 4)}`);
3372
3372
  }
3373
3373
  return { line, character };
3374
3374
  }
3375
- Position4.create = create;
3375
+ Position5.create = create;
3376
3376
  function is(value) {
3377
3377
  const candidate = value;
3378
3378
  return Is.objectLiteral(candidate) && Is.uinteger(candidate.line) && Is.uinteger(candidate.character);
3379
3379
  }
3380
- Position4.is = is;
3380
+ Position5.is = is;
3381
3381
  })(Position || (Position = {}));
3382
- (function(Range4) {
3382
+ (function(Range5) {
3383
3383
  function create(one, two, three, four) {
3384
3384
  if (Is.uinteger(one) && Is.uinteger(two) && Is.uinteger(three) && Is.uinteger(four)) {
3385
3385
  return { start: Position.create(one, two), end: Position.create(three, four) };
@@ -3389,12 +3389,12 @@ ${JSON.stringify(message, null, 4)}`);
3389
3389
  throw new Error(`Range#create called with invalid arguments[${one}, ${two}, ${three}, ${four}]`);
3390
3390
  }
3391
3391
  }
3392
- Range4.create = create;
3392
+ Range5.create = create;
3393
3393
  function is(value) {
3394
3394
  const candidate = value;
3395
3395
  return Is.objectLiteral(candidate) && Position.is(candidate.start) && Position.is(candidate.end);
3396
3396
  }
3397
- Range4.is = is;
3397
+ Range5.is = is;
3398
3398
  })(Range || (Range = {}));
3399
3399
  (function(Location4) {
3400
3400
  function create(uri, range) {
@@ -12435,7 +12435,7 @@ ${JSON.stringify(message, null, 4)}`);
12435
12435
  }
12436
12436
  uinteger3.is = is;
12437
12437
  })(uinteger2 || (uinteger2 = {}));
12438
- (function(Position4) {
12438
+ (function(Position5) {
12439
12439
  function create(line, character) {
12440
12440
  if (line === Number.MAX_VALUE) {
12441
12441
  line = uinteger2.MAX_VALUE;
@@ -12445,14 +12445,14 @@ ${JSON.stringify(message, null, 4)}`);
12445
12445
  }
12446
12446
  return { line, character };
12447
12447
  }
12448
- Position4.create = create;
12448
+ Position5.create = create;
12449
12449
  function is(value) {
12450
12450
  let candidate = value;
12451
12451
  return Is2.objectLiteral(candidate) && Is2.uinteger(candidate.line) && Is2.uinteger(candidate.character);
12452
12452
  }
12453
- Position4.is = is;
12453
+ Position5.is = is;
12454
12454
  })(Position2 || (Position2 = {}));
12455
- (function(Range4) {
12455
+ (function(Range5) {
12456
12456
  function create(one, two, three, four) {
12457
12457
  if (Is2.uinteger(one) && Is2.uinteger(two) && Is2.uinteger(three) && Is2.uinteger(four)) {
12458
12458
  return { start: Position2.create(one, two), end: Position2.create(three, four) };
@@ -12462,12 +12462,12 @@ ${JSON.stringify(message, null, 4)}`);
12462
12462
  throw new Error(`Range#create called with invalid arguments[${one}, ${two}, ${three}, ${four}]`);
12463
12463
  }
12464
12464
  }
12465
- Range4.create = create;
12465
+ Range5.create = create;
12466
12466
  function is(value) {
12467
12467
  let candidate = value;
12468
12468
  return Is2.objectLiteral(candidate) && Position2.is(candidate.start) && Position2.is(candidate.end);
12469
12469
  }
12470
- Range4.is = is;
12470
+ Range5.is = is;
12471
12471
  })(Range2 || (Range2 = {}));
12472
12472
  (function(Location4) {
12473
12473
  function create(uri, range) {
@@ -130252,6 +130252,10 @@ ${JSON.stringify(message, null, 4)}`);
130252
130252
  function canonicalUri(uri) {
130253
130253
  return uri.replace(/^file:\/\/\/([A-Za-z])(?::|%3[Aa])(?=\/|$)/, (_m, drive) => `file:///${drive.toLowerCase()}:`);
130254
130254
  }
130255
+ function isInFolder(uri, folderUri) {
130256
+ const folder = canonicalUri(folderUri);
130257
+ return canonicalUri(uri).startsWith(folder.endsWith("/") ? folder : `${folder}/`);
130258
+ }
130255
130259
  function isSameDocumentUri(a, b) {
130256
130260
  return a === b || canonicalUri(a) === canonicalUri(b);
130257
130261
  }
@@ -130410,6 +130414,7 @@ ${JSON.stringify(message, null, 4)}`);
130410
130414
  var NAMESPACE_URL = v5_default.URL;
130411
130415
  var DEFAULT_URL_PREFIX = "https://github.com/daltskin/sysml-v2-lsp/";
130412
130416
  var urlPrefix = DEFAULT_URL_PREFIX;
130417
+ var folderPrefixes = [];
130413
130418
  function setProjectId(projectId) {
130414
130419
  if (projectId === void 0) {
130415
130420
  urlPrefix = DEFAULT_URL_PREFIX;
@@ -130419,8 +130424,14 @@ ${JSON.stringify(message, null, 4)}`);
130419
130424
  urlPrefix = `urn:uuid:${projectId.toLowerCase()}/`;
130420
130425
  return true;
130421
130426
  }
130422
- function getUrlPrefix() {
130423
- return urlPrefix;
130427
+ function setFolderProjectIds(projectIds) {
130428
+ const rejected = projectIds.filter((p) => !validate_default(p.projectId));
130429
+ folderPrefixes = projectIds.filter((p) => validate_default(p.projectId)).map((p) => ({ folderUri: p.folderUri, prefix: `urn:uuid:${p.projectId.toLowerCase()}/` })).sort((a, b) => b.folderUri.length - a.folderUri.length);
130430
+ return rejected;
130431
+ }
130432
+ function getUrlPrefix(uri) {
130433
+ const match = uri === void 0 ? void 0 : folderPrefixes.find((f2) => isInFolder(uri, f2.folderUri));
130434
+ return match?.prefix ?? urlPrefix;
130424
130435
  }
130425
130436
  function uuidV5(namespace, name) {
130426
130437
  return v5_default(name, namespace);
@@ -130502,6 +130513,10 @@ ${JSON.stringify(message, null, 4)}`);
130502
130513
  return "RequirementDefinition";
130503
130514
  case "requirement" /* RequirementUsage */:
130504
130515
  return "RequirementUsage";
130516
+ case "concern def" /* ConcernDef */:
130517
+ return "ConcernDefinition";
130518
+ case "concern" /* ConcernUsage */:
130519
+ return "ConcernUsage";
130505
130520
  case "constraint def" /* ConstraintDef */:
130506
130521
  return "ConstraintDefinition";
130507
130522
  case "constraint" /* ConstraintUsage */:
@@ -130624,7 +130639,7 @@ ${JSON.stringify(message, null, 4)}`);
130624
130639
  declaration.parentId = owner?.symbolId;
130625
130640
  const path = declaration.qualifiedName !== void 0 ? this.qualifiedNameAsWritten(declaration) : owner ? `${this.paths.get(owner)}/${segmentOf(declaration)}` : segmentOf(declaration);
130626
130641
  const namespace = owner ? this.topLevelOf(owner).symbolId : NAMESPACE_URL;
130627
- const key = owner ? path : getUrlPrefix() + encodeURIComponent(path);
130642
+ const key = owner ? path : getUrlPrefix(declaration.uri) + encodeURIComponent(path);
130628
130643
  const groupId = this.uuidOf(namespace, key);
130629
130644
  this.groupKeys.set(groupId, { namespace, key, path });
130630
130645
  this.groupOf.set(declaration, groupId);
@@ -130809,6 +130824,12 @@ ${JSON.stringify(message, null, 4)}`);
130809
130824
  // 343
130810
130825
  [SysMLv2Parser.RULE_requirementDefinition, "requirement def" /* RequirementDef */],
130811
130826
  // 384
130827
+ [SysMLv2Parser.RULE_concernDefinition, "concern def" /* ConcernDef */],
130828
+ // 405
130829
+ [SysMLv2Parser.RULE_concernUsage, "concern" /* ConcernUsage */],
130830
+ // 406
130831
+ [SysMLv2Parser.RULE_framedConcernUsage, "concern" /* ConcernUsage */],
130832
+ // 394
130812
130833
  [SysMLv2Parser.RULE_constraintDefinition, "constraint def" /* ConstraintDef */],
130813
130834
  // 380
130814
130835
  [SysMLv2Parser.RULE_itemDefinition, "item def" /* ItemDef */],
@@ -130881,6 +130902,10 @@ ${JSON.stringify(message, null, 4)}`);
130881
130902
  // 268
130882
130903
  [SysMLv2Parser.RULE_performActionUsage, "perform action" /* PerformActionUsage */],
130883
130904
  // 298
130905
+ // A state's `entry`/`do`/`exit` action (`exit action a : A;`, `exit a;`): the
130906
+ // StatePerformActionUsage production, a PerformActionUsage without `perform`.
130907
+ [SysMLv2Parser.RULE_statePerformActionUsage, "perform action" /* PerformActionUsage */],
130908
+ // 352
130884
130909
  [SysMLv2Parser.RULE_exhibitStateUsage, "exhibit state" /* ExhibitStateUsage */],
130885
130910
  // 359
130886
130911
  [SysMLv2Parser.RULE_transitionUsage, "transition" /* TransitionUsage */],
@@ -131004,8 +131029,10 @@ ${JSON.stringify(message, null, 4)}`);
131004
131029
  // 210
131005
131030
  SysMLv2Parser.RULE_definition,
131006
131031
  // 192
131007
- SysMLv2Parser.RULE_usage
131032
+ SysMLv2Parser.RULE_usage,
131008
131033
  // 208
131034
+ SysMLv2Parser.RULE_payloadFeatureSpecializationPart
131035
+ // 157
131009
131036
  ]);
131010
131037
  var DOC_RULE_INDICES = /* @__PURE__ */ new Set([
131011
131038
  SysMLv2Parser.RULE_comment,
@@ -131630,8 +131657,9 @@ ${JSON.stringify(message, null, 4)}`);
131630
131657
  const shortName = transition || isFlowUsage(kind) && !declaredName ? void 0 : this.extractShortName(ctx);
131631
131658
  const qualifiedName = anonymous || owner && owner.qualifiedName === void 0 ? void 0 : owner ? `${owner.qualifiedName}::${name}` : name;
131632
131659
  const selectionRange = anonymous ? ctx.start ? tokenToRange(ctx.start) : range : this.extractNameRange(ctx) ?? range;
131633
- const typeNames = isFlowUsage(kind) ? this.extractFlowTypeNames(ctx) : this.extractTypeNames(ctx);
131660
+ const typeNames = isFlowUsage(kind) ? this.extractFlowTypeNames(ctx) : transition ? this.extractTransitionTypeNames(ctx) : this.extractTypeNames(ctx);
131634
131661
  const specializationNames = this.extractSpecializationNames(ctx);
131662
+ const redefinedFeatureTargets = this.extractRedefinedFeatureTargets(ctx);
131635
131663
  const typeName = typeNames[0];
131636
131664
  const documentation = this.extractDocumentation(ctx);
131637
131665
  const visibility = this.extractVisibility(ctx);
@@ -131662,6 +131690,7 @@ ${JSON.stringify(message, null, 4)}`);
131662
131690
  typeName,
131663
131691
  typeNames,
131664
131692
  specializationNames,
131693
+ redefinedFeatureTargets: redefinedFeatureTargets.length > 0 ? redefinedFeatureTargets : void 0,
131665
131694
  documentation,
131666
131695
  visibility,
131667
131696
  source: transition?.source,
@@ -131745,6 +131774,25 @@ ${JSON.stringify(message, null, 4)}`);
131745
131774
  const typeDeclaration = declaration && (this.findOwnHeaderRule(declaration, SysMLv2Parser.RULE_featureDeclaration) ?? this.findOwnHeaderRule(declaration, SysMLv2Parser.RULE_usageDeclaration));
131746
131775
  return typeDeclaration ? this.extractTypeNames(typeDeclaration) : [];
131747
131776
  }
131777
+ /**
131778
+ * A transition's own typing, then the types of the payload its trigger
131779
+ * accepts (`accept cmd : Command`, `accept Command`; TriggerAction ->
131780
+ * AcceptParameterPart -> PayloadParameter). Read from the parse tree only:
131781
+ * the regex fallback of `extractTypeNames` runs on whitespace-free text, where
131782
+ * the payload type runs into the guard, effect or target that follows it
131783
+ * (`Commandifcmd`, `Commandthenbusy`).
131784
+ */
131785
+ extractTransitionTypeNames(ctx) {
131786
+ const names = [];
131787
+ this.collectTypeNamesFromTree(ctx, names, 0);
131788
+ const trigger = this.findOwnHeaderRule(ctx, SysMLv2Parser.RULE_triggerActionMember);
131789
+ const parameter = trigger && this.findRuleContext(trigger, SysMLv2Parser.RULE_payloadParameter);
131790
+ if (parameter) {
131791
+ const payload = this.findRuleContext(parameter, SysMLv2Parser.RULE_payloadFeature) ?? parameter;
131792
+ this.collectTypeNamesFromTree(payload, names, 0);
131793
+ }
131794
+ return names;
131795
+ }
131748
131796
  /** Find the first descendant of `ctx` with rule `ruleIndex`, in source order. */
131749
131797
  findRuleContext(ctx, ruleIndex) {
131750
131798
  const matches = [];
@@ -131870,7 +131918,7 @@ ${JSON.stringify(message, null, 4)}`);
131870
131918
  */
131871
131919
  anonymousDeclaration(ctx, kind, transition) {
131872
131920
  if (!isDefinition(kind) && !isUsage(kind)) return void 0;
131873
- if (transition && !(transition.source && transition.target) && this.extractTypeNames(ctx).length === 0) return void 0;
131921
+ if (transition && !(transition.source && transition.target) && this.extractTransitionTypeNames(ctx).length === 0) return void 0;
131874
131922
  return this.declarationText(ctx);
131875
131923
  }
131876
131924
  /**
@@ -131894,15 +131942,28 @@ ${JSON.stringify(message, null, 4)}`);
131894
131942
  * such as `#metadata`.
131895
131943
  */
131896
131944
  findOwnHeaderRule(ctx, ruleIndex) {
131945
+ const matches = [];
131946
+ this.findOwnHeaderRules(ctx, ruleIndex, matches, true);
131947
+ return matches[0];
131948
+ }
131949
+ findOwnHeaderRules(ctx, ruleIndex, matches, firstOnly = false) {
131897
131950
  for (let i = 0; i < ctx.getChildCount(); i++) {
131898
131951
  const child = ctx.getChild(i);
131899
131952
  if (!(child instanceof ParserRuleContext)) continue;
131900
- if (child.ruleIndex === ruleIndex) return child;
131953
+ if (child.ruleIndex === ruleIndex) {
131954
+ matches.push(child);
131955
+ if (firstOnly) return;
131956
+ continue;
131957
+ }
131901
131958
  if (RULE_INDEX_TO_KIND.has(child.ruleIndex) || BODY_RULE_INDICES.has(child.ruleIndex) || child.ruleIndex === SysMLv2Parser.RULE_valuePart || FLOW_PART_RULE_INDICES.has(child.ruleIndex) || child.ruleIndex === SysMLv2Parser.RULE_ownedCrossMultiplicityMember || this.isPrefixOrExtensionContext(child)) continue;
131902
- const found = this.findOwnHeaderRule(child, ruleIndex);
131903
- if (found) return found;
131959
+ this.findOwnHeaderRules(child, ruleIndex, matches, firstOnly);
131960
+ if (firstOnly && matches.length > 0) return;
131904
131961
  }
131905
- return void 0;
131962
+ }
131963
+ extractRedefinedFeatureTargets(ctx) {
131964
+ const targets = [];
131965
+ this.findOwnHeaderRules(ctx, SysMLv2Parser.RULE_ownedRedefinition, targets);
131966
+ return targets.map((target) => target.getText());
131906
131967
  }
131907
131968
  /**
131908
131969
  * A connection, interface or allocation usage's end reference paths, in
@@ -131930,13 +131991,7 @@ ${JSON.stringify(message, null, 4)}`);
131930
131991
  const segment = reference.getText().split(/::|\./).pop();
131931
131992
  return segment ? this.unquoteName(segment) : void 0;
131932
131993
  }
131933
- /**
131934
- * An element's declaration as written, without its body: its tokens up to
131935
- * its body or closing `;`, each exactly as written (a quoted name keeps its
131936
- * spaces), with one space wherever the source has whitespace or a comment
131937
- * between two of them (`connect a.p to b.p`, `connection : Conn`).
131938
- */
131939
- declarationText(ctx) {
131994
+ declarationTokens(ctx) {
131940
131995
  const tokens = [];
131941
131996
  const visit = (node) => {
131942
131997
  for (let i = 0; i < node.getChildCount(); i++) {
@@ -131951,6 +132006,16 @@ ${JSON.stringify(message, null, 4)}`);
131951
132006
  return false;
131952
132007
  };
131953
132008
  visit(ctx);
132009
+ return tokens;
132010
+ }
132011
+ /**
132012
+ * An element's declaration as written, without its body: its tokens up to
132013
+ * its body or closing `;`, each exactly as written (a quoted name keeps its
132014
+ * spaces), with one space wherever the source has whitespace or a comment
132015
+ * between two of them (`connect a.p to b.p`, `connection : Conn`).
132016
+ */
132017
+ declarationText(ctx) {
132018
+ const tokens = this.declarationTokens(ctx);
131954
132019
  let text = "";
131955
132020
  tokens.forEach((token, i) => {
131956
132021
  if (i > 0 && token.start > tokens[i - 1].stop + 1) text += " ";
@@ -132091,17 +132156,16 @@ ${JSON.stringify(message, null, 4)}`);
132091
132156
  const names = [];
132092
132157
  this.collectTypeNamesFromTree(ctx, names, 0);
132093
132158
  if (names.length > 0) return names;
132094
- const fullText = ctx.getText();
132095
- const braceIdx = fullText.indexOf("{");
132096
- let text = braceIdx >= 0 ? fullText.substring(0, braceIdx) : fullText;
132159
+ const { text: declarationText, quotedName } = this.maskedDeclaration(ctx);
132160
+ let text = declarationText;
132097
132161
  text = text.replace(RE_KEYWORD_TRUNCATE, "");
132098
132162
  const specMatch = text.match(RE_SPEC);
132099
132163
  if (specMatch) {
132100
132164
  const specStr = text.substring(text.indexOf(specMatch[0]) + specMatch[0].indexOf(specMatch[1]));
132101
132165
  for (const part of specStr.split(",")) {
132102
- const qm = part.match(RE_QUOTED_NAME);
132103
- if (qm) {
132104
- names.push(qm[1]);
132166
+ const quoted = quotedName(part);
132167
+ if (quoted !== void 0) {
132168
+ names.push(quoted);
132105
132169
  continue;
132106
132170
  }
132107
132171
  const m2 = part.trim().match(RE_IDENT_START);
@@ -132122,9 +132186,9 @@ ${JSON.stringify(message, null, 4)}`);
132122
132186
  const fullMatchIdx = text.indexOf(typingMatch[0]);
132123
132187
  const afterColon = text.substring(fullMatchIdx + 1).trim();
132124
132188
  for (const part of afterColon.split(",")) {
132125
- const qm = part.match(RE_QUOTED_NAME);
132126
- if (qm) {
132127
- names.push(qm[1]);
132189
+ const quoted = quotedName(part);
132190
+ if (quoted !== void 0) {
132191
+ names.push(quoted);
132128
132192
  continue;
132129
132193
  }
132130
132194
  const m2 = part.trim().match(RE_IDENT_START);
@@ -132134,6 +132198,28 @@ ${JSON.stringify(message, null, 4)}`);
132134
132198
  }
132135
132199
  return names;
132136
132200
  }
132201
+ /**
132202
+ * The declaration tokens before the body, with each lexer STRING token
132203
+ * replaced by a numbered placeholder (`'0'`, `'1'`, ...), and
132204
+ * `quotedName`, which turns a placeholder in a part of that text back into
132205
+ * the name. SysML 2.0 section 7.2.2 permits punctuation in unrestricted
132206
+ * names (the STRING lexer production), so fallback regexes must never see
132207
+ * their `:`, `:>`, `{` or keywords. Documentation is not a name token.
132208
+ */
132209
+ maskedDeclaration(ctx) {
132210
+ const quoted = [];
132211
+ const masked = this.declarationTokens(ctx).map((token) => {
132212
+ const text = token.text ?? "";
132213
+ return token.type === SysMLv2Lexer.STRING ? `'${quoted.push(text.slice(1, -1)) - 1}'` : text;
132214
+ }).join("");
132215
+ return {
132216
+ text: masked,
132217
+ quotedName: (part) => {
132218
+ const qm = part.match(RE_QUOTED_NAME);
132219
+ return qm ? quoted[Number(qm[1])] : void 0;
132220
+ }
132221
+ };
132222
+ }
132137
132223
  /**
132138
132224
  * Extract only the specialization names (:> / specializes / subsets) from a context.
132139
132225
  * Uses the same tree-walk as extractTypeNames but restricted to
@@ -132144,17 +132230,15 @@ ${JSON.stringify(message, null, 4)}`);
132144
132230
  const names = [];
132145
132231
  this.collectNamesFromTree(ctx, names, 0, TYPE_SPECIALIZATION_RULE_INDICES);
132146
132232
  if (names.length > 0) return names;
132147
- const fullText = ctx.getText();
132148
- const braceIdx = fullText.indexOf("{");
132149
- let text = braceIdx >= 0 ? fullText.substring(0, braceIdx) : fullText;
132150
- text = text.replace(RE_KEYWORD_TRUNCATE_SPEC, "");
132233
+ const { text: declarationText, quotedName } = this.maskedDeclaration(ctx);
132234
+ const text = declarationText.replace(RE_KEYWORD_TRUNCATE_SPEC, "");
132151
132235
  const specMatch = text.match(RE_SPEC_WITH_SUBSETS);
132152
132236
  if (specMatch) {
132153
132237
  const specStr = text.substring(text.indexOf(specMatch[0]) + specMatch[0].indexOf(specMatch[1]));
132154
132238
  for (const part of specStr.split(",")) {
132155
- const qm = part.match(RE_QUOTED_NAME);
132156
- if (qm) {
132157
- names.push(qm[1]);
132239
+ const quoted = quotedName(part);
132240
+ if (quoted !== void 0) {
132241
+ names.push(quoted);
132158
132242
  continue;
132159
132243
  }
132160
132244
  const m2 = part.trim().match(RE_IDENT_START);
@@ -132950,6 +133034,17 @@ ${JSON.stringify(message, null, 4)}`);
132950
133034
  }
132951
133035
  return this.wsSymbolTable;
132952
133036
  }
133037
+ /**
133038
+ * Rebuild the symbol tables of `uris` on next use, e.g. after their projectId
133039
+ * changed, which changes their symbol IDs (see `setFolderProjectIds`).
133040
+ */
133041
+ invalidateSymbols(uris) {
133042
+ for (const uri of uris) {
133043
+ const cached = this.cache.get(uri);
133044
+ if (cached) cached.symbolTable = void 0;
133045
+ this.wsBuiltVersions.delete(uri);
133046
+ }
133047
+ }
132953
133048
  /**
132954
133049
  * Cache semantic diagnostics for the current document version.
132955
133050
  */
@@ -136348,14 +136443,21 @@ ${JSON.stringify(message, null, 4)}`);
136348
136443
  * namespace.
136349
136444
  */
136350
136445
  isLocallyVisible(symbol, name, indexes) {
136351
- return this.resolveQualifiedNameFrom(ownerKeyOf(symbol, indexes.byId), name, indexes) !== void 0;
136446
+ return this.resolveNameFrom(symbol, name, indexes) !== void 0;
136447
+ }
136448
+ /**
136449
+ * Resolve a (possibly qualified) name from the namespace containing
136450
+ * `symbol`, respecting namespace membership and visibility.
136451
+ */
136452
+ resolveNameFrom(symbol, name, indexes) {
136453
+ return this.resolveQualifiedNameFrom(ownerKeyOf(symbol, indexes.byId), name, indexes);
136352
136454
  }
136353
136455
  /**
136354
136456
  * Resolve a (possibly qualified) name to its symbol per §7.5.1, searching
136355
136457
  * outward from namespace `start` and its enclosing namespaces (its own resolved
136356
136458
  * members first, then its parent's, ...). Shared by `isLocallyVisible` (an
136357
- * ordinary reference resolving relative to its own enclosing namespace) and
136358
- * import-target resolution (an `import` declaration's target is itself a
136459
+ * ordinary reference resolving relative to its own enclosing namespace),
136460
+ * `resolveNameFrom`, and import-target resolution (an `import` declaration's target is itself a
136359
136461
  * qualifiedName, resolved the same relative way -- not as an absolute/global
136360
136462
  * name -- so a bare `import C;` inside a nested package can pick up a `C`
136361
136463
  * its own enclosing package already imported, per §7.5.1/§7.5.3).
@@ -139305,6 +139407,8 @@ ${childIndent}item def ${unresolvedType};
139305
139407
  // Requirements → Object
139306
139408
  case "requirement def" /* RequirementDef */:
139307
139409
  case "requirement" /* RequirementUsage */:
139410
+ case "concern def" /* ConcernDef */:
139411
+ case "concern" /* ConcernUsage */:
139308
139412
  case "actor" /* ActorUsage */:
139309
139413
  case "subject" /* SubjectUsage */:
139310
139414
  case "stakeholder" /* StakeholderUsage */:
@@ -140563,6 +140667,13 @@ ${info.documentation}`);
140563
140667
  "assert",
140564
140668
  "assume"
140565
140669
  ]);
140670
+ var CONNECTOR_KINDS = /* @__PURE__ */ new Set([
140671
+ "connection" /* ConnectionUsage */,
140672
+ "interface" /* InterfaceUsage */,
140673
+ "allocation" /* AllocationUsage */,
140674
+ "flow" /* FlowUsage */,
140675
+ "succession flow" /* SuccessionFlowUsage */
140676
+ ]);
140566
140677
  var SemanticValidator = class _SemanticValidator {
140567
140678
  constructor(documentManager2) {
140568
140679
  this.documentManager = documentManager2;
@@ -140639,7 +140750,7 @@ ${info.documentation}`);
140639
140750
  diagnostics.push(...this.checkAmbiguousNamespaceName(symbols, allSymbols));
140640
140751
  diagnostics.push(...this.checkUnusedDefinitions(allSymbols, uri));
140641
140752
  diagnostics.push(...this.checkRedefinitionMultiplicity(symbols, indexes, text));
140642
- diagnostics.push(...this.checkPortCompatibility(text, uri, indexes));
140753
+ diagnostics.push(...this.checkPortCompatibility(text, uri, symbols, indexes));
140643
140754
  diagnostics.push(...this.checkConstraintBodyReferences(text, uri, symbols, indexes));
140644
140755
  diagnostics.push(...this.checkCircularSpecialization(symbols, indexes));
140645
140756
  diagnostics.push(...this.checkUnsatisfiedRequirements(symbols, indexes));
@@ -140860,7 +140971,7 @@ ${info.documentation}`);
140860
140971
  opts?.text ? [opts.text] : []
140861
140972
  ));
140862
140973
  if (opts?.text && opts.uri) {
140863
- diagnostics.push(...instance.checkPortCompatibility(opts.text, opts.uri, indexes));
140974
+ diagnostics.push(...instance.checkPortCompatibility(opts.text, opts.uri, symbolsInUri, indexes));
140864
140975
  diagnostics.push(...instance.checkConstraintBodyReferences(opts.text, opts.uri, symbolsInUri, indexes));
140865
140976
  }
140866
140977
  return instance.dedupeDiagnostics(diagnostics);
@@ -141223,17 +141334,20 @@ ${info.documentation}`);
141223
141334
  * - The connection is within an interface usage
141224
141335
  * - Both ports are untyped (empty port defs with no features)
141225
141336
  */
141226
- checkPortCompatibility(text, uri, indexes) {
141337
+ checkPortCompatibility(text, uri, symbolsInUri, indexes) {
141227
141338
  if (!text) return [];
141228
141339
  const diagnostics = [];
141229
141340
  const lines = text.split("\n");
141230
141341
  const re = /\bconnect\s+([A-Za-z_][\w.]*)\s+to\s+([A-Za-z_][\w.]*)/g;
141231
141342
  let m2;
141232
141343
  while ((m2 = re.exec(text)) !== null) {
141233
- const left = m2[1].split(".").pop();
141234
- const right = m2[2].split(".").pop();
141235
- const lSym = (indexes.portsByName.get(left) ?? [])[0];
141236
- const rSym = (indexes.portsByName.get(right) ?? [])[0];
141344
+ const leftPath = m2[1].split(".");
141345
+ const rightPath = m2[2].split(".");
141346
+ const left = leftPath[leftPath.length - 1];
141347
+ const right = rightPath[rightPath.length - 1];
141348
+ const scope = this.connectorScope(symbolsInUri, this.indexToRange(text, m2.index, 0).start, indexes);
141349
+ const lSym = this.resolveConnectorEnd(leftPath, scope, indexes);
141350
+ const rSym = this.resolveConnectorEnd(rightPath, scope, indexes);
141237
141351
  if (!lSym || !rSym) continue;
141238
141352
  const lType = lSym.typeNames[0] ?? lSym.typeName;
141239
141353
  const rType = rSym.typeNames[0] ?? rSym.typeName;
@@ -141283,6 +141397,55 @@ ${info.documentation}`);
141283
141397
  }
141284
141398
  return diagnostics;
141285
141399
  }
141400
+ /**
141401
+ * The innermost element around `position` that owns a connector declared
141402
+ * there: the connector's own symbol, when it has one, is skipped.
141403
+ */
141404
+ connectorScope(symbols, position, indexes) {
141405
+ const before = (a, b) => a.line < b.line || a.line === b.line && a.character <= b.character;
141406
+ const size = (r) => (r.end.line - r.start.line) * 1e6 + (r.end.character - r.start.character);
141407
+ let scope;
141408
+ for (const s of symbols) {
141409
+ if (!before(s.range.start, position) || !before(position, s.range.end)) continue;
141410
+ if (!scope || size(s.range) < size(scope.range)) scope = s;
141411
+ }
141412
+ while (scope && CONNECTOR_KINDS.has(scope.kind)) scope = ownerOf(scope, indexes);
141413
+ return scope;
141414
+ }
141415
+ /**
141416
+ * The port that a connector end (`a.p`, `a.p.q`) names, resolved from
141417
+ * `scope` outward: its first segment is a feature of `scope` or of one of
141418
+ * its owners, each next one a feature of the one before. Two parts can each
141419
+ * have a port of the same name, so an end is never matched by its last
141420
+ * segment alone, except when the path does not resolve and the workspace
141421
+ * has only one port of that name.
141422
+ */
141423
+ resolveConnectorEnd(path, scope, indexes) {
141424
+ let feature;
141425
+ for (let namespace = scope; namespace && !feature; namespace = ownerOf(namespace, indexes)) {
141426
+ feature = this.findFeature(namespace, path[0], indexes);
141427
+ }
141428
+ for (const name of path.slice(1)) {
141429
+ feature = feature && this.findFeature(feature, name, indexes);
141430
+ }
141431
+ if (feature) return feature.kind === "port" /* PortUsage */ ? feature : void 0;
141432
+ const sameName = indexes.portsByName.get(path[path.length - 1]) ?? [];
141433
+ return sameName.length === 1 ? sameName[0] : void 0;
141434
+ }
141435
+ /** The feature `name` of `owner`: its own member, else a member of one of its types or their supertypes. */
141436
+ findFeature(owner, name, indexes) {
141437
+ const own = (indexes.byParent.get(namespaceKeyOf(owner)) ?? []).find((s) => s.name === name);
141438
+ if (own) return own;
141439
+ for (const typeName of owner.typeNames) {
141440
+ const type = this.namespaceResolver.resolveNameFrom(owner, typeName, indexes);
141441
+ if (!type || !isDefinition(type.kind)) continue;
141442
+ for (const definition of this.getSpecializationHierarchy(type, indexes).flat()) {
141443
+ const member = (indexes.byParent.get(namespaceKeyOf(definition)) ?? []).find((s) => s.name === name);
141444
+ if (member) return member;
141445
+ }
141446
+ }
141447
+ return void 0;
141448
+ }
141286
141449
  /**
141287
141450
  * Resolve the full type hierarchy for a type name by following
141288
141451
  * specialization chains transitively (max depth 10).
@@ -141330,7 +141493,7 @@ ${info.documentation}`);
141330
141493
  }
141331
141494
  const parent = this.findConstraintScopeSymbol(symbolsInUri, indexes, b.startLine);
141332
141495
  if (!parent) continue;
141333
- const parentMembers = indexes.byParent.get(namespaceKeyOf(parent)) ?? [];
141496
+ const parentMembers = this.getConstraintScopeMembers(parent, indexes);
141334
141497
  if (parentMembers.length === 0) continue;
141335
141498
  const ignoredRanges = this.getIgnoredBodyRanges(b.body);
141336
141499
  const idRe = /\b([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*)\b/g;
@@ -141389,18 +141552,135 @@ ${info.documentation}`);
141389
141552
  const root = parentMembers.find((s) => s.name === path[0]);
141390
141553
  if (!root) return false;
141391
141554
  if (path.length === 1) return true;
141392
- let typeName = root.typeNames[0] ?? root.typeName;
141555
+ let current = root;
141393
141556
  for (let i = 1; i < path.length; i++) {
141557
+ const typeName = current.typeNames[0] ?? current.typeName;
141394
141558
  if (!typeName) return false;
141395
- const typeDefs = indexes.definitionsByName.get(typeName) ?? [];
141396
- const typeDef = typeDefs[0];
141397
- if (!typeDef) return false;
141398
- const member = (indexes.byParent.get(namespaceKeyOf(typeDef)) ?? []).find((s) => s.name === path[i]);
141559
+ const typeDef = this.namespaceResolver.resolveNameFrom(current, typeName, indexes);
141560
+ if (!typeDef || !isDefinition(typeDef.kind)) return false;
141561
+ const member = this.getConstraintScopeMembers(typeDef, indexes, true).find((s) => s.name === path[i]);
141399
141562
  if (!member) return false;
141400
- typeName = member.typeNames[0] ?? member.typeName;
141563
+ current = member;
141401
141564
  }
141402
141565
  return true;
141403
141566
  }
141567
+ getConstraintScopeMembers(scope, indexes, publicOnly = false) {
141568
+ const hierarchy = [[scope]];
141569
+ const visited = /* @__PURE__ */ new Set([scope]);
141570
+ let frontier = [scope];
141571
+ while (frontier.length > 0) {
141572
+ const next = [];
141573
+ for (const current of frontier) {
141574
+ for (const typeName of current.typeNames) {
141575
+ const supertype = this.namespaceResolver.resolveNameFrom(current, typeName, indexes);
141576
+ if (!supertype || !isDefinition(supertype.kind) || visited.has(supertype)) continue;
141577
+ visited.add(supertype);
141578
+ next.push(supertype);
141579
+ }
141580
+ }
141581
+ if (next.length > 0) hierarchy.push(next);
141582
+ frontier = next;
141583
+ }
141584
+ const membersByLevel = hierarchy.map((level) => level.flatMap((namespace) => indexes.byParent.get(namespaceKeyOf(namespace)) ?? []));
141585
+ const hiddenMembers = /* @__PURE__ */ new Set();
141586
+ for (let level = membersByLevel.length - 1; level >= 0; level--) {
141587
+ for (const redefining of membersByLevel[level]) {
141588
+ for (const target of redefining.redefinedFeatureTargets ?? []) {
141589
+ const owner = ownerOf(redefining, indexes);
141590
+ if (!owner) continue;
141591
+ for (const candidate of this.resolveInheritedRedefinitionTarget(owner, target, hiddenMembers, indexes)) {
141592
+ hiddenMembers.add(candidate.symbolId);
141593
+ }
141594
+ }
141595
+ if (redefining.kind === "subject" /* SubjectUsage */) {
141596
+ const owner = ownerOf(redefining, indexes);
141597
+ if (!owner) continue;
141598
+ for (const ancestor of this.getSpecializationHierarchy(owner, indexes).slice(1).flat()) {
141599
+ for (const candidate of indexes.byParent.get(namespaceKeyOf(ancestor)) ?? []) {
141600
+ if (candidate.kind === "subject" /* SubjectUsage */) hiddenMembers.add(candidate.symbolId);
141601
+ }
141602
+ }
141603
+ }
141604
+ }
141605
+ }
141606
+ const membersByName = /* @__PURE__ */ new Map();
141607
+ for (let level = 0; level < membersByLevel.length; level++) {
141608
+ for (const member of membersByLevel[level]) {
141609
+ if (level > 0 && member.visibility === "private") continue;
141610
+ if (publicOnly && member.visibility !== void 0 && member.visibility !== "public") continue;
141611
+ if (hiddenMembers.has(member.symbolId) || membersByName.has(member.name)) continue;
141612
+ membersByName.set(member.name, member);
141613
+ }
141614
+ }
141615
+ return [...membersByName.values()];
141616
+ }
141617
+ resolveInheritedRedefinitionTarget(owner, target, alreadyRedefined, indexes) {
141618
+ if (target.includes(".")) return [];
141619
+ const segments = target.split("::");
141620
+ const targetName = segments.pop()?.replace(/^'|'$/g, "");
141621
+ if (!targetName) return [];
141622
+ const qualifier = segments.join("::").replace(/^'|'$/g, "");
141623
+ const matches = /* @__PURE__ */ new Map();
141624
+ for (const supertype of this.resolveDirectSupertypes(owner, indexes)) {
141625
+ const branch = this.getSpecializationHierarchy(supertype, indexes);
141626
+ const anchors = qualifier ? branch.flat().filter((type) => this.matchesSpecializationQualifier(type, qualifier)) : [supertype];
141627
+ for (const anchor of anchors) {
141628
+ let frontier = [anchor];
141629
+ const visited = new Set(frontier);
141630
+ const candidates = [];
141631
+ while (frontier.length > 0 && candidates.length === 0) {
141632
+ for (const type of frontier) {
141633
+ for (const member of indexes.byParent.get(namespaceKeyOf(type)) ?? []) {
141634
+ if (member.name === targetName && member.visibility !== "private" && !alreadyRedefined.has(member.symbolId)) {
141635
+ candidates.push(member);
141636
+ }
141637
+ }
141638
+ }
141639
+ if (candidates.length > 0) break;
141640
+ const next = /* @__PURE__ */ new Map();
141641
+ for (const type of frontier) {
141642
+ for (const parent of this.resolveDirectSupertypes(type, indexes)) {
141643
+ if (visited.has(parent)) continue;
141644
+ visited.add(parent);
141645
+ next.set(parent.symbolId, parent);
141646
+ }
141647
+ }
141648
+ frontier = [...next.values()];
141649
+ }
141650
+ for (const candidate of candidates) matches.set(candidate.symbolId, candidate);
141651
+ }
141652
+ }
141653
+ return matches.size === 1 ? [...matches.values()] : [];
141654
+ }
141655
+ resolveDirectSupertypes(scope, indexes) {
141656
+ const supertypes = /* @__PURE__ */ new Map();
141657
+ for (const typeName of scope.typeNames) {
141658
+ const supertype = this.namespaceResolver.resolveNameFrom(scope, typeName, indexes);
141659
+ if (supertype && isDefinition(supertype.kind)) supertypes.set(supertype.symbolId, supertype);
141660
+ }
141661
+ return [...supertypes.values()];
141662
+ }
141663
+ getSpecializationHierarchy(scope, indexes) {
141664
+ const levels = [[scope]];
141665
+ const visited = /* @__PURE__ */ new Set([scope]);
141666
+ let frontier = [scope];
141667
+ while (frontier.length > 0) {
141668
+ const next = [];
141669
+ for (const type of frontier) {
141670
+ for (const parent of this.resolveDirectSupertypes(type, indexes)) {
141671
+ if (visited.has(parent)) continue;
141672
+ visited.add(parent);
141673
+ next.push(parent);
141674
+ }
141675
+ }
141676
+ if (next.length > 0) levels.push(next);
141677
+ frontier = next;
141678
+ }
141679
+ return levels;
141680
+ }
141681
+ matchesSpecializationQualifier(type, qualifier) {
141682
+ return type.name === qualifier || type.qualifiedName === qualifier || type.qualifiedName?.endsWith(`::${qualifier}`) === true;
141683
+ }
141404
141684
  findContainingSymbolByLine(symbols, line) {
141405
141685
  return symbols.filter((s) => s.range.start.line <= line && s.range.end.line >= line).sort((a, b) => {
141406
141686
  const ar = (a.range.end.line - a.range.start.line) * 1e3 + (a.range.end.character - a.range.start.character);
@@ -141411,7 +141691,7 @@ ${info.documentation}`);
141411
141691
  findConstraintScopeSymbol(symbolsInUri, indexes, line) {
141412
141692
  let scope = this.findContainingSymbolByLine(symbolsInUri, line);
141413
141693
  while (scope) {
141414
- const members = indexes.byParent.get(namespaceKeyOf(scope)) ?? [];
141694
+ const members = this.getConstraintScopeMembers(scope, indexes);
141415
141695
  if (members.length > 0) return scope;
141416
141696
  if (!scope.parentId) return scope;
141417
141697
  scope = ownerOf(scope, indexes);
@@ -141704,6 +141984,10 @@ ${info.documentation}`);
141704
141984
  var hasConfigurationCapability = false;
141705
141985
  var hasWorkspaceFolderCapability = false;
141706
141986
  var workspaceRoots = [];
141987
+ var workspaceFolderUris = [];
141988
+ function rootsOf(folderUris) {
141989
+ return folderUris.map((uri) => toFsPath(uri)).filter((p) => p !== void 0);
141990
+ }
141707
141991
  var isWorkspaceFile = false;
141708
141992
  var preloadOnOpen = "workspaceOnly";
141709
141993
  var disabledDiagnosticCodes = /* @__PURE__ */ new Set();
@@ -141715,6 +141999,10 @@ ${info.documentation}`);
141715
141999
  }
141716
142000
  var skipDirs = new Set(DEFAULT_SKIP_DIRS);
141717
142001
  var serverReady = false;
142002
+ var resolveInitialization;
142003
+ var initialization = new Promise((resolve) => {
142004
+ resolveInitialization = resolve;
142005
+ });
141718
142006
  var earlyOpenUris = /* @__PURE__ */ new Set();
141719
142007
  var workerRequestId = 0;
141720
142008
  var isBrowserServer = true;
@@ -141828,7 +142116,8 @@ ${info.documentation}`);
141828
142116
  connection.console.warn(`projectId is not a UUID: ${initOpts.projectId}; symbol IDs are unique only within this workspace`);
141829
142117
  }
141830
142118
  if (params.workspaceFolders) {
141831
- workspaceRoots = params.workspaceFolders.map((f2) => toFsPath(f2.uri)).filter((p) => p !== void 0);
142119
+ workspaceFolderUris = params.workspaceFolders.map((f2) => f2.uri);
142120
+ workspaceRoots = rootsOf(workspaceFolderUris);
141832
142121
  } else if (params.rootUri) {
141833
142122
  const root = toFsPath(params.rootUri);
141834
142123
  if (root) workspaceRoots = [root];
@@ -141878,7 +142167,8 @@ ${info.documentation}`);
141878
142167
  if (hasWorkspaceFolderCapability) {
141879
142168
  result.capabilities.workspace = {
141880
142169
  workspaceFolders: {
141881
- supported: true
142170
+ supported: true,
142171
+ changeNotifications: true
141882
142172
  }
141883
142173
  };
141884
142174
  }
@@ -141890,8 +142180,17 @@ ${info.documentation}`);
141890
142180
  import_node11.DidChangeConfigurationNotification.type,
141891
142181
  void 0
141892
142182
  );
142183
+ }
142184
+ if (hasWorkspaceFolderCapability) {
142185
+ connection.workspace.onDidChangeWorkspaceFolders((event) => {
142186
+ onWorkspaceFoldersChanged(event).catch((e) => connection.console.error(`Workspace folder change failed: ${e}`));
142187
+ });
142188
+ }
142189
+ if (hasConfigurationCapability) {
141893
142190
  await pullSettings().catch(() => {
141894
142191
  });
142192
+ await pullFolderProjectIds().catch(() => {
142193
+ });
141895
142194
  }
141896
142195
  const libCount = initLibraryIndex("/");
141897
142196
  connection.console.log(`SysML v2 Language Server initialized (${libCount} library packages indexed)`);
@@ -141907,14 +142206,13 @@ ${info.documentation}`);
141907
142206
  );
141908
142207
  }
141909
142208
  serverReady = true;
142209
+ resolveInitialization();
141910
142210
  spawnParseWorker();
141911
142211
  if (workspaceRoots.length > 0 && (preloadOnOpen === "always" || preloadOnOpen === "workspaceOnly" && isWorkspaceFile)) {
141912
- documentManager.setWorkspaceScanComplete(false);
141913
- scanWorkspaceFoldersAsync(workspaceRoots).then(({ fileCount, scanMs }) => {
142212
+ scanWorkspaceFolders(workspaceRoots).then(({ fileCount, scanMs }) => {
141914
142213
  connection.console.log(
141915
142214
  `Workspace scan: pre-parsed ${fileCount} .sysml files in ${scanMs} ms`
141916
142215
  );
141917
- documentManager.setWorkspaceScanComplete(true);
141918
142216
  revalidateOpenDocuments();
141919
142217
  });
141920
142218
  }
@@ -141949,9 +142247,80 @@ ${info.documentation}`);
141949
142247
  }
141950
142248
  }
141951
142249
  connection.onDidChangeConfiguration((_change) => {
141952
- pullSettings().then(() => revalidateOpenDocuments()).catch(() => {
142250
+ pullSettings().then(() => pullFolderProjectIds()).then(() => revalidateOpenDocuments()).catch(() => {
142251
+ });
142252
+ });
142253
+ function latestWins(task) {
142254
+ let calls = 0;
142255
+ let latest = Promise.resolve();
142256
+ return () => {
142257
+ const call = ++calls;
142258
+ const isSuperseded = () => call !== calls;
142259
+ const run = task(isSuperseded).then(() => isSuperseded() ? latest : void 0);
142260
+ latest = run;
142261
+ return run;
142262
+ };
142263
+ }
142264
+ var pullFolderProjectIds = latestWins(async (isSuperseded) => {
142265
+ if (!hasConfigurationCapability) return;
142266
+ const folderUris = [...workspaceFolderUris];
142267
+ const answers = folderUris.length === 0 ? [] : await connection.workspace.getConfiguration(folderUris.map((scopeUri) => ({ scopeUri, section: "sysml.project" })));
142268
+ if (isSuperseded()) return;
142269
+ const projectIds = folderUris.flatMap((folderUri, i) => {
142270
+ const projectId = answers[i]?.projectId;
142271
+ return typeof projectId === "string" ? [{ folderUri, projectId }] : [];
141953
142272
  });
142273
+ const uris = documentManager.getUris();
142274
+ const prefixBefore = new Map(uris.map((uri) => [uri, getUrlPrefix(uri)]));
142275
+ const rejected = setFolderProjectIds(projectIds);
142276
+ for (const entry of rejected) {
142277
+ connection.console.warn(`projectId of ${entry.folderUri} is not a UUID: ${entry.projectId}; ignored, so its documents use the projectId of an enclosing folder, else initializationOptions.projectId, else the default prefix`);
142278
+ }
142279
+ documentManager.invalidateSymbols(uris.filter((uri) => getUrlPrefix(uri) !== prefixBefore.get(uri)));
142280
+ logFolderPrefixes(new Set(projectIds.filter((p) => !rejected.includes(p)).map((p) => p.folderUri)));
141954
142281
  });
142282
+ var loggedFolderPrefixes = /* @__PURE__ */ new Map();
142283
+ function logFolderPrefixes(ownProjectIds) {
142284
+ for (const folderUri of workspaceFolderUris) {
142285
+ const prefix = getUrlPrefix(`${folderUri.endsWith("/") ? folderUri : `${folderUri}/`}_.sysml`);
142286
+ if (loggedFolderPrefixes.get(folderUri) === prefix) continue;
142287
+ loggedFolderPrefixes.set(folderUri, prefix);
142288
+ const source = ownProjectIds.has(folderUri) ? "its projectId" : prefix === getUrlPrefix() ? prefix === DEFAULT_URL_PREFIX ? "the default prefix, no projectId" : "initializationOptions.projectId" : "an enclosing folder's projectId";
142289
+ const folderPath = toFsPath(folderUri) ?? folderUri;
142290
+ connection.console.debug(`Folder ${folderPath}: element ID namespace ${prefix} (${source}; ID namespace only, no network access)`);
142291
+ }
142292
+ for (const folderUri of loggedFolderPrefixes.keys()) {
142293
+ if (!workspaceFolderUris.includes(folderUri)) loggedFolderPrefixes.delete(folderUri);
142294
+ }
142295
+ }
142296
+ async function onWorkspaceFoldersChanged(event) {
142297
+ const initialScanPending = !serverReady;
142298
+ const removed = new Set(event.removed.map((f2) => f2.uri));
142299
+ workspaceFolderUris = [...workspaceFolderUris.filter((uri) => !removed.has(uri)), ...event.added.map((f2) => f2.uri)];
142300
+ workspaceRoots = rootsOf(workspaceFolderUris);
142301
+ dropDocumentsOutsideWorkspace(event.removed.map((f2) => f2.uri));
142302
+ await pullFolderProjectIds().catch(() => {
142303
+ });
142304
+ if (initialScanPending) return;
142305
+ const addedRoots = rootsOf(event.added.map((f2) => f2.uri).filter((uri) => workspaceFolderUris.includes(uri)));
142306
+ if (addedRoots.length > 0 && (preloadOnOpen === "always" || preloadOnOpen === "workspaceOnly" && isWorkspaceFile)) {
142307
+ const { fileCount, scanMs } = await scanWorkspaceFolders(addedRoots);
142308
+ connection.console.log(`Workspace scan: pre-parsed ${fileCount} .sysml files of ${addedRoots.length} added folder(s) in ${scanMs} ms`);
142309
+ }
142310
+ revalidateOpenDocuments();
142311
+ }
142312
+ function dropDocumentsOutsideWorkspace(folderUris) {
142313
+ for (const uri of documentManager.getUris()) {
142314
+ if (openDocumentFor(uri)) continue;
142315
+ if (folderUris.some((f2) => isInFolder(uri, f2)) && !isInWorkspace(uri)) {
142316
+ documentManager.remove(uri);
142317
+ modelProvider.removeUri(uri);
142318
+ }
142319
+ }
142320
+ }
142321
+ function isInWorkspace(uri) {
142322
+ return workspaceRoots.some((root) => isInFolder(uri, pathToFileURL(root).toString()));
142323
+ }
141955
142324
  function openDocumentFor(uri) {
141956
142325
  return documents.get(uri) ?? documents.all().find((d) => isSameDocumentUri(d.uri, uri));
141957
142326
  }
@@ -141976,6 +142345,16 @@ ${info.documentation}`);
141976
142345
  documentManager.parse(doc);
141977
142346
  return true;
141978
142347
  }
142348
+ var runningScans = 0;
142349
+ async function scanWorkspaceFolders(roots) {
142350
+ runningScans++;
142351
+ documentManager.setWorkspaceScanComplete(false);
142352
+ try {
142353
+ return await scanWorkspaceFoldersAsync(roots);
142354
+ } finally {
142355
+ if (--runningScans === 0) documentManager.setWorkspaceScanComplete(true);
142356
+ }
142357
+ }
141979
142358
  async function scanWorkspaceFoldersAsync(roots) {
141980
142359
  const scanT0 = Date.now();
141981
142360
  const fileArrays = await Promise.all(roots.map((r) => findSysMLFilesAsync(r, skipDirs)));
@@ -141987,6 +142366,7 @@ ${info.documentation}`);
141987
142366
  const filePath = allFiles[i];
141988
142367
  const uri = pathToFileURL(filePath).toString();
141989
142368
  if (openDocumentFor(uri)) continue;
142369
+ if (!isInWorkspace(uri)) continue;
141990
142370
  const content = fileContents.get(filePath);
141991
142371
  if (content === void 0) continue;
141992
142372
  documentManager.parseBatch(uri, 0, content);
@@ -142199,14 +142579,16 @@ ${info.documentation}`);
142199
142579
  return formattingProvider.provideRangeFormatting(params);
142200
142580
  }
142201
142581
  );
142202
- connection.onRequest("sysml/model", (params) => {
142582
+ connection.onRequest("sysml/model", async (params) => {
142583
+ await initialization;
142203
142584
  return modelProvider.getModel(
142204
142585
  params.textDocument.uri,
142205
142586
  documentManager.getVersion(params.textDocument.uri),
142206
142587
  params.scope
142207
142588
  );
142208
142589
  });
142209
- connection.onRequest("sysml/elementLookup", (params) => {
142590
+ connection.onRequest("sysml/elementLookup", async (params) => {
142591
+ await initialization;
142210
142592
  return elementLookupProvider.elementLookup(params);
142211
142593
  });
142212
142594
  connection.onRequest("sysml/serverStats", () => {