Skip to content

Commit

Permalink
Implement getProjectVersion (#963)
Browse files Browse the repository at this point in the history
* Implement getProjectVersion

* fix linter failures

* address pr feedback
  • Loading branch information
cspotcode committed Mar 2, 2020
1 parent f3cd4a5 commit 35e2f92
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ export function create (rawOptions: CreateOptions = {}): Register {

// Use language services by default (TODO: invert next major version).
if (!options.compilerHost) {
let projectVersion = 1
const fileVersions = new Map<string, number>()

const getCustomTransformers = () => {
Expand All @@ -469,6 +470,7 @@ export function create (rawOptions: CreateOptions = {}): Register {

// Create the compiler host for type checking.
const serviceHost: _ts.LanguageServiceHost = {
getProjectVersion: () => String(projectVersion),
getScriptFileNames: () => rootFileNames,
getScriptVersion: (fileName: string) => {
const version = fileVersions.get(fileName)
Expand Down Expand Up @@ -505,27 +507,52 @@ export function create (rawOptions: CreateOptions = {}): Register {
const service = ts.createLanguageService(serviceHost, registry)

const updateMemoryCache = (contents: string, fileName: string) => {
let shouldIncrementProjectVersion = false
const fileVersion = fileVersions.get(fileName) || 0
const isFileInCache = fileVersion !== 0

// Add to `rootFiles` when discovered for the first time.
if (fileVersion === 0) rootFileNames.push(fileName)
if (!isFileInCache) {
rootFileNames.push(fileName)
// Modifying rootFileNames means a project change
shouldIncrementProjectVersion = true
}

const previousContents = fileContents.get(fileName)
// Avoid incrementing cache when nothing has changed.
if (fileContents.get(fileName) === contents) return
if (previousContents !== contents) {
fileVersions.set(fileName, fileVersion + 1)
fileContents.set(fileName, contents)
// Only bump project version when file is modified in cache, not when discovered for the first time
if (isFileInCache) {
shouldIncrementProjectVersion = true
}
}

fileVersions.set(fileName, fileVersion + 1)
fileContents.set(fileName, contents)
if (shouldIncrementProjectVersion) projectVersion++
}

let previousProgram: _ts.Program | undefined = undefined

getOutput = (code: string, fileName: string) => {
updateMemoryCache(code, fileName)

const programBefore = service.getProgram()
if (programBefore !== previousProgram) {
debug(`compiler rebuilt Program instance when getting output for ${ fileName }`)
}

const output = service.getEmitOutput(fileName)

// Get the relevant diagnostics - this is 3x faster than `getPreEmitDiagnostics`.
const diagnostics = service.getSemanticDiagnostics(fileName)
.concat(service.getSyntacticDiagnostics(fileName))

const programAfter = service.getProgram()
debug('invariant: Is service.getProject() identical before and after getting emit output and diagnostics? (should always be true) ', programBefore === programAfter)

previousProgram = programAfter

const diagnosticList = filterDiagnostics(diagnostics, ignoreDiagnostics)
if (diagnosticList.length) reportTSError(diagnosticList)

Expand Down

0 comments on commit 35e2f92

Please sign in to comment.