typescript-language-server 5.0.0 → 5.0.1
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 +8 -0
- package/README.md +0 -32
- package/lib/cli.mjs +874 -309
- package/lib/cli.mjs.map +1 -1
- package/package.json +12 -12
package/lib/cli.mjs
CHANGED
|
@@ -12990,6 +12990,28 @@ function requireStat() {
|
|
|
12990
12990
|
return stat;
|
|
12991
12991
|
}
|
|
12992
12992
|
|
|
12993
|
+
var async;
|
|
12994
|
+
|
|
12995
|
+
var hasRequiredAsync;
|
|
12996
|
+
|
|
12997
|
+
function requireAsync() {
|
|
12998
|
+
if (hasRequiredAsync) return async;
|
|
12999
|
+
hasRequiredAsync = 1;
|
|
13000
|
+
async function asyncIteratorConcurrentProcess(iterator, fn) {
|
|
13001
|
+
const promises = [];
|
|
13002
|
+
for await (const item of iterator) {
|
|
13003
|
+
promises.push(fn(item).then(() => null, err => err ?? new Error('unknown error')));
|
|
13004
|
+
}
|
|
13005
|
+
await Promise.all(promises.map(promise => promise.then(possibleErr => {
|
|
13006
|
+
if (possibleErr !== null) throw possibleErr;
|
|
13007
|
+
})));
|
|
13008
|
+
}
|
|
13009
|
+
async = {
|
|
13010
|
+
asyncIteratorConcurrentProcess: asyncIteratorConcurrentProcess
|
|
13011
|
+
};
|
|
13012
|
+
return async;
|
|
13013
|
+
}
|
|
13014
|
+
|
|
12993
13015
|
var copy_1;
|
|
12994
13016
|
|
|
12995
13017
|
var hasRequiredCopy$1;
|
|
@@ -13003,6 +13025,7 @@ function requireCopy$1() {
|
|
|
13003
13025
|
const {pathExists: pathExists} = requirePathExists();
|
|
13004
13026
|
const {utimesMillis: utimesMillis} = requireUtimes();
|
|
13005
13027
|
const stat = requireStat();
|
|
13028
|
+
const {asyncIteratorConcurrentProcess: asyncIteratorConcurrentProcess} = requireAsync();
|
|
13006
13029
|
async function copy(src, dest, opts = {}) {
|
|
13007
13030
|
if (typeof opts === 'function') {
|
|
13008
13031
|
opts = {
|
|
@@ -13070,17 +13093,15 @@ function requireCopy$1() {
|
|
|
13070
13093
|
if (!destStat) {
|
|
13071
13094
|
await fs.mkdir(dest);
|
|
13072
13095
|
}
|
|
13073
|
-
|
|
13074
|
-
for await (const item of await fs.opendir(src)) {
|
|
13096
|
+
await asyncIteratorConcurrentProcess(await fs.opendir(src), async item => {
|
|
13075
13097
|
const srcItem = path.join(src, item.name);
|
|
13076
13098
|
const destItem = path.join(dest, item.name);
|
|
13077
|
-
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
|
|
13081
|
-
}
|
|
13082
|
-
}
|
|
13083
|
-
await Promise.all(promises);
|
|
13099
|
+
const include = await runFilter(srcItem, destItem, opts);
|
|
13100
|
+
if (include) {
|
|
13101
|
+
const {destStat: destStat} = await stat.checkPaths(srcItem, destItem, 'copy', opts);
|
|
13102
|
+
await getStatsAndPerformCopy(destStat, srcItem, destItem, opts);
|
|
13103
|
+
}
|
|
13104
|
+
});
|
|
13084
13105
|
if (!destStat) {
|
|
13085
13106
|
await fs.chmod(dest, srcStat.mode);
|
|
13086
13107
|
}
|
|
@@ -18191,7 +18212,7 @@ class SingleTsServer {
|
|
|
18191
18212
|
tryCancelRequest(seq, command) {
|
|
18192
18213
|
try {
|
|
18193
18214
|
if (this._requestQueue.tryDeletePendingRequest(seq)) {
|
|
18194
|
-
this.logTrace(`Canceled request with sequence number ${seq}`);
|
|
18215
|
+
this.logTrace(`Canceled pending request with sequence number ${seq}`);
|
|
18195
18216
|
return true;
|
|
18196
18217
|
}
|
|
18197
18218
|
if (this._requestCanceller.tryCancelOngoingRequest(seq)) {
|
|
@@ -19305,7 +19326,8 @@ class TsClient {
|
|
|
19305
19326
|
executions[0].catch(err => this.fatalError(command, err));
|
|
19306
19327
|
}
|
|
19307
19328
|
if (command === CommandTypes.UpdateOpen) {
|
|
19308
|
-
|
|
19329
|
+
const executionsWithResults = executions.filter(e => e !== undefined);
|
|
19330
|
+
Promise.all(executionsWithResults).then(() => {
|
|
19309
19331
|
this.loadingIndicator.reset();
|
|
19310
19332
|
});
|
|
19311
19333
|
}
|
|
@@ -19375,30 +19397,73 @@ class TsClient {
|
|
|
19375
19397
|
}
|
|
19376
19398
|
}
|
|
19377
19399
|
|
|
19378
|
-
const pDebounce = (
|
|
19400
|
+
const pDebounce = (function_, wait, options = {}) => {
|
|
19379
19401
|
if (!Number.isFinite(wait)) {
|
|
19380
19402
|
throw new TypeError('Expected `wait` to be a finite number');
|
|
19381
19403
|
}
|
|
19382
19404
|
let leadingValue;
|
|
19383
19405
|
let timeout;
|
|
19384
19406
|
let resolveList = [];
|
|
19407
|
+
let rejectList = [];
|
|
19408
|
+
const onAbort = () => {
|
|
19409
|
+
clearTimeout(timeout);
|
|
19410
|
+
timeout = null;
|
|
19411
|
+
try {
|
|
19412
|
+
options.signal?.throwIfAborted();
|
|
19413
|
+
} catch (error) {
|
|
19414
|
+
for (const reject of rejectList) {
|
|
19415
|
+
reject(error);
|
|
19416
|
+
}
|
|
19417
|
+
resolveList = [];
|
|
19418
|
+
rejectList = [];
|
|
19419
|
+
}
|
|
19420
|
+
};
|
|
19385
19421
|
return function(...arguments_) {
|
|
19386
|
-
return new Promise(resolve => {
|
|
19422
|
+
return new Promise((resolve, reject) => {
|
|
19423
|
+
try {
|
|
19424
|
+
options.signal?.throwIfAborted();
|
|
19425
|
+
} catch (error) {
|
|
19426
|
+
reject(error);
|
|
19427
|
+
return;
|
|
19428
|
+
}
|
|
19387
19429
|
const shouldCallNow = options.before && !timeout;
|
|
19388
19430
|
clearTimeout(timeout);
|
|
19389
|
-
timeout = setTimeout(() => {
|
|
19431
|
+
timeout = setTimeout(async () => {
|
|
19390
19432
|
timeout = null;
|
|
19391
|
-
const
|
|
19392
|
-
|
|
19393
|
-
resolve(result);
|
|
19394
|
-
}
|
|
19433
|
+
const currentResolveList = resolveList;
|
|
19434
|
+
const currentRejectList = rejectList;
|
|
19395
19435
|
resolveList = [];
|
|
19436
|
+
rejectList = [];
|
|
19437
|
+
try {
|
|
19438
|
+
const result = options.before ? leadingValue : await function_.apply(this, arguments_);
|
|
19439
|
+
for (const resolveFunction of currentResolveList) {
|
|
19440
|
+
resolveFunction(result);
|
|
19441
|
+
}
|
|
19442
|
+
} catch (error) {
|
|
19443
|
+
for (const rejectFunction of currentRejectList) {
|
|
19444
|
+
rejectFunction(error);
|
|
19445
|
+
}
|
|
19446
|
+
}
|
|
19447
|
+
leadingValue = undefined;
|
|
19448
|
+
options.signal?.removeEventListener('abort', onAbort);
|
|
19396
19449
|
}, wait);
|
|
19397
19450
|
if (shouldCallNow) {
|
|
19398
|
-
|
|
19399
|
-
|
|
19451
|
+
(async () => {
|
|
19452
|
+
try {
|
|
19453
|
+
leadingValue = await function_.apply(this, arguments_);
|
|
19454
|
+
resolve(leadingValue);
|
|
19455
|
+
} catch (error) {
|
|
19456
|
+
reject(error);
|
|
19457
|
+
}
|
|
19458
|
+
})();
|
|
19400
19459
|
} else {
|
|
19401
19460
|
resolveList.push(resolve);
|
|
19461
|
+
rejectList.push(reject);
|
|
19462
|
+
if (options.signal && resolveList.length === 1) {
|
|
19463
|
+
options.signal.addEventListener('abort', onAbort, {
|
|
19464
|
+
once: true
|
|
19465
|
+
});
|
|
19466
|
+
}
|
|
19402
19467
|
}
|
|
19403
19468
|
});
|
|
19404
19469
|
};
|
|
@@ -19741,7 +19806,7 @@ class FileDiagnostics {
|
|
|
19741
19806
|
}
|
|
19742
19807
|
}
|
|
19743
19808
|
|
|
19744
|
-
class
|
|
19809
|
+
class DiagnosticsManager {
|
|
19745
19810
|
constructor(publishDiagnostics, client, features, logger) {
|
|
19746
19811
|
this.publishDiagnostics = publishDiagnostics;
|
|
19747
19812
|
this.client = client;
|
|
@@ -19858,8 +19923,6 @@ class TSServerRequestCommand {
|
|
|
19858
19923
|
TSServerRequestCommand.id = 'typescript.tsserverRequest';
|
|
19859
19924
|
|
|
19860
19925
|
const Commands = {
|
|
19861
|
-
APPLY_WORKSPACE_EDIT: '_typescript.applyWorkspaceEdit',
|
|
19862
|
-
APPLY_CODE_ACTION: '_typescript.applyCodeAction',
|
|
19863
19926
|
APPLY_REFACTORING: '_typescript.applyRefactoring',
|
|
19864
19927
|
CONFIGURE_PLUGIN: '_typescript.configurePlugin',
|
|
19865
19928
|
ORGANIZE_IMPORTS: '_typescript.organizeImports',
|
|
@@ -20682,19 +20745,6 @@ function toTsTriggerReason(context) {
|
|
|
20682
20745
|
}
|
|
20683
20746
|
}
|
|
20684
20747
|
|
|
20685
|
-
function provideQuickFix(response, client) {
|
|
20686
|
-
if (!response?.body) {
|
|
20687
|
-
return [];
|
|
20688
|
-
}
|
|
20689
|
-
return response.body.map(fix => mainExports$2.CodeAction.create(fix.description, {
|
|
20690
|
-
title: fix.description,
|
|
20691
|
-
command: Commands.APPLY_WORKSPACE_EDIT,
|
|
20692
|
-
arguments: [ {
|
|
20693
|
-
documentChanges: fix.changes.map(c => toTextDocumentEdit(c, client))
|
|
20694
|
-
} ]
|
|
20695
|
-
}, mainExports$2.CodeActionKind.QuickFix));
|
|
20696
|
-
}
|
|
20697
|
-
|
|
20698
20748
|
var CodeActionKind$1;
|
|
20699
20749
|
|
|
20700
20750
|
(function(CodeActionKind) {
|
|
@@ -21440,187 +21490,6 @@ class FileConfigurationManager {
|
|
|
21440
21490
|
}
|
|
21441
21491
|
}
|
|
21442
21492
|
|
|
21443
|
-
const variableDeclaredButNeverUsed = new Set([ 6196, 6133 ]);
|
|
21444
|
-
|
|
21445
|
-
const unreachableCode$1 = new Set([ 7027 ]);
|
|
21446
|
-
|
|
21447
|
-
const incorrectlyImplementsInterface = new Set([ 2420 ]);
|
|
21448
|
-
|
|
21449
|
-
const cannotFindName = new Set([ 2552, 2304 ]);
|
|
21450
|
-
|
|
21451
|
-
const asyncOnlyAllowedInAsyncFunctions = new Set([ 1308 ]);
|
|
21452
|
-
|
|
21453
|
-
const awaitInSyncFunction = 'fixAwaitInSyncFunction';
|
|
21454
|
-
|
|
21455
|
-
const classIncorrectlyImplementsInterface = 'fixClassIncorrectlyImplementsInterface';
|
|
21456
|
-
|
|
21457
|
-
const unreachableCode = 'fixUnreachableCode';
|
|
21458
|
-
|
|
21459
|
-
const unusedIdentifier = 'unusedIdentifier';
|
|
21460
|
-
|
|
21461
|
-
const fixImport = 'import';
|
|
21462
|
-
|
|
21463
|
-
async function buildIndividualFixes(fixes, client, file, diagnostics) {
|
|
21464
|
-
const edits = [];
|
|
21465
|
-
for (const diagnostic of diagnostics) {
|
|
21466
|
-
for (const {codes: codes, fixName: fixName} of fixes) {
|
|
21467
|
-
if (!codes.has(diagnostic.code)) {
|
|
21468
|
-
continue;
|
|
21469
|
-
}
|
|
21470
|
-
const args = {
|
|
21471
|
-
...Range.toFileRangeRequestArgs(file, diagnostic.range),
|
|
21472
|
-
errorCodes: [ +diagnostic.code ]
|
|
21473
|
-
};
|
|
21474
|
-
const response = await client.execute(CommandTypes.GetCodeFixes, args);
|
|
21475
|
-
if (response.type !== 'response') {
|
|
21476
|
-
continue;
|
|
21477
|
-
}
|
|
21478
|
-
const fix = response.body?.find(fix => fix.fixName === fixName);
|
|
21479
|
-
if (fix) {
|
|
21480
|
-
edits.push(...fix.changes.map(change => toTextDocumentEdit(change, client)));
|
|
21481
|
-
break;
|
|
21482
|
-
}
|
|
21483
|
-
}
|
|
21484
|
-
}
|
|
21485
|
-
return edits;
|
|
21486
|
-
}
|
|
21487
|
-
|
|
21488
|
-
async function buildCombinedFix(fixes, client, file, diagnostics) {
|
|
21489
|
-
const edits = [];
|
|
21490
|
-
for (const diagnostic of diagnostics) {
|
|
21491
|
-
for (const {codes: codes, fixName: fixName} of fixes) {
|
|
21492
|
-
if (!codes.has(diagnostic.code)) {
|
|
21493
|
-
continue;
|
|
21494
|
-
}
|
|
21495
|
-
const args = {
|
|
21496
|
-
...Range.toFileRangeRequestArgs(file, diagnostic.range),
|
|
21497
|
-
errorCodes: [ +diagnostic.code ]
|
|
21498
|
-
};
|
|
21499
|
-
const response = await client.execute(CommandTypes.GetCodeFixes, args);
|
|
21500
|
-
if (response.type !== 'response' || !response.body?.length) {
|
|
21501
|
-
continue;
|
|
21502
|
-
}
|
|
21503
|
-
const fix = response.body?.find(fix => fix.fixName === fixName);
|
|
21504
|
-
if (!fix) {
|
|
21505
|
-
continue;
|
|
21506
|
-
}
|
|
21507
|
-
if (!fix.fixId) {
|
|
21508
|
-
edits.push(...fix.changes.map(change => toTextDocumentEdit(change, client)));
|
|
21509
|
-
return edits;
|
|
21510
|
-
}
|
|
21511
|
-
const combinedArgs = {
|
|
21512
|
-
scope: {
|
|
21513
|
-
type: 'file',
|
|
21514
|
-
args: {
|
|
21515
|
-
file: file
|
|
21516
|
-
}
|
|
21517
|
-
},
|
|
21518
|
-
fixId: fix.fixId
|
|
21519
|
-
};
|
|
21520
|
-
const combinedResponse = await client.execute(CommandTypes.GetCombinedCodeFix, combinedArgs);
|
|
21521
|
-
if (combinedResponse.type !== 'response' || !combinedResponse.body) {
|
|
21522
|
-
return edits;
|
|
21523
|
-
}
|
|
21524
|
-
edits.push(...combinedResponse.body.changes.map(change => toTextDocumentEdit(change, client)));
|
|
21525
|
-
return edits;
|
|
21526
|
-
}
|
|
21527
|
-
}
|
|
21528
|
-
return edits;
|
|
21529
|
-
}
|
|
21530
|
-
|
|
21531
|
-
class SourceAction {}
|
|
21532
|
-
|
|
21533
|
-
class SourceFixAll extends SourceAction {
|
|
21534
|
-
constructor() {
|
|
21535
|
-
super(...arguments);
|
|
21536
|
-
this.title = 'Fix all';
|
|
21537
|
-
}
|
|
21538
|
-
async build(client, file, diagnostics) {
|
|
21539
|
-
const edits = [];
|
|
21540
|
-
edits.push(...await buildIndividualFixes([ {
|
|
21541
|
-
codes: incorrectlyImplementsInterface,
|
|
21542
|
-
fixName: classIncorrectlyImplementsInterface
|
|
21543
|
-
}, {
|
|
21544
|
-
codes: asyncOnlyAllowedInAsyncFunctions,
|
|
21545
|
-
fixName: awaitInSyncFunction
|
|
21546
|
-
} ], client, file, diagnostics));
|
|
21547
|
-
edits.push(...await buildCombinedFix([ {
|
|
21548
|
-
codes: unreachableCode$1,
|
|
21549
|
-
fixName: unreachableCode
|
|
21550
|
-
} ], client, file, diagnostics));
|
|
21551
|
-
if (!edits.length) {
|
|
21552
|
-
return null;
|
|
21553
|
-
}
|
|
21554
|
-
return mainExports$2.CodeAction.create(this.title, {
|
|
21555
|
-
documentChanges: edits
|
|
21556
|
-
}, SourceFixAll.kind.value);
|
|
21557
|
-
}
|
|
21558
|
-
}
|
|
21559
|
-
|
|
21560
|
-
SourceFixAll.kind = CodeActionKind.SourceFixAllTs;
|
|
21561
|
-
|
|
21562
|
-
class SourceRemoveUnused extends SourceAction {
|
|
21563
|
-
constructor() {
|
|
21564
|
-
super(...arguments);
|
|
21565
|
-
this.title = 'Remove all unused code';
|
|
21566
|
-
}
|
|
21567
|
-
async build(client, file, diagnostics) {
|
|
21568
|
-
const edits = await buildCombinedFix([ {
|
|
21569
|
-
codes: variableDeclaredButNeverUsed,
|
|
21570
|
-
fixName: unusedIdentifier
|
|
21571
|
-
} ], client, file, diagnostics);
|
|
21572
|
-
if (!edits.length) {
|
|
21573
|
-
return null;
|
|
21574
|
-
}
|
|
21575
|
-
return mainExports$2.CodeAction.create(this.title, {
|
|
21576
|
-
documentChanges: edits
|
|
21577
|
-
}, SourceRemoveUnused.kind.value);
|
|
21578
|
-
}
|
|
21579
|
-
}
|
|
21580
|
-
|
|
21581
|
-
SourceRemoveUnused.kind = CodeActionKind.SourceRemoveUnusedTs;
|
|
21582
|
-
|
|
21583
|
-
class SourceAddMissingImports extends SourceAction {
|
|
21584
|
-
constructor() {
|
|
21585
|
-
super(...arguments);
|
|
21586
|
-
this.title = 'Add all missing imports';
|
|
21587
|
-
}
|
|
21588
|
-
async build(client, file, diagnostics) {
|
|
21589
|
-
const edits = await buildCombinedFix([ {
|
|
21590
|
-
codes: cannotFindName,
|
|
21591
|
-
fixName: fixImport
|
|
21592
|
-
} ], client, file, diagnostics);
|
|
21593
|
-
if (!edits.length) {
|
|
21594
|
-
return null;
|
|
21595
|
-
}
|
|
21596
|
-
return mainExports$2.CodeAction.create(this.title, {
|
|
21597
|
-
documentChanges: edits
|
|
21598
|
-
}, SourceAddMissingImports.kind.value);
|
|
21599
|
-
}
|
|
21600
|
-
}
|
|
21601
|
-
|
|
21602
|
-
SourceAddMissingImports.kind = CodeActionKind.SourceAddMissingImportsTs;
|
|
21603
|
-
|
|
21604
|
-
class TypeScriptAutoFixProvider {
|
|
21605
|
-
static get kinds() {
|
|
21606
|
-
return TypeScriptAutoFixProvider.kindProviders.map(provider => provider.kind);
|
|
21607
|
-
}
|
|
21608
|
-
constructor(client) {
|
|
21609
|
-
this.client = client;
|
|
21610
|
-
}
|
|
21611
|
-
async provideCodeActions(kinds, file, diagnostics) {
|
|
21612
|
-
const results = [];
|
|
21613
|
-
for (const provider of TypeScriptAutoFixProvider.kindProviders) {
|
|
21614
|
-
if (kinds.some(kind => kind.contains(provider.kind))) {
|
|
21615
|
-
results.push((new provider).build(this.client, file, diagnostics));
|
|
21616
|
-
}
|
|
21617
|
-
}
|
|
21618
|
-
return (await Promise.all(results)).flatMap(result => result || []);
|
|
21619
|
-
}
|
|
21620
|
-
}
|
|
21621
|
-
|
|
21622
|
-
TypeScriptAutoFixProvider.kindProviders = [ SourceFixAll, SourceRemoveUnused, SourceAddMissingImports ];
|
|
21623
|
-
|
|
21624
21493
|
function escapeRegExp(text) {
|
|
21625
21494
|
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
|
21626
21495
|
}
|
|
@@ -22465,60 +22334,783 @@ class TypeScriptVersionProvider {
|
|
|
22465
22334
|
}
|
|
22466
22335
|
}
|
|
22467
22336
|
|
|
22468
|
-
class
|
|
22469
|
-
constructor(
|
|
22470
|
-
this.
|
|
22471
|
-
this.initializeParams = null;
|
|
22472
|
-
this.completionDataCache = new CompletionDataCache;
|
|
22473
|
-
this.typeScriptAutoFixProvider = null;
|
|
22474
|
-
this.features = {};
|
|
22475
|
-
this.cachedNavTreeResponse = new CachedResponse;
|
|
22476
|
-
this.implementationsCodeLensProvider = null;
|
|
22477
|
-
this.referencesCodeLensProvider = null;
|
|
22478
|
-
this.logger = new PrefixingLogger(options.logger, '[lspserver]');
|
|
22479
|
-
this.tsClient = new TsClient(onCaseInsensitiveFileSystem(), this.logger, options.lspClient);
|
|
22480
|
-
this.fileConfigurationManager = new FileConfigurationManager(this.tsClient, onCaseInsensitiveFileSystem());
|
|
22481
|
-
this.diagnosticQueue = new DiagnosticEventQueue(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.tsClient, this.features, this.logger);
|
|
22337
|
+
class CommandManager {
|
|
22338
|
+
constructor() {
|
|
22339
|
+
this.commands = new Map;
|
|
22482
22340
|
}
|
|
22483
|
-
|
|
22484
|
-
|
|
22485
|
-
|
|
22341
|
+
dispose() {
|
|
22342
|
+
this.commands.clear();
|
|
22343
|
+
}
|
|
22344
|
+
register(command) {
|
|
22345
|
+
const entry = this.commands.get(command.id);
|
|
22346
|
+
if (!entry) {
|
|
22347
|
+
this.commands.set(command.id, command);
|
|
22486
22348
|
}
|
|
22487
22349
|
}
|
|
22488
|
-
async
|
|
22489
|
-
const
|
|
22490
|
-
if (
|
|
22491
|
-
|
|
22350
|
+
async handle(commandId, ...args) {
|
|
22351
|
+
const entry = this.commands.get(commandId);
|
|
22352
|
+
if (entry) {
|
|
22353
|
+
await entry.execute(...args);
|
|
22354
|
+
return true;
|
|
22492
22355
|
}
|
|
22493
|
-
|
|
22356
|
+
return false;
|
|
22494
22357
|
}
|
|
22495
|
-
|
|
22496
|
-
|
|
22358
|
+
}
|
|
22359
|
+
|
|
22360
|
+
const variableDeclaredButNeverUsed = new Set([ 6196, 6133 ]);
|
|
22361
|
+
|
|
22362
|
+
const unreachableCode$1 = new Set([ 7027 ]);
|
|
22363
|
+
|
|
22364
|
+
const incorrectlyImplementsInterface = new Set([ 2420 ]);
|
|
22365
|
+
|
|
22366
|
+
const cannotFindName = new Set([ 2552, 2304 ]);
|
|
22367
|
+
|
|
22368
|
+
const asyncOnlyAllowedInAsyncFunctions = new Set([ 1308 ]);
|
|
22369
|
+
|
|
22370
|
+
const addMissingAwait = 'addMissingAwait';
|
|
22371
|
+
|
|
22372
|
+
const addMissingNewOperator = 'addMissingNewOperator';
|
|
22373
|
+
|
|
22374
|
+
const addMissingOverride = 'fixOverrideModifier';
|
|
22375
|
+
|
|
22376
|
+
const annotateWithTypeFromJSDoc = 'annotateWithTypeFromJSDoc';
|
|
22377
|
+
|
|
22378
|
+
const awaitInSyncFunction = 'fixAwaitInSyncFunction';
|
|
22379
|
+
|
|
22380
|
+
const classDoesntImplementInheritedAbstractMember = 'fixClassDoesntImplementInheritedAbstractMember';
|
|
22381
|
+
|
|
22382
|
+
const classIncorrectlyImplementsInterface = 'fixClassIncorrectlyImplementsInterface';
|
|
22383
|
+
|
|
22384
|
+
const constructorForDerivedNeedSuperCall = 'constructorForDerivedNeedSuperCall';
|
|
22385
|
+
|
|
22386
|
+
const extendsInterfaceBecomesImplements = 'extendsInterfaceBecomesImplements';
|
|
22387
|
+
|
|
22388
|
+
const fixImport = 'import';
|
|
22389
|
+
|
|
22390
|
+
const forgottenThisPropertyAccess = 'forgottenThisPropertyAccess';
|
|
22391
|
+
|
|
22392
|
+
const removeUnnecessaryAwait = 'removeUnnecessaryAwait';
|
|
22393
|
+
|
|
22394
|
+
const spelling = 'spelling';
|
|
22395
|
+
|
|
22396
|
+
const unreachableCode = 'fixUnreachableCode';
|
|
22397
|
+
|
|
22398
|
+
const unusedIdentifier = 'unusedIdentifier';
|
|
22399
|
+
|
|
22400
|
+
class TsCodeAction {
|
|
22401
|
+
constructor(title, kind) {
|
|
22402
|
+
this.title = title;
|
|
22403
|
+
this.kind = kind;
|
|
22497
22404
|
}
|
|
22498
|
-
|
|
22499
|
-
this.
|
|
22500
|
-
|
|
22501
|
-
|
|
22502
|
-
const userInitializationOptions = this.initializeParams.initializationOptions || {};
|
|
22503
|
-
const {disableAutomaticTypingAcquisition: disableAutomaticTypingAcquisition, hostInfo: hostInfo, maxTsServerMemory: maxTsServerMemory, npmLocation: npmLocation, locale: locale, plugins: plugins, tsserver: tsserver} = userInitializationOptions;
|
|
22504
|
-
const typescriptVersion = this.findTypescriptVersion(tsserver?.path, tsserver?.fallbackPath);
|
|
22505
|
-
if (typescriptVersion) {
|
|
22506
|
-
this.options.lspClient.logMessage({
|
|
22507
|
-
type: mainExports$2.MessageType.Info,
|
|
22508
|
-
message: `Using Typescript version (${typescriptVersion.source}) ${typescriptVersion.versionString} from path "${typescriptVersion.tsServerPath}"`
|
|
22509
|
-
});
|
|
22510
|
-
} else {
|
|
22511
|
-
throw Error('Could not find a valid TypeScript installation. Please ensure that the "typescript" dependency is installed in the workspace or that a valid `tsserver.path` is specified. Exiting.');
|
|
22405
|
+
toLspCodeAction() {
|
|
22406
|
+
const codeAction = mainExports$2.CodeAction.create(this.title, this.kind);
|
|
22407
|
+
if (this.command !== undefined) {
|
|
22408
|
+
codeAction.command = this.command;
|
|
22512
22409
|
}
|
|
22513
|
-
this.
|
|
22514
|
-
|
|
22515
|
-
|
|
22516
|
-
|
|
22517
|
-
|
|
22518
|
-
|
|
22519
|
-
|
|
22520
|
-
|
|
22521
|
-
|
|
22410
|
+
if (this.diagnostics !== undefined) {
|
|
22411
|
+
codeAction.diagnostics = this.diagnostics;
|
|
22412
|
+
}
|
|
22413
|
+
if (this.disabled !== undefined) {
|
|
22414
|
+
codeAction.disabled = this.disabled;
|
|
22415
|
+
}
|
|
22416
|
+
if (this.edit !== undefined) {
|
|
22417
|
+
codeAction.edit = this.edit;
|
|
22418
|
+
}
|
|
22419
|
+
if (this.isPreferred !== undefined) {
|
|
22420
|
+
codeAction.isPreferred = this.isPreferred;
|
|
22421
|
+
}
|
|
22422
|
+
return codeAction;
|
|
22423
|
+
}
|
|
22424
|
+
}
|
|
22425
|
+
|
|
22426
|
+
async function buildIndividualFixes(fixes, client, file, diagnostics, token) {
|
|
22427
|
+
const documentChanges = [];
|
|
22428
|
+
for (const diagnostic of diagnostics) {
|
|
22429
|
+
for (const {codes: codes, fixName: fixName} of fixes) {
|
|
22430
|
+
if (token.isCancellationRequested) {
|
|
22431
|
+
return;
|
|
22432
|
+
}
|
|
22433
|
+
if (!codes.has(diagnostic.code)) {
|
|
22434
|
+
continue;
|
|
22435
|
+
}
|
|
22436
|
+
const args = {
|
|
22437
|
+
...Range.toFileRangeRequestArgs(file, diagnostic.range),
|
|
22438
|
+
errorCodes: [ +diagnostic.code ]
|
|
22439
|
+
};
|
|
22440
|
+
const response = await client.execute(CommandTypes.GetCodeFixes, args, token);
|
|
22441
|
+
if (response.type !== 'response') {
|
|
22442
|
+
continue;
|
|
22443
|
+
}
|
|
22444
|
+
const fix = response.body?.find(fix => fix.fixName === fixName);
|
|
22445
|
+
if (fix) {
|
|
22446
|
+
documentChanges.push(...fix.changes.map(change => toTextDocumentEdit(change, client)));
|
|
22447
|
+
break;
|
|
22448
|
+
}
|
|
22449
|
+
}
|
|
22450
|
+
}
|
|
22451
|
+
return {
|
|
22452
|
+
documentChanges: documentChanges
|
|
22453
|
+
};
|
|
22454
|
+
}
|
|
22455
|
+
|
|
22456
|
+
async function buildCombinedFix(fixes, client, file, diagnostics, token) {
|
|
22457
|
+
for (const diagnostic of diagnostics) {
|
|
22458
|
+
for (const {codes: codes, fixName: fixName} of fixes) {
|
|
22459
|
+
if (token.isCancellationRequested) {
|
|
22460
|
+
return;
|
|
22461
|
+
}
|
|
22462
|
+
if (!codes.has(diagnostic.code)) {
|
|
22463
|
+
continue;
|
|
22464
|
+
}
|
|
22465
|
+
const args = {
|
|
22466
|
+
...Range.toFileRangeRequestArgs(file, diagnostic.range),
|
|
22467
|
+
errorCodes: [ +diagnostic.code ]
|
|
22468
|
+
};
|
|
22469
|
+
const response = await client.execute(CommandTypes.GetCodeFixes, args, token);
|
|
22470
|
+
if (response.type !== 'response' || !response.body?.length) {
|
|
22471
|
+
continue;
|
|
22472
|
+
}
|
|
22473
|
+
const fix = response.body?.find(fix => fix.fixName === fixName);
|
|
22474
|
+
if (!fix) {
|
|
22475
|
+
continue;
|
|
22476
|
+
}
|
|
22477
|
+
if (!fix.fixId) {
|
|
22478
|
+
return {
|
|
22479
|
+
documentChanges: fix.changes.map(change => toTextDocumentEdit(change, client))
|
|
22480
|
+
};
|
|
22481
|
+
}
|
|
22482
|
+
const combinedArgs = {
|
|
22483
|
+
scope: {
|
|
22484
|
+
type: 'file',
|
|
22485
|
+
args: {
|
|
22486
|
+
file: file
|
|
22487
|
+
}
|
|
22488
|
+
},
|
|
22489
|
+
fixId: fix.fixId
|
|
22490
|
+
};
|
|
22491
|
+
const combinedResponse = await client.execute(CommandTypes.GetCombinedCodeFix, combinedArgs, token);
|
|
22492
|
+
if (combinedResponse.type !== 'response' || !combinedResponse.body) {
|
|
22493
|
+
return;
|
|
22494
|
+
}
|
|
22495
|
+
return {
|
|
22496
|
+
documentChanges: combinedResponse.body.changes.map(change => toTextDocumentEdit(change, client))
|
|
22497
|
+
};
|
|
22498
|
+
}
|
|
22499
|
+
}
|
|
22500
|
+
}
|
|
22501
|
+
|
|
22502
|
+
class SourceAction extends TsCodeAction {}
|
|
22503
|
+
|
|
22504
|
+
class SourceFixAll extends SourceAction {
|
|
22505
|
+
constructor() {
|
|
22506
|
+
super('Fix all fixable JS/TS issues', SourceFixAll.kind.value);
|
|
22507
|
+
}
|
|
22508
|
+
async build(client, file, diagnostics, token) {
|
|
22509
|
+
this.edit = await buildIndividualFixes([ {
|
|
22510
|
+
codes: incorrectlyImplementsInterface,
|
|
22511
|
+
fixName: classIncorrectlyImplementsInterface
|
|
22512
|
+
}, {
|
|
22513
|
+
codes: asyncOnlyAllowedInAsyncFunctions,
|
|
22514
|
+
fixName: awaitInSyncFunction
|
|
22515
|
+
} ], client, file, diagnostics, token);
|
|
22516
|
+
const edits = await buildCombinedFix([ {
|
|
22517
|
+
codes: unreachableCode$1,
|
|
22518
|
+
fixName: unreachableCode
|
|
22519
|
+
} ], client, file, diagnostics, token);
|
|
22520
|
+
if (edits?.documentChanges) {
|
|
22521
|
+
this.edit?.documentChanges?.push(...edits.documentChanges);
|
|
22522
|
+
}
|
|
22523
|
+
}
|
|
22524
|
+
}
|
|
22525
|
+
|
|
22526
|
+
SourceFixAll.kind = CodeActionKind.SourceFixAllTs;
|
|
22527
|
+
|
|
22528
|
+
class SourceRemoveUnused extends SourceAction {
|
|
22529
|
+
constructor() {
|
|
22530
|
+
super('Remove all unused code', SourceRemoveUnused.kind.value);
|
|
22531
|
+
}
|
|
22532
|
+
async build(client, file, diagnostics, token) {
|
|
22533
|
+
this.edit = await buildCombinedFix([ {
|
|
22534
|
+
codes: variableDeclaredButNeverUsed,
|
|
22535
|
+
fixName: unusedIdentifier
|
|
22536
|
+
} ], client, file, diagnostics, token);
|
|
22537
|
+
}
|
|
22538
|
+
}
|
|
22539
|
+
|
|
22540
|
+
SourceRemoveUnused.kind = CodeActionKind.SourceRemoveUnusedTs;
|
|
22541
|
+
|
|
22542
|
+
class SourceAddMissingImports extends SourceAction {
|
|
22543
|
+
constructor() {
|
|
22544
|
+
super('Add all missing imports', SourceAddMissingImports.kind.value);
|
|
22545
|
+
}
|
|
22546
|
+
async build(client, file, diagnostics, token) {
|
|
22547
|
+
this.edit = await buildCombinedFix([ {
|
|
22548
|
+
codes: cannotFindName,
|
|
22549
|
+
fixName: fixImport
|
|
22550
|
+
} ], client, file, diagnostics, token);
|
|
22551
|
+
}
|
|
22552
|
+
}
|
|
22553
|
+
|
|
22554
|
+
SourceAddMissingImports.kind = CodeActionKind.SourceAddMissingImportsTs;
|
|
22555
|
+
|
|
22556
|
+
class TypeScriptAutoFixProvider {
|
|
22557
|
+
constructor(client, fileConfigurationManager, diagnosticsManager) {
|
|
22558
|
+
this.client = client;
|
|
22559
|
+
this.fileConfigurationManager = fileConfigurationManager;
|
|
22560
|
+
this.diagnosticsManager = diagnosticsManager;
|
|
22561
|
+
}
|
|
22562
|
+
getMetadata() {
|
|
22563
|
+
return {
|
|
22564
|
+
providedCodeActionKinds: TypeScriptAutoFixProvider.kindProviders.map(x => x.kind.value)
|
|
22565
|
+
};
|
|
22566
|
+
}
|
|
22567
|
+
async provideCodeActions(document, _range, context, token) {
|
|
22568
|
+
if (!context.only?.length) {
|
|
22569
|
+
return undefined;
|
|
22570
|
+
}
|
|
22571
|
+
const sourceKinds = context.only.map(kind => new CodeActionKind(kind)).filter(codeActionKind => CodeActionKind.Source.intersects(codeActionKind));
|
|
22572
|
+
if (!sourceKinds.length) {
|
|
22573
|
+
return undefined;
|
|
22574
|
+
}
|
|
22575
|
+
if (this.client.hasPendingDiagnostics(document.uri)) {
|
|
22576
|
+
return undefined;
|
|
22577
|
+
}
|
|
22578
|
+
const actions = this.getFixAllActions(sourceKinds);
|
|
22579
|
+
const diagnostics = this.diagnosticsManager.getDiagnosticsForFile(document.filepath);
|
|
22580
|
+
if (!diagnostics.length) {
|
|
22581
|
+
return actions;
|
|
22582
|
+
}
|
|
22583
|
+
await this.fileConfigurationManager.ensureConfigurationForDocument(document, token);
|
|
22584
|
+
if (token.isCancellationRequested) {
|
|
22585
|
+
return undefined;
|
|
22586
|
+
}
|
|
22587
|
+
await Promise.all(actions.map(action => action.build(this.client, document.filepath, diagnostics, token)));
|
|
22588
|
+
return actions;
|
|
22589
|
+
}
|
|
22590
|
+
isCodeActionResolvable(_codeAction) {
|
|
22591
|
+
return false;
|
|
22592
|
+
}
|
|
22593
|
+
getFixAllActions(kinds) {
|
|
22594
|
+
return TypeScriptAutoFixProvider.kindProviders.filter(provider => kinds.some(only => only.intersects(provider.kind))).map(provider => new provider);
|
|
22595
|
+
}
|
|
22596
|
+
}
|
|
22597
|
+
|
|
22598
|
+
TypeScriptAutoFixProvider.kindProviders = [ SourceFixAll, SourceRemoveUnused, SourceAddMissingImports ];
|
|
22599
|
+
|
|
22600
|
+
class Lazy {
|
|
22601
|
+
constructor(executor) {
|
|
22602
|
+
this.executor = executor;
|
|
22603
|
+
this._didRun = false;
|
|
22604
|
+
}
|
|
22605
|
+
get hasValue() {
|
|
22606
|
+
return this._didRun;
|
|
22607
|
+
}
|
|
22608
|
+
get value() {
|
|
22609
|
+
if (!this._didRun) {
|
|
22610
|
+
try {
|
|
22611
|
+
this._value = this.executor();
|
|
22612
|
+
} catch (err) {
|
|
22613
|
+
this._error = err;
|
|
22614
|
+
} finally {
|
|
22615
|
+
this._didRun = true;
|
|
22616
|
+
}
|
|
22617
|
+
}
|
|
22618
|
+
if (this._error) {
|
|
22619
|
+
throw this._error;
|
|
22620
|
+
}
|
|
22621
|
+
return this._value;
|
|
22622
|
+
}
|
|
22623
|
+
get rawValue() {
|
|
22624
|
+
return this._value;
|
|
22625
|
+
}
|
|
22626
|
+
}
|
|
22627
|
+
|
|
22628
|
+
function getEditForCodeAction(client, action) {
|
|
22629
|
+
return action.changes?.length ? {
|
|
22630
|
+
documentChanges: action.changes.map(change => toTextDocumentEdit(change, client))
|
|
22631
|
+
} : undefined;
|
|
22632
|
+
}
|
|
22633
|
+
|
|
22634
|
+
async function applyCodeActionCommands(client, commands, token) {
|
|
22635
|
+
if (commands?.length) {
|
|
22636
|
+
for (const command of commands) {
|
|
22637
|
+
await client.execute(CommandTypes.ApplyCodeActionCommand, {
|
|
22638
|
+
command: command
|
|
22639
|
+
}, token);
|
|
22640
|
+
}
|
|
22641
|
+
}
|
|
22642
|
+
return true;
|
|
22643
|
+
}
|
|
22644
|
+
|
|
22645
|
+
class ApplyCodeActionCommand {
|
|
22646
|
+
constructor(client) {
|
|
22647
|
+
this.client = client;
|
|
22648
|
+
this.id = ApplyCodeActionCommand.ID;
|
|
22649
|
+
}
|
|
22650
|
+
async execute({action: action}) {
|
|
22651
|
+
const codeActionResult = await applyCodeActionCommands(this.client, action.commands);
|
|
22652
|
+
return codeActionResult;
|
|
22653
|
+
}
|
|
22654
|
+
}
|
|
22655
|
+
|
|
22656
|
+
ApplyCodeActionCommand.ID = '_typescript.applyCodeActionCommand';
|
|
22657
|
+
|
|
22658
|
+
class ApplyFixAllCodeAction {
|
|
22659
|
+
constructor(client, tsCodeActionProvider) {
|
|
22660
|
+
this.client = client;
|
|
22661
|
+
this.tsCodeActionProvider = tsCodeActionProvider;
|
|
22662
|
+
this.id = ApplyFixAllCodeAction.ID;
|
|
22663
|
+
}
|
|
22664
|
+
async execute(args) {
|
|
22665
|
+
const tsAction = this.tsCodeActionProvider.getQuickFixAllTsCodeActionByFixName(args.tsActionId);
|
|
22666
|
+
if (tsAction instanceof TsQuickFixAllCodeAction && tsAction.combinedResponse) {
|
|
22667
|
+
await applyCodeActionCommands(this.client, tsAction.combinedResponse.body.commands);
|
|
22668
|
+
}
|
|
22669
|
+
}
|
|
22670
|
+
}
|
|
22671
|
+
|
|
22672
|
+
ApplyFixAllCodeAction.ID = '_typescript.applyFixAllCodeAction';
|
|
22673
|
+
|
|
22674
|
+
class DiagnosticsSet {
|
|
22675
|
+
static from(diagnostics) {
|
|
22676
|
+
const values = new Map;
|
|
22677
|
+
for (const diagnostic of diagnostics) {
|
|
22678
|
+
values.set(DiagnosticsSet.key(diagnostic), diagnostic);
|
|
22679
|
+
}
|
|
22680
|
+
return new DiagnosticsSet(values);
|
|
22681
|
+
}
|
|
22682
|
+
static key(diagnostic) {
|
|
22683
|
+
const {start: start, end: end} = diagnostic.range;
|
|
22684
|
+
return `${diagnostic.code}-${start.line},${start.character}-${end.line},${end.character}`;
|
|
22685
|
+
}
|
|
22686
|
+
constructor(_values) {
|
|
22687
|
+
this._values = _values;
|
|
22688
|
+
}
|
|
22689
|
+
get values() {
|
|
22690
|
+
return this._values.values();
|
|
22691
|
+
}
|
|
22692
|
+
get size() {
|
|
22693
|
+
return this._values.size;
|
|
22694
|
+
}
|
|
22695
|
+
}
|
|
22696
|
+
|
|
22697
|
+
class TsQuickFixCodeAction extends TsCodeAction {
|
|
22698
|
+
constructor(tsAction, title, kind) {
|
|
22699
|
+
super(title, kind);
|
|
22700
|
+
this.tsAction = tsAction;
|
|
22701
|
+
}
|
|
22702
|
+
}
|
|
22703
|
+
|
|
22704
|
+
class TsQuickFixAllCodeAction extends TsQuickFixCodeAction {
|
|
22705
|
+
constructor(tsAction, file, title, kind) {
|
|
22706
|
+
super(tsAction, title, kind);
|
|
22707
|
+
this.file = file;
|
|
22708
|
+
}
|
|
22709
|
+
}
|
|
22710
|
+
|
|
22711
|
+
class CodeActionSet {
|
|
22712
|
+
constructor() {
|
|
22713
|
+
this._actions = new Set;
|
|
22714
|
+
this._fixAllActions = new Map;
|
|
22715
|
+
this._aiActions = new Set;
|
|
22716
|
+
}
|
|
22717
|
+
* values() {
|
|
22718
|
+
yield* this._actions;
|
|
22719
|
+
yield* this._aiActions;
|
|
22720
|
+
}
|
|
22721
|
+
addAction(action) {
|
|
22722
|
+
for (const existing of this._actions) {
|
|
22723
|
+
if (action.tsAction.fixName === existing.tsAction.fixName && equals(action.edit, existing.edit)) {
|
|
22724
|
+
this._actions.delete(existing);
|
|
22725
|
+
}
|
|
22726
|
+
}
|
|
22727
|
+
this._actions.add(action);
|
|
22728
|
+
if (action.tsAction.fixId) {
|
|
22729
|
+
const existingFixAll = this._fixAllActions.get(action.tsAction.fixId);
|
|
22730
|
+
if (existingFixAll) {
|
|
22731
|
+
this._actions.delete(existingFixAll);
|
|
22732
|
+
this._actions.add(existingFixAll);
|
|
22733
|
+
}
|
|
22734
|
+
}
|
|
22735
|
+
}
|
|
22736
|
+
addFixAllAction(fixId, action) {
|
|
22737
|
+
const existing = this._fixAllActions.get(fixId);
|
|
22738
|
+
if (existing) {
|
|
22739
|
+
this._actions.delete(existing);
|
|
22740
|
+
}
|
|
22741
|
+
this.addAction(action);
|
|
22742
|
+
this._fixAllActions.set(fixId, action);
|
|
22743
|
+
}
|
|
22744
|
+
hasFixAllAction(fixId) {
|
|
22745
|
+
return this._fixAllActions.has(fixId);
|
|
22746
|
+
}
|
|
22747
|
+
}
|
|
22748
|
+
|
|
22749
|
+
class SupportedCodeActionProvider {
|
|
22750
|
+
constructor(client) {
|
|
22751
|
+
this.client = client;
|
|
22752
|
+
this.fixableDiagnosticCodes = new Lazy(() => this.client.execute(CommandTypes.GetSupportedCodeFixes, null).then(response => response.type === 'response' ? response.body || [] : []).then(codes => new Set(codes)));
|
|
22753
|
+
}
|
|
22754
|
+
async getFixableDiagnosticsForContext(diagnostics) {
|
|
22755
|
+
const fixableCodes = await this.fixableDiagnosticCodes.value;
|
|
22756
|
+
return DiagnosticsSet.from(diagnostics.filter(diagnostic => typeof diagnostic.code !== 'undefined' && fixableCodes.has(diagnostic.code + '')));
|
|
22757
|
+
}
|
|
22758
|
+
}
|
|
22759
|
+
|
|
22760
|
+
class TypeScriptQuickFixProvider {
|
|
22761
|
+
constructor(client, fileConfigurationManager, commandManager, diagnosticsManager, features) {
|
|
22762
|
+
this.client = client;
|
|
22763
|
+
this.fileConfigurationManager = fileConfigurationManager;
|
|
22764
|
+
this.diagnosticsManager = diagnosticsManager;
|
|
22765
|
+
this.features = features;
|
|
22766
|
+
this._quickFixAllTsCodeActionMap = new Map;
|
|
22767
|
+
commandManager.register(new ApplyCodeActionCommand(client));
|
|
22768
|
+
commandManager.register(new ApplyFixAllCodeAction(client, this));
|
|
22769
|
+
this.supportedCodeActionProvider = new SupportedCodeActionProvider(client);
|
|
22770
|
+
}
|
|
22771
|
+
getMetadata() {
|
|
22772
|
+
return {
|
|
22773
|
+
providedCodeActionKinds: [ CodeActionKind.QuickFix.value ]
|
|
22774
|
+
};
|
|
22775
|
+
}
|
|
22776
|
+
async provideCodeActions(document, range, context, token) {
|
|
22777
|
+
this._quickFixAllTsCodeActionMap.clear();
|
|
22778
|
+
let diagnostics = context.diagnostics;
|
|
22779
|
+
if (this.client.hasPendingDiagnostics(document.uri)) {
|
|
22780
|
+
await new Promise(resolve => {
|
|
22781
|
+
setTimeout(resolve, 500);
|
|
22782
|
+
});
|
|
22783
|
+
if (token.isCancellationRequested) {
|
|
22784
|
+
return;
|
|
22785
|
+
}
|
|
22786
|
+
const allDiagnostics = [];
|
|
22787
|
+
for (const diagnostic of this.diagnosticsManager.getDiagnosticsForFile(document.filepath)) {
|
|
22788
|
+
if (Range.intersection(range, diagnostic.range)) {
|
|
22789
|
+
const newLen = allDiagnostics.push(diagnostic);
|
|
22790
|
+
if (newLen > TypeScriptQuickFixProvider._maxCodeActionsPerFile) {
|
|
22791
|
+
break;
|
|
22792
|
+
}
|
|
22793
|
+
}
|
|
22794
|
+
}
|
|
22795
|
+
diagnostics = allDiagnostics;
|
|
22796
|
+
}
|
|
22797
|
+
const fixableDiagnostics = await this.supportedCodeActionProvider.getFixableDiagnosticsForContext(diagnostics);
|
|
22798
|
+
if (!fixableDiagnostics.size || token.isCancellationRequested) {
|
|
22799
|
+
return;
|
|
22800
|
+
}
|
|
22801
|
+
await this.fileConfigurationManager.ensureConfigurationForDocument(document, token);
|
|
22802
|
+
if (token.isCancellationRequested) {
|
|
22803
|
+
return;
|
|
22804
|
+
}
|
|
22805
|
+
const results = new CodeActionSet;
|
|
22806
|
+
for (const diagnostic of fixableDiagnostics.values) {
|
|
22807
|
+
await this.getFixesForDiagnostic(document, diagnostic, results, token);
|
|
22808
|
+
if (token.isCancellationRequested) {
|
|
22809
|
+
return;
|
|
22810
|
+
}
|
|
22811
|
+
}
|
|
22812
|
+
const allActions = Array.from(results.values());
|
|
22813
|
+
for (const action of allActions) {
|
|
22814
|
+
action.isPreferred = isPreferredFix(action, allActions);
|
|
22815
|
+
}
|
|
22816
|
+
return allActions;
|
|
22817
|
+
}
|
|
22818
|
+
isCodeActionResolvable(codeAction) {
|
|
22819
|
+
return codeAction instanceof TsQuickFixAllCodeAction;
|
|
22820
|
+
}
|
|
22821
|
+
async resolveCodeAction(codeAction, token) {
|
|
22822
|
+
if (!this.isCodeActionResolvable(codeAction) || !codeAction.tsAction.fixId) {
|
|
22823
|
+
return codeAction;
|
|
22824
|
+
}
|
|
22825
|
+
const arg = {
|
|
22826
|
+
scope: {
|
|
22827
|
+
type: 'file',
|
|
22828
|
+
args: {
|
|
22829
|
+
file: codeAction.file
|
|
22830
|
+
}
|
|
22831
|
+
},
|
|
22832
|
+
fixId: codeAction.tsAction.fixId
|
|
22833
|
+
};
|
|
22834
|
+
const response = await this.client.execute(CommandTypes.GetCombinedCodeFix, arg, token);
|
|
22835
|
+
if (response.type === 'response') {
|
|
22836
|
+
codeAction.combinedResponse = response;
|
|
22837
|
+
codeAction.edit = {
|
|
22838
|
+
documentChanges: response.body.changes.map(change => toTextDocumentEdit(change, this.client))
|
|
22839
|
+
};
|
|
22840
|
+
}
|
|
22841
|
+
return codeAction;
|
|
22842
|
+
}
|
|
22843
|
+
getQuickFixAllTsCodeActionByFixName(fixName) {
|
|
22844
|
+
return this._quickFixAllTsCodeActionMap.get(fixName);
|
|
22845
|
+
}
|
|
22846
|
+
async getFixesForDiagnostic(document, diagnostic, results, token) {
|
|
22847
|
+
const args = {
|
|
22848
|
+
...Range.toFileRangeRequestArgs(document.filepath, diagnostic.range),
|
|
22849
|
+
errorCodes: [ +diagnostic.code ]
|
|
22850
|
+
};
|
|
22851
|
+
const response = await this.client.execute(CommandTypes.GetCodeFixes, args, token);
|
|
22852
|
+
if (response.type !== 'response' || !response.body) {
|
|
22853
|
+
return results;
|
|
22854
|
+
}
|
|
22855
|
+
for (const tsCodeFix of response.body) {
|
|
22856
|
+
for (const action of this.getFixesForTsCodeAction(document, diagnostic, tsCodeFix)) {
|
|
22857
|
+
results.addAction(action);
|
|
22858
|
+
}
|
|
22859
|
+
if (this.features.codeActionResolveSupport) {
|
|
22860
|
+
this.addFixAllForTsCodeAction(results, document.uri, document.filepath, diagnostic, tsCodeFix);
|
|
22861
|
+
}
|
|
22862
|
+
}
|
|
22863
|
+
return results;
|
|
22864
|
+
}
|
|
22865
|
+
getFixesForTsCodeAction(document, diagnostic, action) {
|
|
22866
|
+
const actions = [];
|
|
22867
|
+
const codeAction = new TsQuickFixCodeAction(action, action.description, mainExports$2.CodeActionKind.QuickFix);
|
|
22868
|
+
codeAction.edit = getEditForCodeAction(this.client, action);
|
|
22869
|
+
codeAction.diagnostics = [ diagnostic ];
|
|
22870
|
+
codeAction.command = {
|
|
22871
|
+
command: ApplyCodeActionCommand.ID,
|
|
22872
|
+
arguments: [ {
|
|
22873
|
+
action: action,
|
|
22874
|
+
diagnostic: diagnostic,
|
|
22875
|
+
documentUri: document.uri.toString()
|
|
22876
|
+
} ],
|
|
22877
|
+
title: ''
|
|
22878
|
+
};
|
|
22879
|
+
actions.push(codeAction);
|
|
22880
|
+
return actions;
|
|
22881
|
+
}
|
|
22882
|
+
addFixAllForTsCodeAction(results, _resource, file, diagnostic, tsAction) {
|
|
22883
|
+
if (!tsAction.fixId || results.hasFixAllAction(tsAction.fixId)) {
|
|
22884
|
+
return results;
|
|
22885
|
+
}
|
|
22886
|
+
if (!this.diagnosticsManager.getDiagnosticsForFile(file).some(x => {
|
|
22887
|
+
if (x === diagnostic) {
|
|
22888
|
+
return false;
|
|
22889
|
+
}
|
|
22890
|
+
return x.code === diagnostic.code || fixAllErrorCodes.has(x.code) && fixAllErrorCodes.get(x.code) === fixAllErrorCodes.get(diagnostic.code);
|
|
22891
|
+
})) {
|
|
22892
|
+
return results;
|
|
22893
|
+
}
|
|
22894
|
+
const action = new TsQuickFixAllCodeAction(tsAction, file, tsAction.fixAllDescription || `${tsAction.description} (Fix all in file)`, mainExports$2.CodeActionKind.QuickFix);
|
|
22895
|
+
action.diagnostics = [ diagnostic ];
|
|
22896
|
+
action.command = {
|
|
22897
|
+
command: ApplyFixAllCodeAction.ID,
|
|
22898
|
+
arguments: [ {
|
|
22899
|
+
tsActionId: tsAction.fixName
|
|
22900
|
+
} ],
|
|
22901
|
+
title: ''
|
|
22902
|
+
};
|
|
22903
|
+
this._quickFixAllTsCodeActionMap.set(tsAction.fixName, action);
|
|
22904
|
+
results.addFixAllAction(tsAction.fixId, action);
|
|
22905
|
+
return results;
|
|
22906
|
+
}
|
|
22907
|
+
}
|
|
22908
|
+
|
|
22909
|
+
TypeScriptQuickFixProvider._maxCodeActionsPerFile = 1e3;
|
|
22910
|
+
|
|
22911
|
+
const fixAllErrorCodes = new Map([ [ 2339, 2339 ], [ 2345, 2339 ] ]);
|
|
22912
|
+
|
|
22913
|
+
const preferredFixes = new Map([ [ annotateWithTypeFromJSDoc, {
|
|
22914
|
+
priority: 2
|
|
22915
|
+
} ], [ constructorForDerivedNeedSuperCall, {
|
|
22916
|
+
priority: 2
|
|
22917
|
+
} ], [ extendsInterfaceBecomesImplements, {
|
|
22918
|
+
priority: 2
|
|
22919
|
+
} ], [ awaitInSyncFunction, {
|
|
22920
|
+
priority: 2
|
|
22921
|
+
} ], [ removeUnnecessaryAwait, {
|
|
22922
|
+
priority: 2
|
|
22923
|
+
} ], [ classIncorrectlyImplementsInterface, {
|
|
22924
|
+
priority: 3
|
|
22925
|
+
} ], [ classDoesntImplementInheritedAbstractMember, {
|
|
22926
|
+
priority: 3
|
|
22927
|
+
} ], [ unreachableCode, {
|
|
22928
|
+
priority: 2
|
|
22929
|
+
} ], [ unusedIdentifier, {
|
|
22930
|
+
priority: 2
|
|
22931
|
+
} ], [ forgottenThisPropertyAccess, {
|
|
22932
|
+
priority: 2
|
|
22933
|
+
} ], [ spelling, {
|
|
22934
|
+
priority: 0
|
|
22935
|
+
} ], [ addMissingAwait, {
|
|
22936
|
+
priority: 2
|
|
22937
|
+
} ], [ addMissingOverride, {
|
|
22938
|
+
priority: 2
|
|
22939
|
+
} ], [ addMissingNewOperator, {
|
|
22940
|
+
priority: 2
|
|
22941
|
+
} ], [ fixImport, {
|
|
22942
|
+
priority: 1,
|
|
22943
|
+
thereCanOnlyBeOne: true
|
|
22944
|
+
} ] ]);
|
|
22945
|
+
|
|
22946
|
+
function isPreferredFix(action, allActions) {
|
|
22947
|
+
if (action instanceof TsQuickFixAllCodeAction) {
|
|
22948
|
+
return false;
|
|
22949
|
+
}
|
|
22950
|
+
const fixPriority = preferredFixes.get(action.tsAction.fixName);
|
|
22951
|
+
if (!fixPriority) {
|
|
22952
|
+
return false;
|
|
22953
|
+
}
|
|
22954
|
+
return allActions.every(otherAction => {
|
|
22955
|
+
if (otherAction === action) {
|
|
22956
|
+
return true;
|
|
22957
|
+
}
|
|
22958
|
+
if (otherAction instanceof TsQuickFixAllCodeAction) {
|
|
22959
|
+
return true;
|
|
22960
|
+
}
|
|
22961
|
+
const otherFixPriority = preferredFixes.get(otherAction.tsAction.fixName);
|
|
22962
|
+
if (!otherFixPriority || otherFixPriority.priority < fixPriority.priority) {
|
|
22963
|
+
return true;
|
|
22964
|
+
} else if (otherFixPriority.priority > fixPriority.priority) {
|
|
22965
|
+
return false;
|
|
22966
|
+
}
|
|
22967
|
+
if (fixPriority.thereCanOnlyBeOne && action.tsAction.fixName === otherAction.tsAction.fixName) {
|
|
22968
|
+
return false;
|
|
22969
|
+
}
|
|
22970
|
+
return true;
|
|
22971
|
+
});
|
|
22972
|
+
}
|
|
22973
|
+
|
|
22974
|
+
const noopDisposable = mainExports$2.Disposable.create(() => {});
|
|
22975
|
+
|
|
22976
|
+
const nulToken = {
|
|
22977
|
+
isCancellationRequested: false,
|
|
22978
|
+
onCancellationRequested: () => noopDisposable
|
|
22979
|
+
};
|
|
22980
|
+
|
|
22981
|
+
class CodeActionManager {
|
|
22982
|
+
constructor(client, fileConfigurationManager, commandManager, diagnosticsManager, features) {
|
|
22983
|
+
this.features = features;
|
|
22984
|
+
this.providerMap = new Map;
|
|
22985
|
+
this.nextProviderId = 1;
|
|
22986
|
+
this.resolveCodeActionsMap = new Map;
|
|
22987
|
+
this.nextGlobalCodeActionId = 1;
|
|
22988
|
+
this.addProvider(new TypeScriptAutoFixProvider(client, fileConfigurationManager, diagnosticsManager));
|
|
22989
|
+
this.addProvider(new TypeScriptQuickFixProvider(client, fileConfigurationManager, commandManager, diagnosticsManager, features));
|
|
22990
|
+
}
|
|
22991
|
+
get kinds() {
|
|
22992
|
+
const allKinds = [];
|
|
22993
|
+
for (const [_, provider] of this.providerMap) {
|
|
22994
|
+
allKinds.push(...provider.getMetadata().providedCodeActionKinds || []);
|
|
22995
|
+
}
|
|
22996
|
+
return allKinds;
|
|
22997
|
+
}
|
|
22998
|
+
async provideCodeActions(document, range, context, token) {
|
|
22999
|
+
this.resolveCodeActionsMap.clear();
|
|
23000
|
+
const allCodeActions = [];
|
|
23001
|
+
for (const [providerId, provider] of this.providerMap.entries()) {
|
|
23002
|
+
const codeActions = await provider.provideCodeActions(document, range, context, token || nulToken);
|
|
23003
|
+
if (!codeActions) {
|
|
23004
|
+
continue;
|
|
23005
|
+
}
|
|
23006
|
+
for (const action of codeActions) {
|
|
23007
|
+
if (mainExports$2.Command.is(action)) {
|
|
23008
|
+
allCodeActions.push(action);
|
|
23009
|
+
continue;
|
|
23010
|
+
}
|
|
23011
|
+
const lspCodeAction = action.toLspCodeAction();
|
|
23012
|
+
if (provider.isCodeActionResolvable(action)) {
|
|
23013
|
+
const globalId = this.nextGlobalCodeActionId++;
|
|
23014
|
+
this.resolveCodeActionsMap.set(globalId, action);
|
|
23015
|
+
lspCodeAction.data = {
|
|
23016
|
+
globalId: globalId,
|
|
23017
|
+
providerId: providerId
|
|
23018
|
+
};
|
|
23019
|
+
}
|
|
23020
|
+
allCodeActions.push(lspCodeAction);
|
|
23021
|
+
}
|
|
23022
|
+
}
|
|
23023
|
+
return allCodeActions;
|
|
23024
|
+
}
|
|
23025
|
+
async resolveCodeAction(codeAction, token) {
|
|
23026
|
+
if (!this.features.codeActionResolveSupport) {
|
|
23027
|
+
return codeAction;
|
|
23028
|
+
}
|
|
23029
|
+
const {globalId: globalId, providerId: providerId} = codeAction.data || {};
|
|
23030
|
+
if (globalId === undefined || providerId === undefined) {
|
|
23031
|
+
return codeAction;
|
|
23032
|
+
}
|
|
23033
|
+
const provider = this.providerMap.get(providerId);
|
|
23034
|
+
if (!provider || !provider.resolveCodeAction) {
|
|
23035
|
+
return codeAction;
|
|
23036
|
+
}
|
|
23037
|
+
const tsCodeAction = this.resolveCodeActionsMap.get(globalId);
|
|
23038
|
+
if (!tsCodeAction || !providerId) {
|
|
23039
|
+
return codeAction;
|
|
23040
|
+
}
|
|
23041
|
+
const resolvedTsCodeAction = await provider.resolveCodeAction(tsCodeAction, token || nulToken);
|
|
23042
|
+
if (!resolvedTsCodeAction) {
|
|
23043
|
+
return codeAction;
|
|
23044
|
+
}
|
|
23045
|
+
const lspCodeAction = resolvedTsCodeAction.toLspCodeAction();
|
|
23046
|
+
for (const property of this.features.codeActionResolveSupport.properties) {
|
|
23047
|
+
if (property in lspCodeAction) {
|
|
23048
|
+
codeAction[property] = lspCodeAction[property];
|
|
23049
|
+
}
|
|
23050
|
+
}
|
|
23051
|
+
return codeAction;
|
|
23052
|
+
}
|
|
23053
|
+
addProvider(provider) {
|
|
23054
|
+
this.providerMap.set(this.nextProviderId++, provider);
|
|
23055
|
+
}
|
|
23056
|
+
}
|
|
23057
|
+
|
|
23058
|
+
class LspServer {
|
|
23059
|
+
constructor(options) {
|
|
23060
|
+
this.options = options;
|
|
23061
|
+
this.initializeParams = null;
|
|
23062
|
+
this.completionDataCache = new CompletionDataCache;
|
|
23063
|
+
this.features = {};
|
|
23064
|
+
this.cachedNavTreeResponse = new CachedResponse;
|
|
23065
|
+
this.implementationsCodeLensProvider = null;
|
|
23066
|
+
this.referencesCodeLensProvider = null;
|
|
23067
|
+
this.logger = new PrefixingLogger(options.logger, '[lspserver]');
|
|
23068
|
+
this.tsClient = new TsClient(onCaseInsensitiveFileSystem(), this.logger, options.lspClient);
|
|
23069
|
+
this.fileConfigurationManager = new FileConfigurationManager(this.tsClient, onCaseInsensitiveFileSystem());
|
|
23070
|
+
this.commandManager = new CommandManager;
|
|
23071
|
+
this.diagnosticsManager = new DiagnosticsManager(diagnostics => this.options.lspClient.publishDiagnostics(diagnostics), this.tsClient, this.features, this.logger);
|
|
23072
|
+
this.codeActionsManager = new CodeActionManager(this.tsClient, this.fileConfigurationManager, this.commandManager, this.diagnosticsManager, this.features);
|
|
23073
|
+
}
|
|
23074
|
+
closeAllForTesting() {
|
|
23075
|
+
for (const document of this.tsClient.documentsForTesting.values()) {
|
|
23076
|
+
this.closeDocument(document.uri.toString());
|
|
23077
|
+
}
|
|
23078
|
+
}
|
|
23079
|
+
async waitForDiagnosticsForFile(uri) {
|
|
23080
|
+
const document = this.tsClient.toOpenDocument(uri);
|
|
23081
|
+
if (!document) {
|
|
23082
|
+
throw new Error(`Document not open: ${uri}`);
|
|
23083
|
+
}
|
|
23084
|
+
await this.diagnosticsManager.waitForDiagnosticsForTesting(document.filepath);
|
|
23085
|
+
}
|
|
23086
|
+
shutdown() {
|
|
23087
|
+
this.tsClient.shutdown();
|
|
23088
|
+
}
|
|
23089
|
+
initialize(params) {
|
|
23090
|
+
this.initializeParams = params;
|
|
23091
|
+
const clientCapabilities = this.initializeParams.capabilities;
|
|
23092
|
+
this.workspaceRoot = this.initializeParams.rootUri ? URI.parse(this.initializeParams.rootUri).fsPath : this.initializeParams.rootPath || undefined;
|
|
23093
|
+
const userInitializationOptions = this.initializeParams.initializationOptions || {};
|
|
23094
|
+
const {disableAutomaticTypingAcquisition: disableAutomaticTypingAcquisition, hostInfo: hostInfo, maxTsServerMemory: maxTsServerMemory, npmLocation: npmLocation, locale: locale, plugins: plugins, tsserver: tsserver} = userInitializationOptions;
|
|
23095
|
+
const typescriptVersion = this.findTypescriptVersion(tsserver?.path, tsserver?.fallbackPath);
|
|
23096
|
+
if (typescriptVersion) {
|
|
23097
|
+
this.options.lspClient.logMessage({
|
|
23098
|
+
type: mainExports$2.MessageType.Info,
|
|
23099
|
+
message: `Using Typescript version (${typescriptVersion.source}) ${typescriptVersion.versionString} from path "${typescriptVersion.tsServerPath}"`
|
|
23100
|
+
});
|
|
23101
|
+
} else {
|
|
23102
|
+
throw Error('Could not find a valid TypeScript installation. Please ensure that the "typescript" dependency is installed in the workspace or that a valid `tsserver.path` is specified. Exiting.');
|
|
23103
|
+
}
|
|
23104
|
+
this.fileConfigurationManager.mergeTsPreferences(userInitializationOptions.preferences || {});
|
|
23105
|
+
this.features.completionDisableFilterText = userInitializationOptions.completionDisableFilterText ?? false;
|
|
23106
|
+
this.features.moveToFileCodeActionSupport = userInitializationOptions.supportsMoveToFileCodeAction && typescriptVersion.version?.gte(API.v520);
|
|
23107
|
+
const {textDocument: textDocument} = clientCapabilities;
|
|
23108
|
+
if (textDocument) {
|
|
23109
|
+
const {codeAction: codeAction, completion: completion, definition: definition, publishDiagnostics: publishDiagnostics} = textDocument;
|
|
23110
|
+
if (codeAction) {
|
|
23111
|
+
this.features.codeActionDisabledSupport = codeAction.disabledSupport;
|
|
23112
|
+
this.features.codeActionResolveSupport = codeAction.resolveSupport;
|
|
23113
|
+
}
|
|
22522
23114
|
if (completion) {
|
|
22523
23115
|
const {completionItem: completionItem} = completion;
|
|
22524
23116
|
if (completionItem) {
|
|
@@ -22568,10 +23160,10 @@ class LspServer {
|
|
|
22568
23160
|
process.on('SIGINT', () => {
|
|
22569
23161
|
process.exit();
|
|
22570
23162
|
});
|
|
22571
|
-
this.typeScriptAutoFixProvider = new TypeScriptAutoFixProvider(this.tsClient);
|
|
22572
23163
|
this.fileConfigurationManager.setGlobalConfiguration(this.workspaceRoot, hostInfo);
|
|
22573
23164
|
this.registerHandlers();
|
|
22574
23165
|
const prepareSupport = textDocument?.rename?.prepareSupport && this.tsClient.apiVersion.gte(API.v310);
|
|
23166
|
+
const {codeActionLiteralSupport: codeActionLiteralSupport, resolveSupport: codeActionResolveSupport} = textDocument?.codeAction || {};
|
|
22575
23167
|
const initializeResult = {
|
|
22576
23168
|
capabilities: {
|
|
22577
23169
|
textDocumentSync: mainExports$2.TextDocumentSyncKind.Incremental,
|
|
@@ -22579,8 +23171,13 @@ class LspServer {
|
|
|
22579
23171
|
triggerCharacters: [ '.', '"', '\'', '/', '@', '<' ],
|
|
22580
23172
|
resolveProvider: true
|
|
22581
23173
|
},
|
|
22582
|
-
codeActionProvider:
|
|
22583
|
-
|
|
23174
|
+
codeActionProvider: codeActionLiteralSupport || codeActionResolveSupport ? {
|
|
23175
|
+
...codeActionLiteralSupport ? {
|
|
23176
|
+
codeActionKinds: [ ...this.codeActionsManager.kinds, CodeActionKind.SourceOrganizeImportsTs.value, CodeActionKind.SourceRemoveUnusedImportsTs.value, CodeActionKind.SourceSortImportsTs.value, CodeActionKind.Refactor.value ]
|
|
23177
|
+
} : {},
|
|
23178
|
+
...codeActionResolveSupport ? {
|
|
23179
|
+
resolveProvider: true
|
|
23180
|
+
} : {}
|
|
22584
23181
|
} : true,
|
|
22585
23182
|
codeLensProvider: {
|
|
22586
23183
|
resolveProvider: true
|
|
@@ -22591,7 +23188,7 @@ class LspServer {
|
|
|
22591
23188
|
documentHighlightProvider: true,
|
|
22592
23189
|
documentSymbolProvider: true,
|
|
22593
23190
|
executeCommandProvider: {
|
|
22594
|
-
commands: [ Commands.
|
|
23191
|
+
commands: [ Commands.APPLY_REFACTORING, Commands.CONFIGURE_PLUGIN, Commands.ORGANIZE_IMPORTS, Commands.APPLY_RENAME_FILE, Commands.SOURCE_DEFINITION, Commands.TS_SERVER_REQUEST ]
|
|
22595
23192
|
},
|
|
22596
23193
|
hoverProvider: true,
|
|
22597
23194
|
inlayHintProvider: true,
|
|
@@ -22702,7 +23299,7 @@ class LspServer {
|
|
|
22702
23299
|
didChangeConfiguration(params) {
|
|
22703
23300
|
this.fileConfigurationManager.setWorkspaceConfiguration(params.settings || {});
|
|
22704
23301
|
const ignoredDiagnosticCodes = this.fileConfigurationManager.workspaceConfiguration.diagnostics?.ignoredCodes || [];
|
|
22705
|
-
this.tsClient.interruptGetErr(() => this.
|
|
23302
|
+
this.tsClient.interruptGetErr(() => this.diagnosticsManager.updateIgnoredDiagnosticCodes(ignoredDiagnosticCodes));
|
|
22706
23303
|
}
|
|
22707
23304
|
didOpenTextDocument(params) {
|
|
22708
23305
|
if (this.tsClient.toOpenDocument(params.textDocument.uri, {
|
|
@@ -22724,7 +23321,7 @@ class LspServer {
|
|
|
22724
23321
|
}
|
|
22725
23322
|
this.cachedNavTreeResponse.onDocumentClose(document);
|
|
22726
23323
|
this.tsClient.onDidCloseTextDocument(uri);
|
|
22727
|
-
this.
|
|
23324
|
+
this.diagnosticsManager.onDidCloseFile(document.filepath);
|
|
22728
23325
|
this.fileConfigurationManager.onDidCloseTextDocument(document.uri);
|
|
22729
23326
|
}
|
|
22730
23327
|
didChangeTextDocument(params) {
|
|
@@ -23048,13 +23645,9 @@ class LspServer {
|
|
|
23048
23645
|
if (!document) {
|
|
23049
23646
|
return [];
|
|
23050
23647
|
}
|
|
23051
|
-
await this.
|
|
23648
|
+
const actions = await this.codeActionsManager.provideCodeActions(document, params.range, params.context, token);
|
|
23052
23649
|
const fileRangeArgs = Range.toFileRangeRequestArgs(document.filepath, params.range);
|
|
23053
|
-
const actions = [];
|
|
23054
23650
|
const kinds = params.context.only?.map(kind => new CodeActionKind(kind));
|
|
23055
|
-
if (!kinds || kinds.some(kind => CodeActionKind.QuickFix.contains(kind))) {
|
|
23056
|
-
actions.push(...provideQuickFix(await this.getCodeFixes(fileRangeArgs, params.context, token), this.tsClient));
|
|
23057
|
-
}
|
|
23058
23651
|
if (!kinds || kinds.some(kind => CodeActionKind.Refactor.contains(kind))) {
|
|
23059
23652
|
actions.push(...provideRefactors(await this.getRefactors(fileRangeArgs, params.context, this.features, token), fileRangeArgs, this.features));
|
|
23060
23653
|
}
|
|
@@ -23084,23 +23677,8 @@ class LspServer {
|
|
|
23084
23677
|
}
|
|
23085
23678
|
}
|
|
23086
23679
|
}
|
|
23087
|
-
if (kinds && !this.tsClient.hasPendingDiagnostics(document.uri)) {
|
|
23088
|
-
const diagnostics = this.diagnosticQueue.getDiagnosticsForFile(document.filepath) || [];
|
|
23089
|
-
if (diagnostics.length) {
|
|
23090
|
-
actions.push(...await this.typeScriptAutoFixProvider.provideCodeActions(kinds, document.filepath, diagnostics));
|
|
23091
|
-
}
|
|
23092
|
-
}
|
|
23093
23680
|
return actions;
|
|
23094
23681
|
}
|
|
23095
|
-
async getCodeFixes(fileRangeArgs, context, token) {
|
|
23096
|
-
const errorCodes = context.diagnostics.map(diagnostic => Number(diagnostic.code));
|
|
23097
|
-
const args = {
|
|
23098
|
-
...fileRangeArgs,
|
|
23099
|
-
errorCodes: errorCodes
|
|
23100
|
-
};
|
|
23101
|
-
const response = await this.tsClient.execute(CommandTypes.GetCodeFixes, args, token);
|
|
23102
|
-
return response.type === 'response' ? response : undefined;
|
|
23103
|
-
}
|
|
23104
23682
|
async getRefactors(fileRangeArgs, context, features, token) {
|
|
23105
23683
|
const kinds = context.only || [ undefined ];
|
|
23106
23684
|
const responses = await Promise.all(kinds.map(async kind => {
|
|
@@ -23115,25 +23693,11 @@ class LspServer {
|
|
|
23115
23693
|
}));
|
|
23116
23694
|
return responses.flat();
|
|
23117
23695
|
}
|
|
23696
|
+
async codeActionResolve(params, _token) {
|
|
23697
|
+
return this.codeActionsManager.resolveCodeAction(params);
|
|
23698
|
+
}
|
|
23118
23699
|
async executeCommand(params, token, workDoneProgress) {
|
|
23119
|
-
if (params.command === Commands.
|
|
23120
|
-
const edit = params.arguments[0];
|
|
23121
|
-
await this.options.lspClient.applyWorkspaceEdit({
|
|
23122
|
-
edit: edit
|
|
23123
|
-
});
|
|
23124
|
-
} else if (params.command === Commands.APPLY_CODE_ACTION && params.arguments) {
|
|
23125
|
-
const codeAction = params.arguments[0];
|
|
23126
|
-
if (!await this.applyFileCodeEdits(codeAction.changes)) {
|
|
23127
|
-
return;
|
|
23128
|
-
}
|
|
23129
|
-
if (codeAction.commands?.length) {
|
|
23130
|
-
for (const command of codeAction.commands) {
|
|
23131
|
-
await this.tsClient.execute(CommandTypes.ApplyCodeActionCommand, {
|
|
23132
|
-
command: command
|
|
23133
|
-
}, token);
|
|
23134
|
-
}
|
|
23135
|
-
}
|
|
23136
|
-
} else if (params.command === Commands.APPLY_REFACTORING && params.arguments) {
|
|
23700
|
+
if (await this.commandManager.handle(params.command, ...params.arguments || [])) ; else if (params.command === Commands.APPLY_REFACTORING && params.arguments) {
|
|
23137
23701
|
const args = params.arguments[0];
|
|
23138
23702
|
const response = await this.tsClient.execute(CommandTypes.GetEditsForRefactor, args, token);
|
|
23139
23703
|
if (response.type !== 'response' || !response.body) {
|
|
@@ -23388,7 +23952,7 @@ class LspServer {
|
|
|
23388
23952
|
const diagnosticEvent = event;
|
|
23389
23953
|
if (diagnosticEvent.body?.diagnostics) {
|
|
23390
23954
|
const {file: file, diagnostics: diagnostics} = diagnosticEvent.body;
|
|
23391
|
-
this.
|
|
23955
|
+
this.diagnosticsManager.updateDiagnostics(getDignosticsKind(event), file, diagnostics);
|
|
23392
23956
|
}
|
|
23393
23957
|
}
|
|
23394
23958
|
}
|
|
@@ -23559,6 +24123,7 @@ function createLspConnection(options) {
|
|
|
23559
24123
|
connection.onDidCloseTextDocument(server.didCloseTextDocument.bind(server));
|
|
23560
24124
|
connection.onDidChangeTextDocument(server.didChangeTextDocument.bind(server));
|
|
23561
24125
|
connection.onCodeAction(server.codeAction.bind(server));
|
|
24126
|
+
connection.onCodeActionResolve(server.codeActionResolve.bind(server));
|
|
23562
24127
|
connection.onCodeLens(server.codeLens.bind(server));
|
|
23563
24128
|
connection.onCodeLensResolve(server.codeLensResolve.bind(server));
|
|
23564
24129
|
connection.onCompletion(server.completion.bind(server));
|