UNPKG

atom-nuclide

Version:

A unified developer experience for web and mobile development, built as a suite of features on top of Atom to provide hackability and the support of an active community.

220 lines (184 loc) 7.29 kB
Object.defineProperty(exports, '__esModule', { value: true }); /* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. */ /** * Executes hh_client with proper arguments returning the result string or json object. */ var callHHClient = _asyncToGenerator(function* (args, errorStream, outputJson, processInput, filePath) { if (!hhPromiseQueue) { hhPromiseQueue = new (_commonsNodePromiseExecutors2 || _commonsNodePromiseExecutors()).PromiseQueue(); } var hackExecOptions = yield (0, (_hackConfig2 || _hackConfig()).getHackExecOptions)(filePath); if (!hackExecOptions) { return null; } var hackRoot = hackExecOptions.hackRoot; var hackCommand = hackExecOptions.hackCommand; (0, (_assert2 || _assert()).default)(hhPromiseQueue); return hhPromiseQueue.submit(_asyncToGenerator(function* (resolve, reject) { // Append args on the end of our commands. var defaults = ['--retries', '0', '--retry-if-init', 'false', '--from', 'nuclide']; if (outputJson) { defaults.unshift('--json'); } var allArgs = defaults.concat(args); allArgs.push(hackRoot); var execResult = null; try { (_hackConfig4 || _hackConfig3()).logger.logTrace('Calling Hack: ' + hackCommand + ' with ' + allArgs.toString()); execResult = yield (0, (_commonsNodeProcess2 || _commonsNodeProcess()).asyncExecute)(hackCommand, allArgs, { stdin: processInput }); } catch (err) { reject(err); return; } var _execResult = execResult; var stdout = _execResult.stdout; var stderr = _execResult.stderr; if (stderr.indexOf(HH_SERVER_INIT_MESSAGE) !== -1) { reject(new Error(HH_SERVER_INIT_MESSAGE + ': try: `arc build` or try again later!')); return; } else if (stderr.startsWith(HH_SERVER_BUSY_MESSAGE)) { reject(new Error(HH_SERVER_BUSY_MESSAGE + ': try: `arc build` or try again later!')); return; } var output = errorStream ? stderr : stdout; (_hackConfig4 || _hackConfig3()).logger.logTrace('Hack output for ' + allArgs.toString() + ': ' + output); if (!outputJson) { resolve(output); return; } try { resolve(JSON.parse(output)); } catch (err) { var errorMessage = 'hh_client error, args: [' + args.join(',') + ']\nstdout: ' + stdout + ', stderr: ' + stderr; (_hackConfig4 || _hackConfig3()).logger.logError(errorMessage); reject(new Error(errorMessage)); } })); }); exports.callHHClient = callHHClient; var getSearchResults = _asyncToGenerator(function* (filePath, search, filterTypes, searchPostfix) { if (search == null) { return null; } var hackRoot = yield (0, (_hackConfig2 || _hackConfig()).findHackConfigDir)(filePath); if (hackRoot == null) { return null; } // `pendingSearchPromises` is used to temporally cache search result promises. // So, when a matching search query is done in parallel, it will wait and resolve // with the original search call. var searchPromise = pendingSearchPromises.get(search); if (!searchPromise) { searchPromise = callHHClient( /* args */['--search' + (searchPostfix || ''), search], /* errorStream */false, /* outputJson */true, /* processInput */null, /* file */filePath); pendingSearchPromises.set(search, searchPromise); } var searchResponse = null; try { searchResponse = yield searchPromise; } finally { pendingSearchPromises.delete(search); } if (searchResponse == null) { return null; } var searchResult = searchResponse; var result = []; for (var entry of searchResult) { var resultFile = entry.filename; if (!resultFile.startsWith(hackRoot)) { // Filter out files out of repo results, e.g. hh internal files. continue; } result.push({ line: entry.line - 1, column: entry.char_start - 1, name: entry.name, path: resultFile, length: entry.char_end - entry.char_start + 1, scope: entry.scope, additionalInfo: entry.desc }); } if (filterTypes) { result = filterSearchResults(result, filterTypes); } return { hackRoot: hackRoot, result: result }; } // Eventually this will happen on the hack side, but for now, this will do. ); exports.getSearchResults = getSearchResults; function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { var callNext = step.bind(null, 'next'); var callThrow = step.bind(null, 'throw'); function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(callNext, callThrow); } } callNext(); }); }; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _assert2; function _assert() { return _assert2 = _interopRequireDefault(require('assert')); } var _commonsNodeProcess2; function _commonsNodeProcess() { return _commonsNodeProcess2 = require('../../commons-node/process'); } var _commonsNodePromiseExecutors2; function _commonsNodePromiseExecutors() { return _commonsNodePromiseExecutors2 = require('../../commons-node/promise-executors'); } var _nuclideHackCommon2; function _nuclideHackCommon() { return _nuclideHackCommon2 = require('../../nuclide-hack-common'); } var _hackConfig2; function _hackConfig() { return _hackConfig2 = require('./hack-config'); } var HH_SERVER_INIT_MESSAGE = 'hh_server still initializing'; var HH_SERVER_BUSY_MESSAGE = 'hh_server is busy'; var _hackConfig4; function _hackConfig3() { return _hackConfig4 = require('./hack-config'); } var hhPromiseQueue = null; var pendingSearchPromises = new Map();function filterSearchResults(results, filter) { return results.filter(function (result) { var info = result.additionalInfo; var searchType = getSearchType(info); return filter.indexOf(searchType) !== -1; }); } function getSearchType(info) { switch (info) { case 'typedef': return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.TYPEDEF; case 'function': return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.FUNCTION; case 'constant': return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.CONSTANT; case 'trait': return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.TRAIT; case 'interface': return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.INTERFACE; case 'abstract class': return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.ABSTRACT_CLASS; default: { if (info.startsWith('method') || info.startsWith('static method')) { return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.METHOD; } if (info.startsWith('class var') || info.startsWith('static class var')) { return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.CLASS_VAR; } return (_nuclideHackCommon2 || _nuclideHackCommon()).SearchResultType.CLASS; } } }