Last active
June 1, 2020 13:08
-
-
Save mihailik/11369fd2b5e0603a14bc5d883d47dd6c to your computer and use it in GitHub Desktop.
TypeScript custom transformers with ts.createSolutionBuilderWithWatch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var ts = require('typescript'); | |
var diagReport = ts.createBuilderStatusReporter(ts.sys, ts.sys.writeOutputIsTTY && ts.sys.writeOutputIsTTY()); | |
var host = ts.createWatchCompilerHost( | |
[__filename], | |
{ allowJs: true, checkJs: true, outFile: __filename + '.out.js' }, | |
ts.sys, | |
createAndPatchProgram, | |
void 0, | |
reportWatch); | |
var buildStart = Date.now(); | |
ts.createWatchProgram(host); | |
function reportWatch(diag, newLine, options, errorCount) { | |
ts.sys.write(typeof errorCount === 'number' ? | |
'\x1b[90m ' + (((Date.now() - buildStart) / 1000) + 's ').slice(0, 10) + '\x1b[0m' : | |
'WATCH DIAG '); | |
diagReport(diag); | |
if (typeof errorCount !== 'number') buildStart = Date.now(); | |
} | |
var prog; | |
function createAndPatchProgram() { | |
prog = ts.createEmitAndSemanticDiagnosticsBuilderProgram.apply(ts, arguments); | |
prog.__oldEmit = prog.emit; | |
prog.emit = overrideEmit; | |
return prog; | |
} | |
function overrideEmit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) { | |
return this.__oldEmit( | |
targetSourceFile, | |
writeFile, | |
cancellationToken, | |
emitOnlyDtsFiles, | |
{ after: [transformInjectStatementNumbers] } | |
); | |
} | |
var checker; | |
/** @param {import('typescript').TransformationContext} context */ | |
function transformInjectStatementNumbers(context) { | |
checker = prog.getProgram().getTypeChecker(); | |
return transformFile; | |
function transformFile(sourceFile) { | |
return ts.updateSourceFileNode( | |
sourceFile, | |
sourceFile.statements.map(decorateStatementWithComplexityAndType)); | |
} | |
} | |
function decorateStatementWithComplexityAndType(statement) { | |
var nodeCount = 0; | |
var type; | |
ts.forEachChild(statement, visitStatementChild); | |
return ts.addSyntheticLeadingComment( | |
statement, ts.SyntaxKind.SingleLineCommentTrivia, | |
' complexity: ' + nodeCount + | |
(!type ? '' : ' = ' + checker.typeToString(type))); | |
function visitStatementChild(child) { | |
nodeCount++; | |
if (!type) type = checker.getTypeAtLocation(child); | |
if (type.getFlags() === ts.TypeFlags.Any) type = null; | |
ts.forEachChild(child, visitStatementChild); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment