From f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe Mon Sep 17 00:00:00 2001 From: Cyril Sobierajewicz Date: Mon, 3 Dec 2018 11:37:46 +0100 Subject: [PATCH] Watch failed modules and their dependencies on compilation error --- src/index.js | 37 ++++++++++++++++++++++++++++++++++--- src/utils.js | 23 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/utils.js 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'); const dargs = require('./dargs'); +const utils = require('./utils'); + const spawn = require('cross-spawn').sync const eol = require('os').EOL @@ -186,9 +188,38 @@ module.exports = function purescriptLoader(source, map) { CACHE_VAR.warnings.push(warning); } }, - emitError: error => { - if (error.length) { - CACHE_VAR.errors.push(error); + emitError: pscMessage => { + if (pscMessage.length) { + const matchErrorsSeparator = /\n(?=Error)/; + const errors = pscMessage.split(matchErrorsSeparator); + for (const error of errors) { + const matchErrLocation = /at (.+\.purs) line (\d+), column (\d+) - line (\d+), column (\d+)/; + const [, filename] = matchErrLocation.exec(error) || []; + if (!filename) continue; + + const baseModulePath = path.join(this.rootContext, filename); + this.addDependency(baseModulePath); + + const matchErrModuleName = /in module ((?:\w+\.)*\w+)/; + const [, baseModuleName] = matchErrModuleName.exec(error) || []; + if (!baseModuleName) continue; + + const matchMissingModuleName = /Module ((?:\w+\.)*\w+) was not found/; + const matchMissingImportFromModuleName = /Cannot import value \w+ from module ((?:\w+\.)*\w+)/; + for (const re of [matchMissingModuleName, matchMissingImportFromModuleName]) { + const [, targetModuleName] = re.exec(error) || []; + if (targetModuleName) { + const resolved = utils.resolvePursModule({ + baseModulePath, + baseModuleName, + targetModuleName + }); + this.addDependency(resolved); + } + } + } + + CACHE_VAR.errors.push(pscMessage); } } } 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 @@ +const path = require('path'); + +const repeat = (value, times) => + times <= 0 ? [] : [value, ...repeat(value, times - 1)]; +const diffPursModuleNames = (from, target, parts) => { + if (!from.length) return parts.concat(target); + if (!target.length) return parts.concat(repeat('..', from.length)); + const [head_from, ...tail_from] = from; + const [head_target, ...tail_target] = target; + return head_from === head_target + ? diffPursModuleNames(tail_from, tail_target, parts) + : parts.concat(repeat('..', from.length), target); +}; +exports.resolvePursModule = ({ baseModulePath, baseModuleName, targetModuleName }) => { + const parts = diffPursModuleNames( + baseModuleName.split('.'), + targetModuleName.split('.'), + []); + return parts.length + ? path.resolve(baseModulePath, + `${path.join(...parts)}.purs`) + : baseModulePath; +}; -- 2.41.0