(program: ts.Program, files: ProcessedFile[])
| 86 | } |
| 87 | |
| 88 | export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile] { |
| 89 | const diagnostics: ts.Diagnostic[] = []; |
| 90 | |
| 91 | const options = program.getCompilerOptions() as CompilerOptions; |
| 92 | const bundleFile = cast(options.luaBundle, isNonNull); |
| 93 | const entryModule = cast(options.luaBundleEntry, isNonNull); |
| 94 | |
| 95 | // Resolve project settings relative to project file. |
| 96 | const resolvedEntryModule = path.resolve(getProjectRoot(program), entryModule); |
| 97 | const outputPath = path.resolve(getEmitOutDir(program), bundleFile); |
| 98 | const entryModuleFilePath = |
| 99 | program.getSourceFile(entryModule)?.fileName ?? program.getSourceFile(resolvedEntryModule)?.fileName; |
| 100 | |
| 101 | if (entryModuleFilePath === undefined) { |
| 102 | diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); |
| 103 | } |
| 104 | |
| 105 | // For each file: ["<module path>"] = function() <lua content> end, |
| 106 | const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(f.fileName, program))); |
| 107 | |
| 108 | // Create ____modules table containing all entries from moduleTableEntries |
| 109 | const moduleTable = createModuleTableNode(moduleTableEntries); |
| 110 | |
| 111 | // return require("<entry module path>") |
| 112 | const args = options.luaTarget === LuaTarget.Lua50 ? "unpack(arg == nil and {} or arg)" : "..."; |
| 113 | // Avoid producing a tail-call (which removes the bundle's stack frame) by assigning the `require` result to a local and returning it. |
| 114 | const entryPath = createModulePath(entryModuleFilePath ?? entryModule, program); |
| 115 | const entryPoint = `local ____entry = require(${entryPath}, ${args})\nreturn ____entry\n`; |
| 116 | |
| 117 | const footers: string[] = []; |
| 118 | if (options.sourceMapTraceback) { |
| 119 | // Generates SourceMapTraceback for the entire file |
| 120 | footers.push('local __TS__SourceMapTraceBack = require("lualib_bundle").__TS__SourceMapTraceBack\n'); |
| 121 | footers.push(`${sourceMapTracebackBundlePlaceholder}\n`); |
| 122 | } |
| 123 | |
| 124 | const sourceChunks = [requireOverride(options), moduleTable, ...footers, entryPoint]; |
| 125 | |
| 126 | if (!options.noHeader) { |
| 127 | sourceChunks.unshift(tstlHeader); |
| 128 | } |
| 129 | |
| 130 | const bundleNode = joinSourceChunks(sourceChunks); |
| 131 | let { code, map } = bundleNode.toStringWithSourceMap(); |
| 132 | code = code.replace(sourceMapTracebackBundlePlaceholder, printStackTraceBundleOverride(bundleNode)); |
| 133 | |
| 134 | return [ |
| 135 | diagnostics, |
| 136 | { |
| 137 | outputPath, |
| 138 | code, |
| 139 | sourceMap: map.toString(), |
| 140 | sourceFiles: files.flatMap(x => x.sourceFiles ?? []), |
| 141 | }, |
| 142 | ]; |
| 143 | } |
| 144 | |
| 145 | function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode { |
no test coverage detected