Files
vscode/build/lib/tsb/builder.js

505 lines
42 KiB
JavaScript

"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTypeScriptBuilder = exports.CancellationToken = void 0;
const fs_1 = require("fs");
const path = require("path");
const crypto = require("crypto");
const utils = require("./utils");
const colors = require("ansi-colors");
const ts = require("typescript");
const Vinyl = require("vinyl");
var CancellationToken;
(function (CancellationToken) {
CancellationToken.None = {
isCancellationRequested() { return false; }
};
})(CancellationToken = exports.CancellationToken || (exports.CancellationToken = {}));
function normalize(path) {
return path.replace(/\\/g, '/');
}
function createTypeScriptBuilder(config, projectFile, cmd) {
const _log = config.logFn;
const host = new LanguageServiceHost(cmd, projectFile, _log);
const service = ts.createLanguageService(host, ts.createDocumentRegistry());
const lastBuildVersion = Object.create(null);
const lastDtsHash = Object.create(null);
const userWantsDeclarations = cmd.options.declaration;
let oldErrors = Object.create(null);
let headUsed = process.memoryUsage().heapUsed;
let emitSourceMapsInStream = true;
// always emit declaraction files
host.getCompilationSettings().declaration = true;
function file(file) {
// support gulp-sourcemaps
if (file.sourceMap) {
emitSourceMapsInStream = false;
}
if (!file.contents) {
host.removeScriptSnapshot(file.path);
}
else {
host.addScriptSnapshot(file.path, new VinylScriptSnapshot(file));
}
}
function baseFor(snapshot) {
if (snapshot instanceof VinylScriptSnapshot) {
return cmd.options.outDir || snapshot.getBase();
}
else {
return '';
}
}
function isExternalModule(sourceFile) {
return sourceFile.externalModuleIndicator
|| /declare\s+module\s+('|")(.+)\1/.test(sourceFile.getText());
}
function build(out, onError, token = CancellationToken.None) {
function checkSyntaxSoon(fileName) {
return new Promise(resolve => {
process.nextTick(function () {
if (!host.getScriptSnapshot(fileName, false)) {
resolve([]); // no script, no problems
}
else {
resolve(service.getSyntacticDiagnostics(fileName));
}
});
});
}
function checkSemanticsSoon(fileName) {
return new Promise(resolve => {
process.nextTick(function () {
if (!host.getScriptSnapshot(fileName, false)) {
resolve([]); // no script, no problems
}
else {
resolve(service.getSemanticDiagnostics(fileName));
}
});
});
}
function emitSoon(fileName) {
return new Promise(resolve => {
process.nextTick(function () {
if (/\.d\.ts$/.test(fileName)) {
// if it's already a d.ts file just emit it signature
const snapshot = host.getScriptSnapshot(fileName);
const signature = crypto.createHash('md5')
.update(snapshot.getText(0, snapshot.getLength()))
.digest('base64');
return resolve({
fileName,
signature,
files: []
});
}
const output = service.getEmitOutput(fileName);
const files = [];
let signature;
for (const file of output.outputFiles) {
if (!emitSourceMapsInStream && /\.js\.map$/.test(file.name)) {
continue;
}
if (/\.d\.ts$/.test(file.name)) {
signature = crypto.createHash('md5')
.update(file.text)
.digest('base64');
if (!userWantsDeclarations) {
// don't leak .d.ts files if users don't want them
continue;
}
}
const vinyl = new Vinyl({
path: file.name,
contents: Buffer.from(file.text),
base: !config._emitWithoutBasePath && baseFor(host.getScriptSnapshot(fileName)) || undefined
});
if (!emitSourceMapsInStream && /\.js$/.test(file.name)) {
const sourcemapFile = output.outputFiles.filter(f => /\.js\.map$/.test(f.name))[0];
if (sourcemapFile) {
const extname = path.extname(vinyl.relative);
const basename = path.basename(vinyl.relative, extname);
const dirname = path.dirname(vinyl.relative);
const tsname = (dirname === '.' ? '' : dirname + '/') + basename + '.ts';
const sourceMap = JSON.parse(sourcemapFile.text);
sourceMap.sources[0] = tsname.replace(/\\/g, '/');
vinyl.sourceMap = sourceMap;
}
}
files.push(vinyl);
}
resolve({
fileName,
signature,
files
});
});
});
}
const newErrors = Object.create(null);
const t1 = Date.now();
const toBeEmitted = [];
const toBeCheckedSyntactically = [];
const toBeCheckedSemantically = [];
const filesWithChangedSignature = [];
const dependentFiles = [];
const newLastBuildVersion = new Map();
for (const fileName of host.getScriptFileNames()) {
if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) {
toBeEmitted.push(fileName);
toBeCheckedSyntactically.push(fileName);
toBeCheckedSemantically.push(fileName);
}
}
return new Promise(resolve => {
const semanticCheckInfo = new Map();
const seenAsDependentFile = new Set();
function workOnNext() {
let promise;
// let fileName: string;
// someone told us to stop this
if (token.isCancellationRequested()) {
_log('[CANCEL]', '>>This compile run was cancelled<<');
newLastBuildVersion.clear();
resolve();
return;
}
// (1st) emit code
else if (toBeEmitted.length) {
const fileName = toBeEmitted.pop();
promise = emitSoon(fileName).then(value => {
for (const file of value.files) {
_log('[emit code]', file.path);
out(file);
}
// remember when this was build
newLastBuildVersion.set(fileName, host.getScriptVersion(fileName));
// remeber the signature
if (value.signature && lastDtsHash[fileName] !== value.signature) {
lastDtsHash[fileName] = value.signature;
filesWithChangedSignature.push(fileName);
}
}).catch(e => {
// can't just skip this or make a result up..
host.error(`ERROR emitting ${fileName}`);
host.error(e);
});
}
// (2nd) check syntax
else if (toBeCheckedSyntactically.length) {
const fileName = toBeCheckedSyntactically.pop();
_log('[check syntax]', fileName);
promise = checkSyntaxSoon(fileName).then(diagnostics => {
delete oldErrors[fileName];
if (diagnostics.length > 0) {
diagnostics.forEach(d => onError(d));
newErrors[fileName] = diagnostics;
// stop the world when there are syntax errors
toBeCheckedSyntactically.length = 0;
toBeCheckedSemantically.length = 0;
filesWithChangedSignature.length = 0;
}
});
}
// (3rd) check semantics
else if (toBeCheckedSemantically.length) {
let fileName = toBeCheckedSemantically.pop();
while (fileName && semanticCheckInfo.has(fileName)) {
fileName = toBeCheckedSemantically.pop();
}
if (fileName) {
_log('[check semantics]', fileName);
promise = checkSemanticsSoon(fileName).then(diagnostics => {
delete oldErrors[fileName];
semanticCheckInfo.set(fileName, diagnostics.length);
if (diagnostics.length > 0) {
diagnostics.forEach(d => onError(d));
newErrors[fileName] = diagnostics;
}
});
}
}
// (4th) check dependents
else if (filesWithChangedSignature.length) {
while (filesWithChangedSignature.length) {
const fileName = filesWithChangedSignature.pop();
if (!isExternalModule(service.getProgram().getSourceFile(fileName))) {
_log('[check semantics*]', fileName + ' is an internal module and it has changed shape -> check whatever hasn\'t been checked yet');
toBeCheckedSemantically.push(...host.getScriptFileNames());
filesWithChangedSignature.length = 0;
dependentFiles.length = 0;
break;
}
host.collectDependents(fileName, dependentFiles);
}
}
// (5th) dependents contd
else if (dependentFiles.length) {
let fileName = dependentFiles.pop();
while (fileName && seenAsDependentFile.has(fileName)) {
fileName = dependentFiles.pop();
}
if (fileName) {
seenAsDependentFile.add(fileName);
const value = semanticCheckInfo.get(fileName);
if (value === 0) {
// already validated successfully -> look at dependents next
host.collectDependents(fileName, dependentFiles);
}
else if (typeof value === 'undefined') {
// first validate -> look at dependents next
dependentFiles.push(fileName);
toBeCheckedSemantically.push(fileName);
}
}
}
// (last) done
else {
resolve();
return;
}
if (!promise) {
promise = Promise.resolve();
}
promise.then(function () {
// change to change
process.nextTick(workOnNext);
}).catch(err => {
console.error(err);
});
}
workOnNext();
}).then(() => {
// store the build versions to not rebuilt the next time
newLastBuildVersion.forEach((value, key) => {
lastBuildVersion[key] = value;
});
// print old errors and keep them
utils.collections.forEach(oldErrors, entry => {
entry.value.forEach(diag => onError(diag));
newErrors[entry.key] = entry.value;
});
oldErrors = newErrors;
// print stats
const headNow = process.memoryUsage().heapUsed;
const MB = 1024 * 1024;
_log('[tsb]', `time: ${colors.yellow((Date.now() - t1) + 'ms')} + \nmem: ${colors.cyan(Math.ceil(headNow / MB) + 'MB')} ${colors.bgCyan('delta: ' + Math.ceil((headNow - headUsed) / MB))}`);
headUsed = headNow;
});
}
return {
file,
build,
languageService: service
};
}
exports.createTypeScriptBuilder = createTypeScriptBuilder;
class ScriptSnapshot {
_text;
_mtime;
constructor(text, mtime) {
this._text = text;
this._mtime = mtime;
}
getVersion() {
return this._mtime.toUTCString();
}
getText(start, end) {
return this._text.substring(start, end);
}
getLength() {
return this._text.length;
}
getChangeRange(_oldSnapshot) {
return undefined;
}
}
class VinylScriptSnapshot extends ScriptSnapshot {
_base;
constructor(file) {
super(file.contents.toString(), file.stat.mtime);
this._base = file.base;
}
getBase() {
return this._base;
}
}
class LanguageServiceHost {
_cmdLine;
_projectPath;
_log;
_snapshots;
_filesInProject;
_filesAdded;
_dependencies;
_dependenciesRecomputeList;
_fileNameToDeclaredModule;
_projectVersion;
constructor(_cmdLine, _projectPath, _log) {
this._cmdLine = _cmdLine;
this._projectPath = _projectPath;
this._log = _log;
this._snapshots = Object.create(null);
this._filesInProject = new Set(_cmdLine.fileNames);
this._filesAdded = new Set();
this._dependencies = new utils.graph.Graph(s => s);
this._dependenciesRecomputeList = [];
this._fileNameToDeclaredModule = Object.create(null);
this._projectVersion = 1;
}
log(_s) {
// console.log(s);
}
trace(_s) {
// console.log(s);
}
error(s) {
console.error(s);
}
getCompilationSettings() {
return this._cmdLine.options;
}
getProjectVersion() {
return String(this._projectVersion);
}
getScriptFileNames() {
const res = Object.keys(this._snapshots).filter(path => this._filesInProject.has(path) || this._filesAdded.has(path));
return res;
}
getScriptVersion(filename) {
filename = normalize(filename);
const result = this._snapshots[filename];
if (result) {
return result.getVersion();
}
return 'UNKNWON_FILE_' + Math.random().toString(16).slice(2);
}
getScriptSnapshot(filename, resolve = true) {
filename = normalize(filename);
let result = this._snapshots[filename];
if (!result && resolve) {
try {
result = new VinylScriptSnapshot(new Vinyl({
path: filename,
contents: (0, fs_1.readFileSync)(filename),
base: this.getCompilationSettings().outDir,
stat: (0, fs_1.statSync)(filename)
}));
this.addScriptSnapshot(filename, result);
}
catch (e) {
// ignore
}
}
return result;
}
static _declareModule = /declare\s+module\s+('|")(.+)\1/g;
addScriptSnapshot(filename, snapshot) {
this._projectVersion++;
filename = normalize(filename);
const old = this._snapshots[filename];
if (!old && !this._filesInProject.has(filename) && !filename.endsWith('.d.ts')) {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// not very proper!
this._filesAdded.add(filename);
}
if (!old || old.getVersion() !== snapshot.getVersion()) {
this._dependenciesRecomputeList.push(filename);
const node = this._dependencies.lookup(filename);
if (node) {
node.outgoing = Object.create(null);
}
// (cheap) check for declare module
LanguageServiceHost._declareModule.lastIndex = 0;
let match;
while ((match = LanguageServiceHost._declareModule.exec(snapshot.getText(0, snapshot.getLength())))) {
let declaredModules = this._fileNameToDeclaredModule[filename];
if (!declaredModules) {
this._fileNameToDeclaredModule[filename] = declaredModules = [];
}
declaredModules.push(match[2]);
}
}
this._snapshots[filename] = snapshot;
return old;
}
removeScriptSnapshot(filename) {
this._filesInProject.delete(filename);
this._filesAdded.delete(filename);
this._projectVersion++;
filename = normalize(filename);
delete this._fileNameToDeclaredModule[filename];
return delete this._snapshots[filename];
}
getCurrentDirectory() {
return path.dirname(this._projectPath);
}
getDefaultLibFileName(options) {
return ts.getDefaultLibFilePath(options);
}
directoryExists = ts.sys.directoryExists;
getDirectories = ts.sys.getDirectories;
fileExists = ts.sys.fileExists;
readFile = ts.sys.readFile;
readDirectory = ts.sys.readDirectory;
// ---- dependency management
collectDependents(filename, target) {
while (this._dependenciesRecomputeList.length) {
this._processFile(this._dependenciesRecomputeList.pop());
}
filename = normalize(filename);
const node = this._dependencies.lookup(filename);
if (node) {
utils.collections.forEach(node.incoming, entry => target.push(entry.key));
}
}
_processFile(filename) {
if (filename.match(/.*\.d\.ts$/)) {
return;
}
filename = normalize(filename);
const snapshot = this.getScriptSnapshot(filename);
if (!snapshot) {
this._log('processFile', `Missing snapshot for: ${filename}`);
return;
}
const info = ts.preProcessFile(snapshot.getText(0, snapshot.getLength()), true);
// (1) ///-references
info.referencedFiles.forEach(ref => {
const resolvedPath = path.resolve(path.dirname(filename), ref.fileName);
const normalizedPath = normalize(resolvedPath);
this._dependencies.inertEdge(filename, normalizedPath);
});
// (2) import-require statements
info.importedFiles.forEach(ref => {
const stopDirname = normalize(this.getCurrentDirectory());
let dirname = filename;
let found = false;
while (!found && dirname.indexOf(stopDirname) === 0) {
dirname = path.dirname(dirname);
const resolvedPath = path.resolve(dirname, ref.fileName);
const normalizedPath = normalize(resolvedPath);
if (this.getScriptSnapshot(normalizedPath + '.ts')) {
this._dependencies.inertEdge(filename, normalizedPath + '.ts');
found = true;
}
else if (this.getScriptSnapshot(normalizedPath + '.d.ts')) {
this._dependencies.inertEdge(filename, normalizedPath + '.d.ts');
found = true;
}
}
if (!found) {
for (const key in this._fileNameToDeclaredModule) {
if (this._fileNameToDeclaredModule[key] && ~this._fileNameToDeclaredModule[key].indexOf(ref.fileName)) {
this._dependencies.inertEdge(filename, key);
}
}
}
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Z0dBR2dHOzs7QUFFaEcsMkJBQTRDO0FBQzVDLDZCQUE2QjtBQUM3QixpQ0FBaUM7QUFDakMsaUNBQWlDO0FBQ2pDLHNDQUFzQztBQUN0QyxpQ0FBaUM7QUFDakMsK0JBQStCO0FBVy9CLElBQWlCLGlCQUFpQixDQUlqQztBQUpELFdBQWlCLGlCQUFpQjtJQUNwQixzQkFBSSxHQUFzQjtRQUN0Qyx1QkFBdUIsS0FBSyxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUM7S0FDM0MsQ0FBQztBQUNILENBQUMsRUFKZ0IsaUJBQWlCLEdBQWpCLHlCQUFpQixLQUFqQix5QkFBaUIsUUFJakM7QUFRRCxTQUFTLFNBQVMsQ0FBQyxJQUFZO0lBQzlCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDakMsQ0FBQztBQUVELFNBQWdCLHVCQUF1QixDQUFDLE1BQXNCLEVBQUUsV0FBbUIsRUFBRSxHQUF5QjtJQUU3RyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBRTFCLE1BQU0sSUFBSSxHQUFHLElBQUksbUJBQW1CLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3RCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLENBQUM7SUFDNUUsTUFBTSxnQkFBZ0IsR0FBK0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6RSxNQUFNLFdBQVcsR0FBK0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwRSxNQUFNLHFCQUFxQixHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO0lBQ3RELElBQUksU0FB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