Move typescript sources to /src/

This commit is contained in:
Alex Dima 2021-11-13 20:06:41 +01:00
parent c41a5ce8aa
commit 8b4f06b8c5
No known key found for this signature in database
GPG key ID: 39563C1504FDD0C9
24 changed files with 107 additions and 667 deletions

File diff suppressed because it is too large Load diff

8
src/typescript/lib/editor.worker.d.ts vendored Normal file
View file

@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'monaco-editor-core/esm/vs/editor/editor.worker' {
export function initialize(callback: (ctx: any, createData: any) => any): void;
}

View file

@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//
// **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
//
/** Contains all the lib files */
export const libFileSet: Record<string, boolean> = {}
libFileSet['lib.d.ts'] = true;
libFileSet['lib.dom.d.ts'] = true;
libFileSet['lib.dom.iterable.d.ts'] = true;
libFileSet['lib.es2015.collection.d.ts'] = true;
libFileSet['lib.es2015.core.d.ts'] = true;
libFileSet['lib.es2015.d.ts'] = true;
libFileSet['lib.es2015.generator.d.ts'] = true;
libFileSet['lib.es2015.iterable.d.ts'] = true;
libFileSet['lib.es2015.promise.d.ts'] = true;
libFileSet['lib.es2015.proxy.d.ts'] = true;
libFileSet['lib.es2015.reflect.d.ts'] = true;
libFileSet['lib.es2015.symbol.d.ts'] = true;
libFileSet['lib.es2015.symbol.wellknown.d.ts'] = true;
libFileSet['lib.es2016.array.include.d.ts'] = true;
libFileSet['lib.es2016.d.ts'] = true;
libFileSet['lib.es2016.full.d.ts'] = true;
libFileSet['lib.es2017.d.ts'] = true;
libFileSet['lib.es2017.full.d.ts'] = true;
libFileSet['lib.es2017.intl.d.ts'] = true;
libFileSet['lib.es2017.object.d.ts'] = true;
libFileSet['lib.es2017.sharedmemory.d.ts'] = true;
libFileSet['lib.es2017.string.d.ts'] = true;
libFileSet['lib.es2017.typedarrays.d.ts'] = true;
libFileSet['lib.es2018.asyncgenerator.d.ts'] = true;
libFileSet['lib.es2018.asynciterable.d.ts'] = true;
libFileSet['lib.es2018.d.ts'] = true;
libFileSet['lib.es2018.full.d.ts'] = true;
libFileSet['lib.es2018.intl.d.ts'] = true;
libFileSet['lib.es2018.promise.d.ts'] = true;
libFileSet['lib.es2018.regexp.d.ts'] = true;
libFileSet['lib.es2019.array.d.ts'] = true;
libFileSet['lib.es2019.d.ts'] = true;
libFileSet['lib.es2019.full.d.ts'] = true;
libFileSet['lib.es2019.object.d.ts'] = true;
libFileSet['lib.es2019.string.d.ts'] = true;
libFileSet['lib.es2019.symbol.d.ts'] = true;
libFileSet['lib.es2020.bigint.d.ts'] = true;
libFileSet['lib.es2020.d.ts'] = true;
libFileSet['lib.es2020.full.d.ts'] = true;
libFileSet['lib.es2020.intl.d.ts'] = true;
libFileSet['lib.es2020.promise.d.ts'] = true;
libFileSet['lib.es2020.sharedmemory.d.ts'] = true;
libFileSet['lib.es2020.string.d.ts'] = true;
libFileSet['lib.es2020.symbol.wellknown.d.ts'] = true;
libFileSet['lib.es2021.d.ts'] = true;
libFileSet['lib.es2021.full.d.ts'] = true;
libFileSet['lib.es2021.promise.d.ts'] = true;
libFileSet['lib.es2021.string.d.ts'] = true;
libFileSet['lib.es2021.weakref.d.ts'] = true;
libFileSet['lib.es5.d.ts'] = true;
libFileSet['lib.es6.d.ts'] = true;
libFileSet['lib.esnext.d.ts'] = true;
libFileSet['lib.esnext.full.d.ts'] = true;
libFileSet['lib.esnext.intl.d.ts'] = true;
libFileSet['lib.esnext.promise.d.ts'] = true;
libFileSet['lib.esnext.string.d.ts'] = true;
libFileSet['lib.esnext.weakref.d.ts'] = true;
libFileSet['lib.scripthost.d.ts'] = true;
libFileSet['lib.webworker.d.ts'] = true;
libFileSet['lib.webworker.importscripts.d.ts'] = true;
libFileSet['lib.webworker.iterable.d.ts'] = true;

