roblox-ts
Version:
A TypeScript-to-Luau Compiler for Roblox
212 lines • 8.81 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupProjectWatchProgram = setupProjectWatchProgram;
const chokidar_1 = __importDefault(require("chokidar"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const checkFileName_1 = require("./checkFileName");
const cleanup_1 = require("./cleanup");
const compileFiles_1 = require("./compileFiles");
const copyFiles_1 = require("./copyFiles");
const copyInclude_1 = require("./copyInclude");
const copyItem_1 = require("./copyItem");
const createPathTranslator_1 = require("./createPathTranslator");
const createProgramFactory_1 = require("./createProgramFactory");
const getChangedSourceFiles_1 = require("./getChangedSourceFiles");
const getParsedCommandLine_1 = require("./getParsedCommandLine");
const tryRemoveOutput_1 = require("./tryRemoveOutput");
const isCompilableFile_1 = require("../util/isCompilableFile");
const walkDirectorySync_1 = require("../util/walkDirectorySync");
const constants_1 = require("../../Shared/constants");
const DiagnosticError_1 = require("../../Shared/errors/DiagnosticError");
const assert_1 = require("../../Shared/util/assert");
const getRootDirs_1 = require("../../Shared/util/getRootDirs");
const typescript_1 = __importDefault(require("typescript"));
const CHOKIDAR_OPTIONS = {
awaitWriteFinish: {
pollInterval: 10,
stabilityThreshold: 50,
},
ignoreInitial: true,
disableGlobbing: true,
};
function fixSlashes(fsPath) {
return fsPath.replace(/\\/g, "/");
}
function setupProjectWatchProgram(data, usePolling) {
const { fileNames, options } = (0, getParsedCommandLine_1.getParsedCommandLine)(data);
const fileNamesSet = new Set(fileNames);
let initialCompileCompleted = false;
let collecting = false;
let filesToAdd = new Set();
let filesToChange = new Set();
let filesToDelete = new Set();
const watchReporter = typescript_1.default.createWatchStatusReporter(typescript_1.default.sys, true);
const diagnosticReporter = typescript_1.default.createDiagnosticReporter(typescript_1.default.sys, true);
function reportText(messageText) {
watchReporter({
category: typescript_1.default.DiagnosticCategory.Message,
messageText,
code: 0,
file: undefined,
length: undefined,
start: undefined,
}, typescript_1.default.sys.newLine, options);
}
function reportEmitResult(emitResult) {
for (const diagnostic of emitResult.diagnostics) {
diagnosticReporter(diagnostic);
}
const amtErrors = emitResult.diagnostics.filter(v => v.category === typescript_1.default.DiagnosticCategory.Error).length;
reportText(`Found ${amtErrors} error${amtErrors === 1 ? "" : "s"}. Watching for file changes.`);
}
let program;
let pathTranslator;
const createProgram = (0, createProgramFactory_1.createProgramFactory)(data, options);
function refreshProgram() {
program = createProgram([...fileNamesSet], options);
pathTranslator = (0, createPathTranslator_1.createPathTranslator)(program, data);
}
function runInitialCompile() {
refreshProgram();
(0, assert_1.assert)(program && pathTranslator);
(0, cleanup_1.cleanup)(pathTranslator);
(0, copyInclude_1.copyInclude)(data);
(0, copyFiles_1.copyFiles)(data, pathTranslator, new Set((0, getRootDirs_1.getRootDirs)(options)));
const sourceFiles = (0, getChangedSourceFiles_1.getChangedSourceFiles)(program);
const emitResult = (0, compileFiles_1.compileFiles)(program.getProgram(), data, pathTranslator, sourceFiles);
if (!emitResult.emitSkipped) {
initialCompileCompleted = true;
}
return emitResult;
}
const filesToCompile = new Set();
const filesToCopy = new Set();
const filesToClean = new Set();
function runIncrementalCompile(additions, changes, removals) {
for (const fsPath of additions) {
if (fs_extra_1.default.statSync(fsPath).isDirectory()) {
(0, walkDirectorySync_1.walkDirectorySync)(fsPath, item => {
if ((0, isCompilableFile_1.isCompilableFile)(item)) {
fileNamesSet.add(item);
filesToCompile.add(item);
}
});
}
else if ((0, isCompilableFile_1.isCompilableFile)(fsPath)) {
fileNamesSet.add(fsPath);
filesToCompile.add(fsPath);
}
else {
(0, checkFileName_1.checkFileName)(fsPath);
filesToCopy.add(fsPath);
}
}
for (const fsPath of changes) {
if ((0, isCompilableFile_1.isCompilableFile)(fsPath)) {
filesToCompile.add(fsPath);
}
else {
if (fsPath.endsWith(constants_1.DTS_EXT)) {
const transformerWatcher = data.transformerWatcher;
if (transformerWatcher) {
const contents = typescript_1.default.sys.readFile(fsPath);
if (contents) {
transformerWatcher.updateFile(fsPath, contents);
}
}
}
filesToCopy.add(fsPath);
}
}
for (const fsPath of removals) {
fileNamesSet.delete(fsPath);
filesToClean.add(fsPath);
}
refreshProgram();
(0, assert_1.assert)(program && pathTranslator);
const sourceFiles = (0, getChangedSourceFiles_1.getChangedSourceFiles)(program, options.incremental ? undefined : [...filesToCompile]);
const emitResult = (0, compileFiles_1.compileFiles)(program.getProgram(), data, pathTranslator, sourceFiles);
if (emitResult.emitSkipped) {
return emitResult;
}
for (const fsPath of filesToClean) {
(0, tryRemoveOutput_1.tryRemoveOutput)(pathTranslator, pathTranslator.getOutputPath(fsPath));
if (options.declaration) {
(0, tryRemoveOutput_1.tryRemoveOutput)(pathTranslator, pathTranslator.getOutputDeclarationPath(fsPath));
}
}
for (const fsPath of filesToCopy) {
(0, copyItem_1.copyItem)(data, pathTranslator, fsPath);
}
filesToCompile.clear();
filesToCopy.clear();
filesToClean.clear();
return emitResult;
}
function runCompile() {
try {
if (!initialCompileCompleted) {
return runInitialCompile();
}
else {
const additions = filesToAdd;
const changes = filesToChange;
const removals = filesToDelete;
filesToAdd = new Set();
filesToChange = new Set();
filesToDelete = new Set();
return runIncrementalCompile(additions, changes, removals);
}
}
catch (e) {
if (e instanceof DiagnosticError_1.DiagnosticError) {
return {
emitSkipped: true,
diagnostics: e.diagnostics,
};
}
else {
throw e;
}
}
}
function closeEventCollection() {
collecting = false;
reportEmitResult(runCompile());
}
function openEventCollection() {
if (!collecting) {
collecting = true;
reportText("File change detected. Starting incremental compilation...");
setTimeout(closeEventCollection, 100);
}
}
function collectAddEvent(fsPath) {
filesToAdd.add(fixSlashes(fsPath));
openEventCollection();
}
function collectChangeEvent(fsPath) {
filesToChange.add(fixSlashes(fsPath));
openEventCollection();
}
function collectDeleteEvent(fsPath) {
filesToDelete.add(fixSlashes(fsPath));
openEventCollection();
}
const chokidarOptions = { ...CHOKIDAR_OPTIONS, usePolling };
chokidar_1.default
.watch((0, getRootDirs_1.getRootDirs)(options), chokidarOptions)
.on("add", collectAddEvent)
.on("addDir", collectAddEvent)
.on("change", collectChangeEvent)
.on("unlink", collectDeleteEvent)
.on("unlinkDir", collectDeleteEvent)
.once("ready", () => {
reportText("Starting compilation in watch mode...");
reportEmitResult(runCompile());
});
}
//# sourceMappingURL=setupProjectWatchProgram.js.map