sysml-v2-lsp 0.36.0 → 0.38.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.
@@ -123,30 +123,30 @@
123
123
  Object.defineProperty(exports, "__esModule", { value: true });
124
124
  exports.Message = exports.NotificationType9 = exports.NotificationType8 = exports.NotificationType7 = exports.NotificationType6 = exports.NotificationType5 = exports.NotificationType4 = exports.NotificationType3 = exports.NotificationType2 = exports.NotificationType1 = exports.NotificationType0 = exports.NotificationType = exports.RequestType9 = exports.RequestType8 = exports.RequestType7 = exports.RequestType6 = exports.RequestType5 = exports.RequestType4 = exports.RequestType3 = exports.RequestType2 = exports.RequestType1 = exports.RequestType = exports.RequestType0 = exports.AbstractMessageSignature = exports.ParameterStructures = exports.ResponseError = exports.ErrorCodes = void 0;
125
125
  var is = __importStar(require_is());
126
- var ErrorCodes;
127
- (function(ErrorCodes2) {
128
- ErrorCodes2.ParseError = -32700;
129
- ErrorCodes2.InvalidRequest = -32600;
130
- ErrorCodes2.MethodNotFound = -32601;
131
- ErrorCodes2.InvalidParams = -32602;
132
- ErrorCodes2.InternalError = -32603;
133
- ErrorCodes2.jsonrpcReservedErrorRangeStart = -32099;
134
- ErrorCodes2.serverErrorStart = -32099;
135
- ErrorCodes2.MessageWriteError = -32099;
136
- ErrorCodes2.MessageReadError = -32098;
137
- ErrorCodes2.PendingResponseRejected = -32097;
138
- ErrorCodes2.ConnectionInactive = -32096;
139
- ErrorCodes2.ServerNotInitialized = -32002;
140
- ErrorCodes2.UnknownErrorCode = -32001;
141
- ErrorCodes2.jsonrpcReservedErrorRangeEnd = -32e3;
142
- ErrorCodes2.serverErrorEnd = -32e3;
143
- })(ErrorCodes || (exports.ErrorCodes = ErrorCodes = {}));
144
- var ResponseError = class _ResponseError extends Error {
126
+ var ErrorCodes3;
127
+ (function(ErrorCodes4) {
128
+ ErrorCodes4.ParseError = -32700;
129
+ ErrorCodes4.InvalidRequest = -32600;
130
+ ErrorCodes4.MethodNotFound = -32601;
131
+ ErrorCodes4.InvalidParams = -32602;
132
+ ErrorCodes4.InternalError = -32603;
133
+ ErrorCodes4.jsonrpcReservedErrorRangeStart = -32099;
134
+ ErrorCodes4.serverErrorStart = -32099;
135
+ ErrorCodes4.MessageWriteError = -32099;
136
+ ErrorCodes4.MessageReadError = -32098;
137
+ ErrorCodes4.PendingResponseRejected = -32097;
138
+ ErrorCodes4.ConnectionInactive = -32096;
139
+ ErrorCodes4.ServerNotInitialized = -32002;
140
+ ErrorCodes4.UnknownErrorCode = -32001;
141
+ ErrorCodes4.jsonrpcReservedErrorRangeEnd = -32e3;
142
+ ErrorCodes4.serverErrorEnd = -32e3;
143
+ })(ErrorCodes3 || (exports.ErrorCodes = ErrorCodes3 = {}));
144
+ var ResponseError3 = class _ResponseError extends Error {
145
145
  code;
146
146
  data;
147
147
  constructor(code, message, data) {
148
148
  super(message);
149
- this.code = is.number(code) ? code : ErrorCodes.UnknownErrorCode;
149
+ this.code = is.number(code) ? code : ErrorCodes3.UnknownErrorCode;
150
150
  this.data = data;
151
151
  Object.setPrototypeOf(this, _ResponseError.prototype);
152
152
  }
@@ -161,7 +161,7 @@
161
161
  return result;
162
162
  }
163
163
  };
164
- exports.ResponseError = ResponseError;
164
+ exports.ResponseError = ResponseError3;
165
165
  var ParameterStructures = class _ParameterStructures {
166
166
  kind;
167
167
  /**
@@ -3362,7 +3362,7 @@ ${JSON.stringify(message, null, 4)}`);
3362
3362
  }
3363
3363
  uinteger3.is = is;
3364
3364
  })(uinteger || (uinteger = {}));
3365
- (function(Position5) {
3365
+ (function(Position6) {
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
- Position5.create = create;
3375
+ Position6.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
- Position5.is = is;
3380
+ Position6.is = is;
3381
3381
  })(Position || (Position = {}));
3382
- (function(Range5) {
3382
+ (function(Range8) {
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,23 +3389,23 @@ ${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
- Range5.create = create;
3392
+ Range8.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
- Range5.is = is;
3397
+ Range8.is = is;
3398
3398
  })(Range || (Range = {}));
3399
- (function(Location4) {
3399
+ (function(Location5) {
3400
3400
  function create(uri, range) {
3401
3401
  return { uri, range };
3402
3402
  }
3403
- Location4.create = create;
3403
+ Location5.create = create;
3404
3404
  function is(value) {
3405
3405
  const candidate = value;
3406
3406
  return Is.objectLiteral(candidate) && Range.is(candidate.range) && (Is.string(candidate.uri) || Is.undefined(candidate.uri));
3407
3407
  }
3408
- Location4.is = is;
3408
+ Location5.is = is;
3409
3409
  })(Location || (Location = {}));
3410
3410
  (function(LocationLink3) {
3411
3411
  function create(targetUri, targetRange, targetSelectionRange, originSelectionRange) {
@@ -3526,7 +3526,7 @@ ${JSON.stringify(message, null, 4)}`);
3526
3526
  }
3527
3527
  CodeDescription3.is = is;
3528
3528
  })(CodeDescription || (CodeDescription = {}));
3529
- (function(Diagnostic8) {
3529
+ (function(Diagnostic9) {
3530
3530
  function create(range, message, severity, code, source, relatedInformation) {
3531
3531
  const result = { range, message };
3532
3532
  if (Is.defined(severity)) {
@@ -3543,17 +3543,17 @@ ${JSON.stringify(message, null, 4)}`);
3543
3543
  }
3544
3544
  return result;
3545
3545
  }
3546
- Diagnostic8.create = create;
3546
+ Diagnostic9.create = create;
3547
3547
  function is(value) {
3548
3548
  var _a;
3549
3549
  const candidate = value;
3550
3550
  return Is.defined(candidate) && Range.is(candidate.range) && (Is.string(candidate.message) || MarkupContent.is(candidate.message)) && (Is.number(candidate.severity) || Is.undefined(candidate.severity)) && (Is.integer(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code)) && (Is.undefined(candidate.codeDescription) || Is.string((_a = candidate.codeDescription) === null || _a === void 0 ? void 0 : _a.href)) && (Is.string(candidate.source) || Is.undefined(candidate.source)) && (Is.undefined(candidate.relatedInformation) || Is.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation.is));
3551
3551
  }
3552
- Diagnostic8.is = is;
3552
+ Diagnostic9.is = is;
3553
3553
  function is3_17(value) {
3554
3554
  return Is.string(value.message);
3555
3555
  }
3556
- Diagnostic8.is3_17 = is3_17;
3556
+ Diagnostic9.is3_17 = is3_17;
3557
3557
  function getMessageString(diagnostic) {
3558
3558
  if (Is.string(diagnostic.message)) {
3559
3559
  return diagnostic.message;
@@ -3563,7 +3563,7 @@ ${JSON.stringify(message, null, 4)}`);
3563
3563
  throw new Error(`Unknown message type ${typeof diagnostic.message}`);
3564
3564
  }
3565
3565
  }
3566
- Diagnostic8.getMessageString = getMessageString;
3566
+ Diagnostic9.getMessageString = getMessageString;
3567
3567
  })(Diagnostic || (Diagnostic = {}));
3568
3568
  (function(Command3) {
3569
3569
  function create(title, command, ...args) {
@@ -3580,24 +3580,24 @@ ${JSON.stringify(message, null, 4)}`);
3580
3580
  }
3581
3581
  Command3.is = is;
3582
3582
  })(Command || (Command = {}));
3583
- (function(TextEdit6) {
3583
+ (function(TextEdit7) {
3584
3584
  function replace(range, newText) {
3585
3585
  return { range, newText };
3586
3586
  }
3587
- TextEdit6.replace = replace;
3587
+ TextEdit7.replace = replace;
3588
3588
  function insert(position, newText) {
3589
3589
  return { range: { start: position, end: position }, newText };
3590
3590
  }
3591
- TextEdit6.insert = insert;
3591
+ TextEdit7.insert = insert;
3592
3592
  function del(range) {
3593
3593
  return { range, newText: "" };
3594
3594
  }
3595
- TextEdit6.del = del;
3595
+ TextEdit7.del = del;
3596
3596
  function is(value) {
3597
3597
  const candidate = value;
3598
3598
  return Is.objectLiteral(candidate) && Is.string(candidate.newText) && Range.is(candidate.range);
3599
3599
  }
3600
- TextEdit6.is = is;
3600
+ TextEdit7.is = is;
3601
3601
  })(TextEdit || (TextEdit = {}));
3602
3602
  (function(ChangeAnnotation3) {
3603
3603
  function create(label, needsConfirmation, description) {
@@ -3718,7 +3718,7 @@ ${JSON.stringify(message, null, 4)}`);
3718
3718
  }
3719
3719
  DeleteFile3.is = is;
3720
3720
  })(DeleteFile || (DeleteFile = {}));
3721
- (function(WorkspaceEdit5) {
3721
+ (function(WorkspaceEdit6) {
3722
3722
  function is(value) {
3723
3723
  const candidate = value;
3724
3724
  return candidate && (candidate.changes !== void 0 || candidate.documentChanges !== void 0) && (candidate.documentChanges === void 0 || candidate.documentChanges.every((change) => {
@@ -3729,7 +3729,7 @@ ${JSON.stringify(message, null, 4)}`);
3729
3729
  }
3730
3730
  }));
3731
3731
  }
3732
- WorkspaceEdit5.is = is;
3732
+ WorkspaceEdit6.is = is;
3733
3733
  })(WorkspaceEdit || (WorkspaceEdit = {}));
3734
3734
  TextEditChangeImpl = class {
3735
3735
  constructor(edits, changeAnnotations) {
@@ -9290,28 +9290,28 @@ ${JSON.stringify(message, null, 4)}`);
9290
9290
  Object.defineProperty(exports, "__esModule", { value: true });
9291
9291
  exports.Message = exports.NotificationType9 = exports.NotificationType8 = exports.NotificationType7 = exports.NotificationType6 = exports.NotificationType5 = exports.NotificationType4 = exports.NotificationType3 = exports.NotificationType2 = exports.NotificationType1 = exports.NotificationType0 = exports.NotificationType = exports.RequestType9 = exports.RequestType8 = exports.RequestType7 = exports.RequestType6 = exports.RequestType5 = exports.RequestType4 = exports.RequestType3 = exports.RequestType2 = exports.RequestType1 = exports.RequestType = exports.RequestType0 = exports.AbstractMessageSignature = exports.ParameterStructures = exports.ResponseError = exports.ErrorCodes = void 0;
9292
9292
  var is = require_is4();
9293
- var ErrorCodes;
9294
- (function(ErrorCodes2) {
9295
- ErrorCodes2.ParseError = -32700;
9296
- ErrorCodes2.InvalidRequest = -32600;
9297
- ErrorCodes2.MethodNotFound = -32601;
9298
- ErrorCodes2.InvalidParams = -32602;
9299
- ErrorCodes2.InternalError = -32603;
9300
- ErrorCodes2.jsonrpcReservedErrorRangeStart = -32099;
9301
- ErrorCodes2.serverErrorStart = -32099;
9302
- ErrorCodes2.MessageWriteError = -32099;
9303
- ErrorCodes2.MessageReadError = -32098;
9304
- ErrorCodes2.PendingResponseRejected = -32097;
9305
- ErrorCodes2.ConnectionInactive = -32096;
9306
- ErrorCodes2.ServerNotInitialized = -32002;
9307
- ErrorCodes2.UnknownErrorCode = -32001;
9308
- ErrorCodes2.jsonrpcReservedErrorRangeEnd = -32e3;
9309
- ErrorCodes2.serverErrorEnd = -32e3;
9310
- })(ErrorCodes || (exports.ErrorCodes = ErrorCodes = {}));
9311
- var ResponseError = class _ResponseError extends Error {
9293
+ var ErrorCodes3;
9294
+ (function(ErrorCodes4) {
9295
+ ErrorCodes4.ParseError = -32700;
9296
+ ErrorCodes4.InvalidRequest = -32600;
9297
+ ErrorCodes4.MethodNotFound = -32601;
9298
+ ErrorCodes4.InvalidParams = -32602;
9299
+ ErrorCodes4.InternalError = -32603;
9300
+ ErrorCodes4.jsonrpcReservedErrorRangeStart = -32099;
9301
+ ErrorCodes4.serverErrorStart = -32099;
9302
+ ErrorCodes4.MessageWriteError = -32099;
9303
+ ErrorCodes4.MessageReadError = -32098;
9304
+ ErrorCodes4.PendingResponseRejected = -32097;
9305
+ ErrorCodes4.ConnectionInactive = -32096;
9306
+ ErrorCodes4.ServerNotInitialized = -32002;
9307
+ ErrorCodes4.UnknownErrorCode = -32001;
9308
+ ErrorCodes4.jsonrpcReservedErrorRangeEnd = -32e3;
9309
+ ErrorCodes4.serverErrorEnd = -32e3;
9310
+ })(ErrorCodes3 || (exports.ErrorCodes = ErrorCodes3 = {}));
9311
+ var ResponseError3 = class _ResponseError extends Error {
9312
9312
  constructor(code, message, data) {
9313
9313
  super(message);
9314
- this.code = is.number(code) ? code : ErrorCodes.UnknownErrorCode;
9314
+ this.code = is.number(code) ? code : ErrorCodes3.UnknownErrorCode;
9315
9315
  this.data = data;
9316
9316
  Object.setPrototypeOf(this, _ResponseError.prototype);
9317
9317
  }
@@ -9326,7 +9326,7 @@ ${JSON.stringify(message, null, 4)}`);
9326
9326
  return result;
9327
9327
  }
9328
9328
  };
9329
- exports.ResponseError = ResponseError;
9329
+ exports.ResponseError = ResponseError3;
9330
9330
  var ParameterStructures = class _ParameterStructures {
9331
9331
  constructor(kind) {
9332
9332
  this.kind = kind;
@@ -12435,7 +12435,7 @@ ${JSON.stringify(message, null, 4)}`);
12435
12435
  }
12436
12436
  uinteger3.is = is;
12437
12437
  })(uinteger2 || (uinteger2 = {}));
12438
- (function(Position5) {
12438
+ (function(Position6) {
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
- Position5.create = create;
12448
+ Position6.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
- Position5.is = is;
12453
+ Position6.is = is;
12454
12454
  })(Position2 || (Position2 = {}));
12455
- (function(Range5) {
12455
+ (function(Range8) {
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,23 +12462,23 @@ ${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
- Range5.create = create;
12465
+ Range8.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
- Range5.is = is;
12470
+ Range8.is = is;
12471
12471
  })(Range2 || (Range2 = {}));
12472
- (function(Location4) {
12472
+ (function(Location5) {
12473
12473
  function create(uri, range) {
12474
12474
  return { uri, range };
12475
12475
  }
12476
- Location4.create = create;
12476
+ Location5.create = create;
12477
12477
  function is(value) {
12478
12478
  let candidate = value;
12479
12479
  return Is2.objectLiteral(candidate) && Range2.is(candidate.range) && (Is2.string(candidate.uri) || Is2.undefined(candidate.uri));
12480
12480
  }
12481
- Location4.is = is;
12481
+ Location5.is = is;
12482
12482
  })(Location2 || (Location2 = {}));
12483
12483
  (function(LocationLink3) {
12484
12484
  function create(targetUri, targetRange, targetSelectionRange, originSelectionRange) {
@@ -12599,7 +12599,7 @@ ${JSON.stringify(message, null, 4)}`);
12599
12599
  }
12600
12600
  CodeDescription3.is = is;
12601
12601
  })(CodeDescription2 || (CodeDescription2 = {}));
12602
- (function(Diagnostic8) {
12602
+ (function(Diagnostic9) {
12603
12603
  function create(range, message, severity, code, source, relatedInformation) {
12604
12604
  let result = { range, message };
12605
12605
  if (Is2.defined(severity)) {
@@ -12616,13 +12616,13 @@ ${JSON.stringify(message, null, 4)}`);
12616
12616
  }
12617
12617
  return result;
12618
12618
  }
12619
- Diagnostic8.create = create;
12619
+ Diagnostic9.create = create;
12620
12620
  function is(value) {
12621
12621
  var _a;
12622
12622
  let candidate = value;
12623
12623
  return Is2.defined(candidate) && Range2.is(candidate.range) && Is2.string(candidate.message) && (Is2.number(candidate.severity) || Is2.undefined(candidate.severity)) && (Is2.integer(candidate.code) || Is2.string(candidate.code) || Is2.undefined(candidate.code)) && (Is2.undefined(candidate.codeDescription) || Is2.string((_a = candidate.codeDescription) === null || _a === void 0 ? void 0 : _a.href)) && (Is2.string(candidate.source) || Is2.undefined(candidate.source)) && (Is2.undefined(candidate.relatedInformation) || Is2.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation2.is));
12624
12624
  }
12625
- Diagnostic8.is = is;
12625
+ Diagnostic9.is = is;
12626
12626
  })(Diagnostic2 || (Diagnostic2 = {}));
12627
12627
  (function(Command3) {
12628
12628
  function create(title, command, ...args) {
@@ -12639,24 +12639,24 @@ ${JSON.stringify(message, null, 4)}`);
12639
12639
  }
12640
12640
  Command3.is = is;
12641
12641
  })(Command2 || (Command2 = {}));
12642
- (function(TextEdit6) {
12642
+ (function(TextEdit7) {
12643
12643
  function replace(range, newText) {
12644
12644
  return { range, newText };
12645
12645
  }
12646
- TextEdit6.replace = replace;
12646
+ TextEdit7.replace = replace;
12647
12647
  function insert(position, newText) {
12648
12648
  return { range: { start: position, end: position }, newText };
12649
12649
  }
12650
- TextEdit6.insert = insert;
12650
+ TextEdit7.insert = insert;
12651
12651
  function del(range) {
12652
12652
  return { range, newText: "" };
12653
12653
  }
12654
- TextEdit6.del = del;
12654
+ TextEdit7.del = del;
12655
12655
  function is(value) {
12656
12656
  const candidate = value;
12657
12657
  return Is2.objectLiteral(candidate) && Is2.string(candidate.newText) && Range2.is(candidate.range);
12658
12658
  }
12659
- TextEdit6.is = is;
12659
+ TextEdit7.is = is;
12660
12660
  })(TextEdit2 || (TextEdit2 = {}));
12661
12661
  (function(ChangeAnnotation3) {
12662
12662
  function create(label, needsConfirmation, description) {
@@ -12777,7 +12777,7 @@ ${JSON.stringify(message, null, 4)}`);
12777
12777
  }
12778
12778
  DeleteFile3.is = is;
12779
12779
  })(DeleteFile2 || (DeleteFile2 = {}));
12780
- (function(WorkspaceEdit5) {
12780
+ (function(WorkspaceEdit6) {
12781
12781
  function is(value) {
12782
12782
  let candidate = value;
12783
12783
  return candidate && (candidate.changes !== void 0 || candidate.documentChanges !== void 0) && (candidate.documentChanges === void 0 || candidate.documentChanges.every((change) => {
@@ -12788,7 +12788,7 @@ ${JSON.stringify(message, null, 4)}`);
12788
12788
  }
12789
12789
  }));
12790
12790
  }
12791
- WorkspaceEdit5.is = is;
12791
+ WorkspaceEdit6.is = is;
12792
12792
  })(WorkspaceEdit2 || (WorkspaceEdit2 = {}));
12793
12793
  TextEditChangeImpl2 = class {
12794
12794
  constructor(edits, changeAnnotations) {
@@ -17437,7 +17437,7 @@ ${JSON.stringify(message, null, 4)}`);
17437
17437
  });
17438
17438
 
17439
17439
  // server/src/server.ts
17440
- var import_node11 = __toESM(require_main3());
17440
+ var import_node14 = __toESM(require_main3());
17441
17441
 
17442
17442
  // server/src/platform/shims/fs.ts
17443
17443
  function readFileSync(_path, _enc) {
@@ -130021,18 +130021,71 @@ ${JSON.stringify(message, null, 4)}`);
130021
130021
  }
130022
130022
  };
130023
130023
 
130024
+ // server/src/parser/positionUtils.ts
130025
+ function normalizeUtf16Columns(text, tokens, errors) {
130026
+ if (!/[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(text)) return;
130027
+ const columns = /* @__PURE__ */ new Map();
130028
+ const lines = text.split("\n");
130029
+ for (let line = 0; line < lines.length; line++) {
130030
+ if (!/[\uD800-\uDBFF][\uDC00-\uDFFF]/.test(lines[line])) continue;
130031
+ const offsets = [0];
130032
+ for (const character of lines[line]) offsets.push(offsets[offsets.length - 1] + character.length);
130033
+ columns.set(line, offsets);
130034
+ }
130035
+ for (const token of tokens) {
130036
+ token.column = columns.get(token.line - 1)?.[token.column] ?? token.column;
130037
+ }
130038
+ for (const error of errors) {
130039
+ error.column = columns.get(error.line)?.[error.column] ?? error.column;
130040
+ }
130041
+ }
130042
+ function tokenToPosition(token) {
130043
+ return {
130044
+ line: (token.line ?? 1) - 1,
130045
+ character: token.column ?? 0
130046
+ };
130047
+ }
130048
+ function tokenToRange(token) {
130049
+ const start = tokenToPosition(token);
130050
+ const length = token.text?.length ?? 1;
130051
+ return {
130052
+ start,
130053
+ end: { line: start.line, character: start.character + length }
130054
+ };
130055
+ }
130056
+ function contextToRange(ctx) {
130057
+ const startToken = ctx.start;
130058
+ const stopToken = ctx.stop ?? ctx.start;
130059
+ if (!startToken) {
130060
+ return { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } };
130061
+ }
130062
+ const start = {
130063
+ line: (startToken.line ?? 1) - 1,
130064
+ character: startToken.column ?? 0
130065
+ };
130066
+ const end = stopToken ? {
130067
+ line: (stopToken.line ?? 1) - 1,
130068
+ character: (stopToken.column ?? 0) + (stopToken.text?.length ?? 1)
130069
+ } : { line: start.line, character: start.character + 1 };
130070
+ return { start, end };
130071
+ }
130072
+
130024
130073
  // server/src/parser/parseDocument.ts
