]> git.immae.eu Git - github/fretlink/purs-loader.git/blobdiff - src/index.js
Merge pull request #4 from cyrilfretlink/4.2.0
[github/fretlink/purs-loader.git] / src / index.js
index b151d8285b695a5ee8b5387f73341c72d474ef05..d713737337e985078fab9fef30512ca13e594be9 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
@@ -124,7 +126,8 @@ module.exports = function purescriptLoader(source, map) {
     warnings: true,
     watch: false,
     output: 'output',
-    src: []
+    src: [],
+    rewriteRules: {}
   }, loaderOptions, {
     src: srcOption
   });
@@ -186,9 +189,71 @@ 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 modules = [];
+
+        const matchErrorsSeparator = /\n(?=Error)/;
+        const errors = pscMessage.split(matchErrorsSeparator);
+        for (const error of errors) {
+          const matchErrLocation = /at (.+\.purs):(\d+):(\d+) - (\d+):(\d+) \(line \2, column \3 - line \4, column \5\)/;
+          const [, filename] = matchErrLocation.exec(error) || [];
+          if (!filename) continue;
+
+          const baseModulePath = path.join(this.rootContext, filename);
+          this.addDependency(baseModulePath);
+
+          const foreignModulesErrorCodes = [
+            'ErrorParsingFFIModule',
+            'MissingFFIImplementations',
+            'UnusedFFIImplementations',
+            'MissingFFIModule'
+          ];
+          for (const code of foreignModulesErrorCodes) {
+            if (error.includes(code)) {
+              const resolved = utils.resolveForeignModule(baseModulePath);
+              this.addDependency(resolved);
+            }
+          }
+
+          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,
+                rewriteRules: options.rewriteRules,
+                targetModuleName
+              });
+              this.addDependency(resolved);
+            }
+          }
+
+          const desc = {
+            name: baseModuleName,
+            filename: baseModulePath
+          };
+
+          if (typeof this.describePscError === 'function') {
+            const { dependencies = [], details } = this.describePscError(error, desc);
+
+            for (const dep of dependencies) {
+              this.addDependency(dep);
+            }
+
+            Object.assign(desc, details);
+          }
+
+          modules.push(desc);
+        }
+
+        CACHE_VAR.errors.push(new utils.PscError(pscMessage, modules));
       }
     }
   }