Skip to content

Commit 12ff53d

Browse files
Mikhail Bashurovblakeembrey
Mikhail Bashurov
authored andcommittedSep 15, 2019
Introduce transformers program support (#879)
1 parent 6295254 commit 12ff53d

File tree

2 files changed

+43
-27
lines changed

2 files changed

+43
-27
lines changed
 

‎README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ _Environment variable denoted in parentheses._
140140

141141
### Programmatic Only Options
142142

143-
* `transformers` An array of transformers to pass to TypeScript
143+
* `transformers` `_ts.CustomTransformers | ((p: _ts.Program) => _ts.CustomTransformers)` An object with transformers or a function that accepts a program and returns an transformers object to pass to TypeScript. Function isn't available with `transpileOnly` flag
144144
* `readFile` Custom TypeScript-compatible file reading function
145145
* `fileExists` Custom TypeScript-compatible file existence function
146146

‎src/index.ts

+42-26
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export interface Options {
7171
ignoreDiagnostics?: Array<number | string>
7272
readFile?: (path: string) => string | undefined
7373
fileExists?: (path: string) => boolean
74-
transformers?: _ts.CustomTransformers
74+
transformers?: _ts.CustomTransformers | ((p: _ts.Program) => _ts.CustomTransformers)
7575
}
7676

7777
/**
@@ -274,32 +274,23 @@ export function register (opts: Options = {}): Register {
274274
/**
275275
* Create the basic required function using transpile mode.
276276
*/
277-
let getOutput = function (code: string, fileName: string, lineOffset = 0): SourceOutput {
278-
const result = ts.transpileModule(code, {
279-
fileName,
280-
transformers,
281-
compilerOptions: config.options,
282-
reportDiagnostics: true
283-
})
284-
285-
const diagnosticList = result.diagnostics ?
286-
filterDiagnostics(result.diagnostics, ignoreDiagnostics) :
287-
[]
288-
289-
if (diagnosticList.length) reportTSError(configDiagnosticList)
290-
291-
return [result.outputText, result.sourceMapText as string]
292-
}
293-
294-
let getTypeInfo = function (_code: string, _fileName: string, _position: number): TypeInfo {
295-
throw new TypeError(`Type information is unavailable without "--type-check"`)
296-
}
277+
let getOutput: (code: string, fileName: string, lineOffset: number) => SourceOutput
278+
let getTypeInfo: (_code: string, _fileName: string, _position: number) => TypeInfo
297279

298280
// Use full language services when the fast option is disabled.
299281
if (typeCheck) {
300282
const memoryCache = new MemoryCache(config.fileNames)
301283
const cachedReadFile = cachedLookup(debugFn('readFile', readFile))
302284

285+
const getCustomTransformers = () => {
286+
if (typeof transformers === 'function') {
287+
const program = service.getProgram()
288+
return program ? transformers(program) : undefined
289+
}
290+
291+
return transformers
292+
}
293+
303294
// Create the compiler host for type checking.
304295
const serviceHost: _ts.LanguageServiceHost = {
305296
getScriptFileNames: () => Array.from(memoryCache.fileVersions.keys()),
@@ -331,14 +322,14 @@ export function register (opts: Options = {}): Register {
331322
getCurrentDirectory: () => cwd,
332323
getCompilationSettings: () => config.options,
333324
getDefaultLibFileName: () => ts.getDefaultLibFilePath(config.options),
334-
getCustomTransformers: () => transformers
325+
getCustomTransformers: getCustomTransformers
335326
}
336327

337328
const registry = ts.createDocumentRegistry(ts.sys.useCaseSensitiveFileNames, cwd)
338329
const service = ts.createLanguageService(serviceHost, registry)
339330

340331
// Set the file contents into cache manually.
341-
const updateMemoryCache = function (contents: string, fileName: string) {
332+
const updateMemoryCache = (contents: string, fileName: string) => {
342333
const fileVersion = memoryCache.fileVersions.get(fileName) || 0
343334

344335
// Avoid incrementing cache when nothing has changed.
@@ -348,7 +339,7 @@ export function register (opts: Options = {}): Register {
348339
memoryCache.fileContents.set(fileName, contents)
349340
}
350341

351-
getOutput = function (code: string, fileName: string, lineOffset: number = 0) {
342+
getOutput = (code: string, fileName: string) => {
352343
updateMemoryCache(code, fileName)
353344

354345
const output = service.getEmitOutput(fileName)
@@ -379,7 +370,7 @@ export function register (opts: Options = {}): Register {
379370
return [output.outputFiles[1].text, output.outputFiles[0].text]
380371
}
381372

382-
getTypeInfo = function (code: string, fileName: string, position: number) {
373+
getTypeInfo = (code: string, fileName: string, position: number) => {
383374
updateMemoryCache(code, fileName)
384375

385376
const info = service.getQuickInfoAtPosition(fileName, position)
@@ -388,10 +379,35 @@ export function register (opts: Options = {}): Register {
388379

389380
return { name, comment }
390381
}
382+
} else {
383+
if (typeof transformers === 'function') {
384+
throw new TypeError('Transformers function is unavailable in "--transpile-only"')
385+
}
386+
387+
getOutput = (code: string, fileName: string): SourceOutput => {
388+
const result = ts.transpileModule(code, {
389+
fileName,
390+
transformers,
391+
compilerOptions: config.options,
392+
reportDiagnostics: true
393+
})
394+
395+
const diagnosticList = result.diagnostics ?
396+
filterDiagnostics(result.diagnostics, ignoreDiagnostics) :
397+
[]
398+
399+
if (diagnosticList.length) reportTSError(configDiagnosticList)
400+
401+
return [result.outputText, result.sourceMapText as string]
402+
}
403+
404+
getTypeInfo = () => {
405+
throw new TypeError('Type information is unavailable in "--transpile-only"')
406+
}
391407
}
392408

393409
// Create a simple TypeScript compiler proxy.
394-
function compile (code: string, fileName: string, lineOffset?: number) {
410+
function compile (code: string, fileName: string, lineOffset = 0) {
395411
const [value, sourceMap] = getOutput(code, fileName, lineOffset)
396412
const output = updateOutput(value, fileName, sourceMap, getExtension)
397413
outputCache.set(fileName, output)

0 commit comments

Comments
 (0)
Please sign in to comment.