72
src/typescript/lib/lib.ts Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

7483
src/typescript/lib/typescriptServices.d.ts vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,5 @@
//
// **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
//
export const typescriptVersion = "4.4.4";

View file

@ -0,0 +1,714 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import type * as mode from './tsMode';
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';
//#region enums copied from typescript to prevent loading the entire typescriptServices ---
export enum ModuleKind {
None = 0,
CommonJS = 1,
AMD = 2,
UMD = 3,
System = 4,
ES2015 = 5,
ESNext = 99
}
export enum JsxEmit {
None = 0,
Preserve = 1,
React = 2,
ReactNative = 3,
ReactJSX = 4,
ReactJSXDev = 5
}
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;
/**
* Limit diagnostic computation to only visible files.
* Defaults to false.
*/
onlyVisible?: 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 InlayHintsOptions {
readonly includeInlayParameterNameHints?: 'none' | 'literals' | 'all';
readonly includeInlayParameterNameHintsWhenArgumentMatchesName?: boolean;
readonly includeInlayFunctionParameterTypeHints?: boolean;
readonly includeInlayVariableTypeHints?: boolean;
readonly includeInlayPropertyDeclarationTypeHints?: boolean;
readonly includeInlayFunctionLikeReturnTypeHints?: boolean;
readonly includeInlayEnumMemberValueHints?: boolean;
}
interface IExtraLib {
content: string;
version: number;
}
export interface IExtraLibs {
[path: string]: IExtraLib;
}
/**
* 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?: {};
reportsDeprecated?: {};
source?: string;
relatedInformation?: DiagnosticRelatedInformation[];
}
export interface DiagnosticRelatedInformation {
/** Diagnostic category: warning = 0, error = 1, suggestion = 2, message = 3 */
category: 0 | 1 | 2 | 3;
code: number;
/** TypeScriptWorker removes all but the `fileName` property to avoid serializing circular JSON structures. */
file: { fileName: string } | 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;
readonly inlayHintsOptions: InlayHintsOptions;
/**
* 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;
/**
* Configure webworker options
*/
setWorkerOptions(options: WorkerOptions): 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;
/**
* Configure inlay hints options.
*/
setInlayHintsOptions(options: InlayHintsOptions): void;
}
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, options: any): 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>>;
/**
* Get inlay hints in the range of the file.
* @param fileName
* @returns `Promise<typescript.InlayHint[]>`
*/
provideInlayHints(fileName: string, start: number, end: number): Promise<ReadonlyArray<any>>;
}
// --- TypeScript configuration and defaults ---------
class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
private _onDidChange = new Emitter<void>();
private _onDidExtraLibsChange = new Emitter<void>();
private _extraLibs: IExtraLibs;
private _removedExtraLibs: { [path: string]: number };
private _eagerModelSync: boolean;
private _compilerOptions!: CompilerOptions;
private _diagnosticsOptions!: DiagnosticsOptions;
private _workerOptions!: WorkerOptions;
private _onDidExtraLibsChangeTimeout: number;
private _inlayHintsOptions!: InlayHintsOptions;
constructor(
compilerOptions: CompilerOptions,
diagnosticsOptions: DiagnosticsOptions,
workerOptions: WorkerOptions,
inlayHintsOptions: InlayHintsOptions
) {
this._extraLibs = Object.create(null);
this._removedExtraLibs = Object.create(null);
this._eagerModelSync = false;
this.setCompilerOptions(compilerOptions);
this.setDiagnosticsOptions(diagnosticsOptions);
this.setWorkerOptions(workerOptions);
this.setInlayHintsOptions(inlayHintsOptions);
this._onDidExtraLibsChangeTimeout = -1;
}
get onDidChange(): IEvent<void> {
return this._onDidChange.event;
}
get onDidExtraLibsChange(): IEvent<void> {
return this._onDidExtraLibsChange.event;
}
get workerOptions(): WorkerOptions {
return this._workerOptions;
}
get inlayHintsOptions(): InlayHintsOptions {
return this._inlayHintsOptions;
}
getExtraLibs(): IExtraLibs {
return this._extraLibs;
}
addExtraLib(content: string, _filePath?: string): IDisposable {
let filePath: string;
if (typeof _filePath === 'undefined') {
filePath = `ts:extralib-${Math.random().toString(36).substring(2, 15)}`;
} else {
filePath = _filePath;
}
if (this._extraLibs[filePath] && this._extraLibs[filePath].content === content) {
// no-op, there already exists an extra lib with this content
return {
dispose: () => {}
};
}
let myVersion = 1;
if (this._removedExtraLibs[filePath]) {
myVersion = this._removedExtraLibs[filePath] + 1;
}
if (this._extraLibs[filePath]) {
myVersion = this._extraLibs[filePath].version + 1;
}
this._extraLibs[filePath] = {
content: content,
version: myVersion
};
this._fireOnDidExtraLibsChangeSoon();
return {
dispose: () => {
let extraLib = this._extraLibs[filePath];
if (!extraLib) {
return;
}
if (extraLib.version !== myVersion) {
return;
}
delete this._extraLibs[filePath];
this._removedExtraLibs[filePath] = myVersion;
this._fireOnDidExtraLibsChangeSoon();
}
};
}
setExtraLibs(libs: { content: string; filePath?: string }[]): void {
for (const filePath in this._extraLibs) {
this._removedExtraLibs[filePath] = this._extraLibs[filePath].version;
}
// clear out everything
this._extraLibs = Object.create(null);
if (libs && libs.length > 0) {
for (const lib of libs) {
const filePath =
lib.filePath || `ts:extralib-${Math.random().toString(36).substring(2, 15)}`;
const content = lib.content;
let myVersion = 1;
if (this._removedExtraLibs[filePath]) {
myVersion = this._removedExtraLibs[filePath] + 1;
}
this._extraLibs[filePath] = {
content: content,
version: myVersion
};
}
}
this._fireOnDidExtraLibsChangeSoon();
}
private _fireOnDidExtraLibsChangeSoon(): void {
if (this._onDidExtraLibsChangeTimeout !== -1) {
// already scheduled
return;
}
this._onDidExtraLibsChangeTimeout = window.setTimeout(() => {
this._onDidExtraLibsChangeTimeout = -1;
this._onDidExtraLibsChange.fire(undefined);
}, 0);
}
getCompilerOptions(): CompilerOptions {
return this._compilerOptions;
}
setCompilerOptions(options: CompilerOptions): void {
this._compilerOptions = options || Object.create(null);
this._onDidChange.fire(undefined);
}
getDiagnosticsOptions(): DiagnosticsOptions {
return this._diagnosticsOptions;
}
setDiagnosticsOptions(options: DiagnosticsOptions): void {
this._diagnosticsOptions = options || Object.create(null);
this._onDidChange.fire(undefined);
}
setWorkerOptions(options: WorkerOptions): void {
this._workerOptions = options || Object.create(null);
this._onDidChange.fire(undefined);
}
setInlayHintsOptions(options: InlayHintsOptions): void {
this._inlayHintsOptions = options || Object.create(null);
this._onDidChange.fire(undefined);
}
setMaximumWorkerIdleTime(value: number): void {}
setEagerModelSync(value: boolean) {
// doesn't fire an event since no
// worker restart is required here
this._eagerModelSync = value;
}
getEagerModelSync() {
return this._eagerModelSync;
}
}
export const typescriptVersion: string = tsversion;
export const typescriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
{ allowNonTsExtensions: true, target: ScriptTarget.Latest },
{ noSemanticValidation: false, noSyntaxValidation: false, onlyVisible: false },
{},
{}
);
export const javascriptDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(
{ allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest },
{ noSemanticValidation: true, noSyntaxValidation: false, onlyVisible: false },
{},
{}
);
export const getTypeScriptWorker = (): Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>> => {
return getMode().then((mode) => mode.getTypeScriptWorker());
};
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 ---
declare var AMD: any;
declare var require: any;
function getMode(): Promise<typeof mode> {
if (AMD) {
return new Promise((resolve, reject) => {
require(['vs/language/typescript/tsMode'], resolve, reject);
});
} else {
return import('./tsMode');
}
}
languages.onLanguage('typescript', () => {
return getMode().then((mode) => mode.setupTypeScript(typescriptDefaults));
});
languages.onLanguage('javascript', () => {
return getMode().then((mode) => mode.setupJavaScript(javascriptDefaults));
});

