From fab1a6468e53ab6c59e2c3aebb3ed1ecd1a6e5e8 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Tue, 6 Apr 2021 08:54:35 -0400 Subject: [PATCH] perf(compiler-cli): cache results of `absoluteFromSourceFile` (#41475) The compiler frequently translates TypeScript source file `fileName` strings into absolute paths, via a `fs.resolve()` operation. This is often done via the helper function `absoluteFromSourceFile`. This commit adds a caching mechanism whereby the `AbsoluteFsPath` of a source file is patched onto the object under an Angular-specific symbol property, allowing the compiler to avoid resolving the path on subsequent calls. PR Close #41475 --- .../src/ngtsc/file_system/src/helpers.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/file_system/src/helpers.ts b/packages/compiler-cli/src/ngtsc/file_system/src/helpers.ts index 9e3476e64b..04639840c7 100644 --- a/packages/compiler-cli/src/ngtsc/file_system/src/helpers.ts +++ b/packages/compiler-cli/src/ngtsc/file_system/src/helpers.ts @@ -29,11 +29,21 @@ export function absoluteFrom(path: string): AbsoluteFsPath { return fs.resolve(path); } +const ABSOLUTE_PATH = Symbol('AbsolutePath'); + /** - * Extract an `AbsoluteFsPath` from a `ts.SourceFile`. + * Extract an `AbsoluteFsPath` from a `ts.SourceFile`-like object. */ -export function absoluteFromSourceFile(sf: ts.SourceFile): AbsoluteFsPath { - return fs.resolve(sf.fileName); +export function absoluteFromSourceFile(sf: {fileName: string}): AbsoluteFsPath { + const sfWithPatch = sf as {fileName: string, [ABSOLUTE_PATH]?: AbsoluteFsPath}; + + if (sfWithPatch[ABSOLUTE_PATH] === undefined) { + sfWithPatch[ABSOLUTE_PATH] = fs.resolve(sfWithPatch.fileName); + } + + // Non-null assertion needed since TS doesn't narrow the type of fields that use a symbol as a key + // apparently. + return sfWithPatch[ABSOLUTE_PATH]!; } /**