]> git.immae.eu Git - github/fretlink/purs-loader.git/blobdiff - src/PscIde.js
Version 2.4.2
[github/fretlink/purs-loader.git] / src / PscIde.js
index d99b639842da0c50a06f02ac04540d8a3431abe8..bf92b3860ee502532ee315de68e9f38323cfea0f 100644 (file)
@@ -38,7 +38,7 @@ function connect(psModule) {
     ideClient.stderr.on('data', data => {
       debug(data.toString())
       cache.ideServer = false
-      reject(true)
+      reject(new Error('psc-ide-client failed'))
     })
     ideClient.stdout.once('data', data => {
       debug(data.toString())
@@ -49,11 +49,11 @@ function connect(psModule) {
           resolve(psModule)
         } else {
           cache.ideServer = ideServer
-          reject(true)
+          reject(new Error('psc-ide-client failed'))
         }
       } else {
         cache.ideServer = false
-        reject(true)
+        reject(new Error('psc-ide-client failed'))
       }
     })
     ideClient.stdin.resume()
@@ -61,26 +61,37 @@ function connect(psModule) {
     ideClient.stdin.write('\n')
   })
 
-  const args = dargs(Object.assign({
+  const serverArgs = dargs(Object.assign({
     outputDirectory: options.output,
-  }, options.pscIdeArgs))
+    '_': options.src
+  }, options.pscIdeServerArgs))
 
-  debug('attempting to start psc-ide-server', args)
+  debug('attempting to start psc-ide-server', serverArgs)
+
+  const ideServer = cache.ideServer = spawn('psc-ide-server', serverArgs)
+
+  ideServer.stdout.on('data', data => {
+    debug('psc-ide-server stdout: %s', data.toString());
+  });
 
