Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/build/lib/monaco-api.ts
5221 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import fs from 'fs';
7
import path from 'path';
8
import fancyLog from 'fancy-log';
9
import ansiColors from 'ansi-colors';
10
import { type IFileMap, TypeScriptLanguageServiceHost } from './typeScriptLanguageServiceHost.ts';
11
import ts from 'typescript';
12
13
import tsfmt from '../../tsfmt.json' with { type: 'json' };
14
15
const dtsv = '3';
16
17
const SRC = path.join(import.meta.dirname, '../../src');
18
export const RECIPE_PATH = path.join(import.meta.dirname, '../monaco/monaco.d.ts.recipe');
19
const DECLARATION_PATH = path.join(import.meta.dirname, '../../src/vs/monaco.d.ts');
20
21
function logErr(message: any, ...rest: unknown[]): void {
22
fancyLog(ansiColors.yellow(`[monaco.d.ts]`), message, ...rest);
23
}
24
25
type SourceFileGetter = (moduleId: string) => ts.SourceFile | null;
26
27
type TSTopLevelDeclaration = ts.InterfaceDeclaration | ts.EnumDeclaration | ts.ClassDeclaration | ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.ModuleDeclaration;
28
type TSTopLevelDeclare = TSTopLevelDeclaration | ts.VariableStatement;
29
30
function isDeclaration(ts: typeof import('typescript'), a: TSTopLevelDeclare): a is TSTopLevelDeclaration {
31
return (
32
a.kind === ts.SyntaxKind.InterfaceDeclaration
33
|| a.kind === ts.SyntaxKind.EnumDeclaration
34
|| a.kind === ts.SyntaxKind.ClassDeclaration
35
|| a.kind === ts.SyntaxKind.TypeAliasDeclaration
36
|| a.kind === ts.SyntaxKind.FunctionDeclaration
37
|| a.kind === ts.SyntaxKind.ModuleDeclaration
38
);
39
}
40
41
function visitTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile, visitor: (node: TSTopLevelDeclare) => boolean): void {
42
let stop = false;
43
44
const visit = (node: ts.Node): void => {
45
if (stop) {
46
return;
47
}
48
49
switch (node.kind) {
50
case ts.SyntaxKind.InterfaceDeclaration:
51
case ts.SyntaxKind.EnumDeclaration:
52
case ts.SyntaxKind.ClassDeclaration:
53
case ts.SyntaxKind.VariableStatement:
54
case ts.SyntaxKind.TypeAliasDeclaration:
55
case ts.SyntaxKind.FunctionDeclaration:
56
case ts.SyntaxKind.ModuleDeclaration:
57
stop = visitor(node as TSTopLevelDeclare);
58
}
59
60
if (stop) {
61
return;
62
}
63
ts.forEachChild(node, visit);
64
};
65
66
visit(sourceFile);
67
}
68
69
70
function getAllTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile): TSTopLevelDeclare[] {
71
const all: TSTopLevelDeclare[] = [];
72
visitTopLevelDeclarations(ts, sourceFile, (node) => {
73
if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) {
74
const interfaceDeclaration = node as ts.InterfaceDeclaration;
75
const triviaStart = interfaceDeclaration.pos;
76
const triviaEnd = interfaceDeclaration.name.pos;
77
const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd });
78
79
if (triviaText.indexOf('@internal') === -1) {
80
all.push(node);
81
}
82
} else {
83
const nodeText = getNodeText(sourceFile, node);
84
if (nodeText.indexOf('@internal') === -1) {
85
all.push(node);
86
}
87
}
88
return false /*continue*/;
89
});
90
return all;
91
}
92
93
94
function getTopLevelDeclaration(ts: typeof import('typescript'), sourceFile: ts.SourceFile, typeName: string): TSTopLevelDeclare | null {
95
let result: TSTopLevelDeclare | null = null;
96
visitTopLevelDeclarations(ts, sourceFile, (node) => {
97
if (isDeclaration(ts, node) && node.name) {
98
if (node.name.text === typeName) {
99
result = node;
100
return true /*stop*/;
101
}
102
return false /*continue*/;
103
}
104
// node is ts.VariableStatement
105
if (getNodeText(sourceFile, node).indexOf(typeName) >= 0) {
106
result = node;
107
return true /*stop*/;
108
}
109
return false /*continue*/;
110
});
111
return result;
112
}
113
114
115
function getNodeText(sourceFile: ts.SourceFile, node: { pos: number; end: number }): string {
116
return sourceFile.getFullText().substring(node.pos, node.end);
117
}
118
119
function hasModifier(modifiers: readonly ts.ModifierLike[] | undefined, kind: ts.SyntaxKind): boolean {
120
if (modifiers) {
121
for (let i = 0; i < modifiers.length; i++) {
122
const mod = modifiers[i];
123
if (mod.kind === kind) {
124
return true;
125
}
126
}
127
}
128
return false;
129
}
130
131
function isStatic(ts: typeof import('typescript'), member: ts.ClassElement | ts.TypeElement): boolean {
132
if (ts.canHaveModifiers(member)) {
133
return hasModifier(ts.getModifiers(member), ts.SyntaxKind.StaticKeyword);
134
}
135
return false;
136
}
137
138
function isDefaultExport(ts: typeof import('typescript'), declaration: ts.InterfaceDeclaration | ts.ClassDeclaration): boolean {
139
return (
140
hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword)
141
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword)
142
);
143
}
144
145
function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: IEnumEntry[]): string {
146
let result = getNodeText(sourceFile, declaration);
147
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
148
const interfaceDeclaration = declaration as ts.InterfaceDeclaration | ts.ClassDeclaration;
149
150
const staticTypeName = (
151
isDefaultExport(ts, interfaceDeclaration)
152
? `${importName}.default`
153
: `${importName}.${declaration.name!.text}`
154
);
155
156
let instanceTypeName = staticTypeName;
157
const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0);
158
if (typeParametersCnt > 0) {
159
const arr: string[] = [];
160
for (let i = 0; i < typeParametersCnt; i++) {
161
arr.push('any');
162
}
163
instanceTypeName = `${instanceTypeName}<${arr.join(',')}>`;
164
}
165
166
const members: ts.NodeArray<ts.ClassElement | ts.TypeElement> = interfaceDeclaration.members;
167
members.forEach((member) => {
168
try {
169
const memberText = getNodeText(sourceFile, member);
170
if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) {
171
result = result.replace(memberText, '');
172
} else {
173
const memberName = (member.name as ts.Identifier | ts.StringLiteral).text;
174
const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`);
175
if (isStatic(ts, member)) {
176
usage.push(`a = ${staticTypeName}${memberAccess};`);
177
} else {
178
usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`);
179
}
180
}
181
} catch (err) {
182
// life..
183
}
184
});
185
}
186
result = result.replace(/export default /g, 'export ');
187
result = result.replace(/export declare /g, 'export ');
188
result = result.replace(/declare /g, '');
189
const lines = result.split(/\r\n|\r|\n/);
190
for (let i = 0; i < lines.length; i++) {
191
if (/\s*\*/.test(lines[i])) {
192
// very likely a comment
193
continue;
194
}
195
lines[i] = lines[i].replace(/"/g, '\'');
196
}
197
result = lines.join('\n');
198
199
if (declaration.kind === ts.SyntaxKind.EnumDeclaration) {
200
result = result.replace(/const enum/, 'enum');
201
enums.push({
202
enumName: declaration.name.getText(sourceFile),
203
text: result
204
});
205
}
206
207
return result;
208
}
209
210
interface Formatting<TContext> {
211
getFormatContext(options: ts.FormatCodeSettings): TContext;
212
formatDocument(file: ts.SourceFile, ruleProvider: TContext, options: ts.FormatCodeSettings): ts.TextChange[];
213
}
214
215
type Typescript = typeof import('typescript') & { readonly formatting: Formatting<unknown> };
216
217
function format(ts: Typescript, text: string, endl: string): string {
218
const REALLY_FORMAT = false;
219
220
text = preformat(text, endl);
221
if (!REALLY_FORMAT) {
222
return text;
223
}
224
225
// Parse the source text
226
const sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true);
227
228
// Get the formatting edits on the input sources
229
const edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt);
230
231
// Apply the edits on the input code
232
return applyEdits(text, edits);
233
234
function countParensCurly(text: string): number {
235
let cnt = 0;
236
for (let i = 0; i < text.length; i++) {
237
if (text.charAt(i) === '(' || text.charAt(i) === '{') {
238
cnt++;
239
}
240
if (text.charAt(i) === ')' || text.charAt(i) === '}') {
241
cnt--;
242
}
243
}
244
return cnt;
245
}
246
247
function repeatStr(s: string, cnt: number): string {
248
let r = '';
249
for (let i = 0; i < cnt; i++) {
250
r += s;
251
}
252
return r;
253
}
254
255
function preformat(text: string, endl: string): string {
256
const lines = text.split(endl);
257
let inComment = false;
258
let inCommentDeltaIndent = 0;
259
let indent = 0;
260
for (let i = 0; i < lines.length; i++) {
261
let line = lines[i].replace(/\s$/, '');
262
let repeat = false;
263
let lineIndent = 0;
264
do {
265
repeat = false;
266
if (line.substring(0, 4) === ' ') {
267
line = line.substring(4);
268
lineIndent++;
269
repeat = true;
270
}
271
if (line.charAt(0) === '\t') {
272
line = line.substring(1);
273
lineIndent++;
274
repeat = true;
275
}
276
} while (repeat);
277
278
if (line.length === 0) {
279
continue;
280
}
281
282
if (inComment) {
283
if (/\*\//.test(line)) {
284
inComment = false;
285
}
286
lines[i] = repeatStr('\t', lineIndent + inCommentDeltaIndent) + line;
287
continue;
288
}
289
290
if (/\/\*/.test(line)) {
291
inComment = true;
292
inCommentDeltaIndent = indent - lineIndent;
293
lines[i] = repeatStr('\t', indent) + line;
294
continue;
295
}
296
297
const cnt = countParensCurly(line);
298
let shouldUnindentAfter = false;
299
let shouldUnindentBefore = false;
300
if (cnt < 0) {
301
if (/[({]/.test(line)) {
302
shouldUnindentAfter = true;
303
} else {
304
shouldUnindentBefore = true;
305
}
306
} else if (cnt === 0) {
307
shouldUnindentBefore = /^\}/.test(line);
308
}
309
let shouldIndentAfter = false;
310
if (cnt > 0) {
311
shouldIndentAfter = true;
312
} else if (cnt === 0) {
313
shouldIndentAfter = /{$/.test(line);
314
}
315
316
if (shouldUnindentBefore) {
317
indent--;
318
}
319
320
lines[i] = repeatStr('\t', indent) + line;
321
322
if (shouldUnindentAfter) {
323
indent--;
324
}
325
if (shouldIndentAfter) {
326
indent++;
327
}
328
}
329
return lines.join(endl);
330
}
331
332
function getRuleProvider(options: ts.FormatCodeSettings) {
333
// Share this between multiple formatters using the same options.
334
// This represents the bulk of the space the formatter uses.
335
336
return ts.formatting.getFormatContext(options);
337
}
338
339
function applyEdits(text: string, edits: ts.TextChange[]): string {
340
// Apply edits in reverse on the existing text
341
let result = text;
342
for (let i = edits.length - 1; i >= 0; i--) {
343
const change = edits[i];
344
const head = result.slice(0, change.span.start);
345
const tail = result.slice(change.span.start + change.span.length);
346
result = head + change.newText + tail;
347
}
348
return result;
349
}
350
}
351
352
function createReplacerFromDirectives(directives: [RegExp, string][]): (str: string) => string {
353
return (str: string) => {
354
for (let i = 0; i < directives.length; i++) {
355
str = str.replace(directives[i][0], directives[i][1]);
356
}
357
return str;
358
};
359
}
360
361
function createReplacer(data: string): (str: string) => string {
362
data = data || '';
363
const rawDirectives = data.split(';');
364
const directives: [RegExp, string][] = [];
365
rawDirectives.forEach((rawDirective) => {
366
if (rawDirective.length === 0) {
367
return;
368
}
369
const pieces = rawDirective.split('=>');
370
let findStr = pieces[0];
371
const replaceStr = pieces[1];
372
373
findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&');
374
findStr = '\\b' + findStr + '\\b';
375
directives.push([new RegExp(findStr, 'g'), replaceStr]);
376
});
377
378
return createReplacerFromDirectives(directives);
379
}
380
381
interface ITempResult {
382
result: string;
383
usageContent: string;
384
enums: string;
385
}
386
387
interface IEnumEntry {
388
enumName: string;
389
text: string;
390
}
391
392
function generateDeclarationFile(ts: Typescript, recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null {
393
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
394
395
const lines = recipe.split(endl);
396
const result: string[] = [];
397
398
let usageCounter = 0;
399
const usageImports: string[] = [];
400
const usage: string[] = [];
401
402
let failed = false;
403
404
usage.push(`var a: any;`);
405
usage.push(`var b: any;`);
406
407
const generateUsageImport = (moduleId: string) => {
408
const importName = 'm' + (++usageCounter);
409
usageImports.push(`import * as ${importName} from './${moduleId}';`);
410
return importName;
411
};
412
413
const enums: IEnumEntry[] = [];
414
let version: string | null = null;
415
416
lines.forEach(line => {
417
418
if (failed) {
419
return;
420
}
421
422
const m0 = line.match(/^\/\/dtsv=(\d+)$/);
423
if (m0) {
424
version = m0[1];
425
}
426
427
const m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
428
if (m1) {
429
const moduleId = m1[1];
430
const sourceFile = sourceFileGetter(moduleId);
431
if (!sourceFile) {
432
logErr(`While handling ${line}`);
433
logErr(`Cannot find ${moduleId}`);
434
failed = true;
435
return;
436
}
437
438
const importName = generateUsageImport(moduleId);
439
440
const replacer = createReplacer(m1[2]);
441
442
const typeNames = m1[3].split(/,/);
443
typeNames.forEach((typeName) => {
444
typeName = typeName.trim();
445
if (typeName.length === 0) {
446
return;
447
}
448
const declaration = getTopLevelDeclaration(ts, sourceFile, typeName);
449
if (!declaration) {
450
logErr(`While handling ${line}`);
451
logErr(`Cannot find ${typeName}`);
452
failed = true;
453
return;
454
}
455
result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums)));
456
});
457
return;
458
}
459
460
const m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
461
if (m2) {
462
const moduleId = m2[1];
463
const sourceFile = sourceFileGetter(moduleId);
464
if (!sourceFile) {
465
logErr(`While handling ${line}`);
466
logErr(`Cannot find ${moduleId}`);
467
failed = true;
468
return;
469
}
470
471
const importName = generateUsageImport(moduleId);
472
473
const replacer = createReplacer(m2[2]);
474
475
const typeNames = m2[3].split(/,/);
476
const typesToExcludeMap: { [typeName: string]: boolean } = {};
477
const typesToExcludeArr: string[] = [];
478
typeNames.forEach((typeName) => {
479
typeName = typeName.trim();
480
if (typeName.length === 0) {
481
return;
482
}
483
typesToExcludeMap[typeName] = true;
484
typesToExcludeArr.push(typeName);
485
});
486
487
getAllTopLevelDeclarations(ts, sourceFile).forEach((declaration) => {
488
if (isDeclaration(ts, declaration) && declaration.name) {
489
if (typesToExcludeMap[declaration.name.text]) {
490
return;
491
}
492
} else {
493
// node is ts.VariableStatement
494
const nodeText = getNodeText(sourceFile, declaration);
495
for (let i = 0; i < typesToExcludeArr.length; i++) {
496
if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) {
497
return;
498
}
499
}
500
}
501
result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums)));
502
});
503
return;
504
}
505
506
result.push(line);
507
});
508
509
if (failed) {
510
return null;
511
}
512
513
if (version !== dtsv) {
514
if (!version) {
515
logErr(`gulp watch restart required. 'monaco.d.ts.recipe' is written before versioning was introduced.`);
516
} else {
517
logErr(`gulp watch restart required. 'monaco.d.ts.recipe' v${version} does not match runtime v${dtsv}.`);
518
}
519
return null;
520
}
521
522
let resultTxt = result.join(endl);
523
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
524
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
525
resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);
526
resultTxt = format(ts, resultTxt, endl);
527
resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);
528
529
enums.sort((e1, e2) => {
530
if (e1.enumName < e2.enumName) {
531
return -1;
532
}
533
if (e1.enumName > e2.enumName) {
534
return 1;
535
}
536
return 0;
537
});
538
539
let resultEnums = [
540
'/*---------------------------------------------------------------------------------------------',
541
' * Copyright (c) Microsoft Corporation. All rights reserved.',
542
' * Licensed under the MIT License. See License.txt in the project root for license information.',
543
' *--------------------------------------------------------------------------------------------*/',
544
'',
545
'// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.',
546
''
547
].concat(enums.map(e => e.text)).join(endl);
548
resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);
549
resultEnums = format(ts, resultEnums, endl);
550
resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);
551
552
return {
553
result: resultTxt,
554
usageContent: `${usageImports.join('\n')}\n\n${usage.join('\n')}`,
555
enums: resultEnums
556
};
557
}
558
559
export interface IMonacoDeclarationResult {
560
content: string;
561
usageContent: string;
562
enums: string;
563
filePath: string;
564
isTheSame: boolean;
565
}
566
567
function _run(ts: Typescript, sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult | null {
568
const recipe = fs.readFileSync(RECIPE_PATH).toString();
569
const t = generateDeclarationFile(ts, recipe, sourceFileGetter);
570
if (!t) {
571
return null;
572
}
573
574
const result = t.result;
575
const usageContent = t.usageContent;
576
const enums = t.enums;
577
578
const currentContent = fs.readFileSync(DECLARATION_PATH).toString();
579
const one = currentContent.replace(/\r\n/gm, '\n');
580
const other = result.replace(/\r\n/gm, '\n');
581
const isTheSame = (one === other);
582
583
return {
584
content: result,
585
usageContent: usageContent,
586
enums: enums,
587
filePath: DECLARATION_PATH,
588
isTheSame
589
};
590
}
591
592
export class FSProvider {
593
public existsSync(filePath: string): boolean {
594
return fs.existsSync(filePath);
595
}
596
public statSync(filePath: string): fs.Stats {
597
return fs.statSync(filePath);
598
}
599
public readFileSync(_moduleId: string, filePath: string): Buffer {
600
return fs.readFileSync(filePath);
601
}
602
}
603
604
class CacheEntry {
605
public readonly sourceFile: ts.SourceFile;
606
public readonly mtime: number;
607
608
constructor(
609
sourceFile: ts.SourceFile,
610
mtime: number
611
) {
612
this.sourceFile = sourceFile;
613
this.mtime = mtime;
614
}
615
}
616
617
export class DeclarationResolver {
618
619
public readonly ts: typeof import('typescript');
620
private _sourceFileCache: { [moduleId: string]: CacheEntry | null };
621
private readonly _fsProvider: FSProvider;
622
623
constructor(fsProvider: FSProvider) {
624
this._fsProvider = fsProvider;
625
this.ts = ts;
626
this._sourceFileCache = Object.create(null);
627
}
628
629
public invalidateCache(moduleId: string): void {
630
this._sourceFileCache[moduleId] = null;
631
}
632
633
public getDeclarationSourceFile(moduleId: string): ts.SourceFile | null {
634
if (this._sourceFileCache[moduleId]) {
635
// Since we cannot trust file watching to invalidate the cache, check also the mtime
636
const fileName = this._getFileName(moduleId);
637
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
638
if (this._sourceFileCache[moduleId]!.mtime !== mtime) {
639
this._sourceFileCache[moduleId] = null;
640
}
641
}
642
if (!this._sourceFileCache[moduleId]) {
643
this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId);
644
}
645
return this._sourceFileCache[moduleId] ? this._sourceFileCache[moduleId]!.sourceFile : null;
646
}
647
648
private _getFileName(moduleId: string): string {
649
if (/\.d\.ts$/.test(moduleId)) {
650
return path.join(SRC, moduleId);
651
}
652
if (/\.js$/.test(moduleId)) {
653
return path.join(SRC, moduleId.replace(/\.js$/, '.ts'));
654
}
655
return path.join(SRC, `${moduleId}.ts`);
656
}
657
658
private _getDeclarationSourceFile(moduleId: string): CacheEntry | null {
659
const fileName = this._getFileName(moduleId);
660
if (!this._fsProvider.existsSync(fileName)) {
661
return null;
662
}
663
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
664
if (/\.d\.ts$/.test(moduleId)) {
665
// const mtime = this._fsProvider.statFileSync()
666
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
667
return new CacheEntry(
668
this.ts.createSourceFile(fileName, fileContents, this.ts.ScriptTarget.ES5),
669
mtime
670
);
671
}
672
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
673
const fileMap: IFileMap = new Map([
674
['file.ts', fileContents]
675
]);
676
const service = this.ts.createLanguageService(new TypeScriptLanguageServiceHost(this.ts, fileMap, {}));
677
const text = service.getEmitOutput('file.ts', true, true).outputFiles[0].text;
678
return new CacheEntry(
679
this.ts.createSourceFile(fileName, text, this.ts.ScriptTarget.ES5),
680
mtime
681
);
682
}
683
}
684
685
export function run3(resolver: DeclarationResolver): IMonacoDeclarationResult | null {
686
const sourceFileGetter = (moduleId: string) => resolver.getDeclarationSourceFile(moduleId);
687
return _run(resolver.ts as Typescript, sourceFileGetter);
688
}
689
690
691
export function execute(): IMonacoDeclarationResult {
692
const r = run3(new DeclarationResolver(new FSProvider()));
693
if (!r) {
694
throw new Error(`monaco.d.ts generation error - Cannot continue`);
695
}
696
return r;
697
}
698
699