Wenlu Wang 3 years ago
parent
commit
5632f5fed3

+ 4 - 4
monaco.d.ts

@@ -414,10 +414,10 @@ declare namespace monaco.languages.typescript {
 			formatOptions: any
 		): Promise<ReadonlyArray<any>>;
 		/**
-	 	* Get inlay hints in the range of the file.
-	 	* @param fileName
-	 	* @returns `Promise<typescript.InlayHint[]>`
-	 	*/
+		 * 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>>;
 	}
 	export const typescriptVersion: string;

+ 3 - 3
package-lock.json

@@ -461,9 +461,9 @@
 			}
 		},
 		"typescript": {
-			"version": "4.3.2",
-			"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz",
-			"integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==",
+			"version": "4.4.1-rc",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.1-rc.tgz",
+			"integrity": "sha512-SYdeKrJiOajqNTI+sweR70JET43Z567HFNo7DvvBof8J5/bt2cywy7VoWXqZyrsHEmQ9foraLtLr30mcfpfz9w==",
 			"dev": true
 		},
 		"which": {

+ 1 - 1
package.json

@@ -32,7 +32,7 @@
 		"pretty-quick": "^3.1.0",
 		"requirejs": "^2.3.6",
 		"terser": "^5.6.0",
-		"typescript": "^4.3.2"
+		"typescript": "^4.4.1-rc"
 	},
 	"husky": {
 		"hooks": {

+ 15 - 15
src/languageFeatures.ts

@@ -242,7 +242,9 @@ export class DiagnosticsAdapter extends Adapter {
 			}
 		};
 
-		this._disposables.push(editor.onDidCreateModel((model) => onModelAdd(<IInternalEditorModel>model)));
+		this._disposables.push(
+			editor.onDidCreateModel((model) => onModelAdd(<IInternalEditorModel>model))
+		);
 		this._disposables.push(editor.onWillDisposeModel(onModelRemoved));
 		this._disposables.push(
 			editor.onDidChangeModelLanguage((event) => {
@@ -574,9 +576,9 @@ function tagToString(tag: ts.JSDocTagInfo): string {
 	if (tag.name === 'param' && tag.text) {
 		const [paramName, ...rest] = tag.text;
 		tagLabel += `\`${paramName.text}\``;
-		if (rest.length > 0) tagLabel += ` — ${rest.map(r => r.text).join(' ')}`;
+		if (rest.length > 0) tagLabel += ` — ${rest.map((r) => r.text).join(' ')}`;
 	} else if (Array.isArray(tag.text)) {
-		tagLabel += ` — ${tag.text.map(r => r.text).join(' ')}`;
+		tagLabel += ` — ${tag.text.map((r) => r.text).join(' ')}`;
 	} else if (tag.text) {
 		tagLabel += ` — ${tag.text}`;
 	}
@@ -793,16 +795,14 @@ export class DefinitionAdapter extends Adapter {
 					range: this._textSpanToRange(refModel, entry.textSpan)
 				});
 			} else {
-				const matchedLibFile = typescriptDefaults.getExtraLibs()[entry.fileName]
+				const matchedLibFile = typescriptDefaults.getExtraLibs()[entry.fileName];
 				if (matchedLibFile) {
 					const libModel = editor.createModel(matchedLibFile.content, 'typescript', uri);
 					return {
 						uri: uri,
 						range: this._textSpanToRange(libModel, entry.textSpan)
-					}
+					};
 				}
-
-
 			}
 		}
 		return result;
@@ -894,7 +894,7 @@ export class OutlineAdapter extends Adapter implements languages.DocumentSymbolP
 				kind: <languages.SymbolKind>(outlineTypeTable[item.kind] || languages.SymbolKind.Variable),
 				range: this._textSpanToRange(model, item.spans[0]),
 				selectionRange: this._textSpanToRange(model, item.spans[0]),
-				tags: [],
+				tags: []
 			};
 
 			if (containerLabel) result.containerName = containerLabel;
@@ -1247,23 +1247,23 @@ export class InlayHintsAdapter extends Adapter implements languages.InlayHintsPr
 
 		const hints = await worker.provideInlayHints(fileName, start, end);
 
-		return hints.map(hint => {
+		return hints.map((hint) => {
 			return {
 				...hint,
 				position: model.getPositionAt(hint.position),
 				kind: this._convertHintKind(hint.kind)
-			}
-		})
+			};
+		});
 	}
 
-	private _convertHintKind (kind?: ts.InlayHintKind) {
+	private _convertHintKind(kind?: ts.InlayHintKind) {
 		switch (kind) {
-			case "Parameter":
+			case 'Parameter':
 				return languages.InlayHintKind.Parameter;
-			case "Type":
+			case 'Type':
 				return languages.InlayHintKind.Type;
 			default:
 				return languages.InlayHintKind.Other;
 		}
 	}
-}
+}

