mirror of
https://github.com/microsoft/monaco-editor.git
synced 2025-12-22 17:25:39 +01:00
Run prettier
This commit is contained in:
parent
21ceb6a387
commit
b87c75d7e9
20 changed files with 3351 additions and 2779 deletions
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -1,8 +1,8 @@
|
|||
name: "CI"
|
||||
name: 'CI'
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
build:
|
||||
name: "Builds and Compiles"
|
||||
name: 'Builds and Compiles'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
|
|
|||
25
README.md
25
README.md
|
|
@ -4,7 +4,7 @@ Simple TypeScript and JavaScript language support for the Monaco Editor.
|
|||
|
||||

|
||||
|
||||
*Note* that this project focuses on single-file scenarios and that things like project-isolation, cross-file-features like Rename etc. are *outside* the scope of this project and not supported.
|
||||
_Note_ that this project focuses on single-file scenarios and that things like project-isolation, cross-file-features like Rename etc. are _outside_ the scope of this project and not supported.
|
||||
|
||||
## Issues
|
||||
|
||||
|
|
@ -14,27 +14,26 @@ Please file issues concerning `monaco-typescript` in the [`monaco-editor` reposi
|
|||
|
||||
This npm module is bundled and distributed in the [monaco-editor](https://www.npmjs.com/package/monaco-editor) npm module.
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
* `git clone https://github.com/Microsoft/monaco-typescript`
|
||||
* `cd monaco-typescript`
|
||||
* `npm install .`
|
||||
* `npm run compile`
|
||||
* `npm run watch`
|
||||
* open `$/monaco-typescript/test/index.html` in your favorite browser.
|
||||
- `git clone https://github.com/Microsoft/monaco-typescript`
|
||||
- `cd monaco-typescript`
|
||||
- `npm install .`
|
||||
- `npm run compile`
|
||||
- `npm run watch`
|
||||
- open `$/monaco-typescript/test/index.html` in your favorite browser.
|
||||
|
||||
## Updating TypeScript
|
||||
|
||||
* change typescript's version in `package.json`.
|
||||
* execute `npm install .`
|
||||
* execute `npm run import-typescript`
|
||||
* adopt new APIs
|
||||
- change typescript's version in `package.json`.
|
||||
- execute `npm install .`
|
||||
- execute `npm run import-typescript`
|
||||
- adopt new APIs
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
[MIT](https://github.com/Microsoft/monaco-typescript/blob/master/LICENSE.md)
|
||||
|
|
|
|||
|
|
@ -31,5 +31,10 @@
|
|||
"requirejs": "^2.3.6",
|
||||
"terser": "^5.3.0",
|
||||
"typescript": "^4.0.2"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "pretty-quick --staged"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ bundleOne('tsMode');
|
|||
bundleOne('tsWorker');
|
||||
|
||||
function bundleOne(moduleId, exclude) {
|
||||
requirejs.optimize({
|
||||
requirejs.optimize(
|
||||
{
|
||||
baseUrl: 'release/dev/',
|
||||
name: 'vs/language/typescript/' + moduleId,
|
||||
out: 'release/min/' + moduleId + '.js',
|
||||
|
|
@ -39,7 +40,8 @@ function bundleOne(moduleId, exclude) {
|
|||
'vs/language/typescript': REPO_ROOT + '/release/dev'
|
||||
},
|
||||
optimize: 'none'
|
||||
}, async function(buildResponse) {
|
||||
},
|
||||
async function (buildResponse) {
|
||||
const filePath = path.join(REPO_ROOT, 'release/min/' + moduleId + '.js');
|
||||
const fileContents = fs.readFileSync(filePath).toString();
|
||||
console.log();
|
||||
|
|
@ -47,5 +49,6 @@ function bundleOne(moduleId, exclude) {
|
|||
const result = await terser.minify(fileContents);
|
||||
console.log(`Done minifying ${filePath}.`);
|
||||
fs.writeFileSync(filePath, BUNDLED_FILE_HEADER + result.code);
|
||||
})
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@ const generatedNote = `//
|
|||
//
|
||||
`;
|
||||
|
||||
const TYPESCRIPT_LIB_SOURCE = path.join(__dirname, '../node_modules/typescript/lib');
|
||||
const TYPESCRIPT_LIB_SOURCE = path.join(
|
||||
__dirname,
|
||||
'../node_modules/typescript/lib'
|
||||
);
|
||||
const TYPESCRIPT_LIB_DESTINATION = path.join(__dirname, '../src/lib');
|
||||
|
||||
(function () {
|
||||
|
|
@ -23,8 +26,11 @@ const TYPESCRIPT_LIB_DESTINATION = path.join(__dirname, '../src/lib');
|
|||
}
|
||||
importLibs();
|
||||
|
||||
const npmLsOutput = JSON.parse(child_process.execSync("npm ls typescript --depth=0 --json=true").toString());
|
||||
const typeScriptDependencyVersion = npmLsOutput.dependencies.typescript.version;
|
||||
const npmLsOutput = JSON.parse(
|
||||
child_process.execSync('npm ls typescript --depth=0 --json=true').toString()
|
||||
);
|
||||
const typeScriptDependencyVersion =
|
||||
npmLsOutput.dependencies.typescript.version;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServicesMetadata.ts'),
|
||||
|
|
@ -32,36 +38,55 @@ const TYPESCRIPT_LIB_DESTINATION = path.join(__dirname, '../src/lib');
|
|||
export const typescriptVersion = "${typeScriptDependencyVersion}";\n`
|
||||
);
|
||||
|
||||
var tsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.js')).toString();
|
||||
var tsServices = fs
|
||||
.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.js'))
|
||||
.toString();
|
||||
|
||||
// Ensure we never run into the node system...
|
||||
// (this also removes require calls that trick webpack into shimming those modules...)
|
||||
tsServices = (
|
||||
tsServices.replace(/\n ts\.sys =([^]*)\n \}\)\(\);/m, `\n // MONACOCHANGE\n ts.sys = undefined;\n // END MONACOCHANGE`)
|
||||
tsServices = tsServices.replace(
|
||||
/\n ts\.sys =([^]*)\n \}\)\(\);/m,
|
||||
`\n // MONACOCHANGE\n ts.sys = undefined;\n // END MONACOCHANGE`
|
||||
);
|
||||
|
||||
// Eliminate more require() calls...
|
||||
tsServices = tsServices.replace(/^( +)etwModule = require\(.*$/m, '$1// MONACOCHANGE\n$1etwModule = undefined;\n$1// END MONACOCHANGE');
|
||||
tsServices = tsServices.replace(/^( +)var result = ts\.sys\.require\(.*$/m, '$1// MONACOCHANGE\n$1var result = undefined;\n$1// END MONACOCHANGE');
|
||||
tsServices = tsServices.replace(
|
||||
/^( +)etwModule = require\(.*$/m,
|
||||
'$1// MONACOCHANGE\n$1etwModule = undefined;\n$1// END MONACOCHANGE'
|
||||
);
|
||||
tsServices = tsServices.replace(
|
||||
/^( +)var result = ts\.sys\.require\(.*$/m,
|
||||
'$1// MONACOCHANGE\n$1var result = undefined;\n$1// END MONACOCHANGE'
|
||||
);
|
||||
|
||||
// Flag any new require calls (outside comments) so they can be corrected preemptively.
|
||||
// To avoid missing cases (or using an even more complex regex), temporarily remove comments
|
||||
// about require() and then check for lines actually calling require().
|
||||
// \/[*/] matches the start of a comment (single or multi-line).
|
||||
// ^\s+\*[^/] matches (presumably) a later line of a multi-line comment.
|
||||
const tsServicesNoCommentedRequire = tsServices.replace(/(\/[*/]|^\s+\*[^/]).*\brequire\(.*/gm, '');
|
||||
const linesWithRequire = tsServicesNoCommentedRequire.match(/^.*?\brequire\(.*$/gm)
|
||||
const tsServicesNoCommentedRequire = tsServices.replace(
|
||||
/(\/[*/]|^\s+\*[^/]).*\brequire\(.*/gm,
|
||||
''
|
||||
);
|
||||
const linesWithRequire = tsServicesNoCommentedRequire.match(
|
||||
/^.*?\brequire\(.*$/gm
|
||||
);
|
||||
|
||||
// Allow error messages to include references to require() in their strings
|
||||
const runtimeRequires = linesWithRequire && linesWithRequire.filter(l => !l.includes(": diag("))
|
||||
const runtimeRequires =
|
||||
linesWithRequire && linesWithRequire.filter((l) => !l.includes(': diag('));
|
||||
|
||||
if (runtimeRequires && runtimeRequires.length && linesWithRequire) {
|
||||
console.error('Found new require() calls on the following lines. These should be removed to avoid breaking webpack builds.\n');
|
||||
console.error(
|
||||
'Found new require() calls on the following lines. These should be removed to avoid breaking webpack builds.\n'
|
||||
);
|
||||
console.error(linesWithRequire.join('\n'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var tsServices_amd = generatedNote + tsServices +
|
||||
var tsServices_amd =
|
||||
generatedNote +
|
||||
tsServices +
|
||||
`
|
||||
// MONACOCHANGE
|
||||
// Defining the entire module name because r.js has an issue and cannot bundle this file
|
||||
|
|
@ -69,9 +94,14 @@ export const typescriptVersion = "${typeScriptDependencyVersion}";\n`
|
|||
define("vs/language/typescript/lib/typescriptServices", [], function() { return ts; });
|
||||
// END MONACOCHANGE
|
||||
`;
|
||||
fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices-amd.js'), stripSourceMaps(tsServices_amd));
|
||||
fs.writeFileSync(
|
||||
path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices-amd.js'),
|
||||
stripSourceMaps(tsServices_amd)
|
||||
);
|
||||
|
||||
var tsServices_esm = generatedNote + tsServices +
|
||||
var tsServices_esm =
|
||||
generatedNote +
|
||||
tsServices +
|
||||
`
|
||||
// MONACOCHANGE
|
||||
export var createClassifier = ts.createClassifier;
|
||||
|
|
@ -85,17 +115,23 @@ export var ScriptTarget = ts.ScriptTarget;
|
|||
export var TokenClass = ts.TokenClass;
|
||||
// END MONACOCHANGE
|
||||
`;
|
||||
fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.js'), stripSourceMaps(tsServices_esm));
|
||||
fs.writeFileSync(
|
||||
path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.js'),
|
||||
stripSourceMaps(tsServices_esm)
|
||||
);
|
||||
|
||||
var dtsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.d.ts')).toString();
|
||||
dtsServices +=
|
||||
`
|
||||
var dtsServices = fs
|
||||
.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.d.ts'))
|
||||
.toString();
|
||||
dtsServices += `
|
||||
// MONACOCHANGE
|
||||
export = ts;
|
||||
// END MONACOCHANGE
|
||||
`;
|
||||
fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.d.ts'), generatedNote + dtsServices);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.d.ts'),
|
||||
generatedNote + dtsServices
|
||||
);
|
||||
})();
|
||||
|
||||
function importLibs() {
|
||||
|
|
@ -112,9 +148,7 @@ ${generatedNote}
|
|||
|
||||
/** Contains all the lib files */
|
||||
export const libFileMap: Record<string, string> = {}
|
||||
`
|
||||
;
|
||||
|
||||
`;
|
||||
var strIndexResult = `/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
|
|
@ -123,10 +157,10 @@ ${generatedNote}
|
|||
|
||||
/** Contains all the lib files */
|
||||
export const libFileSet: Record<string, boolean> = {}
|
||||
`
|
||||
;
|
||||
|
||||
var dtsFiles = fs.readdirSync(TYPESCRIPT_LIB_SOURCE).filter(f => f.includes("lib."));
|
||||
`;
|
||||
var dtsFiles = fs
|
||||
.readdirSync(TYPESCRIPT_LIB_SOURCE)
|
||||
.filter((f) => f.includes('lib.'));
|
||||
while (dtsFiles.length > 0) {
|
||||
var name = dtsFiles.shift();
|
||||
var output = readLibFile(name).replace(/\r\n/g, '\n');
|
||||
|
|
@ -134,8 +168,14 @@ export const libFileSet: Record<string, boolean> = {}
|
|||
strIndexResult += `libFileSet['${name}'] = true;\n`;
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'lib.ts'), strLibResult);
|
||||
fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'lib.index.ts'), strIndexResult);
|
||||
fs.writeFileSync(
|
||||
path.join(TYPESCRIPT_LIB_DESTINATION, 'lib.ts'),
|
||||
strLibResult
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(TYPESCRIPT_LIB_DESTINATION, 'lib.index.ts'),
|
||||
strIndexResult
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -153,7 +193,10 @@ function escapeText(text) {
|
|||
var _backslash = '\\'.charCodeAt(0);
|
||||
var _doubleQuote = '"'.charCodeAt(0);
|
||||
|
||||
var startPos = 0, chrCode, replaceWith = null, resultPieces = [];
|
||||
var startPos = 0,
|
||||
chrCode,
|
||||
replaceWith = null,
|
||||
resultPieces = [];
|
||||
|
||||
for (var i = 0, len = text.length; i < len; i++) {
|
||||
chrCode = text.charCodeAt(i);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
import { LanguageServiceDefaultsImpl } from './monaco.contribution';
|
||||
import * as ts from './lib/typescriptServices';
|
||||
import { TypeScriptWorker } from './tsWorker';
|
||||
import { libFileSet } from "./lib/lib.index"
|
||||
import { libFileSet } from './lib/lib.index';
|
||||
|
||||
import Uri = monaco.Uri;
|
||||
import Position = monaco.Position;
|
||||
|
|
@ -23,19 +23,22 @@ enum IndentStyle {
|
|||
Smart = 2
|
||||
}
|
||||
|
||||
export function flattenDiagnosticMessageText(diag: string | ts.DiagnosticMessageChain | undefined, newLine: string, indent = 0): string {
|
||||
if (typeof diag === "string") {
|
||||
export function flattenDiagnosticMessageText(
|
||||
diag: string | ts.DiagnosticMessageChain | undefined,
|
||||
newLine: string,
|
||||
indent = 0
|
||||
): string {
|
||||
if (typeof diag === 'string') {
|
||||
return diag;
|
||||
} else if (diag === undefined) {
|
||||
return '';
|
||||
}
|
||||
else if (diag === undefined) {
|
||||
return "";
|
||||
}
|
||||
let result = "";
|
||||
let result = '';
|
||||
if (indent) {
|
||||
result += newLine;
|
||||
|
||||
for (let i = 0; i < indent; i++) {
|
||||
result += " ";
|
||||
result += ' ';
|
||||
}
|
||||
}
|
||||
result += diag.messageText;
|
||||
|
|
@ -48,19 +51,21 @@ export function flattenDiagnosticMessageText(diag: string | ts.DiagnosticMessage
|
|||
return result;
|
||||
}
|
||||
|
||||
function displayPartsToString(displayParts: ts.SymbolDisplayPart[] | undefined): string {
|
||||
function displayPartsToString(
|
||||
displayParts: ts.SymbolDisplayPart[] | undefined
|
||||
): string {
|
||||
if (displayParts) {
|
||||
return displayParts.map((displayPart) => displayPart.text).join("");
|
||||
return displayParts.map((displayPart) => displayPart.text).join('');
|
||||
}
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
export abstract class Adapter {
|
||||
|
||||
constructor(protected _worker: (...uris: Uri[]) => Promise<TypeScriptWorker>) {
|
||||
}
|
||||
constructor(
|
||||
protected _worker: (...uris: Uri[]) => Promise<TypeScriptWorker>
|
||||
) {}
|
||||
|
||||
// protected _positionToOffset(model: monaco.editor.ITextModel, position: monaco.IPosition): number {
|
||||
// return model.getOffsetAt(position);
|
||||
|
|
@ -70,7 +75,10 @@ export abstract class Adapter {
|
|||
// return model.getPositionAt(offset);
|
||||
// }
|
||||
|
||||
protected _textSpanToRange(model: monaco.editor.ITextModel, span: ts.TextSpan): monaco.IRange {
|
||||
protected _textSpanToRange(
|
||||
model: monaco.editor.ITextModel,
|
||||
span: ts.TextSpan
|
||||
): monaco.IRange {
|
||||
let p1 = model.getPositionAt(span.start);
|
||||
let p2 = model.getPositionAt(span.start + span.length);
|
||||
let { lineNumber: startLineNumber, column: startColumn } = p1;
|
||||
|
|
@ -82,7 +90,6 @@ export abstract class Adapter {
|
|||
// --- lib files
|
||||
|
||||
export class LibFiles {
|
||||
|
||||
private _libFiles: Record<string, string>;
|
||||
private _hasFetchedLibFiles: boolean;
|
||||
private _fetchLibFilesPromise: Promise<void> | null;
|
||||
|
|
@ -99,7 +106,7 @@ export class LibFiles {
|
|||
if (!uri) {
|
||||
return false;
|
||||
}
|
||||
if (uri.path.indexOf("/lib.") === 0) {
|
||||
if (uri.path.indexOf('/lib.') === 0) {
|
||||
return !!libFileSet[uri.path.slice(1)];
|
||||
}
|
||||
return false;
|
||||
|
|
@ -111,7 +118,11 @@ export class LibFiles {
|
|||
return model;
|
||||
}
|
||||
if (this.isLibFile(uri) && this._hasFetchedLibFiles) {
|
||||
return monaco.editor.createModel(this._libFiles[uri.path.slice(1)], "javascript", uri);
|
||||
return monaco.editor.createModel(
|
||||
this._libFiles[uri.path.slice(1)],
|
||||
'javascript',
|
||||
uri
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -135,14 +146,12 @@ export class LibFiles {
|
|||
|
||||
private _fetchLibFiles(): Promise<void> {
|
||||
if (!this._fetchLibFilesPromise) {
|
||||
this._fetchLibFilesPromise = (
|
||||
this._worker()
|
||||
.then(w => w.getLibFiles())
|
||||
this._fetchLibFilesPromise = this._worker()
|
||||
.then((w) => w.getLibFiles())
|
||||
.then((libFiles) => {
|
||||
this._hasFetchedLibFiles = true;
|
||||
this._libFiles = libFiles;
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
return this._fetchLibFilesPromise;
|
||||
}
|
||||
|
|
@ -158,7 +167,6 @@ enum DiagnosticCategory {
|
|||
}
|
||||
|
||||
export class DiagnosticsAdapter extends Adapter {
|
||||
|
||||
private _disposables: IDisposable[] = [];
|
||||
private _listener: { [uri: string]: IDisposable } = Object.create(null);
|
||||
|
||||
|
|
@ -202,10 +210,12 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
|
||||
this._disposables.push(monaco.editor.onDidCreateModel(onModelAdd));
|
||||
this._disposables.push(monaco.editor.onWillDisposeModel(onModelRemoved));
|
||||
this._disposables.push(monaco.editor.onDidChangeModelLanguage(event => {
|
||||
this._disposables.push(
|
||||
monaco.editor.onDidChangeModelLanguage((event) => {
|
||||
onModelRemoved(event.model);
|
||||
onModelAdd(event.model);
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
this._disposables.push({
|
||||
dispose() {
|
||||
|
|
@ -223,13 +233,15 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
}
|
||||
};
|
||||
this._disposables.push(this._defaults.onDidChange(recomputeDiagostics));
|
||||
this._disposables.push(this._defaults.onDidExtraLibsChange(recomputeDiagostics));
|
||||
this._disposables.push(
|
||||
this._defaults.onDidExtraLibsChange(recomputeDiagostics)
|
||||
);
|
||||
|
||||
monaco.editor.getModels().forEach(onModelAdd);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._disposables.forEach(d => d && d.dispose());
|
||||
this._disposables.forEach((d) => d && d.dispose());
|
||||
this._disposables = [];
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +254,11 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
}
|
||||
|
||||
const promises: Promise<ts.Diagnostic[]>[] = [];
|
||||
const { noSyntaxValidation, noSemanticValidation, noSuggestionDiagnostics } = this._defaults.getDiagnosticsOptions();
|
||||
const {
|
||||
noSyntaxValidation,
|
||||
noSemanticValidation,
|
||||
noSuggestionDiagnostics
|
||||
} = this._defaults.getDiagnosticsOptions();
|
||||
if (!noSyntaxValidation) {
|
||||
promises.push(worker.getSyntacticDiagnostics(model.uri.toString()));
|
||||
}
|
||||
|
|
@ -262,13 +278,22 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
|
||||
const diagnostics = allDiagnostics
|
||||
.reduce((p, c) => c.concat(p), [])
|
||||
.filter(d => (this._defaults.getDiagnosticsOptions().diagnosticCodesToIgnore || []).indexOf(d.code) === -1);
|
||||
.filter(
|
||||
(d) =>
|
||||
(
|
||||
this._defaults.getDiagnosticsOptions().diagnosticCodesToIgnore || []
|
||||
).indexOf(d.code) === -1
|
||||
);
|
||||
|
||||
// Fetch lib files if necessary
|
||||
const relatedUris = diagnostics
|
||||
.map(d => d.relatedInformation || [])
|
||||
.map((d) => d.relatedInformation || [])
|
||||
.reduce((p, c) => c.concat(p), [])
|
||||
.map(relatedInformation => relatedInformation.file ? monaco.Uri.parse(relatedInformation.file.fileName) : null);
|
||||
.map((relatedInformation) =>
|
||||
relatedInformation.file
|
||||
? monaco.Uri.parse(relatedInformation.file.fileName)
|
||||
: null
|
||||
);
|
||||
|
||||
await this._libFiles.fetchLibFilesIfNecessary(relatedUris);
|
||||
|
||||
|
|
@ -277,14 +302,27 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
return;
|
||||
}
|
||||
|
||||
monaco.editor.setModelMarkers(model, this._selector, diagnostics.map(d => this._convertDiagnostics(model, d)));
|
||||
monaco.editor.setModelMarkers(
|
||||
model,
|
||||
this._selector,
|
||||
diagnostics.map((d) => this._convertDiagnostics(model, d))
|
||||
);
|
||||
}
|
||||
|
||||
private _convertDiagnostics(model: monaco.editor.ITextModel, diag: ts.Diagnostic): monaco.editor.IMarkerData {
|
||||
private _convertDiagnostics(
|
||||
model: monaco.editor.ITextModel,
|
||||
diag: ts.Diagnostic
|
||||
): monaco.editor.IMarkerData {
|
||||
const diagStart = diag.start || 0;
|
||||
const diagLength = diag.length || 1;
|
||||
const { lineNumber: startLineNumber, column: startColumn } = model.getPositionAt(diagStart);
|
||||
const { lineNumber: endLineNumber, column: endColumn } = model.getPositionAt(diagStart + diagLength);
|
||||
const {
|
||||
lineNumber: startLineNumber,
|
||||
column: startColumn
|
||||
} = model.getPositionAt(diagStart);
|
||||
const {
|
||||
lineNumber: endLineNumber,
|
||||
column: endColumn
|
||||
} = model.getPositionAt(diagStart + diagLength);
|
||||
|
||||
return {
|
||||
severity: this._tsDiagnosticCategoryToMarkerSeverity(diag.category),
|
||||
|
|
@ -295,11 +333,17 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
message: flattenDiagnosticMessageText(diag.messageText, '\n'),
|
||||
code: diag.code.toString(),
|
||||
tags: diag.reportsUnnecessary ? [monaco.MarkerTag.Unnecessary] : [],
|
||||
relatedInformation: this._convertRelatedInformation(model, diag.relatedInformation),
|
||||
relatedInformation: this._convertRelatedInformation(
|
||||
model,
|
||||
diag.relatedInformation
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
private _convertRelatedInformation(model: monaco.editor.ITextModel, relatedInformation?: ts.DiagnosticRelatedInformation[]): monaco.editor.IRelatedInformation[] | undefined {
|
||||
private _convertRelatedInformation(
|
||||
model: monaco.editor.ITextModel,
|
||||
relatedInformation?: ts.DiagnosticRelatedInformation[]
|
||||
): monaco.editor.IRelatedInformation[] | undefined {
|
||||
if (!relatedInformation) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -317,8 +361,14 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
}
|
||||
const infoStart = info.start || 0;
|
||||
const infoLength = info.length || 1;
|
||||
const { lineNumber: startLineNumber, column: startColumn } = relatedResource.getPositionAt(infoStart);
|
||||
const { lineNumber: endLineNumber, column: endColumn } = relatedResource.getPositionAt(infoStart + infoLength);
|
||||
const {
|
||||
lineNumber: startLineNumber,
|
||||
column: startColumn
|
||||
} = relatedResource.getPositionAt(infoStart);
|
||||
const {
|
||||
lineNumber: endLineNumber,
|
||||
column: endColumn
|
||||
} = relatedResource.getPositionAt(infoStart + infoLength);
|
||||
|
||||
result.push({
|
||||
resource: relatedResource.uri,
|
||||
|
|
@ -332,12 +382,18 @@ export class DiagnosticsAdapter extends Adapter {
|
|||
return result;
|
||||
}
|
||||
|
||||
private _tsDiagnosticCategoryToMarkerSeverity(category: ts.DiagnosticCategory): monaco.MarkerSeverity {
|
||||
private _tsDiagnosticCategoryToMarkerSeverity(
|
||||
category: ts.DiagnosticCategory
|
||||
): monaco.MarkerSeverity {
|
||||
switch (category) {
|
||||
case DiagnosticCategory.Error: return monaco.MarkerSeverity.Error
|
||||
case DiagnosticCategory.Message: return monaco.MarkerSeverity.Info
|
||||
case DiagnosticCategory.Warning: return monaco.MarkerSeverity.Warning
|
||||
case DiagnosticCategory.Suggestion: return monaco.MarkerSeverity.Hint
|
||||
case DiagnosticCategory.Error:
|
||||
return monaco.MarkerSeverity.Error;
|
||||
case DiagnosticCategory.Message:
|
||||
return monaco.MarkerSeverity.Info;
|
||||
case DiagnosticCategory.Warning:
|
||||
return monaco.MarkerSeverity.Warning;
|
||||
case DiagnosticCategory.Suggestion:
|
||||
return monaco.MarkerSeverity.Hint;
|
||||
}
|
||||
return monaco.MarkerSeverity.Info;
|
||||
}
|
||||
|
|
@ -351,30 +407,46 @@ interface MyCompletionItem extends monaco.languages.CompletionItem {
|
|||
position: Position;
|
||||
}
|
||||
|
||||
export class SuggestAdapter extends Adapter implements monaco.languages.CompletionItemProvider {
|
||||
|
||||
export class SuggestAdapter
|
||||
extends Adapter
|
||||
implements monaco.languages.CompletionItemProvider {
|
||||
public get triggerCharacters(): string[] {
|
||||
return ['.'];
|
||||
}
|
||||
|
||||
public async provideCompletionItems(model: monaco.editor.ITextModel, position: Position, _context: monaco.languages.CompletionContext, token: CancellationToken): Promise<monaco.languages.CompletionList | undefined> {
|
||||
public async provideCompletionItems(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
_context: monaco.languages.CompletionContext,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.CompletionList | undefined> {
|
||||
const wordInfo = model.getWordUntilPosition(position);
|
||||
const wordRange = new Range(position.lineNumber, wordInfo.startColumn, position.lineNumber, wordInfo.endColumn);
|
||||
const wordRange = new Range(
|
||||
position.lineNumber,
|
||||
wordInfo.startColumn,
|
||||
position.lineNumber,
|
||||
wordInfo.endColumn
|
||||
);
|
||||
const resource = model.uri;
|
||||
const offset = model.getOffsetAt(position);
|
||||
|
||||
const worker = await this._worker(resource);
|
||||
const info = await worker.getCompletionsAtPosition(resource.toString(), offset);
|
||||
const info = await worker.getCompletionsAtPosition(
|
||||
resource.toString(),
|
||||
offset
|
||||
);
|
||||
|
||||
if (!info || model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const suggestions: MyCompletionItem[] = info.entries.map(entry => {
|
||||
const suggestions: MyCompletionItem[] = info.entries.map((entry) => {
|
||||
let range = wordRange;
|
||||
if (entry.replacementSpan) {
|
||||
const p1 = model.getPositionAt(entry.replacementSpan.start);
|
||||
const p2 = model.getPositionAt(entry.replacementSpan.start + entry.replacementSpan.length);
|
||||
const p2 = model.getPositionAt(
|
||||
entry.replacementSpan.start + entry.replacementSpan.length
|
||||
);
|
||||
range = new Range(p1.lineNumber, p1.column, p2.lineNumber, p2.column);
|
||||
}
|
||||
|
||||
|
|
@ -394,14 +466,23 @@ export class SuggestAdapter extends Adapter implements monaco.languages.Completi
|
|||
};
|
||||
}
|
||||
|
||||
public async resolveCompletionItem(model: monaco.editor.ITextModel, _position: Position, item: monaco.languages.CompletionItem, token: CancellationToken): Promise<monaco.languages.CompletionItem> {
|
||||
public async resolveCompletionItem(
|
||||
model: monaco.editor.ITextModel,
|
||||
_position: Position,
|
||||
item: monaco.languages.CompletionItem,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.CompletionItem> {
|
||||
const myItem = <MyCompletionItem>item;
|
||||
const resource = myItem.uri;
|
||||
const position = myItem.position;
|
||||
const offset = model.getOffsetAt(position);
|
||||
|
||||
const worker = await this._worker(resource);
|
||||
const details = await worker.getCompletionEntryDetails(resource.toString(), offset, myItem.label);
|
||||
const details = await worker.getCompletionEntryDetails(
|
||||
resource.toString(),
|
||||
offset,
|
||||
myItem.label
|
||||
);
|
||||
if (!details || model.isDisposed()) {
|
||||
return myItem;
|
||||
}
|
||||
|
|
@ -417,7 +498,9 @@ export class SuggestAdapter extends Adapter implements monaco.languages.Completi
|
|||
};
|
||||
}
|
||||
|
||||
private static convertKind(kind: string): monaco.languages.CompletionItemKind {
|
||||
private static convertKind(
|
||||
kind: string
|
||||
): monaco.languages.CompletionItemKind {
|
||||
switch (kind) {
|
||||
case Kind.primitiveType:
|
||||
case Kind.keyword:
|
||||
|
|
@ -451,15 +534,23 @@ export class SuggestAdapter extends Adapter implements monaco.languages.Completi
|
|||
}
|
||||
}
|
||||
|
||||
export class SignatureHelpAdapter extends Adapter implements monaco.languages.SignatureHelpProvider {
|
||||
|
||||
export class SignatureHelpAdapter
|
||||
extends Adapter
|
||||
implements monaco.languages.SignatureHelpProvider {
|
||||
public signatureHelpTriggerCharacters = ['(', ','];
|
||||
|
||||
public async provideSignatureHelp(model: monaco.editor.ITextModel, position: Position, token: CancellationToken): Promise<monaco.languages.SignatureHelpResult | undefined> {
|
||||
public async provideSignatureHelp(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.SignatureHelpResult | undefined> {
|
||||
const resource = model.uri;
|
||||
const offset = model.getOffsetAt(position);
|
||||
const worker = await this._worker(resource);
|
||||
const info = await worker.getSignatureHelpItems(resource.toString(), offset);
|
||||
const info = await worker.getSignatureHelpItems(
|
||||
resource.toString(),
|
||||
offset
|
||||
);
|
||||
|
||||
if (!info || model.isDisposed()) {
|
||||
return;
|
||||
|
|
@ -471,8 +562,7 @@ export class SignatureHelpAdapter extends Adapter implements monaco.languages.Si
|
|||
signatures: []
|
||||
};
|
||||
|
||||
info.items.forEach(item => {
|
||||
|
||||
info.items.forEach((item) => {
|
||||
const signature: monaco.languages.SignatureInformation = {
|
||||
label: '',
|
||||
parameters: []
|
||||
|
|
@ -509,56 +599,84 @@ export class SignatureHelpAdapter extends Adapter implements monaco.languages.Si
|
|||
|
||||
// --- hover ------
|
||||
|
||||
export class QuickInfoAdapter extends Adapter implements monaco.languages.HoverProvider {
|
||||
|
||||
public async provideHover(model: monaco.editor.ITextModel, position: Position, token: CancellationToken): Promise<monaco.languages.Hover | undefined> {
|
||||
export class QuickInfoAdapter
|
||||
extends Adapter
|
||||
implements monaco.languages.HoverProvider {
|
||||
public async provideHover(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.Hover | undefined> {
|
||||
const resource = model.uri;
|
||||
const offset = model.getOffsetAt(position);
|
||||
const worker = await this._worker(resource);
|
||||
const info = await worker.getQuickInfoAtPosition(resource.toString(), offset);
|
||||
const info = await worker.getQuickInfoAtPosition(
|
||||
resource.toString(),
|
||||
offset
|
||||
);
|
||||
|
||||
if (!info || model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const documentation = displayPartsToString(info.documentation);
|
||||
const tags = info.tags ? info.tags.map(tag => {
|
||||
const tags = info.tags
|
||||
? info.tags
|
||||
.map((tag) => {
|
||||
const label = `*@${tag.name}*`;
|
||||
if (!tag.text) {
|
||||
return label;
|
||||
}
|
||||
return label + (tag.text.match(/\r\n|\n/g) ? ' \n' + tag.text : ` - ${tag.text}`);
|
||||
}).join(' \n\n') : '';
|
||||
return (
|
||||
label +
|
||||
(tag.text.match(/\r\n|\n/g) ? ' \n' + tag.text : ` - ${tag.text}`)
|
||||
);
|
||||
})
|
||||
.join(' \n\n')
|
||||
: '';
|
||||
const contents = displayPartsToString(info.displayParts);
|
||||
return {
|
||||
range: this._textSpanToRange(model, info.textSpan),
|
||||
contents: [{
|
||||
contents: [
|
||||
{
|
||||
value: '```js\n' + contents + '\n```\n'
|
||||
}, {
|
||||
},
|
||||
{
|
||||
value: documentation + (tags ? '\n\n' + tags : '')
|
||||
}]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// --- occurrences ------
|
||||
|
||||
export class OccurrencesAdapter extends Adapter implements monaco.languages.DocumentHighlightProvider {
|
||||
|
||||
public async provideDocumentHighlights(model: monaco.editor.ITextModel, position: Position, token: CancellationToken): Promise<monaco.languages.DocumentHighlight[] | undefined> {
|
||||
export class OccurrencesAdapter
|
||||
extends Adapter
|
||||
implements monaco.languages.DocumentHighlightProvider {
|
||||
public async provideDocumentHighlights(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.DocumentHighlight[] | undefined> {
|
||||
const resource = model.uri;
|
||||
const offset = model.getOffsetAt(position)
|
||||
const offset = model.getOffsetAt(position);
|
||||
const worker = await this._worker(resource);
|
||||
const entries = await worker.getOccurrencesAtPosition(resource.toString(), offset);
|
||||
const entries = await worker.getOccurrencesAtPosition(
|
||||
resource.toString(),
|
||||
offset
|
||||
);
|
||||
|
||||
if (!entries || model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
return entries.map(entry => {
|
||||
return entries.map((entry) => {
|
||||
return <monaco.languages.DocumentHighlight>{
|
||||
range: this._textSpanToRange(model, entry.textSpan),
|
||||
kind: entry.isWriteAccess ? monaco.languages.DocumentHighlightKind.Write : monaco.languages.DocumentHighlightKind.Text
|
||||
kind: entry.isWriteAccess
|
||||
? monaco.languages.DocumentHighlightKind.Write
|
||||
: monaco.languages.DocumentHighlightKind.Text
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
@ -567,7 +685,6 @@ export class OccurrencesAdapter extends Adapter implements monaco.languages.Docu
|
|||
// --- definition ------
|
||||
|
||||
export class DefinitionAdapter extends Adapter {
|
||||
|
||||
constructor(
|
||||
private readonly _libFiles: LibFiles,
|
||||
worker: (...uris: Uri[]) => Promise<TypeScriptWorker>
|
||||
|
|
@ -575,18 +692,27 @@ export class DefinitionAdapter extends Adapter {
|
|||
super(worker);
|
||||
}
|
||||
|
||||
public async provideDefinition(model: monaco.editor.ITextModel, position: Position, token: CancellationToken): Promise<monaco.languages.Definition | undefined> {
|
||||
public async provideDefinition(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.Definition | undefined> {
|
||||
const resource = model.uri;
|
||||
const offset = model.getOffsetAt(position);
|
||||
const worker = await this._worker(resource);
|
||||
const entries = await worker.getDefinitionAtPosition(resource.toString(), offset);
|
||||
const entries = await worker.getDefinitionAtPosition(
|
||||
resource.toString(),
|
||||
offset
|
||||
);
|
||||
|
||||
if (!entries || model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch lib files if necessary
|
||||
await this._libFiles.fetchLibFilesIfNecessary(entries.map(entry => Uri.parse(entry.fileName)));
|
||||
await this._libFiles.fetchLibFilesIfNecessary(
|
||||
entries.map((entry) => Uri.parse(entry.fileName))
|
||||
);
|
||||
|
||||
if (model.isDisposed()) {
|
||||
return;
|
||||
|
|
@ -609,8 +735,9 @@ export class DefinitionAdapter extends Adapter {
|
|||
|
||||
// --- references ------
|
||||
|
||||
export class ReferenceAdapter extends Adapter implements monaco.languages.ReferenceProvider {
|
||||
|
||||
export class ReferenceAdapter
|
||||
extends Adapter
|
||||
implements monaco.languages.ReferenceProvider {
|
||||
constructor(
|
||||
private readonly _libFiles: LibFiles,
|
||||
worker: (...uris: Uri[]) => Promise<TypeScriptWorker>
|
||||
|
|
@ -618,18 +745,28 @@ export class ReferenceAdapter extends Adapter implements monaco.languages.Refere
|
|||
super(worker);
|
||||
}
|
||||
|
||||
public async provideReferences(model: monaco.editor.ITextModel, position: Position, context: monaco.languages.ReferenceContext, token: CancellationToken): Promise<monaco.languages.Location[] | undefined> {
|
||||
public async provideReferences(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
context: monaco.languages.ReferenceContext,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.Location[] | undefined> {
|
||||
const resource = model.uri;
|
||||
const offset = model.getOffsetAt(position);
|
||||
const worker = await this._worker(resource);
|
||||
const entries = await worker.getReferencesAtPosition(resource.toString(), offset);
|
||||
const entries = await worker.getReferencesAtPosition(
|
||||
resource.toString(),
|
||||
offset
|
||||
);
|
||||
|
||||
if (!entries || model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch lib files if necessary
|
||||
await this._libFiles.fetchLibFilesIfNecessary(entries.map(entry => Uri.parse(entry.fileName)));
|
||||
await this._libFiles.fetchLibFilesIfNecessary(
|
||||
entries.map((entry) => Uri.parse(entry.fileName))
|
||||
);
|
||||
|
||||
if (model.isDisposed()) {
|
||||
return;
|
||||
|
|
@ -652,9 +789,13 @@ export class ReferenceAdapter extends Adapter implements monaco.languages.Refere
|
|||
|
||||
// --- outline ------
|
||||
|
||||
export class OutlineAdapter extends Adapter implements monaco.languages.DocumentSymbolProvider {
|
||||
|
||||
public async provideDocumentSymbols(model: monaco.editor.ITextModel, token: CancellationToken): Promise<monaco.languages.DocumentSymbol[] | undefined> {
|
||||
export class OutlineAdapter
|
||||
extends Adapter
|
||||
implements monaco.languages.DocumentSymbolProvider {
|
||||
public async provideDocumentSymbols(
|
||||
model: monaco.editor.ITextModel,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.DocumentSymbol[] | undefined> {
|
||||
const resource = model.uri;
|
||||
const worker = await this._worker(resource);
|
||||
const items = await worker.getNavigationBarItems(resource.toString());
|
||||
|
|
@ -663,11 +804,17 @@ export class OutlineAdapter extends Adapter implements monaco.languages.Document
|
|||
return;
|
||||
}
|
||||
|
||||
const convert = (bucket: monaco.languages.DocumentSymbol[], item: ts.NavigationBarItem, containerLabel?: string): void => {
|
||||
const convert = (
|
||||
bucket: monaco.languages.DocumentSymbol[],
|
||||
item: ts.NavigationBarItem,
|
||||
containerLabel?: string
|
||||
): void => {
|
||||
let result: monaco.languages.DocumentSymbol = {
|
||||
name: item.text,
|
||||
detail: '',
|
||||
kind: <monaco.languages.SymbolKind>(outlineTypeTable[item.kind] || monaco.languages.SymbolKind.Variable),
|
||||
kind: <monaco.languages.SymbolKind>(
|
||||
(outlineTypeTable[item.kind] || monaco.languages.SymbolKind.Variable)
|
||||
),
|
||||
range: this._textSpanToRange(model, item.spans[0]),
|
||||
selectionRange: this._textSpanToRange(model, item.spans[0]),
|
||||
tags: [],
|
||||
|
|
@ -681,10 +828,10 @@ export class OutlineAdapter extends Adapter implements monaco.languages.Document
|
|||
}
|
||||
|
||||
bucket.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
let result: monaco.languages.DocumentSymbol[] = [];
|
||||
items.forEach(item => convert(result, item));
|
||||
items.forEach((item) => convert(result, item));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -720,7 +867,9 @@ export class Kind {
|
|||
public static warning: string = 'warning';
|
||||
}
|
||||
|
||||
let outlineTypeTable: { [kind: string]: monaco.languages.SymbolKind } = Object.create(null);
|
||||
let outlineTypeTable: {
|
||||
[kind: string]: monaco.languages.SymbolKind;
|
||||
} = Object.create(null);
|
||||
outlineTypeTable[Kind.module] = monaco.languages.SymbolKind.Module;
|
||||
outlineTypeTable[Kind.class] = monaco.languages.SymbolKind.Class;
|
||||
outlineTypeTable[Kind.enum] = monaco.languages.SymbolKind.Enum;
|
||||
|
|
@ -739,7 +888,9 @@ outlineTypeTable[Kind.localFunction] = monaco.languages.SymbolKind.Function;
|
|||
// --- formatting ----
|
||||
|
||||
export abstract class FormatHelper extends Adapter {
|
||||
protected static _convertOptions(options: monaco.languages.FormattingOptions): ts.FormatCodeOptions {
|
||||
protected static _convertOptions(
|
||||
options: monaco.languages.FormattingOptions
|
||||
): ts.FormatCodeOptions {
|
||||
return {
|
||||
ConvertTabsToSpaces: options.insertSpaces,
|
||||
TabSize: options.tabSize,
|
||||
|
|
@ -759,7 +910,10 @@ export abstract class FormatHelper extends Adapter {
|
|||
};
|
||||
}
|
||||
|
||||
protected _convertTextChanges(model: monaco.editor.ITextModel, change: ts.TextChange): monaco.languages.TextEdit {
|
||||
protected _convertTextChanges(
|
||||
model: monaco.editor.ITextModel,
|
||||
change: ts.TextChange
|
||||
): monaco.languages.TextEdit {
|
||||
return {
|
||||
text: change.newText,
|
||||
range: this._textSpanToRange(model, change.span)
|
||||
|
|
@ -767,64 +921,116 @@ export abstract class FormatHelper extends Adapter {
|
|||
}
|
||||
}
|
||||
|
||||
export class FormatAdapter extends FormatHelper implements monaco.languages.DocumentRangeFormattingEditProvider {
|
||||
|
||||
public async provideDocumentRangeFormattingEdits(model: monaco.editor.ITextModel, range: Range, options: monaco.languages.FormattingOptions, token: CancellationToken): Promise<monaco.languages.TextEdit[] | undefined> {
|
||||
export class FormatAdapter
|
||||
extends FormatHelper
|
||||
implements monaco.languages.DocumentRangeFormattingEditProvider {
|
||||
public async provideDocumentRangeFormattingEdits(
|
||||
model: monaco.editor.ITextModel,
|
||||
range: Range,
|
||||
options: monaco.languages.FormattingOptions,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.TextEdit[] | undefined> {
|
||||
const resource = model.uri;
|
||||
const startOffset = model.getOffsetAt({ lineNumber: range.startLineNumber, column: range.startColumn });
|
||||
const endOffset = model.getOffsetAt({ lineNumber: range.endLineNumber, column: range.endColumn });
|
||||
const startOffset = model.getOffsetAt({
|
||||
lineNumber: range.startLineNumber,
|
||||
column: range.startColumn
|
||||
});
|
||||
const endOffset = model.getOffsetAt({
|
||||
lineNumber: range.endLineNumber,
|
||||
column: range.endColumn
|
||||
});
|
||||
const worker = await this._worker(resource);
|
||||
const edits = await worker.getFormattingEditsForRange(resource.toString(), startOffset, endOffset, FormatHelper._convertOptions(options));
|
||||
const edits = await worker.getFormattingEditsForRange(
|
||||
resource.toString(),
|
||||
startOffset,
|
||||
endOffset,
|
||||
FormatHelper._convertOptions(options)
|
||||
);
|
||||
|
||||
if (!edits || model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
return edits.map(edit => this._convertTextChanges(model, edit));
|
||||
return edits.map((edit) => this._convertTextChanges(model, edit));
|
||||
}
|
||||
}
|
||||
|
||||
export class FormatOnTypeAdapter extends FormatHelper implements monaco.languages.OnTypeFormattingEditProvider {
|
||||
|
||||
export class FormatOnTypeAdapter
|
||||
extends FormatHelper
|
||||
implements monaco.languages.OnTypeFormattingEditProvider {
|
||||
get autoFormatTriggerCharacters() {
|
||||
return [';', '}', '\n'];
|
||||
}
|
||||
|
||||
public async provideOnTypeFormattingEdits(model: monaco.editor.ITextModel, position: Position, ch: string, options: monaco.languages.FormattingOptions, token: CancellationToken): Promise<monaco.languages.TextEdit[] | undefined> {
|
||||
public async provideOnTypeFormattingEdits(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
ch: string,
|
||||
options: monaco.languages.FormattingOptions,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.TextEdit[] | undefined> {
|
||||
const resource = model.uri;
|
||||
const offset = model.getOffsetAt(position);
|
||||
const worker = await this._worker(resource);
|
||||
const edits = await worker.getFormattingEditsAfterKeystroke(resource.toString(), offset, ch, FormatHelper._convertOptions(options));
|
||||
const edits = await worker.getFormattingEditsAfterKeystroke(
|
||||
resource.toString(),
|
||||
offset,
|
||||
ch,
|
||||
FormatHelper._convertOptions(options)
|
||||
);
|
||||
|
||||
if (!edits || model.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
return edits.map(edit => this._convertTextChanges(model, edit));
|
||||
return edits.map((edit) => this._convertTextChanges(model, edit));
|
||||
}
|
||||
}
|
||||
|
||||
// --- code actions ------
|
||||
|
||||
export class CodeActionAdaptor extends FormatHelper implements monaco.languages.CodeActionProvider {
|
||||
|
||||
public async provideCodeActions(model: monaco.editor.ITextModel, range: Range, context: monaco.languages.CodeActionContext, token: CancellationToken): Promise<monaco.languages.CodeActionList> {
|
||||
export class CodeActionAdaptor
|
||||
extends FormatHelper
|
||||
implements monaco.languages.CodeActionProvider {
|
||||
public async provideCodeActions(
|
||||
model: monaco.editor.ITextModel,
|
||||
range: Range,
|
||||
context: monaco.languages.CodeActionContext,
|
||||
token: CancellationToken
|
||||
): Promise<monaco.languages.CodeActionList> {
|
||||
const resource = model.uri;
|
||||
const start = model.getOffsetAt({ lineNumber: range.startLineNumber, column: range.startColumn });
|
||||
const end = model.getOffsetAt({ lineNumber: range.endLineNumber, column: range.endColumn });
|
||||
const start = model.getOffsetAt({
|
||||
lineNumber: range.startLineNumber,
|
||||
column: range.startColumn
|
||||
});
|
||||
const end = model.getOffsetAt({
|
||||
lineNumber: range.endLineNumber,
|
||||
column: range.endColumn
|
||||
});
|
||||
const formatOptions = FormatHelper._convertOptions(model.getOptions());
|
||||
const errorCodes = context.markers.filter(m => m.code).map(m => m.code).map(Number);
|
||||
const errorCodes = context.markers
|
||||
.filter((m) => m.code)
|
||||
.map((m) => m.code)
|
||||
.map(Number);
|
||||
const worker = await this._worker(resource);
|
||||
const codeFixes = await worker.getCodeFixesAtPosition(resource.toString(), start, end, errorCodes, formatOptions);
|
||||
const codeFixes = await worker.getCodeFixesAtPosition(
|
||||
resource.toString(),
|
||||
start,
|
||||
end,
|
||||
errorCodes,
|
||||
formatOptions
|
||||
);
|
||||
|
||||
if (!codeFixes || model.isDisposed()) {
|
||||
return { actions: [], dispose: () => {} };
|
||||
}
|
||||
|
||||
const actions = codeFixes.filter(fix => {
|
||||
const actions = codeFixes
|
||||
.filter((fix) => {
|
||||
// Removes any 'make a new file'-type code fix
|
||||
return fix.changes.filter(change => change.isNewFile).length === 0;
|
||||
}).map(fix => {
|
||||
return fix.changes.filter((change) => change.isNewFile).length === 0;
|
||||
})
|
||||
.map((fix) => {
|
||||
return this._tsCodeFixActionToMonacoCodeAction(model, context, fix);
|
||||
});
|
||||
|
||||
|
|
@ -834,8 +1040,11 @@ export class CodeActionAdaptor extends FormatHelper implements monaco.languages.
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
private _tsCodeFixActionToMonacoCodeAction(model: monaco.editor.ITextModel, context: monaco.languages.CodeActionContext, codeFix: ts.CodeFixAction): monaco.languages.CodeAction {
|
||||
private _tsCodeFixActionToMonacoCodeAction(
|
||||
model: monaco.editor.ITextModel,
|
||||
context: monaco.languages.CodeActionContext,
|
||||
codeFix: ts.CodeFixAction
|
||||
): monaco.languages.CodeAction {
|
||||
const edits: monaco.languages.WorkspaceTextEdit[] = [];
|
||||
for (const change of codeFix.changes) {
|
||||
for (const textChange of change.textChanges) {
|
||||
|
|
@ -853,7 +1062,7 @@ export class CodeActionAdaptor extends FormatHelper implements monaco.languages.
|
|||
title: codeFix.description,
|
||||
edit: { edits: edits },
|
||||
diagnostics: context.markers,
|
||||
kind: "quickfix"
|
||||
kind: 'quickfix'
|
||||
};
|
||||
|
||||
return action;
|
||||
|
|
@ -861,26 +1070,43 @@ export class CodeActionAdaptor extends FormatHelper implements monaco.languages.
|
|||
}
|
||||
// --- rename ----
|
||||
|
||||
export class RenameAdapter extends Adapter implements monaco.languages.RenameProvider {
|
||||
|
||||
public async provideRenameEdits(model: monaco.editor.ITextModel, position: Position, newName: string, token: CancellationToken): Promise<monaco.languages.WorkspaceEdit & monaco.languages.Rejection | undefined> {
|
||||
export class RenameAdapter
|
||||
extends Adapter
|
||||
implements monaco.languages.RenameProvider {
|
||||
public async provideRenameEdits(
|
||||
model: monaco.editor.ITextModel,
|
||||
position: Position,
|
||||
newName: string,
|
||||
token: CancellationToken
|
||||
): Promise<
|
||||
(monaco.languages.WorkspaceEdit & monaco.languages.Rejection) | undefined
|
||||
> {
|
||||
const resource = model.uri;
|
||||
const fileName = resource.toString();
|
||||
const offset = model.getOffsetAt(position);
|
||||
const worker = await this._worker(resource);
|
||||
|
||||
const renameInfo = await worker.getRenameInfo(fileName, offset, { allowRenameOfImportPath: false });
|
||||
if (renameInfo.canRename === false) { // use explicit comparison so that the discriminated union gets resolved properly
|
||||
const renameInfo = await worker.getRenameInfo(fileName, offset, {
|
||||
allowRenameOfImportPath: false
|
||||
});
|
||||
if (renameInfo.canRename === false) {
|
||||
// use explicit comparison so that the discriminated union gets resolved properly
|
||||
return {
|
||||
edits: [],
|
||||
rejectReason: renameInfo.localizedErrorMessage
|
||||
};
|
||||
}
|
||||
if (renameInfo.fileToRename !== undefined) {
|
||||
throw new Error("Renaming files is not supported.");
|
||||
throw new Error('Renaming files is not supported.');
|
||||
}
|
||||
|
||||
const renameLocations = await worker.findRenameLocations(fileName, offset, /*strings*/ false, /*comments*/ false, /*prefixAndSuffix*/ false);
|
||||
const renameLocations = await worker.findRenameLocations(
|
||||
fileName,
|
||||
offset,
|
||||
/*strings*/ false,
|
||||
/*comments*/ false,
|
||||
/*prefixAndSuffix*/ false
|
||||
);
|
||||
|
||||
if (!renameLocations || model.isDisposed()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ export interface IExtraLibs {
|
|||
[path: string]: IExtraLib;
|
||||
}
|
||||
|
||||
export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.LanguageServiceDefaults {
|
||||
|
||||
export class LanguageServiceDefaultsImpl
|
||||
implements monaco.languages.typescript.LanguageServiceDefaults {
|
||||
private _onDidChange = new Emitter<void>();
|
||||
private _onDidExtraLibsChange = new Emitter<void>();
|
||||
|
||||
|
|
@ -34,12 +34,16 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
private _workerOptions!: monaco.languages.typescript.WorkerOptions;
|
||||
private _onDidExtraLibsChangeTimeout: number;
|
||||
|
||||
constructor(compilerOptions: monaco.languages.typescript.CompilerOptions, diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions, workerOptions: monaco.languages.typescript.WorkerOptions) {
|
||||
constructor(
|
||||
compilerOptions: monaco.languages.typescript.CompilerOptions,
|
||||
diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions,
|
||||
workerOptions: monaco.languages.typescript.WorkerOptions
|
||||
) {
|
||||
this._extraLibs = Object.create(null);
|
||||
this._eagerModelSync = false;
|
||||
this.setCompilerOptions(compilerOptions);
|
||||
this.setDiagnosticsOptions(diagnosticsOptions);
|
||||
this.setWorkerOptions(workerOptions)
|
||||
this.setWorkerOptions(workerOptions);
|
||||
this._onDidExtraLibsChangeTimeout = -1;
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +56,7 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
}
|
||||
|
||||
get workerOptions(): monaco.languages.typescript.WorkerOptions {
|
||||
return this._workerOptions
|
||||
return this._workerOptions;
|
||||
}
|
||||
|
||||
getExtraLibs(): IExtraLibs {
|
||||
|
|
@ -67,7 +71,10 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
filePath = _filePath;
|
||||
}
|
||||
|
||||
if (this._extraLibs[filePath] && this._extraLibs[filePath].content === content) {
|
||||
if (
|
||||
this._extraLibs[filePath] &&
|
||||
this._extraLibs[filePath].content === content
|
||||
) {
|
||||
// no-op, there already exists an extra lib with this content
|
||||
return {
|
||||
dispose: () => {}
|
||||
|
|
@ -81,7 +88,7 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
|
||||
this._extraLibs[filePath] = {
|
||||
content: content,
|
||||
version: myVersion,
|
||||
version: myVersion
|
||||
};
|
||||
this._fireOnDidExtraLibsChangeSoon();
|
||||
|
||||
|
|
@ -107,7 +114,9 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
|
||||
if (libs && libs.length > 0) {
|
||||
for (const lib of libs) {
|
||||
const filePath = lib.filePath || `ts:extralib-${Math.random().toString(36).substring(2, 15)}`;
|
||||
const filePath =
|
||||
lib.filePath ||
|
||||
`ts:extralib-${Math.random().toString(36).substring(2, 15)}`;
|
||||
const content = lib.content;
|
||||
this._extraLibs[filePath] = {
|
||||
content: content,
|
||||
|
|
@ -134,7 +143,9 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
return this._compilerOptions;
|
||||
}
|
||||
|
||||
setCompilerOptions(options: monaco.languages.typescript.CompilerOptions): void {
|
||||
setCompilerOptions(
|
||||
options: monaco.languages.typescript.CompilerOptions
|
||||
): void {
|
||||
this._compilerOptions = options || Object.create(null);
|
||||
this._onDidChange.fire(undefined);
|
||||
}
|
||||
|
|
@ -143,7 +154,9 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
return this._diagnosticsOptions;
|
||||
}
|
||||
|
||||
setDiagnosticsOptions(options: monaco.languages.typescript.DiagnosticsOptions): void {
|
||||
setDiagnosticsOptions(
|
||||
options: monaco.languages.typescript.DiagnosticsOptions
|
||||
): void {
|
||||
this._diagnosticsOptions = options || Object.create(null);
|
||||
this._onDidChange.fire(undefined);
|
||||
}
|
||||
|
|
@ -153,8 +166,7 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
this._onDidChange.fire(undefined);
|
||||
}
|
||||
|
||||
setMaximumWorkerIdleTime(value: number): void {
|
||||
}
|
||||
setMaximumWorkerIdleTime(value: number): void {}
|
||||
|
||||
setEagerModelSync(value: boolean) {
|
||||
// doesn't fire an event since no
|
||||
|
|
@ -202,7 +214,7 @@ enum ScriptTarget {
|
|||
ES2020 = 7,
|
||||
ESNext = 99,
|
||||
JSON = 100,
|
||||
Latest = ESNext,
|
||||
Latest = ESNext
|
||||
}
|
||||
|
||||
enum ModuleResolutionKind {
|
||||
|
|
@ -214,19 +226,29 @@ enum ModuleResolutionKind {
|
|||
const typescriptDefaults = new LanguageServiceDefaultsImpl(
|
||||
{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
|
||||
{ noSemanticValidation: false, noSyntaxValidation: false },
|
||||
{});
|
||||
{}
|
||||
);
|
||||
|
||||
const javascriptDefaults = new LanguageServiceDefaultsImpl(
|
||||
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
|
||||
{ noSemanticValidation: true, noSyntaxValidation: false },
|
||||
{});
|
||||
{}
|
||||
);
|
||||
|
||||
function getTypeScriptWorker(): Promise<(...uris: monaco.Uri[]) => Promise<monaco.languages.typescript.TypeScriptWorker>> {
|
||||
return getMode().then(mode => mode.getTypeScriptWorker());
|
||||
function getTypeScriptWorker(): Promise<
|
||||
(
|
||||
...uris: monaco.Uri[]
|
||||
) => Promise<monaco.languages.typescript.TypeScriptWorker>
|
||||
> {
|
||||
return getMode().then((mode) => mode.getTypeScriptWorker());
|
||||
}
|
||||
|
||||
function getJavaScriptWorker(): Promise<(...uris: monaco.Uri[]) => Promise<monaco.languages.typescript.TypeScriptWorker>> {
|
||||
return getMode().then(mode => mode.getJavaScriptWorker());
|
||||
function getJavaScriptWorker(): Promise<
|
||||
(
|
||||
...uris: monaco.Uri[]
|
||||
) => Promise<monaco.languages.typescript.TypeScriptWorker>
|
||||
> {
|
||||
return getMode().then((mode) => mode.getJavaScriptWorker());
|
||||
}
|
||||
|
||||
// Export API
|
||||
|
|
@ -242,7 +264,7 @@ function createAPI(): typeof monaco.languages.typescript {
|
|||
javascriptDefaults: javascriptDefaults,
|
||||
getTypeScriptWorker: getTypeScriptWorker,
|
||||
getJavaScriptWorker: getJavaScriptWorker
|
||||
}
|
||||
};
|
||||
}
|
||||
monaco.languages.typescript = createAPI();
|
||||
|
||||
|
|
@ -253,8 +275,8 @@ function getMode(): Promise<typeof mode> {
|
|||
}
|
||||
|
||||
monaco.languages.onLanguage('typescript', () => {
|
||||
return getMode().then(mode => mode.setupTypeScript(typescriptDefaults));
|
||||
return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
|
||||
});
|
||||
monaco.languages.onLanguage('javascript', () => {
|
||||
return getMode().then(mode => mode.setupJavaScript(javascriptDefaults));
|
||||
return getMode().then((mode) => mode.setupJavaScript(javascriptDefaults));
|
||||
});
|
||||
|
|
|
|||
99
src/monaco.d.ts
vendored
99
src/monaco.d.ts
vendored
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
declare module monaco.languages.typescript {
|
||||
|
||||
enum ModuleKind {
|
||||
None = 0,
|
||||
CommonJS = 1,
|
||||
|
|
@ -33,7 +31,7 @@ declare module monaco.languages.typescript {
|
|||
ES2020 = 7,
|
||||
ESNext = 99,
|
||||
JSON = 100,
|
||||
Latest = ESNext,
|
||||
Latest = ESNext
|
||||
}
|
||||
|
||||
export enum ModuleResolutionKind {
|
||||
|
|
@ -45,7 +43,15 @@ declare module monaco.languages.typescript {
|
|||
[index: string]: T;
|
||||
}
|
||||
|
||||
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | null | undefined;
|
||||
type CompilerOptionsValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| (string | number)[]
|
||||
| string[]
|
||||
| MapLike<string[]>
|
||||
| null
|
||||
| undefined;
|
||||
interface CompilerOptions {
|
||||
allowJs?: boolean;
|
||||
allowSyntheticDefaultImports?: boolean;
|
||||
|
|
@ -295,43 +301,65 @@ declare module monaco.languages.typescript {
|
|||
* Get code completions for the given file and position.
|
||||
* @returns `Promise<typescript.CompletionInfo | undefined>`
|
||||
*/
|
||||
getCompletionsAtPosition(fileName: string, position: number): Promise<any | undefined>;
|
||||
getCompletionsAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<any | undefined>;
|
||||
|
||||
/**
|
||||
* Get code completion details for the given file, position, and entry.
|
||||
* @returns `Promise<typescript.CompletionEntryDetails | undefined>`
|
||||
*/
|
||||
getCompletionEntryDetails(fileName: string, position: number, entry: string): Promise<any | undefined>;
|
||||
getCompletionEntryDetails(
|
||||
fileName: string,
|
||||
position: number,
|
||||
entry: string
|
||||
): Promise<any | undefined>;
|
||||
|
||||
/**
|
||||
* Get signature help items for the item at the given file and position.
|
||||
* @returns `Promise<typescript.SignatureHelpItems | undefined>`
|
||||
*/
|
||||
getSignatureHelpItems(fileName: string, position: number): Promise<any | undefined>;
|
||||
getSignatureHelpItems(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<any | undefined>;
|
||||
|
||||
/**
|
||||
* Get quick info for the item at the given position in the file.
|
||||
* @returns `Promise<typescript.QuickInfo | undefined>`
|
||||
*/
|
||||
getQuickInfoAtPosition(fileName: string, position: number): Promise<any | undefined>;
|
||||
getQuickInfoAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<any | undefined>;
|
||||
|
||||
/**
|
||||
* Get other ranges which are related to the item at the given position in the file (often used for highlighting).
|
||||
* @returns `Promise<ReadonlyArray<typescript.ReferenceEntry> | undefined>`
|
||||
*/
|
||||
getOccurrencesAtPosition(fileName: string, position: number): Promise<ReadonlyArray<any> | undefined>;
|
||||
getOccurrencesAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ReadonlyArray<any> | undefined>;
|
||||
|
||||
/**
|
||||
* Get the definition of the item at the given position in the file.
|
||||
* @returns `Promise<ReadonlyArray<typescript.DefinitionInfo> | undefined>`
|
||||
*/
|
||||
getDefinitionAtPosition(fileName: string, position: number): Promise<ReadonlyArray<any> | undefined>;
|
||||
getDefinitionAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ReadonlyArray<any> | undefined>;
|
||||
|
||||
/**
|
||||
* Get references to the item at the given position in the file.
|
||||
* @returns `Promise<typescript.ReferenceEntry[] | undefined>`
|
||||
*/
|
||||
getReferencesAtPosition(fileName: string, position: number): Promise<any[] | undefined>;
|
||||
getReferencesAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<any[] | undefined>;
|
||||
|
||||
/**
|
||||
* Get outline entries for the item at the given position in the file.
|
||||
|
|
@ -344,34 +372,57 @@ declare module monaco.languages.typescript {
|
|||
* @param options `typescript.FormatCodeOptions`
|
||||
* @returns `Promise<typescript.TextChange[]>`
|
||||
*/
|
||||
getFormattingEditsForDocument(fileName: string, options: any): Promise<any[]>;
|
||||
getFormattingEditsForDocument(
|
||||
fileName: string,
|
||||
options: any
|
||||
): Promise<any[]>;
|
||||
|
||||
/**
|
||||
* Get changes which should be applied to format the given range in the file.
|
||||
* @param options `typescript.FormatCodeOptions`
|
||||
* @returns `Promise<typescript.TextChange[]>`
|
||||
*/
|
||||
getFormattingEditsForRange(fileName: string, start: number, end: number, options: any): Promise<any[]>;
|
||||
getFormattingEditsForRange(
|
||||
fileName: string,
|
||||
start: number,
|
||||
end: number,
|
||||
options: any
|
||||
): Promise<any[]>;
|
||||
|
||||
/**
|
||||
* Get formatting changes which should be applied after the given keystroke.
|
||||
* @param options `typescript.FormatCodeOptions`
|
||||
* @returns `Promise<typescript.TextChange[]>`
|
||||
*/
|
||||
getFormattingEditsAfterKeystroke(fileName: string, postion: number, ch: string, options: any): Promise<any[]>;
|
||||
getFormattingEditsAfterKeystroke(
|
||||
fileName: string,
|
||||
postion: number,
|
||||
ch: string,
|
||||
options: any
|
||||
): Promise<any[]>;
|
||||
|
||||
/**
|
||||
* Get other occurrences which should be updated when renaming the item at the given file and position.
|
||||
* @returns `Promise<readonly typescript.RenameLocation[] | undefined>`
|
||||
*/
|
||||
findRenameLocations(fileName: string, positon: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename: boolean): Promise<readonly any[] | undefined>;
|
||||
findRenameLocations(
|
||||
fileName: string,
|
||||
positon: number,
|
||||
findInStrings: boolean,
|
||||
findInComments: boolean,
|
||||
providePrefixAndSuffixTextForRename: boolean
|
||||
): Promise<readonly any[] | undefined>;
|
||||
|
||||
/**
|
||||
* Get edits which should be applied to rename the item at the given file and position (or a failure reason).
|
||||
* @param options `typescript.RenameInfoOptions`
|
||||
* @returns `Promise<typescript.RenameInfo>`
|
||||
*/
|
||||
getRenameInfo(fileName: string, positon: number, options: any): Promise<any>;
|
||||
getRenameInfo(
|
||||
fileName: string,
|
||||
positon: number,
|
||||
options: any
|
||||
): Promise<any>;
|
||||
|
||||
/**
|
||||
* Get transpiled output for the given file.
|
||||
|
|
@ -384,7 +435,13 @@ declare module monaco.languages.typescript {
|
|||
* @param formatOptions `typescript.FormatCodeOptions`
|
||||
* @returns `Promise<ReadonlyArray<typescript.CodeFixAction>>`
|
||||
*/
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: any): Promise<ReadonlyArray<any>>;
|
||||
getCodeFixesAtPosition(
|
||||
fileName: string,
|
||||
start: number,
|
||||
end: number,
|
||||
errorCodes: number[],
|
||||
formatOptions: any
|
||||
): Promise<ReadonlyArray<any>>;
|
||||
}
|
||||
|
||||
export const typescriptVersion: string;
|
||||
|
|
@ -392,6 +449,10 @@ declare module monaco.languages.typescript {
|
|||
export const typescriptDefaults: LanguageServiceDefaults;
|
||||
export const javascriptDefaults: LanguageServiceDefaults;
|
||||
|
||||
export const getTypeScriptWorker: () => Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>>;
|
||||
export const getJavaScriptWorker: () => Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>>;
|
||||
export const getTypeScriptWorker: () => Promise<
|
||||
(...uris: Uri[]) => Promise<TypeScriptWorker>
|
||||
>;
|
||||
export const getJavaScriptWorker: () => Promise<
|
||||
(...uris: Uri[]) => Promise<TypeScriptWorker>
|
||||
>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import { TypeScriptWorker, ICreateData } from './tsWorker';
|
|||
|
||||
self.onmessage = () => {
|
||||
// ignore the first message
|
||||
worker.initialize((ctx: monaco.worker.IWorkerContext, createData: ICreateData) => {
|
||||
return new TypeScriptWorker(ctx, createData)
|
||||
});
|
||||
worker.initialize(
|
||||
(ctx: monaco.worker.IWorkerContext, createData: ICreateData) => {
|
||||
return new TypeScriptWorker(ctx, createData);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,41 +15,41 @@ let javaScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
|
|||
let typeScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
|
||||
|
||||
export function setupTypeScript(defaults: LanguageServiceDefaultsImpl): void {
|
||||
typeScriptWorker = setupMode(
|
||||
defaults,
|
||||
'typescript'
|
||||
);
|
||||
typeScriptWorker = setupMode(defaults, 'typescript');
|
||||
}
|
||||
|
||||
export function setupJavaScript(defaults: LanguageServiceDefaultsImpl): void {
|
||||
javaScriptWorker = setupMode(
|
||||
defaults,
|
||||
'javascript'
|
||||
);
|
||||
javaScriptWorker = setupMode(defaults, 'javascript');
|
||||
}
|
||||
|
||||
export function getJavaScriptWorker(): Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>> {
|
||||
export function getJavaScriptWorker(): Promise<
|
||||
(...uris: Uri[]) => Promise<TypeScriptWorker>
|
||||
> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!javaScriptWorker) {
|
||||
return reject("JavaScript not registered!");
|
||||
return reject('JavaScript not registered!');
|
||||
}
|
||||
|
||||
resolve(javaScriptWorker);
|
||||
});
|
||||
}
|
||||
|
||||
export function getTypeScriptWorker(): Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>> {
|
||||
export function getTypeScriptWorker(): Promise<
|
||||
(...uris: Uri[]) => Promise<TypeScriptWorker>
|
||||
> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!typeScriptWorker) {
|
||||
return reject("TypeScript not registered!");
|
||||
return reject('TypeScript not registered!');
|
||||
}
|
||||
|
||||
resolve(typeScriptWorker);
|
||||
});
|
||||
}
|
||||
|
||||
function setupMode(defaults: LanguageServiceDefaultsImpl, modeId: string): (...uris: Uri[]) => Promise<TypeScriptWorker> {
|
||||
|
||||
function setupMode(
|
||||
defaults: LanguageServiceDefaultsImpl,
|
||||
modeId: string
|
||||
): (...uris: Uri[]) => Promise<TypeScriptWorker> {
|
||||
const client = new WorkerManager(modeId, defaults);
|
||||
const worker = (...uris: Uri[]): Promise<TypeScriptWorker> => {
|
||||
return client.getLanguageServiceWorker(...uris);
|
||||
|
|
@ -57,17 +57,50 @@ function setupMode(defaults: LanguageServiceDefaultsImpl, modeId: string): (...u
|
|||
|
||||
const libFiles = new languageFeatures.LibFiles(worker);
|
||||
|
||||
monaco.languages.registerCompletionItemProvider(modeId, new languageFeatures.SuggestAdapter(worker));
|
||||
monaco.languages.registerSignatureHelpProvider(modeId, new languageFeatures.SignatureHelpAdapter(worker));
|
||||
monaco.languages.registerHoverProvider(modeId, new languageFeatures.QuickInfoAdapter(worker));
|
||||
monaco.languages.registerDocumentHighlightProvider(modeId, new languageFeatures.OccurrencesAdapter(worker));
|
||||
monaco.languages.registerDefinitionProvider(modeId, new languageFeatures.DefinitionAdapter(libFiles, worker));
|
||||
monaco.languages.registerReferenceProvider(modeId, new languageFeatures.ReferenceAdapter(libFiles, worker));
|
||||
monaco.languages.registerDocumentSymbolProvider(modeId, new languageFeatures.OutlineAdapter(worker));
|
||||
monaco.languages.registerDocumentRangeFormattingEditProvider(modeId, new languageFeatures.FormatAdapter(worker));
|
||||
monaco.languages.registerOnTypeFormattingEditProvider(modeId, new languageFeatures.FormatOnTypeAdapter(worker));
|
||||
monaco.languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker));
|
||||
monaco.languages.registerRenameProvider(modeId, new languageFeatures.RenameAdapter(worker));
|
||||
monaco.languages.registerCompletionItemProvider(
|
||||
modeId,
|
||||
new languageFeatures.SuggestAdapter(worker)
|
||||
);
|
||||
monaco.languages.registerSignatureHelpProvider(
|
||||
modeId,
|
||||
new languageFeatures.SignatureHelpAdapter(worker)
|
||||
);
|
||||
monaco.languages.registerHoverProvider(
|
||||
modeId,
|
||||
new languageFeatures.QuickInfoAdapter(worker)
|
||||
);
|
||||
monaco.languages.registerDocumentHighlightProvider(
|
||||
modeId,
|
||||
new languageFeatures.OccurrencesAdapter(worker)
|
||||
);
|
||||
monaco.languages.registerDefinitionProvider(
|
||||
modeId,
|
||||
new languageFeatures.DefinitionAdapter(libFiles, worker)
|
||||
);
|
||||
monaco.languages.registerReferenceProvider(
|
||||
modeId,
|
||||
new languageFeatures.ReferenceAdapter(libFiles, worker)
|
||||
);
|
||||
monaco.languages.registerDocumentSymbolProvider(
|
||||
modeId,
|
||||
new languageFeatures.OutlineAdapter(worker)
|
||||
);
|
||||
monaco.languages.registerDocumentRangeFormattingEditProvider(
|
||||
modeId,
|
||||
new languageFeatures.FormatAdapter(worker)
|
||||
);
|
||||
monaco.languages.registerOnTypeFormattingEditProvider(
|
||||
modeId,
|
||||
new languageFeatures.FormatOnTypeAdapter(worker)
|
||||
);
|
||||
monaco.languages.registerCodeActionProvider(
|
||||
modeId,
|
||||
new languageFeatures.CodeActionAdaptor(worker)
|
||||
);
|
||||
monaco.languages.registerRenameProvider(
|
||||
modeId,
|
||||
new languageFeatures.RenameAdapter(worker)
|
||||
);
|
||||
new languageFeatures.DiagnosticsAdapter(libFiles, defaults, modeId, worker);
|
||||
|
||||
return worker;
|
||||
|
|
|
|||
272
src/tsWorker.ts
272
src/tsWorker.ts
|
|
@ -10,9 +10,10 @@ import { IExtraLibs } from './monaco.contribution';
|
|||
|
||||
import IWorkerContext = monaco.worker.IWorkerContext;
|
||||
|
||||
|
||||
export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.languages.typescript.TypeScriptWorker {
|
||||
|
||||
export class TypeScriptWorker
|
||||
implements
|
||||
ts.LanguageServiceHost,
|
||||
monaco.languages.typescript.TypeScriptWorker {
|
||||
// --- model sync -----------------------
|
||||
|
||||
private _ctx: IWorkerContext;
|
||||
|
|
@ -33,7 +34,9 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
|||
}
|
||||
|
||||
getScriptFileNames(): string[] {
|
||||
let models = this._ctx.getMirrorModels().map(model => model.uri.toString());
|
||||
let models = this._ctx
|
||||
.getMirrorModels()
|
||||
.map((model) => model.uri.toString());
|
||||
return models.concat(Object.keys(this._extraLibs));
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +75,6 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
|||
text = model.getValue();
|
||||
} else if (fileName in libFileMap) {
|
||||
text = libFileMap[fileName];
|
||||
|
||||
} else if (fileName in this._extraLibs) {
|
||||
// extra lib
|
||||
text = this._extraLibs[fileName].content;
|
||||
|
|
@ -99,11 +101,16 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
|||
getScriptKind?(fileName: string): ts.ScriptKind {
|
||||
const suffix = fileName.substr(fileName.lastIndexOf('.') + 1);
|
||||
switch (suffix) {
|
||||
case 'ts': return ts.ScriptKind.TS;
|
||||
case 'tsx': return ts.ScriptKind.TSX;
|
||||
case 'js': return ts.ScriptKind.JS;
|
||||
case 'jsx': return ts.ScriptKind.JSX;
|
||||
default: return this.getCompilationSettings().allowJs
|
||||
case 'ts':
|
||||
return ts.ScriptKind.TS;
|
||||
case 'tsx':
|
||||
return ts.ScriptKind.TSX;
|
||||
case 'js':
|
||||
return ts.ScriptKind.JS;
|
||||
case 'jsx':
|
||||
return ts.ScriptKind.JSX;
|
||||
default:
|
||||
return this.getCompilationSettings().allowJs
|
||||
? ts.ScriptKind.JS
|
||||
: ts.ScriptKind.TS;
|
||||
}
|
||||
|
|
@ -116,8 +123,8 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
|||
getDefaultLibFileName(options: ts.CompilerOptions): string {
|
||||
switch (options.target) {
|
||||
case 99 /* ESNext */:
|
||||
const esnext = "lib.esnext.full.d.ts";
|
||||
if (esnext in libFileMap || esnext in this._extraLibs) return esnext
|
||||
const esnext = 'lib.esnext.full.d.ts';
|
||||
if (esnext in libFileMap || esnext in this._extraLibs) return esnext;
|
||||
case 7 /* ES2020 */:
|
||||
case 6 /* ES2019 */:
|
||||
case 5 /* ES2018 */:
|
||||
|
|
@ -135,10 +142,10 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
|||
return eslib;
|
||||
}
|
||||
|
||||
return "lib.es6.d.ts"; // We don't use lib.es2015.full.d.ts due to breaking change.
|
||||
return 'lib.es6.d.ts'; // We don't use lib.es2015.full.d.ts due to breaking change.
|
||||
case 1:
|
||||
case 0:
|
||||
return "lib.d.ts";
|
||||
return 'lib.d.ts';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,98 +159,223 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
|||
|
||||
// --- language features
|
||||
|
||||
private static clearFiles(diagnostics: ts.Diagnostic[]): monaco.languages.typescript.Diagnostic[] {
|
||||
private static clearFiles(
|
||||
diagnostics: ts.Diagnostic[]
|
||||
): monaco.languages.typescript.Diagnostic[] {
|
||||
// Clear the `file` field, which cannot be JSON'yfied because it
|
||||
// contains cyclic data structures.
|
||||
diagnostics.forEach(diag => {
|
||||
diagnostics.forEach((diag) => {
|
||||
diag.file = undefined;
|
||||
const related = <ts.Diagnostic[]>diag.relatedInformation;
|
||||
if (related) {
|
||||
related.forEach(diag2 => diag2.file = undefined);
|
||||
related.forEach((diag2) => (diag2.file = undefined));
|
||||
}
|
||||
});
|
||||
return <monaco.languages.typescript.Diagnostic[]>diagnostics;
|
||||
}
|
||||
|
||||
getSyntacticDiagnostics(fileName: string): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
getSyntacticDiagnostics(
|
||||
fileName: string
|
||||
): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getSyntacticDiagnostics(fileName);
|
||||
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
|
||||
}
|
||||
|
||||
getSemanticDiagnostics(fileName: string): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
getSemanticDiagnostics(
|
||||
fileName: string
|
||||
): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getSemanticDiagnostics(fileName);
|
||||
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
|
||||
}
|
||||
|
||||
getSuggestionDiagnostics(fileName: string): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getSuggestionDiagnostics(fileName);
|
||||
getSuggestionDiagnostics(
|
||||
fileName: string
|
||||
): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getSuggestionDiagnostics(
|
||||
fileName
|
||||
);
|
||||
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
|
||||
}
|
||||
|
||||
getCompilerOptionsDiagnostics(fileName: string): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
getCompilerOptionsDiagnostics(
|
||||
fileName: string
|
||||
): Promise<monaco.languages.typescript.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getCompilerOptionsDiagnostics();
|
||||
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
|
||||
}
|
||||
|
||||
getCompletionsAtPosition(fileName: string, position: number): Promise<ts.CompletionInfo | undefined> {
|
||||
return Promise.resolve(this._languageService.getCompletionsAtPosition(fileName, position, undefined));
|
||||
getCompletionsAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ts.CompletionInfo | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getCompletionsAtPosition(
|
||||
fileName,
|
||||
position,
|
||||
undefined
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getCompletionEntryDetails(fileName: string, position: number, entry: string): Promise<ts.CompletionEntryDetails | undefined> {
|
||||
return Promise.resolve(this._languageService.getCompletionEntryDetails(fileName, position, entry, undefined, undefined, undefined));
|
||||
getCompletionEntryDetails(
|
||||
fileName: string,
|
||||
position: number,
|
||||
entry: string
|
||||
): Promise<ts.CompletionEntryDetails | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getCompletionEntryDetails(
|
||||
fileName,
|
||||
position,
|
||||
entry,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getSignatureHelpItems(fileName: string, position: number): Promise<ts.SignatureHelpItems | undefined> {
|
||||
return Promise.resolve(this._languageService.getSignatureHelpItems(fileName, position, undefined));
|
||||
getSignatureHelpItems(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ts.SignatureHelpItems | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getSignatureHelpItems(fileName, position, undefined)
|
||||
);
|
||||
}
|
||||
|
||||
getQuickInfoAtPosition(fileName: string, position: number): Promise<ts.QuickInfo | undefined> {
|
||||
return Promise.resolve(this._languageService.getQuickInfoAtPosition(fileName, position));
|
||||
getQuickInfoAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ts.QuickInfo | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getQuickInfoAtPosition(fileName, position)
|
||||
);
|
||||
}
|
||||
|
||||
getOccurrencesAtPosition(fileName: string, position: number): Promise<ReadonlyArray<ts.ReferenceEntry> | undefined> {
|
||||
return Promise.resolve(this._languageService.getOccurrencesAtPosition(fileName, position));
|
||||
getOccurrencesAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ReadonlyArray<ts.ReferenceEntry> | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getOccurrencesAtPosition(fileName, position)
|
||||
);
|
||||
}
|
||||
|
||||
getDefinitionAtPosition(fileName: string, position: number): Promise<ReadonlyArray<ts.DefinitionInfo> | undefined> {
|
||||
return Promise.resolve(this._languageService.getDefinitionAtPosition(fileName, position));
|
||||
getDefinitionAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ReadonlyArray<ts.DefinitionInfo> | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getDefinitionAtPosition(fileName, position)
|
||||
);
|
||||
}
|
||||
|
||||
getReferencesAtPosition(fileName: string, position: number): Promise<ts.ReferenceEntry[] | undefined> {
|
||||
return Promise.resolve(this._languageService.getReferencesAtPosition(fileName, position));
|
||||
getReferencesAtPosition(
|
||||
fileName: string,
|
||||
position: number
|
||||
): Promise<ts.ReferenceEntry[] | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getReferencesAtPosition(fileName, position)
|
||||
);
|
||||
}
|
||||
|
||||
getNavigationBarItems(fileName: string): Promise<ts.NavigationBarItem[]> {
|
||||
return Promise.resolve(this._languageService.getNavigationBarItems(fileName));
|
||||
return Promise.resolve(
|
||||
this._languageService.getNavigationBarItems(fileName)
|
||||
);
|
||||
}
|
||||
|
||||
getFormattingEditsForDocument(fileName: string, options: ts.FormatCodeOptions): Promise<ts.TextChange[]> {
|
||||
return Promise.resolve(this._languageService.getFormattingEditsForDocument(fileName, options));
|
||||
getFormattingEditsForDocument(
|
||||
fileName: string,
|
||||
options: ts.FormatCodeOptions
|
||||
): Promise<ts.TextChange[]> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getFormattingEditsForDocument(fileName, options)
|
||||
);
|
||||
}
|
||||
|
||||
getFormattingEditsForRange(fileName: string, start: number, end: number, options: ts.FormatCodeOptions): Promise<ts.TextChange[]> {
|
||||
return Promise.resolve(this._languageService.getFormattingEditsForRange(fileName, start, end, options));
|
||||
getFormattingEditsForRange(
|
||||
fileName: string,
|
||||
start: number,
|
||||
end: number,
|
||||
options: ts.FormatCodeOptions
|
||||
): Promise<ts.TextChange[]> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getFormattingEditsForRange(
|
||||
fileName,
|
||||
start,
|
||||
end,
|
||||
options
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getFormattingEditsAfterKeystroke(fileName: string, postion: number, ch: string, options: ts.FormatCodeOptions): Promise<ts.TextChange[]> {
|
||||
return Promise.resolve(this._languageService.getFormattingEditsAfterKeystroke(fileName, postion, ch, options));
|
||||
getFormattingEditsAfterKeystroke(
|
||||
fileName: string,
|
||||
postion: number,
|
||||
ch: string,
|
||||
options: ts.FormatCodeOptions
|
||||
): Promise<ts.TextChange[]> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getFormattingEditsAfterKeystroke(
|
||||
fileName,
|
||||
postion,
|
||||
ch,
|
||||
options
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename: boolean): Promise<readonly ts.RenameLocation[] | undefined> {
|
||||
return Promise.resolve(this._languageService.findRenameLocations(fileName, position, findInStrings, findInComments, providePrefixAndSuffixTextForRename));
|
||||
findRenameLocations(
|
||||
fileName: string,
|
||||
position: number,
|
||||
findInStrings: boolean,
|
||||
findInComments: boolean,
|
||||
providePrefixAndSuffixTextForRename: boolean
|
||||
): Promise<readonly ts.RenameLocation[] | undefined> {
|
||||
return Promise.resolve(
|
||||
this._languageService.findRenameLocations(
|
||||
fileName,
|
||||
position,
|
||||
findInStrings,
|
||||
findInComments,
|
||||
providePrefixAndSuffixTextForRename
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getRenameInfo(fileName: string, position: number, options: ts.RenameInfoOptions): Promise<ts.RenameInfo> {
|
||||
return Promise.resolve(this._languageService.getRenameInfo(fileName, position, options));
|
||||
getRenameInfo(
|
||||
fileName: string,
|
||||
position: number,
|
||||
options: ts.RenameInfoOptions
|
||||
): Promise<ts.RenameInfo> {
|
||||
return Promise.resolve(
|
||||
this._languageService.getRenameInfo(fileName, position, options)
|
||||
);
|
||||
}
|
||||
|
||||
getEmitOutput(fileName: string): Promise<ts.EmitOutput> {
|
||||
return Promise.resolve(this._languageService.getEmitOutput(fileName));
|
||||
}
|
||||
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: ts.FormatCodeOptions): Promise<ReadonlyArray<ts.CodeFixAction>> {
|
||||
const preferences = {}
|
||||
return Promise.resolve(this._languageService.getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences));
|
||||
getCodeFixesAtPosition(
|
||||
fileName: string,
|
||||
start: number,
|
||||
end: number,
|
||||
errorCodes: number[],
|
||||
formatOptions: ts.FormatCodeOptions
|
||||
): Promise<ReadonlyArray<ts.CodeFixAction>> {
|
||||
const preferences = {};
|
||||
return Promise.resolve(
|
||||
this._languageService.getCodeFixesAtPosition(
|
||||
fileName,
|
||||
start,
|
||||
end,
|
||||
errorCodes,
|
||||
formatOptions,
|
||||
preferences
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
updateExtraLibs(extraLibs: IExtraLibs) {
|
||||
|
|
@ -254,31 +386,45 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language
|
|||
export interface ICreateData {
|
||||
compilerOptions: ts.CompilerOptions;
|
||||
extraLibs: IExtraLibs;
|
||||
customWorkerPath?: string
|
||||
customWorkerPath?: string;
|
||||
}
|
||||
|
||||
/** The shape of the factory */
|
||||
export interface CustomTSWebWorkerFactory {
|
||||
(TSWorkerClass: typeof TypeScriptWorker, tsc: typeof ts, libs: Record<string, string>): typeof TypeScriptWorker
|
||||
(
|
||||
TSWorkerClass: typeof TypeScriptWorker,
|
||||
tsc: typeof ts,
|
||||
libs: Record<string, string>
|
||||
): typeof TypeScriptWorker;
|
||||
}
|
||||
|
||||
export function create(ctx: IWorkerContext, createData: ICreateData): TypeScriptWorker {
|
||||
let TSWorkerClass = TypeScriptWorker
|
||||
declare global {
|
||||
var importScripts: (path: string) => void | undefined;
|
||||
var customTSWorkerFactory: CustomTSWebWorkerFactory | undefined;
|
||||
}
|
||||
|
||||
export function create(
|
||||
ctx: IWorkerContext,
|
||||
createData: ICreateData
|
||||
): TypeScriptWorker {
|
||||
let TSWorkerClass = TypeScriptWorker;
|
||||
if (createData.customWorkerPath) {
|
||||
// @ts-ignore - This is available in a webworker
|
||||
if (typeof importScripts === "undefined") {
|
||||
console.warn("Monaco is not using webworkers for background tasks, and that is needed to support the customWorkerPath flag")
|
||||
if (typeof importScripts === 'undefined') {
|
||||
console.warn(
|
||||
'Monaco is not using webworkers for background tasks, and that is needed to support the customWorkerPath flag'
|
||||
);
|
||||
} else {
|
||||
// @ts-ignore - This is available in a webworker
|
||||
importScripts(createData.customWorkerPath)
|
||||
importScripts(createData.customWorkerPath);
|
||||
|
||||
// @ts-ignore - This should come from the above eval
|
||||
const workerFactoryFunc: CustomTSWebWorkerFactory | undefined = self.customTSWorkerFactory
|
||||
const workerFactoryFunc: CustomTSWebWorkerFactory | undefined =
|
||||
self.customTSWorkerFactory;
|
||||
if (!workerFactoryFunc) {
|
||||
throw new Error(`The script at ${createData.customWorkerPath} does not add customTSWorkerFactory to self`)
|
||||
throw new Error(
|
||||
`The script at ${createData.customWorkerPath} does not add customTSWorkerFactory to self`
|
||||
);
|
||||
}
|
||||
|
||||
TSWorkerClass = workerFactoryFunc(TypeScriptWorker, ts, libFileMap)
|
||||
TSWorkerClass = workerFactoryFunc(TypeScriptWorker, ts, libFileMap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@
|
|||
],
|
||||
"strict": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
],
|
||||
"files": [
|
||||
"../node_modules/monaco-editor-core/monaco.d.ts"
|
||||
]
|
||||
"include": ["**/*.ts"],
|
||||
"files": ["../node_modules/monaco-editor-core/monaco.d.ts"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@
|
|||
],
|
||||
"strict": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
],
|
||||
"files": [
|
||||
"../node_modules/monaco-editor-core/monaco.d.ts"
|
||||
]
|
||||
"include": ["**/*.ts"],
|
||||
"files": ["../node_modules/monaco-editor-core/monaco.d.ts"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import IDisposable = monaco.IDisposable;
|
|||
import Uri = monaco.Uri;
|
||||
|
||||
export class WorkerManager {
|
||||
|
||||
private _modeId: string;
|
||||
private _defaults: LanguageServiceDefaultsImpl;
|
||||
private _configChangeListener: IDisposable;
|
||||
|
|
@ -26,9 +25,13 @@ export class WorkerManager {
|
|||
this._defaults = defaults;
|
||||
this._worker = null;
|
||||
this._client = null;
|
||||
this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
|
||||
this._configChangeListener = this._defaults.onDidChange(() =>
|
||||
this._stopWorker()
|
||||
);
|
||||
this._updateExtraLibsToken = 0;
|
||||
this._extraLibsChangeListener = this._defaults.onDidExtraLibsChange(() => this._updateExtraLibs());
|
||||
this._extraLibsChangeListener = this._defaults.onDidExtraLibsChange(() =>
|
||||
this._updateExtraLibs()
|
||||
);
|
||||
}
|
||||
|
||||
private _stopWorker(): void {
|
||||
|
|
@ -61,7 +64,6 @@ export class WorkerManager {
|
|||
private _getClient(): Promise<TypeScriptWorker> {
|
||||
if (!this._client) {
|
||||
this._worker = monaco.editor.createWebWorker<TypeScriptWorker>({
|
||||
|
||||
// module that exports the create() method and returns a `TypeScriptWorker` instance
|
||||
moduleId: 'vs/language/typescript/tsWorker',
|
||||
|
||||
|
|
@ -80,11 +82,13 @@ export class WorkerManager {
|
|||
let p = <Promise<TypeScriptWorker>>this._worker.getProxy();
|
||||
|
||||
if (this._defaults.getEagerModelSync()) {
|
||||
p = p.then(worker => {
|
||||
p = p.then((worker) => {
|
||||
if (this._worker) {
|
||||
return this._worker.withSyncedResources(monaco.editor.getModels()
|
||||
.filter(model => model.getModeId() === this._modeId)
|
||||
.map(model => model.uri)
|
||||
return this._worker.withSyncedResources(
|
||||
monaco.editor
|
||||
.getModels()
|
||||
.filter((model) => model.getModeId() === this._modeId)
|
||||
.map((model) => model.uri)
|
||||
);
|
||||
}
|
||||
return worker;
|
||||
|
|
@ -99,12 +103,15 @@ export class WorkerManager {
|
|||
|
||||
getLanguageServiceWorker(...resources: Uri[]): Promise<TypeScriptWorker> {
|
||||
let _client: TypeScriptWorker;
|
||||
return this._getClient().then((client) => {
|
||||
_client = client
|
||||
}).then(_ => {
|
||||
return this._getClient()
|
||||
.then((client) => {
|
||||
_client = client;
|
||||
})
|
||||
.then((_) => {
|
||||
if (this._worker) {
|
||||
return this._worker.withSyncedResources(resources)
|
||||
return this._worker.withSyncedResources(resources);
|
||||
}
|
||||
}).then(_ => _client);
|
||||
})
|
||||
.then((_) => _client);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,19 @@
|
|||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main" href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
data-name="vs/editor/editor.main"
|
||||
href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Monaco Editor TypeScript test page</h2>
|
||||
<button id="resetBtn">Reset Sample</button>
|
||||
<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>
|
||||
<div
|
||||
id="container"
|
||||
style="width: 800px; height: 600px; border: 1px solid grey"
|
||||
></div>
|
||||
<h3>Custom webworker</h3>
|
||||
<button id="logDTS">Log DTS</button>
|
||||
<button id="getAST">Print AST to console</button>
|
||||
|
|
@ -26,7 +32,7 @@
|
|||
var paths = {
|
||||
'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
|
||||
'vs/language/typescript': '../release/dev',
|
||||
'vs': '../node_modules/monaco-editor-core/dev/vs'
|
||||
vs: '../node_modules/monaco-editor-core/dev/vs'
|
||||
};
|
||||
if (document.location.protocol === 'http:') {
|
||||
// Add support for running local http server
|
||||
|
|
@ -82,9 +88,9 @@
|
|||
' constructor() {',
|
||||
' this.gridSize = 50;',
|
||||
' this.canvasSize = 600;',
|
||||
' this.lineColor = \'#cdcdcd\';',
|
||||
' this.liveColor = \'#666\';',
|
||||
' this.deadColor = \'#eee\';',
|
||||
" this.lineColor = '#cdcdcd';",
|
||||
" this.liveColor = '#666';",
|
||||
" this.deadColor = '#eee';",
|
||||
' this.initialLifeProbability = 0.5;',
|
||||
' this.animationRate = 60;',
|
||||
' this.cellSize = 0;',
|
||||
|
|
@ -157,43 +163,53 @@
|
|||
' }',
|
||||
'',
|
||||
' public createDrawingContext() {',
|
||||
' var canvas = <HTMLCanvasElement> document.getElementById(\'conway-canvas\');',
|
||||
" var canvas = <HTMLCanvasElement> document.getElementById('conway-canvas');",
|
||||
' if(canvas == null) {',
|
||||
' canvas = document.createElement(\'canvas\');',
|
||||
' canvas.id = \'conway-canvas\';',
|
||||
" canvas = document.createElement('canvas');",
|
||||
" canvas.id = 'conway-canvas';",
|
||||
' canvas.width = this.canvasSize;',
|
||||
' canvas.height = this.canvasSize;',
|
||||
' document.body.appendChild(canvas);',
|
||||
' }',
|
||||
' return canvas.getContext(\'2d\');',
|
||||
" return canvas.getContext('2d');",
|
||||
' }',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var game = new Conway.GameOfLife();',
|
||||
'var game = new Conway.GameOfLife();'
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
function getDefaultComplierOpts() {
|
||||
return { target: 99, jsx: 1, allowNonTsExtensions: true }
|
||||
return { target: 99, jsx: 1, allowNonTsExtensions: true };
|
||||
}
|
||||
require([
|
||||
'vs/basic-languages/monaco.contribution',
|
||||
'vs/language/typescript/monaco.contribution'
|
||||
], () => {
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setWorkerOptions({ customWorkerPath: "http://localhost:5000/test/custom-worker.js" })
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ target: 99, jsx: 1, allowNonTsExtensions: true, declaration: true, noLibCheck: true })
|
||||
|
||||
var editor = monaco.editor.create(document.getElementById('container'), {
|
||||
value: localStorage.getItem("code") || getDefaultCode(),
|
||||
language: 'typescript',
|
||||
lightbulb: { enabled: true }
|
||||
monaco.languages.typescript.typescriptDefaults.setWorkerOptions({
|
||||
customWorkerPath: 'http://localhost:5000/test/custom-worker.js'
|
||||
});
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
||||
target: 99,
|
||||
jsx: 1,
|
||||
allowNonTsExtensions: true,
|
||||
declaration: true,
|
||||
noLibCheck: true
|
||||
});
|
||||
|
||||
var editor = monaco.editor.create(
|
||||
document.getElementById('container'),
|
||||
{
|
||||
value: localStorage.getItem('code') || getDefaultCode(),
|
||||
language: 'typescript',
|
||||
lightbulb: { enabled: true }
|
||||
}
|
||||
);
|
||||
|
||||
editor.onDidChangeModelContent(() => {
|
||||
const code = editor.getModel().getValue()
|
||||
localStorage.setItem("code", code)
|
||||
const code = editor.getModel().getValue();
|
||||
localStorage.setItem('code', code);
|
||||
});
|
||||
|
||||
document.getElementById('resetBtn').onclick = () => {
|
||||
|
|
@ -201,21 +217,20 @@
|
|||
};
|
||||
|
||||
document.getElementById('logDTS').onclick = async () => {
|
||||
const model = editor.getModel()
|
||||
const worker = await monaco.languages.typescript.getTypeScriptWorker()
|
||||
const thisWorker = await worker(model.uri)
|
||||
const dts = await thisWorker.getDTSEmitForFile(model.uri.toString())
|
||||
console.log(dts)
|
||||
const model = editor.getModel();
|
||||
const worker = await monaco.languages.typescript.getTypeScriptWorker();
|
||||
const thisWorker = await worker(model.uri);
|
||||
const dts = await thisWorker.getDTSEmitForFile(model.uri.toString());
|
||||
console.log(dts);
|
||||
};
|
||||
|
||||
document.getElementById('getAST').onclick = async () => {
|
||||
const model = editor.getModel()
|
||||
const worker = await monaco.languages.typescript.getTypeScriptWorker()
|
||||
const thisWorker = await worker(model.uri)
|
||||
const ast = await thisWorker.printAST(model.uri.toString())
|
||||
console.log(ast)
|
||||
const model = editor.getModel();
|
||||
const worker = await monaco.languages.typescript.getTypeScriptWorker();
|
||||
const thisWorker = await worker(model.uri);
|
||||
const ast = await thisWorker.printAST(model.uri.toString());
|
||||
console.log(ast);
|
||||
};
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -2,59 +2,58 @@
|
|||
// which can do work on a bg thread.
|
||||
|
||||
// This version of the vfs edits the global scope (in the case of a webworker, this is 'self')
|
||||
importScripts("https://unpkg.com/@typescript/vfs@1.3.0/dist/vfs.globals.js")
|
||||
importScripts('https://unpkg.com/@typescript/vfs@1.3.0/dist/vfs.globals.js');
|
||||
|
||||
/** @type { import("@typescript/vfs") } */
|
||||
const tsvfs = globalThis.tsvfs
|
||||
const tsvfs = globalThis.tsvfs;
|
||||
|
||||
/** @type {import("../src/tsWorker").CustomTSWebWorkerFactory }*/
|
||||
const worker = (TypeScriptWorker, ts, libFileMap) => {
|
||||
return class MonacoTSWorker extends TypeScriptWorker {
|
||||
|
||||
// Adds a custom function to the webworker
|
||||
async getDTSEmitForFile(fileName) {
|
||||
const result = await this.getEmitOutput(fileName)
|
||||
const firstDTS = result.outputFiles.find(o => o.name.endsWith(".d.ts"))
|
||||
return (firstDTS && firstDTS.text) || ""
|
||||
const result = await this.getEmitOutput(fileName);
|
||||
const firstDTS = result.outputFiles.find((o) => o.name.endsWith('.d.ts'));
|
||||
return (firstDTS && firstDTS.text) || '';
|
||||
}
|
||||
|
||||
async printAST(fileName) {
|
||||
console.log("Creating virtual TS project")
|
||||
const compilerOptions = this.getCompilationSettings()
|
||||
const fsMap = new Map()
|
||||
console.log('Creating virtual TS project');
|
||||
const compilerOptions = this.getCompilationSettings();
|
||||
const fsMap = new Map();
|
||||
for (const key of Object.keys(libFileMap)) {
|
||||
fsMap.set(key, "/" + libFileMap[key])
|
||||
fsMap.set(key, '/' + libFileMap[key]);
|
||||
}
|
||||
|
||||
const thisCode = await this.getScriptText(fileName)
|
||||
fsMap.set("index.ts", thisCode)
|
||||
const thisCode = await this.getScriptText(fileName);
|
||||
fsMap.set('index.ts', thisCode);
|
||||
|
||||
console.log("Starting up TS program")
|
||||
const system = tsvfs.createSystem(fsMap)
|
||||
const host = tsvfs.createVirtualCompilerHost(system, compilerOptions, ts)
|
||||
console.log('Starting up TS program');
|
||||
const system = tsvfs.createSystem(fsMap);
|
||||
const host = tsvfs.createVirtualCompilerHost(system, compilerOptions, ts);
|
||||
|
||||
const program = ts.createProgram({
|
||||
rootNames: [...fsMap.keys()],
|
||||
options: compilerOptions,
|
||||
host: host.compilerHost,
|
||||
})
|
||||
host: host.compilerHost
|
||||
});
|
||||
|
||||
// Now I can look at the AST for the .ts file too
|
||||
const mainSrcFile = program.getSourceFile("index.ts")
|
||||
let miniAST = "SourceFile"
|
||||
const mainSrcFile = program.getSourceFile('index.ts');
|
||||
let miniAST = 'SourceFile';
|
||||
|
||||
const recurse = (parent, depth) => {
|
||||
if (depth > 5) return
|
||||
ts.forEachChild(parent, node => {
|
||||
const spaces = " ".repeat(depth + 1)
|
||||
miniAST += `\n${spaces}${ts.SyntaxKind[node.kind]}`
|
||||
recurse(node, depth + 1)
|
||||
})
|
||||
}
|
||||
recurse(mainSrcFile, 0)
|
||||
return miniAST
|
||||
}
|
||||
}
|
||||
if (depth > 5) return;
|
||||
ts.forEachChild(parent, (node) => {
|
||||
const spaces = ' '.repeat(depth + 1);
|
||||
miniAST += `\n${spaces}${ts.SyntaxKind[node.kind]}`;
|
||||
recurse(node, depth + 1);
|
||||
});
|
||||
};
|
||||
recurse(mainSrcFile, 0);
|
||||
return miniAST;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
self.customTSWorkerFactory = worker
|
||||
self.customTSWorkerFactory = worker;
|
||||
|
|
|
|||
|
|
@ -3,22 +3,34 @@
|
|||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main" href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
data-name="vs/editor/editor.main"
|
||||
href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Monaco Editor TypeScript test page</h2>
|
||||
<button id="resetBtn">Reset Sample</button>
|
||||
<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>
|
||||
<div
|
||||
id="container"
|
||||
style="width: 800px; height: 600px; border: 1px solid grey"
|
||||
></div>
|
||||
<h3>Compiler settings</h3>
|
||||
<textarea style="font-family: monospace;" id="compilerOpts" cols="60" rows="30"></textarea><br/>
|
||||
<textarea
|
||||
style="font-family: monospace"
|
||||
id="compilerOpts"
|
||||
cols="60"
|
||||
rows="30"
|
||||
></textarea
|
||||
><br />
|
||||
<button id="updateCompilerSettingsBtn">Update compiler settings</button>
|
||||
|
||||
<script>
|
||||
var paths = {
|
||||
'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
|
||||
'vs/language/typescript': '../release/dev',
|
||||
'vs': '../node_modules/monaco-editor-core/dev/vs'
|
||||
vs: '../node_modules/monaco-editor-core/dev/vs'
|
||||
};
|
||||
if (document.location.protocol === 'http:') {
|
||||
// Add support for running local http server
|
||||
|
|
@ -74,9 +86,9 @@
|
|||
' constructor() {',
|
||||
' this.gridSize = 50;',
|
||||
' this.canvasSize = 600;',
|
||||
' this.lineColor = \'#cdcdcd\';',
|
||||
' this.liveColor = \'#666\';',
|
||||
' this.deadColor = \'#eee\';',
|
||||
" this.lineColor = '#cdcdcd';",
|
||||
" this.liveColor = '#666';",
|
||||
" this.deadColor = '#eee';",
|
||||
' this.initialLifeProbability = 0.5;',
|
||||
' this.animationRate = 60;',
|
||||
' this.cellSize = 0;',
|
||||
|
|
@ -149,56 +161,63 @@
|
|||
' }',
|
||||
'',
|
||||
' public createDrawingContext() {',
|
||||
' var canvas = <HTMLCanvasElement> document.getElementById(\'conway-canvas\');',
|
||||
" var canvas = <HTMLCanvasElement> document.getElementById('conway-canvas');",
|
||||
' if(canvas == null) {',
|
||||
' canvas = document.createElement(\'canvas\');',
|
||||
' canvas.id = \'conway-canvas\';',
|
||||
" canvas = document.createElement('canvas');",
|
||||
" canvas.id = 'conway-canvas';",
|
||||
' canvas.width = this.canvasSize;',
|
||||
' canvas.height = this.canvasSize;',
|
||||
' document.body.appendChild(canvas);',
|
||||
' }',
|
||||
' return canvas.getContext(\'2d\');',
|
||||
" return canvas.getContext('2d');",
|
||||
' }',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'var game = new Conway.GameOfLife();',
|
||||
'var game = new Conway.GameOfLife();'
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
function getDefaultComplierOpts() {
|
||||
return { target: 99, jsx: 1, allowNonTsExtensions: true }
|
||||
return { target: 99, jsx: 1, allowNonTsExtensions: true };
|
||||
}
|
||||
require([
|
||||
'vs/basic-languages/monaco.contribution',
|
||||
'vs/language/typescript/monaco.contribution'
|
||||
], () => {
|
||||
|
||||
var editor = monaco.editor.create(document.getElementById('container'), {
|
||||
value: localStorage.getItem("code") || getDefaultCode(),
|
||||
var editor = monaco.editor.create(
|
||||
document.getElementById('container'),
|
||||
{
|
||||
value: localStorage.getItem('code') || getDefaultCode(),
|
||||
language: 'typescript',
|
||||
lightbulb: { enabled: true }
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
editor.onDidChangeModelContent(() => {
|
||||
const code = editor.getModel().getValue()
|
||||
localStorage.setItem("code", code)
|
||||
const code = editor.getModel().getValue();
|
||||
localStorage.setItem('code', code);
|
||||
});
|
||||
|
||||
document.getElementById('resetBtn').onclick = () => {
|
||||
editor.setValue(getDefaultCode());
|
||||
};
|
||||
|
||||
const optsString = localStorage.getItem("compiler-opts") || JSON.stringify(getDefaultComplierOpts(), null, 4)
|
||||
document.getElementById("compilerOpts").textContent = optsString
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(JSON.parse(optsString))
|
||||
const optsString =
|
||||
localStorage.getItem('compiler-opts') ||
|
||||
JSON.stringify(getDefaultComplierOpts(), null, 4);
|
||||
document.getElementById('compilerOpts').textContent = optsString;
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(
|
||||
JSON.parse(optsString)
|
||||
);
|
||||
|
||||
document.getElementById('updateCompilerSettingsBtn').onclick = () => {
|
||||
const newOpts = document.getElementById('compilerOpts').value
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(JSON.parse(newOpts))
|
||||
localStorage.setItem("compiler-opts", newOpts)
|
||||
const newOpts = document.getElementById('compilerOpts').value;
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions(
|
||||
JSON.parse(newOpts)
|
||||
);
|
||||
localStorage.setItem('compiler-opts', newOpts);
|
||||
};
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue