brighterscript 1.0.0-alpha.44 → 1.0.0-alpha.45
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 +63 -0
- package/bsconfig.schema.json +6 -1
- package/dist/AstValidationSegmenter.js +6 -1
- package/dist/AstValidationSegmenter.js.map +1 -1
- package/dist/BsConfig.d.ts +4 -0
- package/dist/BusyStatusTracker.d.ts +37 -7
- package/dist/BusyStatusTracker.js +73 -8
- package/dist/BusyStatusTracker.js.map +1 -1
- package/dist/Cache.d.ts +0 -4
- package/dist/Cache.js +0 -6
- package/dist/Cache.js.map +1 -1
- package/dist/CrossScopeValidator.d.ts +1 -1
- package/dist/CrossScopeValidator.js +4 -4
- package/dist/CrossScopeValidator.js.map +1 -1
- package/dist/DiagnosticCollection.d.ts +19 -5
- package/dist/DiagnosticCollection.js +71 -23
- package/dist/DiagnosticCollection.js.map +1 -1
- package/dist/DiagnosticFilterer.d.ts +14 -1
- package/dist/DiagnosticFilterer.js +130 -12
- package/dist/DiagnosticFilterer.js.map +1 -1
- package/dist/DiagnosticManager.d.ts +11 -1
- package/dist/DiagnosticManager.js +192 -35
- package/dist/DiagnosticManager.js.map +1 -1
- package/dist/LanguageServer.d.ts +82 -139
- package/dist/LanguageServer.js +402 -980
- package/dist/LanguageServer.js.map +1 -1
- package/dist/Logger.d.ts +9 -4
- package/dist/Logger.js +30 -6
- package/dist/Logger.js.map +1 -1
- package/dist/PluginInterface.d.ts +8 -8
- package/dist/PluginInterface.js.map +1 -1
- package/dist/Program.d.ts +23 -4
- package/dist/Program.js +294 -194
- package/dist/Program.js.map +1 -1
- package/dist/ProgramBuilder.d.ts +22 -7
- package/dist/ProgramBuilder.js +44 -21
- package/dist/ProgramBuilder.js.map +1 -1
- package/dist/Scope.d.ts +11 -6
- package/dist/Scope.js +60 -36
- package/dist/Scope.js.map +1 -1
- package/dist/SemanticTokenUtils.js +1 -1
- package/dist/SemanticTokenUtils.js.map +1 -1
- package/dist/astUtils/reflection.d.ts +4 -4
- package/dist/astUtils/reflection.js +12 -10
- package/dist/astUtils/reflection.js.map +1 -1
- package/dist/bscPlugin/BscPlugin.d.ts +3 -3
- package/dist/bscPlugin/BscPlugin.js.map +1 -1
- package/dist/bscPlugin/CallExpressionInfo.js +4 -2
- package/dist/bscPlugin/CallExpressionInfo.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.d.ts +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.js +15 -15
- package/dist/bscPlugin/completions/CompletionsProcessor.js.map +1 -1
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js +82 -5
- package/dist/bscPlugin/completions/CompletionsProcessor.spec.js.map +1 -1
- package/dist/bscPlugin/hover/HoverProcessor.js +3 -0
- package/dist/bscPlugin/hover/HoverProcessor.js.map +1 -1
- package/dist/bscPlugin/validation/ScopeValidator.d.ts +4 -1
- package/dist/bscPlugin/validation/ScopeValidator.js +161 -61
- package/dist/bscPlugin/validation/ScopeValidator.js.map +1 -1
- package/dist/common/Sequencer.d.ts +53 -0
- package/dist/common/Sequencer.js +232 -0
- package/dist/common/Sequencer.js.map +1 -0
- package/dist/common/Sequencer.spec.d.ts +1 -0
- package/dist/common/Sequencer.spec.js +75 -0
- package/dist/common/Sequencer.spec.js.map +1 -0
- package/dist/deferred.d.ts +2 -0
- package/dist/deferred.js +10 -0
- package/dist/deferred.js.map +1 -1
- package/dist/examples/plugins/removePrint.d.ts +2 -2
- package/dist/examples/plugins/removePrint.js.map +1 -1
- package/dist/files/BrsFile.d.ts +1 -1
- package/dist/files/BrsFile.js +11 -40
- package/dist/files/BrsFile.js.map +1 -1
- package/dist/files/BrsFile.spec.js +51 -2
- package/dist/files/BrsFile.spec.js.map +1 -1
- package/dist/files/BscFile.d.ts +1 -0
- package/dist/files/LazyFileData.d.ts +1 -0
- package/dist/files/XmlFile.spec.js +1 -1
- package/dist/files/XmlFile.spec.js.map +1 -1
- package/dist/globalCallables.js +186 -186
- package/dist/globalCallables.js.map +1 -1
- package/dist/interfaces.d.ts +56 -13
- package/dist/interfaces.js.map +1 -1
- package/dist/lexer/Lexer.js +1 -1
- package/dist/lexer/Lexer.js.map +1 -1
- package/dist/logging.d.ts +6 -1
- package/dist/logging.js +14 -1
- package/dist/logging.js.map +1 -1
- package/dist/lsp/ActionQueue.d.ts +35 -0
- package/dist/lsp/ActionQueue.js +115 -0
- package/dist/lsp/ActionQueue.js.map +1 -0
- package/dist/lsp/ActionQueue.spec.d.ts +1 -0
- package/dist/lsp/ActionQueue.spec.js +80 -0
- package/dist/lsp/ActionQueue.spec.js.map +1 -0
- package/dist/lsp/DocumentManager.d.ts +63 -0
- package/dist/lsp/DocumentManager.js +122 -0
- package/dist/lsp/DocumentManager.js.map +1 -0
- package/dist/lsp/DocumentManager.spec.d.ts +1 -0
- package/dist/lsp/DocumentManager.spec.js +103 -0
- package/dist/lsp/DocumentManager.spec.js.map +1 -0
- package/dist/lsp/LspProject.d.ts +231 -0
- package/dist/lsp/LspProject.js +3 -0
- package/dist/lsp/LspProject.js.map +1 -0
- package/dist/lsp/PathFilterer.d.ts +75 -0
- package/dist/lsp/PathFilterer.js +196 -0
- package/dist/lsp/PathFilterer.js.map +1 -0
- package/dist/lsp/PathFilterer.spec.d.ts +1 -0
- package/dist/lsp/PathFilterer.spec.js +182 -0
- package/dist/lsp/PathFilterer.spec.js.map +1 -0
- package/dist/lsp/Project.d.ts +167 -0
- package/dist/lsp/Project.js +432 -0
- package/dist/lsp/Project.js.map +1 -0
- package/dist/lsp/Project.spec.d.ts +1 -0
- package/dist/lsp/Project.spec.js +220 -0
- package/dist/lsp/Project.spec.js.map +1 -0
- package/dist/lsp/ProjectManager.d.ts +221 -0
- package/dist/lsp/ProjectManager.js +735 -0
- package/dist/lsp/ProjectManager.js.map +1 -0
- package/dist/lsp/ProjectManager.spec.d.ts +1 -0
- package/dist/lsp/ProjectManager.spec.js +757 -0
- package/dist/lsp/ProjectManager.spec.js.map +1 -0
- package/dist/lsp/ReaderWriterManager.d.ts +21 -0
- package/dist/lsp/ReaderWriterManager.js +60 -0
- package/dist/lsp/ReaderWriterManager.js.map +1 -0
- package/dist/lsp/worker/MessageHandler.d.ts +99 -0
- package/dist/lsp/worker/MessageHandler.js +138 -0
- package/dist/lsp/worker/MessageHandler.js.map +1 -0
- package/dist/lsp/worker/MessageHandler.spec.d.ts +1 -0
- package/dist/lsp/worker/MessageHandler.spec.js +64 -0
- package/dist/lsp/worker/MessageHandler.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerPool.d.ts +38 -0
- package/dist/lsp/worker/WorkerPool.js +78 -0
- package/dist/lsp/worker/WorkerPool.js.map +1 -0
- package/dist/lsp/worker/WorkerPool.spec.d.ts +1 -0
- package/dist/lsp/worker/WorkerPool.spec.js +59 -0
- package/dist/lsp/worker/WorkerPool.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProject.d.ts +144 -0
- package/dist/lsp/worker/WorkerThreadProject.js +183 -0
- package/dist/lsp/worker/WorkerThreadProject.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.d.ts +2 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.js +68 -0
- package/dist/lsp/worker/WorkerThreadProject.spec.js.map +1 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.d.ts +15 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.js +58 -0
- package/dist/lsp/worker/WorkerThreadProjectRunner.js.map +1 -0
- package/dist/parser/Expression.js +7 -2
- package/dist/parser/Expression.js.map +1 -1
- package/dist/parser/Parser.spec.js +12 -0
- package/dist/parser/Parser.spec.js.map +1 -1
- package/dist/parser/Statement.js +2 -2
- package/dist/parser/Statement.js.map +1 -1
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js +51 -5
- package/dist/parser/tests/expression/TemplateStringExpression.spec.js.map +1 -1
- package/dist/roku-types/data.json +745 -751
- package/dist/types/BooleanType.d.ts +0 -2
- package/dist/types/BooleanType.js +4 -6
- package/dist/types/BooleanType.js.map +1 -1
- package/dist/types/BscType.js +5 -0
- package/dist/types/BscType.js.map +1 -1
- package/dist/types/BuiltInInterfaceAdder.d.ts +1 -0
- package/dist/types/BuiltInInterfaceAdder.js +24 -17
- package/dist/types/BuiltInInterfaceAdder.js.map +1 -1
- package/dist/types/DoubleType.d.ts +0 -2
- package/dist/types/DoubleType.js +4 -6
- package/dist/types/DoubleType.js.map +1 -1
- package/dist/types/DynamicType.d.ts +0 -2
- package/dist/types/DynamicType.js +3 -5
- package/dist/types/DynamicType.js.map +1 -1
- package/dist/types/FloatType.d.ts +0 -2
- package/dist/types/FloatType.js +4 -6
- package/dist/types/FloatType.js.map +1 -1
- package/dist/types/FunctionType.d.ts +0 -2
- package/dist/types/FunctionType.js +5 -7
- package/dist/types/FunctionType.js.map +1 -1
- package/dist/types/IntegerType.d.ts +0 -2
- package/dist/types/IntegerType.js +4 -6
- package/dist/types/IntegerType.js.map +1 -1
- package/dist/types/LongIntegerType.d.ts +0 -2
- package/dist/types/LongIntegerType.js +4 -6
- package/dist/types/LongIntegerType.js.map +1 -1
- package/dist/types/ObjectType.d.ts +3 -3
- package/dist/types/ObjectType.js +6 -8
- package/dist/types/ObjectType.js.map +1 -1
- package/dist/types/StringType.d.ts +0 -2
- package/dist/types/StringType.js +4 -6
- package/dist/types/StringType.js.map +1 -1
- package/dist/types/VoidType.d.ts +0 -2
- package/dist/types/VoidType.js +4 -6
- package/dist/types/VoidType.js.map +1 -1
- package/dist/types/helpers.d.ts +4 -0
- package/dist/types/helpers.js +5 -1
- package/dist/types/helpers.js.map +1 -1
- package/dist/util.d.ts +44 -16
- package/dist/util.js +196 -70
- package/dist/util.js.map +1 -1
- package/dist/validators/ClassValidator.js +2 -2
- package/dist/validators/ClassValidator.js.map +1 -1
- package/package.json +15 -5
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const chai_1 = require("chai");
|
|
4
|
+
const ActionQueue_1 = require("./ActionQueue");
|
|
5
|
+
const util_1 = require("../util");
|
|
6
|
+
const deferred_1 = require("../deferred");
|
|
7
|
+
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
8
|
+
describe('ActionQueue', () => {
|
|
9
|
+
let queue;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
queue = new ActionQueue_1.ActionQueue();
|
|
12
|
+
});
|
|
13
|
+
it('runs successful actions in sequence', async () => {
|
|
14
|
+
let results = [];
|
|
15
|
+
void queue.run(() => {
|
|
16
|
+
results.push(1);
|
|
17
|
+
});
|
|
18
|
+
await queue.run(() => {
|
|
19
|
+
results.push(2);
|
|
20
|
+
});
|
|
21
|
+
(0, chai_1.expect)(results).to.eql([1, 2]);
|
|
22
|
+
});
|
|
23
|
+
it('runs actions after a failed action', async () => {
|
|
24
|
+
let results = [];
|
|
25
|
+
void queue.run(() => {
|
|
26
|
+
results.push(1);
|
|
27
|
+
});
|
|
28
|
+
void queue.run(() => {
|
|
29
|
+
throw new Error('Crash');
|
|
30
|
+
});
|
|
31
|
+
await queue.run(() => {
|
|
32
|
+
results.push(3);
|
|
33
|
+
});
|
|
34
|
+
(0, chai_1.expect)(results).to.eql([1, 3]);
|
|
35
|
+
});
|
|
36
|
+
it('properly serializes bigInt', async () => {
|
|
37
|
+
queue = new ActionQueue_1.ActionQueue({
|
|
38
|
+
maxActionDuration: 1
|
|
39
|
+
});
|
|
40
|
+
await (0, testHelpers_spec_1.expectThrowsAsync)(async () => {
|
|
41
|
+
await queue.run(async () => {
|
|
42
|
+
await util_1.default.sleep(10);
|
|
43
|
+
}, BigInt(1));
|
|
44
|
+
}, 'Action took longer than 1ms to complete. Data: "1"');
|
|
45
|
+
});
|
|
46
|
+
it('rejects action that took too long, and marks cancellationToken accordingly', async () => {
|
|
47
|
+
queue = new ActionQueue_1.ActionQueue({
|
|
48
|
+
maxActionDuration: 100
|
|
49
|
+
});
|
|
50
|
+
let cancellationToken;
|
|
51
|
+
let results = [];
|
|
52
|
+
let task1Deferred = new deferred_1.Deferred();
|
|
53
|
+
let task1Promise = queue.run(async (data, token) => {
|
|
54
|
+
await util_1.default.sleep(200);
|
|
55
|
+
cancellationToken = token;
|
|
56
|
+
if (!cancellationToken.isCancellationRequested) {
|
|
57
|
+
results.push(1);
|
|
58
|
+
}
|
|
59
|
+
task1Deferred.resolve();
|
|
60
|
+
});
|
|
61
|
+
await queue.run(() => {
|
|
62
|
+
results.push(2);
|
|
63
|
+
});
|
|
64
|
+
(0, chai_1.expect)(results).to.eql([2]);
|
|
65
|
+
//wait for task 1's promise to finish and verify we get an error
|
|
66
|
+
let error;
|
|
67
|
+
try {
|
|
68
|
+
await task1Promise;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
error = e;
|
|
72
|
+
}
|
|
73
|
+
(0, chai_1.expect)(error === null || error === void 0 ? void 0 : error.message).to.eql('Action took longer than 100ms to complete. Data: undefined');
|
|
74
|
+
//now wait for task1's work to actually finish
|
|
75
|
+
await task1Deferred.promise;
|
|
76
|
+
//the token should be marked as cancelled
|
|
77
|
+
(0, chai_1.expect)(cancellationToken.isCancellationRequested).to.be.true;
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=ActionQueue.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionQueue.spec.js","sourceRoot":"","sources":["../../src/lsp/ActionQueue.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { MaybePromise } from '../interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Maintains a queued/buffered list of file operations. These operations don't actually do anything on their own.
|
|
4
|
+
* You need to call the .apply() function and provide an action to operate on them.
|
|
5
|
+
*/
|
|
6
|
+
export declare class DocumentManager {
|
|
7
|
+
private options;
|
|
8
|
+
constructor(options: {
|
|
9
|
+
delay: number;
|
|
10
|
+
flushHandler?: (event: FlushEvent) => any;
|
|
11
|
+
});
|
|
12
|
+
private queue;
|
|
13
|
+
private timeoutHandle;
|
|
14
|
+
private throttle;
|
|
15
|
+
/**
|
|
16
|
+
* Add/set the contents of a file
|
|
17
|
+
*/
|
|
18
|
+
set(options: {
|
|
19
|
+
srcPath: string;
|
|
20
|
+
fileContents?: string;
|
|
21
|
+
allowStandaloneProject?: boolean;
|
|
22
|
+
}): void;
|
|
23
|
+
/**
|
|
24
|
+
* Delete a file or directory. If a directory is provided, all pending changes within that directory will be discarded
|
|
25
|
+
* and only the delete action will be queued
|
|
26
|
+
*/
|
|
27
|
+
delete(srcPath: string): void;
|
|
28
|
+
private isFlushRunning;
|
|
29
|
+
private flush;
|
|
30
|
+
/**
|
|
31
|
+
* Is the manager settled (i.e. no pending files, all files have been fully flushed)
|
|
32
|
+
*/
|
|
33
|
+
get isIdle(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Returns a promise that resolves when there are no pending files and no active flushes are running. Will immediately resolve if there are no files,
|
|
36
|
+
* and will wait until files are flushed if there are files.
|
|
37
|
+
*/
|
|
38
|
+
onIdle(): Promise<void>;
|
|
39
|
+
once(eventName: 'flush'): Promise<FlushEvent>;
|
|
40
|
+
on(eventName: 'flush', handler: (data: any) => MaybePromise<void>): any;
|
|
41
|
+
private emitSync;
|
|
42
|
+
private emitter;
|
|
43
|
+
dispose(): void;
|
|
44
|
+
}
|
|
45
|
+
export interface SetDocumentAction {
|
|
46
|
+
srcPath: string;
|
|
47
|
+
type: 'set';
|
|
48
|
+
allowStandaloneProject?: boolean;
|
|
49
|
+
fileContents: string;
|
|
50
|
+
}
|
|
51
|
+
export interface DeleteDocumentAction {
|
|
52
|
+
srcPath: string;
|
|
53
|
+
type: 'delete';
|
|
54
|
+
allowStandaloneProject?: boolean;
|
|
55
|
+
}
|
|
56
|
+
export declare type DocumentAction = SetDocumentAction | DeleteDocumentAction;
|
|
57
|
+
export declare type DocumentActionWithStatus = DocumentAction & {
|
|
58
|
+
id: number;
|
|
59
|
+
status: 'accepted' | 'rejected';
|
|
60
|
+
};
|
|
61
|
+
export interface FlushEvent {
|
|
62
|
+
actions: DocumentAction[];
|
|
63
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentManager = void 0;
|
|
4
|
+
const EventEmitter = require("eventemitter3");
|
|
5
|
+
const util_1 = require("../util");
|
|
6
|
+
/**
|
|
7
|
+
* Maintains a queued/buffered list of file operations. These operations don't actually do anything on their own.
|
|
8
|
+
* You need to call the .apply() function and provide an action to operate on them.
|
|
9
|
+
*/
|
|
10
|
+
class DocumentManager {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.options = options;
|
|
13
|
+
this.queue = new Map();
|
|
14
|
+
this.isFlushRunning = false;
|
|
15
|
+
this.emitter = new EventEmitter();
|
|
16
|
+
}
|
|
17
|
+
throttle() {
|
|
18
|
+
if (this.timeoutHandle) {
|
|
19
|
+
clearTimeout(this.timeoutHandle);
|
|
20
|
+
}
|
|
21
|
+
this.timeoutHandle = setTimeout(() => {
|
|
22
|
+
void this.flush();
|
|
23
|
+
}, this.options.delay);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Add/set the contents of a file
|
|
27
|
+
*/
|
|
28
|
+
set(options) {
|
|
29
|
+
var _a;
|
|
30
|
+
const srcPath = util_1.default.standardizePath(options.srcPath);
|
|
31
|
+
if (this.queue.has(srcPath)) {
|
|
32
|
+
this.queue.delete(srcPath);
|
|
33
|
+
}
|
|
34
|
+
this.queue.set(srcPath, {
|
|
35
|
+
type: 'set',
|
|
36
|
+
srcPath: srcPath,
|
|
37
|
+
fileContents: options.fileContents,
|
|
38
|
+
allowStandaloneProject: (_a = options.allowStandaloneProject) !== null && _a !== void 0 ? _a : false
|
|
39
|
+
});
|
|
40
|
+
//schedule a future flush
|
|
41
|
+
this.throttle();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Delete a file or directory. If a directory is provided, all pending changes within that directory will be discarded
|
|
45
|
+
* and only the delete action will be queued
|
|
46
|
+
*/
|
|
47
|
+
delete(srcPath) {
|
|
48
|
+
srcPath = util_1.default.standardizePath(srcPath);
|
|
49
|
+
//remove any pending action with this exact path
|
|
50
|
+
this.queue.delete(srcPath);
|
|
51
|
+
//we can't tell if this a directory, so just remove all pending changes for files that start with this path
|
|
52
|
+
for (const key of this.queue.keys()) {
|
|
53
|
+
if (key.startsWith(srcPath)) {
|
|
54
|
+
this.queue.delete(key);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//register this delete
|
|
58
|
+
this.queue.set(srcPath, { type: 'delete', srcPath: srcPath });
|
|
59
|
+
//schedule a future flush
|
|
60
|
+
this.throttle();
|
|
61
|
+
}
|
|
62
|
+
async flush() {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
//if we're already running a flush, don't run another
|
|
65
|
+
if (this.isFlushRunning) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.isFlushRunning = true;
|
|
69
|
+
while (this.queue.size > 0) {
|
|
70
|
+
try {
|
|
71
|
+
const event = {
|
|
72
|
+
actions: [...this.queue.values()]
|
|
73
|
+
};
|
|
74
|
+
this.queue.clear();
|
|
75
|
+
await ((_b = (_a = this.options).flushHandler) === null || _b === void 0 ? void 0 : _b.call(_a, event));
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
console.error(e);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
this.emitSync('flush');
|
|
82
|
+
this.isFlushRunning = false;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Is the manager settled (i.e. no pending files, all files have been fully flushed)
|
|
86
|
+
*/
|
|
87
|
+
get isIdle() {
|
|
88
|
+
return this.queue.size === 0 && this.isFlushRunning === false;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Returns a promise that resolves when there are no pending files and no active flushes are running. Will immediately resolve if there are no files,
|
|
92
|
+
* and will wait until files are flushed if there are files.
|
|
93
|
+
*/
|
|
94
|
+
async onIdle() {
|
|
95
|
+
while (!this.isIdle) {
|
|
96
|
+
await this.once('flush');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
once(eventName) {
|
|
100
|
+
return new Promise((resolve) => {
|
|
101
|
+
const off = this.on(eventName, (data) => {
|
|
102
|
+
off();
|
|
103
|
+
resolve(data);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
on(eventName, handler) {
|
|
108
|
+
this.emitter.on(eventName, handler);
|
|
109
|
+
return () => {
|
|
110
|
+
this.emitter.removeListener(eventName, handler);
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
emitSync(eventName, data) {
|
|
114
|
+
this.emitter.emit(eventName, data);
|
|
115
|
+
}
|
|
116
|
+
dispose() {
|
|
117
|
+
this.queue = new Map();
|
|
118
|
+
this.emitter.removeAllListeners();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.DocumentManager = DocumentManager;
|
|
122
|
+
//# sourceMappingURL=DocumentManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentManager.js","sourceRoot":"","sources":["../../src/lsp/DocumentManager.ts"],"names":[],"mappings":";;;AAAA,8CAA8C;AAE9C,kCAA2B;AAE3B;;;GAGG;AACH,MAAa,eAAe;IAExB,YACY,OAGP;QAHO,YAAO,GAAP,OAAO,CAGd;QAGG,UAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;QAmD1C,mBAAc,GAAG,KAAK,CAAC;QAgEvB,YAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IArHrC,CAAC;IAKO,QAAQ;QACZ,IAAI,IAAI,CAAC,aAAa,EAAE;YACpB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;SACpC;QACD,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;YACjC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,OAAqF;;QAC5F,MAAM,OAAO,GAAG,cAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YACzB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;SAC9B;QACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE;YACpB,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,OAAO;YAChB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,sBAAsB,EAAE,MAAA,OAAO,CAAC,sBAAsB,mCAAI,KAAK;SAClE,CAAC,CAAC;QACH,yBAAyB;QACzB,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,OAAe;QACzB,OAAO,GAAG,cAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACxC,gDAAgD;QAChD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3B,2GAA2G;QAC3G,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE;YACjC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;gBACzB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aAC1B;SACJ;QACD,sBAAsB;QACtB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAE9D,yBAAyB;QACzB,IAAI,CAAC,QAAQ,EAAE,CAAC;IACpB,CAAC;IAIO,KAAK,CAAC,KAAK;;QACf,qDAAqD;QACrD,IAAI,IAAI,CAAC,cAAc,EAAE;YACrB,OAAO;SACV;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,EAAE;YACxB,IAAI;gBACA,MAAM,KAAK,GAAe;oBACtB,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;iBACpC,CAAC;gBACF,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,CAAA,MAAA,MAAA,IAAI,CAAC,OAAO,EAAC,YAAY,mDAAG,KAAK,CAAC,CAAA,CAAC;aAC5C;YAAC,OAAO,CAAC,EAAE;gBACR,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;aACpB;SACJ;QACD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK,CAAC;IAClE,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,MAAM;QACf,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE;YACjB,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SAC5B;IACL,CAAC;IAGM,IAAI,CAAC,SAAiB;QACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,SAAgB,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC3C,GAAG,EAAE,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAGM,EAAE,CAAC,SAAiB,EAAE,OAA+C;QACxE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAc,CAAC,CAAC;QAC3C,OAAO,GAAG,EAAE;YACR,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,OAAc,CAAC,CAAC;QAC3D,CAAC,CAAC;IACN,CAAC;IAGO,QAAQ,CAAC,SAAiB,EAAE,IAAK;QACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC;IAIM,OAAO;QACV,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;IACtC,CAAC;CACJ;AAlID,0CAkIC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const chai_1 = require("chai");
|
|
4
|
+
const util_1 = require("../util");
|
|
5
|
+
const DocumentManager_1 = require("./DocumentManager");
|
|
6
|
+
const testHelpers_spec_1 = require("../testHelpers.spec");
|
|
7
|
+
describe('DocumentManager', () => {
|
|
8
|
+
let manager;
|
|
9
|
+
let results = [];
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
results = [];
|
|
12
|
+
manager = new DocumentManager_1.DocumentManager({
|
|
13
|
+
delay: 5,
|
|
14
|
+
flushHandler: (event) => {
|
|
15
|
+
results.push(...event.actions);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
it('throttles multiple events', async () => {
|
|
20
|
+
manager.set({ srcPath: 'alpha', fileContents: 'one' });
|
|
21
|
+
await util_1.util.sleep(1);
|
|
22
|
+
manager.set({ srcPath: 'alpha', fileContents: 'two' });
|
|
23
|
+
await util_1.util.sleep(1);
|
|
24
|
+
manager.set({ srcPath: 'alpha', fileContents: 'three' });
|
|
25
|
+
await manager.onIdle();
|
|
26
|
+
(0, chai_1.expect)(results).to.eql([{
|
|
27
|
+
type: 'set',
|
|
28
|
+
srcPath: 'alpha',
|
|
29
|
+
fileContents: 'three',
|
|
30
|
+
allowStandaloneProject: false
|
|
31
|
+
}]);
|
|
32
|
+
});
|
|
33
|
+
it('does not lose newly added that arrives during a flush operation', async () => {
|
|
34
|
+
const srcPath = (0, util_1.standardizePath) `${testHelpers_spec_1.rootDir}/source/main.bs`;
|
|
35
|
+
let contentsQueue = [
|
|
36
|
+
'two',
|
|
37
|
+
'three',
|
|
38
|
+
'four'
|
|
39
|
+
];
|
|
40
|
+
manager = new DocumentManager_1.DocumentManager({
|
|
41
|
+
delay: 5,
|
|
42
|
+
flushHandler: (event) => {
|
|
43
|
+
//once the flush happens, add NEW data to the queue. this is the data we need to ensure we don't lose
|
|
44
|
+
if (contentsQueue.length > 0) {
|
|
45
|
+
manager.set({ srcPath: srcPath, fileContents: contentsQueue.shift() });
|
|
46
|
+
}
|
|
47
|
+
//store the actions
|
|
48
|
+
results.push(...event.actions);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
manager.set({ srcPath: srcPath, fileContents: 'one' });
|
|
52
|
+
await manager.onIdle();
|
|
53
|
+
(0, chai_1.expect)(results.map(x => x.fileContents)).to.eql([
|
|
54
|
+
'one',
|
|
55
|
+
'two',
|
|
56
|
+
'three',
|
|
57
|
+
'four'
|
|
58
|
+
]);
|
|
59
|
+
});
|
|
60
|
+
it('any file change delays the first one', async () => {
|
|
61
|
+
manager.set({ srcPath: 'alpha', fileContents: 'one' });
|
|
62
|
+
await util_1.util.sleep(1);
|
|
63
|
+
manager.set({ srcPath: 'beta', fileContents: 'two' });
|
|
64
|
+
await util_1.util.sleep(1);
|
|
65
|
+
manager.set({ srcPath: 'alpha', fileContents: 'three' });
|
|
66
|
+
await util_1.util.sleep(1);
|
|
67
|
+
manager.set({ srcPath: 'beta', fileContents: 'four' });
|
|
68
|
+
await util_1.util.sleep(1);
|
|
69
|
+
await manager.onIdle();
|
|
70
|
+
(0, chai_1.expect)(results).to.eql([{
|
|
71
|
+
type: 'set',
|
|
72
|
+
srcPath: 'alpha',
|
|
73
|
+
fileContents: 'three',
|
|
74
|
+
allowStandaloneProject: false
|
|
75
|
+
}, {
|
|
76
|
+
type: 'set',
|
|
77
|
+
srcPath: 'beta',
|
|
78
|
+
fileContents: 'four',
|
|
79
|
+
allowStandaloneProject: false
|
|
80
|
+
}]);
|
|
81
|
+
});
|
|
82
|
+
it('keeps the last-in change', async () => {
|
|
83
|
+
manager.set({ srcPath: 'alpha', fileContents: 'one' });
|
|
84
|
+
manager.delete('alpha');
|
|
85
|
+
await manager.onIdle();
|
|
86
|
+
(0, chai_1.expect)(results).to.eql([{
|
|
87
|
+
type: 'delete',
|
|
88
|
+
srcPath: 'alpha'
|
|
89
|
+
}]);
|
|
90
|
+
results = [];
|
|
91
|
+
manager.set({ srcPath: 'alpha', fileContents: 'two' });
|
|
92
|
+
manager.delete('alpha');
|
|
93
|
+
manager.set({ srcPath: 'alpha', fileContents: 'three' });
|
|
94
|
+
await manager.onIdle();
|
|
95
|
+
(0, chai_1.expect)(results).to.eql([{
|
|
96
|
+
type: 'set',
|
|
97
|
+
srcPath: 'alpha',
|
|
98
|
+
fileContents: 'three',
|
|
99
|
+
allowStandaloneProject: false
|
|
100
|
+
}]);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=DocumentManager.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentManager.spec.js","sourceRoot":"","sources":["../../src/lsp/DocumentManager.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type { Diagnostic, Position, Range, Location, DocumentSymbol, WorkspaceSymbol, CodeAction, CompletionList } from 'vscode-languageserver-protocol';
|
|
2
|
+
import type { Hover, MaybePromise, SemanticToken } from '../interfaces';
|
|
3
|
+
import type { DocumentAction, DocumentActionWithStatus } from './DocumentManager';
|
|
4
|
+
import type { FileTranspileResult, SignatureInfoObj } from '../Program';
|
|
5
|
+
import type { Logger, LogLevel } from '../logging';
|
|
6
|
+
/**
|
|
7
|
+
* Defines the contract between the ProjectManager and the main or worker thread Project classes
|
|
8
|
+
*/
|
|
9
|
+
export interface LspProject {
|
|
10
|
+
/**
|
|
11
|
+
* Is this a standalone project?
|
|
12
|
+
*/
|
|
13
|
+
isStandaloneProject: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* A logger instance used for logging in this project
|
|
16
|
+
*/
|
|
17
|
+
logger: Logger;
|
|
18
|
+
/**
|
|
19
|
+
* The config used to activate this project
|
|
20
|
+
*/
|
|
21
|
+
activateOptions: ProjectConfig;
|
|
22
|
+
/**
|
|
23
|
+
* The path to where the project resides
|
|
24
|
+
*/
|
|
25
|
+
projectPath: string;
|
|
26
|
+
/**
|
|
27
|
+
* A unique number for this project, generated during this current language server session. Mostly used so we can identify which project is doing logging
|
|
28
|
+
*/
|
|
29
|
+
projectNumber: number;
|
|
30
|
+
/**
|
|
31
|
+
* A unique name for this project used in logs to help keep track of everything
|
|
32
|
+
*/
|
|
33
|
+
projectIdentifier: string;
|
|
34
|
+
/**
|
|
35
|
+
* The root directory of the project.
|
|
36
|
+
* Only available after `.activate()` has completed
|
|
37
|
+
*/
|
|
38
|
+
rootDir: string;
|
|
39
|
+
/**
|
|
40
|
+
* The file patterns from bsconfig.json that were used to find all files for this project
|
|
41
|
+
*/
|
|
42
|
+
filePatterns: string[];
|
|
43
|
+
/**
|
|
44
|
+
* Path to a bsconfig.json file that will be used for this project.
|
|
45
|
+
* Only available after `.activate()` has completed
|
|
46
|
+
*/
|
|
47
|
+
bsconfigPath?: string;
|
|
48
|
+
/**
|
|
49
|
+
* The contents of the bsconfig.json file. This is used to detect when the bsconfig file has not actually been changed (even if the fs says it did).
|
|
50
|
+
*
|
|
51
|
+
* Only available after `.activate()` has completed.
|
|
52
|
+
* @deprecated do not depend on this property. This will certainly be removed in a future release
|
|
53
|
+
*/
|
|
54
|
+
bsconfigFileContents?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Initialize and start running the project. This will scan for all files, and build a full project in memory, then validate the project
|
|
57
|
+
* @param options
|
|
58
|
+
*/
|
|
59
|
+
activate(options: ProjectConfig): MaybePromise<ActivateResponse>;
|
|
60
|
+
/**
|
|
61
|
+
* Get a promise that resolves when the project finishes activating
|
|
62
|
+
*/
|
|
63
|
+
whenActivated(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Validate the project. This will trigger a full validation on any scopes that were changed since the last validation,
|
|
66
|
+
* and will also eventually emit a new 'diagnostics' event that includes all diagnostics for the project
|
|
67
|
+
*/
|
|
68
|
+
validate(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Cancel any active validation that's running
|
|
71
|
+
*/
|
|
72
|
+
cancelValidate(): MaybePromise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Get the list of all diagnostics from this project
|
|
75
|
+
*/
|
|
76
|
+
getDiagnostics(): MaybePromise<LspDiagnostic[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the full list of semantic tokens for the given file path
|
|
79
|
+
* @param srcPath absolute path to the source file
|
|
80
|
+
*/
|
|
81
|
+
getSemanticTokens(options: {
|
|
82
|
+
srcPath: string;
|
|
83
|
+
}): MaybePromise<SemanticToken[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Transpile the specified file
|
|
86
|
+
* @param srcPath
|
|
87
|
+
*/
|
|
88
|
+
transpileFile(options: {
|
|
89
|
+
srcPath: string;
|
|
90
|
+
}): MaybePromise<FileTranspileResult>;
|
|
91
|
+
/**
|
|
92
|
+
* Get the hover information for the specified position in the specified file
|
|
93
|
+
*/
|
|
94
|
+
getHover(options: {
|
|
95
|
+
srcPath: string;
|
|
96
|
+
position: Position;
|
|
97
|
+
}): MaybePromise<Hover[]>;
|
|
98
|
+
/**
|
|
99
|
+
* Get the locations where the symbol at the specified position is defined
|
|
100
|
+
* @param options the file path and position to get the definition for
|
|
101
|
+
*/
|
|
102
|
+
getDefinition(options: {
|
|
103
|
+
srcPath: string;
|
|
104
|
+
position: Position;
|
|
105
|
+
}): MaybePromise<Location[]>;
|
|
106
|
+
/**
|
|
107
|
+
* Get the locations where the symbol at the specified position is defined
|
|
108
|
+
* @param options the file path and position to get the definition for
|
|
109
|
+
*/
|
|
110
|
+
getSignatureHelp(options: {
|
|
111
|
+
srcPath: string;
|
|
112
|
+
position: Position;
|
|
113
|
+
}): MaybePromise<SignatureInfoObj[]>;
|
|
114
|
+
/**
|
|
115
|
+
* Get the list of symbols for the specified file
|
|
116
|
+
*/
|
|
117
|
+
getDocumentSymbol(options: {
|
|
118
|
+
srcPath: string;
|
|
119
|
+
}): MaybePromise<DocumentSymbol[]>;
|
|
120
|
+
/**
|
|
121
|
+
* Get the list of symbols for the entire workspace
|
|
122
|
+
*/
|
|
123
|
+
getWorkspaceSymbol(): Promise<WorkspaceSymbol[]>;
|
|
124
|
+
/**
|
|
125
|
+
* Get the list of references for the specified file and position
|
|
126
|
+
*/
|
|
127
|
+
getReferences(options: {
|
|
128
|
+
srcPath: string;
|
|
129
|
+
position: Position;
|
|
130
|
+
}): MaybePromise<Location[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Get all of the code actions for the specified file and range
|
|
133
|
+
*/
|
|
134
|
+
getCodeActions(options: {
|
|
135
|
+
srcPath: string;
|
|
136
|
+
range: Range;
|
|
137
|
+
}): Promise<CodeAction[]>;
|
|
138
|
+
/**
|
|
139
|
+
* Get the completions for the specified file and position
|
|
140
|
+
*/
|
|
141
|
+
getCompletions(options: {
|
|
142
|
+
srcPath: string;
|
|
143
|
+
position: Position;
|
|
144
|
+
}): Promise<CompletionList>;
|
|
145
|
+
/**
|
|
146
|
+
* Apply a series of file changes to the program.
|
|
147
|
+
* This will cancel any active validation.
|
|
148
|
+
* @param documentActions
|
|
149
|
+
* @returns a boolean indicating whether this project accepted any of the file changes. If false, then this project didn't recognize any of the files and thus did nothing
|
|
150
|
+
*/
|
|
151
|
+
applyFileChanges(documentActions: DocumentAction[]): Promise<DocumentActionWithStatus[]>;
|
|
152
|
+
/**
|
|
153
|
+
* An event that is emitted anytime the diagnostics for the project have changed (typically after a validate cycle has finished)
|
|
154
|
+
* @param eventName
|
|
155
|
+
* @param handler
|
|
156
|
+
*/
|
|
157
|
+
on(eventName: 'diagnostics', handler: (data: {
|
|
158
|
+
diagnostics: LspDiagnostic[];
|
|
159
|
+
}) => void): any;
|
|
160
|
+
on(eventName: 'all', handler: (eventName: string, data: Record<string, any>) => void): any;
|
|
161
|
+
/**
|
|
162
|
+
* List of items to dispose when this project is disposed
|
|
163
|
+
*/
|
|
164
|
+
disposables: Array<{
|
|
165
|
+
dispose(): void;
|
|
166
|
+
}>;
|
|
167
|
+
/**
|
|
168
|
+
* Release all resources so this file can be safely garbage collected
|
|
169
|
+
*/
|
|
170
|
+
dispose(): void;
|
|
171
|
+
}
|
|
172
|
+
export interface ProjectConfig {
|
|
173
|
+
/**
|
|
174
|
+
* Path to the project
|
|
175
|
+
*/
|
|
176
|
+
projectPath: string;
|
|
177
|
+
/**
|
|
178
|
+
* Path to the workspace in which all project files reside or are referenced by
|
|
179
|
+
*/
|
|
180
|
+
workspaceFolder: string;
|
|
181
|
+
/**
|
|
182
|
+
* A list of glob patterns used to _exclude_ files from various bsconfig searches
|
|
183
|
+
*/
|
|
184
|
+
excludePatterns?: string[];
|
|
185
|
+
/**
|
|
186
|
+
* An optional project number to assign to the project within the context of a language server. reloaded projects should keep the same number if possible
|
|
187
|
+
*/
|
|
188
|
+
projectNumber?: number;
|
|
189
|
+
/**
|
|
190
|
+
* Path to a bsconfig that should be used instead of the auto-discovery algorithm. If this is present, no bsconfig discovery should be used. and an error should be emitted if this file is missing
|
|
191
|
+
*/
|
|
192
|
+
bsconfigPath?: string;
|
|
193
|
+
/**
|
|
194
|
+
* Should this project run in its own dedicated worker thread
|
|
195
|
+
* TODO - is there a better name for this?
|
|
196
|
+
*/
|
|
197
|
+
enableThreading?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* If present, this will override any files array found in bsconfig or the default.
|
|
200
|
+
*
|
|
201
|
+
* The list of file globs used to find all files for the project
|
|
202
|
+
* If using the {src;dest;} format, you can specify a different destination directory
|
|
203
|
+
* for the matched files in src.
|
|
204
|
+
*
|
|
205
|
+
*/
|
|
206
|
+
files?: Array<string | {
|
|
207
|
+
src: string | string[];
|
|
208
|
+
dest?: string;
|
|
209
|
+
}>;
|
|
210
|
+
}
|
|
211
|
+
export interface LspDiagnostic extends Diagnostic {
|
|
212
|
+
uri: string;
|
|
213
|
+
}
|
|
214
|
+
export interface ActivateResponse {
|
|
215
|
+
/**
|
|
216
|
+
* The root directory of the project
|
|
217
|
+
*/
|
|
218
|
+
rootDir: string;
|
|
219
|
+
/**
|
|
220
|
+
* The path to the config file (i.e. `bsconfig.json`) that was used to load this project
|
|
221
|
+
*/
|
|
222
|
+
bsconfigPath: string;
|
|
223
|
+
/**
|
|
224
|
+
* The file patterns from bsconfig.json that were used to find all files for this project
|
|
225
|
+
*/
|
|
226
|
+
filePatterns: string[];
|
|
227
|
+
/**
|
|
228
|
+
* The logLevel used for this project's logger
|
|
229
|
+
*/
|
|
230
|
+
logLevel: LogLevel;
|
|
231
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LspProject.js","sourceRoot":"","sources":["../../src/lsp/LspProject.ts"],"names":[],"mappings":""}
|