View file

@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as edworker from 'monaco-editor-core/esm/vs/editor/editor.worker';
import { TypeScriptWorker, ICreateData } from './tsWorker';
import { worker } from '../fillers/monaco-editor-core';
self.onmessage = () => {
// ignore the first message
edworker.initialize((ctx: worker.IWorkerContext, createData: ICreateData) => {
return new TypeScriptWorker(ctx, createData);
});
};

87
src/typescript/tsMode.ts Normal file
View file

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { WorkerManager } from './workerManager';
import type { TypeScriptWorker } from './tsWorker';
import { LanguageServiceDefaults } from './monaco.contribution';
import * as languageFeatures from './languageFeatures';
import { languages, Uri } from '../fillers/monaco-editor-core';
let javaScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
let typeScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
export function setupTypeScript(defaults: LanguageServiceDefaults): void {
typeScriptWorker = setupMode(defaults, 'typescript');
}
export function setupJavaScript(defaults: LanguageServiceDefaults): void {
javaScriptWorker = setupMode(defaults, 'javascript');
}
export function getJavaScriptWorker(): Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>> {
return new Promise((resolve, reject) => {
if (!javaScriptWorker) {
return reject('JavaScript not registered!');
}
resolve(javaScriptWorker);
});
}
export function getTypeScriptWorker(): Promise<(...uris: Uri[]) => Promise<TypeScriptWorker>> {
return new Promise((resolve, reject) => {
if (!typeScriptWorker) {
return reject('TypeScript not registered!');
}
resolve(typeScriptWorker);
});
}
function setupMode(
defaults: LanguageServiceDefaults,
modeId: string
): (...uris: Uri[]) => Promise<TypeScriptWorker> {
const client = new WorkerManager(modeId, defaults);
const worker = (...uris: Uri[]): Promise<TypeScriptWorker> => {
return client.getLanguageServiceWorker(...uris);
};
const libFiles = new languageFeatures.LibFiles(worker);
languages.registerCompletionItemProvider(modeId, new languageFeatures.SuggestAdapter(worker));
languages.registerSignatureHelpProvider(
modeId,
new languageFeatures.SignatureHelpAdapter(worker)
);
languages.registerHoverProvider(modeId, new languageFeatures.QuickInfoAdapter(worker));
languages.registerDocumentHighlightProvider(
modeId,
new languageFeatures.OccurrencesAdapter(worker)
);
languages.registerDefinitionProvider(
modeId,
new languageFeatures.DefinitionAdapter(libFiles, worker)
);
languages.registerReferenceProvider(
modeId,
new languageFeatures.ReferenceAdapter(libFiles, worker)
);
languages.registerDocumentSymbolProvider(modeId, new languageFeatures.OutlineAdapter(worker));
languages.registerDocumentRangeFormattingEditProvider(
modeId,
new languageFeatures.FormatAdapter(worker)
);
languages.registerOnTypeFormattingEditProvider(
modeId,
new languageFeatures.FormatOnTypeAdapter(worker)
);
languages.registerCodeActionProvider(modeId, new languageFeatures.CodeActionAdaptor(worker));
languages.registerRenameProvider(modeId, new languageFeatures.RenameAdapter(libFiles, worker));
languages.registerInlayHintsProvider(modeId, new languageFeatures.InlayHintsAdapter(worker));
new languageFeatures.DiagnosticsAdapter(libFiles, defaults, modeId, worker);
return worker;
}

