diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/ts_library_builder/ast_util.ts | 5 | ||||
-rw-r--r-- | tools/ts_library_builder/build_library.ts | 166 | ||||
-rw-r--r-- | tools/ts_library_builder/main.ts | 1 | ||||
-rw-r--r-- | tools/ts_library_builder/test.ts | 17 |
4 files changed, 137 insertions, 52 deletions
diff --git a/tools/ts_library_builder/ast_util.ts b/tools/ts_library_builder/ast_util.ts index d195da721..14546f9c5 100644 --- a/tools/ts_library_builder/ast_util.ts +++ b/tools/ts_library_builder/ast_util.ts @@ -94,11 +94,14 @@ export function addVariableDeclaration( node: StatementedNode, name: string, type: string, + isConst: boolean, hasDeclareKeyword?: boolean, jsdocs?: JSDoc[] ): VariableStatement { return node.addVariableStatement({ - declarationKind: VariableDeclarationKind.Const, + declarationKind: isConst + ? VariableDeclarationKind.Const + : VariableDeclarationKind.Let, declarations: [{ name, type }], docs: jsdocs && jsdocs.map(jsdoc => jsdoc.getText()), hasDeclareKeyword diff --git a/tools/ts_library_builder/build_library.ts b/tools/ts_library_builder/build_library.ts index 2045c288f..22268f1dc 100644 --- a/tools/ts_library_builder/build_library.ts +++ b/tools/ts_library_builder/build_library.ts @@ -57,6 +57,16 @@ export interface BuildLibraryOptions { inputs?: string[]; /** + * Path to globals file to be used I.E. `js/globals.ts` + */ + additionalGlobals?: string[]; + + /** + * List of global variables to define as let instead of the default const. + */ + declareAsLet?: string[]; + + /** * The path to the output library */ outFile: string; @@ -170,30 +180,21 @@ export function flatten({ } } -interface MergeGlobalOptions { - basePath: string; - debug?: boolean; - declarationProject: Project; - filePath: string; +interface PrepareFileForMergeOptions { globalVarName: string; - ignore?: string[]; - inputProject: Project; interfaceName: string; targetSourceFile: SourceFile; } -/** Take a module and merge it into the global scope */ -export function mergeGlobal({ - basePath, - debug, - declarationProject, - filePath, +interface PrepareFileForMergeReturn { + interfaceDeclaration: InterfaceDeclaration; +} + +export function prepareFileForMerge({ globalVarName, - ignore, - inputProject, interfaceName, targetSourceFile -}: MergeGlobalOptions): void { +}: PrepareFileForMergeOptions): PrepareFileForMergeReturn { // Add the global object interface const interfaceDeclaration = targetSourceFile.addInterface({ name: interfaceName, @@ -201,15 +202,56 @@ export function mergeGlobal({ }); // Declare the global variable - addVariableDeclaration(targetSourceFile, globalVarName, interfaceName, true); + addVariableDeclaration( + targetSourceFile, + globalVarName, + interfaceName, + true, + true + ); // `globalThis` accesses the global scope and is defined here: // https://github.com/tc39/proposal-global - addVariableDeclaration(targetSourceFile, "globalThis", interfaceName, true); + addVariableDeclaration( + targetSourceFile, + "globalThis", + interfaceName, + true, + true + ); // Add self reference to the global variable addInterfaceProperty(interfaceDeclaration, globalVarName, interfaceName); + return { + interfaceDeclaration + }; +} + +interface MergeGlobalOptions extends PrepareFileForMergeOptions { + basePath: string; + debug?: boolean; + declarationProject: Project; + filePath: string; + ignore?: string[]; + inputProject: Project; + prepareReturn: PrepareFileForMergeReturn; + declareAsLet?: string[]; +} + +/** Take a module and merge it into the global scope */ +export function mergeGlobals({ + basePath, + debug, + declarationProject, + filePath, + globalVarName, + ignore, + inputProject, + targetSourceFile, + declareAsLet, + prepareReturn: { interfaceDeclaration } +}: MergeGlobalOptions): void { // Retrieve source file from the input project const sourceFile = inputProject.getSourceFileOrThrow(filePath); @@ -267,7 +309,8 @@ export function mergeGlobal({ dependentSourceFiles.add(valueDeclaration.getSourceFile()); } } - addVariableDeclaration(targetSourceFile, property, type, true); + const isConst = !(declareAsLet && declareAsLet.includes(property)); + addVariableDeclaration(targetSourceFile, property, type, isConst, true); addInterfaceProperty(interfaceDeclaration, property, type); } } @@ -297,29 +340,32 @@ export function mergeGlobal({ const importDeclarations = sourceFile.getImportDeclarations(); const namespaces = new Set<string>(); for (const declaration of importDeclarations) { - const declarationSourceFile = declaration.getModuleSpecifierSourceFile(); - if ( - declarationSourceFile && - dependentSourceFiles.has(declarationSourceFile) - ) { - // the source file will resolve to the original `.ts` file, but the - // information we really want is in the emitted `.d.ts` file, so we will - // resolve to that file - const dtsFilePath = declarationSourceFile - .getFilePath() - .replace(/\.ts$/, ".d.ts"); - const dtsSourceFile = declarationProject.getSourceFileOrThrow( - dtsFilePath - ); - targetSourceFile.addStatements( - namespaceSourceFile(dtsSourceFile, { - debug, - namespace: declaration.getNamespaceImportOrThrow().getText(), - namespaces, - rootPath: basePath, - sourceFileMap - }) - ); + const namespaceImport = declaration.getNamespaceImport(); + if (namespaceImport) { + const declarationSourceFile = declaration.getModuleSpecifierSourceFile(); + if ( + declarationSourceFile && + dependentSourceFiles.has(declarationSourceFile) + ) { + // the source file will resolve to the original `.ts` file, but the + // information we really want is in the emitted `.d.ts` file, so we will + // resolve to that file + const dtsFilePath = declarationSourceFile + .getFilePath() + .replace(/\.ts$/, ".d.ts"); + const dtsSourceFile = declarationProject.getSourceFileOrThrow( + dtsFilePath + ); + targetSourceFile.addStatements( + namespaceSourceFile(dtsSourceFile, { + debug, + namespace: namespaceImport.getText(), + namespaces, + rootPath: basePath, + sourceFileMap + }) + ); + } } } @@ -337,6 +383,8 @@ export function main({ buildPath, inline, inputs, + additionalGlobals, + declareAsLet, debug, outFile, silent @@ -476,20 +524,46 @@ export function main({ }${msgGeneratedDtsText}\n` }; - mergeGlobal({ + const prepareForMergeOpts: PrepareFileForMergeOptions = { + globalVarName: "window", + interfaceName: "Window", + targetSourceFile: libDTs + }; + + const prepareReturn = prepareFileForMerge(prepareForMergeOpts); + + mergeGlobals({ basePath, debug, declarationProject, filePath: `${basePath}/js/globals.ts`, - globalVarName: "window", inputProject, ignore: ["Deno"], - interfaceName: "Window", - targetSourceFile: libDTs + declareAsLet, + ...prepareForMergeOpts, + prepareReturn }); log(`Merged "globals" into global scope.`); + if (additionalGlobals) { + for (const additionalGlobal of additionalGlobals) { + mergeGlobals({ + basePath, + debug, + declarationProject, + filePath: `${basePath}/${additionalGlobal}`, + inputProject, + ignore: ["Deno"], + declareAsLet, + ...prepareForMergeOpts, + prepareReturn + }); + } + + log(`Added additional "globals" into global scope.`); + } + flatten({ basePath, customSources, diff --git a/tools/ts_library_builder/main.ts b/tools/ts_library_builder/main.ts index 54a659d01..e4e2e73ed 100644 --- a/tools/ts_library_builder/main.ts +++ b/tools/ts_library_builder/main.ts @@ -46,6 +46,7 @@ buildRuntimeLib({ "js/deno.ts", "js/globals.ts" ], + declareAsLet: ["onmessage"], outFile, silent }); diff --git a/tools/ts_library_builder/test.ts b/tools/ts_library_builder/test.ts index 5aeb8d611..2b6abe714 100644 --- a/tools/ts_library_builder/test.ts +++ b/tools/ts_library_builder/test.ts @@ -5,7 +5,7 @@ import * as assert from "assert"; import { Project, ts } from "ts-morph"; -import { flatten, mergeGlobal } from "./build_library"; +import { flatten, mergeGlobals, prepareFileForMerge } from "./build_library"; import { inlineFiles, loadDtsFiles } from "./ast_util"; const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts; @@ -146,15 +146,22 @@ function buildLibraryMerge(): void { outputSourceFile: targetSourceFile } = setupFixtures(); - mergeGlobal({ + const prepareForMergeOpts = { + globalVarName: "foobarbaz", + interfaceName: "FooBar", + targetSourceFile + }; + + const prepareReturn = prepareFileForMerge(prepareForMergeOpts); + + mergeGlobals({ basePath, declarationProject, debug, - globalVarName: "foobarbaz", filePath: `${buildPath}/globals.ts`, inputProject, - interfaceName: "FooBar", - targetSourceFile + ...prepareForMergeOpts, + prepareReturn }); assert(targetSourceFile.getNamespace("moduleC") != null); |