Skip to content

Commit

Permalink
chore: use Map for compiler memory cache (#1575)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahnpnl committed May 4, 2020
1 parent a9f02bd commit 5a349e2
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 30 deletions.
4 changes: 2 additions & 2 deletions src/compiler/compiler-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export function getAndCacheProjectReference(
files: TSFiles,
projectReferences: ReadonlyArray<_ts.ProjectReference> | undefined,
) {
const file = files[filePath]
const file = files.get(filePath)
if (file?.projectReference) {
return file.projectReference.project
}
Expand Down Expand Up @@ -156,7 +156,7 @@ function getAndCacheOutputJSFileName(
projectReference: _ts.ResolvedProjectReference,
files: TSFiles,
) {
const file = files[inputFileName]
const file = files.get(inputFileName)
if (file?.projectReference?.outputFileName) {
return file.projectReference.outputFileName
}
Expand Down
16 changes: 8 additions & 8 deletions src/compiler/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import mkdirp = require('mkdirp')
import { basename, extname } from 'path'

import { ConfigSet } from '../config/config-set'
import { CompileFn, CompilerInstance, MemoryCache, TsCompiler } from '../types'
import { CompileFn, CompilerInstance, MemoryCache, TSFile, TsCompiler } from '../types'

import { getResolvedModulesCache } from './compiler-utils'
import { initializeLanguageServiceInstance } from './language-service'
Expand Down Expand Up @@ -55,10 +55,10 @@ const compileAndCacheResult = (

const [value, sourceMap] = compileFn(code, fileName, lineOffset)
const output = updateOutput(value, fileName, sourceMap, getExtension)
memoryCache.files[fileName] = {
...memoryCache.files[fileName],
memoryCache.files.set(fileName, {
...memoryCache.files.get(fileName)!,
output,
}
})

return output
}
Expand All @@ -78,7 +78,7 @@ export const createCompilerInstance = (configs: ConfigSet): TsCompiler => {
const ts = configs.compilerModule // Require the TypeScript compiler and configuration.
const extensions = ['.ts', '.tsx']
const memoryCache: MemoryCache = {
files: Object.create(null),
files: new Map<string, TSFile>(),
resolvedModules: Object.create(null),
}
// Enable `allowJs` when flag is set.
Expand All @@ -95,11 +95,11 @@ export const createCompilerInstance = (configs: ConfigSet): TsCompiler => {
memoryCache.resolvedModules = JSON.parse(fsMemoryCache)
} catch (e) {}
}
/* istanbul ignore next (we leave this for e2e) */
// Initialize memory cache for typescript compiler
configs.typescript.fileNames.forEach(fileName => {
memoryCache.files[fileName] = {
memoryCache.files.set(fileName, {
version: 0,
}
})
})
/**
* Get the extension for a transpiled file.
Expand Down
34 changes: 18 additions & 16 deletions src/compiler/language-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,33 @@ export const initializeLanguageServiceInstance = (
call: null,
[LogContexts.logLevel]: LogLevels.trace,
}
function isFileInCache(fileName: string) {
return memoryCache.files.has(fileName) && memoryCache.files.get(fileName)!.version !== 0
}
let projectVersion = 1
// Set the file contents into cache.
/* istanbul ignore next (cover by e2e) */
const updateMemoryCache = (contents: string, fileName: string) => {
logger.debug({ fileName }, `updateMemoryCache(): update memory cache for language service`)

let shouldIncrementProjectVersion = false
const isFileInCache = hasOwn.call(memoryCache.files, fileName) && memoryCache.files[fileName].version !== 0
if (!isFileInCache) {
memoryCache.files[fileName] = {
const hit = isFileInCache(fileName)
if (!hit) {
memoryCache.files.set(fileName, {
text: contents,
version: 1,
}
})
shouldIncrementProjectVersion = true
} else {
const previousContents = memoryCache.files[fileName].text
const previousContents = memoryCache.files.get(fileName)!.text
// Avoid incrementing cache when nothing has changed.
if (previousContents !== contents) {
memoryCache.files[fileName] = {
memoryCache.files.set(fileName, {
text: contents,
version: memoryCache.files[fileName].version + 1,
}
version: memoryCache.files.get(fileName)!.version + 1,
})
// Only bump project version when file is modified in cache, not when discovered for the first time
if (isFileInCache) shouldIncrementProjectVersion = true
if (hit) shouldIncrementProjectVersion = true
}
/**
* When a file is from node_modules or referenced to a referenced project and jest wants to transform it, we need
Expand All @@ -83,10 +86,10 @@ export const initializeLanguageServiceInstance = (
const serviceHost: _ts.LanguageServiceHost = {
getProjectVersion: () => String(projectVersion),
getProjectReferences: () => projectReferences,
getScriptFileNames: () => Object.keys(memoryCache.files),
getScriptFileNames: () => [...memoryCache.files.keys()],
getScriptVersion: (fileName: string) => {
const normalizedFileName = normalize(fileName)
const version = memoryCache.files[normalizedFileName].version
const version = memoryCache.files.get(normalizedFileName)!.version

// We need to return `undefined` and not a string here because TypeScript will use
// `getScriptVersion` and compare against their own version - which can be `undefined`.
Expand All @@ -97,19 +100,18 @@ export const initializeLanguageServiceInstance = (
},
getScriptSnapshot(fileName: string) {
const normalizedFileName = normalize(fileName)
const hit =
hasOwn.call(memoryCache.files, normalizedFileName) && memoryCache.files[normalizedFileName].version !== 0
const hit = memoryCache.files.has(normalizedFileName) && memoryCache.files.get(normalizedFileName)!.version !== 0

logger.trace({ normalizedFileName, cacheHit: hit }, `getScriptSnapshot():`, 'cache', hit ? 'hit' : 'miss')

// Read contents from TypeScript memory cache.
if (!hit) {
memoryCache.files[normalizedFileName] = {
memoryCache.files.set(normalizedFileName, {
text: ts.sys.readFile(normalizedFileName),
version: 1,
}
})
}
const contents = memoryCache.files[normalizedFileName]?.text
const contents = memoryCache.files.get(normalizedFileName)?.text

if (contents === undefined) return

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/transpiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const initializeTranspilerInstance = (
: ts.createProgram([], options)
/* istanbul ignore next (we leave this for e2e) */
const updateFileInCache = (contents: string, filePath: string) => {
const file = memoryCache.files[filePath]
const file = memoryCache.files.get(filePath)
if (file && file.text !== contents) {
file.version++
file.text = contents
Expand Down
4 changes: 1 addition & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,7 @@ export interface AstTransformerDesc {
factory(cs: ConfigSet): _ts.TransformerFactory<_ts.SourceFile>
}
/** where key is filepath */
export interface TSFiles {
[filePath: string]: TSFile
}
export type TSFiles = Map<string, TSFile>
export interface TSFile {
text?: string
output?: string
Expand Down

0 comments on commit 5a349e2

Please sign in to comment.