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())
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()
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)
}
}
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) => {
})
.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')
})
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();
}