130074
+ function withUtf16Columns(text, result) {
130075
+ normalizeUtf16Columns(text, result.tokenStream.getTokens(), result.errors);
130076
+ return result;
130077
+ }
130025
130078
  function parseDocument(text) {
130026
130079
  const result = parseDocumentCore(text);
130027
130080
  if (result.errors.length > 0 && hasStaleDfaStates()) {
130028
130081
  markDfaNotPreSeeded();
130029
130082
  clearAllDFAStates();
130030
- return parseDocumentLL(text, result.lexer, result.tokenStream);
130083
+ return withUtf16Columns(text, parseDocumentLL(text, result.lexer, result.tokenStream));
130031
130084
  }
130032
130085
  if (isDfaPreSeeded()) {
130033
130086
  markDfaNotPreSeeded();
130034
130087
  }
130035
- return result;
130088
+ return withUtf16Columns(text, result);
130036
130089
  }
130037
130090
  function parseDocumentCore(text) {
130038
130091
  const inputStream = CharStream.fromString(text);
@@ -130174,19 +130227,19 @@ ${JSON.stringify(message, null, 4)}`);
130174
130227
  if (errors.length > 0 && hasStaleDfaStates()) {
130175
130228
  markDfaNotPreSeeded();
130176
130229
  clearAllDFAStates();
130177
- return parseDocumentBatchLL(text, lexer, tokenStream, lexMs);
130230
+ return withUtf16Columns(text, parseDocumentBatchLL(text, lexer, tokenStream, lexMs));
130178
130231
  }
130179
130232
  if (isDfaPreSeeded()) {
130180
130233
  markDfaNotPreSeeded();
130181
130234
  }
130182
- return {
130235
+ return withUtf16Columns(text, {
130183
130236
  tree,
130184
130237
  tokenStream,
130185
130238
  parser,
130186
130239
  lexer,
130187
130240
  errors,
130188
130241
  timing: { lexMs, parseMs }
130189
- };
130242
+ });
130190
130243
  }
130191
130244
  function parseDocumentBatchLL(_text, lexer, tokenStream, lexMs) {
130192
130245
  tokenStream.seek(0);
@@ -130212,41 +130265,162 @@ ${JSON.stringify(message, null, 4)}`);
130212
130265
  };
130213
130266
  }
130214
130267
 