496
src/typescript/tsWorker.ts Normal file
View file

@ -0,0 +1,496 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as ts from './lib/typescriptServices';
import { libFileMap } from './lib/lib';
import {
Diagnostic,
DiagnosticRelatedInformation,
IExtraLibs,
TypeScriptWorker as ITypeScriptWorker
} from './monaco.contribution';
import { Uri, worker } from '../fillers/monaco-editor-core';
/**
* Loading a default lib as a source file will mess up TS completely.
* So our strategy is to hide such a text model from TS.
* See https://github.com/microsoft/monaco-editor/issues/2182
*/
function fileNameIsLib(resource: Uri | string): boolean {
if (typeof resource === 'string') {
if (/^file:\/\/\//.test(resource)) {
return !!libFileMap[resource.substr(8)];
}
return false;
}
if (resource.path.indexOf('/lib.') === 0) {
return !!libFileMap[resource.path.slice(1)];
}
return false;
}
export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWorker {
// --- model sync -----------------------
private _ctx: worker.IWorkerContext;
private _extraLibs: IExtraLibs = Object.create(null);
private _languageService = ts.createLanguageService(this);
private _compilerOptions: ts.CompilerOptions;
private _inlayHintsOptions?: ts.InlayHintsOptions;
constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
this._ctx = ctx;
this._compilerOptions = createData.compilerOptions;
this._extraLibs = createData.extraLibs;
this._inlayHintsOptions = createData.inlayHintsOptions;
}
// --- language service host ---------------
getCompilationSettings(): ts.CompilerOptions {
return this._compilerOptions;
}
getLanguageService(): ts.LanguageService {
return this._languageService;
}
getExtraLibs(): IExtraLibs {
return this._extraLibs;
}
getScriptFileNames(): string[] {
const allModels = this._ctx.getMirrorModels().map((model) => model.uri);
const models = allModels.filter((uri) => !fileNameIsLib(uri)).map((uri) => uri.toString());
return models.concat(Object.keys(this._extraLibs));
}
private _getModel(fileName: string): worker.IMirrorModel | null {
let models = this._ctx.getMirrorModels();
for (let i = 0; i < models.length; i++) {
if (models[i].uri.toString() === fileName) {
return models[i];
}
}
return null;
}
getScriptVersion(fileName: string): string {
let model = this._getModel(fileName);
if (model) {
return model.version.toString();
} else if (this.isDefaultLibFileName(fileName)) {
// default lib is static
return '1';
} else if (fileName in this._extraLibs) {
return String(this._extraLibs[fileName].version);
}
return '';
}
async getScriptText(fileName: string): Promise<string | undefined> {
return this._getScriptText(fileName);
}
_getScriptText(fileName: string): string | undefined {
let text: string;
let model = this._getModel(fileName);
const libizedFileName = 'lib.' + fileName + '.d.ts';
if (model) {
// a true editor model
text = model.getValue();
} else if (fileName in libFileMap) {
text = libFileMap[fileName];
} else if (libizedFileName in libFileMap) {
text = libFileMap[libizedFileName];
} else if (fileName in this._extraLibs) {
// extra lib
text = this._extraLibs[fileName].content;
} else {
return;
}
return text;
}
getScriptSnapshot(fileName: string): ts.IScriptSnapshot | undefined {
const text = this._getScriptText(fileName);
if (text === undefined) {
return;
}
return <ts.IScriptSnapshot>{
getText: (start, end) => text.substring(start, end),
getLength: () => text.length,
getChangeRange: () => undefined
};
}
getScriptKind?(fileName: string): ts.ScriptKind {
const suffix = fileName.substr(fileName.lastIndexOf('.') + 1);
switch (suffix) {
case 'ts':
return ts.ScriptKind.TS;
case 'tsx':
return ts.ScriptKind.TSX;
case 'js':
return ts.ScriptKind.JS;
case 'jsx':
return ts.ScriptKind.JSX;
default:
return this.getCompilationSettings().allowJs ? ts.ScriptKind.JS : ts.ScriptKind.TS;
}
}
getCurrentDirectory(): string {
return '';
}
getDefaultLibFileName(options: ts.CompilerOptions): string {
switch (options.target) {
case 99 /* ESNext */:
const esnext = 'lib.esnext.full.d.ts';
if (esnext in libFileMap || esnext in this._extraLibs) return esnext;
case 7 /* ES2020 */:
case 6 /* ES2019 */:
case 5 /* ES2018 */:
case 4 /* ES2017 */:
case 3 /* ES2016 */:
case 2 /* ES2015 */:
default:
// Support a dynamic lookup for the ES20XX version based on the target
// which is safe unless TC39 changes their numbering system
const eslib = `lib.es${2013 + (options.target || 99)}.full.d.ts`;
// Note: This also looks in _extraLibs, If you want
// to add support for additional target options, you will need to
// add the extra dts files to _extraLibs via the API.
if (eslib in libFileMap || eslib in this._extraLibs) {
return eslib;
}
return 'lib.es6.d.ts'; // We don't use lib.es2015.full.d.ts due to breaking change.
case 1:
case 0:
return 'lib.d.ts';
}
}
isDefaultLibFileName(fileName: string): boolean {
return fileName === this.getDefaultLibFileName(this._compilerOptions);
}
async getLibFiles(): Promise<Record<string, string>> {
return libFileMap;
}
// --- language features
private static clearFiles(tsDiagnostics: ts.Diagnostic[]): Diagnostic[] {
// Clear the `file` field, which cannot be JSON'yfied because it
// contains cyclic data structures, except for the `fileName`
// property.
// Do a deep clone so we don't mutate the ts.Diagnostic object (see https://github.com/microsoft/monaco-editor/issues/2392)
const diagnostics: Diagnostic[] = [];
for (const tsDiagnostic of tsDiagnostics) {
const diagnostic: Diagnostic = { ...tsDiagnostic };
diagnostic.file = diagnostic.file ? { fileName: diagnostic.file.fileName } : undefined;
if (tsDiagnostic.relatedInformation) {
diagnostic.relatedInformation = [];
for (const tsRelatedDiagnostic of tsDiagnostic.relatedInformation) {
const relatedDiagnostic: DiagnosticRelatedInformation = { ...tsRelatedDiagnostic };
relatedDiagnostic.file = relatedDiagnostic.file
? { fileName: relatedDiagnostic.file.fileName }
: undefined;
diagnostic.relatedInformation.push(relatedDiagnostic);
}
}
diagnostics.push(diagnostic);
}
return diagnostics;
}
async getSyntacticDiagnostics(fileName: string): Promise<Diagnostic[]> {
if (fileNameIsLib(fileName)) {
return [];
}
const diagnostics = this._languageService.getSyntacticDiagnostics(fileName);
return TypeScriptWorker.clearFiles(diagnostics);
}
async getSemanticDiagnostics(fileName: string): Promise<Diagnostic[]> {
if (fileNameIsLib(fileName)) {
return [];
}
const diagnostics = this._languageService.getSemanticDiagnostics(fileName);
return TypeScriptWorker.clearFiles(diagnostics);
}
async getSuggestionDiagnostics(fileName: string): Promise<Diagnostic[]> {
if (fileNameIsLib(fileName)) {
return [];
}
const diagnostics = this._languageService.getSuggestionDiagnostics(fileName);
return TypeScriptWorker.clearFiles(diagnostics);
}
async getCompilerOptionsDiagnostics(fileName: string): Promise<Diagnostic[]> {
if (fileNameIsLib(fileName)) {
return [];
}
const diagnostics = this._languageService.getCompilerOptionsDiagnostics();
return TypeScriptWorker.clearFiles(diagnostics);
}
async getCompletionsAtPosition(
fileName: string,
position: number
): Promise<ts.CompletionInfo | undefined> {
if (fileNameIsLib(fileName)) {
return undefined;
}
return this._languageService.getCompletionsAtPosition(fileName, position, undefined);
}
async getCompletionEntryDetails(
fileName: string,
position: number,
entry: string
): Promise<ts.CompletionEntryDetails | undefined> {
return this._languageService.getCompletionEntryDetails(
fileName,
position,
entry,
undefined,
undefined,
undefined,
undefined
);
}
async getSignatureHelpItems(
fileName: string,
position: number,
options: ts.SignatureHelpItemsOptions | undefined
): Promise<ts.SignatureHelpItems | undefined> {
if (fileNameIsLib(fileName)) {
return undefined;
}
return this._languageService.getSignatureHelpItems(fileName, position, options);
}
async getQuickInfoAtPosition(
fileName: string,
position: number
): Promise<ts.QuickInfo | undefined> {
if (fileNameIsLib(fileName)) {
return undefined;
}
return this._languageService.getQuickInfoAtPosition(fileName, position);
}
async getOccurrencesAtPosition(
fileName: string,
position: number
): Promise<ReadonlyArray<ts.ReferenceEntry> | undefined> {
if (fileNameIsLib(fileName)) {
return undefined;
}
return this._languageService.getOccurrencesAtPosition(fileName, position);
}
async getDefinitionAtPosition(
fileName: string,
position: number
): Promise<ReadonlyArray<ts.DefinitionInfo> | undefined> {
if (fileNameIsLib(fileName)) {
return undefined;
}
return this._languageService.getDefinitionAtPosition(fileName, position);
}
async getReferencesAtPosition(
fileName: string,
position: number
): Promise<ts.ReferenceEntry[] | undefined> {
if (fileNameIsLib(fileName)) {
return undefined;
}
return this._languageService.getReferencesAtPosition(fileName, position);
}
async getNavigationBarItems(fileName: string): Promise<ts.NavigationBarItem[]> {
if (fileNameIsLib(fileName)) {
return [];
}
return this._languageService.getNavigationBarItems(fileName);
}
async getFormattingEditsForDocument(
fileName: string,
options: ts.FormatCodeOptions
): Promise<ts.TextChange[]> {
if (fileNameIsLib(fileName)) {
return [];
}
return this._languageService.getFormattingEditsForDocument(fileName, options);
}
async getFormattingEditsForRange(
fileName: string,
start: number,
end: number,
options: ts.FormatCodeOptions
): Promise<ts.TextChange[]> {
if (fileNameIsLib(fileName)) {
return [];
}
return this._languageService.getFormattingEditsForRange(fileName, start, end, options);
}
async getFormattingEditsAfterKeystroke(
fileName: string,
postion: number,
ch: string,
options: ts.FormatCodeOptions
): Promise<ts.TextChange[]> {
if (fileNameIsLib(fileName)) {
return [];
}
return this._languageService.getFormattingEditsAfterKeystroke(fileName, postion, ch, options);
}
async findRenameLocations(
fileName: string,
position: number,
findInStrings: boolean,
findInComments: boolean,
providePrefixAndSuffixTextForRename: boolean
): Promise<readonly ts.RenameLocation[] | undefined> {
if (fileNameIsLib(fileName)) {
return undefined;
}
return this._languageService.findRenameLocations(
fileName,
position,
findInStrings,
findInComments,
providePrefixAndSuffixTextForRename
);
}
async getRenameInfo(
fileName: string,
position: number,
options: ts.RenameInfoOptions
): Promise<ts.RenameInfo> {
if (fileNameIsLib(fileName)) {
return { canRename: false, localizedErrorMessage: 'Cannot rename in lib file' };
}
return this._languageService.getRenameInfo(fileName, position, options);
}
async getEmitOutput(fileName: string): Promise<ts.EmitOutput> {
if (fileNameIsLib(fileName)) {
return { outputFiles: [], emitSkipped: true };
}
return this._languageService.getEmitOutput(fileName);
}
async getCodeFixesAtPosition(
fileName: string,
start: number,
end: number,
errorCodes: number[],
formatOptions: ts.FormatCodeOptions
): Promise<ReadonlyArray<ts.CodeFixAction>> {
if (fileNameIsLib(fileName)) {
return [];
}
const preferences = {};
try {
return this._languageService.getCodeFixesAtPosition(
fileName,
start,
end,
errorCodes,
formatOptions,
preferences
);
} catch {
return [];
}
}
async updateExtraLibs(extraLibs: IExtraLibs): Promise<void> {
this._extraLibs = extraLibs;
}
async provideInlayHints(
fileName: string,
start: number,
end: number
): Promise<readonly ts.InlayHint[]> {
if (fileNameIsLib(fileName)) {
return [];
}
const preferences: ts.InlayHintsOptions = this._inlayHintsOptions ?? {};
const span: ts.TextSpan = {
start,
length: end - start
};
try {
return this._languageService.provideInlayHints(fileName, span, preferences);
} catch {
return [];
}
}
}
export interface ICreateData {
compilerOptions: ts.CompilerOptions;
extraLibs: IExtraLibs;
customWorkerPath?: string;
inlayHintsOptions?: ts.InlayHintsOptions;
}
/** The shape of the factory */
export interface CustomTSWebWorkerFactory {
(
TSWorkerClass: typeof TypeScriptWorker,
tsc: typeof ts,
libs: Record<string, string>
): typeof TypeScriptWorker;
}
declare global {
var importScripts: (path: string) => void | undefined;
var customTSWorkerFactory: CustomTSWebWorkerFactory | undefined;
}
export function create(ctx: worker.IWorkerContext, createData: ICreateData): TypeScriptWorker {
let TSWorkerClass = TypeScriptWorker;
if (createData.customWorkerPath) {
if (typeof importScripts === 'undefined') {
console.warn(
'Monaco is not using webworkers for background tasks, and that is needed to support the customWorkerPath flag'
);
} else {
importScripts(createData.customWorkerPath);
const workerFactoryFunc: CustomTSWebWorkerFactory | undefined = self.customTSWorkerFactory;
if (!workerFactoryFunc) {
throw new Error(
`The script at ${createData.customWorkerPath} does not add customTSWorkerFactory to self`
);
}
TSWorkerClass = workerFactoryFunc(TypeScriptWorker, ts, libFileMap);
}
}
return new TSWorkerClass(ctx, createData);
}

