From 01958a4fce4e4e0a2f85f306bc67845b0aaf1469 Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Thu, 9 Mar 2017 22:04:23 +0200 Subject: [PATCH] - fix plugin chaining If we have plugins that are ordered before typescript, e.g. `replace`, the input to typescript should be the output of the previous plugin. However, this doesn't happen, instead typescript transforms the original file. From my (possibly incorrect) analysis, this happens because of a cache invalidation issue. If a module is processed by typescript before it is transformed by the plugin, it seems the file is read directly from the disk and inserted into the LanguageService `HostCache`. Later, when the file is transformed by the plugin, there is a call to `setSnapshot` with the "good" code (transformed by previous plugins), and then a call to `getEmitOutput` which is expected to use the snapshot we had just set. But this does *not* happen, instead we get the "bad" code from the `HostCache`. To fix this, make each call to `setSnapshot` increment the "script version"; this tells typescript that it needs to reprocess the file. --- src/host.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/host.ts b/src/host.ts index 492419c..a9f873d 100644 --- a/src/host.ts +++ b/src/host.ts @@ -6,6 +6,7 @@ export class LanguageServiceHost implements ts.LanguageServiceHost { private cwd = process.cwd(); private snapshots: { [fileName: string]: ts.IScriptSnapshot } = {}; + private versions: { [fileName: string]: number } = {}; constructor(private parsedConfig: ts.ParsedCommandLine) { @@ -15,6 +16,7 @@ export class LanguageServiceHost implements ts.LanguageServiceHost { let snapshot = ts.ScriptSnapshot.fromString(data); this.snapshots[fileName] = snapshot; + this.versions[fileName] = (this.versions[fileName] || 0) + 1; return snapshot; } @@ -39,7 +41,7 @@ export class LanguageServiceHost implements ts.LanguageServiceHost public getScriptVersion(_fileName: string) { - return "0"; + return (this.versions[_fileName] || 0).toString(); } public getScriptFileNames()