brighterscript 0.65.1 → 0.65.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
 
8
8
 
9
+ ## [0.65.3](https://github.com/rokucommunity/brighterscript/compare/v0.65.2...0.65.3) - 2023-07-22
10
+ ### Changed
11
+ - Show busy spinner for lsp builds. Remove `build-status` event in favor of new `busy-status` ([#852](https://github.com/rokucommunity/brighterscript/pull/852))
12
+ - upgrade to [roku-deploy@3.10.3](https://github.com/rokucommunity/roku-deploy/blob/master/CHANGELOG.md#3103---2023-07-22). Notable changes since 3.10.2:
13
+ - Bump word-wrap from 1.2.3 to 1.2.4 ([roku-deploy#117](https://github.com/rokucommunity/roku-deploy/pull/117))
14
+ - Bump word-wrap from 1.2.3 to 1.2.4 ([#851](https://github.com/rokucommunity/brighterscript/pull/851))
15
+
16
+
17
+
18
+ ## [0.65.2](https://github.com/rokucommunity/brighterscript/compare/v0.65.1...v0.65.2) - 2023-07-17
19
+ ### Added
20
+ - beforeProgramDispose event ([#844](https://github.com/rokucommunity/brighterscript/pull/844)), ([#845](https://github.com/rokucommunity/brighterscript/pull/845))
21
+ - profiling support to the cli via the `--profile` flag ([#833](https://github.com/rokucommunity/brighterscript/pull/833))
22
+ ### Changed
23
+ - Make component ready on afterScopeCreate ([#843](https://github.com/rokucommunity/brighterscript/pull/843))
24
+ - Add project index to language server log entries ([#836](https://github.com/rokucommunity/brighterscript/pull/836))
25
+ - Prevent crashing when diagnostic is missing range. ([#832](https://github.com/rokucommunity/brighterscript/pull/832))
26
+ - Prevent crash when diagnostic is missing range ([#831](https://github.com/rokucommunity/brighterscript/pull/831))
27
+ - Add baseline interface docs ([#829](https://github.com/rokucommunity/brighterscript/pull/829))
28
+
29
+
30
+
9
31
  ## [0.65.1](https://github.com/rokucommunity/brighterscript/compare/v0.65.0...v0.65.1) - 2023-06-09
10
32
  ### Fixed
11
33
  - injection of duplicate super calls into classes ([#823](https://github.com/rokucommunity/brighterscript/pull/823))
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tracks the busy/idle status of various sync or async tasks
3
+ * Reports the overall status to the client
4
+ */
5
+ export declare class BusyStatusTracker {
6
+ /**
7
+ * @readonly
8
+ */
9
+ activeRuns: Set<{
10
+ label?: string;
11
+ startTime?: Date;
12
+ }>;
13
+ /**
14
+ * Start a new piece of work
15
+ */
16
+ run<T, R = T | Promise<T>>(callback: (finalize?: FinalizeBuildStatusRun) => R, label?: string): R;
17
+ private emitter;
18
+ on(eventName: 'change', handler: (status: BusyStatus) => void): () => void;
19
+ private emit;
20
+ destroy(): void;
21
+ /**
22
+ * The current status of the busy tracker.
23
+ * @readonly
24
+ */
25
+ get status(): BusyStatus;
26
+ }
27
+ export declare type FinalizeBuildStatusRun = (status?: BusyStatus) => void;
28
+ export declare enum BusyStatus {
29
+ busy = "busy",
30
+ idle = "idle"
31
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BusyStatus = exports.BusyStatusTracker = void 0;
4
+ const eventemitter3_1 = require("eventemitter3");
5
+ /**
6
+ * Tracks the busy/idle status of various sync or async tasks
7
+ * Reports the overall status to the client
8
+ */
9
+ class BusyStatusTracker {
10
+ constructor() {
11
+ /**
12
+ * @readonly
13
+ */
14
+ this.activeRuns = new Set();
15
+ this.emitter = new eventemitter3_1.EventEmitter();
16
+ }
17
+ /**
18
+ * Start a new piece of work
19
+ */
20
+ run(callback, label) {
21
+ const run = {
22
+ label: label,
23
+ startTime: new Date()
24
+ };
25
+ this.activeRuns.add(run);
26
+ if (this.activeRuns.size === 1) {
27
+ this.emit('change', BusyStatus.busy);
28
+ }
29
+ let isFinalized = false;
30
+ const finalizeRun = () => {
31
+ if (isFinalized === false) {
32
+ isFinalized = true;
33
+ this.activeRuns.delete(run);
34
+ if (this.activeRuns.size <= 0) {
35
+ this.emit('change', BusyStatus.idle);
36
+ }
37
+ }
38
+ };
39
+ let result;
40
+ //call the callback function
41
+ try {
42
+ result = callback(finalizeRun);
43
+ //if the result is a promise, don't finalize until it completes
44
+ if (typeof (result === null || result === void 0 ? void 0 : result.then) === 'function') {
45
+ return Promise.resolve(result).finally(finalizeRun).then(() => result);
46
+ }
47
+ else {
48
+ finalizeRun();
49
+ return result;
50
+ }
51
+ }
52
+ catch (e) {
53
+ finalizeRun();
54
+ throw e;
55
+ }
56
+ }
57
+ on(eventName, handler) {
58
+ this.emitter.on(eventName, handler);
59
+ return () => {
60
+ this.emitter.off(eventName, handler);
61
+ };
62
+ }
63
+ emit(eventName, value) {
64
+ this.emitter.emit(eventName, value);
65
+ }
66
+ destroy() {
67
+ this.emitter.removeAllListeners();
68
+ }
69
+ /**
70
+ * The current status of the busy tracker.
71
+ * @readonly
72
+ */
73
+ get status() {
74
+ return this.activeRuns.size === 0 ? BusyStatus.idle : BusyStatus.busy;
75
+ }
76
+ }
77
+ exports.BusyStatusTracker = BusyStatusTracker;
78
+ var BusyStatus;
79
+ (function (BusyStatus) {
80
+ BusyStatus["busy"] = "busy";
81
+ BusyStatus["idle"] = "idle";
82
+ })(BusyStatus = exports.BusyStatus || (exports.BusyStatus = {}));
83
+ //# sourceMappingURL=BusyStatusTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BusyStatusTracker.js","sourceRoot":"","sources":["../src/BusyStatusTracker.ts"],"names":[],"mappings":";;;AAAA,iDAA6C;AAE7C;;;GAGG;AACH,MAAa,iBAAiB;IAA9B;QACI;;WAEG;QACI,eAAU,GAAG,IAAI,GAAG,EAGvB,CAAC;QA4CG,YAAO,GAAG,IAAI,4BAAY,EAAsB,CAAC;IAwB7D,CAAC;IAlEG;;OAEG;IACI,GAAG,CAAwB,QAAkD,EAAE,KAAc;QAChG,MAAM,GAAG,GAAG;YACR,KAAK,EAAE,KAAK;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE;SACxB,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEzB,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;SACxC;QAED,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,MAAM,WAAW,GAAG,GAAG,EAAE;YACrB,IAAI,WAAW,KAAK,KAAK,EAAE;gBACvB,WAAW,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,EAAE;oBAC3B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;iBACxC;aACJ;QACL,CAAC,CAAC;QAEF,IAAI,MAA0B,CAAC;QAC/B,4BAA4B;QAC5B,IAAI;YACA,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC/B,+DAA+D;YAC/D,IAAI,OAAO,CAAC,MAAc,aAAd,MAAM,uBAAN,MAAM,CAAU,IAAI,CAAA,KAAK,UAAU,EAAE;gBAC7C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAQ,CAAC;aACjF;iBAAM;gBACH,WAAW,EAAE,CAAC;gBACd,OAAO,MAAM,CAAC;aACjB;SACJ;QAAC,OAAO,CAAC,EAAE;YACR,WAAW,EAAE,CAAC;YACd,MAAM,CAAC,CAAC;SACX;IACL,CAAC;IAIM,EAAE,CAAC,SAAmB,EAAE,OAAqC;QAChE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,GAAG,EAAE;YACR,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC;IACN,CAAC;IAEO,IAAI,CAAC,SAAmB,EAAE,KAAiB;QAC/C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;IACtC,CAAC;IAED;;;OAGG;IACH,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;IAC1E,CAAC;CACJ;AA3ED,8CA2EC;AAID,IAAY,UAGX;AAHD,WAAY,UAAU;IAClB,2BAAa,CAAA;IACb,2BAAa,CAAA;AACjB,CAAC,EAHW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAGrB"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DiagnosticCollection = void 0;
4
+ const util_1 = require("./util");
4
5
  class DiagnosticCollection {
5
6
  constructor() {
6
7
  this.previousDiagnosticsByFile = {};
@@ -13,7 +14,7 @@ class DiagnosticCollection {
13
14
  return patch;
14
15
  }
15
16
  getDiagnosticsByFileFromProjects(projects) {
16
- var _a;
17
+ var _a, _b;
17
18
  const result = {};
18
19
  //get all diagnostics for all projects
19
20
  let diagnostics = Array.prototype.concat.apply([], projects.map((x) => x.builder.getDiagnostics()));
@@ -26,13 +27,15 @@ class DiagnosticCollection {
26
27
  result[srcPath] = [];
27
28
  }
28
29
  const diagnosticMap = result[srcPath];
30
+ //fall back to a default range if missing
31
+ const range = (_b = diagnostic === null || diagnostic === void 0 ? void 0 : diagnostic.range) !== null && _b !== void 0 ? _b : util_1.util.createRange(0, 0, 0, 0);
29
32
  diagnostic.key =
30
33
  srcPath.toLowerCase() + '-' +
31
34
  diagnostic.code + '-' +
32
- diagnostic.range.start.line + '-' +
33
- diagnostic.range.start.character + '-' +
34
- diagnostic.range.end.line + '-' +
35
- diagnostic.range.end.character +
35
+ range.start.line + '-' +
36
+ range.start.character + '-' +
37
+ range.end.line + '-' +
38
+ range.end.character +
36
39
  diagnostic.message;
37
40
  //don't include duplicates
38
41
  if (!keys[diagnostic.key]) {
@@ -1 +1 @@
1
- {"version":3,"file":"DiagnosticCollection.js","sourceRoot":"","sources":["../src/DiagnosticCollection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DiagnosticCollection.js","sourceRoot":"","sources":["../src/DiagnosticCollection.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import type { InitializeParams, ServerCapabilities, ExecuteCommandParams, Worksp
3
3
  import { FileChangeType } from 'vscode-languageserver/node';
4
4
  import { ProgramBuilder } from './ProgramBuilder';
5
5
  import { Throttler } from './Throttler';
6
+ import { BusyStatusTracker } from './BusyStatusTracker';
6
7
  export declare class LanguageServer {
7
8
  private connection;
8
9
  projects: Project[];
@@ -34,7 +35,10 @@ export declare class LanguageServer {
34
35
  private sendDiagnosticsThrottler;
35
36
  private boundValidateAll;
36
37
  private validateAllThrottled;
38
+ busyStatusTracker: BusyStatusTracker;
37
39
  run(): void;
40
+ private busyStatusIndex;
41
+ private sendBusyStatus;
38
42
  /**
39
43
  * Called when the client starts initialization
40
44
  */
@@ -80,6 +84,15 @@ export declare class LanguageServer {
80
84
  */
81
85
  private documentFileResolver;
82
86
  private getConfigFilePath;
87
+ /**
88
+ * A unique project counter to help distinguish log entries in lsp mode
89
+ */
90
+ private projectCounter;
91
+ /**
92
+ * @param projectPath path to the project
93
+ * @param workspacePath path to the workspace in which all project should reside or are referenced by
94
+ * @param projectNumber an optional project number to assign to the project. Used when reloading projects that should keep the same number
95
+ */
83
96
  private createProject;
84
97
  private createStandaloneFileProject;
85
98
  private getProjects;
@@ -139,6 +152,7 @@ export declare class LanguageServer {
139
152
  private onDefinition;
140
153
  private onSignatureHelp;
141
154
  private onReferences;
155
+ private onValidateSettled;
142
156
  private onFullSemanticTokens;
143
157
  private diagnosticCollection;
144
158
  private sendDiagnostics;
@@ -147,6 +161,10 @@ export declare class LanguageServer {
147
161
  dispose(): void;
148
162
  }
149
163
  export interface Project {
164
+ /**
165
+ * A unique number for this project, generated during this current language server session. Mostly used so we can identify which project is doing logging
166
+ */
167
+ projectNumber: number;
150
168
  firstRunPromise: Promise<any>;
151
169
  builder: ProgramBuilder;
152
170
  /**
@@ -165,3 +183,6 @@ export interface Project {
165
183
  export declare enum CustomCommands {
166
184
  TranspileFile = "TranspileFile"
167
185
  }
186
+ export declare enum NotificationName {
187
+ busyStatus = "busyStatus"
188
+ }
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.CustomCommands = exports.LanguageServer = void 0;
9
+ exports.NotificationName = exports.CustomCommands = exports.LanguageServer = void 0;
10
10
  require("array-flat-polyfill");
11
11
  const fastGlob = require("fast-glob");
12
12
  const path = require("path");
@@ -24,6 +24,7 @@ const KeyedThrottler_1 = require("./KeyedThrottler");
24
24
  const DiagnosticCollection_1 = require("./DiagnosticCollection");
25
25
  const reflection_1 = require("./astUtils/reflection");
26
26
  const SemanticTokenUtils_1 = require("./SemanticTokenUtils");
27
+ const BusyStatusTracker_1 = require("./BusyStatusTracker");
27
28
  class LanguageServer {
28
29
  constructor() {
29
30
  this.connection = undefined;
@@ -53,6 +54,12 @@ class LanguageServer {
53
54
  this.validateThrottler = new Throttler_1.Throttler(0);
54
55
  this.sendDiagnosticsThrottler = new Throttler_1.Throttler(0);
55
56
  this.boundValidateAll = this.validateAll.bind(this);
57
+ this.busyStatusTracker = new BusyStatusTracker_1.BusyStatusTracker();
58
+ this.busyStatusIndex = -1;
59
+ /**
60
+ * A unique project counter to help distinguish log entries in lsp mode
61
+ */
62
+ this.projectCounter = 0;
56
63
  this.diagnosticCollection = new DiagnosticCollection_1.DiagnosticCollection();
57
64
  }
58
65
  createConnection() {
@@ -66,6 +73,10 @@ class LanguageServer {
66
73
  // Create a connection for the server. The connection uses Node's IPC as a transport.
67
74
  // Also include all preview / proposed LSP features.
68
75
  this.connection = this.createConnection();
76
+ // Send the current status of the busyStatusTracker anytime it changes
77
+ this.busyStatusTracker.on('change', (status) => {
78
+ this.sendBusyStatus(status);
79
+ });
69
80
  //listen to all of the output log events and pipe them into the debug channel in the extension
70
81
  this.loggerSubscription = Logger_1.Logger.subscribe((text) => {
71
82
  this.connection.tracer.log(text);
@@ -120,6 +131,15 @@ class LanguageServer {
120
131
  // Listen on the connection
121
132
  this.connection.listen();
122
133
  }
134
+ sendBusyStatus(status) {
135
+ this.busyStatusIndex = ++this.busyStatusIndex <= 0 ? 0 : this.busyStatusIndex;
136
+ this.connection.sendNotification(NotificationName.busyStatus, {
137
+ status: status,
138
+ timestamp: Date.now(),
139
+ index: this.busyStatusIndex,
140
+ activeRuns: [...this.busyStatusTracker.activeRuns]
141
+ });
142
+ }
123
143
  /**
124
144
  * Called when the client starts initialization
125
145
  */
@@ -322,7 +342,6 @@ class LanguageServer {
322
342
  if (waitForFirstProject) {
323
343
  await this.initialProjectsCreated;
324
344
  }
325
- let status;
326
345
  for (let project of this.getProjects()) {
327
346
  try {
328
347
  await project.firstRunPromise;
@@ -335,7 +354,6 @@ class LanguageServer {
335
354
  this.sendCriticalFailure(`BrighterScript language server failed to start: \n${e.message}`);
336
355
  }
337
356
  }
338
- this.connection.sendNotification('build-status', status ? status : 'success');
339
357
  }
340
358
  /**
341
359
  * Event handler for when the program wants to load file contents.
@@ -390,7 +408,12 @@ class LanguageServer {
390
408
  //no config file could be found
391
409
  return undefined;
392
410
  }
393
- async createProject(projectPath, workspacePath = projectPath) {
411
+ /**
412
+ * @param projectPath path to the project
413
+ * @param workspacePath path to the workspace in which all project should reside or are referenced by
414
+ * @param projectNumber an optional project number to assign to the project. Used when reloading projects that should keep the same number
415
+ */
416
+ async createProject(projectPath, workspacePath = projectPath, projectNumber) {
394
417
  workspacePath !== null && workspacePath !== void 0 ? workspacePath : (workspacePath = projectPath);
395
418
  let project = this.projects.find((x) => x.projectPath === projectPath);
396
419
  //skip this project if we already have it
@@ -398,6 +421,9 @@ class LanguageServer {
398
421
  return;
399
422
  }
400
423
  let builder = new ProgramBuilder_1.ProgramBuilder();
424
+ projectNumber !== null && projectNumber !== void 0 ? projectNumber : (projectNumber = this.projectCounter++);
425
+ builder.logger.prefix = `[prj${projectNumber}]`;
426
+ builder.logger.log(`Created project #${projectNumber} for: "${projectPath}"`);
401
427
  //flush diagnostics every time the program finishes validating
402
428
  builder.plugins.add({
403
429
  name: 'bsc-language-server',
@@ -419,21 +445,11 @@ class LanguageServer {
419
445
  //config file doesn't exist...let `brighterscript` resolve the default way
420
446
  configFilePath = undefined;
421
447
  }
422
- let firstRunPromise = builder.run({
423
- cwd: cwd,
424
- project: configFilePath,
425
- watch: false,
426
- createPackage: false,
427
- deploy: false,
428
- copyToStaging: false,
429
- showDiagnosticsInConsole: false
430
- });
431
- firstRunPromise.catch((err) => {
432
- console.error(err);
433
- });
448
+ const firstRunDeferred = new deferred_1.Deferred();
434
449
  let newProject = {
450
+ projectNumber: projectNumber,
435
451
  builder: builder,
436
- firstRunPromise: firstRunPromise,
452
+ firstRunPromise: firstRunDeferred.promise,
437
453
  projectPath: projectPath,
438
454
  workspacePath: workspacePath,
439
455
  isFirstRunComplete: false,
@@ -442,19 +458,31 @@ class LanguageServer {
442
458
  isStandaloneFileProject: false
443
459
  };
444
460
  this.projects.push(newProject);
445
- await firstRunPromise.then(() => {
461
+ try {
462
+ await builder.run({
463
+ cwd: cwd,
464
+ project: configFilePath,
465
+ watch: false,
466
+ createPackage: false,
467
+ deploy: false,
468
+ copyToStaging: false,
469
+ showDiagnosticsInConsole: false
470
+ });
446
471
  newProject.isFirstRunComplete = true;
447
472
  newProject.isFirstRunSuccessful = true;
448
- }).catch(() => {
473
+ firstRunDeferred.resolve();
474
+ }
475
+ catch (e) {
476
+ builder.logger.error(e);
477
+ firstRunDeferred.reject(e);
449
478
  newProject.isFirstRunComplete = true;
450
479
  newProject.isFirstRunSuccessful = false;
451
- }).then(() => {
452
- //if we found a deprecated brsconfig.json, add a diagnostic warning the user
453
- if (configFilePath && path.basename(configFilePath) === 'brsconfig.json') {
454
- builder.addDiagnostic(configFilePath, Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.brsConfigJsonIsDeprecated()), { range: util_1.util.createRange(0, 0, 0, 0) }));
455
- return this.sendDiagnostics();
456
- }
457
- });
480
+ }
481
+ //if we found a deprecated brsconfig.json, add a diagnostic warning the user
482
+ if (configFilePath && path.basename(configFilePath) === 'brsconfig.json') {
483
+ builder.addDiagnostic(configFilePath, Object.assign(Object.assign({}, DiagnosticMessages_1.DiagnosticMessages.brsConfigJsonIsDeprecated()), { range: util_1.util.createRange(0, 0, 0, 0) }));
484
+ return this.sendDiagnostics();
485
+ }
458
486
  }
459
487
  async createStandaloneFileProject(srcPath) {
460
488
  //skip this workspace if we already have it
@@ -487,6 +515,7 @@ class LanguageServer {
487
515
  console.error(err);
488
516
  });
489
517
  let newProject = {
518
+ projectNumber: this.projectCounter++,
490
519
  builder: builder,
491
520
  firstRunPromise: firstRunPromise,
492
521
  projectPath: srcPath,
@@ -588,7 +617,7 @@ class LanguageServer {
588
617
  if (project.isStandaloneFileProject === false) {
589
618
  this.removeProject(project);
590
619
  //create a new workspace/brs program
591
- await this.createProject(project.projectPath, project.workspacePath);
620
+ await this.createProject(project.projectPath, project.workspacePath, project.projectNumber);
592
621
  //handle temp workspace
593
622
  }
594
623
  else {
@@ -669,7 +698,6 @@ class LanguageServer {
669
698
  async onDidChangeWatchedFiles(params) {
670
699
  //ensure programs are initialized
671
700
  await this.waitAllProjectFirstRuns();
672
- this.connection.sendNotification('build-status', 'building');
673
701
  let projects = this.getProjects();
674
702
  //convert all file paths to absolute paths
675
703
  let changes = params.changes.map(x => {
@@ -738,7 +766,6 @@ class LanguageServer {
738
766
  //give every workspace the chance to handle file changes
739
767
  await Promise.all(projects.map((project) => this.handleFileChanges(project, changes)));
740
768
  }
741
- this.connection.sendNotification('build-status', 'success');
742
769
  }
743
770
  /**
744
771
  * This only operates on files that match the specified files globs, so it is safe to throw
@@ -863,7 +890,6 @@ class LanguageServer {
863
890
  //throttle file processing. first call is run immediately, and then the last call is processed.
864
891
  await this.keyedThrottler.run(filePath, () => {
865
892
  var _a;
866
- this.connection.sendNotification('build-status', 'building');
867
893
  let documentText = document.getText();
868
894
  for (const project of this.getProjects()) {
869
895
  //only add or replace existing files. All of the files in the project should
@@ -892,13 +918,15 @@ class LanguageServer {
892
918
  await this.synchronizeStandaloneProjects();
893
919
  let projects = this.getProjects();
894
920
  //validate all programs
895
- await Promise.all(projects.map((x) => x.builder.program.validate()));
921
+ await Promise.all(projects.map((project) => {
922
+ project.builder.program.validate();
923
+ return project;
924
+ }));
896
925
  }
897
926
  catch (e) {
898
927
  this.connection.console.error(e);
899
928
  this.sendCriticalFailure(`Critical error validating project: ${e.message}${(_a = e.stack) !== null && _a !== void 0 ? _a : ''}`);
900
929
  }
901
- this.connection.sendNotification('build-status', 'success');
902
930
  }
903
931
  async onWorkspaceSymbol(params) {
904
932
  await this.waitAllProjectFirstRuns();
@@ -966,15 +994,20 @@ class LanguageServer {
966
994
  })), c => c);
967
995
  return results.filter((r) => r);
968
996
  }
997
+ onValidateSettled() {
998
+ return Promise.all([
999
+ //wait for the validator to start running (or timeout if it never did)
1000
+ this.validateThrottler.onRunOnce(100),
1001
+ //wait for the validator to stop running (or resolve immediately if it's already idle)
1002
+ this.validateThrottler.onIdleOnce(true)
1003
+ ]);
1004
+ }
969
1005
  async onFullSemanticTokens(params) {
970
1006
  await this.waitAllProjectFirstRuns();
971
- await Promise.all([
972
- //wait for the file to settle (in case there are multiple file changes in quick succession)
973
- this.keyedThrottler.onIdleOnce(util_1.util.uriToPath(params.textDocument.uri), true),
974
- // wait for the validation to finish before providing semantic tokens. program.validate() populates and then caches AstNode.parent properties.
975
- // If we don't wait, then fetching semantic tokens can cause some invalid cache
976
- this.validateThrottler.onIdleOnce(false)
977
- ]);
1007
+ //wait for the file to settle (in case there are multiple file changes in quick succession)
1008
+ await this.keyedThrottler.onIdleOnce(util_1.util.uriToPath(params.textDocument.uri), true);
1009
+ //wait for the validation cycle to settle
1010
+ await this.onValidateSettled();
978
1011
  const srcPath = util_1.util.uriToPath(params.textDocument.uri);
979
1012
  for (const project of this.projects) {
980
1013
  //find the first program that has this file, since it would be incredibly inefficient to generate semantic tokens for the same file multiple times.
@@ -1031,22 +1064,35 @@ __decorate([
1031
1064
  AddStackToErrorMessage
1032
1065
  ], LanguageServer.prototype, "onInitialize", null);
1033
1066
  __decorate([
1034
- AddStackToErrorMessage
1067
+ TrackBusyStatus
1068
+ ], LanguageServer.prototype, "getProjectPaths", null);
1069
+ __decorate([
1070
+ TrackBusyStatus
1071
+ ], LanguageServer.prototype, "syncProjects", null);
1072
+ __decorate([
1073
+ AddStackToErrorMessage,
1074
+ TrackBusyStatus
1035
1075
  ], LanguageServer.prototype, "onInitialized", null);
1036
1076
  __decorate([
1037
- AddStackToErrorMessage
1077
+ TrackBusyStatus
1078
+ ], LanguageServer.prototype, "createProject", null);
1079
+ __decorate([
1080
+ AddStackToErrorMessage,
1081
+ TrackBusyStatus
1038
1082
  ], LanguageServer.prototype, "onCompletion", null);
1039
1083
  __decorate([
1040
1084
  AddStackToErrorMessage
1041
1085
  ], LanguageServer.prototype, "onCompletionResolve", null);
1042
1086
  __decorate([
1043
- AddStackToErrorMessage
1087
+ AddStackToErrorMessage,
1088
+ TrackBusyStatus
1044
1089
  ], LanguageServer.prototype, "onCodeAction", null);
1045
1090
  __decorate([
1046
1091
  AddStackToErrorMessage
1047
1092
  ], LanguageServer.prototype, "onDidChangeConfiguration", null);
1048
1093
  __decorate([
1049
- AddStackToErrorMessage
1094
+ AddStackToErrorMessage,
1095
+ TrackBusyStatus
1050
1096
  ], LanguageServer.prototype, "onDidChangeWatchedFiles", null);
1051
1097
  __decorate([
1052
1098
  AddStackToErrorMessage
@@ -1055,34 +1101,49 @@ __decorate([
1055
1101
  AddStackToErrorMessage
1056
1102
  ], LanguageServer.prototype, "onDocumentClose", null);
1057
1103
  __decorate([
1058
- AddStackToErrorMessage
1104
+ AddStackToErrorMessage,
1105
+ TrackBusyStatus
1059
1106
  ], LanguageServer.prototype, "validateTextDocument", null);
1060
1107
  __decorate([
1061
- AddStackToErrorMessage
1108
+ TrackBusyStatus
1109
+ ], LanguageServer.prototype, "validateAll", null);
1110
+ __decorate([
1111
+ AddStackToErrorMessage,
1112
+ TrackBusyStatus
1062
1113
  ], LanguageServer.prototype, "onWorkspaceSymbol", null);
1063
1114
  __decorate([
1064
- AddStackToErrorMessage
1115
+ AddStackToErrorMessage,
1116
+ TrackBusyStatus
1065
1117
  ], LanguageServer.prototype, "onDocumentSymbol", null);
1066
1118
  __decorate([
1067
- AddStackToErrorMessage
1119
+ AddStackToErrorMessage,
1120
+ TrackBusyStatus
1068
1121
  ], LanguageServer.prototype, "onDefinition", null);
1069
1122
  __decorate([
1070
- AddStackToErrorMessage
1123
+ AddStackToErrorMessage,
1124
+ TrackBusyStatus
1071
1125
  ], LanguageServer.prototype, "onSignatureHelp", null);
1072
1126
  __decorate([
1073
- AddStackToErrorMessage
1127
+ AddStackToErrorMessage,
1128
+ TrackBusyStatus
1074
1129
  ], LanguageServer.prototype, "onReferences", null);
1075
1130
  __decorate([
1076
- AddStackToErrorMessage
1131
+ AddStackToErrorMessage,
1132
+ TrackBusyStatus
1077
1133
  ], LanguageServer.prototype, "onFullSemanticTokens", null);
1078
1134
  __decorate([
1079
- AddStackToErrorMessage
1135
+ AddStackToErrorMessage,
1136
+ TrackBusyStatus
1080
1137
  ], LanguageServer.prototype, "onExecuteCommand", null);
1081
1138
  exports.LanguageServer = LanguageServer;
1082
1139
  var CustomCommands;
1083
1140
  (function (CustomCommands) {
1084
1141
  CustomCommands["TranspileFile"] = "TranspileFile";
1085
1142
  })(CustomCommands = exports.CustomCommands || (exports.CustomCommands = {}));
1143
+ var NotificationName;
1144
+ (function (NotificationName) {
1145
+ NotificationName["busyStatus"] = "busyStatus";
1146
+ })(NotificationName = exports.NotificationName || (exports.NotificationName = {}));
1086
1147
  /**
1087
1148
  * Wraps a method. If there's an error (either sync or via a promise),
1088
1149
  * this appends the error's stack trace at the end of the error message so that the connection will
@@ -1114,4 +1175,16 @@ function AddStackToErrorMessage(target, propertyKey, descriptor) {
1114
1175
  }
1115
1176
  };
1116
1177
  }
1178
+ /**
1179
+ * An annotation used to wrap the method in a busyStatus tracking call
1180
+ */
1181
+ function TrackBusyStatus(target, propertyKey, descriptor) {
1182
+ let originalMethod = descriptor.value;
1183
+ //wrapping the original method
1184
+ descriptor.value = function value(...args) {
1185
+ return this.busyStatusTracker.run(() => {
1186
+ return originalMethod.apply(this, args);
1187
+ }, originalMethod.name);
1188
+ };
1189
+ }
1117
1190
  //# sourceMappingURL=LanguageServer.js.map