File diff suppressed because it is too large
+ 0 - 0
src/lib/lib.ts


File diff suppressed because it is too large
+ 444 - 341
src/lib/typescriptServices-amd.js


File diff suppressed because it is too large
+ 314 - 308
src/lib/typescriptServices.d.ts


File diff suppressed because it is too large
+ 444 - 341
src/lib/typescriptServices.js


+ 1 - 1
src/lib/typescriptServicesMetadata.ts

@@ -2,4 +2,4 @@
 // **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
 //
 
-export const typescriptVersion = "4.3.2";
+export const typescriptVersion = "4.4.1-rc";

+ 28 - 6
src/monaco.contribution.ts

@@ -169,6 +169,16 @@ export interface WorkerOptions {
 	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;
@@ -230,6 +240,8 @@ export interface LanguageServiceDefaults {
 
 	readonly workerOptions: WorkerOptions;
 
+	readonly inlayHintsOptions: InlayHintsOptions;
+
 	/**
 	 * Get the current extra libs registered with the language service.
 	 */
@@ -458,11 +470,7 @@ export interface TypeScriptWorker {
 	 * @param fileName
 	 * @returns `Promise<typescript.InlayHint[]>`
 	 */
-	provideInlayHints(
-		fileName: string,
-		start: number,
-		end: number,
-	): Promise<ReadonlyArray<any>>;
+	provideInlayHints(fileName: string, start: number, end: number): Promise<ReadonlyArray<any>>;
 }
 
 // --- TypeScript configuration and defaults ---------
@@ -478,11 +486,13 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 	private _diagnosticsOptions!: DiagnosticsOptions;
 	private _workerOptions!: WorkerOptions;
 	private _onDidExtraLibsChangeTimeout: number;
+	private _inlayHintsOptions!: InlayHintsOptions;
 
 	constructor(
 		compilerOptions: CompilerOptions,
 		diagnosticsOptions: DiagnosticsOptions,
-		workerOptions: WorkerOptions
+		workerOptions: WorkerOptions,
+		inlayHintsOptions: InlayHintsOptions
 	) {
 		this._extraLibs = Object.create(null);
 		this._removedExtraLibs = Object.create(null);
@@ -490,6 +500,7 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 		this.setCompilerOptions(compilerOptions);
 		this.setDiagnosticsOptions(diagnosticsOptions);
 		this.setWorkerOptions(workerOptions);
+		this.setInlayHintsOptions(inlayHintsOptions);
 		this._onDidExtraLibsChangeTimeout = -1;
 	}
 
@@ -505,6 +516,10 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 		return this._workerOptions;
 	}
 
+	get inlayHintsOptions(): InlayHintsOptions {
+		return this._inlayHintsOptions;
+	}
+
 	getExtraLibs(): IExtraLibs {
 		return this._extraLibs;
 	}
@@ -615,6 +630,11 @@ class LanguageServiceDefaultsImpl implements LanguageServiceDefaults {
 		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) {
@@ -633,12 +653,14 @@ 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 },
+	{},
 	{}
 );
 

+ 14 - 11
src/tsWorker.ts

@@ -39,11 +39,13 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
 	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 ---------------
@@ -191,7 +193,9 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
 				diagnostic.relatedInformation = [];
 				for (const tsRelatedDiagnostic of tsDiagnostic.relatedInformation) {
 					const relatedDiagnostic: DiagnosticRelatedInformation = { ...tsRelatedDiagnostic };
-					relatedDiagnostic.file = relatedDiagnostic.file ? { fileName: relatedDiagnostic.file.fileName } : undefined
+					relatedDiagnostic.file = relatedDiagnostic.file
+						? { fileName: relatedDiagnostic.file.fileName }
+						: undefined;
 					diagnostic.relatedInformation.push(relatedDiagnostic);
 				}
 			}
@@ -416,24 +420,22 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
 		this._extraLibs = extraLibs;
 	}
 
-	async provideInlayHints(fileName: string, start: number, end: number): Promise<readonly ts.InlayHint[]> {
+	async provideInlayHints(
+		fileName: string,
+		start: number,
+		end: number
+	): Promise<readonly ts.InlayHint[]> {
 		if (fileNameIsLib(fileName)) {
 			return [];
 		}
-		const preferences: ts.InlayHintsOptions = {
-			includeInlayParameterNameHints: "all"
-		};
+		const preferences: ts.InlayHintsOptions = this._inlayHintsOptions ?? {};
 		const span: ts.TextSpan = {
 			start,
 			length: end - start
-		}
+		};
 
 		try {
-			return this._languageService.provideInlayHints(
-				fileName,
-				span,
-				preferences
-			);
+			return this._languageService.provideInlayHints(fileName, span, preferences);
 		} catch {
 			return [];
 		}
@@ -444,6 +446,7 @@ export interface ICreateData {
 	compilerOptions: ts.CompilerOptions;
 	extraLibs: IExtraLibs;
 	customWorkerPath?: string;
+	inlayHintsOptions?: ts.InlayHintsOptions;
 }
 
 /** The shape of the factory */

+ 2 - 1
src/workerManager.ts

@@ -71,7 +71,8 @@ export class WorkerManager {
 				createData: {
 					compilerOptions: this._defaults.getCompilerOptions(),
 					extraLibs: this._defaults.getExtraLibs(),
-					customWorkerPath: this._defaults.workerOptions.customWorkerPath
+					customWorkerPath: this._defaults.workerOptions.customWorkerPath,
+					inlayHintsOptions: this._defaults.inlayHintsOptions
 				}
 			});
 

+ 219 - 0
test/inlayHints.html

@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+		<link
+			rel="stylesheet"
+			data-name="vs/editor/editor.main"
+			href="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.css"
+		/>
+	</head>
+	<body>
+		<h2>Monaco Editor TypeScript test page</h2>
+		<button id="resetBtn">Reset Sample</button>
+		<div id="container" style="width: 800px; height: 600px; border: 1px solid grey"></div>
+		<h3>Inlay Hints options</h3>
+		<textarea style="font-family: monospace" id="inlayHintsOpts" cols="60" rows="30"></textarea
+		><br />
+		<button id="updateInlayHintsOptionsBtn">Update Inaly Hints options</button>
+
+		<script>
+			const paths = {
+				'vs/basic-languages': '../node_modules/monaco-languages/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'
+			};
+			if (document.location.protocol === 'http:') {
+				// Add support for running local http server
+				let testIndex = document.location.pathname.indexOf('/test/');
+				if (testIndex !== -1) {
+					let prefix = document.location.pathname.substr(0, testIndex);
+					paths['vs/language/typescript'] = prefix + '/out/amd';
+				}
+			}
+			self.require = {
+				paths: paths
+			};
+		</script>
+		<script src="../node_modules/monaco-editor-core/dev/vs/loader.js"></script>
+		<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.nls.js"></script>
+		<script src="../node_modules/monaco-editor-core/dev/vs/editor/editor.main.js"></script>
+
+		<script>
+			function getDefaultCode() {
+				return [
+					'/* Game of Life',
+					' * Implemented in TypeScript',
+					' * To learn more about TypeScript, please visit http://www.typescriptlang.org/',
+					' */',
+					'',
+					'module Conway {',
+					'',
+					'	export class Cell {',
+					'		public row: number;',
+					'		public col: number;',
+					'		public live: boolean;',
+					'',
+					'		constructor(row: number, col: number, live: boolean) {',
+					'			this.row = row;',
+					'			this.col = col;',
+					'			this.live = live',
+					'		}',
+					'	}',
+					'',
+					'	export class GameOfLife {',
+					'		private gridSize: number;',
+					'		private canvasSize: number;',
+					'		private lineColor: string;',
+					'		private liveColor: string;',
+					'		private deadColor: string;',
+					'		private initialLifeProbability: number;',
+					'		private animationRate: number;',
+					'		private cellSize: number;',
+					'		private context: CanvasRenderingContext2D;',
+					'		private world;',
+					'',
+					'',
+					'		constructor() {',
+					'			this.gridSize = 50;',
+					'			this.canvasSize = 600;',
+					"			this.lineColor = '#cdcdcd';",
+					"			this.liveColor = '#666';",
+					"			this.deadColor = '#eee';",
+					'			this.initialLifeProbability = 0.5;',
+					'			this.animationRate = 60;',
+					'			this.cellSize = 0;',
+					'			this.world = this.createWorld();',
+					'			this.circleOfLife();',
+					'		}',
+					'',
+					'		public createWorld() {',
+					'			return this.travelWorld( (cell : Cell) =>  {',
+					'				cell.live = Math.random() < this.initialLifeProbability;',
+					'				return cell;',
+					'			});',
+					'		}',
+					'',
+					'		public circleOfLife() : void {',
+					'			this.world = this.travelWorld( (cell: Cell) => {',
+					'				cell = this.world[cell.row][cell.col];',
+					'				this.draw(cell);',
+					'				return this.resolveNextGeneration(cell);',
+					'			});',
+					'			setTimeout( () => {this.circleOfLife()}, this.animationRate);',
+					'		}',
+					'',
+					'		public resolveNextGeneration(cell : Cell) {',
+					'			var count = this.countNeighbors(cell);',
+					'			var newCell = new Cell(cell.row, cell.col, cell.live);',
+					'			if(count < 2 || count > 3) newCell.live = false;',
+					'			else if(count == 3) newCell.live = true;',
+					'			return newCell;',
+					'		}',
+					'',
+					'		public countNeighbors(cell : Cell) {',
+					'			var neighbors = 0;',
+					'			for(var row = -1; row <=1; row++) {',
+					'				for(var col = -1; col <= 1; col++) {',
+					'					if(row == 0 && col == 0) continue;',
+					'					if(this.isAlive(cell.row + row, cell.col + col)) {',
+					'						neighbors++;',
+					'					}',
+					'				}',
+					'			}',
+					'			return neighbors;',
+					'		}',
+					'',
+					'		public isAlive(row : number, col : number) {',
+					'			if(row < 0 || col < 0 || row >= this.gridSize || col >= this.gridSize) return false;',
+					'			return this.world[row][col].live;',
+					'		}',
+					'',
+					'		public travelWorld(callback) {',
+					'			var result = [];',
+					'			for(var row = 0; row < this.gridSize; row++) {',
+					'				var rowData = [];',
+					'				for(var col = 0; col < this.gridSize; col++) {',
+					'					rowData.push(callback(new Cell(row, col, false)));',
+					'				}',
+					'				result.push(rowData);',
+					'			}',
+					'			return result;',
+					'		}',
+					'',
+					'		public draw(cell : Cell) {',
+					'			if(this.context == null) this.context = this.createDrawingContext();',
+					'			if(this.cellSize == 0) this.cellSize = this.canvasSize/this.gridSize;',
+					'',
+					'			this.context.strokeStyle = this.lineColor;',
+					'			this.context.strokeRect(cell.row * this.cellSize, cell.col*this.cellSize, this.cellSize, this.cellSize);',
+					'			this.context.fillStyle = cell.live ? this.liveColor : this.deadColor;',
+					'			this.context.fillRect(cell.row * this.cellSize, cell.col*this.cellSize, this.cellSize, this.cellSize);',
+					'		}',
+					'',
+					'		public createDrawingContext() {',
+					"			var canvas = <HTMLCanvasElement> document.getElementById('conway-canvas');",
+					'			if(canvas == null) {',
+					"					canvas = document.createElement('canvas');",
+					"					canvas.id = 'conway-canvas';",
+					'					canvas.width = this.canvasSize;',
+					'					canvas.height = this.canvasSize;',
+					'					document.body.appendChild(canvas);',
+					'			}',
+					"			return canvas.getContext('2d');",
+					'		}',
+					'	}',
+					'}',
+					'',
+					'var game = new Conway.GameOfLife();'
+				].join('\n');
+			}
+
+			function getDefaultInlayHintsOpts() {
+				return {
+					includeInlayParameterNameHints: 'all',
+					includeInlayParameterNameHintsWhenArgumentMatchesName: true,
+					includeInlayFunctionParameterTypeHints: true,
+					includeInlayVariableTypeHints: true,
+					includeInlayPropertyDeclarationTypeHints: true,
+					includeInlayFunctionLikeReturnTypeHints: true,
+					includeInlayEnumMemberValueHints: true
+				};
+			}
+			require([
+				'vs/basic-languages/monaco.contribution',
+				'vs/language/typescript/monaco.contribution'
+			], () => {
+				const editor = monaco.editor.create(document.getElementById('container'), {
+					value: localStorage.getItem('code') || getDefaultCode(),
+					language: 'typescript',
+					lightbulb: { enabled: true }
+				});
+
+				editor.onDidChangeModelContent(() => {
+					const code = editor.getModel().getValue();
+					localStorage.setItem('code', code);
+				});
+
+				document.getElementById('resetBtn').onclick = () => {
+					editor.setValue(getDefaultCode());
+				};
+
+				const optsString =
+					localStorage.getItem('inlay-hints-opts') ||
+					JSON.stringify(getDefaultInlayHintsOpts(), null, 4);
+				document.getElementById('inlayHintsOpts').textContent = optsString;
+				monaco.languages.typescript.typescriptDefaults.setInlayHintsOptions(JSON.parse(optsString));
+
+				document.getElementById('updateInlayHintsOptionsBtn').onclick = () => {
+					const newOpts = document.getElementById('inlayHintsOpts').value;
+					monaco.languages.typescript.typescriptDefaults.setInlayHintsOptions(JSON.parse(newOpts));
+					localStorage.setItem('inlay-hints-opts', newOpts);
+				};
+			});
+		</script>
+	</body>
+</html>

Some files were not shown because too many files changed in this diff