UNPKG

roblox-ts

Version:

<div align="center"><img width=25% src="https://i.imgur.com/yCjHmng.png"></div> <h1 align="center"><a href="https://roblox-ts.github.io/">roblox-ts</a></h1> <div align="center">A TypeScript-to-Lua Compiler for Roblox</div> <br> <div align="center"> <a hr

708 lines 34.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_extra_1 = __importDefault(require("fs-extra")); const klaw_1 = __importDefault(require("klaw")); const luamin_1 = require("luamin"); const path_1 = __importDefault(require("path")); const ts = __importStar(require("ts-morph")); const compiler_1 = require("./compiler"); const CompilerState_1 = require("./CompilerState"); const CompilerError_1 = require("./errors/CompilerError"); const DiagnosticError_1 = require("./errors/DiagnosticError"); const ProjectError_1 = require("./errors/ProjectError"); const RojoProject_1 = require("./RojoProject"); const utility_1 = require("./utility"); const MINIMUM_RBX_TYPES_VERSION = 203; const LIB_PATH = path_1.default.resolve(__dirname, "..", "lib"); const ROJO_FILE_REGEX = /^.+\.project\.json$/; const ROJO_DEFAULT_NAME = "default.project.json"; const ROJO_OLD_NAME = "roblox-project.json"; const IGNORED_DIAGNOSTIC_CODES = [ 2688, 6054, ]; const LUA_EXT = ".lua"; function getLuaFiles(sourceFolder) { return new Promise((resolve, reject) => { const result = new Array(); klaw_1.default(sourceFolder) .on("data", item => { if (item.stats.isFile() && path_1.default.extname(item.path) === LUA_EXT) { result.push(item.path); } }) .on("end", () => resolve(result)) .on("error", reject); }); } function joinIfNotAbsolute(basePath, relativePath) { if (path_1.default.isAbsolute(relativePath)) { return relativePath; } else { return path_1.default.join(basePath, relativePath); } } function copyLuaFiles(sourceFolder, destinationFolder, transform) { return __awaiter(this, void 0, void 0, function* () { (yield getLuaFiles(sourceFolder)).forEach((oldPath) => __awaiter(this, void 0, void 0, function* () { const newPath = path_1.default.join(destinationFolder, path_1.default.relative(sourceFolder, oldPath)); let source = yield fs_extra_1.default.readFile(oldPath, "utf8"); if (transform) { source = transform(source); } if (!(yield fs_extra_1.default.pathExists(newPath)) || (yield fs_extra_1.default.readFile(newPath, "utf8")) !== source) { yield fs_extra_1.default.ensureFile(newPath); yield fs_extra_1.default.writeFile(newPath, source); } })); }); } function cleanDeadLuaFiles(sourceFolder, destinationFolder) { return __awaiter(this, void 0, void 0, function* () { function searchForDeadFiles(dir) { return __awaiter(this, void 0, void 0, function* () { if (yield fs_extra_1.default.pathExists(dir)) { for (const fileName of yield fs_extra_1.default.readdir(dir)) { const filePath = path_1.default.join(dir, fileName); try { const stats = yield fs_extra_1.default.stat(filePath); if (stats.isDirectory()) { searchForDeadFiles(filePath); if ((yield fs_extra_1.default.readdir(dir)).length === 0) { fs_extra_1.default.remove(filePath); console.log("delete", "dir", filePath); } } else if (stats.isFile()) { const relativeToDestFolder = path_1.default.relative(destinationFolder, filePath); if (!(yield fs_extra_1.default.existsSync(path_1.default.join(sourceFolder, relativeToDestFolder)))) { fs_extra_1.default.remove(filePath); console.log("delete", "file", filePath); } } } catch (e) { console.log("failed to clean", filePath); } } } }); } yield searchForDeadFiles(destinationFolder); }); } function copyAndCleanDeadLuaFiles(sourceFolder, destinationFolder, transform) { return __awaiter(this, void 0, void 0, function* () { yield copyLuaFiles(sourceFolder, destinationFolder, transform); yield cleanDeadLuaFiles(sourceFolder, destinationFolder); }); } var ProjectType; (function (ProjectType) { ProjectType[ProjectType["Game"] = 0] = "Game"; ProjectType[ProjectType["Bundle"] = 1] = "Bundle"; ProjectType[ProjectType["Package"] = 2] = "Package"; })(ProjectType = exports.ProjectType || (exports.ProjectType = {})); class Project { constructor(opts = {}) { this.project = {}; this.compilerOptions = {}; this.projectPath = ""; this.projectInfo = { type: ProjectType.Package }; this.virtualFileNum = 1; // cli mode if (opts.project !== undefined && opts.includePath !== undefined && opts.rojo !== undefined) { this.configFilePath = path_1.default.resolve(opts.project); this.reloadProject(); this.noInclude = opts.noInclude === true; this.includePath = joinIfNotAbsolute(this.projectPath, opts.includePath); this.minify = opts.minify === true; this.luaSourceTransformer = this.minify ? luamin_1.minify : undefined; this.modulesPath = path_1.default.join(this.includePath, "node_modules"); this.rojoOverridePath = opts.rojo !== "" ? joinIfNotAbsolute(this.projectPath, opts.rojo) : undefined; this.ci = opts.ci === true; try { this.validateRbxTypes(); } catch (e) { if (e instanceof ProjectError_1.ProjectError) { console.log(utility_1.red("Compiler Error:"), e.message); process.exit(1); } else { throw e; } } const rootDirPath = this.compilerOptions.rootDir; if (!rootDirPath) { throw new ProjectError_1.ProjectError("Expected 'rootDir' option in tsconfig.json!", ProjectError_1.ProjectErrorType.MissingRootDir); } this.rootDirPath = rootDirPath; const outDirPath = this.compilerOptions.outDir; if (!outDirPath) { throw new ProjectError_1.ProjectError("Expected 'outDir' option in tsconfig.json!", ProjectError_1.ProjectErrorType.MissingOutDir); } this.outDirPath = outDirPath; // filter out outDir .d.ts files const outDir = this.project.getDirectory(outDirPath); if (outDir) { this.project.getSourceFiles().forEach(sourceFile => { if (outDir.isAncestorOf(sourceFile)) { this.project.removeSourceFile(sourceFile); } }); } this.modulesDir = this.project.getDirectory(path_1.default.join(this.projectPath, "node_modules")); this.rojoFilePath = this.getRojoFilePath(); this.reloadRojo(); } else { this.configFilePath = ""; this.includePath = ""; this.noInclude = true; this.minify = false; this.modulesPath = ""; this.rootDirPath = ""; this.outDirPath = ""; this.ci = false; this.runtimeOverride = "local TS = ...; -- link to runtime library"; this.project = new ts.Project({ compilerOptions: { allowSyntheticDefaultImports: true, baseUrl: "src", declaration: false, downlevelIteration: true, isolatedModules: true, jsx: ts.ts.JsxEmit.React, jsxFactory: "Roact.createElement", module: ts.ts.ModuleKind.CommonJS, noLib: true, outDir: "out", rootDir: ".", strict: true, target: ts.ts.ScriptTarget.ES2015, typeRoots: ["node_modules/@rbxts"], }, useVirtualFileSystem: true, }); } } reloadProject() { try { fs_extra_1.default.accessSync(this.configFilePath, fs_extra_1.default.constants.R_OK | fs_extra_1.default.constants.W_OK); } catch (e) { throw new Error("Project path does not exist!"); } if (fs_extra_1.default.statSync(this.configFilePath).isDirectory()) { this.configFilePath = path_1.default.resolve(this.configFilePath, "tsconfig.json"); } if (!fs_extra_1.default.existsSync(this.configFilePath) || !fs_extra_1.default.statSync(this.configFilePath).isFile()) { throw new Error("Cannot find tsconfig.json!"); } this.projectPath = path_1.default.resolve(this.configFilePath, ".."); this.project = new ts.Project({ compilerOptions: { configFilePath: this.configFilePath, }, tsConfigFilePath: this.configFilePath, }); this.compilerOptions = this.project.getCompilerOptions(); try { this.validateCompilerOptions(); } catch (e) { if (e instanceof ProjectError_1.ProjectError) { console.log(utility_1.red("Compiler Error:"), e.message); process.exit(1); } else { throw e; } } } reloadRojo() { if (this.rojoFilePath) { try { this.rojoProject = RojoProject_1.RojoProject.fromPathSync(this.rojoFilePath); } catch (e) { if (e instanceof RojoProject_1.RojoProjectError) { console.log("Warning!", "Failed to load Rojo configuration. Import and export statements will not compile.", e.message); } } } if (this.rojoFilePath && this.rojoProject) { const runtimeFsPath = path_1.default.join(this.includePath, "RuntimeLib.lua"); const runtimeLibPath = this.rojoProject.getRbxFromFile(runtimeFsPath).path; if (!runtimeLibPath) { throw new ProjectError_1.ProjectError(`A Rojo project file was found ( ${this.rojoFilePath} ), but contained no data for include folder!`, ProjectError_1.ProjectErrorType.BadRojoInclude); } else if (this.rojoProject.getNetworkType(runtimeFsPath) !== RojoProject_1.NetworkType.Unknown) { throw new ProjectError_1.ProjectError(`Runtime library cannot be in a server-only or client-only container!`, ProjectError_1.ProjectErrorType.BadRojoInclude); } else if (this.rojoProject.isIsolated(runtimeFsPath)) { throw new ProjectError_1.ProjectError(`Runtime library cannot be in an isolated container!`, ProjectError_1.ProjectErrorType.BadRojoInclude); } let type; if (this.rojoProject.isGame()) { type = ProjectType.Game; } else { type = ProjectType.Bundle; } this.projectInfo = { runtimeLibPath, type, }; } else { this.projectInfo = { type: ProjectType.Package }; } } validateCompilerOptions() { const opts = this.compilerOptions; const errors = new Array(); // required compiler options if (opts.downlevelIteration !== true) { errors.push(`${utility_1.yellow(`"downlevelIteration"`)} must be ${utility_1.yellow(`true`)}`); } if (opts.module !== ts.ts.ModuleKind.CommonJS) { errors.push(`${utility_1.yellow(`"module"`)} must be ${utility_1.yellow(`"commonjs"`)}`); } if (opts.noLib !== true) { errors.push(`${utility_1.yellow(`"noLib"`)} must be ${utility_1.yellow(`true`)}`); } if (opts.strict !== true) { errors.push(`${utility_1.yellow(`"strict"`)} must be ${utility_1.yellow(`true`)}`); } if (opts.target !== ts.ts.ScriptTarget.ES2015) { errors.push(`${utility_1.yellow(`"target"`)} must be ${utility_1.yellow(`"es6"`)}`); } if (opts.allowSyntheticDefaultImports !== true) { errors.push(`${utility_1.yellow(`"allowSyntheticDefaultImports"`)} must be ${utility_1.yellow(`true`)}`); } if (opts.declaration !== true && opts.isolatedModules !== true) { errors.push(`${utility_1.yellow(`"isolatedModules"`)} must be ${utility_1.yellow(`true`)}`); } const rbxTsModulesPath = path_1.default.join(this.projectPath, "node_modules", "@rbxts"); if (opts.typeRoots === undefined || opts.typeRoots.find(v => path_1.default.normalize(v) === rbxTsModulesPath) === undefined) { errors.push(`${utility_1.yellow(`"typeRoots"`)} must be ${utility_1.yellow(`[ "node_modules/@rbxts" ]`)}`); } if (opts.types !== undefined) { errors.push(`${utility_1.yellow(`"types"`)} must be ${utility_1.yellow(`undefined`)}`); } // configurable compiler options if (opts.rootDir === undefined) { errors.push(`${utility_1.yellow(`"rootDir"`)} must be defined`); } if (opts.outDir === undefined) { errors.push(`${utility_1.yellow(`"outDir"`)} must be defined`); } // roact compiler options if (opts.jsx !== undefined && opts.jsx !== ts.ts.JsxEmit.React) { errors.push(`${utility_1.yellow(`"jsx"`)} must be ${utility_1.yellow(`"react"`)} or not defined`); } if (opts.jsxFactory !== undefined && opts.jsxFactory !== "Roact.createElement") { errors.push(`${utility_1.yellow(`"jsxFactory"`)} must be ${utility_1.yellow(`"Roact.createElement"`)} or not defined`); } // throw if errors if (errors.length > 0) { throw new ProjectError_1.ProjectError(`Invalid "tsconfig.json" configuration!\n` + "https://roblox-ts.github.io/docs/quick-start#project-folder-setup" + "\n- " + errors.join("\n- "), ProjectError_1.ProjectErrorType.BadTsConfig); } } validateRbxTypes() { const pkgJsonPath = path_1.default.join(this.projectPath, "node_modules", "@rbxts", "types", "package.json"); if (fs_extra_1.default.pathExistsSync(pkgJsonPath)) { const pkgJson = JSON.parse(fs_extra_1.default.readFileSync(pkgJsonPath).toString()); if (pkgJson !== undefined) { const versionStr = pkgJson.version; if (versionStr !== undefined) { const regexMatch = versionStr.match(/\d+$/g); if (regexMatch !== null) { const patchNumber = Number(regexMatch[0]); if (!isNaN(patchNumber)) { if (patchNumber >= MINIMUM_RBX_TYPES_VERSION) { return; } else { throw new ProjectError_1.ProjectError(`@rbxts/types is out of date!\n` + utility_1.yellow(`Installed version: 1.0.${patchNumber}\n`) + utility_1.yellow(`Minimum required version: 1.0.${MINIMUM_RBX_TYPES_VERSION}\n`) + `Run 'npm i @rbxts/types' to fix this.`, ProjectError_1.ProjectErrorType.BadRbxTypes); } } } } } } throw new ProjectError_1.ProjectError(`Could not find @rbxts/types!\n` + `Run 'npm i @rbxts/types' to fix this.`, ProjectError_1.ProjectErrorType.BadRbxTypes); } getRojoFilePath() { if (this.rojoOverridePath) { if (fs_extra_1.default.pathExistsSync(this.rojoOverridePath)) { return this.rojoOverridePath; } } else { const candidates = new Array(); const defaultPath = path_1.default.join(this.projectPath, ROJO_DEFAULT_NAME); if (fs_extra_1.default.pathExistsSync(defaultPath)) { candidates.push(defaultPath); } for (const fileName of fs_extra_1.default.readdirSync(this.projectPath)) { if (fileName !== ROJO_DEFAULT_NAME && (fileName === ROJO_OLD_NAME || ROJO_FILE_REGEX.test(fileName))) { candidates.push(path_1.default.join(this.projectPath, fileName)); } } if (candidates.length > 1) { console.log(utility_1.yellow(`Warning! Multiple *.project.json files found, using ${candidates[0]}`)); } return candidates[0]; } } addFile(filePath) { this.project.addExistingSourceFile(filePath); } removeFile(filePath) { return __awaiter(this, void 0, void 0, function* () { const sourceFile = this.project.getSourceFile(filePath); if (sourceFile) { this.project.removeSourceFile(sourceFile); } yield this.cleanDirRecursive(this.outDirPath); }); } refreshFile(filePath) { return __awaiter(this, void 0, void 0, function* () { const file = this.project.getSourceFile(filePath); if (file) { file.refreshFromFileSystem(); } else { this.project.addExistingSourceFile(filePath); } }); } cleanDirRecursive(dir) { return __awaiter(this, void 0, void 0, function* () { if (yield fs_extra_1.default.pathExists(dir)) { for (const name of yield fs_extra_1.default.readdir(dir)) { const filePath = path_1.default.join(dir, name); if ((yield fs_extra_1.default.stat(filePath)).isDirectory()) { yield this.cleanDirRecursive(filePath); if ((yield fs_extra_1.default.readdir(filePath)).length === 0) { yield fs_extra_1.default.rmdir(filePath); } } else { let ext = path_1.default.extname(filePath); let baseName = path_1.default.basename(filePath, ext); let subext = path_1.default.extname(baseName); baseName = path_1.default.basename(baseName, subext); const relativeToOut = path_1.default.dirname(path_1.default.relative(this.outDirPath, filePath)); const rootPath = path_1.default.join(this.rootDirPath, relativeToOut); if (ext === ".lua") { let exists = false; exists = exists || (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, baseName) + subext + ".ts")); exists = exists || (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, baseName) + subext + ".tsx")); exists = exists || (baseName === "init" && (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, "init") + subext + ".lua"))); exists = exists || (baseName === "init" && (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, "index") + subext + ".ts"))); exists = exists || (baseName === "init" && (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, "index") + subext + ".tsx"))); exists = exists || (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, baseName) + subext + ".lua")); if (!exists) { yield fs_extra_1.default.remove(filePath); console.log("remove", filePath); } } else if (subext === ".d" && ext === ".ts") { if (!this.compilerOptions.declaration) { yield fs_extra_1.default.remove(filePath); console.log("remove", filePath); } else { ext = subext + ext; baseName = path_1.default.basename(filePath, ext); subext = path_1.default.extname(baseName); baseName = path_1.default.basename(baseName, subext); let exists = false; exists = exists || (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, baseName) + subext + ".d.ts")); exists = exists || (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, baseName) + subext + ".ts")); exists = exists || (yield fs_extra_1.default.pathExists(path_1.default.join(rootPath, baseName) + subext + ".tsx")); if (!exists) { yield fs_extra_1.default.remove(filePath); console.log("remove", filePath); } } } } } } }); } getRootDirOrThrow() { if (!this.rootDirPath) { throw new ProjectError_1.ProjectError("Could not find rootDir!", ProjectError_1.ProjectErrorType.MissingRootDir); } return this.rootDirPath; } copyModuleFiles() { return __awaiter(this, void 0, void 0, function* () { if (this.modulesDir && this.projectInfo.type !== ProjectType.Package) { const modulesPath = this.modulesPath; const rbxTsModulesPath = path_1.default.resolve(this.modulesDir.getPath(), "@rbxts"); if (yield fs_extra_1.default.pathExists(rbxTsModulesPath)) { for (const name of yield fs_extra_1.default.readdir(rbxTsModulesPath)) { const oldModulePath = path_1.default.join(rbxTsModulesPath, name); const newModulePath = path_1.default.join(modulesPath, name); yield copyAndCleanDeadLuaFiles(oldModulePath, newModulePath, this.luaSourceTransformer); } } } }); } copyIncludeFiles() { return __awaiter(this, void 0, void 0, function* () { if (!this.noInclude && this.projectInfo.type !== ProjectType.Package) { yield copyLuaFiles(LIB_PATH, this.includePath, this.luaSourceTransformer); } }); } copyLuaFiles() { return __awaiter(this, void 0, void 0, function* () { yield copyLuaFiles(this.rootDirPath, this.outDirPath, this.luaSourceTransformer); }); } copyDtsFiles() { return __awaiter(this, void 0, void 0, function* () { const dtsFiles = new Array(); yield new Promise(resolve => { klaw_1.default(this.rootDirPath) .on("data", item => { if (item.path.endsWith(".d.ts")) { dtsFiles.push(item.path); } }) .on("end", () => resolve()); }); return Promise.all(dtsFiles.map(filePath => { return new Promise(resolve => { const outPath = path_1.default.join(this.outDirPath, path_1.default.relative(this.rootDirPath, filePath)); fs_extra_1.default.readFile(filePath).then(buffer => { const contents = buffer.toString(); fs_extra_1.default.ensureFile(outPath).then(() => { fs_extra_1.default.writeFile(outPath, contents).then(() => resolve()); }); }); }); })); }); } compileAll() { return __awaiter(this, void 0, void 0, function* () { yield this.compileFiles(this.project.getSourceFiles()); if (process.exitCode === 0) { yield this.copyLuaFiles(); if (this.compilerOptions.declaration) { yield this.copyDtsFiles(); } yield this.copyIncludeFiles(); yield this.copyModuleFiles(); } }); } compileFileByPath(filePath) { return __awaiter(this, void 0, void 0, function* () { const ext = path_1.default.extname(filePath); if (ext === ".ts" || ext === ".tsx") { const sourceFile = this.project.getSourceFile(filePath); if (!sourceFile) { throw new ProjectError_1.ProjectError(`No source file for Compiler.compileFileByPath() (filePath = ${filePath})`, ProjectError_1.ProjectErrorType.MissingSourceFile); } return this.compileFiles([sourceFile]); } else if (ext === ".lua") { yield this.copyLuaFiles(); } }); } createCompilerState() { return new CompilerState_1.CompilerState(this.rootDirPath, this.outDirPath, this.projectInfo, this.rojoProject, this.modulesDir, this.runtimeOverride); } compileSource(source) { const sourceFile = this.project.createSourceFile(`file_${this.virtualFileNum++}.ts`, source); let exception; let compiledSource = ""; try { compiledSource = compiler_1.compileSourceFile(this.createCompilerState(), sourceFile); } catch (e) { exception = e; } const errors = this.getDiagnosticErrors([sourceFile]); sourceFile.deleteImmediately(); if (errors.length > 0) { throw new DiagnosticError_1.DiagnosticError(errors); } if (exception) { throw exception; } return compiledSource; } getEmittedDtsFiles() { return __awaiter(this, void 0, void 0, function* () { return new Promise(resolve => { const result = new Array(); klaw_1.default(this.outDirPath) .on("data", item => { if (item.stats.isFile() && item.path.endsWith(".d.ts")) { result.push(item.path); } }) .on("end", () => resolve(result)); }); }); } postProcessDtsFiles() { return __awaiter(this, void 0, void 0, function* () { return Promise.all((yield this.getEmittedDtsFiles()).map(filePath => new Promise(resolve => { fs_extra_1.default.readFile(filePath).then(contentsBuffer => { let fileContents = contentsBuffer.toString(); fileContents = fileContents.replace(/<reference types="([^."]+)" \/>/g, '<reference types="@rbxts/$1" />'); fs_extra_1.default.writeFile(filePath, fileContents).then(() => resolve()); }); }))); }); } getDiagnosticErrors(files) { const errors = new Array(); for (const file of files) { const diagnostics = file .getPreEmitDiagnostics() .filter(diagnostic => diagnostic.getCategory() === ts.DiagnosticCategory.Error) .filter(diagnostic => IGNORED_DIAGNOSTIC_CODES.indexOf(diagnostic.getCode()) === -1); for (const diagnostic of diagnostics) { const diagnosticFile = diagnostic.getSourceFile(); const line = diagnostic.getLineNumber(); let prefix = ""; if (diagnosticFile) { prefix += path_1.default.relative(this.projectPath, diagnosticFile.getFilePath()); if (line) { prefix += ":" + line; } prefix += " - "; } let messageText = diagnostic.getMessageText(); if (messageText instanceof ts.DiagnosticMessageChain) { const textSegments = new Array(); let chain = messageText; while (chain !== undefined) { textSegments.push(chain.getMessageText()); chain = chain.getNext(); } messageText = textSegments.join("\n"); } errors.push(prefix + utility_1.red("Diagnostic Error: ") + messageText); } } return errors; } compileFiles(files) { return __awaiter(this, void 0, void 0, function* () { yield this.cleanDirRecursive(this.outDirPath); process.exitCode = 0; const errors = this.getDiagnosticErrors(files); try { if (errors.length > 0) { process.exitCode = 1; throw new DiagnosticError_1.DiagnosticError(errors); } const sources = new Array(); for (const sourceFile of files) { if (!sourceFile.isDeclarationFile()) { const filePath = sourceFile.getFilePath(); const outPath = utility_1.transformPathToLua(this.rootDirPath, this.outDirPath, filePath); let source = compiler_1.compileSourceFile(this.createCompilerState(), sourceFile); if (this.luaSourceTransformer) { source = this.luaSourceTransformer(source); } sources.push([outPath, source]); } } for (const [filePath, contents] of sources) { if (yield fs_extra_1.default.pathExists(filePath)) { const oldContents = (yield fs_extra_1.default.readFile(filePath)).toString(); if (oldContents === contents) { continue; } } yield fs_extra_1.default.ensureFile(filePath); yield fs_extra_1.default.writeFile(filePath, contents); } if (this.compilerOptions.declaration === true) { yield this.project.emit({ emitOnlyDtsFiles: true }); yield this.postProcessDtsFiles(); } } catch (e) { // do not silence errors for CI tests if (this.ci) { throw e; } if (e instanceof CompilerError_1.CompilerError) { const node = e.node; if (ts.TypeGuards.isSourceFile(node)) { console.log("%s - %s %s", path_1.default.relative(this.projectPath, e.node.getSourceFile().getFilePath()), utility_1.red("Compiler Error:"), e.message); } else { console.log("%s:%d:%d - %s %s", path_1.default.relative(this.projectPath, e.node.getSourceFile().getFilePath()), e.node.getStartLineNumber(), e.node.getNonWhitespaceStart() - e.node.getStartLinePos(), utility_1.red("Compiler Error:"), e.message); } } else if (e instanceof ProjectError_1.ProjectError) { console.log(utility_1.red("Project Error:"), e.message); } else if (e instanceof DiagnosticError_1.DiagnosticError) { console.log(e.toString()); } else { throw e; } process.exitCode = 1; } }); } } exports.Project = Project; //# sourceMappingURL=Project.js.map