sysml-v2-lsp 0.33.0 → 0.35.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 +194 -53
- package/dist/server/mcpServer.js +143 -56
- package/dist/server/server.js +194 -53
- package/package.json +1 -1
package/dist/server/server.js
CHANGED
|
@@ -121638,6 +121638,10 @@ var SYSML_KEYWORDS = new Set(SYSML_KEYWORDS_ARRAY);
|
|
|
121638
121638
|
function canonicalUri(uri) {
|
|
121639
121639
|
return uri.replace(/^file:\/\/\/([A-Za-z])(?::|%3[Aa])(?=\/|$)/, (_m, drive) => `file:///${drive.toLowerCase()}:`);
|
|
121640
121640
|
}
|
|
121641
|
+
function isInFolder(uri, folderUri) {
|
|
121642
|
+
const folder = canonicalUri(folderUri);
|
|
121643
|
+
return canonicalUri(uri).startsWith(folder.endsWith("/") ? folder : `${folder}/`);
|
|
121644
|
+
}
|
|
121641
121645
|
function isSameDocumentUri(a, b) {
|
|
121642
121646
|
return a === b || canonicalUri(a) === canonicalUri(b);
|
|
121643
121647
|
}
|
|
@@ -121740,6 +121744,7 @@ var v5_default = v5;
|
|
|
121740
121744
|
var NAMESPACE_URL = v5_default.URL;
|
|
121741
121745
|
var DEFAULT_URL_PREFIX = "https://github.com/daltskin/sysml-v2-lsp/";
|
|
121742
121746
|
var urlPrefix = DEFAULT_URL_PREFIX;
|
|
121747
|
+
var folderPrefixes = [];
|
|
121743
121748
|
function setProjectId(projectId) {
|
|
121744
121749
|
if (projectId === void 0) {
|
|
121745
121750
|
urlPrefix = DEFAULT_URL_PREFIX;
|
|
@@ -121749,8 +121754,14 @@ function setProjectId(projectId) {
|
|
|
121749
121754
|
urlPrefix = `urn:uuid:${projectId.toLowerCase()}/`;
|
|
121750
121755
|
return true;
|
|
121751
121756
|
}
|
|
121752
|
-
function
|
|
121753
|
-
|
|
121757
|
+
function setFolderProjectIds(projectIds) {
|
|
121758
|
+
const rejected = projectIds.filter((p) => !validate_default(p.projectId));
|
|
121759
|
+
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);
|
|
121760
|
+
return rejected;
|
|
121761
|
+
}
|
|
121762
|
+
function getUrlPrefix(uri) {
|
|
121763
|
+
const match = uri === void 0 ? void 0 : folderPrefixes.find((f) => isInFolder(uri, f.folderUri));
|
|
121764
|
+
return match?.prefix ?? urlPrefix;
|
|
121754
121765
|
}
|
|
121755
121766
|
function uuidV5(namespace, name) {
|
|
121756
121767
|
return v5_default(name, namespace);
|
|
@@ -121832,6 +121843,10 @@ function toMetaclassName(kind) {
|
|
|
121832
121843
|
return "RequirementDefinition";
|
|
121833
121844
|
case "requirement" /* RequirementUsage */:
|
|
121834
121845
|
return "RequirementUsage";
|
|
121846
|
+
case "concern def" /* ConcernDef */:
|
|
121847
|
+
return "ConcernDefinition";
|
|
121848
|
+
case "concern" /* ConcernUsage */:
|
|
121849
|
+
return "ConcernUsage";
|
|
121835
121850
|
case "constraint def" /* ConstraintDef */:
|
|
121836
121851
|
return "ConstraintDefinition";
|
|
121837
121852
|
case "constraint" /* ConstraintUsage */:
|
|
@@ -121954,7 +121969,7 @@ var IdRegistry = class {
|
|
|
121954
121969
|
declaration.parentId = owner?.symbolId;
|
|
121955
121970
|
const path3 = declaration.qualifiedName !== void 0 ? this.qualifiedNameAsWritten(declaration) : owner ? `${this.paths.get(owner)}/${segmentOf(declaration)}` : segmentOf(declaration);
|
|
121956
121971
|
const namespace = owner ? this.topLevelOf(owner).symbolId : NAMESPACE_URL;
|
|
121957
|
-
const key = owner ? path3 : getUrlPrefix() + encodeURIComponent(path3);
|
|
121972
|
+
const key = owner ? path3 : getUrlPrefix(declaration.uri) + encodeURIComponent(path3);
|
|
121958
121973
|
const groupId = this.uuidOf(namespace, key);
|
|
121959
121974
|
this.groupKeys.set(groupId, { namespace, key, path: path3 });
|
|
121960
121975
|
this.groupOf.set(declaration, groupId);
|
|
@@ -122139,6 +122154,12 @@ var RULE_INDEX_TO_KIND = /* @__PURE__ */ new Map([
|
|
|
122139
122154
|
// 343
|
|
122140
122155
|
[SysMLv2Parser.RULE_requirementDefinition, "requirement def" /* RequirementDef */],
|
|
122141
122156
|
// 384
|
|
122157
|
+
[SysMLv2Parser.RULE_concernDefinition, "concern def" /* ConcernDef */],
|
|
122158
|
+
// 405
|
|
122159
|
+
[SysMLv2Parser.RULE_concernUsage, "concern" /* ConcernUsage */],
|
|
122160
|
+
// 406
|
|
122161
|
+
[SysMLv2Parser.RULE_framedConcernUsage, "concern" /* ConcernUsage */],
|
|
122162
|
+
// 394
|
|
122142
122163
|
[SysMLv2Parser.RULE_constraintDefinition, "constraint def" /* ConstraintDef */],
|
|
122143
122164
|
// 380
|
|
122144
122165
|
[SysMLv2Parser.RULE_itemDefinition, "item def" /* ItemDef */],
|
|
@@ -122211,6 +122232,10 @@ var RULE_INDEX_TO_KIND = /* @__PURE__ */ new Map([
|
|
|
122211
122232
|
// 268
|
|
122212
122233
|
[SysMLv2Parser.RULE_performActionUsage, "perform action" /* PerformActionUsage */],
|
|
122213
122234
|
// 298
|
|
122235
|
+
// A state's `entry`/`do`/`exit` action (`exit action a : A;`, `exit a;`): the
|
|
122236
|
+
// StatePerformActionUsage production, a PerformActionUsage without `perform`.
|
|
122237
|
+
[SysMLv2Parser.RULE_statePerformActionUsage, "perform action" /* PerformActionUsage */],
|
|
122238
|
+
// 352
|
|
122214
122239
|
[SysMLv2Parser.RULE_exhibitStateUsage, "exhibit state" /* ExhibitStateUsage */],
|
|
122215
122240
|
// 359
|
|
122216
122241
|
[SysMLv2Parser.RULE_transitionUsage, "transition" /* TransitionUsage */],
|
|
@@ -122334,8 +122359,10 @@ var TYPE_RECURSE_RULE_INDICES = /* @__PURE__ */ new Set([
|
|
|
122334
122359
|
// 210
|
|
122335
122360
|
SysMLv2Parser.RULE_definition,
|
|
122336
122361
|
// 192
|
|
122337
|
-
SysMLv2Parser.RULE_usage
|
|
122362
|
+
SysMLv2Parser.RULE_usage,
|
|
122338
122363
|
// 208
|
|
122364
|
+
SysMLv2Parser.RULE_payloadFeatureSpecializationPart
|
|
122365
|
+
// 157
|
|
122339
122366
|
]);
|
|
122340
122367
|
var DOC_RULE_INDICES = /* @__PURE__ */ new Set([
|
|
122341
122368
|
SysMLv2Parser.RULE_comment,
|
|
@@ -122960,7 +122987,7 @@ var SymbolTable = class {
|
|
|
122960
122987
|
const shortName = transition || isFlowUsage(kind) && !declaredName ? void 0 : this.extractShortName(ctx);
|
|
122961
122988
|
const qualifiedName = anonymous || owner && owner.qualifiedName === void 0 ? void 0 : owner ? `${owner.qualifiedName}::${name}` : name;
|
|
122962
122989
|
const selectionRange = anonymous ? ctx.start ? tokenToRange(ctx.start) : range : this.extractNameRange(ctx) ?? range;
|
|
122963
|
-
const typeNames = isFlowUsage(kind) ? this.extractFlowTypeNames(ctx) : this.extractTypeNames(ctx);
|
|
122990
|
+
const typeNames = isFlowUsage(kind) ? this.extractFlowTypeNames(ctx) : transition ? this.extractTransitionTypeNames(ctx) : this.extractTypeNames(ctx);
|
|
122964
122991
|
const specializationNames = this.extractSpecializationNames(ctx);
|
|
122965
122992
|
const typeName = typeNames[0];
|
|
122966
122993
|
const documentation = this.extractDocumentation(ctx);
|
|
@@ -123075,6 +123102,25 @@ var SymbolTable = class {
|
|
|
123075
123102
|
const typeDeclaration = declaration && (this.findOwnHeaderRule(declaration, SysMLv2Parser.RULE_featureDeclaration) ?? this.findOwnHeaderRule(declaration, SysMLv2Parser.RULE_usageDeclaration));
|
|
123076
123103
|
return typeDeclaration ? this.extractTypeNames(typeDeclaration) : [];
|
|
123077
123104
|
}
|
|
123105
|
+
/**
|
|
123106
|
+
* A transition's own typing, then the types of the payload its trigger
|
|
123107
|
+
* accepts (`accept cmd : Command`, `accept Command`; TriggerAction ->
|
|
123108
|
+
* AcceptParameterPart -> PayloadParameter). Read from the parse tree only:
|
|
123109
|
+
* the regex fallback of `extractTypeNames` runs on whitespace-free text, where
|
|
123110
|
+
* the payload type runs into the guard, effect or target that follows it
|
|
123111
|
+
* (`Commandifcmd`, `Commandthenbusy`).
|
|
123112
|
+
*/
|
|
123113
|
+
extractTransitionTypeNames(ctx) {
|
|
123114
|
+
const names = [];
|
|
123115
|
+
this.collectTypeNamesFromTree(ctx, names, 0);
|
|
123116
|
+
const trigger = this.findOwnHeaderRule(ctx, SysMLv2Parser.RULE_triggerActionMember);
|
|
123117
|
+
const parameter = trigger && this.findRuleContext(trigger, SysMLv2Parser.RULE_payloadParameter);
|
|
123118
|
+
if (parameter) {
|
|
123119
|
+
const payload = this.findRuleContext(parameter, SysMLv2Parser.RULE_payloadFeature) ?? parameter;
|
|
123120
|
+
this.collectTypeNamesFromTree(payload, names, 0);
|
|
123121
|
+
}
|
|
123122
|
+
return names;
|
|
123123
|
+
}
|
|
123078
123124
|
/** Find the first descendant of `ctx` with rule `ruleIndex`, in source order. */
|
|
123079
123125
|
findRuleContext(ctx, ruleIndex) {
|
|
123080
123126
|
const matches = [];
|
|
@@ -123168,7 +123214,7 @@ var SymbolTable = class {
|
|
|
123168
123214
|
const child = ctx.getChild(i);
|
|
123169
123215
|
if (child instanceof TerminalNode) {
|
|
123170
123216
|
const token = child.symbol;
|
|
123171
|
-
if (this.
|
|
123217
|
+
if (this.isNameTerminal(child)) {
|
|
123172
123218
|
return this.unquoteName(token.text ?? "");
|
|
123173
123219
|
}
|
|
123174
123220
|
}
|
|
@@ -123200,7 +123246,7 @@ var SymbolTable = class {
|
|
|
123200
123246
|
*/
|
|
123201
123247
|
anonymousDeclaration(ctx, kind, transition) {
|
|
123202
123248
|
if (!isDefinition(kind) && !isUsage(kind)) return void 0;
|
|
123203
|
-
if (transition && !(transition.source && transition.target) && this.
|
|
123249
|
+
if (transition && !(transition.source && transition.target) && this.extractTransitionTypeNames(ctx).length === 0) return void 0;
|
|
123204
123250
|
return this.declarationText(ctx);
|
|
123205
123251
|
}
|
|
123206
123252
|
/**
|
|
@@ -123220,14 +123266,15 @@ var SymbolTable = class {
|
|
|
123220
123266
|
/**
|
|
123221
123267
|
* The first node of rule `ruleIndex` in `ctx`'s own declaration: never
|
|
123222
123268
|
* inside a nested element, its body, its value, a flow's payload or ends,
|
|
123223
|
-
*
|
|
123269
|
+
* a connector end's own multiplicity (`connect [2] a to b`), or a prefix
|
|
123270
|
+
* such as `#metadata`.
|
|
123224
123271
|
*/
|
|
123225
123272
|
findOwnHeaderRule(ctx, ruleIndex) {
|
|
123226
123273
|
for (let i = 0; i < ctx.getChildCount(); i++) {
|
|
123227
123274
|
const child = ctx.getChild(i);
|
|
123228
123275
|
if (!(child instanceof ParserRuleContext)) continue;
|
|
123229
123276
|
if (child.ruleIndex === ruleIndex) return child;
|
|
123230
|
-
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) || this.isPrefixOrExtensionContext(child)) continue;
|
|
123277
|
+
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;
|
|
123231
123278
|
const found = this.findOwnHeaderRule(child, ruleIndex);
|
|
123232
123279
|
if (found) return found;
|
|
123233
123280
|
}
|
|
@@ -123391,7 +123438,7 @@ var SymbolTable = class {
|
|
|
123391
123438
|
extractNameRange(ctx) {
|
|
123392
123439
|
for (let i = 0; i < ctx.getChildCount(); i++) {
|
|
123393
123440
|
const child = ctx.getChild(i);
|
|
123394
|
-
if (child instanceof TerminalNode && this.
|
|
123441
|
+
if (child instanceof TerminalNode && this.isNameTerminal(child)) {
|
|
123395
123442
|
return tokenToRange(child.symbol);
|
|
123396
123443
|
}
|
|
123397
123444
|
if (child instanceof ParserRuleContext) {
|
|
@@ -123576,12 +123623,12 @@ var SymbolTable = class {
|
|
|
123576
123623
|
return lines.join("\n").trim();
|
|
123577
123624
|
}
|
|
123578
123625
|
/**
|
|
123579
|
-
* Extract multiplicity from a context
|
|
123580
|
-
*
|
|
123626
|
+
* Extract multiplicity from a context's own declaration, never from a
|
|
123627
|
+
* nested element or its body.
|
|
123581
123628
|
* Returns { multiplicity: "1..5", multiplicityRange: { lower: 1, upper: 5 } }
|
|
123582
123629
|
*/
|
|
123583
123630
|
extractMultiplicity(ctx) {
|
|
123584
|
-
const multCtx = this.
|
|
123631
|
+
const multCtx = this.findOwnHeaderRule(ctx, SysMLv2Parser.RULE_multiplicityBounds);
|
|
123585
123632
|
if (!multCtx) {
|
|
123586
123633
|
return {};
|
|
123587
123634
|
}
|
|
@@ -123635,24 +123682,6 @@ var SymbolTable = class {
|
|
|
123635
123682
|
multiplicityRange: { lower, upper }
|
|
123636
123683
|
};
|
|
123637
123684
|
}
|
|
123638
|
-
/**
|
|
123639
|
-
* Recursively search for a MultiplicityBoundsContext in the subtree.
|
|
123640
|
-
*/
|
|
123641
|
-
findMultiplicityBounds(ctx) {
|
|
123642
|
-
if (ctx.ruleIndex === SysMLv2Parser.RULE_multiplicityBounds) {
|
|
123643
|
-
return ctx;
|
|
123644
|
-
}
|
|
123645
|
-
for (let i = 0; i < ctx.getChildCount(); i++) {
|
|
123646
|
-
const child = ctx.getChild(i);
|
|
123647
|
-
if (child instanceof ParserRuleContext) {
|
|
123648
|
-
const result = this.findMultiplicityBounds(child);
|
|
123649
|
-
if (result) {
|
|
123650
|
-
return result;
|
|
123651
|
-
}
|
|
123652
|
-
}
|
|
123653
|
-
}
|
|
123654
|
-
return void 0;
|
|
123655
|
-
}
|
|
123656
123685
|
/**
|
|
123657
123686
|
* Whether a context is a prefix metadata or definition/usage prefix rule.
|
|
123658
123687
|
* These contain annotation identifiers (e.g. from `#product`) that should
|
|
@@ -123694,6 +123723,14 @@ var SymbolTable = class {
|
|
|
123694
123723
|
if (this.isQuotedName(text)) return true;
|
|
123695
123724
|
return /^[a-zA-Z_]/.test(text) && !this.isKeyword(text);
|
|
123696
123725
|
}
|
|
123726
|
+
/**
|
|
123727
|
+
* Whether a terminal is (part of) a name: an identifier, a quoted name, or
|
|
123728
|
+
* a KerML keyword such as `step` or `function` that the grammar parsed as a
|
|
123729
|
+
* name (`name : IDENTIFIER | STRING | unreservedKeyword`).
|
|
123730
|
+
*/
|
|
123731
|
+
isNameTerminal(node) {
|
|
123732
|
+
return this.isIdentifierToken(node.symbol) || node.parent?.ruleIndex === SysMLv2Parser.RULE_unreservedKeyword;
|
|
123733
|
+
}
|
|
123697
123734
|
/**
|
|
123698
123735
|
* Check if text is a SysML quoted name (single-quoted string).
|
|
123699
123736
|
*/
|
|
@@ -124063,7 +124100,7 @@ var SymbolTable = class {
|
|
|
124063
124100
|
const child = ctx.getChild(i);
|
|
124064
124101
|
if (child instanceof TerminalNode) {
|
|
124065
124102
|
const text = child.symbol.text;
|
|
124066
|
-
if (text && this.
|
|
124103
|
+
if (text && this.isNameTerminal(child)) {
|
|
124067
124104
|
parts.push(this.unquoteName(text));
|
|
124068
124105
|
}
|
|
124069
124106
|
} else if (child instanceof ParserRuleContext) {
|
|
@@ -124289,6 +124326,17 @@ var DocumentManager = class {
|
|
|
124289
124326
|
}
|
|
124290
124327
|
return this.wsSymbolTable;
|
|
124291
124328
|
}
|
|
124329
|
+
/**
|
|
124330
|
+
* Rebuild the symbol tables of `uris` on next use, e.g. after their projectId
|
|
124331
|
+
* changed, which changes their symbol IDs (see `setFolderProjectIds`).
|
|
124332
|
+
*/
|
|
124333
|
+
invalidateSymbols(uris) {
|
|
124334
|
+
for (const uri of uris) {
|
|
124335
|
+
const cached = this.cache.get(uri);
|
|
124336
|
+
if (cached) cached.symbolTable = void 0;
|
|
124337
|
+
this.wsBuiltVersions.delete(uri);
|
|
124338
|
+
}
|
|
124339
|
+
}
|
|
124292
124340
|
/**
|
|
124293
124341
|
* Cache semantic diagnostics for the current document version.
|
|
124294
124342
|
*/
|
|
@@ -126020,9 +126068,8 @@ var SysMLModelProvider = class {
|
|
|
126020
126068
|
if (direction) {
|
|
126021
126069
|
attributes["direction"] = direction;
|
|
126022
126070
|
}
|
|
126023
|
-
|
|
126024
|
-
|
|
126025
|
-
attributes["multiplicity"] = multiplicity;
|
|
126071
|
+
if (symbol.multiplicity) {
|
|
126072
|
+
attributes["multiplicity"] = symbol.multiplicity;
|
|
126026
126073
|
}
|
|
126027
126074
|
const modifier = this.extractModifier(symbol, lines);
|
|
126028
126075
|
if (modifier) {
|
|
@@ -126640,7 +126687,7 @@ var SysMLModelProvider = class {
|
|
|
126640
126687
|
name: c.name,
|
|
126641
126688
|
kind: toMetaclassName(c.kind),
|
|
126642
126689
|
type: c.typeNames.join(", ") || void 0,
|
|
126643
|
-
multiplicity: c.multiplicity
|
|
126690
|
+
multiplicity: c.multiplicity,
|
|
126644
126691
|
direction,
|
|
126645
126692
|
visibility: c.visibility,
|
|
126646
126693
|
isDerived: modifier?.split(", ").includes("derived") ?? false,
|
|
@@ -126764,15 +126811,6 @@ var SysMLModelProvider = class {
|
|
|
126764
126811
|
if (containsWord(elementText, "out")) return "out";
|
|
126765
126812
|
return void 0;
|
|
126766
126813
|
}
|
|
126767
|
-
/** Extract multiplicity (e.g., [4], [0..*]) from source text. */
|
|
126768
|
-
extractMultiplicity(symbol, lines) {
|
|
126769
|
-
const elementText = this.getElementText(symbol, lines);
|
|
126770
|
-
const open = elementText.indexOf("[");
|
|
126771
|
-
if (open < 0) return void 0;
|
|
126772
|
-
const close = elementText.indexOf("]", open + 1);
|
|
126773
|
-
if (close < 0) return void 0;
|
|
126774
|
-
return elementText.substring(open + 1, close);
|
|
126775
|
-
}
|
|
126776
126814
|
/** Extract modifiers (abstract, readonly, derived, etc.) from source text. */
|
|
126777
126815
|
extractModifier(symbol, lines) {
|
|
126778
126816
|
const elementText = this.getElementText(symbol, lines);
|
|
@@ -128292,6 +128330,8 @@ function toSysMLSymbolKind(kind) {
|
|
|
128292
128330
|
// Requirements → Object
|
|
128293
128331
|
case "requirement def" /* RequirementDef */:
|
|
128294
128332
|
case "requirement" /* RequirementUsage */:
|
|
128333
|
+
case "concern def" /* ConcernDef */:
|
|
128334
|
+
case "concern" /* ConcernUsage */:
|
|
128295
128335
|
case "actor" /* ActorUsage */:
|
|
128296
128336
|
case "subject" /* SubjectUsage */:
|
|
128297
128337
|
case "stakeholder" /* StakeholderUsage */:
|
|
@@ -130685,6 +130725,10 @@ hoverProvider.setSemanticValidator(semanticValidator);
|
|
|
130685
130725
|
var hasConfigurationCapability = false;
|
|
130686
130726
|
var hasWorkspaceFolderCapability = false;
|
|
130687
130727
|
var workspaceRoots = [];
|
|
130728
|
+
var workspaceFolderUris = [];
|
|
130729
|
+
function rootsOf(folderUris) {
|
|
130730
|
+
return folderUris.map((uri) => toFsPath(uri)).filter((p) => p !== void 0);
|
|
130731
|
+
}
|
|
130688
130732
|
var isWorkspaceFile = false;
|
|
130689
130733
|
var preloadOnOpen = "workspaceOnly";
|
|
130690
130734
|
var disabledDiagnosticCodes = /* @__PURE__ */ new Set();
|
|
@@ -130696,6 +130740,10 @@ function publishDiagnostics(uri, diagnostics) {
|
|
|
130696
130740
|
}
|
|
130697
130741
|
var skipDirs = new Set(DEFAULT_SKIP_DIRS);
|
|
130698
130742
|
var serverReady = false;
|
|
130743
|
+
var resolveInitialization;
|
|
130744
|
+
var initialization = new Promise((resolve2) => {
|
|
130745
|
+
resolveInitialization = resolve2;
|
|
130746
|
+
});
|
|
130699
130747
|
var earlyOpenUris = /* @__PURE__ */ new Set();
|
|
130700
130748
|
var workerRequestId = 0;
|
|
130701
130749
|
var isBrowserServer = typeof __SYSML_BROWSER_SERVER__ !== "undefined" && __SYSML_BROWSER_SERVER__;
|
|
@@ -130809,7 +130857,8 @@ connection.onInitialize((params) => {
|
|
|
130809
130857
|
connection.console.warn(`projectId is not a UUID: ${initOpts.projectId}; symbol IDs are unique only within this workspace`);
|
|
130810
130858
|
}
|
|
130811
130859
|
if (params.workspaceFolders) {
|
|
130812
|
-
|
|
130860
|
+
workspaceFolderUris = params.workspaceFolders.map((f) => f.uri);
|
|
130861
|
+
workspaceRoots = rootsOf(workspaceFolderUris);
|
|
130813
130862
|
} else if (params.rootUri) {
|
|
130814
130863
|
const root = toFsPath(params.rootUri);
|
|
130815
130864
|
if (root) workspaceRoots = [root];
|
|
@@ -130859,7 +130908,8 @@ connection.onInitialize((params) => {
|
|
|
130859
130908
|
if (hasWorkspaceFolderCapability) {
|
|
130860
130909
|
result.capabilities.workspace = {
|
|
130861
130910
|
workspaceFolders: {
|
|
130862
|
-
supported: true
|
|
130911
|
+
supported: true,
|
|
130912
|
+
changeNotifications: true
|
|
130863
130913
|
}
|
|
130864
130914
|
};
|
|
130865
130915
|
}
|
|
@@ -130871,8 +130921,17 @@ connection.onInitialized(async () => {
|
|
|
130871
130921
|
import_node12.DidChangeConfigurationNotification.type,
|
|
130872
130922
|
void 0
|
|
130873
130923
|
);
|
|
130924
|
+
}
|
|
130925
|
+
if (hasWorkspaceFolderCapability) {
|
|
130926
|
+
connection.workspace.onDidChangeWorkspaceFolders((event) => {
|
|
130927
|
+
onWorkspaceFoldersChanged(event).catch((e) => connection.console.error(`Workspace folder change failed: ${e}`));
|
|
130928
|
+
});
|
|
130929
|
+
}
|
|
130930
|
+
if (hasConfigurationCapability) {
|
|
130874
130931
|
await pullSettings().catch(() => {
|
|
130875
130932
|
});
|
|
130933
|
+
await pullFolderProjectIds().catch(() => {
|
|
130934
|
+
});
|
|
130876
130935
|
}
|
|
130877
130936
|
const libCount = initLibraryIndex(__dirname);
|
|
130878
130937
|
connection.console.log(`SysML v2 Language Server initialized (${libCount} library packages indexed)`);
|
|
@@ -130888,14 +130947,13 @@ connection.onInitialized(async () => {
|
|
|
130888
130947
|
);
|
|
130889
130948
|
}
|
|
130890
130949
|
serverReady = true;
|
|
130950
|
+
resolveInitialization();
|
|
130891
130951
|
spawnParseWorker();
|
|
130892
130952
|
if (workspaceRoots.length > 0 && (preloadOnOpen === "always" || preloadOnOpen === "workspaceOnly" && isWorkspaceFile)) {
|
|
130893
|
-
|
|
130894
|
-
scanWorkspaceFoldersAsync(workspaceRoots).then(({ fileCount, scanMs }) => {
|
|
130953
|
+
scanWorkspaceFolders(workspaceRoots).then(({ fileCount, scanMs }) => {
|
|
130895
130954
|
connection.console.log(
|
|
130896
130955
|
`Workspace scan: pre-parsed ${fileCount} .sysml files in ${scanMs} ms`
|
|
130897
130956
|
);
|
|
130898
|
-
documentManager.setWorkspaceScanComplete(true);
|
|
130899
130957
|
revalidateOpenDocuments();
|
|
130900
130958
|
});
|
|
130901
130959
|
}
|
|
@@ -130930,9 +130988,79 @@ function applySettings(config) {
|
|
|
130930
130988
|
}
|
|
130931
130989
|
}
|
|
130932
130990
|
connection.onDidChangeConfiguration((_change) => {
|
|
130933
|
-
pullSettings().then(() => revalidateOpenDocuments()).catch(() => {
|
|
130991
|
+
pullSettings().then(() => pullFolderProjectIds()).then(() => revalidateOpenDocuments()).catch(() => {
|
|
130992
|
+
});
|
|
130993
|
+
});
|
|
130994
|
+
function latestWins(task) {
|
|
130995
|
+
let calls = 0;
|
|
130996
|
+
let latest = Promise.resolve();
|
|
130997
|
+
return () => {
|
|
130998
|
+
const call = ++calls;
|
|
130999
|
+
const isSuperseded = () => call !== calls;
|
|
131000
|
+
const run = task(isSuperseded).then(() => isSuperseded() ? latest : void 0);
|
|
131001
|
+
latest = run;
|
|
131002
|
+
return run;
|
|
131003
|
+
};
|
|
131004
|
+
}
|
|
131005
|
+
var pullFolderProjectIds = latestWins(async (isSuperseded) => {
|
|
131006
|
+
if (!hasConfigurationCapability) return;
|
|
131007
|
+
const folderUris = [...workspaceFolderUris];
|
|
131008
|
+
const answers = folderUris.length === 0 ? [] : await connection.workspace.getConfiguration(folderUris.map((scopeUri) => ({ scopeUri, section: "sysml.project" })));
|
|
131009
|
+
if (isSuperseded()) return;
|
|
131010
|
+
const projectIds = folderUris.flatMap((folderUri, i) => {
|
|
131011
|
+
const projectId = answers[i]?.projectId;
|
|
131012
|
+
return typeof projectId === "string" ? [{ folderUri, projectId }] : [];
|
|
130934
131013
|
});
|
|
131014
|
+
const uris = documentManager.getUris();
|
|
131015
|
+
const prefixBefore = new Map(uris.map((uri) => [uri, getUrlPrefix(uri)]));
|
|
131016
|
+
const rejected = setFolderProjectIds(projectIds);
|
|
131017
|
+
for (const entry of rejected) {
|
|
131018
|
+
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`);
|
|
131019
|
+
}
|
|
131020
|
+
documentManager.invalidateSymbols(uris.filter((uri) => getUrlPrefix(uri) !== prefixBefore.get(uri)));
|
|
131021
|
+
logFolderPrefixes(new Set(projectIds.filter((p) => !rejected.includes(p)).map((p) => p.folderUri)));
|
|
130935
131022
|
});
|
|
131023
|
+
var loggedFolderPrefixes = /* @__PURE__ */ new Map();
|
|
131024
|
+
function logFolderPrefixes(ownProjectIds) {
|
|
131025
|
+
for (const folderUri of workspaceFolderUris) {
|
|
131026
|
+
const prefix = getUrlPrefix(`${folderUri.endsWith("/") ? folderUri : `${folderUri}/`}_.sysml`);
|
|
131027
|
+
if (loggedFolderPrefixes.get(folderUri) === prefix) continue;
|
|
131028
|
+
loggedFolderPrefixes.set(folderUri, prefix);
|
|
131029
|
+
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";
|
|
131030
|
+
connection.console.info(`Folder ${folderUri}: top-level elements' URLs start with ${prefix} (${source})`);
|
|
131031
|
+
}
|
|
131032
|
+
for (const folderUri of loggedFolderPrefixes.keys()) {
|
|
131033
|
+
if (!workspaceFolderUris.includes(folderUri)) loggedFolderPrefixes.delete(folderUri);
|
|
131034
|
+
}
|
|
131035
|
+
}
|
|
131036
|
+
async function onWorkspaceFoldersChanged(event) {
|
|
131037
|
+
const initialScanPending = !serverReady;
|
|
131038
|
+
const removed = new Set(event.removed.map((f) => f.uri));
|
|
131039
|
+
workspaceFolderUris = [...workspaceFolderUris.filter((uri) => !removed.has(uri)), ...event.added.map((f) => f.uri)];
|
|
131040
|
+
workspaceRoots = rootsOf(workspaceFolderUris);
|
|
131041
|
+
dropDocumentsOutsideWorkspace(event.removed.map((f) => f.uri));
|
|
131042
|
+
await pullFolderProjectIds().catch(() => {
|
|
131043
|
+
});
|
|
131044
|
+
if (initialScanPending) return;
|
|
131045
|
+
const addedRoots = rootsOf(event.added.map((f) => f.uri).filter((uri) => workspaceFolderUris.includes(uri)));
|
|
131046
|
+
if (addedRoots.length > 0 && (preloadOnOpen === "always" || preloadOnOpen === "workspaceOnly" && isWorkspaceFile)) {
|
|
131047
|
+
const { fileCount, scanMs } = await scanWorkspaceFolders(addedRoots);
|
|
131048
|
+
connection.console.log(`Workspace scan: pre-parsed ${fileCount} .sysml files of ${addedRoots.length} added folder(s) in ${scanMs} ms`);
|
|
131049
|
+
}
|
|
131050
|
+
revalidateOpenDocuments();
|
|
131051
|
+
}
|
|
131052
|
+
function dropDocumentsOutsideWorkspace(folderUris) {
|
|
131053
|
+
for (const uri of documentManager.getUris()) {
|
|
131054
|
+
if (openDocumentFor(uri)) continue;
|
|
131055
|
+
if (folderUris.some((f) => isInFolder(uri, f)) && !isInWorkspace(uri)) {
|
|
131056
|
+
documentManager.remove(uri);
|
|
131057
|
+
modelProvider.removeUri(uri);
|
|
131058
|
+
}
|
|
131059
|
+
}
|
|
131060
|
+
}
|
|
131061
|
+
function isInWorkspace(uri) {
|
|
131062
|
+
return workspaceRoots.some((root) => isInFolder(uri, (0, import_node_url2.pathToFileURL)(root).toString()));
|
|
131063
|
+
}
|
|
130936
131064
|
function openDocumentFor(uri) {
|
|
130937
131065
|
return documents.get(uri) ?? documents.all().find((d) => isSameDocumentUri(d.uri, uri));
|
|
130938
131066
|
}
|
|
@@ -130957,6 +131085,16 @@ function parseWorkspaceFile(filePath, uri = (0, import_node_url2.pathToFileURL)(
|
|
|
130957
131085
|
documentManager.parse(doc);
|
|
130958
131086
|
return true;
|
|
130959
131087
|
}
|
|
131088
|
+
var runningScans = 0;
|
|
131089
|
+
async function scanWorkspaceFolders(roots) {
|
|
131090
|
+
runningScans++;
|
|
131091
|
+
documentManager.setWorkspaceScanComplete(false);
|
|
131092
|
+
try {
|
|
131093
|
+
return await scanWorkspaceFoldersAsync(roots);
|
|
131094
|
+
} finally {
|
|
131095
|
+
if (--runningScans === 0) documentManager.setWorkspaceScanComplete(true);
|
|
131096
|
+
}
|
|
131097
|
+
}
|
|
130960
131098
|
async function scanWorkspaceFoldersAsync(roots) {
|
|
130961
131099
|
const scanT0 = Date.now();
|
|
130962
131100
|
const fileArrays = await Promise.all(roots.map((r) => findSysMLFilesAsync(r, skipDirs)));
|
|
@@ -130968,6 +131106,7 @@ async function scanWorkspaceFoldersAsync(roots) {
|
|
|
130968
131106
|
const filePath = allFiles[i];
|
|
130969
131107
|
const uri = (0, import_node_url2.pathToFileURL)(filePath).toString();
|
|
130970
131108
|
if (openDocumentFor(uri)) continue;
|
|
131109
|
+
if (!isInWorkspace(uri)) continue;
|
|
130971
131110
|
const content = fileContents.get(filePath);
|
|
130972
131111
|
if (content === void 0) continue;
|
|
130973
131112
|
documentManager.parseBatch(uri, 0, content);
|
|
@@ -131180,14 +131319,16 @@ connection.onDocumentRangeFormatting(
|
|
|
131180
131319
|
return formattingProvider.provideRangeFormatting(params);
|
|
131181
131320
|
}
|
|
131182
131321
|
);
|
|
131183
|
-
connection.onRequest("sysml/model", (params) => {
|
|
131322
|
+
connection.onRequest("sysml/model", async (params) => {
|
|
131323
|
+
await initialization;
|
|
131184
131324
|
return modelProvider.getModel(
|
|
131185
131325
|
params.textDocument.uri,
|
|
131186
131326
|
documentManager.getVersion(params.textDocument.uri),
|
|
131187
131327
|
params.scope
|
|
131188
131328
|
);
|
|
131189
131329
|
});
|
|
131190
|
-
connection.onRequest("sysml/elementLookup", (params) => {
|
|
131330
|
+
connection.onRequest("sysml/elementLookup", async (params) => {
|
|
131331
|
+
await initialization;
|
|
131191
131332
|
return elementLookupProvider.elementLookup(params);
|
|
131192
131333
|
});
|
|
131193
131334
|
connection.onRequest("sysml/serverStats", () => {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "sysml-v2-lsp",
|
|
3
3
|
"displayName": "SysML v2 Language Server",
|
|
4
4
|
"description": "Language Server Protocol implementation for SysML v2, powered by ANTLR4",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.35.0",
|
|
6
6
|
"publisher": "JamieD",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"repository": {
|