View file

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { LanguageServiceDefaults } from './monaco.contribution';
import type { TypeScriptWorker } from './tsWorker';
import { editor, Uri, IDisposable } from '../fillers/monaco-editor-core';
export class WorkerManager {
private _modeId: string;
private _defaults: LanguageServiceDefaults;
private _configChangeListener: IDisposable;
private _updateExtraLibsToken: number;
private _extraLibsChangeListener: IDisposable;
private _worker: editor.MonacoWebWorker<TypeScriptWorker> | null;
private _client: Promise<TypeScriptWorker> | null;
constructor(modeId: string, defaults: LanguageServiceDefaults) {
this._modeId = modeId;
this._defaults = defaults;
this._worker = null;
this._client = null;
this._configChangeListener = this._defaults.onDidChange(() => this._stopWorker());
this._updateExtraLibsToken = 0;
this._extraLibsChangeListener = this._defaults.onDidExtraLibsChange(() =>
this._updateExtraLibs()
);
}
private _stopWorker(): void {
if (this._worker) {
this._worker.dispose();
this._worker = null;
}
this._client = null;
}
dispose(): void {
this._configChangeListener.dispose();
this._extraLibsChangeListener.dispose();
this._stopWorker();
}
private async _updateExtraLibs(): Promise<void> {
if (!this._worker) {
return;
}
const myToken = ++this._updateExtraLibsToken;
const proxy = await this._worker.getProxy();
if (this._updateExtraLibsToken !== myToken) {
// avoid multiple calls
return;
}
proxy.updateExtraLibs(this._defaults.getExtraLibs());
}
private _getClient(): Promise<TypeScriptWorker> {
if (!this._client) {
this._worker = editor.createWebWorker<TypeScriptWorker>({
// module that exports the create() method and returns a `TypeScriptWorker` instance
moduleId: 'vs/language/typescript/tsWorker',
label: this._modeId,
keepIdleModels: true,
// passed in to the create() method
createData: {
compilerOptions: this._defaults.getCompilerOptions(),
extraLibs: this._defaults.getExtraLibs(),
customWorkerPath: this._defaults.workerOptions.customWorkerPath,
inlayHintsOptions: this._defaults.inlayHintsOptions
}
});
let p = <Promise<TypeScriptWorker>>this._worker.getProxy();
if (this._defaults.getEagerModelSync()) {
p = p.then((worker) => {
if (this._worker) {
return this._worker.withSyncedResources(
editor
.getModels()
.filter((model) => model.getLanguageId() === this._modeId)
.map((model) => model.uri)
);
}
return worker;
});
}
this._client = p;
}
return this._client;
}
getLanguageServiceWorker(...resources: Uri[]): Promise<TypeScriptWorker> {
let _client: TypeScriptWorker;
return this._getClient()
.then((client) => {
_client = client;
})
.then((_) => {
if (this._worker) {
return this._worker.withSyncedResources(resources);
}
})
.then((_) => _client);
}
}