From 921b49580306a4601f126ab126b809562068eacf Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Mon, 1 Apr 2019 12:32:53 +1100 Subject: [PATCH] Upgrade to TypeScript 2.4 --- js/assets.ts | 10 ++ js/globals_test.ts | 1 + package.json | 2 +- third_party | 2 +- tools/ts_library_builder/ast_util.ts | 156 ++++++++++++---------- tools/ts_library_builder/build_library.ts | 18 +-- tools/ts_library_builder/test.ts | 13 +- 7 files changed, 116 insertions(+), 86 deletions(-) diff --git a/js/assets.ts b/js/assets.ts index 6e576c2d1b0e76..436906783566c4 100644 --- a/js/assets.ts +++ b/js/assets.ts @@ -28,9 +28,14 @@ import libEs2017SharedmemoryDts from "/third_party/node_modules/typescript/lib/l import libEs2017StringDts from "/third_party/node_modules/typescript/lib/lib.es2017.string.d.ts!string"; import libEs2017TypedarraysDts from "/third_party/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts!string"; import libEs2018Dts from "/third_party/node_modules/typescript/lib/lib.es2018.d.ts!string"; +import libEs2018AsyncIterableDts from "/third_party/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts!string"; import libEs2018IntlDts from "/third_party/node_modules/typescript/lib/lib.es2018.intl.d.ts!string"; import libEs2018PromiseDts from "/third_party/node_modules/typescript/lib/lib.es2018.promise.d.ts!string"; import libEs2018RegexpDts from "/third_party/node_modules/typescript/lib/lib.es2018.regexp.d.ts!string"; +import libEs2019Dts from "/third_party/node_modules/typescript/lib/lib.es2019.d.ts!string"; +import libEs2019ArrayDts from "/third_party/node_modules/typescript/lib/lib.es2019.array.d.ts!string"; +import libEs2019StringDts from "/third_party/node_modules/typescript/lib/lib.es2019.string.d.ts!string"; +import libEs2019SymbolDts from "/third_party/node_modules/typescript/lib/lib.es2019.symbol.d.ts!string"; import libEs5Dts from "/third_party/node_modules/typescript/lib/lib.es5.d.ts!string"; import libEsnextArrayDts from "/third_party/node_modules/typescript/lib/lib.esnext.array.d.ts!string"; import libEsnextAsynciterablesDts from "/third_party/node_modules/typescript/lib/lib.esnext.asynciterable.d.ts!string"; @@ -64,9 +69,14 @@ export const assetSourceCode: { [key: string]: string } = { "lib.es2017.string.d.ts": libEs2017StringDts, "lib.es2017.typedarrays.d.ts": libEs2017TypedarraysDts, "lib.es2018.d.ts": libEs2018Dts, + "lib.es2018.asynciterable.d.ts": libEs2018AsyncIterableDts, "lib.es2018.intl.d.ts": libEs2018IntlDts, "lib.es2018.promise.d.ts": libEs2018PromiseDts, "lib.es2018.regexp.d.ts": libEs2018RegexpDts, + "lib.es2019.d.ts": libEs2019Dts, + "lib.es2019.array.d.ts": libEs2019ArrayDts, + "lib.es2019.string.d.ts": libEs2019StringDts, + "lib.es2019.symbol.d.ts": libEs2019SymbolDts, "lib.es5.d.ts": libEs5Dts, "lib.esnext.d.ts": libEsnextDts, "lib.esnext.array.d.ts": libEsnextArrayDts, diff --git a/js/globals_test.ts b/js/globals_test.ts index 64a5c37abdb0b5..60b56013417a38 100644 --- a/js/globals_test.ts +++ b/js/globals_test.ts @@ -14,6 +14,7 @@ test(function windowWindowExists() { }); test(function globalThisEqualsWindow() { + // @ts-ignore (TypeScript thinks globalThis and window don't match) assert(globalThis === window); }); diff --git a/package.json b/package.json index 5f91cf50357386..a5734ec80039d2 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,6 @@ "rollup-pluginutils": "2.4.1", "ts-morph": "1.3.0", "ts-node": "8.0.2", - "typescript": "3.3.3333" + "typescript": "3.4.1" } } diff --git a/third_party b/third_party index d2df9adb30b153..1902aba524c96f 160000 --- a/third_party +++ b/third_party @@ -1 +1 @@ -Subproject commit d2df9adb30b15326c1f481420df7bacb468cf440 +Subproject commit 1902aba524c96f56c1dd654f04660a1fc3ebf80d diff --git a/tools/ts_library_builder/ast_util.ts b/tools/ts_library_builder/ast_util.ts index b43145e75baa88..d195da721b29cc 100644 --- a/tools/ts_library_builder/ast_util.ts +++ b/tools/ts_library_builder/ast_util.ts @@ -1,5 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { relative } from "path"; +import { basename, dirname, join, relative } from "path"; import { readFileSync } from "fs"; import { EOL } from "os"; import { @@ -12,6 +12,7 @@ import { SourceFile, StatementedNode, ts, + TypeAliasDeclaration, TypeGuards, VariableStatement, VariableDeclarationKind @@ -20,7 +21,7 @@ import { let silent = false; /** Logs a message to the console. */ -export function log(message: any = "", ...args: any[]) { +export function log(message: any = "", ...args: any[]): void { if (!silent) { console.log(message, ...args); } @@ -64,7 +65,7 @@ export function addTypeAlias( type: string, hasDeclareKeyword = false, jsdocs?: JSDoc[] -) { +): TypeAliasDeclaration { return node.addTypeAlias({ name, type, @@ -112,8 +113,30 @@ export function appendSourceFile( targetSourceFile.addStatements(`\n${sourceFile.print()}`); } +/** Used when formatting diagnostics */ +const formatDiagnosticHost: ts.FormatDiagnosticsHost = { + getCurrentDirectory() { + return process.cwd(); + }, + getCanonicalFileName(path: string) { + return path; + }, + getNewLine() { + return EOL; + } +}; + +/** Log diagnostics to the console with colour. */ +export function logDiagnostics(diagnostics: ts.Diagnostic[]): void { + if (diagnostics.length) { + console.log( + ts.formatDiagnosticsWithColorAndContext(diagnostics, formatDiagnosticHost) + ); + } +} + /** Check diagnostics, and if any exist, exit the process */ -export function checkDiagnostics(project: Project, onlyFor?: string[]) { +export function checkDiagnostics(project: Project, onlyFor?: string[]): void { const program = project.getProgram(); const diagnostics = [ ...program.getGlobalDiagnostics(), @@ -154,6 +177,32 @@ export interface FlattenNamespaceOptions { sourceFile: SourceFile; } +/** Returns a string which indicates the source file as the source */ +export function getSourceComment( + sourceFile: SourceFile, + rootPath: string +): string { + return `\n// @url ${relative(rootPath, sourceFile.getFilePath())}\n\n`; +} + +/** Return a set of fully qualified symbol names for the files exports */ +function getExportedSymbols(sourceFile: SourceFile): Set { + const exportedSymbols = new Set(); + const exportDeclarations = sourceFile.getExportDeclarations(); + for (const exportDeclaration of exportDeclarations) { + const exportSpecifiers = exportDeclaration.getNamedExports(); + for (const exportSpecifier of exportSpecifiers) { + const aliasedSymbol = exportSpecifier + .getSymbolOrThrow() + .getAliasedSymbol(); + if (aliasedSymbol) { + exportedSymbols.add(aliasedSymbol.getFullyQualifiedName()); + } + } + } + return exportedSymbols; +} + /** Take a namespace and flatten all exports. */ export function flattenNamespace({ customSources, @@ -167,15 +216,16 @@ export function flattenNamespace({ function flattenDeclarations( declaration: ImportDeclaration | ExportDeclaration - ) { + ): void { const declarationSourceFile = declaration.getModuleSpecifierSourceFile(); if (declarationSourceFile) { + // eslint-disable-next-line @typescript-eslint/no-use-before-define processSourceFile(declarationSourceFile); declaration.remove(); } } - function rectifyNodes(currentSourceFile: SourceFile) { + function rectifyNodes(currentSourceFile: SourceFile): void { currentSourceFile.forEachChild(node => { if (TypeGuards.isAmbientableNode(node)) { node.setHasDeclareKeyword(false); @@ -192,7 +242,9 @@ export function flattenNamespace({ }); } - function processSourceFile(currentSourceFile: SourceFile) { + function processSourceFile( + currentSourceFile: SourceFile + ): string | undefined { if (sourceFiles.has(currentSourceFile)) { return; } @@ -237,45 +289,6 @@ export function flattenNamespace({ ); } -/** Used when formatting diagnostics */ -const formatDiagnosticHost: ts.FormatDiagnosticsHost = { - getCurrentDirectory() { - return process.cwd(); - }, - getCanonicalFileName(path: string) { - return path; - }, - getNewLine() { - return EOL; - } -}; - -/** Return a set of fully qualified symbol names for the files exports */ -function getExportedSymbols(sourceFile: SourceFile): Set { - const exportedSymbols = new Set(); - const exportDeclarations = sourceFile.getExportDeclarations(); - for (const exportDeclaration of exportDeclarations) { - const exportSpecifiers = exportDeclaration.getNamedExports(); - for (const exportSpecifier of exportSpecifiers) { - const aliasedSymbol = exportSpecifier - .getSymbolOrThrow() - .getAliasedSymbol(); - if (aliasedSymbol) { - exportedSymbols.add(aliasedSymbol.getFullyQualifiedName()); - } - } - } - return exportedSymbols; -} - -/** Returns a string which indicates the source file as the source */ -export function getSourceComment( - sourceFile: SourceFile, - rootPath: string -): string { - return `\n// @url ${relative(rootPath, sourceFile.getFilePath())}\n\n`; -} - interface InlineFilesOptions { basePath: string; debug?: boolean; @@ -289,7 +302,7 @@ export function inlineFiles({ debug, inline, targetSourceFile -}: InlineFilesOptions) { +}: InlineFilesOptions): void { for (const filename of inline) { const text = readFileSync(filename, { encoding: "utf8" @@ -302,11 +315,34 @@ export function inlineFiles({ } } +/** Load a set of files into a file system host. */ +export function loadFiles( + project: Project, + filePaths: string[], + rebase?: string +): void { + const fileSystem = project.getFileSystem(); + for (const filePath of filePaths) { + const fileText = readFileSync(filePath, { + encoding: "utf8" + }); + fileSystem.writeFileSync( + rebase ? join(rebase, basename(filePath)) : filePath, + fileText + ); + } +} + /** * Load and write to a virtual file system all the default libs needed to * resolve types on project. */ -export function loadDtsFiles(project: Project) { +export function loadDtsFiles( + project: Project, + compilerOptions: ts.CompilerOptions +): void { + const libSourcePath = dirname(ts.getDefaultLibFilePath(compilerOptions)); + // TODO (@kitsonk) Add missing libs when ts-morph supports TypeScript 3.4 loadFiles( project, [ @@ -331,37 +367,17 @@ export function loadDtsFiles(project: Project) { "lib.es2018.d.ts", "lib.es2018.intl.d.ts", "lib.es2018.promise.d.ts", - "lib.es2018.regexp.d.ts", "lib.es5.d.ts", "lib.esnext.d.ts", "lib.esnext.array.d.ts", "lib.esnext.asynciterable.d.ts", "lib.esnext.intl.d.ts", "lib.esnext.symbol.d.ts" - ].map(fileName => `node_modules/typescript/lib/${fileName}`) + ].map(fileName => join(libSourcePath, fileName)), + "node_modules/typescript/lib/" ); } -/** Load a set of files into a file system host. */ -export function loadFiles(project: Project, filePaths: string[]) { - const fileSystem = project.getFileSystem(); - for (const filePath of filePaths) { - const fileText = readFileSync(filePath, { - encoding: "utf8" - }); - fileSystem.writeFileSync(filePath, fileText); - } -} - -/** Log diagnostics to the console with colour. */ -export function logDiagnostics(diagnostics: ts.Diagnostic[]): void { - if (diagnostics.length) { - console.log( - ts.formatDiagnosticsWithColorAndContext(diagnostics, formatDiagnosticHost) - ); - } -} - export interface NamespaceSourceFileOptions { debug?: boolean; namespace?: string; diff --git a/tools/ts_library_builder/build_library.ts b/tools/ts_library_builder/build_library.ts index b0d438531ed331..2045c288f01b5e 100644 --- a/tools/ts_library_builder/build_library.ts +++ b/tools/ts_library_builder/build_library.ts @@ -439,19 +439,21 @@ export function main({ // the outputProject will contain the final library file we are looking to // build + const outputProjectCompilerOptions: ts.CompilerOptions = { + baseUrl: buildPath, + lib: ["esnext"], + moduleResolution: ModuleResolutionKind.NodeJs, + strict: true, + target: ScriptTarget.ESNext + }; + const outputProject = new Project({ - compilerOptions: { - baseUrl: buildPath, - lib: ["esnext"], - moduleResolution: ModuleResolutionKind.NodeJs, - strict: true, - target: ScriptTarget.ESNext - }, + compilerOptions: outputProjectCompilerOptions, useVirtualFileSystem: true }); // There are files we need to load into memory, so that the project "compiles" - loadDtsFiles(outputProject); + loadDtsFiles(outputProject, outputProjectCompilerOptions); // libDts is the final output file we are looking to build and we are not // actually creating it, only in memory at this stage. diff --git a/tools/ts_library_builder/test.ts b/tools/ts_library_builder/test.ts index c4c9234902601e..5aeb8d611d414a 100644 --- a/tools/ts_library_builder/test.ts +++ b/tools/ts_library_builder/test.ts @@ -11,6 +11,7 @@ import { inlineFiles, loadDtsFiles } from "./ast_util"; const { ModuleKind, ModuleResolutionKind, ScriptTarget } = ts; /** setups and returns the fixtures for testing */ +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type function setupFixtures() { const basePath = process.cwd(); const buildPath = `${basePath}/tools/ts_library_builder/testdata`; @@ -35,7 +36,7 @@ function setupFixtures() { compilerOptions: {}, useVirtualFileSystem: true }); - loadDtsFiles(declarationProject); + loadDtsFiles(declarationProject, {}); for (const { filePath, text } of inputProject.emitToMemory().getFiles()) { declarationProject.createSourceFile(filePath, text); } @@ -43,7 +44,7 @@ function setupFixtures() { compilerOptions: {}, useVirtualFileSystem: true }); - loadDtsFiles(outputProject); + loadDtsFiles(outputProject, {}); const outputSourceFile = outputProject.createSourceFile(outputFile); const debug = true; @@ -59,7 +60,7 @@ function setupFixtures() { }; } -function buildLibraryFlatten() { +function buildLibraryFlatten(): void { const { basePath, buildPath, @@ -135,7 +136,7 @@ function buildLibraryFlatten() { assert.equal(variableDeclarationsNs.length, 1); } -function buildLibraryMerge() { +function buildLibraryMerge(): void { const { basePath, buildPath, @@ -198,7 +199,7 @@ function buildLibraryMerge() { assert.equal(interfaceProperties![1].type, "number"); } -function testInlineFiles() { +function testInlineFiles(): void { const { basePath, buildPath, @@ -220,7 +221,7 @@ function testInlineFiles() { // TODO author unit tests for `ast_util.ts` -function main() { +function main(): void { console.log("ts_library_builder buildLibraryFlatten"); buildLibraryFlatten(); console.log("ts_library_builder buildLibraryMerge");