mirror of
https://github.com/microsoft/monaco-editor.git
synced 2025-12-22 17:25:39 +01:00
Merge remote-tracking branch 'origin/master' into pr/DenysVuika/24
This commit is contained in:
commit
1f15497486
20 changed files with 92863 additions and 53555 deletions
14
.github/workflows/ci.yml
vendored
Normal file
14
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
name: "CI"
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
build:
|
||||
name: "Builds and Compiles"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '10.x'
|
||||
- run: npm install
|
||||
- run: npm run compile
|
||||
|
|
@ -8,7 +8,7 @@ Simple TypeScript and JavaScript language support for the Monaco Editor.
|
|||
|
||||
## Issues
|
||||
|
||||
Please file issues concering `monaco-typescript` in the [`monaco-editor` repository](https://github.com/Microsoft/monaco-editor/issues).
|
||||
Please file issues concerning `monaco-typescript` in the [`monaco-editor` repository](https://github.com/Microsoft/monaco-editor/issues).
|
||||
|
||||
## Installing
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ This npm module is bundled and distributed in the [monaco-editor](https://www.np
|
|||
* `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.
|
||||
|
||||
|
|
|
|||
75
package-lock.json
generated
75
package-lock.json
generated
|
|
@ -1,25 +1,25 @@
|
|||
{
|
||||
"name": "monaco-typescript",
|
||||
"version": "3.2.0",
|
||||
"version": "3.5.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.16.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz",
|
||||
"integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==",
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||
"dev": true
|
||||
},
|
||||
"monaco-editor-core": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.14.1.tgz",
|
||||
"integrity": "sha512-bWJuPbDEftxaN2bG+JZ29+aJhg0rmq+y6VmCUqPZpmw8bSevoYjuTcdLkt9BbNaGnwosAVy+vSktXgs/JW7OvQ==",
|
||||
"version": "0.18.1",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.18.1.tgz",
|
||||
"integrity": "sha512-euzXzmwjZFG0oAPGjICMwINcZBzQDyfGDYlAR5YNMBJZO9Bmkqq1xpTTze/qQ0KKbVmawFXiwgUbg7WVgebP9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"monaco-languages": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/monaco-languages/-/monaco-languages-1.4.0.tgz",
|
||||
"integrity": "sha512-39MZMAEKToktfSpOS0Soj05IvkT5vbebL9AIBGPn8fGi8WgJOcfS3YLiMu07gZKViR7CFZ4RyQJKJHglx0fPdA==",
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/monaco-languages/-/monaco-languages-1.8.0.tgz",
|
||||
"integrity": "sha512-vC/lqNgSslQT3vSlNOpyT34ELK0eoNbA/rHUvTUjQemIiR1GpRMKhuwB21BqzWk+0MjZuJydGSCQMCebBge7jg==",
|
||||
"dev": true
|
||||
},
|
||||
"monaco-plugin-helpers": {
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
"integrity": "sha512-7kUx8dtd5qVNVgUARBRhnM8oftPglYwlINfigC4yGUiuzqtIN22u1tly8umiOCIPR0eFiBLjt6aN23oZh2QJgg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"typescript": "2.9.2"
|
||||
"typescript": "^2.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": {
|
||||
|
|
@ -40,9 +40,9 @@
|
|||
}
|
||||
},
|
||||
"requirejs": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz",
|
||||
"integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==",
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
|
||||
"integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
|
|
@ -51,21 +51,40 @@
|
|||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.0.1.tgz",
|
||||
"integrity": "sha512-zQIMOmC+372pC/CCVLqnQ0zSBiY7HHodU7mpQdjiZddek4GMj31I3dUJ7gAs9o65X7mnRma6OokOkc6f9jjfBg==",
|
||||
"dev": true
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.4.7",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.7.tgz",
|
||||
"integrity": "sha512-J0M2i1mQA+ze3EdN9SBi751DNdAXmeFLfJrd/MDIkRc3G3Gbb9OPVSx7GIQvVwfWxQARcYV2DTxIkMyDAk3o9Q==",
|
||||
"source-map-support": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz",
|
||||
"integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "2.16.0",
|
||||
"source-map": "0.6.1"
|
||||
}
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.4.3.tgz",
|
||||
"integrity": "sha512-0ikKraVtRDKGzHrzkCv5rUNDzqlhmhowOBqC0XqUHFpW+vJ45+20/IFBcebwKfiS2Z9fJin6Eo+F1zLZsxi8RA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "^2.20.0",
|
||||
"source-map": "~0.6.1",
|
||||
"source-map-support": "~0.5.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.7.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz",
|
||||
"integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
package.json
14
package.json
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"name": "monaco-typescript",
|
||||
"version": "3.2.0",
|
||||
"version": "3.5.1",
|
||||
"description": "TypeScript and JavaScript language support for Monaco Editor",
|
||||
"scripts": {
|
||||
"compile-amd": "mcopy ./src/lib/typescriptServices-amd.js ./release/dev/lib/typescriptServices.js && tsc -p ./src/tsconfig.json",
|
||||
"compile-esm": "mcopy ./src/lib/typescriptServices.js ./release/esm/lib/typescriptServices.js && tsc -p ./src/tsconfig.esm.json",
|
||||
"compile": "mrmdir ./release && npm run compile-amd && npm run compile-esm",
|
||||
"watch": "tsc -p ./src --watch",
|
||||
"prepublish": "npm run compile && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts",
|
||||
"prepublishOnly": "npm run compile && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts",
|
||||
"import-typescript": "node ./scripts/importTypescript"
|
||||
},
|
||||
"author": "Microsoft Corporation",
|
||||
|
|
@ -20,11 +20,11 @@
|
|||
"url": "https://github.com/Microsoft/monaco-typescript/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"monaco-editor-core": "0.14.1",
|
||||
"monaco-languages": "^1.4.0",
|
||||
"monaco-editor-core": "^0.18.1",
|
||||
"monaco-languages": "^1.8.0",
|
||||
"monaco-plugin-helpers": "^1.0.2",
|
||||
"requirejs": "^2.3.5",
|
||||
"typescript": "3.0.1",
|
||||
"uglify-js": "^3.4.7"
|
||||
"requirejs": "^2.3.6",
|
||||
"terser": "^4.4.3",
|
||||
"typescript": "^3.7.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
const requirejs = require('requirejs');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const UglifyJS = require('uglify-js');
|
||||
const terser = require('terser');
|
||||
const helpers = require('monaco-plugin-helpers');
|
||||
|
||||
const REPO_ROOT = path.resolve(__dirname, '..');
|
||||
|
|
@ -44,11 +44,7 @@ function bundleOne(moduleId, exclude) {
|
|||
const fileContents = fs.readFileSync(filePath).toString();
|
||||
console.log();
|
||||
console.log(`Minifying ${filePath}...`);
|
||||
const result = UglifyJS.minify(fileContents, {
|
||||
output: {
|
||||
comments: 'some'
|
||||
}
|
||||
});
|
||||
const result = terser.minify(fileContents);
|
||||
console.log(`Done.`);
|
||||
fs.writeFileSync(filePath, BUNDLED_FILE_HEADER + result.code);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const child_process = require('child_process');
|
||||
|
||||
const TYPESCRIPT_LIB_SOURCE = path.join(__dirname, '../node_modules/typescript/lib');
|
||||
const TYPESCRIPT_LIB_DESTINATION = path.join(__dirname, '../src/lib');
|
||||
|
|
@ -17,6 +18,14 @@ 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;
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServicesMetadata.ts'),
|
||||
`export const typescriptVersion = "${typeScriptDependencyVersion}";\n`
|
||||
);
|
||||
|
||||
var tsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescriptServices.js')).toString();
|
||||
|
||||
// Ensure we never run into the node system...
|
||||
|
|
@ -25,6 +34,29 @@ const TYPESCRIPT_LIB_DESTINATION = path.join(__dirname, '../src/lib');
|
|||
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');
|
||||
|
||||
// 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);
|
||||
if (linesWithRequire && linesWithRequire.length) {
|
||||
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);
|
||||
}
|
||||
|
||||
// Make sure process.args don't get called in the browser, this
|
||||
// should only happen in TS 2.6.2
|
||||
const beforeProcess = `ts.perfLogger.logInfoEvent("Starting TypeScript v" + ts.versionMajorMinor + " with command line: " + JSON.stringify(process.argv));`
|
||||
const afterProcess = `// MONACOCHANGE\n ts.perfLogger.logInfoEvent("Starting TypeScript v" + ts.versionMajorMinor + " with command line: " + JSON.stringify([]));\n// END MONACOCHANGE`
|
||||
tsServices = tsServices.replace(beforeProcess, afterProcess);
|
||||
|
||||
var tsServices_amd = tsServices +
|
||||
`
|
||||
// MONACOCHANGE
|
||||
|
|
@ -38,15 +70,15 @@ define("vs/language/typescript/lib/typescriptServices", [], function() { return
|
|||
var tsServices_esm = tsServices +
|
||||
`
|
||||
// MONACOCHANGE
|
||||
export const createClassifier = ts.createClassifier;
|
||||
export const createLanguageService = ts.createLanguageService;
|
||||
export const displayPartsToString = ts.displayPartsToString;
|
||||
export const EndOfLineState = ts.EndOfLineState;
|
||||
export const flattenDiagnosticMessageText = ts.flattenDiagnosticMessageText;
|
||||
export const IndentStyle = ts.IndentStyle;
|
||||
export const ScriptKind = ts.ScriptKind;
|
||||
export const ScriptTarget = ts.ScriptTarget;
|
||||
export const TokenClass = ts.TokenClass;
|
||||
export var createClassifier = ts.createClassifier;
|
||||
export var createLanguageService = ts.createLanguageService;
|
||||
export var displayPartsToString = ts.displayPartsToString;
|
||||
export var EndOfLineState = ts.EndOfLineState;
|
||||
export var flattenDiagnosticMessageText = ts.flattenDiagnosticMessageText;
|
||||
export var IndentStyle = ts.IndentStyle;
|
||||
export var ScriptKind = ts.ScriptKind;
|
||||
export var ScriptTarget = ts.ScriptTarget;
|
||||
export var TokenClass = ts.TokenClass;
|
||||
// END MONACOCHANGE
|
||||
`;
|
||||
fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.js'), tsServices_esm);
|
||||
|
|
@ -59,6 +91,7 @@ export = ts;
|
|||
// END MONACOCHANGE
|
||||
`;
|
||||
fs.writeFileSync(path.join(TYPESCRIPT_LIB_DESTINATION, 'typescriptServices.d.ts'), dtsServices);
|
||||
|
||||
})();
|
||||
|
||||
function importLibs() {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import Uri = monaco.Uri;
|
|||
import Position = monaco.Position;
|
||||
import Range = monaco.Range;
|
||||
import Thenable = monaco.Thenable;
|
||||
import Promise = monaco.Promise;
|
||||
import CancellationToken = monaco.CancellationToken;
|
||||
import IDisposable = monaco.IDisposable;
|
||||
|
||||
|
|
@ -24,27 +23,30 @@ enum IndentStyle {
|
|||
Smart = 2
|
||||
}
|
||||
|
||||
function flattenDiagnosticMessageText(messageText: string | ts.DiagnosticMessageChain, newLine: '\n'): string {
|
||||
if (typeof messageText === "string") {
|
||||
return messageText;
|
||||
} else {
|
||||
let diagnosticChain = messageText;
|
||||
export function flattenDiagnosticMessageText(diag: string | ts.DiagnosticMessageChain | undefined, newLine: string, indent = 0): string {
|
||||
if (typeof diag === "string") {
|
||||
return diag;
|
||||
}
|
||||
else if (diag === undefined) {
|
||||
return "";
|
||||
}
|
||||
let result = "";
|
||||
let indent = 0;
|
||||
while (diagnosticChain) {
|
||||
if (indent) {
|
||||
result += newLine;
|
||||
|
||||
for (let i = 0; i < indent; i++) {
|
||||
result += " ";
|
||||
}
|
||||
}
|
||||
result += diagnosticChain.messageText;
|
||||
result += diag.messageText;
|
||||
indent++;
|
||||
diagnosticChain = diagnosticChain.next;
|
||||
if (diag.next) {
|
||||
for (const kid of diag.next) {
|
||||
result += flattenDiagnosticMessageText(kid, newLine, indent);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function displayPartsToString(displayParts: ts.SymbolDisplayPart[]): string {
|
||||
if (displayParts) {
|
||||
|
|
@ -81,7 +83,14 @@ export abstract class Adapter {
|
|||
|
||||
// --- diagnostics --- ---
|
||||
|
||||
export class DiagnostcsAdapter extends Adapter {
|
||||
enum DiagnosticCategory {
|
||||
Warning = 0,
|
||||
Error = 1,
|
||||
Suggestion = 2,
|
||||
Message = 3
|
||||
}
|
||||
|
||||
export class DiagnosticsAdapter extends Adapter {
|
||||
|
||||
private _disposables: IDisposable[] = [];
|
||||
private _listener: { [uri: string]: IDisposable } = Object.create(null);
|
||||
|
|
@ -136,13 +145,15 @@ export class DiagnostcsAdapter extends Adapter {
|
|||
}
|
||||
});
|
||||
|
||||
this._disposables.push(this._defaults.onDidChange(() => {
|
||||
const recomputeDiagostics = () => {
|
||||
// redo diagnostics when options change
|
||||
for (const model of monaco.editor.getModels()) {
|
||||
onModelRemoved(model);
|
||||
onModelAdd(model);
|
||||
}
|
||||
}));
|
||||
};
|
||||
this._disposables.push(this._defaults.onDidChange(recomputeDiagostics));
|
||||
this._disposables.push(this._defaults.onDidExtraLibsChange(recomputeDiagostics));
|
||||
|
||||
monaco.editor.getModels().forEach(onModelAdd);
|
||||
}
|
||||
|
|
@ -159,14 +170,17 @@ export class DiagnostcsAdapter extends Adapter {
|
|||
return null;
|
||||
}
|
||||
const promises: Promise<ts.Diagnostic[]>[] = [];
|
||||
const { noSyntaxValidation, noSemanticValidation } = this._defaults.getDiagnosticsOptions();
|
||||
const { noSyntaxValidation, noSemanticValidation, noSuggestionDiagnostics } = this._defaults.getDiagnosticsOptions();
|
||||
if (!noSyntaxValidation) {
|
||||
promises.push(worker.getSyntacticDiagnostics(resource.toString()));
|
||||
}
|
||||
if (!noSemanticValidation) {
|
||||
promises.push(worker.getSemanticDiagnostics(resource.toString()));
|
||||
}
|
||||
return Promise.join(promises);
|
||||
if (!noSuggestionDiagnostics) {
|
||||
promises.push(worker.getSuggestionDiagnostics(resource.toString()));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}).then(diagnostics => {
|
||||
if (!diagnostics || !monaco.editor.getModel(resource)) {
|
||||
// model was disposed in the meantime
|
||||
|
|
@ -174,10 +188,11 @@ export class DiagnostcsAdapter extends Adapter {
|
|||
}
|
||||
const markers = diagnostics
|
||||
.reduce((p, c) => c.concat(p), [])
|
||||
.filter(d => (this._defaults.getDiagnosticsOptions().diagnosticCodesToIgnore || []).indexOf(d.code) === -1)
|
||||
.map(d => this._convertDiagnostics(resource, d));
|
||||
|
||||
monaco.editor.setModelMarkers(monaco.editor.getModel(resource), this._selector, markers);
|
||||
}).done(undefined, err => {
|
||||
}).then(undefined, err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
|
@ -187,14 +202,46 @@ export class DiagnostcsAdapter extends Adapter {
|
|||
const { lineNumber: endLineNumber, column: endColumn } = this._offsetToPosition(resource, diag.start + diag.length);
|
||||
|
||||
return {
|
||||
severity: monaco.MarkerSeverity.Error,
|
||||
severity: this._tsDiagnosticCategoryToMarkerSeverity(diag.category),
|
||||
startLineNumber,
|
||||
startColumn,
|
||||
endLineNumber,
|
||||
endColumn,
|
||||
message: flattenDiagnosticMessageText(diag.messageText, '\n')
|
||||
message: flattenDiagnosticMessageText(diag.messageText, '\n'),
|
||||
code: diag.code.toString(),
|
||||
tags: diag.reportsUnnecessary ? [monaco.MarkerTag.Unnecessary] : [],
|
||||
relatedInformation: this._convertRelatedInformation(resource, diag.relatedInformation),
|
||||
};
|
||||
}
|
||||
|
||||
private _convertRelatedInformation(resource: Uri, relatedInformation?: ts.DiagnosticRelatedInformation[]): monaco.editor.IRelatedInformation[] {
|
||||
if (relatedInformation === undefined)
|
||||
return undefined;
|
||||
|
||||
return relatedInformation.map(info => {
|
||||
const relatedResource = info.file === undefined ? resource : monaco.Uri.parse(info.file.fileName);
|
||||
const { lineNumber: startLineNumber, column: startColumn } = this._offsetToPosition(relatedResource, info.start);
|
||||
const { lineNumber: endLineNumber, column: endColumn } = this._offsetToPosition(relatedResource, info.start + info.length);
|
||||
|
||||
return {
|
||||
resource: relatedResource,
|
||||
startLineNumber,
|
||||
startColumn,
|
||||
endLineNumber,
|
||||
endColumn,
|
||||
message: flattenDiagnosticMessageText(info.messageText, '\n')
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- suggest ------
|
||||
|
|
@ -210,37 +257,49 @@ export class SuggestAdapter extends Adapter implements monaco.languages.Completi
|
|||
return ['.'];
|
||||
}
|
||||
|
||||
provideCompletionItems(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.CompletionItem[]> {
|
||||
provideCompletionItems(model: monaco.editor.IReadOnlyModel, position: Position, _context: monaco.languages.CompletionContext, token: CancellationToken): Thenable<monaco.languages.CompletionList> {
|
||||
const wordInfo = model.getWordUntilPosition(position);
|
||||
const wordRange = new Range(position.lineNumber, wordInfo.startColumn, position.lineNumber, wordInfo.endColumn);
|
||||
const resource = model.uri;
|
||||
const offset = this._positionToOffset(resource, position);
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getCompletionsAtPosition(resource.toString(), offset);
|
||||
}).then(info => {
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
let 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);
|
||||
range = new Range(p1.lineNumber, p1.column, p2.lineNumber, p2.column);
|
||||
}
|
||||
|
||||
return {
|
||||
uri: resource,
|
||||
position: position,
|
||||
range: range,
|
||||
label: entry.name,
|
||||
insertText: entry.name,
|
||||
sortText: entry.sortText,
|
||||
kind: SuggestAdapter.convertKind(entry.kind)
|
||||
};
|
||||
});
|
||||
|
||||
return suggestions;
|
||||
}));
|
||||
return {
|
||||
suggestions
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
resolveCompletionItem(item: monaco.languages.CompletionItem, token: CancellationToken): Thenable<monaco.languages.CompletionItem> {
|
||||
resolveCompletionItem(_model: monaco.editor.IReadOnlyModel, _position: Position, item: monaco.languages.CompletionItem, token: CancellationToken): Thenable<monaco.languages.CompletionItem> {
|
||||
let myItem = <MyCompletionItem>item;
|
||||
const resource = myItem.uri;
|
||||
const position = myItem.position;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getCompletionEntryDetails(resource.toString(),
|
||||
this._positionToOffset(resource, position),
|
||||
myItem.label);
|
||||
|
|
@ -255,9 +314,11 @@ export class SuggestAdapter extends Adapter implements monaco.languages.Completi
|
|||
label: details.name,
|
||||
kind: SuggestAdapter.convertKind(details.kind),
|
||||
detail: displayPartsToString(details.displayParts),
|
||||
documentation: displayPartsToString(details.documentation)
|
||||
documentation: {
|
||||
value: displayPartsToString(details.documentation)
|
||||
}
|
||||
};
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
private static convertKind(kind: string): monaco.languages.CompletionItemKind {
|
||||
|
|
@ -298,9 +359,9 @@ export class SignatureHelpAdapter extends Adapter implements monaco.languages.Si
|
|||
|
||||
public signatureHelpTriggerCharacters = ['(', ','];
|
||||
|
||||
provideSignatureHelp(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.SignatureHelp> {
|
||||
provideSignatureHelp(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.SignatureHelpResult> {
|
||||
let resource = model.uri;
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => worker.getSignatureHelpItems(resource.toString(), this._positionToOffset(resource, position))).then(info => {
|
||||
return this._worker(resource).then(worker => worker.getSignatureHelpItems(resource.toString(), this._positionToOffset(resource, position))).then(info => {
|
||||
|
||||
if (!info) {
|
||||
return;
|
||||
|
|
@ -316,10 +377,10 @@ export class SignatureHelpAdapter extends Adapter implements monaco.languages.Si
|
|||
|
||||
let signature: monaco.languages.SignatureInformation = {
|
||||
label: '',
|
||||
documentation: null,
|
||||
parameters: []
|
||||
};
|
||||
|
||||
signature.documentation = displayPartsToString(item.documentation);
|
||||
signature.label += displayPartsToString(item.prefixDisplayParts);
|
||||
item.parameters.forEach((p, i, a) => {
|
||||
let label = displayPartsToString(p.displayParts);
|
||||
|
|
@ -337,9 +398,11 @@ export class SignatureHelpAdapter extends Adapter implements monaco.languages.Si
|
|||
ret.signatures.push(signature);
|
||||
});
|
||||
|
||||
return ret;
|
||||
|
||||
}));
|
||||
return {
|
||||
value: ret,
|
||||
dispose() { }
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -350,7 +413,7 @@ export class QuickInfoAdapter extends Adapter implements monaco.languages.HoverP
|
|||
provideHover(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.Hover> {
|
||||
let resource = model.uri;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getQuickInfoAtPosition(resource.toString(), this._positionToOffset(resource, position));
|
||||
}).then(info => {
|
||||
if (!info) {
|
||||
|
|
@ -374,7 +437,7 @@ export class QuickInfoAdapter extends Adapter implements monaco.languages.HoverP
|
|||
value: documentation + (tags ? '\n\n' + tags : '')
|
||||
}]
|
||||
};
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -385,7 +448,7 @@ export class OccurrencesAdapter extends Adapter implements monaco.languages.Docu
|
|||
public provideDocumentHighlights(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.DocumentHighlight[]> {
|
||||
const resource = model.uri;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getOccurrencesAtPosition(resource.toString(), this._positionToOffset(resource, position));
|
||||
}).then(entries => {
|
||||
if (!entries) {
|
||||
|
|
@ -397,7 +460,7 @@ export class OccurrencesAdapter extends Adapter implements monaco.languages.Docu
|
|||
kind: entry.isWriteAccess ? monaco.languages.DocumentHighlightKind.Write : monaco.languages.DocumentHighlightKind.Text
|
||||
};
|
||||
});
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -408,7 +471,7 @@ export class DefinitionAdapter extends Adapter {
|
|||
public provideDefinition(model: monaco.editor.IReadOnlyModel, position: Position, token: CancellationToken): Thenable<monaco.languages.Definition> {
|
||||
const resource = model.uri;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getDefinitionAtPosition(resource.toString(), this._positionToOffset(resource, position));
|
||||
}).then(entries => {
|
||||
if (!entries) {
|
||||
|
|
@ -425,7 +488,7 @@ export class DefinitionAdapter extends Adapter {
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -436,7 +499,7 @@ export class ReferenceAdapter extends Adapter implements monaco.languages.Refere
|
|||
provideReferences(model: monaco.editor.IReadOnlyModel, position: Position, context: monaco.languages.ReferenceContext, token: CancellationToken): Thenable<monaco.languages.Location[]> {
|
||||
const resource = model.uri;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getReferencesAtPosition(resource.toString(), this._positionToOffset(resource, position));
|
||||
}).then(entries => {
|
||||
if (!entries) {
|
||||
|
|
@ -453,7 +516,7 @@ export class ReferenceAdapter extends Adapter implements monaco.languages.Refere
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -464,7 +527,7 @@ export class OutlineAdapter extends Adapter implements monaco.languages.Document
|
|||
public provideDocumentSymbols(model: monaco.editor.IReadOnlyModel, token: CancellationToken): Thenable<monaco.languages.DocumentSymbol[]> {
|
||||
const resource = model.uri;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => worker.getNavigationBarItems(resource.toString())).then(items => {
|
||||
return this._worker(resource).then(worker => worker.getNavigationBarItems(resource.toString())).then(items => {
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -476,6 +539,7 @@ export class OutlineAdapter extends Adapter implements monaco.languages.Document
|
|||
kind: <monaco.languages.SymbolKind>(outlineTypeTable[item.kind] || monaco.languages.SymbolKind.Variable),
|
||||
range: this._textSpanToRange(resource, item.spans[0]),
|
||||
selectionRange: this._textSpanToRange(resource, item.spans[0]),
|
||||
tags: [],
|
||||
containerName: containerLabel
|
||||
};
|
||||
|
||||
|
|
@ -491,7 +555,7 @@ export class OutlineAdapter extends Adapter implements monaco.languages.Document
|
|||
let result: monaco.languages.DocumentSymbol[] = [];
|
||||
items.forEach(item => convert(result, item));
|
||||
return result;
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -578,7 +642,7 @@ export class FormatAdapter extends FormatHelper implements monaco.languages.Docu
|
|||
provideDocumentRangeFormattingEdits(model: monaco.editor.IReadOnlyModel, range: Range, options: monaco.languages.FormattingOptions, token: CancellationToken): Thenable<monaco.editor.ISingleEditOperation[]> {
|
||||
const resource = model.uri;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getFormattingEditsForRange(resource.toString(),
|
||||
this._positionToOffset(resource, { lineNumber: range.startLineNumber, column: range.startColumn }),
|
||||
this._positionToOffset(resource, { lineNumber: range.endLineNumber, column: range.endColumn }),
|
||||
|
|
@ -587,7 +651,7 @@ export class FormatAdapter extends FormatHelper implements monaco.languages.Docu
|
|||
if (edits) {
|
||||
return edits.map(edit => this._convertTextChanges(resource, edit));
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -600,7 +664,7 @@ export class FormatOnTypeAdapter extends FormatHelper implements monaco.language
|
|||
provideOnTypeFormattingEdits(model: monaco.editor.IReadOnlyModel, position: Position, ch: string, options: monaco.languages.FormattingOptions, token: CancellationToken): Thenable<monaco.editor.ISingleEditOperation[]> {
|
||||
const resource = model.uri;
|
||||
|
||||
return wireCancellationToken(token, this._worker(resource).then(worker => {
|
||||
return this._worker(resource).then(worker => {
|
||||
return worker.getFormattingEditsAfterKeystroke(resource.toString(),
|
||||
this._positionToOffset(resource, position),
|
||||
ch, FormatHelper._convertOptions(options));
|
||||
|
|
@ -608,14 +672,103 @@ export class FormatOnTypeAdapter extends FormatHelper implements monaco.language
|
|||
if (edits) {
|
||||
return edits.map(edit => this._convertTextChanges(resource, edit));
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook a cancellation token to a WinJS Promise
|
||||
*/
|
||||
function wireCancellationToken<T>(token: CancellationToken, promise: Promise<T>): Thenable<T> {
|
||||
token.onCancellationRequested(() => promise.cancel());
|
||||
return promise;
|
||||
// --- code actions ------
|
||||
|
||||
export class CodeActionAdaptor extends FormatHelper implements monaco.languages.CodeActionProvider {
|
||||
|
||||
public provideCodeActions(model: monaco.editor.ITextModel, range: Range, context: monaco.languages.CodeActionContext, token: CancellationToken): Promise<monaco.languages.CodeActionList> {
|
||||
const resource = model.uri;
|
||||
|
||||
return this._worker(resource).then(worker => {
|
||||
const start = this._positionToOffset(resource, { lineNumber: range.startLineNumber, column: range.startColumn });
|
||||
const end = this._positionToOffset(resource, { 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);
|
||||
|
||||
return worker.getCodeFixesAtPosition(resource.toString(), start, end, errorCodes, formatOptions);
|
||||
|
||||
}).then(codeFixes => {
|
||||
|
||||
return codeFixes.filter(fix => {
|
||||
// Removes any 'make a new file'-type code fix
|
||||
return fix.changes.filter(change => change.isNewFile).length === 0;
|
||||
}).map(fix => {
|
||||
return this._tsCodeFixActionToMonacoCodeAction(model, context, fix);
|
||||
})
|
||||
}).then(result => {
|
||||
return {
|
||||
actions: result,
|
||||
dispose: () => { }
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private _tsCodeFixActionToMonacoCodeAction(model: monaco.editor.ITextModel, context: monaco.languages.CodeActionContext, codeFix: ts.CodeFixAction): monaco.languages.CodeAction {
|
||||
const edits: monaco.languages.ResourceTextEdit[] = codeFix.changes.map(edit => ({
|
||||
resource: model.uri,
|
||||
edits: edit.textChanges.map(tc => ({
|
||||
range: this._textSpanToRange(model.uri, tc.span),
|
||||
text: tc.newText
|
||||
}))
|
||||
}));
|
||||
|
||||
const action: monaco.languages.CodeAction = {
|
||||
title: codeFix.description,
|
||||
edit: { edits: edits },
|
||||
diagnostics: context.markers,
|
||||
kind: "quickfix"
|
||||
};
|
||||
|
||||
return action;
|
||||
}
|
||||
}
|
||||
// --- rename ----
|
||||
|
||||
export class RenameAdapter extends Adapter implements monaco.languages.RenameProvider {
|
||||
|
||||
async provideRenameEdits(model: monaco.editor.ITextModel, position: Position, newName: string, token: CancellationToken): Promise<monaco.languages.WorkspaceEdit & monaco.languages.Rejection> {
|
||||
const resource = model.uri;
|
||||
const fileName = resource.toString();
|
||||
const offset = this._positionToOffset(resource, 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
|
||||
return {
|
||||
edits: [],
|
||||
rejectReason: renameInfo.localizedErrorMessage
|
||||
};
|
||||
}
|
||||
if (renameInfo.fileToRename !== undefined) {
|
||||
throw new Error("Renaming files is not supported.");
|
||||
}
|
||||
|
||||
const renameLocations = await worker.findRenameLocations(fileName, offset, /*strings*/ false, /*comments*/ false, /*prefixAndSuffix*/ false);
|
||||
const fileNameToResourceTextEditMap: { [fileName: string]: monaco.languages.ResourceTextEdit } = {};
|
||||
|
||||
const edits: monaco.languages.ResourceTextEdit[] = [];
|
||||
for (const renameLocation of renameLocations) {
|
||||
if (!(renameLocation.fileName in fileNameToResourceTextEditMap)) {
|
||||
const resourceTextEdit = {
|
||||
edits: [],
|
||||
resource: monaco.Uri.parse(renameLocation.fileName)
|
||||
};
|
||||
fileNameToResourceTextEditMap[renameLocation.fileName] = resourceTextEdit;
|
||||
edits.push(resourceTextEdit);
|
||||
}
|
||||
|
||||
fileNameToResourceTextEditMap[renameLocation.fileName].edits.push({
|
||||
range: this._textSpanToRange(resource, renameLocation.textSpan),
|
||||
text: newName
|
||||
});
|
||||
}
|
||||
|
||||
return { edits };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3201
src/lib/typescriptServices.d.ts
vendored
3201
src/lib/typescriptServices.d.ts
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
1
src/lib/typescriptServicesMetadata.ts
Normal file
1
src/lib/typescriptServicesMetadata.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const typescriptVersion = "3.7.3";
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
'use strict';
|
||||
|
||||
import * as mode from './tsMode';
|
||||
import { typescriptVersion } from './lib/typescriptServicesMetadata'; // do not import the whole typescriptServices here
|
||||
|
||||
import Emitter = monaco.Emitter;
|
||||
import IEvent = monaco.IEvent;
|
||||
|
|
@ -12,87 +13,113 @@ import IDisposable = monaco.IDisposable;
|
|||
|
||||
// --- TypeScript configuration and defaults ---------
|
||||
|
||||
export interface IExtraLib {
|
||||
content: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface IExtraLibs {
|
||||
[path: string]: IExtraLib;
|
||||
}
|
||||
|
||||
export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.LanguageServiceDefaults {
|
||||
|
||||
private _onDidChange = new Emitter<monaco.languages.typescript.LanguageServiceDefaults>();
|
||||
private _extraLibs: { [path: string]: string };
|
||||
private _onDidChange = new Emitter<void>();
|
||||
private _onDidExtraLibsChange = new Emitter<void>();
|
||||
|
||||
private _extraLibs: IExtraLibs;
|
||||
private _workerMaxIdleTime: number;
|
||||
private _eagerModelSync: boolean;
|
||||
private _compilerOptions: monaco.languages.typescript.CompilerOptions;
|
||||
private _diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions;
|
||||
private _onDidExtraLibsChangeTimeout: number;
|
||||
|
||||
constructor(compilerOptions: monaco.languages.typescript.CompilerOptions, diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions) {
|
||||
this._extraLibs = Object.create(null);
|
||||
this._workerMaxIdleTime = 2 * 60 * 1000;
|
||||
this.setCompilerOptions(compilerOptions);
|
||||
this.setDiagnosticsOptions(diagnosticsOptions);
|
||||
this._onDidExtraLibsChangeTimeout = -1;
|
||||
}
|
||||
|
||||
get onDidChange(): IEvent<monaco.languages.typescript.LanguageServiceDefaults> {
|
||||
get onDidChange(): IEvent<void> {
|
||||
return this._onDidChange.event;
|
||||
}
|
||||
|
||||
getExtraLibs(): { [path: string]: string; } {
|
||||
const result = Object.create(null);
|
||||
for (var key in this._extraLibs) {
|
||||
result[key] = this._extraLibs[key];
|
||||
get onDidExtraLibsChange(): IEvent<void> {
|
||||
return this._onDidExtraLibsChange.event;
|
||||
}
|
||||
return Object.freeze(result);
|
||||
|
||||
getExtraLibs(): IExtraLibs {
|
||||
return this._extraLibs;
|
||||
}
|
||||
|
||||
addExtraLib(content: string, filePath?: string): IDisposable {
|
||||
if (typeof filePath === 'undefined') {
|
||||
filePath = `ts:extralib-${Date.now()}`;
|
||||
filePath = `ts:extralib-${Math.random().toString(36).substring(2, 15)}`;
|
||||
}
|
||||
|
||||
if (this._extraLibs[filePath] && this._extraLibs[filePath].content === content) {
|
||||
// no-op, there already exists an extra lib with this content
|
||||
return {
|
||||
dispose: () => { }
|
||||
};
|
||||
}
|
||||
|
||||
let myVersion = 1;
|
||||
if (this._extraLibs[filePath]) {
|
||||
throw new Error(`${filePath} already a extra lib`);
|
||||
myVersion = this._extraLibs[filePath].version + 1;
|
||||
}
|
||||
|
||||
this._extraLibs[filePath] = content;
|
||||
this._onDidChange.fire(this);
|
||||
this._extraLibs[filePath] = {
|
||||
content: content,
|
||||
version: myVersion,
|
||||
};
|
||||
this._fireOnDidExtraLibsChangeSoon();
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
if (delete this._extraLibs[filePath]) {
|
||||
this._onDidChange.fire(this);
|
||||
let extraLib = this._extraLibs[filePath];
|
||||
if (!extraLib) {
|
||||
return;
|
||||
}
|
||||
if (extraLib.version !== myVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete this._extraLibs[filePath];
|
||||
this._fireOnDidExtraLibsChangeSoon();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
setExtraLibs(libs: Array<{ content: string; filePath?: string }>): IDisposable {
|
||||
const paths = [];
|
||||
setExtraLibs(libs: { content: string; filePath?: string }[]): void {
|
||||
// clear out everything
|
||||
this._extraLibs = Object.create(null);
|
||||
|
||||
if (libs && libs.length > 0) {
|
||||
libs.forEach(lib => {
|
||||
const filePath = lib.filePath || `ts:extralib-${Date.now()}`;
|
||||
for (const lib of libs) {
|
||||
const filePath = lib.filePath || `ts:extralib-${Math.random().toString(36).substring(2, 15)}`;
|
||||
const content = lib.content;
|
||||
|
||||
this._extraLibs[filePath] = content;
|
||||
paths.push(filePath);
|
||||
});
|
||||
|
||||
this._onDidChange.fire(this);
|
||||
this._extraLibs[filePath] = {
|
||||
content: content,
|
||||
version: 1
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
dispose: () => {
|
||||
if (paths.length > 0) {
|
||||
let changed = false;
|
||||
this._fireOnDidExtraLibsChangeSoon();
|
||||
}
|
||||
|
||||
paths.forEach(filePath => {
|
||||
if (delete this._extraLibs[filePath]) {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
this._onDidChange.fire(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
private _fireOnDidExtraLibsChangeSoon(): void {
|
||||
if (this._onDidExtraLibsChangeTimeout !== -1) {
|
||||
// already scheduled
|
||||
return;
|
||||
}
|
||||
this._onDidExtraLibsChangeTimeout = setTimeout(() => {
|
||||
this._onDidExtraLibsChangeTimeout = -1;
|
||||
this._onDidExtraLibsChange.fire(undefined);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
getCompilerOptions(): monaco.languages.typescript.CompilerOptions {
|
||||
|
|
@ -101,7 +128,7 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
|
||||
setCompilerOptions(options: monaco.languages.typescript.CompilerOptions): void {
|
||||
this._compilerOptions = options || Object.create(null);
|
||||
this._onDidChange.fire(this);
|
||||
this._onDidChange.fire(undefined);
|
||||
}
|
||||
|
||||
getDiagnosticsOptions(): monaco.languages.typescript.DiagnosticsOptions {
|
||||
|
|
@ -110,7 +137,7 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript.
|
|||
|
||||
setDiagnosticsOptions(options: monaco.languages.typescript.DiagnosticsOptions): void {
|
||||
this._diagnosticsOptions = options || Object.create(null);
|
||||
this._onDidChange.fire(this);
|
||||
this._onDidChange.fire(undefined);
|
||||
}
|
||||
|
||||
setMaximumWorkerIdleTime(value: number): void {
|
||||
|
|
@ -143,18 +170,21 @@ enum ModuleKind {
|
|||
UMD = 3,
|
||||
System = 4,
|
||||
ES2015 = 5,
|
||||
ESNext = 6
|
||||
ESNext = 99
|
||||
}
|
||||
|
||||
enum JsxEmit {
|
||||
None = 0,
|
||||
Preserve = 1,
|
||||
React = 2,
|
||||
ReactNative = 3
|
||||
}
|
||||
|
||||
enum NewLineKind {
|
||||
CarriageReturnLineFeed = 0,
|
||||
LineFeed = 1
|
||||
}
|
||||
|
||||
enum ScriptTarget {
|
||||
ES3 = 0,
|
||||
ES5 = 1,
|
||||
|
|
@ -162,10 +192,13 @@ enum ScriptTarget {
|
|||
ES2016 = 3,
|
||||
ES2017 = 4,
|
||||
ES2018 = 5,
|
||||
ESNext = 6,
|
||||
ES2019 = 6,
|
||||
ES2020 = 7,
|
||||
ESNext = 99,
|
||||
JSON = 100,
|
||||
Latest = 6
|
||||
Latest = ESNext,
|
||||
}
|
||||
|
||||
enum ModuleResolutionKind {
|
||||
Classic = 1,
|
||||
NodeJs = 2
|
||||
|
|
@ -180,11 +213,11 @@ const javascriptDefaults = new LanguageServiceDefaultsImpl(
|
|||
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
|
||||
{ noSemanticValidation: true, noSyntaxValidation: false });
|
||||
|
||||
function getTypeScriptWorker(): monaco.Promise<any> {
|
||||
function getTypeScriptWorker(): Promise<any> {
|
||||
return getMode().then(mode => mode.getTypeScriptWorker());
|
||||
}
|
||||
|
||||
function getJavaScriptWorker(): monaco.Promise<any> {
|
||||
function getJavaScriptWorker(): Promise<any> {
|
||||
return getMode().then(mode => mode.getJavaScriptWorker());
|
||||
}
|
||||
|
||||
|
|
@ -196,6 +229,7 @@ function createAPI(): typeof monaco.languages.typescript {
|
|||
NewLineKind: NewLineKind,
|
||||
ScriptTarget: ScriptTarget,
|
||||
ModuleResolutionKind: ModuleResolutionKind,
|
||||
typescriptVersion,
|
||||
typescriptDefaults: typescriptDefaults,
|
||||
javascriptDefaults: javascriptDefaults,
|
||||
getTypeScriptWorker: getTypeScriptWorker,
|
||||
|
|
@ -206,8 +240,8 @@ monaco.languages.typescript = createAPI();
|
|||
|
||||
// --- Registration to monaco editor ---
|
||||
|
||||
function getMode(): monaco.Promise<typeof mode> {
|
||||
return monaco.Promise.wrap(import('./tsMode'))
|
||||
function getMode(): Promise<typeof mode> {
|
||||
return import('./tsMode');
|
||||
}
|
||||
|
||||
monaco.languages.onLanguage('typescript', () => {
|
||||
|
|
|
|||
29
src/monaco.d.ts
vendored
29
src/monaco.d.ts
vendored
|
|
@ -8,8 +8,9 @@ declare module monaco.languages.typescript {
|
|||
UMD = 3,
|
||||
System = 4,
|
||||
ES2015 = 5,
|
||||
ESNext = 6
|
||||
ESNext = 99
|
||||
}
|
||||
|
||||
enum JsxEmit {
|
||||
None = 0,
|
||||
Preserve = 1,
|
||||
|
|
@ -28,9 +29,11 @@ declare module monaco.languages.typescript {
|
|||
ES2016 = 3,
|
||||
ES2017 = 4,
|
||||
ES2018 = 5,
|
||||
ESNext = 6,
|
||||
ES2019 = 6,
|
||||
ES2020 = 7,
|
||||
ESNext = 99,
|
||||
JSON = 100,
|
||||
Latest = 6
|
||||
Latest = ESNext,
|
||||
}
|
||||
|
||||
export enum ModuleResolutionKind {
|
||||
|
|
@ -125,32 +128,30 @@ declare module monaco.languages.typescript {
|
|||
export interface DiagnosticsOptions {
|
||||
noSemanticValidation?: boolean;
|
||||
noSyntaxValidation?: boolean;
|
||||
noSuggestionDiagnostics?: boolean;
|
||||
diagnosticCodesToIgnore?: number[];
|
||||
}
|
||||
|
||||
export interface LanguageServiceDefaults {
|
||||
/**
|
||||
* Add an additional source file to the language service. Use this
|
||||
* for typescript (definition) files that won't be loaded as editor
|
||||
* document, like `jquery.d.ts`.
|
||||
* documents, like `jquery.d.ts`.
|
||||
*
|
||||
* @param content The file content
|
||||
* @param filePath An optional file path
|
||||
* @returns A disposable which will remove the file from the
|
||||
* language service upon cleanup.
|
||||
* language service upon disposal.
|
||||
*/
|
||||
addExtraLib(content: string, filePath?: string): IDisposable;
|
||||
|
||||
/**
|
||||
* Add multiple source files to the language service.
|
||||
* Use this for multiple typescript (definition) files that won't be loaded
|
||||
* as editor document, like `jquery.d.ts`.
|
||||
* This method is optimised for performance and raises change events only once
|
||||
* for the whole list.
|
||||
* Remove all existing extra libs and set the additional source
|
||||
* files to the language service. Use this for typescript definition
|
||||
* files that won't be loaded as editor documents, like `jquery.d.ts`.
|
||||
* @param libs An array of entries to register.
|
||||
* @returns A disposable which will remove the file from the
|
||||
* language service upon cleanup.
|
||||
*/
|
||||
setExtraLibs(libs: Array<{ content: string; filePath?: string }>): IDisposable;
|
||||
setExtraLibs(libs: { content: string; filePath?: string }[]): void;
|
||||
|
||||
/**
|
||||
* Set TypeScript compiler options.
|
||||
|
|
@ -178,6 +179,8 @@ declare module monaco.languages.typescript {
|
|||
setEagerModelSync(value: boolean): void;
|
||||
}
|
||||
|
||||
export var typescriptVersion: string;
|
||||
|
||||
export var typescriptDefaults: LanguageServiceDefaults;
|
||||
export var javascriptDefaults: LanguageServiceDefaults;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { TypeScriptWorker } from './tsWorker';
|
|||
import { LanguageServiceDefaultsImpl } from './monaco.contribution';
|
||||
import * as languageFeatures from './languageFeatures';
|
||||
|
||||
import Promise = monaco.Promise;
|
||||
import Uri = monaco.Uri;
|
||||
|
||||
let javaScriptWorker: (first: Uri, ...more: Uri[]) => Promise<TypeScriptWorker>;
|
||||
|
|
@ -30,7 +29,7 @@ export function setupJavaScript(defaults: LanguageServiceDefaultsImpl): void {
|
|||
}
|
||||
|
||||
export function getJavaScriptWorker(): Promise<(first: Uri, ...more: Uri[]) => Promise<TypeScriptWorker>> {
|
||||
return new monaco.Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!javaScriptWorker) {
|
||||
return reject("JavaScript not registered!");
|
||||
}
|
||||
|
|
@ -40,7 +39,7 @@ export function getJavaScriptWorker(): Promise<(first: Uri, ...more: Uri[]) => P
|
|||
}
|
||||
|
||||
export function getTypeScriptWorker(): Promise<(first: Uri, ...more: Uri[]) => Promise<TypeScriptWorker>> {
|
||||
return new monaco.Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!typeScriptWorker) {
|
||||
return reject("TypeScript not registered!");
|
||||
}
|
||||
|
|
@ -65,7 +64,9 @@ function setupMode(defaults: LanguageServiceDefaultsImpl, modeId: string): (firs
|
|||
monaco.languages.registerDocumentSymbolProvider(modeId, new languageFeatures.OutlineAdapter(worker));
|
||||
monaco.languages.registerDocumentRangeFormattingEditProvider(modeId, new languageFeatures.FormatAdapter(worker));
|
||||
monaco.languages.registerOnTypeFormattingEditProvider(modeId, new languageFeatures.FormatOnTypeAdapter(worker));
|
||||
new languageFeatures.DiagnostcsAdapter(defaults, modeId, worker);
|
||||
monaco.languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker));
|
||||
monaco.languages.registerRenameProvider(modeId, new languageFeatures.RenameAdapter(worker));
|
||||
new languageFeatures.DiagnosticsAdapter(defaults, modeId, worker);
|
||||
|
||||
return worker;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
import * as ts from './lib/typescriptServices';
|
||||
import { lib_dts, lib_es6_dts } from './lib/lib';
|
||||
import { IExtraLibs } from './monaco.contribution';
|
||||
|
||||
import Promise = monaco.Promise;
|
||||
import IWorkerContext = monaco.worker.IWorkerContext;
|
||||
|
||||
const DEFAULT_LIB = {
|
||||
|
|
@ -25,7 +25,7 @@ export class TypeScriptWorker implements ts.LanguageServiceHost {
|
|||
// --- model sync -----------------------
|
||||
|
||||
private _ctx: IWorkerContext;
|
||||
private _extraLibs: { [fileName: string]: string } = Object.create(null);
|
||||
private _extraLibs: IExtraLibs = Object.create(null);
|
||||
private _languageService = ts.createLanguageService(this);
|
||||
private _compilerOptions: ts.CompilerOptions;
|
||||
|
||||
|
|
@ -60,9 +60,11 @@ export class TypeScriptWorker implements ts.LanguageServiceHost {
|
|||
let model = this._getModel(fileName);
|
||||
if (model) {
|
||||
return model.version.toString();
|
||||
} else if (this.isDefaultLibFileName(fileName) || fileName in this._extraLibs) {
|
||||
// extra lib and default lib are static
|
||||
} else if (this.isDefaultLibFileName(fileName)) {
|
||||
// default lib is static
|
||||
return '1';
|
||||
} else if (fileName in this._extraLibs) {
|
||||
return String(this._extraLibs[fileName].version);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -74,8 +76,8 @@ export class TypeScriptWorker implements ts.LanguageServiceHost {
|
|||
text = model.getValue();
|
||||
|
||||
} else if (fileName in this._extraLibs) {
|
||||
// static extra lib
|
||||
text = this._extraLibs[fileName];
|
||||
// extra lib
|
||||
text = this._extraLibs[fileName].content;
|
||||
|
||||
} else if (fileName === DEFAULT_LIB.NAME) {
|
||||
text = DEFAULT_LIB.CONTENTS;
|
||||
|
|
@ -135,73 +137,96 @@ export class TypeScriptWorker implements ts.LanguageServiceHost {
|
|||
getSyntacticDiagnostics(fileName: string): Promise<ts.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getSyntacticDiagnostics(fileName);
|
||||
TypeScriptWorker.clearFiles(diagnostics);
|
||||
return Promise.as(diagnostics);
|
||||
return Promise.resolve(diagnostics);
|
||||
}
|
||||
|
||||
getSemanticDiagnostics(fileName: string): Promise<ts.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getSemanticDiagnostics(fileName);
|
||||
TypeScriptWorker.clearFiles(diagnostics);
|
||||
return Promise.as(diagnostics);
|
||||
return Promise.resolve(diagnostics);
|
||||
}
|
||||
|
||||
getSuggestionDiagnostics(fileName: string): Promise<ts.DiagnosticWithLocation[]> {
|
||||
const diagnostics = this._languageService.getSuggestionDiagnostics(fileName);
|
||||
TypeScriptWorker.clearFiles(diagnostics);
|
||||
return Promise.resolve(diagnostics);
|
||||
}
|
||||
|
||||
getCompilerOptionsDiagnostics(fileName: string): Promise<ts.Diagnostic[]> {
|
||||
const diagnostics = this._languageService.getCompilerOptionsDiagnostics();
|
||||
TypeScriptWorker.clearFiles(diagnostics);
|
||||
return Promise.as(diagnostics);
|
||||
return Promise.resolve(diagnostics);
|
||||
}
|
||||
|
||||
getCompletionsAtPosition(fileName: string, position: number): Promise<ts.CompletionInfo> {
|
||||
return Promise.as(this._languageService.getCompletionsAtPosition(fileName, position, undefined));
|
||||
return Promise.resolve(this._languageService.getCompletionsAtPosition(fileName, position, undefined));
|
||||
}
|
||||
|
||||
getCompletionEntryDetails(fileName: string, position: number, entry: string): Promise<ts.CompletionEntryDetails> {
|
||||
return Promise.as(this._languageService.getCompletionEntryDetails(fileName, position, entry, undefined, undefined, undefined));
|
||||
return Promise.resolve(this._languageService.getCompletionEntryDetails(fileName, position, entry, undefined, undefined, undefined));
|
||||
}
|
||||
|
||||
getSignatureHelpItems(fileName: string, position: number): Promise<ts.SignatureHelpItems> {
|
||||
return Promise.as(this._languageService.getSignatureHelpItems(fileName, position, undefined));
|
||||
return Promise.resolve(this._languageService.getSignatureHelpItems(fileName, position, undefined));
|
||||
}
|
||||
|
||||
getQuickInfoAtPosition(fileName: string, position: number): Promise<ts.QuickInfo> {
|
||||
return Promise.as(this._languageService.getQuickInfoAtPosition(fileName, position));
|
||||
return Promise.resolve(this._languageService.getQuickInfoAtPosition(fileName, position));
|
||||
}
|
||||
|
||||
getOccurrencesAtPosition(fileName: string, position: number): Promise<ts.ReferenceEntry[]> {
|
||||
return Promise.as(this._languageService.getOccurrencesAtPosition(fileName, position));
|
||||
getOccurrencesAtPosition(fileName: string, position: number): Promise<ReadonlyArray<ts.ReferenceEntry>> {
|
||||
return Promise.resolve(this._languageService.getOccurrencesAtPosition(fileName, position));
|
||||
}
|
||||
|
||||
getDefinitionAtPosition(fileName: string, position: number): Promise<ts.DefinitionInfo[]> {
|
||||
return Promise.as(this._languageService.getDefinitionAtPosition(fileName, position));
|
||||
getDefinitionAtPosition(fileName: string, position: number): Promise<ReadonlyArray<ts.DefinitionInfo>> {
|
||||
return Promise.resolve(this._languageService.getDefinitionAtPosition(fileName, position));
|
||||
}
|
||||
|
||||
getReferencesAtPosition(fileName: string, position: number): Promise<ts.ReferenceEntry[]> {
|
||||
return Promise.as(this._languageService.getReferencesAtPosition(fileName, position));
|
||||
return Promise.resolve(this._languageService.getReferencesAtPosition(fileName, position));
|
||||
}
|
||||
|
||||
getNavigationBarItems(fileName: string): Promise<ts.NavigationBarItem[]> {
|
||||
return Promise.as(this._languageService.getNavigationBarItems(fileName));
|
||||
return Promise.resolve(this._languageService.getNavigationBarItems(fileName));
|
||||
}
|
||||
|
||||
getFormattingEditsForDocument(fileName: string, options: ts.FormatCodeOptions): Promise<ts.TextChange[]> {
|
||||
return Promise.as(this._languageService.getFormattingEditsForDocument(fileName, options));
|
||||
return Promise.resolve(this._languageService.getFormattingEditsForDocument(fileName, options));
|
||||
}
|
||||
|
||||
getFormattingEditsForRange(fileName: string, start: number, end: number, options: ts.FormatCodeOptions): Promise<ts.TextChange[]> {
|
||||
return Promise.as(this._languageService.getFormattingEditsForRange(fileName, start, end, options));
|
||||
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.as(this._languageService.getFormattingEditsAfterKeystroke(fileName, postion, ch, options));
|
||||
return Promise.resolve(this._languageService.getFormattingEditsAfterKeystroke(fileName, postion, ch, options));
|
||||
}
|
||||
|
||||
findRenameLocations(fileName: string, positon: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename: boolean): Promise<readonly ts.RenameLocation[]> {
|
||||
return Promise.resolve(this._languageService.findRenameLocations(fileName, positon, findInStrings, findInComments, providePrefixAndSuffixTextForRename));
|
||||
}
|
||||
|
||||
getRenameInfo(fileName: string, positon: number, options: ts.RenameInfoOptions): Promise<ts.RenameInfo> {
|
||||
return Promise.resolve(this._languageService.getRenameInfo(fileName, positon, options));
|
||||
}
|
||||
|
||||
getEmitOutput(fileName: string): Promise<ts.EmitOutput> {
|
||||
return Promise.as(this._languageService.getEmitOutput(fileName));
|
||||
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));
|
||||
}
|
||||
|
||||
updateExtraLibs(extraLibs: IExtraLibs) {
|
||||
this._extraLibs = extraLibs;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ICreateData {
|
||||
compilerOptions: ts.CompilerOptions;
|
||||
extraLibs: { [path: string]: string };
|
||||
extraLibs: IExtraLibs;
|
||||
}
|
||||
|
||||
export function create(ctx: IWorkerContext, createData: ICreateData): TypeScriptWorker {
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@
|
|||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"declaration": true,
|
||||
"outDir": "../release/esm",
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es5",
|
||||
"es2015.collection",
|
||||
"es2015.iterable",
|
||||
"es2015.promise"
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@
|
|||
"module": "amd",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../release/dev",
|
||||
"declaration": true,
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es5",
|
||||
"es2015.collection",
|
||||
"es2015.iterable",
|
||||
"es2015.promise"
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
import { LanguageServiceDefaultsImpl } from './monaco.contribution';
|
||||
import { TypeScriptWorker } from './tsWorker';
|
||||
|
||||
import Promise = monaco.Promise;
|
||||
import IDisposable = monaco.IDisposable;
|
||||
import Uri = monaco.Uri;
|
||||
|
||||
|
|
@ -18,6 +17,8 @@ export class WorkerManager {
|
|||
private _idleCheckInterval: number;
|
||||
private _lastUsedTime: number;
|
||||
private _configChangeListener: IDisposable;
|
||||
private _updateExtraLibsToken: number;
|
||||
private _extraLibsChangeListener: IDisposable;
|
||||
|
||||
private _worker: monaco.editor.MonacoWebWorker<TypeScriptWorker>;
|
||||
private _client: Promise<TypeScriptWorker>;
|
||||
|
|
@ -29,6 +30,8 @@ export class WorkerManager {
|
|||
this._idleCheckInterval = setInterval(() => this._checkIfIdle(), 30 * 1000);
|
||||
this._lastUsedTime = 0;
|
||||
this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
|
||||
this._updateExtraLibsToken = 0;
|
||||
this._extraLibsChangeListener = this._defaults.onDidExtraLibsChange(() => this._updateExtraLibs());
|
||||
}
|
||||
|
||||
private _stopWorker(): void {
|
||||
|
|
@ -42,9 +45,23 @@ export class WorkerManager {
|
|||
dispose(): void {
|
||||
clearInterval(this._idleCheckInterval);
|
||||
this._configChangeListener.dispose();
|
||||
this._extraLibsChangeListener.dispose();
|
||||
this._stopWorker();
|
||||
}
|
||||
|
||||
private async _updateExtraLibs(): Promise<void> {
|
||||
if (!this._worker) {
|
||||
return;
|
||||
}
|
||||
const myToken = ++this._updateExtraLibsToken;
|
||||
const proxy = await this._worker.getProxy();
|
||||
if (this._updateExtraLibsToken !== myToken) {
|
||||
// avoid multiple calls
|
||||
return;
|
||||
}
|
||||
proxy.updateExtraLibs(this._defaults.getExtraLibs());
|
||||
}
|
||||
|
||||
private _checkIfIdle(): void {
|
||||
if (!this._worker) {
|
||||
return;
|
||||
|
|
@ -74,7 +91,7 @@ export class WorkerManager {
|
|||
}
|
||||
});
|
||||
|
||||
let p = this._worker.getProxy();
|
||||
let p = <Promise<TypeScriptWorker>>this._worker.getProxy();
|
||||
|
||||
if (this._defaults.getEagerModelSync()) {
|
||||
p = p.then(worker => {
|
||||
|
|
@ -93,26 +110,10 @@ export class WorkerManager {
|
|||
|
||||
getLanguageServiceWorker(...resources: Uri[]): Promise<TypeScriptWorker> {
|
||||
let _client: TypeScriptWorker;
|
||||
return toShallowCancelPromise(
|
||||
this._getClient().then((client) => {
|
||||
return this._getClient().then((client) => {
|
||||
_client = client
|
||||
}).then(_ => {
|
||||
return this._worker.withSyncedResources(resources)
|
||||
}).then(_ => _client)
|
||||
);
|
||||
}).then(_ => _client);
|
||||
}
|
||||
}
|
||||
|
||||
function toShallowCancelPromise<T>(p: Promise<T>): Promise<T> {
|
||||
let completeCallback: (value: T) => void;
|
||||
let errorCallback: (err: any) => void;
|
||||
|
||||
let r = new Promise<T>((c, e) => {
|
||||
completeCallback = c;
|
||||
errorCallback = e;
|
||||
}, () => { });
|
||||
|
||||
p.then(completeCallback, errorCallback);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,9 @@
|
|||
<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.js"></script>
|
||||
|
||||
<script>
|
||||
require([
|
||||
'vs/basic-languages/monaco.contribution',
|
||||
'vs/language/typescript/monaco.contribution'
|
||||
], function() {
|
||||
var editor = monaco.editor.create(document.getElementById('container'), {
|
||||
value: [
|
||||
let text = localStorage.getItem("code")
|
||||
if (!text) {
|
||||
text = [
|
||||
'/* Game of Life',
|
||||
' * Implemented in TypeScript',
|
||||
' * To learn more about TypeScript, please visit http://www.typescriptlang.org/',
|
||||
|
|
@ -163,10 +160,23 @@
|
|||
'}',
|
||||
'',
|
||||
'var game = new Conway.GameOfLife();',
|
||||
].join('\n');
|
||||
}
|
||||
require([
|
||||
'vs/basic-languages/monaco.contribution',
|
||||
'vs/language/typescript/monaco.contribution'
|
||||
], function() {
|
||||
|
||||
].join('\n'),
|
||||
language: 'typescript'
|
||||
var editor = monaco.editor.create(document.getElementById('container'), {
|
||||
value: text,
|
||||
language: 'typescript',
|
||||
lightbulb: { enabled: true }
|
||||
});
|
||||
|
||||
editor.onDidChangeModelContent(() => {
|
||||
const code = editor.getModel().getValue()
|
||||
localStorage.setItem("code", code)
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue