function generateDeclarationFile()

in build/monaco/api.ts [357:512]


function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null {
	const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';

	let lines = recipe.split(endl);
	let result: string[] = [];

	let usageCounter = 0;
	let usageImports: string[] = [];
	let usage: string[] = [];

	let failed = false;

	usage.push(`var a;`);
	usage.push(`var b;`);

	const generateUsageImport = (moduleId: string) => {
		let importName = 'm' + (++usageCounter);
		usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
		return importName;
	};

	let enums: string[] = [];
	let version: string | null = null;

	lines.forEach(line => {

		if (failed) {
			return;
		}

		let m0 = line.match(/^\/\/dtsv=(\d+)$/);
		if (m0) {
			version = m0[1];
		}

		let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
		if (m1) {
			let moduleId = m1[1];
			const sourceFile = sourceFileGetter(moduleId);
			if (!sourceFile) {
				logErr(`While handling ${line}`);
				logErr(`Cannot find ${moduleId}`);
				failed = true;
				return;
			}

			const importName = generateUsageImport(moduleId);

			let replacer = createReplacer(m1[2]);

			let typeNames = m1[3].split(/,/);
			typeNames.forEach((typeName) => {
				typeName = typeName.trim();
				if (typeName.length === 0) {
					return;
				}
				let declaration = getTopLevelDeclaration(sourceFile, typeName);
				if (!declaration) {
					logErr(`While handling ${line}`);
					logErr(`Cannot find ${typeName}`);
					failed = true;
					return;
				}
				result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
			});
			return;
		}

		let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/);
		if (m2) {
			let moduleId = m2[1];
			const sourceFile = sourceFileGetter(moduleId);
			if (!sourceFile) {
				logErr(`While handling ${line}`);
				logErr(`Cannot find ${moduleId}`);
				failed = true;
				return;
			}

			const importName = generateUsageImport(moduleId);

			let replacer = createReplacer(m2[2]);

			let typeNames = m2[3].split(/,/);
			let typesToExcludeMap: { [typeName: string]: boolean; } = {};
			let typesToExcludeArr: string[] = [];
			typeNames.forEach((typeName) => {
				typeName = typeName.trim();
				if (typeName.length === 0) {
					return;
				}
				typesToExcludeMap[typeName] = true;
				typesToExcludeArr.push(typeName);
			});

			getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
				if (isDeclaration(declaration) && declaration.name) {
					if (typesToExcludeMap[declaration.name.text]) {
						return;
					}
				} else {
					// node is ts.VariableStatement
					let nodeText = getNodeText(sourceFile, declaration);
					for (let i = 0; i < typesToExcludeArr.length; i++) {
						if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) {
							return;
						}
					}
				}
				result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
			});
			return;
		}

		result.push(line);
	});

	if (failed) {
		return null;
	}

	if (version !== dtsv) {
		if (!version) {
			logErr(`gulp watch restart required. 'monaco.d.ts.recipe' is written before versioning was introduced.`);
		} else {
			logErr(`gulp watch restart required. 'monaco.d.ts.recipe' v${version} does not match runtime v${dtsv}.`);
		}
		return null;
	}

	let resultTxt = result.join(endl);
	resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
	resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
	resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);
	resultTxt = format(resultTxt, endl);
	resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);

	let resultEnums = [
		'/*---------------------------------------------------------------------------------------------',
		' *  Copyright (c) Microsoft Corporation. All rights reserved.',
		' *  Licensed under the MIT License. See License.txt in the project root for license information.',
		' *--------------------------------------------------------------------------------------------*/',
		'',
		'// THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY.',
		''
	].concat(enums).join(endl);
	resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);
	resultEnums = format(resultEnums, endl);
	resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);

	return {
		result: resultTxt,
		usageContent: `${usageImports.join('\n')}\n\n${usage.join('\n')}`,
		enums: resultEnums
	};
}