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 +22 -0
- package/dist/BusyStatusTracker.d.ts +31 -0
- package/dist/BusyStatusTracker.js +83 -0
- package/dist/BusyStatusTracker.js.map +1 -0
- package/dist/DiagnosticCollection.js +8 -5
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/LanguageServer.d.ts +21 -0
- package/dist/LanguageServer.js +124 -51
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +3 -2
- package/dist/Logger.js +10 -2
- package/dist/Logger.js.map +1 -1
- package/dist/Program.js +4 -1
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.js +1 -1
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Throttler.d.ts +12 -0
- package/dist/Throttler.js +39 -0
- package/dist/Throttler.js.map +1 -1
- package/dist/cli.js +95 -13
- package/dist/cli.js.map +1 -1
- package/dist/deferred.d.ts +1 -1
- package/dist/deferred.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +4 -0
- package/dist/util.js +1 -1
- package/dist/util.js.map +1 -1
- package/package.json +3 -2
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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":";;;
|
|
1
|
+
{"version":3,"file":"DiagnosticCollection.js","sourceRoot":"","sources":["../src/DiagnosticCollection.ts"],"names":[],"mappings":"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"}
|
package/dist/LanguageServer.d.ts
CHANGED
|
@@ -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
|
+
}
|
package/dist/LanguageServer.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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((
|
|
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
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|