-  const ideServer = cache.ideServer = spawn('psc-ide-server', [])
   ideServer.stderr.on('data', data => {
-    debug(data.toString())
-  })
+    debug('psc-ide-server stderr: %s', data.toString());
+  });
+
+  ideServer.on('error', error => {
+    debug('psc-ide-server error: %o', error);
+  });
+
+  ideServer.on('close', (code, signal) => {
+    debug('psc-ide-server close: %s %s', code, signal);
+  });
 
   return retryPromise((retry, number) => {
     return connect_().catch(error => {
       if (!cache.ideServer && number === 9) {
         debug(error)
 
-        console.log(
-          'failed to connect to or start psc-ide-server, ' +
-          'full compilation will occur on rebuild'
-        )
+        console.warn('Failed to connect to or start psc-ide-server. A full compilation will occur on rebuild');
 
         return Promise.resolve(psModule)
       }
@@ -133,9 +144,7 @@ function rebuild(psModule) {
       }
 
       if (res && !Array.isArray(res.result)) {
-        return res.resultType === 'success'
-               ? resolve(psModule)
-               : reject('psc-ide rebuild failed')
+        return resolve(psModule);
       }
 
       Promise.map(res.result, (item, i) => {
@@ -144,26 +153,42 @@ function rebuild(psModule) {
       })
       .then(compileMessages => {
         if (res.resultType === 'error') {
-          if (res.result.some(item => item.errorCode === 'UnknownModule' || item.errorCode === 'UnknownName')) {
+          if (res.result.some(item => {
+            const isModuleNotFound = item.errorCode === 'ModuleNotFound';
+
+            const isUnknownModule = item.errorCode === 'UnknownModule';
+
+            const isUnknownModuleImport = item.errorCode === 'UnknownName' && /Unknown module/.test(item.message);
+
+            return isModuleNotFound || isUnknownModule || isUnknownModuleImport;
+          })) {
             debug('unknown module, attempting full recompile')
             return Psc.compile(psModule)
               .then(() => PsModuleMap.makeMap(options.src).then(map => {
-                debug('rebuilt module map');
+                debug('rebuilt module map after unknown module forced a recompile');
                 cache.psModuleMap = map;
               }))
               .then(() => request({ command: 'load' }))
               .then(resolve)
-              .catch(() => reject('psc-ide rebuild failed'))
+              .catch(() => resolve(psModule))
+          }
+          const errorMessage = compileMessages.join('\n');
+          if (errorMessage.length) {
+            psModule.emitError(errorMessage);
           }
-          cache.errors = compileMessages.join('\n')
-          reject('psc-ide rebuild failed')
+          resolve(psModule);
         } else {
-          cache.warnings = compileMessages.join('\n')
-          resolve(psModule)
+          const warningMessage = compileMessages.join('\n');
+          if (options.warnings && warningMessage.length) {
+            psModule.emitWarning(warningMessage);
+          }
+          resolve(psModule);
         }
       })
     })
 
+    debug('psc-ide-client stdin: %o', body);
+
     ideClient.stdin.write(JSON.stringify(body))
     ideClient.stdin.write('\n')
   })
@@ -178,54 +203,60 @@ function rebuild(psModule) {
 module.exports.rebuild = rebuild;
 
 function formatIdeResult(result, options, index, length) {
-  const srcPath = path.relative(options.context, result.filename)
-  const pos = result.position
-  const fileAndPos = `${srcPath}:${pos.startLine}:${pos.startColumn}`
   let numAndErr = `[${index+1}/${length} ${result.errorCode}]`
   numAndErr = options.pscIdeColors ? colors.yellow(numAndErr) : numAndErr
 
-  return fs.readFileAsync(result.filename, 'utf8').then(source => {
-    const lines = source.split('\n').slice(pos.startLine - 1, pos.endLine)
-    const endsOnNewline = pos.endColumn === 1 && pos.startLine !== pos.endLine
-    const up = options.pscIdeColors ? colors.red('^') : '^'
-    const down = options.pscIdeColors ? colors.red('v') : 'v'
-    let trimmed = lines.slice(0)
-
-    if (endsOnNewline) {
-      lines.splice(lines.length - 1, 1)
-      pos.endLine = pos.endLine - 1
-      pos.endColumn = lines[lines.length - 1].length || 1
-    }
+  function makeResult() {
+    return Promise.resolve(`\n${numAndErr} ${result.message}`)
+  }
+
+  function makeResultSnippet(filename, pos) {
+    const srcPath = path.relative(options.context, filename);
+    const fileAndPos = `${srcPath}:${pos.startLine}:${pos.startColumn}`
+
+    return fs.readFileAsync(filename, 'utf8').then(source => {
+      const lines = source.split('\n').slice(pos.startLine - 1, pos.endLine)
+      const endsOnNewline = pos.endColumn === 1 && pos.startLine !== pos.endLine
+      const up = options.pscIdeColors ? colors.red('^') : '^'
+      const down = options.pscIdeColors ? colors.red('v') : 'v'
+      let trimmed = lines.slice(0)
+
+      if (endsOnNewline) {
+        lines.splice(lines.length - 1, 1)
+        pos.endLine = pos.endLine - 1
+        pos.endColumn = lines[lines.length - 1].length || 1
+      }
 
-    // strip newlines at the end
-    if (endsOnNewline) {
-      trimmed = lines.reverse().reduce((trimmed, line, i) => {
-        if (i === 0 && line === '') trimmed.trimming = true
-        if (!trimmed.trimming) trimmed.push(line)
-        if (trimmed.trimming && line !== '') {
-          trimmed.trimming = false
-          trimmed.push(line)
-        }
-        return trimmed
-      }, []).reverse()
-      pos.endLine = pos.endLine - (lines.length - trimmed.length)
-      pos.endColumn = trimmed[trimmed.length - 1].length || 1
-    }
+      // strip newlines at the end
+      if (endsOnNewline) {
+        trimmed = lines.reverse().reduce((trimmed, line, i) => {
+          if (i === 0 && line === '') trimmed.trimming = true
+          if (!trimmed.trimming) trimmed.push(line)
+          if (trimmed.trimming && line !== '') {
+            trimmed.trimming = false
+            trimmed.push(line)
+          }
+          return trimmed
+        }, []).reverse()
+        pos.endLine = pos.endLine - (lines.length - trimmed.length)
+        pos.endColumn = trimmed[trimmed.length - 1].length || 1
+      }
 
-    const spaces = ' '.repeat(String(pos.endLine).length)
-    let snippet = trimmed.map((line, i) => {
-      return `  ${pos.startLine + i}  ${line}`
-    }).join('\n')
+      const spaces = ' '.repeat(String(pos.endLine).length)
+      let snippet = trimmed.map((line, i) => {
+        return `  ${pos.startLine + i}  ${line}`
+      }).join('\n')
 
-    if (trimmed.length === 1) {
-      snippet += `\n  ${spaces}  ${' '.repeat(pos.startColumn - 1)}${up.repeat(pos.endColumn - pos.startColumn + 1)}`
-    } else {
-      snippet = `  ${spaces}  ${' '.repeat(pos.startColumn - 1)}${down}\n${snippet}`
-      snippet += `\n  ${spaces}  ${' '.repeat(pos.endColumn - 1)}${up}`
-    }
+      if (trimmed.length === 1) {
+        snippet += `\n  ${spaces}  ${' '.repeat(pos.startColumn - 1)}${up.repeat(pos.endColumn - pos.startColumn + 1)}`
+      } else {
+        snippet = `  ${spaces}  ${' '.repeat(pos.startColumn - 1)}${down}\n${snippet}`
+        snippet += `\n  ${spaces}  ${' '.repeat(pos.endColumn - 1)}${up}`
+      }
 
-    return Promise.resolve(
-      `\n${numAndErr} ${fileAndPos}\n\n${snippet}\n\n${result.message}`
-    )
-  })
+      return Promise.resolve(`\n${numAndErr} ${fileAndPos}\n\n${snippet}\n\n${result.message}`)
+    })
+  }
+
+  return result.filename && result.position ? makeResultSnippet(result.filename, result.position) : makeResult();
 }