130215
- // server/src/parser/positionUtils.ts
130216
- function tokenToPosition(token) {
130217
- return {
130218
- line: (token.line ?? 1) - 1,
130219
- character: token.column ?? 0
130220
- };
130268
+ // server/src/utils/sysmlKeywords.ts
130269
+ var SYSML_KEYWORDS_ARRAY = SysMLv2Lexer.literalNames.filter((n2) => n2 != null).map((n2) => n2.replace(/^'|'$/g, "")).filter((n2) => /^[a-z]+$/.test(n2)).sort();
130270
+ var SYSML_KEYWORDS = new Set(SYSML_KEYWORDS_ARRAY);
130271
+
130272
+ // server/src/utils/identUtils.ts
130273
+ function isIdentStart(c) {
130274
+ return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95;
130221
130275
  }
130222
- function tokenToRange(token) {
130223
- const start = tokenToPosition(token);
130224
- const length = token.text?.length ?? 1;
130225
- return {
130226
- start,
130227
- end: { line: start.line, character: start.character + length }
130228
- };
130276
+ function isIdentPart(c) {
130277
+ return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 48 && c <= 57 || c === 95;
130229
130278
  }
130230
- function contextToRange(ctx) {
130231
- const startToken = ctx.start;
130232
- const stopToken = ctx.stop ?? ctx.start;
130233
- if (!startToken) {
130234
- return { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } };
130279
+ var ESCAPES = {
130280
+ b: "\b",
130281
+ t: " ",
130282
+ n: "\n",
130283
+ f: "\f",
130284
+ r: "\r",
130285
+ "'": "'",
130286
+ '"': '"',
130287
+ "\\": "\\"
130288
+ };
130289
+ function unquoteName(text) {
130290
+ if (!text.startsWith("'") || !text.endsWith("'")) return text;
130291
+ return text.slice(1, -1).replace(/\\([btnfr'"\\])/g, (_, ch) => ESCAPES[ch]);
130292
+ }
130293
+ function quoteName(name) {
130294
+ if (/^[A-Za-z_][A-Za-z_0-9]*$/.test(name) && !SYSML_KEYWORDS.has(name)) return name;
130295
+ const escaped = name.replace(/[\\'\b\t\n\f\r]/g, (ch) => {
130296
+ const entry = Object.entries(ESCAPES).find(([, value]) => value === ch);
130297
+ return `\\${entry[0]}`;
130298
+ });
130299
+ return `'${escaped}'`;
130300
+ }
130301
+ function splitQualifiedName(text) {
130302
+ const parts = [];
130303
+ let start = 0;
130304
+ let quoted = false;
130305
+ for (let i = 0; i < text.length; i++) {
130306
+ if (quoted && text[i] === "\\") {
130307
+ i++;
130308
+ continue;
130309
+ }
130310
+ if (text[i] === "'" && (quoted || i === start)) quoted = !quoted;
130311
+ if (!quoted && text.startsWith("::", i)) {
130312
+ parts.push(unquoteName(text.slice(start, i).trim()));
130313
+ start = i + 2;
130314
+ i++;
130315
+ }
130235
130316
  }
130236
- const start = {
130237
- line: (startToken.line ?? 1) - 1,
130238
- character: startToken.column ?? 0
130239
- };
130240
- const end = stopToken ? {
130241
- line: (stopToken.line ?? 1) - 1,
130242
- character: (stopToken.column ?? 0) + (stopToken.text?.length ?? 1)
130243
- } : { line: start.line, character: start.character + 1 };
130244
- return { start, end };
130317
+ parts.push(unquoteName(text.slice(start).trim()));
130318
+ return parts;
130319
+ }
130320
+ function joinQualifiedName(parts) {
130321
+ return parts.map((part) => /::|['\\\r\n\t\b\f]/.test(part) ? quoteName(part) : part).join("::");
130322
+ }
130323
+ function readNameAt(text, start, allowIncomplete = false) {
130324
+ if (text[start] === "'") {
130325
+ let end2 = start + 1;
130326
+ while (end2 < text.length && text[end2] !== "'") {
130327
+ if (text[end2] === "\r" || text[end2] === "\n") return void 0;
130328
+ if (text[end2] === "\\") {
130329
+ if (!Object.hasOwn(ESCAPES, text[end2 + 1])) return void 0;
130330
+ end2++;
130331
+ }
130332
+ end2++;
130333
+ }
130334
+ if (end2 >= text.length) {
130335
+ return allowIncomplete ? { name: unquoteName(`${text.slice(start)}'`), start, end: text.length } : void 0;
130336
+ }
130337
+ if (end2 === start + 1 && !allowIncomplete) return void 0;
130338
+ return { name: unquoteName(text.slice(start, end2 + 1)), start, end: end2 + 1 };
130339
+ }
130340
+ if (!isIdentStart(text.charCodeAt(start))) return void 0;
130341
+ let end = start + 1;
130342
+ while (end < text.length && isIdentPart(text.charCodeAt(end))) end++;
130343
+ return { name: text.slice(start, end), start, end };
130344
+ }
130345
+ function readQualifiedNameAt(text, start, allowIncomplete = false) {
130346
+ const first = readNameAt(text, start, allowIncomplete);
130347
+ if (!first) return void 0;
130348
+ const segments = [first];
130349
+ let end = first.end;
130350
+ while (end < text.length) {
130351
+ let next = end;
130352
+ while (/\s/.test(text[next] ?? "") && next < text.length) next++;
130353
+ if (!text.startsWith("::", next)) break;
130354
+ next += 2;
130355
+ while (/\s/.test(text[next] ?? "") && next < text.length) next++;
130356
+ const segment = readNameAt(text, next, allowIncomplete);
130357
+ if (!segment) break;
130358
+ segments.push(segment);
130359
+ end = segment.end;
130360
+ }
130361
+ return { name: joinQualifiedName(segments.map((s) => s.name)), start, end, segments };
130362
+ }
130363
+ function* scanQualifiedNames(text, allowIncomplete = false) {
130364
+ let i = 0;
130365
+ while (i < text.length) {
130366
+ if (text.startsWith("//", i)) {
130367
+ const end = text.indexOf("\n", i + 2);
130368
+ i = end < 0 ? text.length : end + 1;
130369
+ } else if (text.startsWith("/*", i)) {
130370
+ const end = text.indexOf("*/", i + 2);
130371
+ i = end < 0 ? text.length : end + 2;
130372
+ } else if (text[i] === '"') {
130373
+ i++;
130374
+ while (i < text.length && text[i] !== '"') i += text[i] === "\\" ? 2 : 1;
130375
+ i++;
130376
+ } else if (/\d/.test(text[i]) || text[i] === "." && /\d/.test(text[i + 1] ?? "")) {
130377
+ const number = text.slice(i).match(/^(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/);
130378
+ i += number[0].length;
130379
+ } else {
130380
+ const name = readQualifiedNameAt(text, i, allowIncomplete);
130381
+ if (name) {
130382
+ yield name;
130383
+ i = name.end;
130384
+ } else if (text[i] === "'") {
130385
+ i++;
130386
+ while (i < text.length && text[i] !== "'" && text[i] !== "\n") {
130387
+ i += text[i] === "\\" ? 2 : 1;
130388
+ }
130389
+ if (text[i] === "'") i++;
130390
+ } else {
130391
+ i++;
130392
+ }
130393
+ }
130394
+ }
130395
+ }
130396
+ function* scanFeaturePaths(text) {
130397
+ const names = [...scanQualifiedNames(text)];
130398
+ for (let i = 0; i < names.length; i++) {
130399
+ const first = names[i];
130400
+ const parts = [first.name];
130401
+ const qualifiedNames = [first];
130402
+ let end = first.end;
130403
+ while (i + 1 < names.length && /^\s*\.\s*$/.test(text.slice(end, names[i + 1].start))) {
130404
+ parts.push(names[++i].name);
130405
+ qualifiedNames.push(names[i]);
130406
+ end = names[i].end;
130407
+ }
130408
+ yield { name: parts.join("."), start: first.start, end, qualifiedNames, parts: parts.map((part) => {
130409
+ const segments = splitQualifiedName(part);
130410
+ return segments.length === 1 ? segments[0] : part;
130411
+ }) };
130412
+ }
130413
+ }
130414
+ function extractQualifiedNameAt(text, character) {
130415
+ for (const name of scanQualifiedNames(text)) {
130416
+ if (character >= name.start && character <= name.end) return name.name;
130417
+ if (name.start > character) break;
130418
+ }
130419
+ return void 0;
130420
+ }
130421
+ function stripComments(text) {
130422
+ return text.replace(/\/\*[\s\S]*?\*\//g, (m2) => m2.replace(/[^\n]/g, " ")).replace(/\/\/[^\n]*/g, (m2) => " ".repeat(m2.length));
130245
130423
  }
130246
-
130247
- // server/src/utils/sysmlKeywords.ts
130248
- var SYSML_KEYWORDS_ARRAY = SysMLv2Lexer.literalNames.filter((n2) => n2 != null).map((n2) => n2.replace(/^'|'$/g, "")).filter((n2) => /^[a-z]+$/.test(n2)).sort();
130249
- var SYSML_KEYWORDS = new Set(SYSML_KEYWORDS_ARRAY);
130250
130424
 
130251
130425
  // server/src/utils/documentUri.ts
130252
130426
  function canonicalUri(uri) {
@@ -131081,7 +131255,7 @@ ${JSON.stringify(message, null, 4)}`);
131081
131255
  var RE_DEFINED_BY = /definedby\s*([A-Za-z_]\w*(?:::\w+)*(?:\s*,\s*[A-Za-z_]\w*(?:::\w+)*)*)/;
131082
131256
  var MAX_RULE_SEARCH_DEPTH = 6;
131083
131257
  var RE_TYPING = /:(?![:>])\s*('[^']+'|[A-Za-z_]\w*(?:::\w+)*)/;
131084
- var RE_QUOTED_NAME = /'([^']+)'/;
131258
+ var RE_QUOTED_NAME = /^\s*(?:\$::)?(?:(?:[A-Za-z_]\w*|'\d+')::)*'(\d+)'/;
131085
131259
  var RE_IDENT_START = /^([A-Za-z_]\w*(?:::\w+)*)/;
131086
131260
  var SymbolTable = class {
131087
131261
  /** All symbols indexed by qualified name */
@@ -131148,7 +131322,12 @@ ${JSON.stringify(message, null, 4)}`);
131148
131322
  * Find a symbol by name (simple name, not qualified).
131149
131323
  */
131150
131324
  findByName(name) {
131151
- return this.symbolsByName.get(name) ?? [];
131325
+ const exact = this.symbolsByName.get(name);
131326
+ if (exact) return exact;
131327
+ const segments = splitQualifiedName(name);
131328
+ if (segments.length === 1) return this.symbolsByName.get(segments[0]) ?? [];
131329
+ const qualified = this.getSymbol(joinQualifiedName(segments));
131330
+ return qualified ? [qualified] : [];
131152
131331
  }
131153
131332
  /**
131154
131333
  * Find all symbols in a given URI.
@@ -131655,7 +131834,7 @@ ${JSON.stringify(message, null, 4)}`);
131655
131834
  const anonymous = !declaredName;
131656
131835
  const name = declaredName ?? "";
131657
131836
  const shortName = transition || isFlowUsage(kind) && !declaredName ? void 0 : this.extractShortName(ctx);
131658
- const qualifiedName = anonymous || owner && owner.qualifiedName === void 0 ? void 0 : owner ? `${owner.qualifiedName}::${name}` : name;
131837
+ const qualifiedName = anonymous || owner && owner.qualifiedName === void 0 ? void 0 : owner ? `${owner.qualifiedName}::${joinQualifiedName([name])}` : joinQualifiedName([name]);
131659
131838
  const selectionRange = anonymous ? ctx.start ? tokenToRange(ctx.start) : range : this.extractNameRange(ctx) ?? range;
131660
131839
  const typeNames = isFlowUsage(kind) ? this.extractFlowTypeNames(ctx) : transition ? this.extractTransitionTypeNames(ctx) : this.extractTypeNames(ctx);
131661
131840
  const specializationNames = this.extractSpecializationNames(ctx);
@@ -131815,7 +131994,10 @@ ${JSON.stringify(message, null, 4)}`);
131815
131994
  }
131816
131995
  /** Remove SysML quoting while retaining qualified and dotted references. */
131817
131996
  cleanTransitionText(text) {
131818
- const cleaned = text.replace(/'([^']+)'/g, "$1").trim();
131997
+ const cleaned = text.replace(
131998
+ /'(?:\\.|[^'\\])*'/g,
131999
+ (name) => joinQualifiedName([unquoteName(name)])
132000
+ ).trim();
131819
132001
  return cleaned || void 0;
131820
132002
  }
131821
132003
  /** Extract explicit first/then successions owned by an action body. */
@@ -131988,8 +132170,8 @@ ${JSON.stringify(message, null, 4)}`);
131988
132170
  }
131989
132171
  /** The name of the feature a reference such as `a.b` or `P::a` ends at (`b`, `a`). */
131990
132172
  lastNameSegment(reference) {
131991
- const segment = reference.getText().split(/::|\./).pop();
131992
- return segment ? this.unquoteName(segment) : void 0;
132173
+ const names = [...scanQualifiedNames(reference.getText())];
132174
+ return names.at(-1)?.segments.at(-1)?.name;
131993
132175
  }
131994
132176
  declarationTokens(ctx) {
131995
132177
  const tokens = [];
@@ -132125,6 +132307,16 @@ ${JSON.stringify(message, null, 4)}`);
132125
132307
  * Extract the range of just the name token.
132126
132308
  */
132127
132309
  extractNameRange(ctx) {
132310
+ if (ctx.ruleIndex === SysMLv2Parser.RULE_identification || ctx.ruleIndex === SysMLv2Parser.RULE_featureIdentification) {
132311
+ let name;
132312
+ for (let i = 0; i < ctx.getChildCount(); i++) {
132313
+ const child = ctx.getChild(i);
132314
+ if (child instanceof ParserRuleContext && child.ruleIndex === SysMLv2Parser.RULE_name) {
132315
+ name = child;
132316
+ }
132317
+ }
132318
+ if (name) return contextToRange(name);
132319
+ }
132128
132320
  for (let i = 0; i < ctx.getChildCount(); i++) {
132129
132321
  const child = ctx.getChild(i);
132130
132322
  if (child instanceof TerminalNode && this.isNameTerminal(child)) {
@@ -132165,7 +132357,7 @@ ${JSON.stringify(message, null, 4)}`);
132165
132357
  for (const part of specStr.split(",")) {
132166
132358
  const quoted = quotedName(part);
132167
132359
  if (quoted !== void 0) {
132168
- names.push(quoted);
132360
+ names.push(joinQualifiedName([quoted]));
132169
132361
  continue;
132170
132362
  }
132171
132363
  const m2 = part.trim().match(RE_IDENT_START);
@@ -132188,7 +132380,7 @@ ${JSON.stringify(message, null, 4)}`);
132188
132380
  for (const part of afterColon.split(",")) {
132189
132381
  const quoted = quotedName(part);
132190
132382
  if (quoted !== void 0) {
132191
- names.push(quoted);
132383
+ names.push(joinQualifiedName([quoted]));
132192
132384
  continue;
132193
132385
  }
132194
132386
  const m2 = part.trim().match(RE_IDENT_START);
@@ -132199,18 +132391,20 @@ ${JSON.stringify(message, null, 4)}`);
132199
132391
  return names;
132200
132392
  }
132201
132393
  /**
132202
- * The declaration tokens before the body, with each lexer STRING token
132394
+ * The declaration tokens before the value or body, with each lexer STRING token
132203
132395
  * replaced by a numbered placeholder (`'0'`, `'1'`, ...), and
132204
132396
  * `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.
132397
+ * the name, when it ends the qualified name the part starts with. SysML
132398
+ * 2.0 section 7.2.2 permits punctuation in unrestricted names (the STRING
132399
+ * lexer production), so fallback regexes must never see their `:`, `:>`,
132400
+ * `{` or keywords. Documentation is not a name token.
132208
132401
  */
132209
132402
  maskedDeclaration(ctx) {
132210
132403
  const quoted = [];
132211
- const masked = this.declarationTokens(ctx).map((token) => {
132404
+ const valueStart = this.findOwnHeaderRule(ctx, SysMLv2Parser.RULE_valuePart)?.start?.tokenIndex;
132405
+ const masked = this.declarationTokens(ctx).filter((token) => valueStart === void 0 || token.tokenIndex < valueStart).map((token) => {
132212
132406
  const text = token.text ?? "";
132213
- return token.type === SysMLv2Lexer.STRING ? `'${quoted.push(text.slice(1, -1)) - 1}'` : text;
132407
+ return token.type === SysMLv2Lexer.STRING ? `'${quoted.push(unquoteName(text)) - 1}'` : text;
132214
132408
  }).join("");
132215
132409
  return {
132216
132410
  text: masked,
@@ -132238,7 +132432,7 @@ ${JSON.stringify(message, null, 4)}`);
132238
132432
  for (const part of specStr.split(",")) {
132239
132433
  const quoted = quotedName(part);
132240
132434
  if (quoted !== void 0) {
132241
- names.push(quoted);
132435
+ names.push(joinQualifiedName([quoted]));
132242
132436
  continue;
132243
132437
  }
132244
132438
  const m2 = part.trim().match(RE_IDENT_START);
@@ -132267,17 +132461,7 @@ ${JSON.stringify(message, null, 4)}`);
132267
132461
  if (!(child instanceof ParserRuleContext)) continue;
132268
132462
  const ri = child.ruleIndex;
132269
132463
  if (extractionRules.has(ri)) {
132270
- const childText = child.getText();
132271
- const stripped = childText.replace(/^(specializes|:>>|:>|:|definedby|subsets|redefines|references|conjugates|disjoints)/i, "");
132272
- for (const part of stripped.split(",")) {
132273
- const qm = part.match(/'([^']+)'/);
132274
- if (qm) {
132275
- names.push(qm[1]);
132276
- } else {
132277
- const m2 = part.match(/([A-Za-z_]\w*(?:::\w+)*)/);
132278
- if (m2) names.push(m2[1]);
132279
- }
132280
- }
132464
+ this.collectQualifiedTypeNames(child, names);
132281
132465
  } else if (
132282
132466
  // Recurse into declaration / part / body wrappers that may
132283
132467
  // contain nested typing rules (but NOT into body rules that
@@ -132290,6 +132474,17 @@ ${JSON.stringify(message, null, 4)}`);
132290
132474
  }
132291
132475
  }
132292
132476
  }
132477
+ collectQualifiedTypeNames(ctx, names) {
132478
+ if (ctx.ruleIndex === SysMLv2Parser.RULE_qualifiedName) {
132479
+ const name = this.extractTextFromSubtree(ctx);
132480
+ if (name) names.push(name);
132481
+ return;
132482
+ }
132483
+ for (let i = 0; i < ctx.getChildCount(); i++) {
132484
+ const child = ctx.getChild(i);
132485
+ if (child instanceof ParserRuleContext) this.collectQualifiedTypeNames(child, names);
132486
+ }
132487
+ }
132293
132488
  /**
132294
132489
  * Extract documentation owned by this element.
132295
132490
  *
@@ -132450,10 +132645,7 @@ ${JSON.stringify(message, null, 4)}`);
132450
132645
  * Returns the text unchanged if not quoted.
132451
132646
  */
132452
132647
  unquoteName(text) {
132453
- if (this.isQuotedName(text)) {
132454
- return text.slice(1, -1);
132455
- }
132456
- return text;
132648
+ return unquoteName(text);
132457
132649
  }
132458
132650
  /**
132459
132651
  * Check if a text is a SysML keyword.
@@ -132741,7 +132933,7 @@ ${JSON.stringify(message, null, 4)}`);
132741
132933
  const child = ctx.getChild(i);
132742
132934
  if (child instanceof TerminalNode) {
132743
132935
  const text = child.symbol.text;
132744
- if (text) parts.push(text);
132936
+ if (text) parts.push(child.symbol.type === SysMLv2Lexer.STRING ? joinQualifiedName([unquoteName(text)]) : text);
132745
132937
  } else if (child instanceof ParserRuleContext) {
132746
132938
  this.collectExposeText(child, parts);
132747
132939
  }
@@ -132803,58 +132995,24 @@ ${JSON.stringify(message, null, 4)}`);
132803
132995
  * Extract all text content from a subtree (concatenate terminal nodes).
132804
132996
  */
132805
132997
  extractTextFromSubtree(ctx) {
132998
+ if (ctx.ruleIndex === SysMLv2Parser.RULE_name) return unquoteName(ctx.getText());
132806
132999
  const parts = [];
132807
133000
  for (let i = 0; i < ctx.getChildCount(); i++) {
132808
133001
  const child = ctx.getChild(i);
132809
133002
  if (child instanceof TerminalNode) {
132810
133003
  const text = child.symbol.text;
132811
133004
  if (text && this.isNameTerminal(child)) {
132812
- parts.push(this.unquoteName(text));
133005
+ parts.push(joinQualifiedName([this.unquoteName(text)]));
132813
133006
  }
132814
133007
  } else if (child instanceof ParserRuleContext) {
132815
133008
  const sub = this.extractTextFromSubtree(child);
132816
- if (sub) parts.push(sub);
133009
+ if (sub) parts.push(child.ruleIndex === SysMLv2Parser.RULE_name ? joinQualifiedName([sub]) : sub);
132817
133010
  }
132818
133011
  }
132819
133012
  return parts.length > 0 ? parts.join("::") : void 0;
132820
133013
  }
132821
133014
  };
132822
133015
 
132823
- // server/src/utils/identUtils.ts
132824
- function isIdentStart(c) {
132825
- return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95;
132826
- }
132827
- function isIdentPart(c) {
132828
- return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 48 && c <= 57 || c === 95;
132829
- }
132830
- function extractQualifiedNameAt(lineText, character) {
132831
- const len = lineText.length;
132832
- let i = 0;
132833
- while (i < len) {
132834
- if (!isIdentStart(lineText.charCodeAt(i))) {
132835
- i++;
132836
- continue;
132837
- }
132838
- const wordStart = i;
132839
- while (i < len) {
132840
- while (i < len && isIdentPart(lineText.charCodeAt(i))) i++;
132841
- if (i + 2 <= len && lineText[i] === ":" && lineText[i + 1] === ":" && i + 2 < len && isIdentStart(lineText.charCodeAt(i + 2))) {
132842
- i += 2;
132843
- } else {
132844
- break;
132845
- }
132846
- }
132847
- const wordEnd = i;
132848
- if (character >= wordStart && character <= wordEnd) {
132849
- return lineText.substring(wordStart, wordEnd);
132850
- }
132851
- }
132852
- return void 0;
132853
- }
132854
- function stripComments(text) {
132855
- return text.replace(/\/\*[\s\S]*?\*\//g, (m2) => m2.replace(/[^\n]/g, " ")).replace(/\/\/[^\n]*/g, (m2) => " ".repeat(m2.length));
132856
- }
132857
-
132858
133016
  // server/src/documentManager.ts
132859
133017
  var DocumentManager = class {
132860
133018
  cache = /* @__PURE__ */ new Map();
@@ -132870,6 +133028,13 @@ ${JSON.stringify(message, null, 4)}`);
132870
133028
  * indexed yet" apart from "genuinely doesn't exist".
132871
133029
  */
132872
133030
  workspaceScanComplete = true;
133031
+ /**
133032
+ * Last version given to a stand-in text by `withTexts`. Caches keyed by
133033
+ * version assume one text per uri and version, so each stand-in gets a
133034
+ * version outside the LSP integer range (LSP 3.17, base types).
133035
+ * These internal positive versions are never sent to the client.
133036
+ */
133037
+ temporaryVersion = 2 ** 31 - 1;
132873
133038
  /**
132874
133039
  * Parse a document and cache the result.
132875
133040
  * Returns the cached result if the content hasn't changed.
@@ -133073,6 +133238,35 @@ ${JSON.stringify(message, null, 4)}`);
133073
133238
  this.wsSymbolTable.removeUri(uri);
133074
133239
  this.wsBuiltVersions.delete(uri);
133075
133240
  }
133241
+ /**
133242
+ * Runs `fn` with each text standing in for the document at its uri (or
133243
+ * added as a new document), all at once, then restores the previous
133244
+ * state. `fn` must be synchronous: no other request can run in between,
133245
+ * so no other request ever sees the temporary texts. Every text is
133246
+ * parsed before anything changes. The stand-ins get versions no real
133247
+ * document has, so caches keyed by version never confuse them with the
133248
+ * real documents.
133249
+ */
133250
+ withTexts(documents2, fn) {
133251
+ if (!Number.isSafeInteger(this.temporaryVersion + documents2.length)) {
133252
+ throw new RangeError("Temporary document version space exhausted.");
133253
+ }
133254
+ const parsed = documents2.map(({ uri, text }) => ({ uri, text, result: parseDocument(text) }));
133255
+ const previous = new Map(parsed.map(({ uri }) => [uri, this.cache.get(uri)]));
133256
+ for (const { uri, text, result } of parsed) {
133257
+ this.cache.set(uri, { version: ++this.temporaryVersion, text, result, needsParse: false });
133258
+ }
133259
+ try {
133260
+ return fn();
133261
+ } finally {
133262
+ for (const [uri, entry] of previous) {
133263
+ if (entry) this.cache.set(uri, entry);
133264
+ else this.cache.delete(uri);
133265
+ this.wsSymbolTable.removeUri(uri);
133266
+ this.wsBuiltVersions.delete(uri);
133267
+ }
133268
+ }
133269
+ }
133076
133270
  /**
133077
133271
  * Get all cached URIs.
133078
133272
  */
@@ -135508,55 +135702,30 @@ ${JSON.stringify(message, null, 4)}`);
135508
135702
  while (pos < line.length && isIdentPart(line.charCodeAt(pos))) pos++;
135509
135703
  return pos > start ? [line.slice(start, pos), pos] : void 0;
135510
135704
  }
135705
+ function readSimpleName(line, pos) {
135706
+ const name = readNameAt(line, skipSpaces(line, pos));
135707
+ return name ? [name.name, name.end] : void 0;
135708
+ }
135511
135709
  function readName(line, pos) {
135512
135710
  pos = skipSpaces(line, pos);
135513
- if (pos < line.length && line[pos] === "'") {
135514
- pos++;
135515
- const start = pos;
135516
- while (pos < line.length && isIdentPart(line.charCodeAt(pos))) pos++;
135517
- const name = line.slice(start, pos);
135518
- if (pos < line.length && line[pos] === "'") pos++;
135519
- return name ? [name, pos] : void 0;
135520
- }
135521
135711
  if (pos < line.length && line[pos] === "<") {
135522
- pos++;
135523
- const start = pos;
135524
- while (pos < line.length && line[pos] !== ">") pos++;
135525
- const shortName = line.slice(start, pos).trim();
135526
- if (pos < line.length && line[pos] === ">") pos++;
135527
- pos = skipSpaces(line, pos);
135528
- if (pos < line.length && line[pos] === "'") {
135529
- pos++;
135530
- while (pos < line.length && line[pos] !== "'") pos++;
135531
- if (pos < line.length) pos++;
135532
- } else if (pos < line.length && isIdentPart(line.charCodeAt(pos))) {
135533
- while (pos < line.length && isIdentPart(line.charCodeAt(pos))) pos++;
135534
- }
135535
- return shortName ? [shortName, pos] : void 0;
135536
- }
135537
- return readWord(line, pos);
135712
+ const short = readSimpleName(line, pos + 1);
135713
+ if (!short) return void 0;
135714
+ pos = skipSpaces(line, short[1]);
135715
+ if (line[pos] !== ">") return void 0;
135716
+ const long = readSimpleName(line, pos + 1);
135717
+ return [short[0], long?.[1] ?? pos + 1];
135718
+ }
135719
+ return readSimpleName(line, pos);
135538
135720
  }
135539
135721
  function readLongName(line, pos) {
135540
135722
  pos = skipSpaces(line, pos);
135541
135723
  if (pos >= line.length || line[pos] !== "<") return void 0;
135542
- while (pos < line.length && line[pos] !== ">") pos++;
135543
- if (pos < line.length) pos++;
135544
- pos = skipSpaces(line, pos);
135545
- if (pos >= line.length) return void 0;
135546
- if (line[pos] === "'") {
135547
- pos++;
135548
- const start = pos;
135549
- while (pos < line.length && line[pos] !== "'") pos++;
135550
- const longName = line.slice(start, pos).trim();
135551
- if (longName && /^[A-Za-z_]\w*$/.test(longName)) return longName;
135552
- return void 0;
135553
- }
135554
- if (isIdentPart(line.charCodeAt(pos))) {
135555
- const start = pos;
135556
- while (pos < line.length && isIdentPart(line.charCodeAt(pos))) pos++;
135557
- return line.slice(start, pos);
135558
- }
135559
- return void 0;
135724
+ const short = readSimpleName(line, pos + 1);
135725
+ if (!short) return void 0;
135726
+ pos = skipSpaces(line, short[1]);
135727
+ if (line[pos] !== ">") return void 0;
135728
+ return readSimpleName(line, pos + 1)?.[0];
135560
135729
  }
135561
135730
  function matchWord(line, pos, keyword) {
135562
135731
  if (!line.startsWith(keyword, pos)) return false;
@@ -135628,7 +135797,7 @@ ${JSON.stringify(message, null, 4)}`);
135628
135797
  if (close < 0) continue;
135629
135798
  pos = skipSpaces(line, close + 1);
135630
135799
  }
135631
- const w = readWord(line, pos);
135800
+ const w = readName(line, pos);
135632
135801
  if (w) return w[0];
135633
135802
  }
135634
135803
  return void 0;
@@ -135753,7 +135922,7 @@ ${JSON.stringify(message, null, 4)}`);
135753
135922
  types.set(usageName, { uri: fileUri, line: i });
135754
135923
  }
135755
135924
  if (pkgName) {
135756
- const qualName = `${pkgName}::${usageName}`;
135925
+ const qualName = joinQualifiedName([pkgName, usageName]);
135757
135926
  if (!types.has(qualName)) {
135758
135927
  types.set(qualName, { uri: fileUri, line: i });
135759
135928
  }
@@ -135764,7 +135933,7 @@ ${JSON.stringify(message, null, 4)}`);
135764
135933
  types.set(longName, { uri: fileUri, line: i });
135765
135934
  }
135766
135935
  if (pkgName) {
135767
- const qualLong = `${pkgName}::${longName}`;
135936
+ const qualLong = joinQualifiedName([pkgName, longName]);
135768
135937
  if (!types.has(qualLong)) {
135769
135938
  types.set(qualLong, { uri: fileUri, line: i });
135770
135939
  }
@@ -135796,15 +135965,17 @@ ${JSON.stringify(message, null, 4)}`);
135796
135965
  }
135797
135966
  function resolveLibraryPackage(name) {
135798
135967
  if (!index) return void 0;
135799
- const pkg = name.split("::")[0];
135968
+ const pkg = splitQualifiedName(name)[0];
135800
135969
  return index.get(pkg);
135801
135970
  }
135802
135971
  function resolveLibraryType(name) {
135803
135972
  if (!typeIndex) return void 0;
135973
+ const segments = splitQualifiedName(name);
135974
+ name = segments.length === 1 ? segments[0] : joinQualifiedName(segments);
135804
135975
  const exact = typeIndex.get(name);
135805
135976
  if (exact) return exact;
135806
- if (name.includes("::")) {
135807
- const member = name.split("::").pop();
135977
+ if (segments.length > 1) {
135978
+ const member = segments[segments.length - 1];
135808
135979
  return typeIndex.get(member);
135809
135980
  }
135810
135981
  return void 0;
@@ -136452,6 +136623,10 @@ ${JSON.stringify(message, null, 4)}`);
136452
136623
  resolveNameFrom(symbol, name, indexes) {
136453
136624
  return this.resolveQualifiedNameFrom(ownerKeyOf(symbol, indexes.byId), name, indexes);
136454
136625
  }
136626
+ /** Resolve an editor reference within its enclosing namespace, including the root. */
136627
+ resolveNameIn(namespace, name, indexes) {
136628
+ return this.resolveQualifiedNameFrom(namespace ? namespaceKeyOf(namespace) : "", name, indexes);
136629
+ }
136455
136630
  /**
136456
136631
  * Resolve a (possibly qualified) name to its symbol per §7.5.1, searching
136457
136632
  * outward from namespace `start` and its enclosing namespaces (its own resolved
@@ -136463,7 +136638,7 @@ ${JSON.stringify(message, null, 4)}`);
136463
136638
  * its own enclosing package already imported, per §7.5.1/§7.5.3).
136464
136639
  */
136465
136640
  resolveQualifiedNameFrom(start, name, indexes) {
136466
- const [first, ...rest] = name.split("::");
136641
+ const [first, ...rest] = splitQualifiedName(name);
136467
136642
  let resolved;
136468
136643
  for (const ancestor of this.namespaceAncestorsOf(start, indexes)) {
136469
136644
  const candidates = this.getResolvedMembers(ancestor, indexes).get(first);
@@ -136630,6 +136805,9 @@ ${JSON.stringify(message, null, 4)}`);
136630
136805
  };
136631
136806
  for (const owned of indexes.byParent.get(namespace) ?? []) {
136632
136807
  addMember(owned.name, { symbol: owned, visibility: owned.visibility ?? "public" });
136808
+ if (owned.shortName) {
136809
+ addMember(owned.shortName, { symbol: owned, visibility: owned.visibility ?? "public" });
136810
+ }
136633
136811
  }
136634
136812
  perIndexesCache.set(namespace, members);
136635
136813
  const owner = typeof namespace === "string" ? indexes.byQualifiedName.get(namespace) : namespace;
@@ -136665,13 +136843,17 @@ ${JSON.stringify(message, null, 4)}`);
136665
136843
  switch (imp.kind) {
136666
136844
  case "membership": {
136667
136845
  const target = this.resolveQualifiedNameFrom(importingNamespace, imp.target, indexes);
136668
- if (target) addMember(target.name, { symbol: target, visibility: imp.visibility });
136846
+ if (target) {
136847
+ addMember(target.name, { symbol: target, visibility: imp.visibility });
136848
+ if (target.shortName) addMember(target.shortName, { symbol: target, visibility: imp.visibility });
136849
+ }
136669
136850
  break;
136670
136851
  }
136671
136852
  case "membership-deep": {
136672
136853
  const target = this.resolveQualifiedNameFrom(importingNamespace, imp.target, indexes);
136673
136854
  if (target) {
136674
136855
  addMember(target.name, { symbol: target, visibility: imp.visibility });
136856
+ if (target.shortName) addMember(target.shortName, { symbol: target, visibility: imp.visibility });
136675
136857
  this.importVisibleMembers(namespaceKeyOf(target), imp.visibility, indexes, addMember, true);
136676
136858
  }
136677
136859
  break;
@@ -136836,7 +137018,7 @@ ${JSON.stringify(message, null, 4)}`);
136836
137018
  function resolveTypeName(typeName, symbol, resolver, indexes, libraryNames) {
136837
137019
  const kwMatch = typeName.match(/^([A-Z][A-Za-z_0-9]*?)(redefines|subsets|references|connect|bind|default|via|accept|send|flow|allocate|assign|decide|merge|join|fork)([A-Z])/);
136838
137020
  const strippedTypeName = kwMatch ? kwMatch[1] : typeName;
136839
- const rootSegment = strippedTypeName.split("::")[0];
137021
+ const rootSegment = splitQualifiedName(strippedTypeName)[0];
136840
137022
  const resolved = resolver.isLocallyVisible(symbol, strippedTypeName, indexes) || STANDARD_LIBRARY_TYPES.has(strippedTypeName) || STANDARD_LIBRARY_TYPES.has(rootSegment) || libraryNames.has(rootSegment) || isISQValueType(strippedTypeName) || resolveLibraryType(strippedTypeName) !== void 0 || resolveLibraryType(rootSegment) !== void 0 || // Names starting with lowercase are feature references (subsettings
136841
137023
  // via :>), not type references — don't flag them as unresolved types.
136842
137024
  strippedTypeName.charCodeAt(0) >= 97 && strippedTypeName.charCodeAt(0) <= 122;
@@ -138384,11 +138566,11 @@ ${this.followingBranchStatements(symbol, lines)}`;
138384
138566
  const packageNames = /* @__PURE__ */ new Set();
138385
138567
  for (const s of allSymbols) {
138386
138568
  if (!isDefinition(s.kind)) continue;
138387
- if (s.name !== unresolvedType) continue;
138569
+ if (s.name !== unquoteName(unresolvedType)) continue;
138388
138570
  if (s.uri === uri) continue;
138389
- const pkg = (s.qualifiedName?.split("::")[0] ?? "").trim();
138571
+ const pkg = s.qualifiedName ? splitQualifiedName(s.qualifiedName)[0] : "";
138390
138572
  if (!pkg || pkg === unresolvedType) continue;
138391
- if (pkg) packageNames.add(pkg);
138573
+ packageNames.add(quoteName(pkg));
138392
138574
  }
138393
138575
  for (const pkg of packageNames) {
138394
138576
  if (this.hasImportForPackage(text, pkg)) {
@@ -138497,7 +138679,7 @@ ${this.followingBranchStatements(symbol, lines)}`;
138497
138679
  const edit = {
138498
138680
  changes: {
138499
138681
  [uri]: [
138500
- import_node.TextEdit.replace(diagnostic.range, newName)
138682
+ import_node.TextEdit.replace(diagnostic.range, quoteName(newName))
138501
138683
  ]
138502
138684
  }
138503
138685
  };
@@ -138606,7 +138788,7 @@ ${childIndent}enum value2;`;
138606
138788
  const edit = {
138607
138789
  changes: {
138608
138790
  [uri]: [
138609
- import_node.TextEdit.replace(diagnostic.range, newName)
138791
+ import_node.TextEdit.replace(diagnostic.range, quoteName(newName))
138610
138792
  ]
138611
138793
  }
138612
138794
  };
@@ -138667,10 +138849,11 @@ ${childIndent}enum value2;`;
138667
138849
  if (diagnostic.code !== "incompatible-port-types") return void 0;
138668
138850
  const msg = diagnostic.message;
138669
138851
  const m2 = msg.match(/'([^']+)'\s+\(([^)]+)\)\s+is connected to\s+'([^']+)'\s+\(([^)]+)\)/);
138670
- if (!m2) return void 0;
138671
- const left = m2[1];
138672
- const leftType = m2[2];
138673
- const right = m2[3];
138852
+ const data = diagnostic.data;
138853
+ const left = data?.left ?? m2?.[1];
138854
+ const leftType = data?.leftType ?? m2?.[2];
138855
+ const right = data?.right ?? m2?.[3];
138856
+ if (!left || !leftType || !right) return void 0;
138674
138857
  const symbolTable = this.documentManager.getWorkspaceSymbolTable();
138675
138858
  const symbolsInUri = symbolTable.getSymbolsForUri(uri);
138676
138859
  const compatible = symbolsInUri.find(
@@ -138685,8 +138868,10 @@ ${childIndent}enum value2;`;
138685
138868
  if (start.line !== end.line) return void 0;
138686
138869
  const segment = (lines[start.line] ?? "").slice(start.character, end.character);
138687
138870
  if (!segment) return void 0;
138688
- const replaced = segment.replace(new RegExp(`\\b${right}\\b`), compatible.name);
138689
- if (replaced === segment) return void 0;
138871
+ const rightPath = [...scanFeaturePaths(segment)].reverse().find((path) => path.parts[path.parts.length - 1] === right);
138872
+ const rightName = rightPath?.qualifiedNames.at(-1)?.segments.at(-1);
138873
+ if (!rightName) return void 0;
138874
+ const replaced = segment.slice(0, rightName.start) + quoteName(compatible.name) + segment.slice(rightName.end);
138690
138875
  const edit = {
138691
138876
  changes: {
138692
138877
  [uri]: [
@@ -138721,12 +138906,14 @@ ${childIndent}enum value2;`;
138721
138906
  diagnostic.range.end.character
138722
138907
  ) : "";
138723
138908
  const m2 = msg.match(/Unresolved constraint reference\s+'([^']+)'(?:\s+in scope\s+'([^']+)')?/);
138909
+ const data = diagnostic.data;
138724
138910
  const expr = rangeExpr && rangeExpr.includes(".") ? rangeExpr : tokenExpr && tokenExpr.includes(".") ? tokenExpr : m2?.[1] ?? "";
138725
- const scopeName = m2?.[2];
138911
+ const scopeName = data?.scopeName ?? m2?.[2];
138726
138912
  if (!expr) return void 0;
138727
138913
  if (!expr.includes(".")) return void 0;
138728
- const parts = expr.split(".");
138729
- if (parts.length < 2) return void 0;
138914
+ const path = [...scanFeaturePaths(expr)].find((path2) => path2.qualifiedNames.length > 1);
138915
+ if (!path) return void 0;
138916
+ const parts = path.parts;
138730
138917
  const root = parts[0];
138731
138918
  const unresolvedLeaf = parts[parts.length - 1];
138732
138919
  const symbolTable = this.documentManager.getWorkspaceSymbolTable();
@@ -138738,7 +138925,7 @@ ${childIndent}enum value2;`;
138738
138925
  const rootType = rootUsage ? rootUsage.typeNames[0] ?? rootUsage.typeName : void 0;
138739
138926
  let memberNames = [];
138740
138927
  if (rootType) {
138741
- const typeDef = allSymbols.find((s) => s.name === rootType && s.kind.endsWith(" def"));
138928
+ const typeDef = symbolTable.findByName(rootType).find((s) => isDefinition(s.kind));
138742
138929
  if (typeDef) {
138743
138930
  memberNames = allSymbols.filter((s) => s.parentId === typeDef.symbolId).map((s) => s.name);
138744
138931
  }
@@ -138760,7 +138947,8 @@ ${childIndent}enum value2;`;
138760
138947
  }
138761
138948
  }
138762
138949
  if (!best || best.dist > 4 || best.name === unresolvedLeaf) return void 0;
138763
- const fixedExpr = `${root}.${best.name}`;
138950
+ const leaf = path.qualifiedNames.at(-1);
138951
+ const fixedExpr = expr.slice(0, leaf.start) + quoteName(best.name) + expr.slice(leaf.end);
138764
138952
  const edit = {
138765
138953
  changes: {
138766
138954
  [uri]: [
@@ -138836,6 +139024,13 @@ ${childIndent}enum value2;`;
138836
139024
  isAttributeTypeContext(text, diagnostic, unresolvedType) {
138837
139025
  const lines = text.split("\n");
138838
139026
  const line = lines[diagnostic.range.start.line] ?? "";
139027
+ const names = [...scanQualifiedNames(line)];
139028
+ const attribute = names.findIndex((name) => line.slice(name.start, name.end) === "attribute");
139029
+ const usage = names[attribute + 1];
139030
+ const type = names[attribute + 2];
139031
+ if (attribute >= 0 && usage && type && type.name === unresolvedType && /^\s*:\s*$/.test(line.slice(usage.end, type.start))) {
139032
+ return true;
139033
+ }
138839
139034
  const beforeRange = line.slice(0, diagnostic.range.start.character);
138840
139035
  const unresolvedInLine = line.slice(diagnostic.range.start.character, diagnostic.range.end.character);
138841
139036
  const escapedType = unresolvedType.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -138848,18 +139043,19 @@ ${childIndent}enum value2;`;
138848
139043
  return /\battribute\s+[A-Za-z_][A-Za-z0-9_]*\s*:\s*[A-Za-z_][A-Za-z0-9_]*\b/.test(beforeRange + unresolvedInLine);
138849
139044
  }
138850
139045
  buildLocalTypeStub(text, diagnostic, unresolvedType, childIndent) {
139046
+ const sourceName = quoteName(unquoteName(unresolvedType));
138851
139047
  if (this.isAttributeTypeContext(text, diagnostic, unresolvedType)) {
138852
139048
  return {
138853
- title: `Create local 'attribute def ${unresolvedType};'`,
139049
+ title: `Create local 'attribute def ${sourceName};'`,
138854
139050
  stubText: `
138855
- ${childIndent}attribute def ${unresolvedType};
139051
+ ${childIndent}attribute def ${sourceName};
138856
139052
  `
138857
139053
  };
138858
139054
  }
138859
139055
  return {
138860
- title: `Create local 'item def ${unresolvedType};'`,
139056
+ title: `Create local 'item def ${sourceName};'`,
138861
139057
  stubText: `
138862
- ${childIndent}item def ${unresolvedType};
139058
+ ${childIndent}item def ${sourceName};
138863
139059
  `
138864
139060
  };
138865
139061
  }
@@ -138895,13 +139091,12 @@ ${childIndent}item def ${unresolvedType};
138895
139091
  }
138896
139092
  function extractDottedTokenAtRange(line, start, end) {
138897
139093
  if (!line || start < 0 || end < 0 || start > line.length || end > line.length) return "";
138898
- const isTokenChar = (ch) => ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z" || ch >= "0" && ch <= "9" || ch === "_" || ch === ".";
138899
- let left = Math.max(0, start);
138900
- while (left > 0 && isTokenChar(line[left - 1])) left--;
138901
- let right = Math.min(line.length, end);
138902
- while (right < line.length && isTokenChar(line[right])) right++;
138903
- const token = line.slice(left, right).trim();
138904
- return token.includes(".") ? token : "";
139094
+ for (const path of scanFeaturePaths(line)) {
139095
+ if (path.qualifiedNames.length > 1 && path.start <= start && path.end >= end) {
139096
+ return line.slice(path.start, path.end);
139097
+ }
139098
+ }
139099
+ return "";
138905
139100
  }
138906
139101
  function extractLikelyMemberNames(text, excludeName) {
138907
139102
  const names = /* @__PURE__ */ new Set();
@@ -139013,6 +139208,7 @@ ${childIndent}item def ${unresolvedType};
139013
139208
  seen.add(sym.name);
139014
139209
  defItems.push({
139015
139210
  label: sym.name,
139211
+ insertText: quoteName(sym.name),
139016
139212
  kind: this.mapSymbolKindToCompletionKind(sym.kind),
139017
139213
  detail: `${sym.kind}${sym.qualifiedName !== void 0 && sym.qualifiedName !== sym.name ? ` (${sym.qualifiedName})` : ""}`,
139018
139214
  documentation: sym.documentation,
@@ -139033,6 +139229,7 @@ ${childIndent}item def ${unresolvedType};
139033
139229
  seenPorts.add(sym.name);
139034
139230
  items.push({
139035
139231
  label: sym.name,
139232
+ insertText: quoteName(sym.name),
139036
139233
  kind: import_node2.CompletionItemKind.Interface,
139037
139234
  detail: `${sym.kind}${sym.typeNames[0] ? ` : ${sym.typeNames[0]}` : ""}`,
139038
139235
  data: sym.qualifiedName,
@@ -139040,13 +139237,17 @@ ${childIndent}item def ${unresolvedType};
139040
139237
  });
139041
139238
  }
139042
139239
  }
139043
- if (context === "type-annotation") {
139044
- return items.filter((i) => this.isTypeOrDefinitionCompletion(i));
139045
- }
139046
- if (context === "connect-endpoint") {
139047
- return items.filter((i) => this.isConnectContextCompletion(i));
139048
- }
139049
- return items;
139240
+ const filtered = context === "type-annotation" ? items.filter((i) => this.isTypeOrDefinitionCompletion(i)) : context === "connect-endpoint" ? items.filter((i) => this.isConnectContextCompletion(i)) : items;
139241
+ const line = this.documentManager.getText(uri)?.split("\n")[params.position.line] ?? "";
139242
+ const segment = [...scanQualifiedNames(line, true)].flatMap((name) => name.segments).find((name) => name.start <= params.position.character && name.end >= params.position.character);
139243
+ if (!segment) return filtered;
139244
+ return filtered.map((item) => item.insertTextFormat === import_node2.InsertTextFormat.Snippet ? item : {
139245
+ ...item,
139246
+ textEdit: {
139247
+ range: import_node2.Range.create(params.position.line, segment.start, params.position.line, segment.end),
139248
+ newText: item.insertText ?? item.label
139249
+ }
139250
+ });
139050
139251
  }
139051
139252
  resolveCompletion(item) {
139052
139253
  return item;
@@ -139119,6 +139320,108 @@ ${childIndent}item def ${unresolvedType};
139119
139320
  }
139120
139321
  };
139121
139322
 
139323
+ // server/src/symbols/nameReferences.ts
139324
+ var import_node3 = __toESM(require_main3());
139325
+ var NameReferences = class {
139326
+ constructor(documents2) {
139327
+ this.documents = documents2;
139328
+ this.symbols = documents2.getWorkspaceSymbolTable().getAllSymbols();
139329
+ this.indexes = buildSymbolIndexes(this.symbols);
139330
+ }
139331
+ documents;
139332
+ symbols;
139333
+ indexes;
139334
+ resolver = new NamespaceResolver();
139335
+ at(uri, position) {
139336
+ return this.inDocument(uri, position).find((ref) => ref.range.start.line === position.line && ref.range.start.character <= position.character && ref.range.end.character >= position.character);
139337
+ }
139338
+ to(symbol, includeDeclaration = true) {
139339
+ return this.documents.getUris().flatMap((uri) => this.inDocument(uri, void 0, symbol)).filter((ref) => ref.symbol?.symbolId === symbol.symbolId && (includeDeclaration || !ref.isDeclaration));
139340
+ }
139341
+ inDocument(uri, position, target) {
139342
+ const text = this.documents.getText(uri);
139343
+ const parsed = this.documents.get(uri);
139344
+ if (text === void 0 || !parsed) return [];
139345
+ const doc = TextDocument2.create(uri, "sysml", 0, text);
139346
+ const symbols = this.symbols.filter((symbol) => symbol.uri === uri);
139347
+ const braces = parsed.tokenStream.getTokens().filter((token) => token.type === SysMLv2Lexer.LBRACE).map((token) => doc.offsetAt({ line: token.line - 1, character: token.column }));
139348
+ const namespaces = symbols.flatMap((symbol) => {
139349
+ const start = doc.offsetAt(symbol.range.start);
139350
+ const end = doc.offsetAt(symbol.range.end);
139351
+ let lo = 0;
139352
+ let hi = braces.length;
139353
+ while (lo < hi) {
139354
+ const mid = lo + hi >>> 1;
139355
+ if (braces[mid] < start) lo = mid + 1;
139356
+ else hi = mid;
139357
+ }
139358
+ const body = braces[lo];
139359
+ return body === void 0 || body >= end ? [] : [{ symbol, body, end }];
139360
+ }).sort((a, b) => a.end - a.body - (b.end - b.body));
139361
+ const refs = [];
139362
+ const cursor = position ? doc.offsetAt(position) : void 0;
139363
+ for (const path of scanFeaturePaths(text)) {
139364
+ if (cursor !== void 0 && (cursor < path.start || cursor > path.end)) continue;
139365
+ if (target && !path.qualifiedNames.some((name) => name.segments.some((segment) => segment.name === target.name || segment.name === target.shortName))) continue;
139366
+ const namespace = namespaces.find((ns) => ns.body < path.start && path.end <= ns.end);
139367
+ let receiver;
139368
+ for (let group = 0; group < path.qualifiedNames.length; group++) {
139369
+ const qualified = path.qualifiedNames[group];
139370
+ let resolved;
139371
+ for (let index2 = 0; index2 < qualified.segments.length; index2++) {
139372
+ const segment = qualified.segments[index2];
139373
+ const range = import_node3.Range.create(doc.positionAt(segment.start), doc.positionAt(segment.end));
139374
+ let before = segment.start - 1;
139375
+ let after = segment.end;
139376
+ while (before >= 0 && /\s/.test(text[before])) before--;
139377
+ while (after < text.length && /\s/.test(text[after])) after++;
139378
+ const declaration = symbols.find((symbol) => !isAnonymous(symbol) && (symbol.selectionRange.start.line === range.start.line && symbol.selectionRange.start.character === range.start.character && symbol.selectionRange.end.character === range.end.character || symbol.shortName === segment.name && text[before] === "<" && text[after] === ">" && doc.offsetAt(symbol.range.start) <= segment.start && segment.end < doc.offsetAt(symbol.selectionRange.start)));
139379
+ if (declaration) resolved = declaration;
139380
+ else if (index2 > 0) {
139381
+ resolved = resolved ? this.resolver.getResolvedMembers(namespaceKeyOf(resolved), this.indexes).get(segment.name)?.find((entry) => entry.visibility === "public")?.symbol : void 0;
139382
+ } else if (group > 0) {
139383
+ resolved = receiver ? this.resolveFeature(receiver, segment.name) : void 0;
139384
+ } else {
139385
+ resolved = this.resolver.resolveNameIn(
139386
+ namespace?.symbol,
139387
+ joinQualifiedName([segment.name]),
139388
+ this.indexes
139389
+ );
139390
+ }
139391
+ if (cursor !== void 0 && (cursor < segment.start || cursor > segment.end)) continue;
139392
+ if (target && segment.name !== target.name && segment.name !== target.shortName) continue;
139393
+ refs.push({
139394
+ uri,
139395
+ range,
139396
+ name: segment.name,
139397
+ qualifiedName: index2 === qualified.segments.length - 1 ? qualified.name : segment.name,
139398
+ symbol: resolved,
139399
+ isDeclaration: declaration !== void 0
139400
+ });
139401
+ }
139402
+ receiver = resolved;
139403
+ }
139404
+ }
139405
+ return refs;
139406
+ }
139407
+ resolveFeature(receiver, name) {
139408
+ const queue = [receiver];
139409
+ const visited = /* @__PURE__ */ new Set();
139410
+ for (let index2 = 0; index2 < queue.length; index2++) {
139411
+ const owner = queue[index2];
139412
+ if (visited.has(owner)) continue;
139413
+ visited.add(owner);
139414
+ const member = this.resolver.getResolvedMembers(namespaceKeyOf(owner), this.indexes).get(name)?.find((entry) => entry.visibility === "public")?.symbol;
139415
+ if (member) return member;
139416
+ for (const typeName of owner.typeNames) {
139417
+ const type = this.resolver.resolveNameFrom(owner, typeName, this.indexes);
139418
+ if (type && !visited.has(type)) queue.push(type);
139419
+ }
139420
+ }
139421
+ return void 0;
139422
+ }
139423
+ };
139424
+
139122
139425
  // server/src/providers/definitionProvider.ts
139123
139426
  var DefinitionProvider = class {
139124
139427
  constructor(documentManager2) {
@@ -139131,6 +139434,10 @@ ${childIndent}item def ${unresolvedType};
139131
139434
  return null;
139132
139435
  }
139133
139436
  const wsSymbolTable = this.documentManager.getWorkspaceSymbolTable();
139437
+ const reference = new NameReferences(this.documentManager).at(params.textDocument.uri, params.position);
139438
+ if (reference?.symbol && !reference.isDeclaration) {
139439
+ return { uri: reference.symbol.uri, range: reference.symbol.selectionRange };
139440
+ }
139134
139441
  const symbol = symbolTable.findSymbolAtPosition(
139135
139442
  params.textDocument.uri,
139136
139443
  params.position.line,
@@ -139238,7 +139545,7 @@ ${childIndent}item def ${unresolvedType};
139238
139545
  };
139239
139546
 
139240
139547
  // server/src/providers/diagnosticsProvider.ts
139241
- var import_node3 = __toESM(require_main3());
139548
+ var import_node4 = __toESM(require_main3());
139242
139549
  var EXPRESSION_OPERATOR_RE = /(\w\s*[+\-*/^]\s*\w)|(\w\s*\*\*\s*\w)|->|\.(?:\?)|:=|;\s*doc\b|#\w+\s+dependency/;
139243
139550
  var DiagnosticsProvider = class {
139244
139551
  constructor(documentManager2) {
@@ -139290,7 +139597,7 @@ ${childIndent}item def ${unresolvedType};
139290
139597
  message = `'${word}' is a reserved SysML keyword and cannot be used as a name. Consider renaming it (e.g., '${suggestion}').`;
139291
139598
  }
139292
139599
  return {
139293
- severity: import_node3.DiagnosticSeverity.Error,
139600
+ severity: import_node4.DiagnosticSeverity.Error,
139294
139601
  range: {
139295
139602
  start: { line: error.line, character: error.column },
139296
139603
  end: { line: error.line, character: error.column + error.length }
@@ -139359,51 +139666,51 @@ ${childIndent}item def ${unresolvedType};
139359
139666
  };
139360
139667
 
139361
139668
  // server/src/providers/symbolKindMapping.ts
139362
- var import_node4 = __toESM(require_main3());
139669
+ var import_node5 = __toESM(require_main3());
139363
139670
  function toSysMLSymbolKind(kind) {
139364
139671
  switch (kind) {
139365
139672
  // Structural definitions → Class (they *are* types)
139366
139673
  case "part def" /* PartDef */:
139367
139674
  case "occurrence def" /* OccurrenceDef */:
139368
- return import_node4.SymbolKind.Class;
139675
+ return import_node5.SymbolKind.Class;
139369
139676
  // Structural usages → Field (instances / typed features)
139370
139677
  case "part" /* PartUsage */:
139371
139678
  case "occurrence" /* OccurrenceUsage */:
139372
139679
  case "ref" /* RefUsage */:
139373
- return import_node4.SymbolKind.Field;
139680
+ return import_node5.SymbolKind.Field;
139374
139681
  // Attributes
139375
139682
  case "attribute def" /* AttributeDef */:
139376
139683
  case "attribute" /* AttributeUsage */:
139377
- return import_node4.SymbolKind.Property;
139684
+ return import_node5.SymbolKind.Property;
139378
139685
  // Ports & Interfaces → Interface
139379
139686
  case "port def" /* PortDef */:
139380
139687
  case "port" /* PortUsage */:
139381
139688
  case "interface def" /* InterfaceDef */:
139382
139689
  case "interface" /* InterfaceUsage */:
139383
- return import_node4.SymbolKind.Interface;
139690
+ return import_node5.SymbolKind.Interface;
139384
139691
  // Connections
139385
139692
  case "connection def" /* ConnectionDef */:
139386
139693
  case "connection" /* ConnectionUsage */:
139387
- return import_node4.SymbolKind.Interface;
139694
+ return import_node5.SymbolKind.Interface;
139388
139695
  // Behavioral: actions → Method
139389
139696
  case "action def" /* ActionDef */:
139390
139697
  case "action" /* ActionUsage */:
139391
139698
  case "perform action" /* PerformActionUsage */:
139392
- return import_node4.SymbolKind.Method;
139699
+ return import_node5.SymbolKind.Method;
139393
139700
  // Control-flow nodes (fork/join/merge/decide) → Event
139394
139701
  case "fork" /* ForkNode */:
139395
139702
  case "join" /* JoinNode */:
139396
139703
  case "merge" /* MergeNode */:
139397
139704
  case "decide" /* DecisionNode */:
139398
- return import_node4.SymbolKind.Event;
139705
+ return import_node5.SymbolKind.Event;
139399
139706
  // Behavioral: states → Event (better semantic fit than Enum)
139400
139707
  case "state def" /* StateDef */:
139401
139708
  case "state" /* StateUsage */:
139402
139709
  case "exhibit state" /* ExhibitStateUsage */:
139403
- return import_node4.SymbolKind.Event;
139710
+ return import_node5.SymbolKind.Event;
139404
139711
  // Transitions → Event
139405
139712
  case "transition" /* TransitionUsage */:
139406
- return import_node4.SymbolKind.Event;
139713
+ return import_node5.SymbolKind.Event;
139407
139714
  // Requirements → Object
139408
139715
  case "requirement def" /* RequirementDef */:
139409
139716
  case "requirement" /* RequirementUsage */:
@@ -139412,58 +139719,58 @@ ${childIndent}item def ${unresolvedType};
139412
139719
  case "actor" /* ActorUsage */:
139413
139720
  case "subject" /* SubjectUsage */:
139414
139721
  case "stakeholder" /* StakeholderUsage */:
139415
- return import_node4.SymbolKind.Object;
139722
+ return import_node5.SymbolKind.Object;
139416
139723
  // Constraints → Constant (boolean-valued)
139417
139724
  case "constraint def" /* ConstraintDef */:
139418
139725
  case "constraint" /* ConstraintUsage */:
139419
- return import_node4.SymbolKind.Constant;
139726
+ return import_node5.SymbolKind.Constant;
139420
139727
  // Items → Struct (physical things, data)
139421
139728
  case "item def" /* ItemDef */:
139422
139729
  case "item" /* ItemUsage */:
139423
- return import_node4.SymbolKind.Struct;
139730
+ return import_node5.SymbolKind.Struct;
139424
139731
  // Allocations → TypeParameter (cross-concern mapping)
139425
139732
  case "allocation def" /* AllocationDef */:
139426
139733
  case "allocation" /* AllocationUsage */:
139427
- return import_node4.SymbolKind.TypeParameter;
139734
+ return import_node5.SymbolKind.TypeParameter;
139428
139735
  // Enumerations
139429
139736
  case "enum def" /* EnumDef */:
139430
- return import_node4.SymbolKind.Enum;
139737
+ return import_node5.SymbolKind.Enum;
139431
139738
  case "enum" /* EnumUsage */:
139432
- return import_node4.SymbolKind.EnumMember;
139739
+ return import_node5.SymbolKind.EnumMember;
139433
139740
  // Calculations → Function
139434
139741
  case "calc def" /* CalcDef */:
139435
139742
  case "calc" /* CalcUsage */:
139436
139743
  case "analysis case def" /* AnalysisCaseDef */:
139437
139744
  case "verification case def" /* VerificationCaseDef */:
139438
- return import_node4.SymbolKind.Function;
139745
+ return import_node5.SymbolKind.Function;
139439
139746
  // Use cases → Event
139440
139747
  case "use case def" /* UseCaseDef */:
139441
139748
  case "use case" /* UseCaseUsage */:
139442
139749
  case "include use case" /* IncludeUseCaseUsage */:
139443
- return import_node4.SymbolKind.Event;
139750
+ return import_node5.SymbolKind.Event;
139444
139751
  // Views → Namespace
139445
139752
  case "view def" /* ViewDef */:
139446
139753
  case "view" /* ViewUsage */:
139447
139754
  case "viewpoint def" /* ViewpointDef */:
139448
139755
  case "viewpoint" /* ViewpointUsage */:
139449
139756
  case "rendering def" /* RenderingDef */:
139450
- return import_node4.SymbolKind.Namespace;
139757
+ return import_node5.SymbolKind.Namespace;
139451
139758
  // Metadata → TypeParameter
139452
139759
  case "metadata def" /* MetadataDef */:
139453
- return import_node4.SymbolKind.TypeParameter;
139760
+ return import_node5.SymbolKind.TypeParameter;
139454
139761
  // Package
139455
139762
  case "package" /* Package */:
139456
- return import_node4.SymbolKind.Package;
139763
+ return import_node5.SymbolKind.Package;
139457
139764
  // Comments / docs
139458
139765
  case "comment" /* Comment */:
139459
139766
  case "doc" /* Doc */:
139460
- return import_node4.SymbolKind.String;
139767
+ return import_node5.SymbolKind.String;
139461
139768
  // Import / Alias
139462
139769
  case "import" /* Import */:
139463
139770
  case "alias" /* Alias */:
139464
- return import_node4.SymbolKind.Module;
139771
+ return import_node5.SymbolKind.Module;
139465
139772
  default:
139466
- return import_node4.SymbolKind.Variable;
139773
+ return import_node5.SymbolKind.Variable;
139467
139774
  }
139468
139775
  }
139469
139776
 
@@ -139510,7 +139817,7 @@ ${childIndent}item def ${unresolvedType};
139510
139817
  };
139511
139818
 
139512
139819
  // server/src/providers/foldingRangeProvider.ts
139513
- var import_node5 = __toESM(require_main3());
139820
+ var import_node6 = __toESM(require_main3());
139514
139821
  var FoldingRangeProvider = class {
139515
139822
  constructor(documentManager2) {
139516
139823
  this.documentManager = documentManager2;
@@ -139533,7 +139840,7 @@ ${childIndent}item def ${unresolvedType};
139533
139840
  ranges.push({
139534
139841
  startLine: commentStart,
139535
139842
  endLine: i,
139536
- kind: import_node5.FoldingRangeKind.Comment
139843
+ kind: import_node6.FoldingRangeKind.Comment
139537
139844
  });
139538
139845
  commentStart = void 0;
139539
139846
  }
@@ -139546,7 +139853,7 @@ ${childIndent}item def ${unresolvedType};
139546
139853
  ranges.push({
139547
139854
  startLine,
139548
139855
  endLine: i,
139549
- kind: import_node5.FoldingRangeKind.Region
139856
+ kind: import_node6.FoldingRangeKind.Region
139550
139857
  });
139551
139858
  }
139552
139859
  }
@@ -139557,7 +139864,7 @@ ${childIndent}item def ${unresolvedType};
139557
139864
  };
139558
139865
 
139559
139866
  // server/src/providers/formattingProvider.ts
139560
- var import_node6 = __toESM(require_main3());
139867
+ var import_node7 = __toESM(require_main3());
139561
139868
  var FormattingProvider = class {
139562
139869
  constructor(documents2) {
139563
139870
  this.documents = documents2;
@@ -139573,8 +139880,8 @@ ${childIndent}item def ${unresolvedType};
139573
139880
  const formatted = this.formatSysML(text, indent);
139574
139881
  if (formatted === text) return [];
139575
139882
  return [
139576
- import_node6.TextEdit.replace(
139577
- import_node6.Range.create(0, 0, doc.lineCount, 0),
139883
+ import_node7.TextEdit.replace(
139884
+ import_node7.Range.create(0, 0, doc.lineCount, 0),
139578
139885
  formatted
139579
139886
  )
139580
139887
  ];
@@ -139588,7 +139895,7 @@ ${childIndent}item def ${unresolvedType};
139588
139895
  const rangeText = doc.getText(params.range);
139589
139896
  const formatted = this.formatSysML(rangeText, indent);
139590
139897
  if (formatted === rangeText) return [];
139591
- return [import_node6.TextEdit.replace(params.range, formatted)];
139898
+ return [import_node7.TextEdit.replace(params.range, formatted)];
139592
139899
  }
139593
139900
  formatSysML(text, indent) {
139594
139901
  const lines = text.split("\n");
@@ -139724,7 +140031,7 @@ ${childIndent}item def ${unresolvedType};
139724
140031
  };
139725
140032
 
139726
140033
  // server/src/providers/hoverProvider.ts
139727
- var import_node7 = __toESM(require_main3());
140034
+ var import_node8 = __toESM(require_main3());
139728
140035
  var HoverProvider = class {
139729
140036
  constructor(documentManager2) {
139730
140037
  this.documentManager = documentManager2;
@@ -139741,12 +140048,13 @@ ${childIndent}item def ${unresolvedType};
139741
140048
  return null;
139742
140049
  }
139743
140050
  const text = this.documentManager.getText(params.textDocument.uri);
139744
- const word = text ? this.getWordAtPosition(text, params.position.line, params.position.character) : void 0;
139745
- if (word && word.includes("::")) {
140051
+ const reference = new NameReferences(this.documentManager).at(params.textDocument.uri, params.position);
140052
+ const word = reference?.qualifiedName ?? (text ? this.getWordAtPosition(text, params.position.line, params.position.character) : void 0);
140053
+ if (word && word.includes("::") && !reference?.symbol) {
139746
140054
  const libHover = this.buildLibraryHover(word);
139747
140055
  if (libHover) return libHover;
139748
140056
  }
139749
- const symbol = symbolTable.findSymbolAtPosition(
140057
+ const symbol = reference?.symbol ?? symbolTable.findSymbolAtPosition(
139750
140058
  params.textDocument.uri,
139751
140059
  params.position.line,
139752
140060
  params.position.character
@@ -139798,7 +140106,7 @@ ${symbol.documentation}`);
139798
140106
  if (hoverDiags.length > 0) {
139799
140107
  lines.push("\n---\n**Semantic Feedback**");
139800
140108
  for (const d of hoverDiags.slice(0, 3)) {
139801
- const sev = d.severity === import_node7.DiagnosticSeverity.Error ? "Error" : d.severity === import_node7.DiagnosticSeverity.Warning ? "Warning" : "Hint";
140109
+ const sev = d.severity === import_node8.DiagnosticSeverity.Error ? "Error" : d.severity === import_node8.DiagnosticSeverity.Warning ? "Warning" : "Hint";
139802
140110
  lines.push(`- **${sev}**: ${d.message}`);
139803
140111
  const hint = this.getRepairHint(String(d.code ?? ""));
139804
140112
  if (hint) {
@@ -139807,12 +140115,12 @@ ${symbol.documentation}`);
139807
140115
  }
139808
140116
  }
139809
140117
  const content = {
139810
- kind: import_node7.MarkupKind.Markdown,
140118
+ kind: import_node8.MarkupKind.Markdown,
139811
140119
  value: lines.join("\n")
139812
140120
  };
139813
140121
  return {
139814
140122
  contents: content,
139815
- range: symbol.selectionRange
140123
+ range: reference?.range ?? symbol.selectionRange
139816
140124
  };
139817
140125
  }
139818
140126
  /**
@@ -139839,7 +140147,7 @@ ${info.documentation}`);
139839
140147
  }
139840
140148
  return {
139841
140149
  contents: {
139842
- kind: import_node7.MarkupKind.Markdown,
140150
+ kind: import_node8.MarkupKind.Markdown,
139843
140151
  value: lines.join("\n")
139844
140152
  }
139845
140153
  };
@@ -139879,7 +140187,7 @@ ${info.documentation}`);
139879
140187
  };
139880
140188
 
139881
140189
  // server/src/providers/keywordValidator.ts
139882
- var import_node8 = __toESM(require_main3());
140190
+ var import_node9 = __toESM(require_main3());
139883
140191
 
139884
140192
  // server/src/utils/emptyNames.ts
139885
140193
  var EMPTY_NAME_MESSAGE = "Empty name '': a name in single quotes must contain at least one character";
@@ -140278,7 +140586,7 @@ ${info.documentation}`);
140278
140586
  const line2 = (token.line ?? 1) - 1;
140279
140587
  const char2 = token.column ?? 0;
140280
140588
  diagnostics.push({
140281
- severity: import_node8.DiagnosticSeverity.Error,
140589
+ severity: import_node9.DiagnosticSeverity.Error,
140282
140590
  range: { start: { line: line2, character: char2 }, end: { line: line2, character: char2 + 2 } },
140283
140591
  message: EMPTY_NAME_MESSAGE,
140284
140592
  source: "sysml",
@@ -140296,7 +140604,7 @@ ${info.documentation}`);
140296
140604
  const char = token.column ?? 0;
140297
140605
  const message = `Unknown keyword '${text}'. Did you mean '${suggestion}'?`;
140298
140606
  diagnostics.push({
140299
- severity: import_node8.DiagnosticSeverity.Error,
140607
+ severity: import_node9.DiagnosticSeverity.Error,
140300
140608
  range: {
140301
140609
  start: { line, character: char },
140302
140610
  end: { line, character: char + text.length }
@@ -140316,115 +140624,50 @@ ${info.documentation}`);
140316
140624
  }
140317
140625
  documentManager;
140318
140626
  provideReferences(params) {
140319
- const result = this.documentManager.get(params.textDocument.uri);
140320
- if (!result) {
140321
- return [];
140322
- }
140323
- const symbolTable = this.documentManager.getWorkspaceSymbolTable();
140324
- const symbol = symbolTable.findSymbolAtPosition(
140325
- params.textDocument.uri,
140326
- params.position.line,
140327
- params.position.character
140328
- );
140329
- if (!symbol || isAnonymous(symbol)) {
140330
- return [];
140331
- }
140332
- const references = symbolTable.findReferences(symbol.name);
140333
- const locations = [];
140334
- for (const ref of references) {
140335
- locations.push({
140336
- uri: ref.uri,
140337
- range: ref.selectionRange
140338
- });
140339
- }
140340
- if (params.context.includeDeclaration) {
140341
- }
140342
- return locations;
140627
+ const references = new NameReferences(this.documentManager);
140628
+ const ref = references.at(params.textDocument.uri, params.position);
140629
+ return ref?.symbol ? references.to(ref.symbol, params.context.includeDeclaration).map(({ uri, range }) => ({ uri, range })) : [];
140343
140630
  }
140344
140631
  };
140345
140632
 
140346
140633
  // server/src/providers/renameProvider.ts
140347
- function findWordOccurrences(line, word) {
140348
- const positions = [];
140349
- let from = 0;
140350
- while (from <= line.length - word.length) {
140351
- const idx = line.indexOf(word, from);
140352
- if (idx < 0) break;
140353
- if ((idx === 0 || !isIdentPart(line.charCodeAt(idx - 1))) && (idx + word.length >= line.length || !isIdentPart(line.charCodeAt(idx + word.length)))) {
140354
- positions.push(idx);
140355
- }
140356
- from = idx + 1;
140357
- }
140358
- return positions;
140359
- }
140634
+ var import_node10 = __toESM(require_main3());
140360
140635
  var RenameProvider = class {
140361
140636
  constructor(documentManager2) {
140362
140637
  this.documentManager = documentManager2;
140363
140638
  }
140364
140639
  documentManager;
140365
- /**
140366
- * Check if the token at position is renameable and return its range.
140367
- */
140368
140640
  prepareRename(params) {
140369
- const symbolTable = this.documentManager.getSymbolTable(params.textDocument.uri);
140370
- if (!symbolTable) return null;
140371
- const symbol = symbolTable.findSymbolAtPosition(
140372
- params.textDocument.uri,
140373
- params.position.line,
140374
- params.position.character
140375
- );
140376
- if (!symbol || isAnonymous(symbol)) return null;
140377
- return symbol.selectionRange;
140641
+ const ref = new NameReferences(this.documentManager).at(params.textDocument.uri, params.position);
140642
+ return ref?.symbol ? ref.range : null;
140378
140643
  }
140379
- /**
140380
- * Perform the rename — update the symbol and all references.
140381
- */
140382
140644
  provideRename(params) {
140383
- const symbolTable = this.documentManager.getSymbolTable(params.textDocument.uri);
140384
- if (!symbolTable) return null;
140385
- const symbol = symbolTable.findSymbolAtPosition(
140386
- params.textDocument.uri,
140387
- params.position.line,
140388
- params.position.character
140389
- );
140390
- if (!symbol || isAnonymous(symbol)) return null;
140391
- const text = this.documentManager.getText(params.textDocument.uri);
140392
- if (!text) return null;
140393
- const edits = [];
140394
- const oldName = symbol.name;
140395
- const newName = params.newName;
140396
- const references = symbolTable.findReferences(oldName);
140397
- for (const ref of references) {
140398
- if (ref.uri === params.textDocument.uri) {
140399
- edits.push({
140400
- range: ref.selectionRange,
140401
- newText: newName
140402
- });
140403
- }
140645
+ const references = new NameReferences(this.documentManager);
140646
+ const ref = references.at(params.textDocument.uri, params.position);
140647
+ if (!ref?.symbol) return null;
140648
+ const invalidControl = [...params.newName].some((ch) => {
140649
+ const code = ch.charCodeAt(0);
140650
+ return code < 32 && !" \n\r".includes(ch) || code === 127;
140651
+ });
140652
+ if (!params.newName || invalidControl) {
140653
+ throw new import_node10.ResponseError(import_node10.ErrorCodes.InvalidParams, "A SysML name must be non-empty and contain printable characters or escaped whitespace.");
140404
140654
  }
140405
- const lines = text.split("\n");
140406
- for (let i = 0; i < lines.length; i++) {
140407
- for (const col of findWordOccurrences(lines[i], oldName)) {
140408
- const range = {
140409
- start: { line: i, character: col },
140410
- end: { line: i, character: col + oldName.length }
140411
- };
140412
- if (!edits.some((e) => e.range.start.line === i && e.range.start.character === col)) {
140413
- edits.push({ range, newText: newName });
140414
- }
140415
- }
140655
+ const parsed = params.newName.startsWith("'") ? readNameAt(params.newName, 0) : void 0;
140656
+ if (params.newName.startsWith("'") && parsed?.end !== params.newName.length) {
140657
+ throw new import_node10.ResponseError(import_node10.ErrorCodes.InvalidParams, "The quoted SysML name is incomplete or contains an invalid escape sequence.");
140416
140658
  }
140417
- if (edits.length === 0) return null;
140418
- return {
140419
- changes: {
140420
- [params.textDocument.uri]: edits
140421
- }
140422
- };
140659
+ const newText = quoteName(parsed?.name ?? params.newName);
140660
+ const changes = {};
140661
+ for (const occurrence of references.to(ref.symbol)) {
140662
+ if (occurrence.name !== ref.name) continue;
140663
+ (changes[occurrence.uri] ??= []).push({ range: occurrence.range, newText });
140664
+ }
140665
+ return Object.keys(changes).length > 0 ? { changes } : null;
140423
140666
  }
140424
140667
  };
140425
140668
 
140426
140669
  // server/src/providers/semanticTokensProvider.ts
140427
- var import_node9 = __toESM(require_main3());
140670
+ var import_node11 = __toESM(require_main3());
140428
140671
  var OPERATOR_TOKENS = /* @__PURE__ */ new Set([
140429
140672
  SysMLv2Lexer.BANG_EQ_EQ,
140430
140673
  // !==
@@ -140565,7 +140808,7 @@ ${info.documentation}`);
140565
140808
  if (this.tokenCache && this.tokenCache.uri === uri && this.tokenCache.version === version) {
140566
140809
  return this.tokenCache.tokens;
140567
140810
  }
140568
- const builder = new import_node9.SemanticTokensBuilder();
140811
+ const builder = new import_node11.SemanticTokensBuilder();
140569
140812
  const result = this.documentManager.get(uri);
140570
140813
  if (!result) {
140571
140814
  return builder.build();
@@ -140645,7 +140888,7 @@ ${info.documentation}`);
140645
140888
  };
140646
140889
 
140647
140890
  // server/src/providers/semanticValidator.ts
140648
- var import_node10 = __toESM(require_main3());
140891
+ var import_node12 = __toESM(require_main3());
140649
140892
  var CONSTRAINT_KEYWORDS = /* @__PURE__ */ new Set([
140650
140893
  "and",
140651
140894
  "or",
@@ -140771,7 +141014,7 @@ ${info.documentation}`);
140771
141014
  const { resolved, strippedTypeName: typeName } = resolveTypeName(symbol.typeName, symbol, this.namespaceResolver, indexes, libraryNames);
140772
141015
  if (resolved) return [];
140773
141016
  const isMandatory = symbol.multiplicityRange && symbol.multiplicityRange.lower >= 1;
140774
- const severity = isMandatory ? import_node10.DiagnosticSeverity.Error : import_node10.DiagnosticSeverity.Warning;
141017
+ const severity = isMandatory ? import_node12.DiagnosticSeverity.Error : import_node12.DiagnosticSeverity.Warning;
140775
141018
  let message = `Type '${typeName}' is not defined in the current document or standard library`;
140776
141019
  if (isMandatory) {
140777
141020
  const multStr = symbol.multiplicity ?? "1";
@@ -140797,7 +141040,7 @@ ${info.documentation}`);
140797
141040
  const { lower, upper } = symbol.multiplicityRange;
140798
141041
  if (typeof upper === "number" && lower > upper) {
140799
141042
  return [{
140800
- severity: import_node10.DiagnosticSeverity.Error,
141043
+ severity: import_node12.DiagnosticSeverity.Error,
140801
141044
  range: symbol.selectionRange,
140802
141045
  message: `Invalid multiplicity [${symbol.multiplicity}]: lower bound (${lower}) exceeds upper bound (${upper})`,
140803
141046
  source: "sysml",
@@ -140806,7 +141049,7 @@ ${info.documentation}`);
140806
141049
  }
140807
141050
  if (lower < 0) {
140808
141051
  return [{
140809
- severity: import_node10.DiagnosticSeverity.Error,
141052
+ severity: import_node12.DiagnosticSeverity.Error,
140810
141053
  range: symbol.selectionRange,
140811
141054
  message: `Invalid multiplicity [${symbol.multiplicity}]: lower bound cannot be negative`,
140812
141055
  source: "sysml",
@@ -140830,7 +141073,7 @@ ${info.documentation}`);
140830
141073
  );
140831
141074
  if (!hasEnumValues) {
140832
141075
  return [{
140833
- severity: import_node10.DiagnosticSeverity.Information,
141076
+ severity: import_node12.DiagnosticSeverity.Information,
140834
141077
  range: symbol.selectionRange,
140835
141078
  message: `Enumeration '${displayName(symbol)}' has no enum values defined`,
140836
141079
  source: "sysml",
@@ -140850,7 +141093,7 @@ ${info.documentation}`);
140850
141093
  const ch = symbol.name[0];
140851
141094
  if (ch === ch.toLowerCase() && ch !== ch.toUpperCase()) {
140852
141095
  return [{
140853
- severity: import_node10.DiagnosticSeverity.Hint,
141096
+ severity: import_node12.DiagnosticSeverity.Hint,
140854
141097
  range: symbol.selectionRange,
140855
141098
  message: `Definition '${symbol.name}' should use PascalCase`,
140856
141099
  source: "sysml",
@@ -140862,7 +141105,7 @@ ${info.documentation}`);
140862
141105
  const ch = symbol.name[0];
140863
141106
  if (ch === ch.toUpperCase() && ch !== ch.toLowerCase()) {
140864
141107
  return [{
140865
- severity: import_node10.DiagnosticSeverity.Hint,
141108
+ severity: import_node12.DiagnosticSeverity.Hint,
140866
141109
  range: symbol.selectionRange,
140867
141110
  message: `Usage '${symbol.name}' should use camelCase`,
140868
141111
  source: "sysml",
@@ -140881,7 +141124,7 @@ ${info.documentation}`);
140881
141124
  if (!isDefinition(symbol.kind)) return [];
140882
141125
  if (symbol.documentation) return [];
140883
141126
  return [{
140884
- severity: import_node10.DiagnosticSeverity.Information,
141127
+ severity: import_node12.DiagnosticSeverity.Information,
140885
141128
  range: symbol.selectionRange,
140886
141129
  message: `Definition '${displayName(symbol)}' has no documentation`,
140887
141130
  source: "sysml",
@@ -140900,23 +141143,23 @@ ${info.documentation}`);
140900
141143
  );
140901
141144
  const defsInScope = targetUri ? defs.filter((def) => def.uri === targetUri) : defs;
140902
141145
  const referencedTypes = new Set(
140903
- symbols.filter((s) => s.kind !== "package" /* Package */).flatMap((s) => s.typeNames)
141146
+ symbols.filter((s) => s.kind !== "package" /* Package */).flatMap((s) => s.typeNames.flatMap((name) => [name, splitQualifiedName(name).at(-1)]))
140904
141147
  );
140905
141148
  for (const s of symbols) {
140906
141149
  if (s.exposeTargets) {
140907
141150
  for (const target of s.exposeTargets) {
140908
- const simpleName = target.replace(/::\*{1,2}$/, "").split("::").pop();
141151
+ const simpleName = splitQualifiedName(target.replace(/::\*{1,2}$/, "")).pop();
140909
141152
  if (simpleName) referencedTypes.add(simpleName);
140910
141153
  }
140911
141154
  }
140912
141155
  }
140913
141156
  const diagnostics = [];
140914
141157
  for (const def of defsInScope) {
140915
- const isReferenced = referencedTypes.has(def.name);
141158
+ const isReferenced = referencedTypes.has(def.name) || def.shortName !== void 0 && referencedTypes.has(def.shortName);
140916
141159
  const hasBaseType = (def.typeNames?.length ?? 0) > 0;
140917
141160
  if (!isReferenced && !hasBaseType) {
140918
141161
  diagnostics.push({
140919
- severity: import_node10.DiagnosticSeverity.Warning,
141162
+ severity: import_node12.DiagnosticSeverity.Warning,
140920
141163
  range: def.selectionRange,
140921
141164
  message: `Definition '${def.name}' is not referenced by any usage in the workspace`,
140922
141165
  source: "sysml",
@@ -140991,7 +141234,7 @@ ${info.documentation}`);
140991
141234
  const cycle = this.followSpecializationChain(def.name, def.typeNames, visited, indexes);
140992
141235
  if (cycle) {
140993
141236
  diagnostics.push({
140994
- severity: import_node10.DiagnosticSeverity.Error,
141237
+ severity: import_node12.DiagnosticSeverity.Error,
140995
141238
  range: def.selectionRange,
140996
141239
  message: `Circular specialization: ${cycle.join(" :> ")} :> ${cycle[0]}`,
140997
141240
  source: "sysml",
@@ -141079,7 +141322,7 @@ ${info.documentation}`);
141079
141322
  const isSatisfied = satisfiedNames.has(req.name) || req.qualifiedName !== void 0 && satisfiedNames.has(req.qualifiedName);
141080
141323
  if (!isSatisfied) {
141081
141324
  diagnostics.push({
141082
- severity: import_node10.DiagnosticSeverity.Warning,
141325
+ severity: import_node12.DiagnosticSeverity.Warning,
141083
141326
  range: req.selectionRange,
141084
141327
  message: `Requirement '${req.name}' is not satisfied by any element`,
141085
141328
  source: "sysml",
@@ -141216,7 +141459,7 @@ ${info.documentation}`);
141216
141459
  if (!isVerified) {
141217
141460
  const message = isSatisfied ? `Requirement '${req.name}' is satisfied but has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;` : `Requirement '${req.name}' has no verification case \u2014 consider adding: verify ${req.name} by <VerificationCase>;`;
141218
141461
  diagnostics.push({
141219
- severity: import_node10.DiagnosticSeverity.Warning,
141462
+ severity: import_node12.DiagnosticSeverity.Warning,
141220
141463
  range: req.selectionRange,
141221
141464
  message,
141222
141465
  source: "sysml",
@@ -141276,7 +141519,7 @@ ${info.documentation}`);
141276
141519
  const hasFilter = view.viewFilters && view.viewFilters.length > 0;
141277
141520
  if (!hasExpose && !hasFilter) {
141278
141521
  diagnostics.push({
141279
- severity: import_node10.DiagnosticSeverity.Information,
141522
+ severity: import_node12.DiagnosticSeverity.Information,
141280
141523
  range: view.selectionRange,
141281
141524
  message: `View '${view.name}' has no expose or filter directives \u2014 it will show all elements`,
141282
141525
  source: "sysml",
@@ -141316,7 +141559,7 @@ ${info.documentation}`);
141316
141559
  const upperOk = baseUpper === "*" || curUpper !== "*" && curUpper <= baseUpper;
141317
141560
  if (lowerOk && upperOk) continue;
141318
141561
  diagnostics.push({
141319
- severity: import_node10.DiagnosticSeverity.Error,
141562
+ severity: import_node12.DiagnosticSeverity.Error,
141320
141563
  range: s.selectionRange,
141321
141564
  message: `Redefinition multiplicity [${s.multiplicity ?? "?"}] is incompatible with base '${base.name}' multiplicity [${base.multiplicity ?? "?"}]`,
141322
141565
  source: "sysml",
@@ -141338,14 +141581,15 @@ ${info.documentation}`);
141338
141581
  if (!text) return [];
141339
141582
  const diagnostics = [];
141340
141583
  const lines = text.split("\n");
141341
- const re = /\bconnect\s+([A-Za-z_][\w.]*)\s+to\s+([A-Za-z_][\w.]*)/g;
141342
- let m2;
141343
- while ((m2 = re.exec(text)) !== null) {
141344
- const leftPath = m2[1].split(".");
141345
- const rightPath = m2[2].split(".");
141584
+ const paths = [...scanFeaturePaths(text)];
141585
+ for (let i = 0; i + 3 < paths.length; i++) {
141586
+ const [connect, leftEnd, to, rightEnd] = paths.slice(i, i + 4);
141587
+ if (text.slice(connect.start, connect.end) !== "connect" || text.slice(to.start, to.end) !== "to" || !/^\s+$/.test(text.slice(connect.end, leftEnd.start)) || !/^\s+$/.test(text.slice(leftEnd.end, to.start)) || !/^\s+$/.test(text.slice(to.end, rightEnd.start))) continue;
141588
+ const leftPath = [...leftEnd.parts];
141589
+ const rightPath = [...rightEnd.parts];
141346
141590
  const left = leftPath[leftPath.length - 1];
141347
141591
  const right = rightPath[rightPath.length - 1];
141348
- const scope = this.connectorScope(symbolsInUri, this.indexToRange(text, m2.index, 0).start, indexes);
141592
+ const scope = this.connectorScope(symbolsInUri, this.indexToRange(text, connect.start, 0).start, indexes);
141349
141593
  const lSym = this.resolveConnectorEnd(leftPath, scope, indexes);
141350
141594
  const rSym = this.resolveConnectorEnd(rightPath, scope, indexes);
141351
141595
  if (!lSym || !rSym) continue;
@@ -141355,10 +141599,10 @@ ${info.documentation}`);
141355
141599
  if (lType === "~" + rType || rType === "~" + lType) continue;
141356
141600
  if (lType.startsWith("~") && lType.slice(1) === rType) continue;
141357
141601
  if (rType.startsWith("~") && rType.slice(1) === lType) continue;
141358
- const matchLine = text.substring(0, m2.index).split("\n").length - 1;
141602
+ const matchLine = text.substring(0, connect.start).split("\n").length - 1;
141359
141603
  let insideInterfaceDef = false;
141360
- for (let i = matchLine; i >= 0 && i >= matchLine - 30; i--) {
141361
- const line = (lines[i] || "").trim();
141604
+ for (let i2 = matchLine; i2 >= 0 && i2 >= matchLine - 30; i2--) {
141605
+ const line = (lines[i2] || "").trim();
141362
141606
  if (/\binterface\s+def\b/.test(line)) {
141363
141607
  insideInterfaceDef = true;
141364
141608
  break;
@@ -141366,7 +141610,7 @@ ${info.documentation}`);
141366
141610
  if (/^\s*package\b/.test(line)) break;
141367
141611
  }
141368
141612
  if (insideInterfaceDef) continue;
141369
- const precedingText = text.substring(Math.max(0, m2.index - 300), m2.index);
141613
+ const precedingText = text.substring(Math.max(0, connect.start - 300), connect.start);
141370
141614
  if (/\binterface\s+\w[\w']*(:\w[\w']*)?\s*$/m.test(precedingText)) continue;
141371
141615
  const lDefSyms = indexes.byName.get(lType) ?? [];
141372
141616
  const rDefSyms = indexes.byName.get(rType) ?? [];
@@ -141385,14 +141629,14 @@ ${info.documentation}`);
141385
141629
  const hasSharedFeature = rChildren.some((c) => lChildNames.has(c.name));
141386
141630
  if (hasSharedFeature) continue;
141387
141631
  }
141388
- const range = this.indexToRange(text, m2.index, m2[0].length);
141632
+ const range = this.indexToRange(text, connect.start, rightEnd.end - connect.start);
141389
141633
  diagnostics.push({
141390
- severity: import_node10.DiagnosticSeverity.Warning,
141634
+ severity: import_node12.DiagnosticSeverity.Warning,
141391
141635
  range,
141392
141636
  message: `Port compatibility issue: '${left}' (${lType}) is connected to '${right}' (${rType})`,
141393
141637
  source: "sysml",
141394
141638
  code: "incompatible-port-types",
141395
- data: { uri }
141639
+ data: { uri, left, right, leftType: lType }
141396
141640
  });
141397
141641
  }
141398
141642
  return diagnostics;
@@ -141482,7 +141726,7 @@ ${info.documentation}`);
141482
141726
  const startInBody = trimStart >= 0 ? trimStart : 0;
141483
141727
  const trimmedLen = Math.max(1, b.body.trim().length);
141484
141728
  diagnostics.push({
141485
- severity: import_node10.DiagnosticSeverity.Warning,
141729
+ severity: import_node12.DiagnosticSeverity.Warning,
141486
141730
  range: this.indexToRange(text, b.bodyOffset + startInBody, trimmedLen),
141487
141731
  message: "Invalid constraint body: expected expression, found documentation text",
141488
141732
  source: "sysml",
@@ -141495,15 +141739,11 @@ ${info.documentation}`);
141495
141739
  if (!parent) continue;
141496
141740
  const parentMembers = this.getConstraintScopeMembers(parent, indexes);
141497
141741
  if (parentMembers.length === 0) continue;
141498
- const ignoredRanges = this.getIgnoredBodyRanges(b.body);
141499
- const idRe = /\b([A-Za-z_][\w]*(?:\.[A-Za-z_][\w]*)*)\b/g;
141500
- let im;
141501
- while ((im = idRe.exec(b.body)) !== null) {
141502
- if (this.isIndexInRanges(im.index, ignoredRanges)) continue;
141503
- const expr = im[1];
141742
+ for (const reference of scanFeaturePaths(b.body)) {
141743
+ const expr = reference.name;
141504
141744
  if (this.isConstraintKeyword(expr)) continue;
141505
141745
  if (/^\d/.test(expr)) continue;
141506
- const path = expr.split(".");
141746
+ const path = [...reference.parts];
141507
141747
  const ok = this.resolvePathFromParent(path, parentMembers, indexes);
141508
141748
  if (ok) continue;
141509
141749
  if (path.length === 1) {
@@ -141512,14 +141752,14 @@ ${info.documentation}`);
141512
141752
  continue;
141513
141753
  }
141514
141754
  }
141515
- const absoluteStart = b.bodyOffset + im.index;
141755
+ const absoluteStart = b.bodyOffset + reference.start;
141516
141756
  diagnostics.push({
141517
- severity: import_node10.DiagnosticSeverity.Warning,
141518
- range: this.indexToRange(text, absoluteStart, expr.length),
141757
+ severity: import_node12.DiagnosticSeverity.Warning,
141758
+ range: this.indexToRange(text, absoluteStart, reference.end - reference.start),
141519
141759
  message: `Unresolved constraint reference '${expr}' in scope '${displayName(parent)}'`,
141520
141760
  source: "sysml",
141521
141761
  code: "unresolved-constraint-reference",
141522
- data: { uri }
141762
+ data: { uri, scopeName: parent.name }
141523
141763
  });
141524
141764
  }
141525
141765
  }
@@ -141713,25 +141953,6 @@ ${info.documentation}`);
141713
141953
  isConstraintKeyword(value) {
141714
141954
  return CONSTRAINT_KEYWORDS.has(value);
141715
141955
  }
141716
- getIgnoredBodyRanges(body) {
141717
- const ranges = [];
141718
- const blockRe = /\/\*[\s\S]*?\*\//g;
141719
- let m2;
141720
- while ((m2 = blockRe.exec(body)) !== null) {
141721
- ranges.push({ start: m2.index, end: m2.index + m2[0].length });
141722
- }
141723
- const lineRe = /\/\/[^\n\r]*/g;
141724
- while ((m2 = lineRe.exec(body)) !== null) {
141725
- ranges.push({ start: m2.index, end: m2.index + m2[0].length });
141726
- }
141727
- return ranges;
141728
- }
141729
- isIndexInRanges(index2, ranges) {
141730
- for (const r of ranges) {
141731
- if (index2 >= r.start && index2 < r.end) return true;
141732
- }
141733
- return false;
141734
- }
141735
141956
  hasDocumentationOnlyConstraintBody(body) {
141736
141957
  const trimmed = body.trim();
141737
141958
  if (!trimmed) return false;
@@ -141829,7 +142050,7 @@ ${info.documentation}`);
141829
142050
  if (defs.length > 1) {
141830
142051
  for (const def of defs) {
141831
142052
  diagnostics.push({
141832
- severity: import_node10.DiagnosticSeverity.Warning,
142053
+ severity: import_node12.DiagnosticSeverity.Warning,
141833
142054
  range: def.selectionRange,
141834
142055
  message: `Duplicate definition: '${name}' is defined ${defs.length} times in the same scope`,
141835
142056
  source: "sysml",
@@ -141871,7 +142092,7 @@ ${info.documentation}`);
141871
142092
  if (!conflicting) continue;
141872
142093
  const others = otherDeclarations(conflicting, symbol);
141873
142094
  diagnostics.push({
141874
- severity: import_node10.DiagnosticSeverity.Error,
142095
+ severity: import_node12.DiagnosticSeverity.Error,
141875
142096
  range: symbol.selectionRange,
141876
142097
  message: `Ambiguous name '${symbol.name}': also declared as ${describeConflictingDeclarations(others, symbol.uri)}.`,
141877
142098
  source: "sysml",
@@ -141883,6 +142104,115 @@ ${info.documentation}`);
141883
142104
  }
141884
142105
  };
141885
142106
 
142107
+ // server/src/providers/textValidationProvider.ts
142108
+ var import_node13 = __toESM(require_main3());
142109
+ var DEFAULT_TEXT_VALIDATION_SETTINGS = {
142110
+ enabled: false,
142111
+ maxDocuments: 5,
142112
+ maxLines: 200,
142113
+ maxCharacters: 8192,
142114
+ maxTotalCharacters: 16384
142115
+ };
142116
+ function readTextValidationSettings(section) {
142117
+ const raw = typeof section === "object" && section !== null ? section : {};
142118
+ const limit = (value, fallback) => Number.isSafeInteger(value) && value > 0 ? value : fallback;
142119
+ return {
142120
+ enabled: raw.enabled === true,
142121
+ maxDocuments: limit(raw.maxDocuments, DEFAULT_TEXT_VALIDATION_SETTINGS.maxDocuments),
142122
+ maxLines: limit(raw.maxLines, DEFAULT_TEXT_VALIDATION_SETTINGS.maxLines),
142123
+ maxCharacters: limit(raw.maxCharacters, DEFAULT_TEXT_VALIDATION_SETTINGS.maxCharacters),
142124
+ maxTotalCharacters: limit(raw.maxTotalCharacters, DEFAULT_TEXT_VALIDATION_SETTINGS.maxTotalCharacters)
142125
+ };
142126
+ }
142127
+ var TextValidationProvider = class {
142128
+ /**
142129
+ * `isReported` filters diagnostics as the server does before
142130
+ * publishing them (`sysml.validation.disabledCodes`), so a text gets
142131
+ * exactly what it would get as an open document.
142132
+ */
142133
+ constructor(documentManager2, semanticValidator2, isReported2 = () => true) {
142134
+ this.documentManager = documentManager2;
142135
+ this.semanticValidator = semanticValidator2;
142136
+ this.isReported = isReported2;
142137
+ }
142138
+ documentManager;
142139
+ semanticValidator;
142140
+ isReported;
142141
+ settings = { ...DEFAULT_TEXT_VALIDATION_SETTINGS };
142142
+ /** Applies the client's settings to the requests that follow. */
142143
+ configure(settings) {
142144
+ this.settings = { ...settings };
142145
+ }
142146
+ /**
142147
+ * The diagnostics each text would get as an open document, with all
142148
+ * texts in place at the same time. Answers `MethodNotFound` while
142149
+ * disabled, and `InvalidParams` for malformed parameters or parameters
142150
+ * over a limit.
142151
+ */
142152
+ validate(params) {
142153
+ if (!this.settings.enabled) {
142154
+ throw new import_node13.ResponseError(
142155
+ import_node13.ErrorCodes.MethodNotFound,
142156
+ "sysml/validateText is experimental and disabled: set sysml.experimental.validateText.enabled to true."
142157
+ );
142158
+ }
142159
+ const documents2 = this.checkDocuments(params?.documents);
142160
+ const known = documents2.map((document) => ({ uri: this.knownSpelling(document.uri), text: document.text }));
142161
+ const diagnostics = this.documentManager.withTexts(known, () => known.map(({ uri }) => this.diagnose(uri)));
142162
+ return { documents: documents2.map((document, index2) => ({ uri: document.uri, diagnostics: diagnostics[index2] })) };
142163
+ }
142164
+ /** `documents` checked: a non-empty array of `{ uri, text }` within the limits, each naming a different document. */
142165
+ checkDocuments(documents2) {
142166
+ if (!Array.isArray(documents2) || documents2.length === 0) invalid('"documents" must be a non-empty array of { uri, text }.');
142167
+ const { maxDocuments, maxLines, maxCharacters, maxTotalCharacters } = this.settings;
142168
+ if (documents2.length > maxDocuments) {
142169
+ invalid(`${documents2.length} documents, more than the ${maxDocuments} allowed (sysml.experimental.validateText.maxDocuments).`);
142170
+ }
142171
+ const checked = documents2;
142172
+ let totalCharacters = 0;
142173
+ checked.forEach((document, index2) => {
142174
+ if (typeof document?.text !== "string") invalid(`documents[${index2}] needs "text", the SysML text to validate.`);
142175
+ if (document.text.length > maxCharacters) {
142176
+ invalid(`documents[${index2}] has ${document.text.length} characters, more than the ${maxCharacters} allowed (sysml.experimental.validateText.maxCharacters).`);
142177
+ }
142178
+ totalCharacters += document.text.length;
142179
+ if (totalCharacters > maxTotalCharacters) {
142180
+ invalid(`${totalCharacters} total characters, more than the ${maxTotalCharacters} allowed (sysml.experimental.validateText.maxTotalCharacters).`);
142181
+ }
142182
+ const lines = lineCount(document.text);
142183
+ if (lines > maxLines) {
142184
+ invalid(`documents[${index2}] has ${lines} lines, more than the ${maxLines} allowed (sysml.experimental.validateText.maxLines).`);
142185
+ }
142186
+ if (!isUri(document.uri)) invalid(`documents[${index2}] needs "uri", the document the text is the content of.`);
142187
+ const earlier = checked.findIndex((other) => isSameDocumentUri(other.uri, document.uri));
142188
+ if (earlier !== index2) invalid(`documents[${earlier}] and documents[${index2}] name the same document.`);
142189
+ });
142190
+ return checked;
142191
+ }
142192
+ /** The syntax, keyword and semantic diagnostics of the document at `uri`, as published for an open document. */
142193
+ diagnose(uri) {
142194
+ const diagnostics = new DiagnosticsProvider(this.documentManager).getDiagnostics(uri);
142195
+ const parseResult = this.documentManager.get(uri);
142196
+ if (parseResult) diagnostics.push(...validateKeywords(parseResult));
142197
+ diagnostics.push(...this.semanticValidator.validate(uri));
142198
+ return diagnostics.filter(this.isReported);
142199
+ }
142200
+ /** The spelling under which the server knows the document `uri` names, else `uri` itself (see `isSameDocumentUri`). */
142201
+ knownSpelling(uri) {
142202
+ return this.documentManager.getUris().find((known) => isSameDocumentUri(known, uri)) ?? uri;
142203
+ }
142204
+ };
142205
+ function lineCount(text) {
142206
+ const breaks = text.match(/\r\n|\r|\n/g)?.length ?? 0;
142207
+ return text === "" || /[\r\n]$/.test(text) ? breaks : breaks + 1;
142208
+ }
142209
+ function isUri(value) {
142210
+ return typeof value === "string" && value.trim() !== "";
142211
+ }
142212
+ function invalid(message) {
142213
+ throw new import_node13.ResponseError(import_node13.ErrorCodes.InvalidParams, `sysml/validateText: ${message}`);
142214
+ }
142215
+
141886
142216
  // server/src/platform/shims/fs-promises.ts
141887
142217
  async function readFile(_path, _enc) {
141888
142218
  throw new Error("fs/promises.readFile is not available in the browser");
@@ -141963,7 +142293,7 @@ ${info.documentation}`);
141963
142293
  return void 0;
141964
142294
  }
141965
142295
  var connection = createServerConnection();
141966
- var documents = new import_node11.TextDocuments(TextDocument2);
142296
+ var documents = new import_node14.TextDocuments(TextDocument2);
141967
142297
  var serverStartTime = Date.now();
141968
142298
  var documentManager = new DocumentManager();
141969
142299
  var modelProvider = new SysMLModelProvider(documentManager);
@@ -141980,6 +142310,7 @@ ${info.documentation}`);
141980
142310
  var codeActionProvider = new CodeActionProvider(documentManager);
141981
142311
  var formattingProvider = new FormattingProvider(documents);
141982
142312
  var semanticValidator = new SemanticValidator(documentManager);
142313
+ var textValidationProvider = new TextValidationProvider(documentManager, semanticValidator, isReported);
141983
142314
  hoverProvider.setSemanticValidator(semanticValidator);
141984
142315
  var hasConfigurationCapability = false;
141985
142316
  var hasWorkspaceFolderCapability = false;
@@ -141991,11 +142322,11 @@ ${info.documentation}`);
141991
142322
  var isWorkspaceFile = false;
141992
142323
  var preloadOnOpen = "workspaceOnly";
141993
142324
  var disabledDiagnosticCodes = /* @__PURE__ */ new Set();
142325
+ function isReported(diagnostic) {
142326
+ return diagnostic.code === void 0 || !disabledDiagnosticCodes.has(String(diagnostic.code));
142327
+ }
141994
142328
  function publishDiagnostics(uri, diagnostics) {
141995
- connection.sendDiagnostics({
141996
- uri,
141997
- diagnostics: diagnostics.filter((diagnostic) => diagnostic.code === void 0 || !disabledDiagnosticCodes.has(String(diagnostic.code)))
141998
- });
142329
+ connection.sendDiagnostics({ uri, diagnostics: diagnostics.filter(isReported) });
141999
142330
  }
142000
142331
  var skipDirs = new Set(DEFAULT_SKIP_DIRS);
142001
142332
  var serverReady = false;
@@ -142128,7 +142459,7 @@ ${info.documentation}`);
142128
142459
  };
142129
142460
  const result = {
142130
142461
  capabilities: {
142131
- textDocumentSync: import_node11.TextDocumentSyncKind.Incremental,
142462
+ textDocumentSync: import_node14.TextDocumentSyncKind.Incremental,
142132
142463
  // Completion
142133
142464
  completionProvider: {
142134
142465
  resolveProvider: true,
@@ -142156,7 +142487,7 @@ ${info.documentation}`);
142156
142487
  // Code actions (quick fixes)
142157
142488
  codeActionProvider: {
142158
142489
  codeActionKinds: [
142159
- import_node11.CodeActionKind.QuickFix
142490
+ import_node14.CodeActionKind.QuickFix
142160
142491
  ]
142161
142492
  },
142162
142493
  // Document formatting
@@ -142177,7 +142508,7 @@ ${info.documentation}`);
142177
142508
  connection.onInitialized(async () => {
142178
142509
  if (hasConfigurationCapability) {
142179
142510
  connection.client.register(
142180
- import_node11.DidChangeConfigurationNotification.type,
142511
+ import_node14.DidChangeConfigurationNotification.type,
142181
142512
  void 0
142182
142513
  );
142183
142514
  }
@@ -142238,6 +142569,8 @@ ${info.documentation}`);
142238
142569
  const validation = await connection.workspace.getConfiguration("sysml.validation");
142239
142570
  const codes = validation?.disabledCodes;
142240
142571
  disabledDiagnosticCodes = new Set(Array.isArray(codes) ? codes.filter((code) => typeof code === "string") : []);
142572
+ const experimental = await connection.workspace.getConfiguration("sysml.experimental");
142573
+ textValidationProvider.configure(readTextValidationSettings(experimental?.validateText));
142241
142574
  }
142242
142575
  function applySettings(config) {
142243
142576
  if (!config) return;
@@ -142591,6 +142924,10 @@ ${info.documentation}`);
142591
142924
  await initialization;
142592
142925
  return elementLookupProvider.elementLookup(params);
142593
142926
  });
142927
+ connection.onRequest("sysml/validateText", async (params) => {
142928
+ await initialization;
142929
+ return textValidationProvider.validate(params);
142930
+ });
142594
142931
  connection.onRequest("sysml/serverStats", () => {
142595
142932
  const mem = typeof process !== "undefined" && typeof process.memoryUsage === "function" ? process.memoryUsage() : { heapUsed: 0, heapTotal: 0, rss: 0, external: 0 };
142596
142933
  const toMB = (bytes) => Math.round(bytes / 1024 / 1024);