]> git.immae.eu Git - github/fretlink/purs-loader.git/commitdiff
Watch failed modules and their dependencies on compilation error
authorCyril Sobierajewicz <cyril.sobierajewicz@fretlink.com>
Mon, 3 Dec 2018 10:37:46 +0000 (11:37 +0100)
committerCyril Sobierajewicz <cyril.sobierajewicz@fretlink.com>
Mon, 3 Dec 2018 10:57:30 +0000 (11:57 +0100)
src/index.js
src/utils.js [new file with mode: 0644]

index b151d8285b695a5ee8b5387f73341c72d474ef05..fce6394a85bd9978eebead971a428976c6934d76 100644 (file)
@@ -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 (file)
index 0000000..0ab00eb
--- /dev/null
@@ -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;
+};