mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-15 14:05:47 -05:00
Merge branch 'master' into parallelAsyncTests
This commit is contained in:
30
scripts/build/getDirSize.js
Normal file
30
scripts/build/getDirSize.js
Normal file
@@ -0,0 +1,30 @@
|
||||
// @ts-check
|
||||
const { lstatSync, readdirSync } = require("fs");
|
||||
const { join } = require("path");
|
||||
|
||||
/**
|
||||
* Find the size of a directory recursively.
|
||||
* Symbolic links are counted once (same inode).
|
||||
* @param {string} root
|
||||
* @param {Set} seen
|
||||
* @returns {number} bytes
|
||||
*/
|
||||
function getDirSize(root, seen = new Set()) {
|
||||
const stats = lstatSync(root);
|
||||
|
||||
if (seen.has(stats.ino)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
seen.add(stats.ino);
|
||||
|
||||
if (!stats.isDirectory()) {
|
||||
return stats.size;
|
||||
}
|
||||
|
||||
return readdirSync(root)
|
||||
.map(file => getDirSize(join(root, file), seen))
|
||||
.reduce((acc, num) => acc + num, 0);
|
||||
}
|
||||
|
||||
module.exports = getDirSize;
|
||||
88
scripts/build/gulp-typescript-oop.js
Normal file
88
scripts/build/gulp-typescript-oop.js
Normal file
@@ -0,0 +1,88 @@
|
||||
// @ts-check
|
||||
const path = require("path");
|
||||
const child_process = require("child_process");
|
||||
const tsc = require("gulp-typescript");
|
||||
const Vinyl = require("vinyl");
|
||||
const { Duplex, Readable } = require("stream");
|
||||
|
||||
/**
|
||||
* @param {string} tsConfigFileName
|
||||
* @param {tsc.Settings} settings
|
||||
* @param {Object} options
|
||||
* @param {string} [options.typescript]
|
||||
*/
|
||||
function createProject(tsConfigFileName, settings, options) {
|
||||
settings = { ...settings };
|
||||
options = { ...options };
|
||||
if (settings.typescript) throw new Error();
|
||||
|
||||
const localSettings = { ...settings };
|
||||
if (options.typescript) {
|
||||
options.typescript = path.resolve(options.typescript);
|
||||
localSettings.typescript = require(options.typescript);
|
||||
}
|
||||
|
||||
const project = tsc.createProject(tsConfigFileName, localSettings);
|
||||
const wrappedProject = /** @type {tsc.Project} */(() => {
|
||||
const proc = child_process.fork(require.resolve("./main.js"));
|
||||
/** @type {Duplex & { js?: Readable, dts?: Readable }} */
|
||||
const compileStream = new Duplex({
|
||||
objectMode: true,
|
||||
read() {},
|
||||
/** @param {*} file */
|
||||
write(file, encoding, callback) {
|
||||
proc.send({ method: "write", params: { path: file.path, cwd: file.cwd, base: file.base, sourceMap: file.sourceMap }});
|
||||
callback();
|
||||
},
|
||||
final(callback) {
|
||||
proc.send({ method: "final" });
|
||||
callback();
|
||||
}
|
||||
});
|
||||
const jsStream = compileStream.js = new Readable({
|
||||
objectMode: true,
|
||||
read() {}
|
||||
});
|
||||
const dtsStream = compileStream.dts = new Readable({
|
||||
objectMode: true,
|
||||
read() {}
|
||||
});
|
||||
proc.send({ method: "createProject", params: { tsConfigFileName, settings, options } });
|
||||
proc.on("message", ({ method, params }) => {
|
||||
if (method === "write") {
|
||||
const file = new Vinyl({
|
||||
path: params.path,
|
||||
cwd: params.cwd,
|
||||
base: params.base,
|
||||
contents: Buffer.from(params.contents, "utf8")
|
||||
});
|
||||
if (params.sourceMap) file.sourceMap = params.sourceMap
|
||||
compileStream.push(file);;
|
||||
if (file.path.endsWith(".d.ts")) {
|
||||
dtsStream.push(file);
|
||||
}
|
||||
else {
|
||||
jsStream.push(file);
|
||||
}
|
||||
}
|
||||
else if (method === "final") {
|
||||
compileStream.push(null);
|
||||
jsStream.push(null);
|
||||
dtsStream.push(null);
|
||||
proc.kill();
|
||||
}
|
||||
else if (method === "error") {
|
||||
const error = new Error();
|
||||
error.name = params.name;
|
||||
error.message = params.message;
|
||||
error.stack = params.stack;
|
||||
compileStream.emit("error", error);
|
||||
proc.kill();
|
||||
}
|
||||
});
|
||||
return /** @type {*} */(compileStream);
|
||||
});
|
||||
return Object.assign(wrappedProject, project);
|
||||
}
|
||||
|
||||
exports.createProject = createProject;
|
||||
92
scripts/build/main.js
Normal file
92
scripts/build/main.js
Normal file
@@ -0,0 +1,92 @@
|
||||
// @ts-check
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const tsc = require("gulp-typescript");
|
||||
const Vinyl = require("vinyl");
|
||||
const { Readable, Writable } = require("stream");
|
||||
|
||||
/** @type {tsc.Project} */
|
||||
let project;
|
||||
|
||||
/** @type {Readable} */
|
||||
let inputStream;
|
||||
|
||||
/** @type {Writable} */
|
||||
let outputStream;
|
||||
|
||||
/** @type {tsc.CompileStream} */
|
||||
let compileStream;
|
||||
|
||||
process.on("message", ({ method, params }) => {
|
||||
try {
|
||||
if (method === "createProject") {
|
||||
const { tsConfigFileName, settings, options } = params;
|
||||
if (options.typescript) {
|
||||
settings.typescript = require(options.typescript);
|
||||
}
|
||||
project = tsc.createProject(tsConfigFileName, settings);
|
||||
inputStream = new Readable({
|
||||
objectMode: true,
|
||||
read() {}
|
||||
});
|
||||
outputStream = new Writable({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {*} file
|
||||
*/
|
||||
write(file, encoding, callback) {
|
||||
process.send({
|
||||
method: "write",
|
||||
params: {
|
||||
path: file.path,
|
||||
cwd: file.cwd,
|
||||
base: file.base,
|
||||
contents: file.contents.toString(),
|
||||
sourceMap: file.sourceMap
|
||||
}
|
||||
});
|
||||
callback();
|
||||
},
|
||||
final(callback) {
|
||||
process.send({ method: "final" });
|
||||
callback();
|
||||
}
|
||||
});
|
||||
outputStream.on("error", error => {
|
||||
process.send({
|
||||
method: "error",
|
||||
params: {
|
||||
name: error.name,
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
}
|
||||
});
|
||||
});
|
||||
compileStream = project();
|
||||
inputStream.pipe(compileStream).pipe(outputStream);
|
||||
}
|
||||
else if (method === "write") {
|
||||
const file = new Vinyl({
|
||||
path: params.path,
|
||||
cwd: params.cwd,
|
||||
base: params.base
|
||||
});
|
||||
file.contents = fs.readFileSync(file.path);
|
||||
if (params.sourceMap) file.sourceMap = params.sourceMap;
|
||||
inputStream.push(/** @type {*} */(file));
|
||||
}
|
||||
else if (method === "final") {
|
||||
inputStream.push(null);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
process.send({
|
||||
method: "error",
|
||||
params: {
|
||||
name: e.name,
|
||||
message: e.message,
|
||||
stack: e.stack
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -46,7 +46,7 @@ class DeclarationsWalker {
|
||||
if (!s) {
|
||||
return;
|
||||
}
|
||||
if (s.name === "Array") {
|
||||
if (s.name === "Array" || s.name === "ReadOnlyArray") {
|
||||
// we should process type argument instead
|
||||
return this.processType((<any>type).typeArguments[0]);
|
||||
}
|
||||
@@ -55,7 +55,7 @@ class DeclarationsWalker {
|
||||
if (declarations) {
|
||||
for (const decl of declarations) {
|
||||
const sourceFile = decl.getSourceFile();
|
||||
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
|
||||
if (sourceFile === this.protocolFile || /lib(\..+)?\.d.ts/.test(path.basename(sourceFile.fileName))) {
|
||||
return;
|
||||
}
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration && !isStringEnum(decl as ts.EnumDeclaration)) {
|
||||
@@ -121,23 +121,30 @@ class DeclarationsWalker {
|
||||
}
|
||||
|
||||
function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptServicesDts: string) {
|
||||
const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: <string[]>[], stripInternal: true };
|
||||
const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: false, types: <string[]>[], stripInternal: true };
|
||||
|
||||
/**
|
||||
* 1st pass - generate a program from protocol.ts and typescriptservices.d.ts and emit core version of protocol.d.ts with all internal members stripped
|
||||
* @return text of protocol.d.t.s
|
||||
*/
|
||||
function getInitialDtsFileForProtocol() {
|
||||
const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
|
||||
const program = ts.createProgram([protocolTs, typeScriptServicesDts, path.join(typeScriptServicesDts, "../lib.es5.d.ts")], options);
|
||||
|
||||
let protocolDts: string | undefined;
|
||||
program.emit(program.getSourceFile(protocolTs), (file, content) => {
|
||||
const emitResult = program.emit(program.getSourceFile(protocolTs), (file, content) => {
|
||||
if (endsWith(file, ".d.ts")) {
|
||||
protocolDts = content;
|
||||
}
|
||||
});
|
||||
|
||||
if (protocolDts === undefined) {
|
||||
throw new Error(`Declaration file for protocol.ts is not generated`)
|
||||
const diagHost: ts.FormatDiagnosticsHost = {
|
||||
getCanonicalFileName: function (f) { return f; },
|
||||
getCurrentDirectory: function() { return '.'; },
|
||||
getNewLine: function() { return "\r\n"; }
|
||||
}
|
||||
const diags = emitResult.diagnostics.map(d => ts.formatDiagnostic(d, diagHost)).join("\r\n");
|
||||
throw new Error(`Declaration file for protocol.ts is not generated:\r\n${diags}`);
|
||||
}
|
||||
return protocolDts;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import path = require("path");
|
||||
import fs = require("fs");
|
||||
|
||||
interface DiagnosticDetails {
|
||||
category: string;
|
||||
code: number;
|
||||
@@ -5,32 +8,36 @@ interface DiagnosticDetails {
|
||||
isEarly?: boolean;
|
||||
}
|
||||
|
||||
type InputDiagnosticMessageTable = ts.Map<DiagnosticDetails>;
|
||||
type InputDiagnosticMessageTable = Map<string, DiagnosticDetails>;
|
||||
|
||||
function main(): void {
|
||||
const sys = ts.sys;
|
||||
if (sys.args.length < 1) {
|
||||
sys.write("Usage:" + sys.newLine);
|
||||
sys.write("\tnode processDiagnosticMessages.js <diagnostic-json-input-file>" + sys.newLine);
|
||||
if (process.argv.length < 3) {
|
||||
console.log("Usage:");
|
||||
console.log("\tnode processDiagnosticMessages.js <diagnostic-json-input-file>");
|
||||
return;
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, contents: string) {
|
||||
const inputDirectory = ts.getDirectoryPath(inputFilePath);
|
||||
const fileOutputPath = ts.combinePaths(inputDirectory, fileName);
|
||||
sys.writeFile(fileOutputPath, contents);
|
||||
fs.writeFile(path.join(path.dirname(inputFilePath), fileName), contents, { encoding: "utf-8" }, err => {
|
||||
if (err) throw err;
|
||||
})
|
||||
}
|
||||
|
||||
const inputFilePath = sys.args[0].replace(/\\/g, "/");
|
||||
const inputStr = sys.readFile(inputFilePath)!;
|
||||
const inputFilePath = process.argv[2].replace(/\\/g, "/");
|
||||
console.log(`Reading diagnostics from ${inputFilePath}`);
|
||||
const inputStr = fs.readFileSync(inputFilePath, { encoding: "utf-8" });
|
||||
|
||||
const diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
|
||||
|
||||
const diagnosticMessages: InputDiagnosticMessageTable = ts.createMapFromTemplate(diagnosticMessagesJson);
|
||||
const diagnosticMessages: InputDiagnosticMessageTable = new Map();
|
||||
for (const key in diagnosticMessagesJson) {
|
||||
if (Object.hasOwnProperty.call(diagnosticMessagesJson, key)) {
|
||||
diagnosticMessages.set(key, diagnosticMessagesJson[key]);
|
||||
}
|
||||
}
|
||||
|
||||
const outputFilesDir = ts.getDirectoryPath(inputFilePath);
|
||||
const thisFilePathRel = ts.getRelativePathToDirectoryOrUrl(outputFilesDir, sys.getExecutingFilePath(),
|
||||
sys.getCurrentDirectory(), ts.createGetCanonicalFileName(sys.useCaseSensitiveFileNames), /* isAbsolutePathAnUrl */ false);
|
||||
const outputFilesDir = path.dirname(inputFilePath);
|
||||
const thisFilePathRel = path.relative(process.cwd(), outputFilesDir);
|
||||
|
||||
const infoFileOutput = buildInfoFileOutput(diagnosticMessages, "./diagnosticInformationMap.generated.ts", thisFilePathRel);
|
||||
checkForUniqueCodes(diagnosticMessages);
|
||||
@@ -53,7 +60,7 @@ function checkForUniqueCodes(diagnosticTable: InputDiagnosticMessageTable) {
|
||||
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, inputFilePathRel: string, thisFilePathRel: string): string {
|
||||
let result =
|
||||
"// <auto-generated />\r\n" +
|
||||
"// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel + "'\r\n" +
|
||||
"// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel.replace(/\\/g, '/') + "'\r\n" +
|
||||
"/* @internal */\r\n" +
|
||||
"namespace ts {\r\n" +
|
||||
" function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}): DiagnosticMessage {\r\n" +
|
||||
@@ -112,4 +119,4 @@ function convertPropertyName(origName: string): string {
|
||||
return result;
|
||||
}
|
||||
|
||||
main();
|
||||
main();
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"removeComments": false,
|
||||
"outFile": "processDiagnosticMessages.js",
|
||||
"target": "es5",
|
||||
"declaration": false,
|
||||
"lib": [
|
||||
"es6",
|
||||
"scripthost"
|
||||
]
|
||||
],
|
||||
"types": ["node"]
|
||||
},
|
||||
"files": [
|
||||
"../src/compiler/types.ts",
|
||||
"../src/compiler/performance.ts",
|
||||
"../src/compiler/core.ts",
|
||||
"../src/compiler/sys.ts",
|
||||
|
||||
"processDiagnosticMessages.ts"
|
||||
]
|
||||
}
|
||||
|
||||
100
scripts/produceLKG.ts
Normal file
100
scripts/produceLKG.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import childProcess = require('child_process');
|
||||
import fs = require('fs-extra');
|
||||
import path = require('path');
|
||||
import removeInternal = require('remove-internal');
|
||||
import glob = require('glob');
|
||||
|
||||
const root = path.join(__dirname, "..");
|
||||
const source = path.join(root, "built/local");
|
||||
const dest = path.join(root, "lib");
|
||||
const copyright = fs.readFileSync(path.join(__dirname, "../CopyrightNotice.txt"), "utf-8");
|
||||
|
||||
async function produceLKG() {
|
||||
console.log(`Building LKG from ${source} to ${dest}`);
|
||||
await copyLibFiles();
|
||||
await copyLocalizedDiagnostics();
|
||||
await buildProtocol();
|
||||
await copyScriptOutputs();
|
||||
await buildTsc();
|
||||
await copyDeclarationOutputs();
|
||||
await writeGitAttributes();
|
||||
}
|
||||
|
||||
async function copyLibFiles() {
|
||||
await copyFilesWithGlob("lib?(.*).d.ts");
|
||||
}
|
||||
|
||||
async function copyLocalizedDiagnostics() {
|
||||
const dir = await fs.readdir(source);
|
||||
for (const d of dir) {
|
||||
const fileName = path.join(source, d);
|
||||
if (fs.statSync(fileName).isDirectory()) {
|
||||
if (d === 'tslint') continue;
|
||||
await fs.copy(fileName, path.join(dest, d));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function buildProtocol() {
|
||||
const protocolScript = path.join(__dirname, "buildProtocol.js");
|
||||
if (!fs.existsSync(protocolScript)) {
|
||||
throw new Error(`Expected protocol script ${protocolScript} to exist`);
|
||||
}
|
||||
|
||||
const protocolInput = path.join(__dirname, "../src/server/protocol.ts");
|
||||
const protocolServices = path.join(source, "typescriptServices.d.ts");
|
||||
const protocolOutput = path.join(dest, "protocol.d.ts");
|
||||
|
||||
console.log(`Building ${protocolOutput}...`);
|
||||
await exec(protocolScript, [protocolInput, protocolServices, protocolOutput]);
|
||||
}
|
||||
|
||||
async function copyScriptOutputs() {
|
||||
await copyWithCopyright("tsserver.js");
|
||||
await copyWithCopyright("tsc.js");
|
||||
await copyWithCopyright("watchGuard.js");
|
||||
await copyWithCopyright("cancellationToken.js");
|
||||
await copyWithCopyright("typingsInstaller.js");
|
||||
}
|
||||
|
||||
async function buildTsc() {
|
||||
await exec(path.join(source, "tsc.js"), [`-b -f ${path.join(root, "src/tsc/tsconfig.release.json")}`]);
|
||||
}
|
||||
|
||||
async function copyDeclarationOutputs() {
|
||||
await copyWithCopyright("typescript.d.ts");
|
||||
await copyWithCopyright("typescriptServices.d.ts");
|
||||
await copyWithCopyright("tsserverlibrary.d.ts");
|
||||
}
|
||||
|
||||
async function writeGitAttributes() {
|
||||
await fs.writeFile(path.join(dest, ".gitattributes"), `* text eol=lf`, "utf-8");
|
||||
}
|
||||
|
||||
async function copyWithCopyright(fileName: string) {
|
||||
const content = await fs.readFile(path.join(source, fileName), "utf-8");
|
||||
await fs.writeFile(path.join(dest, fileName), copyright + "\r\n" + content);
|
||||
}
|
||||
|
||||
async function copyFromBuiltLocal(fileName: string) {
|
||||
await fs.copy(path.join(source, fileName), path.join(dest, fileName));
|
||||
}
|
||||
|
||||
async function copyFilesWithGlob(pattern: string) {
|
||||
const files = glob.sync(path.join(source, pattern)).map(f => path.basename(f));
|
||||
for (const f of files) {
|
||||
await copyFromBuiltLocal(f);
|
||||
}
|
||||
console.log(`Copied ${files.length} files matching pattern ${pattern}`);
|
||||
}
|
||||
|
||||
async function exec(path: string, args: string[] = []) {
|
||||
const cmdLine = ["node", path, ...args].join(" ");
|
||||
console.log(cmdLine);
|
||||
childProcess.execSync(cmdLine);
|
||||
}
|
||||
|
||||
process.on("unhandledRejection", err => { throw err; });
|
||||
produceLKG().then(() => console.log("Done"), err => { throw err; });
|
||||
20
scripts/tsconfig.json
Normal file
20
scripts/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"removeComments": false,
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"lib": [
|
||||
"es6",
|
||||
"scripthost"
|
||||
],
|
||||
"types": ["node"]
|
||||
},
|
||||
"files": [
|
||||
"produceLKG.ts",
|
||||
"buildProtocol.ts",
|
||||
"processDiagnosticMessages.ts",
|
||||
"generateLocalizedDiagnosticMessages.ts",
|
||||
"configurePrerelease.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es6"],
|
||||
"sourceMap": false,
|
||||
"declaration": false,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
@@ -8,6 +10,10 @@
|
||||
"noUnusedParameters": true,
|
||||
"strictNullChecks": true,
|
||||
"module": "commonjs",
|
||||
"outDir": "../../built/local/tslint"
|
||||
"outDir": "../../built/local/tslint",
|
||||
"baseUrl": "../..",
|
||||
"paths": {
|
||||
"typescript": ["lib/typescript.d.ts"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user