Use the global monaco only in the AMD case (see microsoft/monaco-editor#1974)

This commit is contained in:
Alex Dima 2020-09-07 21:52:41 +02:00
parent b87c75d7e9
commit ee95401a40
No known key found for this signature in database
GPG key ID: 6E58D7B045760DA0
22 changed files with 842 additions and 391 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
/node_modules/ /node_modules/
/out/
/release/ /release/

View file

@ -1,3 +1,4 @@
/.github/
/.vscode/ /.vscode/
/scripts/ /scripts/
/src/ /src/
@ -5,4 +6,5 @@
/gulpfile.js /gulpfile.js
/tsconfig.json /tsconfig.json
/.npmignore /.npmignore
/out/
/release/**/test/ /release/**/test/

View file

@ -1,2 +1,3 @@
/out/
/release/ /release/
/src/lib/ /src/lib/

View file

@ -3,6 +3,7 @@
"files.trimTrailingWhitespace": true, "files.trimTrailingWhitespace": true,
"search.exclude": { "search.exclude": {
"**/node_modules": true, "**/node_modules": true,
"**/out": true,
"**/release": true "**/release": true
} }
} }

View file

@ -1,5 +1,12 @@
declare module monaco.languages.typescript { /*---------------------------------------------------------------------------------------------
enum ModuleKind { * Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path="node_modules/monaco-editor-core/monaco.d.ts" />
declare namespace monaco.languages.typescript {
export enum ModuleKind {
None = 0, None = 0,
CommonJS = 1, CommonJS = 1,
AMD = 2, AMD = 2,
@ -8,19 +15,17 @@ declare module monaco.languages.typescript {
ES2015 = 5, ES2015 = 5,
ESNext = 99 ESNext = 99
} }
export enum JsxEmit {
enum JsxEmit {
None = 0, None = 0,
Preserve = 1, Preserve = 1,
React = 2, React = 2,
ReactNative = 3 ReactNative = 3
} }
enum NewLineKind { export enum NewLineKind {
CarriageReturnLineFeed = 0, CarriageReturnLineFeed = 0,
LineFeed = 1 LineFeed = 1
} }
export enum ScriptTarget {
enum ScriptTarget {
ES3 = 0, ES3 = 0,
ES5 = 1, ES5 = 1,
ES2015 = 2, ES2015 = 2,
@ -31,19 +36,16 @@ declare module monaco.languages.typescript {
ES2020 = 7, ES2020 = 7,
ESNext = 99, ESNext = 99,
JSON = 100, JSON = 100,
Latest = ESNext Latest = 99
} }
export enum ModuleResolutionKind { export enum ModuleResolutionKind {
Classic = 1, Classic = 1,
NodeJs = 2 NodeJs = 2
} }
interface MapLike<T> { interface MapLike<T> {
[index: string]: T; [index: string]: T;
} }
declare type CompilerOptionsValue =
type CompilerOptionsValue =
| string | string
| number | number
| boolean | boolean
@ -135,28 +137,23 @@ declare module monaco.languages.typescript {
useDefineForClassFields?: boolean; useDefineForClassFields?: boolean;
[option: string]: CompilerOptionsValue | undefined; [option: string]: CompilerOptionsValue | undefined;
} }
export interface DiagnosticsOptions { export interface DiagnosticsOptions {
noSemanticValidation?: boolean; noSemanticValidation?: boolean;
noSyntaxValidation?: boolean; noSyntaxValidation?: boolean;
noSuggestionDiagnostics?: boolean; noSuggestionDiagnostics?: boolean;
diagnosticCodesToIgnore?: number[]; diagnosticCodesToIgnore?: number[];
} }
export interface WorkerOptions { export interface WorkerOptions {
/** A full HTTP path to a JavaScript file which adds a function `customTSWorkerFactory` to the self inside a web-worker */ /** A full HTTP path to a JavaScript file which adds a function `customTSWorkerFactory` to the self inside a web-worker */
customWorkerPath?: string; customWorkerPath?: string;
} }
interface IExtraLib { interface IExtraLib {
content: string; content: string;
version: number; version: number;
} }
export interface IExtraLibs {
interface IExtraLibs {
[path: string]: IExtraLib; [path: string]: IExtraLib;
} }
/** /**
* A linked list of formatted diagnostic messages to be used as part of a multiline message. * A linked list of formatted diagnostic messages to be used as part of a multiline message.
* It is built from the bottom up, leaving the head to be the "main" diagnostic. * It is built from the bottom up, leaving the head to be the "main" diagnostic.
@ -168,7 +165,7 @@ declare module monaco.languages.typescript {
code: number; code: number;
next?: DiagnosticMessageChain[]; next?: DiagnosticMessageChain[];
} }
interface Diagnostic extends DiagnosticRelatedInformation { export interface Diagnostic extends DiagnosticRelatedInformation {
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */ /** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {}; reportsUnnecessary?: {};
source?: string; source?: string;
@ -184,7 +181,6 @@ declare module monaco.languages.typescript {
length: number | undefined; length: number | undefined;
messageText: string | DiagnosticMessageChain; messageText: string | DiagnosticMessageChain;
} }
interface EmitOutput { interface EmitOutput {
outputFiles: OutputFile[]; outputFiles: OutputFile[];
emitSkipped: boolean; emitSkipped: boolean;
@ -194,23 +190,20 @@ declare module monaco.languages.typescript {
writeByteOrderMark: boolean; writeByteOrderMark: boolean;
text: string; text: string;
} }
export interface LanguageServiceDefaults { export interface LanguageServiceDefaults {
/** /**
* Event fired when compiler options or diagnostics options are changed. * Event fired when compiler options or diagnostics options are changed.
*/ */
readonly onDidChange: IEvent<void>; readonly onDidChange: IEvent<void>;
/** /**
* Event fired when extra libraries registered with the language service change. * Event fired when extra libraries registered with the language service change.
*/ */
readonly onDidExtraLibsChange: IEvent<void>; readonly onDidExtraLibsChange: IEvent<void>;
readonly workerOptions: WorkerOptions;
/** /**
* Get the current extra libs registered with the language service. * Get the current extra libs registered with the language service.
*/ */
getExtraLibs(): IExtraLibs; getExtraLibs(): IExtraLibs;
/** /**
* Add an additional source file to the language service. Use this * Add an additional source file to the language service. Use this
* for typescript (definition) files that won't be loaded as editor * for typescript (definition) files that won't be loaded as editor
@ -222,81 +215,72 @@ declare module monaco.languages.typescript {
* language service upon disposal. * language service upon disposal.
*/ */
addExtraLib(content: string, filePath?: string): IDisposable; addExtraLib(content: string, filePath?: string): IDisposable;
/** /**
* Remove all existing extra libs and set the additional source * Remove all existing extra libs and set the additional source
* files to the language service. Use this for typescript definition * files to the language service. Use this for typescript definition
* files that won't be loaded as editor documents, like `jquery.d.ts`. * files that won't be loaded as editor documents, like `jquery.d.ts`.
* @param libs An array of entries to register. * @param libs An array of entries to register.
*/ */
setExtraLibs(libs: { content: string; filePath?: string }[]): void; setExtraLibs(
libs: {
content: string;
filePath?: string;
}[]
): void;
/** /**
* Get current TypeScript compiler options for the language service. * Get current TypeScript compiler options for the language service.
*/ */
getCompilerOptions(): CompilerOptions; getCompilerOptions(): CompilerOptions;
/** /**
* Set TypeScript compiler options. * Set TypeScript compiler options.
*/ */
setCompilerOptions(options: CompilerOptions): void; setCompilerOptions(options: CompilerOptions): void;
/** /**
* Get the current diagnostics options for the language service. * Get the current diagnostics options for the language service.
*/ */
getDiagnosticsOptions(): DiagnosticsOptions; getDiagnosticsOptions(): DiagnosticsOptions;
/** /**
* Configure whether syntactic and/or semantic validation should * Configure whether syntactic and/or semantic validation should
* be performed * be performed
*/ */
setDiagnosticsOptions(options: DiagnosticsOptions): void; setDiagnosticsOptions(options: DiagnosticsOptions): void;
/** /**
* No-op. * No-op.
*/ */
setMaximumWorkerIdleTime(value: number): void; setMaximumWorkerIdleTime(value: number): void;
/** /**
* Configure if all existing models should be eagerly sync'd * Configure if all existing models should be eagerly sync'd
* to the worker on start or restart. * to the worker on start or restart.
*/ */
setEagerModelSync(value: boolean): void; setEagerModelSync(value: boolean): void;
/** /**
* Get the current setting for whether all existing models should be eagerly sync'd * Get the current setting for whether all existing models should be eagerly sync'd
* to the worker on start or restart. * to the worker on start or restart.
*/ */
getEagerModelSync(): boolean; getEagerModelSync(): boolean;
} }
export interface TypeScriptWorker { export interface TypeScriptWorker {
/** /**
* Get diagnostic messages for any syntax issues in the given file. * Get diagnostic messages for any syntax issues in the given file.
*/ */
getSyntacticDiagnostics(fileName: string): Promise<Diagnostic[]>; getSyntacticDiagnostics(fileName: string): Promise<Diagnostic[]>;
/** /**
* Get diagnostic messages for any semantic issues in the given file. * Get diagnostic messages for any semantic issues in the given file.
*/ */
getSemanticDiagnostics(fileName: string): Promise<Diagnostic[]>; getSemanticDiagnostics(fileName: string): Promise<Diagnostic[]>;
/** /**
* Get diagnostic messages for any suggestions related to the given file. * Get diagnostic messages for any suggestions related to the given file.
*/ */
getSuggestionDiagnostics(fileName: string): Promise<Diagnostic[]>; getSuggestionDiagnostics(fileName: string): Promise<Diagnostic[]>;
/** /**
* Get the content of a given file. * Get the content of a given file.
*/ */
getScriptText(fileName: string): Promise<string | undefined>; getScriptText(fileName: string): Promise<string | undefined>;
/** /**
* Get diagnostic messages related to the current compiler options. * Get diagnostic messages related to the current compiler options.
* @param fileName Not used * @param fileName Not used
*/ */
getCompilerOptionsDiagnostics(fileName: string): Promise<Diagnostic[]>; getCompilerOptionsDiagnostics(fileName: string): Promise<Diagnostic[]>;
/** /**
* Get code completions for the given file and position. * Get code completions for the given file and position.
* @returns `Promise<typescript.CompletionInfo | undefined>` * @returns `Promise<typescript.CompletionInfo | undefined>`
@ -305,7 +289,6 @@ declare module monaco.languages.typescript {
fileName: string, fileName: string,
position: number position: number
): Promise<any | undefined>; ): Promise<any | undefined>;
/** /**
* Get code completion details for the given file, position, and entry. * Get code completion details for the given file, position, and entry.
* @returns `Promise<typescript.CompletionEntryDetails | undefined>` * @returns `Promise<typescript.CompletionEntryDetails | undefined>`
@ -315,7 +298,6 @@ declare module monaco.languages.typescript {
position: number, position: number,
entry: string entry: string
): Promise<any | undefined>; ): Promise<any | undefined>;
/** /**
* Get signature help items for the item at the given file and position. * Get signature help items for the item at the given file and position.
* @returns `Promise<typescript.SignatureHelpItems | undefined>` * @returns `Promise<typescript.SignatureHelpItems | undefined>`
@ -324,7 +306,6 @@ declare module monaco.languages.typescript {
fileName: string, fileName: string,
position: number position: number
): Promise<any | undefined>; ): Promise<any | undefined>;
/** /**
* Get quick info for the item at the given position in the file. * Get quick info for the item at the given position in the file.
* @returns `Promise<typescript.QuickInfo | undefined>` * @returns `Promise<typescript.QuickInfo | undefined>`
@ -333,7 +314,6 @@ declare module monaco.languages.typescript {
fileName: string, fileName: string,
position: number position: number
): Promise<any | undefined>; ): Promise<any | undefined>;
/** /**
* Get other ranges which are related to the item at the given position in the file (often used for highlighting). * 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>` * @returns `Promise<ReadonlyArray<typescript.ReferenceEntry> | undefined>`
@ -342,7 +322,6 @@ declare module monaco.languages.typescript {
fileName: string, fileName: string,
position: number position: number
): Promise<ReadonlyArray<any> | undefined>; ): Promise<ReadonlyArray<any> | undefined>;
/** /**
* Get the definition of the item at the given position in the file. * Get the definition of the item at the given position in the file.
* @returns `Promise<ReadonlyArray<typescript.DefinitionInfo> | undefined>` * @returns `Promise<ReadonlyArray<typescript.DefinitionInfo> | undefined>`
@ -351,7 +330,6 @@ declare module monaco.languages.typescript {
fileName: string, fileName: string,
position: number position: number
): Promise<ReadonlyArray<any> | undefined>; ): Promise<ReadonlyArray<any> | undefined>;
/** /**
* Get references to the item at the given position in the file. * Get references to the item at the given position in the file.
* @returns `Promise<typescript.ReferenceEntry[] | undefined>` * @returns `Promise<typescript.ReferenceEntry[] | undefined>`
@ -360,13 +338,11 @@ declare module monaco.languages.typescript {
fileName: string, fileName: string,
position: number position: number
): Promise<any[] | undefined>; ): Promise<any[] | undefined>;
/** /**
* Get outline entries for the item at the given position in the file. * Get outline entries for the item at the given position in the file.
* @returns `Promise<typescript.NavigationBarItem[]>` * @returns `Promise<typescript.NavigationBarItem[]>`
*/ */
getNavigationBarItems(fileName: string): Promise<any[]>; getNavigationBarItems(fileName: string): Promise<any[]>;
/** /**
* Get changes which should be applied to format the given file. * Get changes which should be applied to format the given file.
* @param options `typescript.FormatCodeOptions` * @param options `typescript.FormatCodeOptions`
@ -376,7 +352,6 @@ declare module monaco.languages.typescript {
fileName: string, fileName: string,
options: any options: any
): Promise<any[]>; ): Promise<any[]>;
/** /**
* Get changes which should be applied to format the given range in the file. * Get changes which should be applied to format the given range in the file.
* @param options `typescript.FormatCodeOptions` * @param options `typescript.FormatCodeOptions`
@ -388,7 +363,6 @@ declare module monaco.languages.typescript {
end: number, end: number,
options: any options: any
): Promise<any[]>; ): Promise<any[]>;
/** /**
* Get formatting changes which should be applied after the given keystroke. * Get formatting changes which should be applied after the given keystroke.
* @param options `typescript.FormatCodeOptions` * @param options `typescript.FormatCodeOptions`
@ -400,7 +374,6 @@ declare module monaco.languages.typescript {
ch: string, ch: string,
options: any options: any
): Promise<any[]>; ): Promise<any[]>;
/** /**
* Get other occurrences which should be updated when renaming the item at the given file and position. * Get other occurrences which should be updated when renaming the item at the given file and position.
* @returns `Promise<readonly typescript.RenameLocation[] | undefined>` * @returns `Promise<readonly typescript.RenameLocation[] | undefined>`
@ -412,7 +385,6 @@ declare module monaco.languages.typescript {
findInComments: boolean, findInComments: boolean,
providePrefixAndSuffixTextForRename: boolean providePrefixAndSuffixTextForRename: boolean
): Promise<readonly any[] | undefined>; ): Promise<readonly any[] | undefined>;
/** /**
* Get edits which should be applied to rename the item at the given file and position (or a failure reason). * Get edits which should be applied to rename the item at the given file and position (or a failure reason).
* @param options `typescript.RenameInfoOptions` * @param options `typescript.RenameInfoOptions`
@ -423,13 +395,11 @@ declare module monaco.languages.typescript {
positon: number, positon: number,
options: any options: any
): Promise<any>; ): Promise<any>;
/** /**
* Get transpiled output for the given file. * Get transpiled output for the given file.
* @returns `typescript.EmitOutput` * @returns `typescript.EmitOutput`
*/ */
getEmitOutput(fileName: string): Promise<any>; getEmitOutput(fileName: string): Promise<EmitOutput>;
/** /**
* Get possible code fixes at the given position in the file. * Get possible code fixes at the given position in the file.
* @param formatOptions `typescript.FormatCodeOptions` * @param formatOptions `typescript.FormatCodeOptions`
@ -443,12 +413,9 @@ declare module monaco.languages.typescript {
formatOptions: any formatOptions: any
): Promise<ReadonlyArray<any>>; ): Promise<ReadonlyArray<any>>;
} }
export const typescriptVersion: string; export const typescriptVersion: string;
export const typescriptDefaults: LanguageServiceDefaults; export const typescriptDefaults: LanguageServiceDefaults;
export const javascriptDefaults: LanguageServiceDefaults; export const javascriptDefaults: LanguageServiceDefaults;
export const getTypeScriptWorker: () => Promise< export const getTypeScriptWorker: () => Promise<
(...uris: Uri[]) => Promise<TypeScriptWorker> (...uris: Uri[]) => Promise<TypeScriptWorker>
>; >;

View file

@ -3,11 +3,11 @@
"version": "3.7.0", "version": "3.7.0",
"description": "TypeScript and JavaScript language support for Monaco Editor", "description": "TypeScript and JavaScript language support for Monaco Editor",
"scripts": { "scripts": {
"compile-amd": "mcopy ./src/lib/typescriptServices-amd.js ./release/dev/lib/typescriptServices.js && tsc -p ./src/tsconfig.json", "compile-amd": "mcopy ./src/lib/typescriptServices-amd.js ./out/amd/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-esm": "mcopy ./src/lib/typescriptServices.js ./out/esm/lib/typescriptServices.js && tsc -p ./src/tsconfig.esm.json",
"compile": "mrmdir ./release && npm run compile-amd && npm run compile-esm", "compile": "mrmdir ./out && npm run compile-amd && npm run compile-esm && node ./scripts/dts && prettier --write ./monaco.d.ts",
"watch": "tsc -p ./src --watch", "watch": "tsc -p ./src --watch",
"prepublishOnly": "npm run compile && node ./scripts/bundle && mcopy ./src/monaco.d.ts ./release/monaco.d.ts", "prepublishOnly": "mrmdir ./release && npm run compile && node ./scripts/release.js && node ./scripts/bundle && mcopy ./monaco.d.ts ./release/monaco.d.ts && mcopy ./out/esm/monaco.contribution.d.ts ./release/esm/monaco.contribution.d.ts && mcopy ./out/esm/fillers/monaco-editor-core.d.ts ./release/esm/fillers/monaco-editor-core.d.ts",
"import-typescript": "node ./scripts/importTypescript", "import-typescript": "node ./scripts/importTypescript",
"prettier": "prettier --write ." "prettier": "prettier --write ."
}, },
@ -20,6 +20,8 @@
"bugs": { "bugs": {
"url": "https://github.com/Microsoft/monaco-typescript/issues" "url": "https://github.com/Microsoft/monaco-typescript/issues"
}, },
"module": "./release/esm/monaco.contribution.js",
"typings": "./release/esm/monaco.contribution.d.ts",
"devDependencies": { "devDependencies": {
"@typescript/vfs": "^1.3.0", "@typescript/vfs": "^1.3.0",
"husky": "^4.3.0", "husky": "^4.3.0",

View file

@ -26,29 +26,45 @@ const BUNDLED_FILE_HEADER = [
].join('\n'); ].join('\n');
bundleOne('monaco.contribution'); bundleOne('monaco.contribution');
bundleOne('tsMode'); bundleOne('tsMode', ['vs/language/typescript/monaco.contribution']);
bundleOne('tsWorker'); bundleOne('tsWorker');
function bundleOne(moduleId, exclude) { function bundleOne(moduleId, exclude) {
requirejs.optimize( requirejs.optimize(
{ {
baseUrl: 'release/dev/', baseUrl: 'out/amd/',
name: 'vs/language/typescript/' + moduleId, name: 'vs/language/typescript/' + moduleId,
out: 'release/min/' + moduleId + '.js', out: 'release/dev/' + moduleId + '.js',
exclude: exclude, exclude: exclude,
paths: { paths: {
'vs/language/typescript': REPO_ROOT + '/release/dev' 'vs/language/typescript': REPO_ROOT + '/out/amd',
'vs/language/typescript/fillers/monaco-editor-core':
REPO_ROOT + '/out/amd/fillers/monaco-editor-core-amd'
}, },
optimize: 'none' optimize: 'none'
}, },
async function (buildResponse) { async function (buildResponse) {
const filePath = path.join(REPO_ROOT, 'release/min/' + moduleId + '.js'); const devFilePath = path.join(
const fileContents = fs.readFileSync(filePath).toString(); REPO_ROOT,
'release/dev/' + moduleId + '.js'
);
const minFilePath = path.join(
REPO_ROOT,
'release/min/' + moduleId + '.js'
);
const fileContents = fs.readFileSync(devFilePath).toString();
console.log(); console.log();
console.log(`Minifying ${filePath}...`); console.log(`Minifying ${devFilePath}...`);
const result = await terser.minify(fileContents); const result = await terser.minify(fileContents, {
console.log(`Done minifying ${filePath}.`); output: {
fs.writeFileSync(filePath, BUNDLED_FILE_HEADER + result.code); comments: 'some'
}
});
console.log(`Done minifying ${devFilePath}.`);
try {
fs.mkdirSync(path.join(REPO_ROOT, 'release/min'));
} catch (err) {}
fs.writeFileSync(minFilePath, BUNDLED_FILE_HEADER + result.code);
} }
); );
} }

44
scripts/dts.js Normal file
View file

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require('path');
const fs = require('fs');
const REPO_ROOT = path.join(__dirname, '../');
const SRC_PATH = path.join(REPO_ROOT, 'out/amd/monaco.contribution.d.ts');
const DST_PATH = path.join(REPO_ROOT, 'monaco.d.ts');
const lines = fs
.readFileSync(SRC_PATH)
.toString()
.split(/\r\n|\r|\n/);
let result = [
`/*---------------------------------------------------------------------------------------------`,
` * Copyright (c) Microsoft Corporation. All rights reserved.`,
` * Licensed under the MIT License. See License.txt in the project root for license information.`,
` *--------------------------------------------------------------------------------------------*/`,
``,
`/// <reference path="node_modules/monaco-editor-core/monaco.d.ts" />`,
``,
`declare namespace monaco.languages.typescript {`
];
for (let line of lines) {
if (/^import/.test(line)) {
continue;
}
if (line === 'export {};') {
continue;
}
line = line.replace(/ /g, '\t');
line = line.replace(/export declare/g, 'export');
if (line.length > 0) {
line = `\t${line}`;
result.push(line);
}
}
result.push(`}`);
result.push(``);
fs.writeFileSync(DST_PATH, result.join('\n'));

17
scripts/release.js Normal file
View file

@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require('path');
const helpers = require('monaco-plugin-helpers');
const REPO_ROOT = path.join(__dirname, '../');
helpers.packageESM({
repoRoot: REPO_ROOT,
esmSource: 'out/esm',
esmDestination: 'release/esm',
entryPoints: ['monaco.contribution.js', 'tsMode.js', 'ts.worker.js'],
resolveSkip: ['monaco-editor-core']
});

View file

@ -0,0 +1,12 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Resolves with the global monaco API
declare var define: any;
define([], function () {
return (<any>self).monaco;
});

View file

@ -0,0 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export * from 'monaco-editor-core';

View file

@ -4,16 +4,22 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import { LanguageServiceDefaultsImpl } from './monaco.contribution'; import { LanguageServiceDefaults } from './monaco.contribution';
import * as ts from './lib/typescriptServices'; import type * as ts from './lib/typescriptServices';
import { TypeScriptWorker } from './tsWorker'; import type { TypeScriptWorker } from './tsWorker';
import { libFileSet } from './lib/lib.index'; import { libFileSet } from './lib/lib.index';
import {
import Uri = monaco.Uri; editor,
import Position = monaco.Position; languages,
import Range = monaco.Range; Uri,
import CancellationToken = monaco.CancellationToken; Position,
import IDisposable = monaco.IDisposable; Range,
CancellationToken,
IDisposable,
IRange,
MarkerTag,
MarkerSeverity
} from './fillers/monaco-editor-core';
//#region utils copied from typescript to prevent loading the entire typescriptServices --- //#region utils copied from typescript to prevent loading the entire typescriptServices ---
@ -67,18 +73,18 @@ export abstract class Adapter {
protected _worker: (...uris: Uri[]) => Promise<TypeScriptWorker> protected _worker: (...uris: Uri[]) => Promise<TypeScriptWorker>
) {} ) {}
// protected _positionToOffset(model: monaco.editor.ITextModel, position: monaco.IPosition): number { // protected _positionToOffset(model: editor.ITextModel, position: monaco.IPosition): number {
// return model.getOffsetAt(position); // return model.getOffsetAt(position);
// } // }
// protected _offsetToPosition(model: monaco.editor.ITextModel, offset: number): monaco.IPosition { // protected _offsetToPosition(model: editor.ITextModel, offset: number): monaco.IPosition {
// return model.getPositionAt(offset); // return model.getPositionAt(offset);
// } // }
protected _textSpanToRange( protected _textSpanToRange(
model: monaco.editor.ITextModel, model: editor.ITextModel,
span: ts.TextSpan span: ts.TextSpan
): monaco.IRange { ): IRange {
let p1 = model.getPositionAt(span.start); let p1 = model.getPositionAt(span.start);
let p2 = model.getPositionAt(span.start + span.length); let p2 = model.getPositionAt(span.start + span.length);
let { lineNumber: startLineNumber, column: startColumn } = p1; let { lineNumber: startLineNumber, column: startColumn } = p1;
@ -112,13 +118,13 @@ export class LibFiles {
return false; return false;
} }
public getOrCreateModel(uri: Uri): monaco.editor.ITextModel | null { public getOrCreateModel(uri: Uri): editor.ITextModel | null {
const model = monaco.editor.getModel(uri); const model = editor.getModel(uri);
if (model) { if (model) {
return model; return model;
} }
if (this.isLibFile(uri) && this._hasFetchedLibFiles) { if (this.isLibFile(uri) && this._hasFetchedLibFiles) {
return monaco.editor.createModel( return editor.createModel(
this._libFiles[uri.path.slice(1)], this._libFiles[uri.path.slice(1)],
'javascript', 'javascript',
uri uri
@ -172,13 +178,13 @@ export class DiagnosticsAdapter extends Adapter {
constructor( constructor(
private readonly _libFiles: LibFiles, private readonly _libFiles: LibFiles,
private _defaults: LanguageServiceDefaultsImpl, private _defaults: LanguageServiceDefaults,
private _selector: string, private _selector: string,
worker: (...uris: Uri[]) => Promise<TypeScriptWorker> worker: (...uris: Uri[]) => Promise<TypeScriptWorker>
) { ) {
super(worker); super(worker);
const onModelAdd = (model: monaco.editor.IModel): void => { const onModelAdd = (model: editor.IModel): void => {
if (model.getModeId() !== _selector) { if (model.getModeId() !== _selector) {
return; return;
} }
@ -199,8 +205,8 @@ export class DiagnosticsAdapter extends Adapter {
this._doValidate(model); this._doValidate(model);
}; };
const onModelRemoved = (model: monaco.editor.IModel): void => { const onModelRemoved = (model: editor.IModel): void => {
monaco.editor.setModelMarkers(model, this._selector, []); editor.setModelMarkers(model, this._selector, []);
const key = model.uri.toString(); const key = model.uri.toString();
if (this._listener[key]) { if (this._listener[key]) {
this._listener[key].dispose(); this._listener[key].dispose();
@ -208,10 +214,10 @@ export class DiagnosticsAdapter extends Adapter {
} }
}; };
this._disposables.push(monaco.editor.onDidCreateModel(onModelAdd)); this._disposables.push(editor.onDidCreateModel(onModelAdd));
this._disposables.push(monaco.editor.onWillDisposeModel(onModelRemoved)); this._disposables.push(editor.onWillDisposeModel(onModelRemoved));
this._disposables.push( this._disposables.push(
monaco.editor.onDidChangeModelLanguage((event) => { editor.onDidChangeModelLanguage((event) => {
onModelRemoved(event.model); onModelRemoved(event.model);
onModelAdd(event.model); onModelAdd(event.model);
}) })
@ -219,7 +225,7 @@ export class DiagnosticsAdapter extends Adapter {
this._disposables.push({ this._disposables.push({
dispose() { dispose() {
for (const model of monaco.editor.getModels()) { for (const model of editor.getModels()) {
onModelRemoved(model); onModelRemoved(model);
} }
} }
@ -227,7 +233,7 @@ export class DiagnosticsAdapter extends Adapter {
const recomputeDiagostics = () => { const recomputeDiagostics = () => {
// redo diagnostics when options change // redo diagnostics when options change
for (const model of monaco.editor.getModels()) { for (const model of editor.getModels()) {
onModelRemoved(model); onModelRemoved(model);
onModelAdd(model); onModelAdd(model);
} }
@ -237,7 +243,7 @@ export class DiagnosticsAdapter extends Adapter {
this._defaults.onDidExtraLibsChange(recomputeDiagostics) this._defaults.onDidExtraLibsChange(recomputeDiagostics)
); );
monaco.editor.getModels().forEach(onModelAdd); editor.getModels().forEach(onModelAdd);
} }
public dispose(): void { public dispose(): void {
@ -245,7 +251,7 @@ export class DiagnosticsAdapter extends Adapter {
this._disposables = []; this._disposables = [];
} }
private async _doValidate(model: monaco.editor.ITextModel): Promise<void> { private async _doValidate(model: editor.ITextModel): Promise<void> {
const worker = await this._worker(model.uri); const worker = await this._worker(model.uri);
if (model.isDisposed()) { if (model.isDisposed()) {
@ -291,7 +297,7 @@ export class DiagnosticsAdapter extends Adapter {
.reduce((p, c) => c.concat(p), []) .reduce((p, c) => c.concat(p), [])
.map((relatedInformation) => .map((relatedInformation) =>
relatedInformation.file relatedInformation.file
? monaco.Uri.parse(relatedInformation.file.fileName) ? Uri.parse(relatedInformation.file.fileName)
: null : null
); );
@ -302,7 +308,7 @@ export class DiagnosticsAdapter extends Adapter {
return; return;
} }
monaco.editor.setModelMarkers( editor.setModelMarkers(
model, model,
this._selector, this._selector,
diagnostics.map((d) => this._convertDiagnostics(model, d)) diagnostics.map((d) => this._convertDiagnostics(model, d))
@ -310,9 +316,9 @@ export class DiagnosticsAdapter extends Adapter {
} }
private _convertDiagnostics( private _convertDiagnostics(
model: monaco.editor.ITextModel, model: editor.ITextModel,
diag: ts.Diagnostic diag: ts.Diagnostic
): monaco.editor.IMarkerData { ): editor.IMarkerData {
const diagStart = diag.start || 0; const diagStart = diag.start || 0;
const diagLength = diag.length || 1; const diagLength = diag.length || 1;
const { const {
@ -332,7 +338,7 @@ export class DiagnosticsAdapter extends Adapter {
endColumn, endColumn,
message: flattenDiagnosticMessageText(diag.messageText, '\n'), message: flattenDiagnosticMessageText(diag.messageText, '\n'),
code: diag.code.toString(), code: diag.code.toString(),
tags: diag.reportsUnnecessary ? [monaco.MarkerTag.Unnecessary] : [], tags: diag.reportsUnnecessary ? [MarkerTag.Unnecessary] : [],
relatedInformation: this._convertRelatedInformation( relatedInformation: this._convertRelatedInformation(
model, model,
diag.relatedInformation diag.relatedInformation
@ -341,18 +347,18 @@ export class DiagnosticsAdapter extends Adapter {
} }
private _convertRelatedInformation( private _convertRelatedInformation(
model: monaco.editor.ITextModel, model: editor.ITextModel,
relatedInformation?: ts.DiagnosticRelatedInformation[] relatedInformation?: ts.DiagnosticRelatedInformation[]
): monaco.editor.IRelatedInformation[] | undefined { ): editor.IRelatedInformation[] | undefined {
if (!relatedInformation) { if (!relatedInformation) {
return; return;
} }
const result: monaco.editor.IRelatedInformation[] = []; const result: editor.IRelatedInformation[] = [];
relatedInformation.forEach((info) => { relatedInformation.forEach((info) => {
let relatedResource: monaco.editor.ITextModel | null = model; let relatedResource: editor.ITextModel | null = model;
if (info.file) { if (info.file) {
const relatedResourceUri = monaco.Uri.parse(info.file.fileName); const relatedResourceUri = Uri.parse(info.file.fileName);
relatedResource = this._libFiles.getOrCreateModel(relatedResourceUri); relatedResource = this._libFiles.getOrCreateModel(relatedResourceUri);
} }
@ -384,24 +390,24 @@ export class DiagnosticsAdapter extends Adapter {
private _tsDiagnosticCategoryToMarkerSeverity( private _tsDiagnosticCategoryToMarkerSeverity(
category: ts.DiagnosticCategory category: ts.DiagnosticCategory
): monaco.MarkerSeverity { ): MarkerSeverity {
switch (category) { switch (category) {
case DiagnosticCategory.Error: case DiagnosticCategory.Error:
return monaco.MarkerSeverity.Error; return MarkerSeverity.Error;
case DiagnosticCategory.Message: case DiagnosticCategory.Message:
return monaco.MarkerSeverity.Info; return MarkerSeverity.Info;
case DiagnosticCategory.Warning: case DiagnosticCategory.Warning:
return monaco.MarkerSeverity.Warning; return MarkerSeverity.Warning;
case DiagnosticCategory.Suggestion: case DiagnosticCategory.Suggestion:
return monaco.MarkerSeverity.Hint; return MarkerSeverity.Hint;
} }
return monaco.MarkerSeverity.Info; return MarkerSeverity.Info;
} }
} }
// --- suggest ------ // --- suggest ------
interface MyCompletionItem extends monaco.languages.CompletionItem { interface MyCompletionItem extends languages.CompletionItem {
label: string; label: string;
uri: Uri; uri: Uri;
position: Position; position: Position;
@ -409,17 +415,17 @@ interface MyCompletionItem extends monaco.languages.CompletionItem {
export class SuggestAdapter export class SuggestAdapter
extends Adapter extends Adapter
implements monaco.languages.CompletionItemProvider { implements languages.CompletionItemProvider {
public get triggerCharacters(): string[] { public get triggerCharacters(): string[] {
return ['.']; return ['.'];
} }
public async provideCompletionItems( public async provideCompletionItems(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
_context: monaco.languages.CompletionContext, _context: languages.CompletionContext,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.CompletionList | undefined> { ): Promise<languages.CompletionList | undefined> {
const wordInfo = model.getWordUntilPosition(position); const wordInfo = model.getWordUntilPosition(position);
const wordRange = new Range( const wordRange = new Range(
position.lineNumber, position.lineNumber,
@ -467,11 +473,11 @@ export class SuggestAdapter
} }
public async resolveCompletionItem( public async resolveCompletionItem(
model: monaco.editor.ITextModel, model: editor.ITextModel,
_position: Position, _position: Position,
item: monaco.languages.CompletionItem, item: languages.CompletionItem,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.CompletionItem> { ): Promise<languages.CompletionItem> {
const myItem = <MyCompletionItem>item; const myItem = <MyCompletionItem>item;
const resource = myItem.uri; const resource = myItem.uri;
const position = myItem.position; const position = myItem.position;
@ -498,52 +504,50 @@ export class SuggestAdapter
}; };
} }
private static convertKind( private static convertKind(kind: string): languages.CompletionItemKind {
kind: string
): monaco.languages.CompletionItemKind {
switch (kind) { switch (kind) {
case Kind.primitiveType: case Kind.primitiveType:
case Kind.keyword: case Kind.keyword:
return monaco.languages.CompletionItemKind.Keyword; return languages.CompletionItemKind.Keyword;
case Kind.variable: case Kind.variable:
case Kind.localVariable: case Kind.localVariable:
return monaco.languages.CompletionItemKind.Variable; return languages.CompletionItemKind.Variable;
case Kind.memberVariable: case Kind.memberVariable:
case Kind.memberGetAccessor: case Kind.memberGetAccessor:
case Kind.memberSetAccessor: case Kind.memberSetAccessor:
return monaco.languages.CompletionItemKind.Field; return languages.CompletionItemKind.Field;
case Kind.function: case Kind.function:
case Kind.memberFunction: case Kind.memberFunction:
case Kind.constructSignature: case Kind.constructSignature:
case Kind.callSignature: case Kind.callSignature:
case Kind.indexSignature: case Kind.indexSignature:
return monaco.languages.CompletionItemKind.Function; return languages.CompletionItemKind.Function;
case Kind.enum: case Kind.enum:
return monaco.languages.CompletionItemKind.Enum; return languages.CompletionItemKind.Enum;
case Kind.module: case Kind.module:
return monaco.languages.CompletionItemKind.Module; return languages.CompletionItemKind.Module;
case Kind.class: case Kind.class:
return monaco.languages.CompletionItemKind.Class; return languages.CompletionItemKind.Class;
case Kind.interface: case Kind.interface:
return monaco.languages.CompletionItemKind.Interface; return languages.CompletionItemKind.Interface;
case Kind.warning: case Kind.warning:
return monaco.languages.CompletionItemKind.File; return languages.CompletionItemKind.File;
} }
return monaco.languages.CompletionItemKind.Property; return languages.CompletionItemKind.Property;
} }
} }
export class SignatureHelpAdapter export class SignatureHelpAdapter
extends Adapter extends Adapter
implements monaco.languages.SignatureHelpProvider { implements languages.SignatureHelpProvider {
public signatureHelpTriggerCharacters = ['(', ',']; public signatureHelpTriggerCharacters = ['(', ','];
public async provideSignatureHelp( public async provideSignatureHelp(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.SignatureHelpResult | undefined> { ): Promise<languages.SignatureHelpResult | undefined> {
const resource = model.uri; const resource = model.uri;
const offset = model.getOffsetAt(position); const offset = model.getOffsetAt(position);
const worker = await this._worker(resource); const worker = await this._worker(resource);
@ -556,14 +560,14 @@ export class SignatureHelpAdapter
return; return;
} }
const ret: monaco.languages.SignatureHelp = { const ret: languages.SignatureHelp = {
activeSignature: info.selectedItemIndex, activeSignature: info.selectedItemIndex,
activeParameter: info.argumentIndex, activeParameter: info.argumentIndex,
signatures: [] signatures: []
}; };
info.items.forEach((item) => { info.items.forEach((item) => {
const signature: monaco.languages.SignatureInformation = { const signature: languages.SignatureInformation = {
label: '', label: '',
parameters: [] parameters: []
}; };
@ -574,7 +578,7 @@ export class SignatureHelpAdapter
signature.label += displayPartsToString(item.prefixDisplayParts); signature.label += displayPartsToString(item.prefixDisplayParts);
item.parameters.forEach((p, i, a) => { item.parameters.forEach((p, i, a) => {
const label = displayPartsToString(p.displayParts); const label = displayPartsToString(p.displayParts);
const parameter: monaco.languages.ParameterInformation = { const parameter: languages.ParameterInformation = {
label: label, label: label,
documentation: { documentation: {
value: displayPartsToString(p.documentation) value: displayPartsToString(p.documentation)
@ -601,12 +605,12 @@ export class SignatureHelpAdapter
export class QuickInfoAdapter export class QuickInfoAdapter
extends Adapter extends Adapter
implements monaco.languages.HoverProvider { implements languages.HoverProvider {
public async provideHover( public async provideHover(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.Hover | undefined> { ): Promise<languages.Hover | undefined> {
const resource = model.uri; const resource = model.uri;
const offset = model.getOffsetAt(position); const offset = model.getOffsetAt(position);
const worker = await this._worker(resource); const worker = await this._worker(resource);
@ -653,12 +657,12 @@ export class QuickInfoAdapter
export class OccurrencesAdapter export class OccurrencesAdapter
extends Adapter extends Adapter
implements monaco.languages.DocumentHighlightProvider { implements languages.DocumentHighlightProvider {
public async provideDocumentHighlights( public async provideDocumentHighlights(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.DocumentHighlight[] | undefined> { ): Promise<languages.DocumentHighlight[] | undefined> {
const resource = model.uri; const resource = model.uri;
const offset = model.getOffsetAt(position); const offset = model.getOffsetAt(position);
const worker = await this._worker(resource); const worker = await this._worker(resource);
@ -672,11 +676,11 @@ export class OccurrencesAdapter
} }
return entries.map((entry) => { return entries.map((entry) => {
return <monaco.languages.DocumentHighlight>{ return <languages.DocumentHighlight>{
range: this._textSpanToRange(model, entry.textSpan), range: this._textSpanToRange(model, entry.textSpan),
kind: entry.isWriteAccess kind: entry.isWriteAccess
? monaco.languages.DocumentHighlightKind.Write ? languages.DocumentHighlightKind.Write
: monaco.languages.DocumentHighlightKind.Text : languages.DocumentHighlightKind.Text
}; };
}); });
} }
@ -693,10 +697,10 @@ export class DefinitionAdapter extends Adapter {
} }
public async provideDefinition( public async provideDefinition(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.Definition | undefined> { ): Promise<languages.Definition | undefined> {
const resource = model.uri; const resource = model.uri;
const offset = model.getOffsetAt(position); const offset = model.getOffsetAt(position);
const worker = await this._worker(resource); const worker = await this._worker(resource);
@ -718,7 +722,7 @@ export class DefinitionAdapter extends Adapter {
return; return;
} }
const result: monaco.languages.Location[] = []; const result: languages.Location[] = [];
for (let entry of entries) { for (let entry of entries) {
const uri = Uri.parse(entry.fileName); const uri = Uri.parse(entry.fileName);
const refModel = this._libFiles.getOrCreateModel(uri); const refModel = this._libFiles.getOrCreateModel(uri);
@ -737,7 +741,7 @@ export class DefinitionAdapter extends Adapter {
export class ReferenceAdapter export class ReferenceAdapter
extends Adapter extends Adapter
implements monaco.languages.ReferenceProvider { implements languages.ReferenceProvider {
constructor( constructor(
private readonly _libFiles: LibFiles, private readonly _libFiles: LibFiles,
worker: (...uris: Uri[]) => Promise<TypeScriptWorker> worker: (...uris: Uri[]) => Promise<TypeScriptWorker>
@ -746,11 +750,11 @@ export class ReferenceAdapter
} }
public async provideReferences( public async provideReferences(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
context: monaco.languages.ReferenceContext, context: languages.ReferenceContext,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.Location[] | undefined> { ): Promise<languages.Location[] | undefined> {
const resource = model.uri; const resource = model.uri;
const offset = model.getOffsetAt(position); const offset = model.getOffsetAt(position);
const worker = await this._worker(resource); const worker = await this._worker(resource);
@ -772,7 +776,7 @@ export class ReferenceAdapter
return; return;
} }
const result: monaco.languages.Location[] = []; const result: languages.Location[] = [];
for (let entry of entries) { for (let entry of entries) {
const uri = Uri.parse(entry.fileName); const uri = Uri.parse(entry.fileName);
const refModel = this._libFiles.getOrCreateModel(uri); const refModel = this._libFiles.getOrCreateModel(uri);
@ -791,11 +795,11 @@ export class ReferenceAdapter
export class OutlineAdapter export class OutlineAdapter
extends Adapter extends Adapter
implements monaco.languages.DocumentSymbolProvider { implements languages.DocumentSymbolProvider {
public async provideDocumentSymbols( public async provideDocumentSymbols(
model: monaco.editor.ITextModel, model: editor.ITextModel,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.DocumentSymbol[] | undefined> { ): Promise<languages.DocumentSymbol[] | undefined> {
const resource = model.uri; const resource = model.uri;
const worker = await this._worker(resource); const worker = await this._worker(resource);
const items = await worker.getNavigationBarItems(resource.toString()); const items = await worker.getNavigationBarItems(resource.toString());
@ -805,15 +809,15 @@ export class OutlineAdapter
} }
const convert = ( const convert = (
bucket: monaco.languages.DocumentSymbol[], bucket: languages.DocumentSymbol[],
item: ts.NavigationBarItem, item: ts.NavigationBarItem,
containerLabel?: string containerLabel?: string
): void => { ): void => {
let result: monaco.languages.DocumentSymbol = { let result: languages.DocumentSymbol = {
name: item.text, name: item.text,
detail: '', detail: '',
kind: <monaco.languages.SymbolKind>( kind: <languages.SymbolKind>(
(outlineTypeTable[item.kind] || monaco.languages.SymbolKind.Variable) (outlineTypeTable[item.kind] || languages.SymbolKind.Variable)
), ),
range: this._textSpanToRange(model, item.spans[0]), range: this._textSpanToRange(model, item.spans[0]),
selectionRange: this._textSpanToRange(model, item.spans[0]), selectionRange: this._textSpanToRange(model, item.spans[0]),
@ -830,7 +834,7 @@ export class OutlineAdapter
bucket.push(result); bucket.push(result);
}; };
let result: monaco.languages.DocumentSymbol[] = []; let result: languages.DocumentSymbol[] = [];
items.forEach((item) => convert(result, item)); items.forEach((item) => convert(result, item));
return result; return result;
} }
@ -868,28 +872,28 @@ export class Kind {
} }
let outlineTypeTable: { let outlineTypeTable: {
[kind: string]: monaco.languages.SymbolKind; [kind: string]: languages.SymbolKind;
} = Object.create(null); } = Object.create(null);
outlineTypeTable[Kind.module] = monaco.languages.SymbolKind.Module; outlineTypeTable[Kind.module] = languages.SymbolKind.Module;
outlineTypeTable[Kind.class] = monaco.languages.SymbolKind.Class; outlineTypeTable[Kind.class] = languages.SymbolKind.Class;
outlineTypeTable[Kind.enum] = monaco.languages.SymbolKind.Enum; outlineTypeTable[Kind.enum] = languages.SymbolKind.Enum;
outlineTypeTable[Kind.interface] = monaco.languages.SymbolKind.Interface; outlineTypeTable[Kind.interface] = languages.SymbolKind.Interface;
outlineTypeTable[Kind.memberFunction] = monaco.languages.SymbolKind.Method; outlineTypeTable[Kind.memberFunction] = languages.SymbolKind.Method;
outlineTypeTable[Kind.memberVariable] = monaco.languages.SymbolKind.Property; outlineTypeTable[Kind.memberVariable] = languages.SymbolKind.Property;
outlineTypeTable[Kind.memberGetAccessor] = monaco.languages.SymbolKind.Property; outlineTypeTable[Kind.memberGetAccessor] = languages.SymbolKind.Property;
outlineTypeTable[Kind.memberSetAccessor] = monaco.languages.SymbolKind.Property; outlineTypeTable[Kind.memberSetAccessor] = languages.SymbolKind.Property;
outlineTypeTable[Kind.variable] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.variable] = languages.SymbolKind.Variable;
outlineTypeTable[Kind.const] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.const] = languages.SymbolKind.Variable;
outlineTypeTable[Kind.localVariable] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.localVariable] = languages.SymbolKind.Variable;
outlineTypeTable[Kind.variable] = monaco.languages.SymbolKind.Variable; outlineTypeTable[Kind.variable] = languages.SymbolKind.Variable;
outlineTypeTable[Kind.function] = monaco.languages.SymbolKind.Function; outlineTypeTable[Kind.function] = languages.SymbolKind.Function;
outlineTypeTable[Kind.localFunction] = monaco.languages.SymbolKind.Function; outlineTypeTable[Kind.localFunction] = languages.SymbolKind.Function;
// --- formatting ---- // --- formatting ----
export abstract class FormatHelper extends Adapter { export abstract class FormatHelper extends Adapter {
protected static _convertOptions( protected static _convertOptions(
options: monaco.languages.FormattingOptions options: languages.FormattingOptions
): ts.FormatCodeOptions { ): ts.FormatCodeOptions {
return { return {
ConvertTabsToSpaces: options.insertSpaces, ConvertTabsToSpaces: options.insertSpaces,
@ -911,9 +915,9 @@ export abstract class FormatHelper extends Adapter {
} }
protected _convertTextChanges( protected _convertTextChanges(
model: monaco.editor.ITextModel, model: editor.ITextModel,
change: ts.TextChange change: ts.TextChange
): monaco.languages.TextEdit { ): languages.TextEdit {
return { return {
text: change.newText, text: change.newText,
range: this._textSpanToRange(model, change.span) range: this._textSpanToRange(model, change.span)
@ -923,13 +927,13 @@ export abstract class FormatHelper extends Adapter {
export class FormatAdapter export class FormatAdapter
extends FormatHelper extends FormatHelper
implements monaco.languages.DocumentRangeFormattingEditProvider { implements languages.DocumentRangeFormattingEditProvider {
public async provideDocumentRangeFormattingEdits( public async provideDocumentRangeFormattingEdits(
model: monaco.editor.ITextModel, model: editor.ITextModel,
range: Range, range: Range,
options: monaco.languages.FormattingOptions, options: languages.FormattingOptions,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.TextEdit[] | undefined> { ): Promise<languages.TextEdit[] | undefined> {
const resource = model.uri; const resource = model.uri;
const startOffset = model.getOffsetAt({ const startOffset = model.getOffsetAt({
lineNumber: range.startLineNumber, lineNumber: range.startLineNumber,
@ -957,18 +961,18 @@ export class FormatAdapter
export class FormatOnTypeAdapter export class FormatOnTypeAdapter
extends FormatHelper extends FormatHelper
implements monaco.languages.OnTypeFormattingEditProvider { implements languages.OnTypeFormattingEditProvider {
get autoFormatTriggerCharacters() { get autoFormatTriggerCharacters() {
return [';', '}', '\n']; return [';', '}', '\n'];
} }
public async provideOnTypeFormattingEdits( public async provideOnTypeFormattingEdits(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
ch: string, ch: string,
options: monaco.languages.FormattingOptions, options: languages.FormattingOptions,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.TextEdit[] | undefined> { ): Promise<languages.TextEdit[] | undefined> {
const resource = model.uri; const resource = model.uri;
const offset = model.getOffsetAt(position); const offset = model.getOffsetAt(position);
const worker = await this._worker(resource); const worker = await this._worker(resource);
@ -991,13 +995,13 @@ export class FormatOnTypeAdapter
export class CodeActionAdaptor export class CodeActionAdaptor
extends FormatHelper extends FormatHelper
implements monaco.languages.CodeActionProvider { implements languages.CodeActionProvider {
public async provideCodeActions( public async provideCodeActions(
model: monaco.editor.ITextModel, model: editor.ITextModel,
range: Range, range: Range,
context: monaco.languages.CodeActionContext, context: languages.CodeActionContext,
token: CancellationToken token: CancellationToken
): Promise<monaco.languages.CodeActionList> { ): Promise<languages.CodeActionList> {
const resource = model.uri; const resource = model.uri;
const start = model.getOffsetAt({ const start = model.getOffsetAt({
lineNumber: range.startLineNumber, lineNumber: range.startLineNumber,
@ -1041,11 +1045,11 @@ export class CodeActionAdaptor
} }
private _tsCodeFixActionToMonacoCodeAction( private _tsCodeFixActionToMonacoCodeAction(
model: monaco.editor.ITextModel, model: editor.ITextModel,
context: monaco.languages.CodeActionContext, context: languages.CodeActionContext,
codeFix: ts.CodeFixAction codeFix: ts.CodeFixAction
): monaco.languages.CodeAction { ): languages.CodeAction {
const edits: monaco.languages.WorkspaceTextEdit[] = []; const edits: languages.WorkspaceTextEdit[] = [];
for (const change of codeFix.changes) { for (const change of codeFix.changes) {
for (const textChange of change.textChanges) { for (const textChange of change.textChanges) {
edits.push({ edits.push({
@ -1058,7 +1062,7 @@ export class CodeActionAdaptor
} }
} }
const action: monaco.languages.CodeAction = { const action: languages.CodeAction = {
title: codeFix.description, title: codeFix.description,
edit: { edits: edits }, edit: { edits: edits },
diagnostics: context.markers, diagnostics: context.markers,
@ -1070,17 +1074,13 @@ export class CodeActionAdaptor
} }
// --- rename ---- // --- rename ----
export class RenameAdapter export class RenameAdapter extends Adapter implements languages.RenameProvider {
extends Adapter
implements monaco.languages.RenameProvider {
public async provideRenameEdits( public async provideRenameEdits(
model: monaco.editor.ITextModel, model: editor.ITextModel,
position: Position, position: Position,
newName: string, newName: string,
token: CancellationToken token: CancellationToken
): Promise< ): Promise<(languages.WorkspaceEdit & languages.Rejection) | undefined> {
(monaco.languages.WorkspaceEdit & monaco.languages.Rejection) | undefined
> {
const resource = model.uri; const resource = model.uri;
const fileName = resource.toString(); const fileName = resource.toString();
const offset = model.getOffsetAt(position); const offset = model.getOffsetAt(position);
@ -1112,10 +1112,10 @@ export class RenameAdapter
return; return;
} }
const edits: monaco.languages.WorkspaceTextEdit[] = []; const edits: languages.WorkspaceTextEdit[] = [];
for (const renameLocation of renameLocations) { for (const renameLocation of renameLocations) {
edits.push({ edits.push({
resource: monaco.Uri.parse(renameLocation.fileName), resource: Uri.parse(renameLocation.fileName),
edit: { edit: {
range: this._textSpanToRange(model, renameLocation.textSpan), range: this._textSpanToRange(model, renameLocation.textSpan),
text: newName text: newName

View file

@ -4,5 +4,5 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
declare module 'monaco-editor-core/esm/vs/editor/editor.worker' { declare module 'monaco-editor-core/esm/vs/editor/editor.worker' {
export function initialize(callback: (ctx: monaco.worker.IWorkerContext, createData: any) => any): void; export function initialize(callback: (ctx: any, createData: any) => any): void;
} }

View file

@ -4,16 +4,171 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import * as mode from './tsMode'; import type * as mode from './tsMode';
import { typescriptVersion } from './lib/typescriptServicesMetadata'; // do not import the whole typescriptServices here import { typescriptVersion as tsversion } from './lib/typescriptServicesMetadata'; // do not import the whole typescriptServices here
import {
languages,
Emitter,
IEvent,
IDisposable,
Uri
} from './fillers/monaco-editor-core';
import Emitter = monaco.Emitter; //#region enums copied from typescript to prevent loading the entire typescriptServices ---
import IEvent = monaco.IEvent;
import IDisposable = monaco.IDisposable;
// --- TypeScript configuration and defaults --------- export enum ModuleKind {
None = 0,
CommonJS = 1,
AMD = 2,
UMD = 3,
System = 4,
ES2015 = 5,
ESNext = 99
}
export interface IExtraLib { export enum JsxEmit {
None = 0,
Preserve = 1,
React = 2,
ReactNative = 3
}
export enum NewLineKind {
CarriageReturnLineFeed = 0,
LineFeed = 1
}
export enum ScriptTarget {
ES3 = 0,
ES5 = 1,
ES2015 = 2,
ES2016 = 3,
ES2017 = 4,
ES2018 = 5,
ES2019 = 6,
ES2020 = 7,
ESNext = 99,
JSON = 100,
Latest = ESNext
}
export enum ModuleResolutionKind {
Classic = 1,
NodeJs = 2
}
//#endregion
interface MapLike<T> {
[index: string]: T;
}
type CompilerOptionsValue =
| string
| number
| boolean
| (string | number)[]
| string[]
| MapLike<string[]>
| null
| undefined;
interface CompilerOptions {
allowJs?: boolean;
allowSyntheticDefaultImports?: boolean;
allowUmdGlobalAccess?: boolean;
allowUnreachableCode?: boolean;
allowUnusedLabels?: boolean;
alwaysStrict?: boolean;
baseUrl?: string;
charset?: string;
checkJs?: boolean;
declaration?: boolean;
declarationMap?: boolean;
emitDeclarationOnly?: boolean;
declarationDir?: string;
disableSizeLimit?: boolean;
disableSourceOfProjectReferenceRedirect?: boolean;
downlevelIteration?: boolean;
emitBOM?: boolean;
emitDecoratorMetadata?: boolean;
experimentalDecorators?: boolean;
forceConsistentCasingInFileNames?: boolean;
importHelpers?: boolean;
inlineSourceMap?: boolean;
inlineSources?: boolean;
isolatedModules?: boolean;
jsx?: JsxEmit;
keyofStringsOnly?: boolean;
lib?: string[];
locale?: string;
mapRoot?: string;
maxNodeModuleJsDepth?: number;
module?: ModuleKind;
moduleResolution?: ModuleResolutionKind;
newLine?: NewLineKind;
noEmit?: boolean;
noEmitHelpers?: boolean;
noEmitOnError?: boolean;
noErrorTruncation?: boolean;
noFallthroughCasesInSwitch?: boolean;
noImplicitAny?: boolean;
noImplicitReturns?: boolean;
noImplicitThis?: boolean;
noStrictGenericChecks?: boolean;
noUnusedLocals?: boolean;
noUnusedParameters?: boolean;
noImplicitUseStrict?: boolean;
noLib?: boolean;
noResolve?: boolean;
out?: string;
outDir?: string;
outFile?: string;
paths?: MapLike<string[]>;
preserveConstEnums?: boolean;
preserveSymlinks?: boolean;
project?: string;
reactNamespace?: string;
jsxFactory?: string;
composite?: boolean;
removeComments?: boolean;
rootDir?: string;
rootDirs?: string[];
skipLibCheck?: boolean;
skipDefaultLibCheck?: boolean;
sourceMap?: boolean;
sourceRoot?: string;
strict?: boolean;
strictFunctionTypes?: boolean;
strictBindCallApply?: boolean;
strictNullChecks?: boolean;
strictPropertyInitialization?: boolean;
stripInternal?: boolean;
suppressExcessPropertyErrors?: boolean;
suppressImplicitAnyIndexErrors?: boolean;
target?: ScriptTarget;
traceResolution?: boolean;
resolveJsonModule?: boolean;
types?: string[];
/** Paths used to compute primary types search locations */
typeRoots?: string[];
esModuleInterop?: boolean;
useDefineForClassFields?: boolean;
[option: string]: CompilerOptionsValue | undefined;
}
export interface DiagnosticsOptions {
noSemanticValidation?: boolean;
noSyntaxValidation?: boolean;
noSuggestionDiagnostics?: boolean;
diagnosticCodesToIgnore?: number[];
}
export interface WorkerOptions {
/** A full HTTP path to a JavaScript file which adds a function `customTSWorkerFactory` to the self inside a web-worker */
customWorkerPath?: string;
}
interface IExtraLib {
content: string; content: string;
version: number; version: number;
} }
@ -22,22 +177,305 @@ export interface IExtraLibs {
[path: string]: IExtraLib; [path: string]: IExtraLib;
} }
export class LanguageServiceDefaultsImpl /**
implements monaco.languages.typescript.LanguageServiceDefaults { * A linked list of formatted diagnostic messages to be used as part of a multiline message.
* It is built from the bottom up, leaving the head to be the "main" diagnostic.
*/
interface DiagnosticMessageChain {
messageText: string;
/** Diagnostic category: warning = 0, error = 1, suggestion = 2, message = 3 */
category: 0 | 1 | 2 | 3;
code: number;
next?: DiagnosticMessageChain[];
}
export interface Diagnostic extends DiagnosticRelatedInformation {
/** May store more in future. For now, this will simply be `true` to indicate when a diagnostic is an unused-identifier diagnostic. */
reportsUnnecessary?: {};
source?: string;
relatedInformation?: DiagnosticRelatedInformation[];
}
interface DiagnosticRelatedInformation {
/** Diagnostic category: warning = 0, error = 1, suggestion = 2, message = 3 */
category: 0 | 1 | 2 | 3;
code: number;
/** TypeScriptWorker removes this to avoid serializing circular JSON structures. */
file: undefined;
start: number | undefined;
length: number | undefined;
messageText: string | DiagnosticMessageChain;
}
interface EmitOutput {
outputFiles: OutputFile[];
emitSkipped: boolean;
}
interface OutputFile {
name: string;
writeByteOrderMark: boolean;
text: string;
}
export interface LanguageServiceDefaults {
/**
* Event fired when compiler options or diagnostics options are changed.
*/
readonly onDidChange: IEvent<void>;
/**
* Event fired when extra libraries registered with the language service change.
*/
readonly onDidExtraLibsChange: IEvent<void>;
readonly workerOptions: WorkerOptions;
/**
* Get the current extra libs registered with the language service.
*/
getExtraLibs(): IExtraLibs;
/**
* Add an additional source file to the language service. Use this
* for typescript (definition) files that won't be loaded as editor
* 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 disposal.
*/
addExtraLib(content: string, filePath?: string): IDisposable;
/**
* 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.
*/
setExtraLibs(libs: { content: string; filePath?: string }[]): void;
/**
* Get current TypeScript compiler options for the language service.
*/
getCompilerOptions(): CompilerOptions;
/**
* Set TypeScript compiler options.
*/
setCompilerOptions(options: CompilerOptions): void;
/**
* Get the current diagnostics options for the language service.
*/
getDiagnosticsOptions(): DiagnosticsOptions;
/**
* Configure whether syntactic and/or semantic validation should
* be performed
*/
setDiagnosticsOptions(options: DiagnosticsOptions): void;
/**
* No-op.
*/
setMaximumWorkerIdleTime(value: number): void;
/**
* Configure if all existing models should be eagerly sync'd
* to the worker on start or restart.
*/
setEagerModelSync(value: boolean): void;
/**
* Get the current setting for whether all existing models should be eagerly sync'd
* to the worker on start or restart.
*/
getEagerModelSync(): boolean;
}
export interface TypeScriptWorker {
/**
* Get diagnostic messages for any syntax issues in the given file.
*/
getSyntacticDiagnostics(fileName: string): Promise<Diagnostic[]>;
/**
* Get diagnostic messages for any semantic issues in the given file.
*/
getSemanticDiagnostics(fileName: string): Promise<Diagnostic[]>;
/**
* Get diagnostic messages for any suggestions related to the given file.
*/
getSuggestionDiagnostics(fileName: string): Promise<Diagnostic[]>;
/**
* Get the content of a given file.
*/
getScriptText(fileName: string): Promise<string | undefined>;
/**
* Get diagnostic messages related to the current compiler options.
* @param fileName Not used
*/
getCompilerOptionsDiagnostics(fileName: string): Promise<Diagnostic[]>;
/**
* Get code completions for the given file and position.
* @returns `Promise<typescript.CompletionInfo | 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>;
/**
* 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>;
/**
* 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>;
/**
* 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>;
/**
* 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>;
/**
* 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>;
/**
* Get outline entries for the item at the given position in the file.
* @returns `Promise<typescript.NavigationBarItem[]>`
*/
getNavigationBarItems(fileName: string): Promise<any[]>;
/**
* Get changes which should be applied to format the given file.
* @param options `typescript.FormatCodeOptions`
* @returns `Promise<typescript.TextChange[]>`
*/
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[]>;
/**
* 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[]>;
/**
* 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>;
/**
* 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>;
/**
* Get transpiled output for the given file.
* @returns `typescript.EmitOutput`
*/
getEmitOutput(fileName: string): Promise<EmitOutput>;
/**
* Get possible code fixes at the given position in the file.
* @param formatOptions `typescript.FormatCodeOptions`
* @returns `Promise<ReadonlyArray<typescript.CodeFixAction>>`
*/
getCodeFixesAtPosition(
fileName: string,
start: number,
end: number,
errorCodes: number[],
formatOptions: any
): Promise<ReadonlyArray<any>>;
}
// --- TypeScript configuration and defaults ---------
class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
private _onDidChange = new Emitter<void>(); private _onDidChange = new Emitter<void>();
private _onDidExtraLibsChange = new Emitter<void>(); private _onDidExtraLibsChange = new Emitter<void>();
private _extraLibs: IExtraLibs; private _extraLibs: IExtraLibs;
private _eagerModelSync: boolean; private _eagerModelSync: boolean;
private _compilerOptions!: monaco.languages.typescript.CompilerOptions; private _compilerOptions!: CompilerOptions;
private _diagnosticsOptions!: monaco.languages.typescript.DiagnosticsOptions; private _diagnosticsOptions!: DiagnosticsOptions;
private _workerOptions!: monaco.languages.typescript.WorkerOptions; private _workerOptions!: WorkerOptions;
private _onDidExtraLibsChangeTimeout: number; private _onDidExtraLibsChangeTimeout: number;
constructor( constructor(
compilerOptions: monaco.languages.typescript.CompilerOptions, compilerOptions: CompilerOptions,
diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions, diagnosticsOptions: DiagnosticsOptions,
workerOptions: monaco.languages.typescript.WorkerOptions workerOptions: WorkerOptions
) { ) {
this._extraLibs = Object.create(null); this._extraLibs = Object.create(null);
this._eagerModelSync = false; this._eagerModelSync = false;
@ -55,7 +493,7 @@ export class LanguageServiceDefaultsImpl
return this._onDidExtraLibsChange.event; return this._onDidExtraLibsChange.event;
} }
get workerOptions(): monaco.languages.typescript.WorkerOptions { get workerOptions(): WorkerOptions {
return this._workerOptions; return this._workerOptions;
} }
@ -139,29 +577,25 @@ export class LanguageServiceDefaultsImpl
}, 0); }, 0);
} }
getCompilerOptions(): monaco.languages.typescript.CompilerOptions { getCompilerOptions(): CompilerOptions {
return this._compilerOptions; return this._compilerOptions;
} }
setCompilerOptions( setCompilerOptions(options: CompilerOptions): void {
options: monaco.languages.typescript.CompilerOptions
): void {
this._compilerOptions = options || Object.create(null); this._compilerOptions = options || Object.create(null);
this._onDidChange.fire(undefined); this._onDidChange.fire(undefined);
} }
getDiagnosticsOptions(): monaco.languages.typescript.DiagnosticsOptions { getDiagnosticsOptions(): DiagnosticsOptions {
return this._diagnosticsOptions; return this._diagnosticsOptions;
} }
setDiagnosticsOptions( setDiagnosticsOptions(options: DiagnosticsOptions): void {
options: monaco.languages.typescript.DiagnosticsOptions
): void {
this._diagnosticsOptions = options || Object.create(null); this._diagnosticsOptions = options || Object.create(null);
this._onDidChange.fire(undefined); this._onDidChange.fire(undefined);
} }
setWorkerOptions(options: monaco.languages.typescript.WorkerOptions): void { setWorkerOptions(options: WorkerOptions): void {
this._workerOptions = options || Object.create(null); this._workerOptions = options || Object.create(null);
this._onDidChange.fire(undefined); this._onDidChange.fire(undefined);
} }
@ -179,94 +613,45 @@ export class LanguageServiceDefaultsImpl
} }
} }
//#region enums copied from typescript to prevent loading the entire typescriptServices --- export const typescriptVersion: string = tsversion;
enum ModuleKind { export const typescriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
None = 0,
CommonJS = 1,
AMD = 2,
UMD = 3,
System = 4,
ES2015 = 5,
ESNext = 99
}
enum JsxEmit {
None = 0,
Preserve = 1,
React = 2,
ReactNative = 3
}
enum NewLineKind {
CarriageReturnLineFeed = 0,
LineFeed = 1
}
enum ScriptTarget {
ES3 = 0,
ES5 = 1,
ES2015 = 2,
ES2016 = 3,
ES2017 = 4,
ES2018 = 5,
ES2019 = 6,
ES2020 = 7,
ESNext = 99,
JSON = 100,
Latest = ESNext
}
enum ModuleResolutionKind {
Classic = 1,
NodeJs = 2
}
//#endregion
const typescriptDefaults = new LanguageServiceDefaultsImpl(
{ allowNonTsExtensions: true, target: ScriptTarget.Latest }, { allowNonTsExtensions: true, target: ScriptTarget.Latest },
{ noSemanticValidation: false, noSyntaxValidation: false }, { noSemanticValidation: false, noSyntaxValidation: false },
{} {}
); );
const javascriptDefaults = new LanguageServiceDefaultsImpl( export const javascriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest }, { allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
{ noSemanticValidation: true, noSyntaxValidation: false }, { noSemanticValidation: true, noSyntaxValidation: false },
{} {}
); );
function getTypeScriptWorker(): Promise< export const getTypeScriptWorker = (): Promise<
( (...uris: Uri[]) => Promise<TypeScriptWorker>
...uris: monaco.Uri[] > => {
) => Promise<monaco.languages.typescript.TypeScriptWorker>
> {
return getMode().then((mode) => mode.getTypeScriptWorker()); return getMode().then((mode) => mode.getTypeScriptWorker());
}
function getJavaScriptWorker(): Promise<
(
...uris: monaco.Uri[]
) => Promise<monaco.languages.typescript.TypeScriptWorker>
> {
return getMode().then((mode) => mode.getJavaScriptWorker());
}
// Export API
function createAPI(): typeof monaco.languages.typescript {
return {
ModuleKind: ModuleKind,
JsxEmit: JsxEmit,
NewLineKind: NewLineKind,
ScriptTarget: ScriptTarget,
ModuleResolutionKind: ModuleResolutionKind,
typescriptVersion,
typescriptDefaults: typescriptDefaults,
javascriptDefaults: javascriptDefaults,
getTypeScriptWorker: getTypeScriptWorker,
getJavaScriptWorker: getJavaScriptWorker
}; };
}
monaco.languages.typescript = createAPI(); export const getJavaScriptWorker = (): Promise<
(...uris: Uri[]) => Promise<TypeScriptWorker>
> => {
return getMode().then((mode) => mode.getJavaScriptWorker());
};
// export to the global based API
(<any>languages).typescript = {
ModuleKind,
JsxEmit,
NewLineKind,
ScriptTarget,
ModuleResolutionKind,
typescriptVersion,
typescriptDefaults,
javascriptDefaults,
getTypeScriptWorker,
getJavaScriptWorker
};
// --- Registration to monaco editor --- // --- Registration to monaco editor ---
@ -274,9 +659,9 @@ function getMode(): Promise<typeof mode> {
return import('./tsMode'); return import('./tsMode');
} }
monaco.languages.onLanguage('typescript', () => { languages.onLanguage('typescript', () => {
return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults)); return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
}); });
monaco.languages.onLanguage('javascript', () => { languages.onLanguage('javascript', () => {
return getMode().then((mode) => mode.setupJavaScript(javascriptDefaults)); return getMode().then((mode) => mode.setupJavaScript(javascriptDefaults));
}); });

View file

@ -4,14 +4,13 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import * as worker from 'monaco-editor-core/esm/vs/editor/editor.worker'; import * as edworker from 'monaco-editor-core/esm/vs/editor/editor.worker';
import { TypeScriptWorker, ICreateData } from './tsWorker'; import { TypeScriptWorker, ICreateData } from './tsWorker';
import { worker } from './fillers/monaco-editor-core';
self.onmessage = () => { self.onmessage = () => {
// ignore the first message // ignore the first message
worker.initialize( edworker.initialize((ctx: worker.IWorkerContext, createData: ICreateData) => {
(ctx: monaco.worker.IWorkerContext, createData: ICreateData) => {
return new TypeScriptWorker(ctx, createData); return new TypeScriptWorker(ctx, createData);
} });
);
}; };

View file

@ -5,20 +5,19 @@
'use strict'; 'use strict';
import { WorkerManager } from './workerManager'; import { WorkerManager } from './workerManager';
import { TypeScriptWorker } from './tsWorker'; import type { TypeScriptWorker } from './tsWorker';
import { LanguageServiceDefaultsImpl } from './monaco.contribution'; import { LanguageServiceDefaults } from './monaco.contribution';
import * as languageFeatures from './languageFeatures'; import * as languageFeatures from './languageFeatures';
import { languages, Uri } from './fillers/monaco-editor-core';
import Uri = monaco.Uri;
let javaScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>; let javaScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
let typeScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>; let typeScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
export function setupTypeScript(defaults: LanguageServiceDefaultsImpl): void { export function setupTypeScript(defaults: LanguageServiceDefaults): void {
typeScriptWorker = setupMode(defaults, 'typescript'); typeScriptWorker = setupMode(defaults, 'typescript');
} }
export function setupJavaScript(defaults: LanguageServiceDefaultsImpl): void { export function setupJavaScript(defaults: LanguageServiceDefaults): void {
javaScriptWorker = setupMode(defaults, 'javascript'); javaScriptWorker = setupMode(defaults, 'javascript');
} }
@ -47,7 +46,7 @@ export function getTypeScriptWorker(): Promise<
} }
function setupMode( function setupMode(
defaults: LanguageServiceDefaultsImpl, defaults: LanguageServiceDefaults,
modeId: string modeId: string
): (...uris: Uri[]) => Promise<TypeScriptWorker> { ): (...uris: Uri[]) => Promise<TypeScriptWorker> {
const client = new WorkerManager(modeId, defaults); const client = new WorkerManager(modeId, defaults);
@ -57,47 +56,47 @@ function setupMode(
const libFiles = new languageFeatures.LibFiles(worker); const libFiles = new languageFeatures.LibFiles(worker);
monaco.languages.registerCompletionItemProvider( languages.registerCompletionItemProvider(
modeId, modeId,
new languageFeatures.SuggestAdapter(worker) new languageFeatures.SuggestAdapter(worker)
); );
monaco.languages.registerSignatureHelpProvider( languages.registerSignatureHelpProvider(
modeId, modeId,
new languageFeatures.SignatureHelpAdapter(worker) new languageFeatures.SignatureHelpAdapter(worker)
); );
monaco.languages.registerHoverProvider( languages.registerHoverProvider(
modeId, modeId,
new languageFeatures.QuickInfoAdapter(worker) new languageFeatures.QuickInfoAdapter(worker)
); );
monaco.languages.registerDocumentHighlightProvider( languages.registerDocumentHighlightProvider(
modeId, modeId,
new languageFeatures.OccurrencesAdapter(worker) new languageFeatures.OccurrencesAdapter(worker)
); );
monaco.languages.registerDefinitionProvider( languages.registerDefinitionProvider(
modeId, modeId,
new languageFeatures.DefinitionAdapter(libFiles, worker) new languageFeatures.DefinitionAdapter(libFiles, worker)
); );
monaco.languages.registerReferenceProvider( languages.registerReferenceProvider(
modeId, modeId,
new languageFeatures.ReferenceAdapter(libFiles, worker) new languageFeatures.ReferenceAdapter(libFiles, worker)
); );
monaco.languages.registerDocumentSymbolProvider( languages.registerDocumentSymbolProvider(
modeId, modeId,
new languageFeatures.OutlineAdapter(worker) new languageFeatures.OutlineAdapter(worker)
); );
monaco.languages.registerDocumentRangeFormattingEditProvider( languages.registerDocumentRangeFormattingEditProvider(
modeId, modeId,
new languageFeatures.FormatAdapter(worker) new languageFeatures.FormatAdapter(worker)
); );
monaco.languages.registerOnTypeFormattingEditProvider( languages.registerOnTypeFormattingEditProvider(
modeId, modeId,
new languageFeatures.FormatOnTypeAdapter(worker) new languageFeatures.FormatOnTypeAdapter(worker)
); );
monaco.languages.registerCodeActionProvider( languages.registerCodeActionProvider(
modeId, modeId,
new languageFeatures.CodeActionAdaptor(worker) new languageFeatures.CodeActionAdaptor(worker)
); );
monaco.languages.registerRenameProvider( languages.registerRenameProvider(
modeId, modeId,
new languageFeatures.RenameAdapter(worker) new languageFeatures.RenameAdapter(worker)
); );

View file

@ -6,22 +6,23 @@
import * as ts from './lib/typescriptServices'; import * as ts from './lib/typescriptServices';
import { libFileMap } from './lib/lib'; import { libFileMap } from './lib/lib';
import { IExtraLibs } from './monaco.contribution'; import {
Diagnostic,
import IWorkerContext = monaco.worker.IWorkerContext; IExtraLibs,
TypeScriptWorker as ITypeScriptWorker
} from './monaco.contribution';
import { worker } from './fillers/monaco-editor-core';
export class TypeScriptWorker export class TypeScriptWorker
implements implements ts.LanguageServiceHost, ITypeScriptWorker {
ts.LanguageServiceHost,
monaco.languages.typescript.TypeScriptWorker {
// --- model sync ----------------------- // --- model sync -----------------------
private _ctx: IWorkerContext; private _ctx: worker.IWorkerContext;
private _extraLibs: IExtraLibs = Object.create(null); private _extraLibs: IExtraLibs = Object.create(null);
private _languageService = ts.createLanguageService(this); private _languageService = ts.createLanguageService(this);
private _compilerOptions: ts.CompilerOptions; private _compilerOptions: ts.CompilerOptions;
constructor(ctx: IWorkerContext, createData: ICreateData) { constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
this._ctx = ctx; this._ctx = ctx;
this._compilerOptions = createData.compilerOptions; this._compilerOptions = createData.compilerOptions;
this._extraLibs = createData.extraLibs; this._extraLibs = createData.extraLibs;
@ -40,7 +41,7 @@ export class TypeScriptWorker
return models.concat(Object.keys(this._extraLibs)); return models.concat(Object.keys(this._extraLibs));
} }
private _getModel(fileName: string): monaco.worker.IMirrorModel | null { private _getModel(fileName: string): worker.IMirrorModel | null {
let models = this._ctx.getMirrorModels(); let models = this._ctx.getMirrorModels();
for (let i = 0; i < models.length; i++) { for (let i = 0; i < models.length; i++) {
if (models[i].uri.toString() === fileName) { if (models[i].uri.toString() === fileName) {
@ -159,9 +160,7 @@ export class TypeScriptWorker
// --- language features // --- language features
private static clearFiles( private static clearFiles(diagnostics: ts.Diagnostic[]): Diagnostic[] {
diagnostics: ts.Diagnostic[]
): monaco.languages.typescript.Diagnostic[] {
// Clear the `file` field, which cannot be JSON'yfied because it // Clear the `file` field, which cannot be JSON'yfied because it
// contains cyclic data structures. // contains cyclic data structures.
diagnostics.forEach((diag) => { diagnostics.forEach((diag) => {
@ -171,35 +170,27 @@ export class TypeScriptWorker
related.forEach((diag2) => (diag2.file = undefined)); related.forEach((diag2) => (diag2.file = undefined));
} }
}); });
return <monaco.languages.typescript.Diagnostic[]>diagnostics; return <Diagnostic[]>diagnostics;
} }
getSyntacticDiagnostics( getSyntacticDiagnostics(fileName: string): Promise<Diagnostic[]> {
fileName: string
): Promise<monaco.languages.typescript.Diagnostic[]> {
const diagnostics = this._languageService.getSyntacticDiagnostics(fileName); const diagnostics = this._languageService.getSyntacticDiagnostics(fileName);
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics)); return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
} }
getSemanticDiagnostics( getSemanticDiagnostics(fileName: string): Promise<Diagnostic[]> {
fileName: string
): Promise<monaco.languages.typescript.Diagnostic[]> {
const diagnostics = this._languageService.getSemanticDiagnostics(fileName); const diagnostics = this._languageService.getSemanticDiagnostics(fileName);
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics)); return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
} }
getSuggestionDiagnostics( getSuggestionDiagnostics(fileName: string): Promise<Diagnostic[]> {
fileName: string
): Promise<monaco.languages.typescript.Diagnostic[]> {
const diagnostics = this._languageService.getSuggestionDiagnostics( const diagnostics = this._languageService.getSuggestionDiagnostics(
fileName fileName
); );
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics)); return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
} }
getCompilerOptionsDiagnostics( getCompilerOptionsDiagnostics(fileName: string): Promise<Diagnostic[]> {
fileName: string
): Promise<monaco.languages.typescript.Diagnostic[]> {
const diagnostics = this._languageService.getCompilerOptionsDiagnostics(); const diagnostics = this._languageService.getCompilerOptionsDiagnostics();
return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics)); return Promise.resolve(TypeScriptWorker.clearFiles(diagnostics));
} }
@ -404,7 +395,7 @@ declare global {
} }
export function create( export function create(
ctx: IWorkerContext, ctx: worker.IWorkerContext,
createData: ICreateData createData: ICreateData
): TypeScriptWorker { ): TypeScriptWorker {
let TSWorkerClass = TypeScriptWorker; let TSWorkerClass = TypeScriptWorker;

View file

@ -2,7 +2,8 @@
"compilerOptions": { "compilerOptions": {
"module": "esnext", "module": "esnext",
"moduleResolution": "node", "moduleResolution": "node",
"outDir": "../release/esm", "outDir": "../out/esm",
"declaration": true,
"target": "es5", "target": "es5",
"lib": [ "lib": [
"dom", "dom",
@ -12,7 +13,5 @@
"es2015.promise" "es2015.promise"
], ],
"strict": true "strict": true
}, }
"include": ["**/*.ts"],
"files": ["../node_modules/monaco-editor-core/monaco.d.ts"]
} }

View file

@ -2,7 +2,8 @@
"compilerOptions": { "compilerOptions": {
"module": "amd", "module": "amd",
"moduleResolution": "node", "moduleResolution": "node",
"outDir": "../release/dev", "outDir": "../out/amd",
"declaration": true,
"target": "es5", "target": "es5",
"lib": [ "lib": [
"dom", "dom",
@ -12,7 +13,5 @@
"es2015.promise" "es2015.promise"
], ],
"strict": true "strict": true
}, }
"include": ["**/*.ts"],
"files": ["../node_modules/monaco-editor-core/monaco.d.ts"]
} }

View file

@ -4,23 +4,21 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
'use strict'; 'use strict';
import { LanguageServiceDefaultsImpl } from './monaco.contribution'; import { LanguageServiceDefaults } from './monaco.contribution';
import { TypeScriptWorker } from './tsWorker'; import type { TypeScriptWorker } from './tsWorker';
import { editor, Uri, IDisposable } from './fillers/monaco-editor-core';
import IDisposable = monaco.IDisposable;
import Uri = monaco.Uri;
export class WorkerManager { export class WorkerManager {
private _modeId: string; private _modeId: string;
private _defaults: LanguageServiceDefaultsImpl; private _defaults: LanguageServiceDefaults;
private _configChangeListener: IDisposable; private _configChangeListener: IDisposable;
private _updateExtraLibsToken: number; private _updateExtraLibsToken: number;
private _extraLibsChangeListener: IDisposable; private _extraLibsChangeListener: IDisposable;
private _worker: monaco.editor.MonacoWebWorker<TypeScriptWorker> | null; private _worker: editor.MonacoWebWorker<TypeScriptWorker> | null;
private _client: Promise<TypeScriptWorker> | null; private _client: Promise<TypeScriptWorker> | null;
constructor(modeId: string, defaults: LanguageServiceDefaultsImpl) { constructor(modeId: string, defaults: LanguageServiceDefaults) {
this._modeId = modeId; this._modeId = modeId;
this._defaults = defaults; this._defaults = defaults;
this._worker = null; this._worker = null;
@ -63,7 +61,7 @@ export class WorkerManager {
private _getClient(): Promise<TypeScriptWorker> { private _getClient(): Promise<TypeScriptWorker> {
if (!this._client) { if (!this._client) {
this._worker = monaco.editor.createWebWorker<TypeScriptWorker>({ this._worker = editor.createWebWorker<TypeScriptWorker>({
// module that exports the create() method and returns a `TypeScriptWorker` instance // module that exports the create() method and returns a `TypeScriptWorker` instance
moduleId: 'vs/language/typescript/tsWorker', moduleId: 'vs/language/typescript/tsWorker',
@ -85,7 +83,7 @@ export class WorkerManager {
p = p.then((worker) => { p = p.then((worker) => {
if (this._worker) { if (this._worker) {
return this._worker.withSyncedResources( return this._worker.withSyncedResources(
monaco.editor editor
.getModels() .getModels()
.filter((model) => model.getModeId() === this._modeId) .filter((model) => model.getModeId() === this._modeId)
.map((model) => model.uri) .map((model) => model.uri)

View file

@ -31,7 +31,9 @@
<script> <script>
var paths = { var paths = {
'vs/basic-languages': '../node_modules/monaco-languages/release/dev', 'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
'vs/language/typescript': '../release/dev', 'vs/language/typescript/fillers/monaco-editor-core':
'../out/amd/fillers/monaco-editor-core-amd',
'vs/language/typescript': '../out/amd',
vs: '../node_modules/monaco-editor-core/dev/vs' vs: '../node_modules/monaco-editor-core/dev/vs'
}; };
if (document.location.protocol === 'http:') { if (document.location.protocol === 'http:') {
@ -39,7 +41,7 @@
let testIndex = document.location.pathname.indexOf('/test/'); let testIndex = document.location.pathname.indexOf('/test/');
if (testIndex !== -1) { if (testIndex !== -1) {
let prefix = document.location.pathname.substr(0, testIndex); let prefix = document.location.pathname.substr(0, testIndex);
paths['vs/language/typescript'] = prefix + '/release/dev'; paths['vs/language/typescript'] = prefix + '/out/amd';
} }
} }
var require = { var require = {
@ -187,8 +189,16 @@
'vs/basic-languages/monaco.contribution', 'vs/basic-languages/monaco.contribution',
'vs/language/typescript/monaco.contribution' 'vs/language/typescript/monaco.contribution'
], () => { ], () => {
const dirname = (path) => {
const slashIndex = path.lastIndexOf('/');
if (slashIndex >= 0) {
return path.substring(0, slashIndex);
}
return path;
};
const customWorkerPath = `${dirname(location.href)}/custom-worker.js`;
monaco.languages.typescript.typescriptDefaults.setWorkerOptions({ monaco.languages.typescript.typescriptDefaults.setWorkerOptions({
customWorkerPath: 'http://localhost:5000/test/custom-worker.js' customWorkerPath: customWorkerPath
}); });
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: 99, target: 99,

View file

@ -29,7 +29,9 @@
<script> <script>
var paths = { var paths = {
'vs/basic-languages': '../node_modules/monaco-languages/release/dev', 'vs/basic-languages': '../node_modules/monaco-languages/release/dev',
'vs/language/typescript': '../release/dev', 'vs/language/typescript/fillers/monaco-editor-core':
'../out/amd/fillers/monaco-editor-core-amd',
'vs/language/typescript': '../out/amd',
vs: '../node_modules/monaco-editor-core/dev/vs' vs: '../node_modules/monaco-editor-core/dev/vs'
}; };
if (document.location.protocol === 'http:') { if (document.location.protocol === 'http:') {
@ -37,7 +39,7 @@
let testIndex = document.location.pathname.indexOf('/test/'); let testIndex = document.location.pathname.indexOf('/test/');
if (testIndex !== -1) { if (testIndex !== -1) {
let prefix = document.location.pathname.substr(0, testIndex); let prefix = document.location.pathname.substr(0, testIndex);
paths['vs/language/typescript'] = prefix + '/release/dev'; paths['vs/language/typescript'] = prefix + '/out/amd';
} }
} }
var require = { var require = {