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.
- package/CHANGELOG.md +30 -0
- package/dist/server/browserServerMain.js +453 -71
- package/dist/server/mcpServer.js +420 -93
- package/dist/server/server.js +472 -90
- package/package.json +1 -1
|
@@ -3362,7 +3362,7 @@ ${JSON.stringify(message, null, 4)}`);
|
|
|
3362
3362
|
}
|
|
3363
3363
|
uinteger3.is = is;
|
|
3364
3364
|
})(uinteger || (uinteger = {}));
|
|
3365
|
-
(function(
|
|
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
|
-
|
|
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
|
-
|
|
3380
|
+
Position5.is = is;
|
|
3381
3381
|
})(Position || (Position = {}));
|
|
3382
|
-
(function(
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
12453
|
+
Position5.is = is;
|
|
12454
12454
|
})(Position2 || (Position2 = {}));
|
|
12455
|
-
(function(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
130423
|
-
|
|
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.
|
|
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)
|
|
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
|
-
|
|
131903
|
-
if (
|
|
131959
|
+
this.findOwnHeaderRules(child, ruleIndex, matches, firstOnly);
|
|
131960
|
+
if (firstOnly && matches.length > 0) return;
|
|
131904
131961
|
}
|
|
131905
|
-
|
|
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
|
|
132095
|
-
|
|
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
|
|
132103
|
-
if (
|
|
132104
|
-
names.push(
|
|
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
|
|
132126
|
-
if (
|
|
132127
|
-
names.push(
|
|
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
|
|
132148
|
-
const
|
|
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
|
|
132156
|
-
if (
|
|
132157
|
-
names.push(
|
|
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.
|
|
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)
|
|
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
|
|
141234
|
-
const
|
|
141235
|
-
const
|
|
141236
|
-
const
|
|
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 =
|
|
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
|
|
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
|
|
141396
|
-
|
|
141397
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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", () => {
|