diff options
author | Cyril Sobierajewicz <cyril.sobierajewicz@fretlink.com> | 2018-12-03 11:37:46 +0100 |
---|---|---|
committer | Cyril Sobierajewicz <cyril.sobierajewicz@fretlink.com> | 2018-12-03 11:57:30 +0100 |
commit | f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe (patch) | |
tree | 7021319353b6c8af625563936deacc21a4311fe5 /src | |
parent | 9dcf21578cb7e415e9670cd076182ee3c9b67a6b (diff) | |
download | purs-loader-f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe.tar.gz purs-loader-f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe.tar.zst purs-loader-f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe.zip |
Watch failed modules and their dependencies on compilation error
Diffstat (limited to 'src')
-rw-r--r-- | src/index.js | 37 | ||||
-rw-r--r-- | src/utils.js | 23 |
2 files changed, 57 insertions, 3 deletions
diff --git a/src/index.js b/src/index.js index b151d82..fce6394 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -26,6 +26,8 @@ const sourceMaps = require('./source-maps'); | |||
26 | 26 | ||
27 | const dargs = require('./dargs'); | 27 | const dargs = require('./dargs'); |
28 | 28 | ||
29 | const utils = require('./utils'); | ||
30 | |||
29 | const spawn = require('cross-spawn').sync | 31 | const spawn = require('cross-spawn').sync |
30 | 32 | ||
31 | const eol = require('os').EOL | 33 | const eol = require('os').EOL |
@@ -186,9 +188,38 @@ module.exports = function purescriptLoader(source, map) { | |||
186 | CACHE_VAR.warnings.push(warning); | 188 | CACHE_VAR.warnings.push(warning); |
187 | } | 189 | } |
188 | }, | 190 | }, |
189 | emitError: error => { | 191 | emitError: pscMessage => { |
190 | if (error.length) { | 192 | if (pscMessage.length) { |
191 | CACHE_VAR.errors.push(error); | 193 | const matchErrorsSeparator = /\n(?=Error)/; |
194 | const errors = pscMessage.split(matchErrorsSeparator); | ||
195 | for (const error of errors) { | ||
196 | const matchErrLocation = /at (.+\.purs) line (\d+), column (\d+) - line (\d+), column (\d+)/; | ||
197 | const [, filename] = matchErrLocation.exec(error) || []; | ||
198 | if (!filename) continue; | ||
199 | |||
200 | const baseModulePath = path.join(this.rootContext, filename); | ||
201 | this.addDependency(baseModulePath); | ||
202 | |||
203 | const matchErrModuleName = /in module ((?:\w+\.)*\w+)/; | ||
204 | const [, baseModuleName] = matchErrModuleName.exec(error) || []; | ||
205 | if (!baseModuleName) continue; | ||
206 | |||
207 | const matchMissingModuleName = /Module ((?:\w+\.)*\w+) was not found/; | ||
208 | const matchMissingImportFromModuleName = /Cannot import value \w+ from module ((?:\w+\.)*\w+)/; | ||
209 | for (const re of [matchMissingModuleName, matchMissingImportFromModuleName]) { | ||
210 | const [, targetModuleName] = re.exec(error) || []; | ||
211 | if (targetModuleName) { | ||
212 | const resolved = utils.resolvePursModule({ | ||
213 | baseModulePath, | ||
214 | baseModuleName, | ||
215 | targetModuleName | ||
216 | }); | ||
217 | this.addDependency(resolved); | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
222 | CACHE_VAR.errors.push(pscMessage); | ||
192 | } | 223 | } |
193 | } | 224 | } |
194 | } | 225 | } |
diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..0ab00eb --- /dev/null +++ b/src/utils.js | |||
@@ -0,0 +1,23 @@ | |||
1 | const path = require('path'); | ||
2 | |||
3 | const repeat = (value, times) => | ||
4 | times <= 0 ? [] : [value, ...repeat(value, times - 1)]; | ||
5 | const diffPursModuleNames = (from, target, parts) => { | ||
6 | if (!from.length) return parts.concat(target); | ||
7 | if (!target.length) return parts.concat(repeat('..', from.length)); | ||
8 | const [head_from, ...tail_from] = from; | ||
9 | const [head_target, ...tail_target] = target; | ||
10 | return head_from === head_target | ||
11 | ? diffPursModuleNames(tail_from, tail_target, parts) | ||
12 | : parts.concat(repeat('..', from.length), target); | ||
13 | }; | ||
14 | exports.resolvePursModule = ({ baseModulePath, baseModuleName, targetModuleName }) => { | ||
15 | const parts = diffPursModuleNames( | ||
16 | baseModuleName.split('.'), | ||
17 | targetModuleName.split('.'), | ||
18 | []); | ||
19 | return parts.length | ||
20 | ? path.resolve(baseModulePath, | ||
21 | `${path.join(...parts)}.purs`) | ||
22 | : baseModulePath; | ||
23 | }; | ||